1 //===- EscapeEnumerator.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Defines a helper class that enumerates all possible exits from a function,
10 // including exception handling.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/Utils/EscapeEnumerator.h"
15 #include "llvm/Analysis/EHPersonalities.h"
16 #include "llvm/Transforms/Utils/Local.h"
17 #include "llvm/IR/CallSite.h"
18 #include "llvm/IR/Module.h"
21 static FunctionCallee
getDefaultPersonalityFn(Module
*M
) {
22 LLVMContext
&C
= M
->getContext();
23 Triple
T(M
->getTargetTriple());
24 EHPersonality Pers
= getDefaultEHPersonality(T
);
25 return M
->getOrInsertFunction(getEHPersonalityName(Pers
),
26 FunctionType::get(Type::getInt32Ty(C
), true));
29 IRBuilder
<> *EscapeEnumerator::Next() {
33 // Find all 'return', 'resume', and 'unwind' instructions.
34 while (StateBB
!= StateE
) {
35 BasicBlock
*CurBB
= &*StateBB
++;
37 // Branches and invokes do not escape, only unwind, resume, and return
39 Instruction
*TI
= CurBB
->getTerminator();
40 if (!isa
<ReturnInst
>(TI
) && !isa
<ResumeInst
>(TI
))
43 Builder
.SetInsertPoint(TI
);
49 if (!HandleExceptions
)
55 // Find all 'call' instructions that may throw.
56 SmallVector
<Instruction
*, 16> Calls
;
57 for (BasicBlock
&BB
: F
)
58 for (Instruction
&II
: BB
)
59 if (CallInst
*CI
= dyn_cast
<CallInst
>(&II
))
60 if (!CI
->doesNotThrow())
66 // Create a cleanup block.
67 LLVMContext
&C
= F
.getContext();
68 BasicBlock
*CleanupBB
= BasicBlock::Create(C
, CleanupBBName
, &F
);
69 Type
*ExnTy
= StructType::get(Type::getInt8PtrTy(C
), Type::getInt32Ty(C
));
70 if (!F
.hasPersonalityFn()) {
71 FunctionCallee PersFn
= getDefaultPersonalityFn(F
.getParent());
72 F
.setPersonalityFn(cast
<Constant
>(PersFn
.getCallee()));
75 if (isScopedEHPersonality(classifyEHPersonality(F
.getPersonalityFn()))) {
76 report_fatal_error("Scoped EH not supported");
79 LandingPadInst
*LPad
=
80 LandingPadInst::Create(ExnTy
, 1, "cleanup.lpad", CleanupBB
);
81 LPad
->setCleanup(true);
82 ResumeInst
*RI
= ResumeInst::Create(LPad
, CleanupBB
);
84 // Transform the 'call' instructions into 'invoke's branching to the
85 // cleanup block. Go in reverse order to make prettier BB names.
86 SmallVector
<Value
*, 16> Args
;
87 for (unsigned I
= Calls
.size(); I
!= 0;) {
88 CallInst
*CI
= cast
<CallInst
>(Calls
[--I
]);
89 changeToInvokeAndSplitBasicBlock(CI
, CleanupBB
);
92 Builder
.SetInsertPoint(RI
);