llvm.org GIT mirror llvm / a09145e
[CodeExtractor] Allow extracting blocks with exception handling This is a CodeExtractor improvement which adds support for extracting blocks which have exception handling constructs if that is legal to do. CodeExtractor performs validation checks to ensure that extraction is legal when it finds invoke instructions or EH pads (landingpad, catchswitch, or cleanuppad) in blocks to be extracted. I have also added an option to allow extraction of blocks with alloca instructions, but no validation is done for allocas. CodeExtractor caller has to validate it himself before allowing alloca instructions to be extracted. By default allocas are still not allowed in extraction blocks. Differential Revision: https://reviews.llvm.org/D45904 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332151 91177308-0d34-0410-b5e6-96231b3b80d8 Sergey Dmitriev 1 year, 4 months ago
4 changed file(s) with 205 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
7171 /// sequence out into its new function. When a DominatorTree is also given,
7272 /// extra checking and transformations are enabled. If AllowVarArgs is true,
7373 /// vararg functions can be extracted. This is safe, if all vararg handling
74 /// code is extracted, including vastart.
74 /// code is extracted, including vastart. If AllowAlloca is true, then
75 /// extraction of blocks containing alloca instructions would be possible,
76 /// however code extractor won't validate whether extraction is legal.
7577 CodeExtractor(ArrayRef BBs, DominatorTree *DT = nullptr,
7678 bool AggregateArgs = false, BlockFrequencyInfo *BFI = nullptr,
7779 BranchProbabilityInfo *BPI = nullptr,
78 bool AllowVarArgs = false);
80 bool AllowVarArgs = false, bool AllowAlloca = false);
7981
8082 /// Create a code extractor for a loop body.
8183 ///
8486 CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs = false,
8587 BlockFrequencyInfo *BFI = nullptr,
8688 BranchProbabilityInfo *BPI = nullptr);
87
88 /// Check to see if a block is valid for extraction.
89 ///
90 /// Blocks containing EHPads, allocas and invokes are not valid. If
91 /// AllowVarArgs is true, blocks with vastart can be extracted. This is
92 /// safe, if all vararg handling code is extracted, including vastart.
93 static bool isBlockValidForExtraction(const BasicBlock &BB,
94 bool AllowVarArgs);
9589
9690 /// Perform the extraction, returning the new function.
9791 ///
7878 cl::desc("Aggregate arguments to code-extracted functions"));
7979
8080 /// Test whether a block is valid for extraction.
81 bool CodeExtractor::isBlockValidForExtraction(const BasicBlock &BB,
82 bool AllowVarArgs) {
83 // Landing pads must be in the function where they were inserted for cleanup.
84 if (BB.isEHPad())
85 return false;
81 static bool isBlockValidForExtraction(const BasicBlock &BB,
82 const SetVector &Result,
83 bool AllowVarArgs, bool AllowAlloca) {
8684 // taking the address of a basic block moved to another function is illegal
8785 if (BB.hasAddressTaken())
8886 return false;
111109 }
112110 }
113111
114 // Don't hoist code containing allocas or invokes. If explicitly requested,
115 // allow vastart.
112 // If explicitly requested, allow vastart and alloca. For invoke instructions
113 // verify that extraction is valid.
116114 for (BasicBlock::const_iterator I = BB.begin(), E = BB.end(); I != E; ++I) {
117 if (isa(I) || isa(I))
118 return false;
115 if (isa(I)) {
116 if (!AllowAlloca)
117 return false;
118 continue;
119 }
120
121 if (const auto *II = dyn_cast(I)) {
122 // Unwind destination (either a landingpad, catchswitch, or cleanuppad)
123 // must be a part of the subgraph which is being extracted.
124 if (auto *UBB = II->getUnwindDest())
125 if (!Result.count(UBB))
126 return false;
127 continue;
128 }
129
130 // All catch handlers of a catchswitch instruction as well as the unwind
131 // destination must be in the subgraph.
132 if (const auto *CSI = dyn_cast(I)) {
133 if (auto *UBB = CSI->getUnwindDest())
134 if (!Result.count(UBB))
135 return false;
136 for (auto *HBB : CSI->handlers())
137 if (!Result.count(const_cast(HBB)))
138 return false;
139 continue;
140 }
141
142 // Make sure that entire catch handler is within subgraph. It is sufficient
143 // to check that catch return's block is in the list.
144 if (const auto *CPI = dyn_cast(I)) {
145 for (const auto *U : CPI->users())
146 if (const auto *CRI = dyn_cast(U))
147 if (!Result.count(const_cast(CRI->getParent())))
148 return false;
149 continue;
150 }
151
152 // And do similar checks for cleanup handler - the entire handler must be
153 // in subgraph which is going to be extracted. For cleanup return should
154 // additionally check that the unwind destination is also in the subgraph.
155 if (const auto *CPI = dyn_cast(I)) {
156 for (const auto *U : CPI->users())
157 if (const auto *CRI = dyn_cast(U))
158 if (!Result.count(const_cast(CRI->getParent())))
159 return false;
160 continue;
161 }
162 if (const auto *CRI = dyn_cast(I)) {
163 if (auto *UBB = CRI->getUnwindDest())
164 if (!Result.count(UBB))
165 return false;
166 continue;
167 }
168
119169 if (const CallInst *CI = dyn_cast(I))
120170 if (const Function *F = CI->getCalledFunction())
121171 if (F->getIntrinsicID() == Intrinsic::vastart) {
132182 /// Build a set of blocks to extract if the input blocks are viable.
133183 static SetVector
134184 buildExtractionBlockSet(ArrayRef BBs, DominatorTree *DT,
135 bool AllowVarArgs) {
185 bool AllowVarArgs, bool AllowAlloca) {
136186 assert(!BBs.empty() && "The set of blocks to extract must be non-empty");
137187 SetVector Result;
138188
145195
146196 if (!Result.insert(BB))
147197 llvm_unreachable("Repeated basic blocks in extraction input");
148 if (!CodeExtractor::isBlockValidForExtraction(*BB, AllowVarArgs)) {
149 Result.clear();
150 return Result;
151 }
152 }
153
154 #ifndef NDEBUG
155 for (SetVector::iterator I = std::next(Result.begin()),
156 E = Result.end();
157 I != E; ++I)
158 for (pred_iterator PI = pred_begin(*I), PE = pred_end(*I);
159 PI != PE; ++PI)
160 assert(Result.count(*PI) &&
161 "No blocks in this region may have entries from outside the region"
162 " except for the first block!");
163 #endif
198 }
199
200 for (auto *BB : Result) {
201 if (!isBlockValidForExtraction(*BB, Result, AllowVarArgs, AllowAlloca))
202 return {};
203
204 // Make sure that the first block is not a landing pad.
205 if (BB == Result.front()) {
206 if (BB->isEHPad()) {
207 DEBUG(dbgs() << "The first block cannot be an unwind block\n");
208 return {};
209 }
210 continue;
211 }
212
213 // All blocks other than the first must not have predecessors outside of
214 // the subgraph which is being extracted.
215 for (auto *PBB : predecessors(BB))
216 if (!Result.count(PBB)) {
217 DEBUG(dbgs() << "No blocks in this region may have entries from "
218 "outside the region except for the first block!\n");
219 return {};
220 }
221 }
164222
165223 return Result;
166224 }
167225
168226 CodeExtractor::CodeExtractor(ArrayRef BBs, DominatorTree *DT,
169227 bool AggregateArgs, BlockFrequencyInfo *BFI,
170 BranchProbabilityInfo *BPI, bool AllowVarArgs)
228 BranchProbabilityInfo *BPI, bool AllowVarArgs,
229 bool AllowAlloca)
171230 : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
172231 BPI(BPI), AllowVarArgs(AllowVarArgs),
173 Blocks(buildExtractionBlockSet(BBs, DT, AllowVarArgs)) {}
232 Blocks(buildExtractionBlockSet(BBs, DT, AllowVarArgs, AllowAlloca)) {}
174233
175234 CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs,
176235 BlockFrequencyInfo *BFI,
178237 : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI),
179238 BPI(BPI), AllowVarArgs(false),
180239 Blocks(buildExtractionBlockSet(L.getBlocks(), &DT,
181 /* AllowVarArgs */ false)) {}
240 /* AllowVarArgs */ false,
241 /* AllowAlloca */ false)) {}
182242
183243 /// definedInRegion - Return true if the specified value is defined in the
184244 /// extracted region.
11771237
11781238 moveCodeToFunction(newFunction);
11791239
1240 // Propagate personality info to the new function if there is one.
1241 if (oldFunction->hasPersonalityFn())
1242 newFunction->setPersonalityFn(oldFunction->getPersonalityFn());
1243
11801244 // Update the branch weights for the exit block.
11811245 if (BFI && NumExitBlocks > 1)
11821246 calculateNewCallTerminatorWeights(codeReplacer, ExitWeights, BPI);
0 ; RUN: opt < %s -skip-partial-inlining-cost-analysis -partial-inliner -S | FileCheck %s
1 ; RUN: opt < %s -skip-partial-inlining-cost-analysis -passes=partial-inliner -S | FileCheck %s
2
3 declare void @bar()
4 declare i32 @__gxx_personality_v0(...)
5 declare i8* @__cxa_begin_catch(i8*)
6 declare void @__cxa_end_catch()
7
8 define internal void @callee(i1 %cond) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
9 entry:
10 br i1 %cond, label %if.then, label %if.end
11
12 if.then:
13 invoke void @bar()
14 to label %invoke.cont unwind label %lpad
15
16 invoke.cont:
17 br label %try.cont
18
19 lpad:
20 %0 = landingpad { i8*, i32 }
21 catch i8* null
22 %1 = extractvalue { i8*, i32 } %0, 0
23 %2 = extractvalue { i8*, i32 } %0, 1
24 br label %catch
25
26 catch:
27 %3 = call i8* @__cxa_begin_catch(i8* %1)
28 call void @__cxa_end_catch()
29 br label %try.cont
30
31 try.cont:
32 br label %if.end
33
34 if.end:
35 ret void
36 }
37
38 define internal void @caller(i1 %cond) {
39 ; CHECK-LABEL: define {{.*}} @caller
40 entry:
41 ; CHECK: entry:
42 ; CHECK-NEXT: br i1
43 ; CHECK: codeRepl.i:
44 ; CHECK-NEXT: call void @callee.1_{{.*}}()
45 call void @callee(i1 %cond)
46 ret void
47 }
48
49 ; CHECK-LABEL: define {{.*}} @callee.1_{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
50 ; CHECK: invoke void @bar()
51 ; CHECK: landingpad
0 ; RUN: opt < %s -skip-partial-inlining-cost-analysis -partial-inliner -S | FileCheck %s
1 ; RUN: opt < %s -skip-partial-inlining-cost-analysis -passes=partial-inliner -S | FileCheck %s
2
3 declare dso_local void @bar()
4 declare dso_local i32 @__CxxFrameHandler3(...)
5
6 define internal void @callee(i1 %cond) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
7 entry:
8 br i1 %cond, label %if.then, label %if.end
9
10 if.then:
11 invoke void @bar()
12 to label %invoke.cont unwind label %ehcleanup
13
14 invoke.cont:
15 br label %try.cont
16
17 ehcleanup:
18 %0 = cleanuppad within none []
19 cleanupret from %0 unwind label %catch.dispatch
20
21 catch.dispatch:
22 %1 = catchswitch within none [label %catch] unwind to caller
23
24 catch:
25 %2 = catchpad within %1 [i8* null, i32 64, i8* null]
26 catchret from %2 to label %catchret.dest
27
28 catchret.dest:
29 br label %try.cont
30
31 try.cont:
32 br label %if.end
33
34 if.end:
35 ret void
36 }
37
38 define internal void @caller(i1 %cond) {
39 ; CHECK-LABEL: define {{.*}} @caller
40 entry:
41 ; CHECK: entry:
42 ; CHECK-NEXT: br i1
43 ; CHECK: codeRepl.i:
44 ; CHECK-NEXT: call void @callee.1_{{.*}}()
45 call void @callee(i1 %cond)
46 ret void
47 }
48
49 ; CHECK-LABEL: define {{.*}} @callee.1_{{.*}}() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
50 ; CHECK: invoke void @bar()
51 ; CHECK: cleanuppad
52 ; CHECK-NEXT: cleanupret
53 ; CHECK: catchswitch
54 ; CHECK: catchpad
55 ; CHECK-NEXT: catchret