llvm.org GIT mirror llvm / 1b91c5e
Add CallSiteSplitting pass Summary: This change add a pass which tries to split a call-site to pass more constrained arguments if its argument is predicated in the control flow so that we can expose better context to the later passes (e.g, inliner, jump threading, or IPA-CP based function cloning, etc.). As of now we support two cases : 1) If a call site is dominated by an OR condition and if any of its arguments are predicated on this OR condition, try to split the condition with more constrained arguments. For example, in the code below, we try to split the call site since we can predicate the argument (ptr) based on the OR condition. Split from : if (!ptr || c) callee(ptr); to : if (!ptr) callee(null ptr) // set the known constant value else if (c) callee(nonnull ptr) // set non-null attribute in the argument 2) We can also split a call-site based on constant incoming values of a PHI For example, from : BB0: %c = icmp eq i32 %i1, %i2 br i1 %c, label %BB2, label %BB1 BB1: br label %BB2 BB2: %p = phi i32 [ 0, %BB0 ], [ 1, %BB1 ] call void @bar(i32 %p) to BB0: %c = icmp eq i32 %i1, %i2 br i1 %c, label %BB2-split0, label %BB1 BB1: br label %BB2-split1 BB2-split0: call void @bar(i32 0) br label %BB2 BB2-split1: call void @bar(i32 1) br label %BB2 BB2: %p = phi i32 [ 0, %BB2-split0 ], [ 1, %BB2-split1 ] Reviewers: davidxl, huntergr, chandlerc, mcrosier, eraman, davide Reviewed By: davidxl Subscribers: sdesmalen, ashutosh.nema, fhahn, mssimpso, aemerson, mgorny, mehdi_amini, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D39137 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317351 91177308-0d34-0410-b5e6-96231b3b80d8 Jun Bum Lim 1 year, 10 months ago
14 changed file(s) with 1014 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
7979 void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry&);
8080 void initializeBranchRelaxationPass(PassRegistry&);
8181 void initializeBreakCriticalEdgesPass(PassRegistry&);
82 void initializeCallSiteSplittingLegacyPassPass(PassRegistry&);
8283 void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
8384 void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
8485 void initializeCFGPrinterLegacyPassPass(PassRegistry&);
0 //===- CallSiteSplitting..h - Callsite Splitting ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
10 #define LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
11
12 #include "llvm/ADT/SetVector.h"
13 #include "llvm/Analysis/AssumptionCache.h"
14 #include "llvm/IR/Dominators.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/PassManager.h"
17 #include "llvm/Support/Compiler.h"
18 #include
19
20 namespace llvm {
21
22 struct CallSiteSplittingPass : PassInfoMixin {
23 /// \brief Run the pass over the function.
24 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
25 };
26 } // end namespace llvm
27
28 #endif // LLVM_TRANSFORMS_SCALAR_CALLSITESPLITTING__H
7272 //
7373 FunctionPass *createDeadStoreEliminationPass();
7474
75
76 //===----------------------------------------------------------------------===//
77 //
78 // CallSiteSplitting - This pass split call-site based on its known argument
79 // values.
80 FunctionPass *createCallSiteSplittingPass();
81
82
7583 //===----------------------------------------------------------------------===//
7684 //
7785 // AggressiveDCE - This pass uses the SSA based Aggressive DCE algorithm. This
8888 #include "llvm/Transforms/Scalar/ADCE.h"
8989 #include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
9090 #include "llvm/Transforms/Scalar/BDCE.h"
91 #include "llvm/Transforms/Scalar/CallSiteSplitting.h"
9192 #include "llvm/Transforms/Scalar/ConstantHoisting.h"
9293 #include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h"
9394 #include "llvm/Transforms/Scalar/DCE.h"
547548 EarlyFPM.addPass(SROA());
548549 EarlyFPM.addPass(EarlyCSEPass());
549550 EarlyFPM.addPass(LowerExpectIntrinsicPass());
551 if (Level == O3)
552 EarlyFPM.addPass(CallSiteSplittingPass());
553
550554 // In SamplePGO ThinLTO backend, we need instcombine before profile annotation
551555 // to convert bitcast to direct calls so that they can be inlined during the
552556 // profile annotation prepration step.
919923 MPM.addPass(InferFunctionAttrsPass());
920924
921925 if (Level > 1) {
926 FunctionPassManager EarlyFPM(DebugLogging);
927 EarlyFPM.addPass(CallSiteSplittingPass());
928 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
929
922930 // Indirect call promotion. This should promote all the targets that are
923931 // left by the earlier promotion pass that promotes intra-module targets.
924932 // This two-step promotion is to save the compile time. For LTO, it should
925933 // produce the same result as if we only do promotion here.
926934 MPM.addPass(PGOIndirectCallPromotion(
927935 true /* InLTO */, PGOOpt && !PGOOpt->SampleProfileFile.empty()));
928
929936 // Propagate constants at call sites into the functions they call. This
930937 // opens opportunities for globalopt (and inlining) by substituting function
931938 // pointers passed as arguments to direct uses of functions.
139139 FUNCTION_PASS("alignment-from-assumptions", AlignmentFromAssumptionsPass())
140140 FUNCTION_PASS("bdce", BDCEPass())
141141 FUNCTION_PASS("break-crit-edges", BreakCriticalEdgesPass())
142 FUNCTION_PASS("callsite-splitting", CallSiteSplittingPass())
142143 FUNCTION_PASS("consthoist", ConstantHoistingPass())
143144 FUNCTION_PASS("correlated-propagation", CorrelatedValuePropagationPass())
144145 FUNCTION_PASS("dce", DCEPass())
466466
467467 addExtensionsToPM(EP_ModuleOptimizerEarly, MPM);
468468
469 if (OptLevel > 2)
470 MPM.add(createCallSiteSplittingPass());
471
469472 MPM.add(createIPSCCPPass()); // IP SCCP
470473 MPM.add(createCalledValuePropagationPass());
471474 MPM.add(createGlobalOptimizerPass()); // Optimize out global vars
702705 PM.add(createInferFunctionAttrsLegacyPass());
703706
704707 if (OptLevel > 1) {
708 // Split call-site with more constrained arguments.
709 PM.add(createCallSiteSplittingPass());
710
705711 // Indirect call promotion. This should promote all the targets that are
706712 // left by the earlier promotion pass that promotes intra-module targets.
707713 // This two-step promotion is to save the compile time. For LTO, it should
11 ADCE.cpp
22 AlignmentFromAssumptions.cpp
33 BDCE.cpp
4 CallSiteSplitting.cpp
45 ConstantHoisting.cpp
56 ConstantProp.cpp
67 CorrelatedValuePropagation.cpp
0 //===- CallSiteSplitting.cpp ----------------------------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements a transformation that tries to split a call-site to pass
10 // more constrained arguments if its argument is predicated in the control flow
11 // so that we can expose better context to the later passes (e.g, inliner, jump
12 // threading, or IPA-CP based function cloning, etc.).
13 // As of now we support two cases :
14 //
15 // 1) If a call site is dominated by an OR condition and if any of its arguments
16 // are predicated on this OR condition, try to split the condition with more
17 // constrained arguments. For example, in the code below, we try to split the
18 // call site since we can predicate the argument(ptr) based on the OR condition.
19 //
20 // Split from :
21 // if (!ptr || c)
22 // callee(ptr);
23 // to :
24 // if (!ptr)
25 // callee(null) // set the known constant value
26 // else if (c)
27 // callee(nonnull ptr) // set non-null attribute in the argument
28 //
29 // 2) We can also split a call-site based on constant incoming values of a PHI
30 // For example,
31 // from :
32 // Header:
33 // %c = icmp eq i32 %i1, %i2
34 // br i1 %c, label %Tail, label %TBB
35 // TBB:
36 // br label Tail%
37 // Tail:
38 // %p = phi i32 [ 0, %Header], [ 1, %TBB]
39 // call void @bar(i32 %p)
40 // to
41 // Header:
42 // %c = icmp eq i32 %i1, %i2
43 // br i1 %c, label %Tail-split0, label %TBB
44 // TBB:
45 // br label %Tail-split1
46 // Tail-split0:
47 // call void @bar(i32 0)
48 // br label %Tail
49 // Tail-split1:
50 // call void @bar(i32 1)
51 // br label %Tail
52 // Tail:
53 // %p = phi i32 [ 0, %Tail-split0 ], [ 1, %Tail-split1 ]
54 //
55 //===----------------------------------------------------------------------===//
56
57 #include "llvm/Transforms/Scalar/CallSiteSplitting.h"
58 #include "llvm/ADT/Statistic.h"
59 #include "llvm/Analysis/TargetLibraryInfo.h"
60 #include "llvm/IR/IntrinsicInst.h"
61 #include "llvm/IR/PatternMatch.h"
62 #include "llvm/Support/Debug.h"
63 #include "llvm/Transforms/Scalar.h"
64 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
65 #include "llvm/Transforms/Utils/Local.h"
66
67 using namespace llvm;
68 using namespace PatternMatch;
69
70 #define DEBUG_TYPE "callsite-splitting"
71
72 STATISTIC(NumCallSiteSplit, "Number of call-site split");
73
74 static void addNonNullAttribute(Instruction *CallI, Instruction *&NewCallI,
75 Value *Op) {
76 if (!NewCallI)
77 NewCallI = CallI->clone();
78 CallSite CS(NewCallI);
79 unsigned ArgNo = 0;
80 for (auto &I : CS.args()) {
81 if (&*I == Op)
82 CS.addParamAttr(ArgNo, Attribute::NonNull);
83 ++ArgNo;
84 }
85 }
86
87 static void setConstantInArgument(Instruction *CallI, Instruction *&NewCallI,
88 Value *Op, Constant *ConstValue) {
89 if (!NewCallI)
90 NewCallI = CallI->clone();
91 CallSite CS(NewCallI);
92 unsigned ArgNo = 0;
93 for (auto &I : CS.args()) {
94 if (&*I == Op)
95 CS.setArgument(ArgNo, ConstValue);
96 ++ArgNo;
97 }
98 }
99
100 static bool createCallSitesOnOrPredicatedArgument(
101 CallSite CS, Instruction *&NewCSTakenFromHeader,
102 Instruction *&NewCSTakenFromNextCond,
103 SmallVectorImpl &BranchInsts, BasicBlock *HeaderBB) {
104 assert(BranchInsts.size() <= 2 &&
105 "Unexpected number of blocks in the OR predicated condition");
106 Instruction *Instr = CS.getInstruction();
107 BasicBlock *CallSiteBB = Instr->getParent();
108 TerminatorInst *HeaderTI = HeaderBB->getTerminator();
109 bool IsCSInTakenPath = CallSiteBB == HeaderTI->getSuccessor(0);
110
111 for (unsigned I = 0, E = BranchInsts.size(); I != E; ++I) {
112 BranchInst *PBI = BranchInsts[I];
113 assert(isa(PBI->getCondition()) &&
114 "Unexpected condition in a conditional branch.");
115 ICmpInst *Cmp = cast(PBI->getCondition());
116 Value *Arg = Cmp->getOperand(0);
117 assert(isa(Cmp->getOperand(1)) &&
118 "Expected op1 to be a constant.");
119 Constant *ConstVal = cast(Cmp->getOperand(1));
120 CmpInst::Predicate Pred = Cmp->getPredicate();
121
122 if (PBI->getParent() == HeaderBB) {
123 Instruction *&CallTakenFromHeader =
124 IsCSInTakenPath ? NewCSTakenFromHeader : NewCSTakenFromNextCond;
125 Instruction *&CallUntakenFromHeader =
126 IsCSInTakenPath ? NewCSTakenFromNextCond : NewCSTakenFromHeader;
127
128 assert(Pred == ICmpInst::ICMP_EQ ||
129 Pred == ICmpInst::ICMP_NE &&
130 "Unexpected predicate in an OR condition");
131
132 // Set the constant value for agruments in the call predicated based on
133 // the OR condition.
134 Instruction *&CallToSetConst = Pred == ICmpInst::ICMP_EQ
135 ? CallTakenFromHeader
136 : CallUntakenFromHeader;
137 setConstantInArgument(Instr, CallToSetConst, Arg, ConstVal);
138
139 // Add the NonNull attribute if compared with the null pointer.
140 if (ConstVal->getType()->isPointerTy() && ConstVal->isNullValue()) {
141 Instruction *&CallToSetAttr = Pred == ICmpInst::ICMP_EQ
142 ? CallUntakenFromHeader
143 : CallTakenFromHeader;
144 addNonNullAttribute(Instr, CallToSetAttr, Arg);
145 }
146 continue;
147 }
148
149 if (Pred == ICmpInst::ICMP_EQ) {
150 if (PBI->getSuccessor(0) == Instr->getParent()) {
151 // Set the constant value for the call taken from the second block in
152 // the OR condition.
153 setConstantInArgument(Instr, NewCSTakenFromNextCond, Arg, ConstVal);
154 } else {
155 // Add the NonNull attribute if compared with the null pointer for the
156 // call taken from the second block in the OR condition.
157 if (ConstVal->getType()->isPointerTy() && ConstVal->isNullValue())
158 addNonNullAttribute(Instr, NewCSTakenFromNextCond, Arg);
159 }
160 } else {
161 if (PBI->getSuccessor(0) == Instr->getParent()) {
162 // Add the NonNull attribute if compared with the null pointer for the
163 // call taken from the second block in the OR condition.
164 if (ConstVal->getType()->isPointerTy() && ConstVal->isNullValue())
165 addNonNullAttribute(Instr, NewCSTakenFromNextCond, Arg);
166 } else if (Pred == ICmpInst::ICMP_NE) {
167 // Set the constant value for the call in the untaken path from the
168 // header block.
169 setConstantInArgument(Instr, NewCSTakenFromNextCond, Arg, ConstVal);
170 } else
171 llvm_unreachable("Unexpected condition");
172 }
173 }
174 return NewCSTakenFromHeader || NewCSTakenFromNextCond;
175 }
176
177 static bool canSplitCallSite(CallSite CS) {
178 // FIXME: As of now we handle only CallInst. InvokeInst could be handled
179 // without too much effort.
180 Instruction *Instr = CS.getInstruction();
181 if (!isa(Instr))
182 return false;
183
184 // Allow splitting a call-site only when there is no instruction before the
185 // call-site in the basic block. Based on this constraint, we only clone the
186 // call instruction, and we do not move a call-site across any other
187 // instruction.
188 BasicBlock *CallSiteBB = Instr->getParent();
189 if (Instr != CallSiteBB->getFirstNonPHI())
190 return false;
191
192 pred_iterator PII = pred_begin(CallSiteBB);
193 pred_iterator PIE = pred_end(CallSiteBB);
194 unsigned NumPreds = std::distance(PII, PIE);
195
196 // Allow only one extra call-site. No more than two from one call-site.
197 if (NumPreds != 2)
198 return false;
199
200 // Cannot split an edge from an IndirectBrInst.
201 BasicBlock *Preds[2] = {*PII++, *PII};
202 if (isa(Preds[0]->getTerminator()) ||
203 isa(Preds[1]->getTerminator()))
204 return false;
205
206 return CallSiteBB->canSplitPredecessors();
207 }
208
209 /// Return true if the CS is split into its new predecessors which are directly
210 /// hooked to each of its orignial predecessors pointed by PredBB1 and PredBB2.
211 /// Note that PredBB1 and PredBB2 are decided in findPredicatedArgument(),
212 /// especially for the OR predicated case where PredBB1 will point the header,
213 /// and PredBB2 will point the the second compare block. CallInst1 and CallInst2
214 /// will be the new call-sites placed in the new predecessors split for PredBB1
215 /// and PredBB2, repectively. Therefore, CallInst1 will be the call-site placed
216 /// between Header and Tail, and CallInst2 will be the call-site between TBB and
217 /// Tail. For example, in the IR below with an OR condition, the call-site can
218 /// be split
219 ///
220 /// from :
221 ///
222 /// Header:
223 /// %c = icmp eq i32* %a, null
224 /// br i1 %c %Tail, %TBB
225 /// TBB:
226 /// %c2 = icmp eq i32* %b, null
227 /// br i1 %c %Tail, %End
228 /// Tail:
229 /// %ca = call i1 @callee (i32* %a, i32* %b)
230 ///
231 /// to :
232 ///
233 /// Header: // PredBB1 is Header
234 /// %c = icmp eq i32* %a, null
235 /// br i1 %c %Tail-split1, %TBB
236 /// TBB: // PredBB2 is TBB
237 /// %c2 = icmp eq i32* %b, null
238 /// br i1 %c %Tail-split2, %End
239 /// Tail-split1:
240 /// %ca1 = call @callee (i32* null, i32* %b) // CallInst1
241 /// br %Tail
242 /// Tail-split2:
243 /// %ca2 = call @callee (i32* nonnull %a, i32* null) // CallInst2
244 /// br %Tail
245 /// Tail:
246 /// %p = phi i1 [%ca1, %Tail-split1],[%ca2, %Tail-split2]
247 ///
248 /// Note that for an OR predicated case, CallInst1 and CallInst2 should be
249 /// created with more constrained arguments in
250 /// createCallSitesOnOrPredicatedArgument().
251 static void splitCallSite(CallSite CS, BasicBlock *PredBB1, BasicBlock *PredBB2,
252 Instruction *CallInst1, Instruction *CallInst2) {
253 Instruction *Instr = CS.getInstruction();
254 BasicBlock *TailBB = Instr->getParent();
255 assert(Instr == (TailBB->getFirstNonPHI()) && "Unexpected call-site");
256
257 BasicBlock *SplitBlock1 =
258 SplitBlockPredecessors(TailBB, PredBB1, ".predBB1.split");
259 BasicBlock *SplitBlock2 =
260 SplitBlockPredecessors(TailBB, PredBB2, ".predBB2.split");
261
262 assert((SplitBlock1 && SplitBlock2) && "Unexpected new basic block split.");
263
264 if (!CallInst1)
265 CallInst1 = Instr->clone();
266 if (!CallInst2)
267 CallInst2 = Instr->clone();
268
269 CallInst1->insertBefore(&*SplitBlock1->getFirstInsertionPt());
270 CallInst2->insertBefore(&*SplitBlock2->getFirstInsertionPt());
271
272 CallSite CS1(CallInst1);
273 CallSite CS2(CallInst2);
274
275 // Handle PHIs used as arguments in the call-site.
276 for (auto &PI : *TailBB) {
277 PHINode *PN = dyn_cast(&PI);
278 if (!PN)
279 break;
280 unsigned ArgNo = 0;
281 for (auto &CI : CS.args()) {
282 if (&*CI == PN) {
283 CS1.setArgument(ArgNo, PN->getIncomingValueForBlock(SplitBlock1));
284 CS2.setArgument(ArgNo, PN->getIncomingValueForBlock(SplitBlock2));
285 }
286 ++ArgNo;
287 }
288 }
289
290 // Replace users of the original call with a PHI mering call-sites split.
291 if (Instr->getNumUses()) {
292 PHINode *PN = PHINode::Create(Instr->getType(), 2, "phi.call", Instr);
293 PN->addIncoming(CallInst1, SplitBlock1);
294 PN->addIncoming(CallInst2, SplitBlock2);
295 Instr->replaceAllUsesWith(PN);
296 }
297 DEBUG(dbgs() << "split call-site : " << *Instr << " into \n");
298 DEBUG(dbgs() << " " << *CallInst1 << " in " << SplitBlock1->getName()
299 << "\n");
300 DEBUG(dbgs() << " " << *CallInst2 << " in " << SplitBlock2->getName()
301 << "\n");
302 Instr->eraseFromParent();
303 NumCallSiteSplit++;
304 }
305
306 static bool isCondRelevantToAnyCallArgument(ICmpInst *Cmp, CallSite CS) {
307 assert(isa(Cmp->getOperand(1)) && "Expected a constant operand.");
308 Value *Op0 = Cmp->getOperand(0);
309 unsigned ArgNo = 0;
310 for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E;
311 ++I, ++ArgNo) {
312 // Don't consider constant or arguments that are already known non-null.
313 if (isa(*I) || CS.paramHasAttr(ArgNo, Attribute::NonNull))
314 continue;
315
316 if (*I == Op0)
317 return true;
318 }
319 return false;
320 }
321
322 static void findOrCondRelevantToCallArgument(
323 CallSite CS, BasicBlock *PredBB, BasicBlock *OtherPredBB,
324 SmallVectorImpl &BranchInsts, BasicBlock *&HeaderBB) {
325 auto *PBI = dyn_cast(PredBB->getTerminator());
326 if (!PBI || !PBI->isConditional())
327 return;
328
329 if (PBI->getSuccessor(0) == OtherPredBB ||
330 PBI->getSuccessor(1) == OtherPredBB)
331 if (PredBB == OtherPredBB->getSinglePredecessor()) {
332 assert(!HeaderBB && "Expect to find only a single header block");
333 HeaderBB = PredBB;
334 }
335
336 CmpInst::Predicate Pred;
337 Value *Cond = PBI->getCondition();
338 if (!match(Cond, m_ICmp(Pred, m_Value(), m_Constant())))
339 return;
340 ICmpInst *Cmp = cast(Cond);
341 if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE)
342 if (isCondRelevantToAnyCallArgument(Cmp, CS))
343 BranchInsts.push_back(PBI);
344 }
345
346 // Return true if the call-site has an argument which is a PHI with only
347 // constant incoming values.
348 static bool isPredicatedOnPHI(CallSite CS) {
349 Instruction *Instr = CS.getInstruction();
350 BasicBlock *Parent = Instr->getParent();
351 if (Instr != Parent->getFirstNonPHI())
352 return false;
353
354 for (auto &BI : *Parent) {
355 if (PHINode *PN = dyn_cast(&BI)) {
356 for (auto &I : CS.args())
357 if (&*I == PN) {
358 assert(PN->getNumIncomingValues() == 2 &&
359 "Unexpected number of incoming values");
360 if (PN->getIncomingBlock(0) == PN->getIncomingBlock(1))
361 return false;
362 if (PN->getIncomingValue(0) == PN->getIncomingValue(1))
363 continue;
364 if (isa(PN->getIncomingValue(0)) &&
365 isa(PN->getIncomingValue(1)))
366 return true;
367 }
368 }
369 break;
370 }
371 return false;
372 }
373
374 // Return true if an agument in CS is predicated on an 'or' condition.
375 // Create new call-site with arguments constrained based on the OR condition.
376 static bool findPredicatedOnOrCondition(CallSite CS, BasicBlock *PredBB1,
377 BasicBlock *PredBB2,
378 Instruction *&NewCallTakenFromHeader,
379 Instruction *&NewCallTakenFromNextCond,
380 BasicBlock *&HeaderBB) {
381 SmallVector BranchInsts;
382 findOrCondRelevantToCallArgument(CS, PredBB1, PredBB2, BranchInsts, HeaderBB);
383 findOrCondRelevantToCallArgument(CS, PredBB2, PredBB1, BranchInsts, HeaderBB);
384 if (BranchInsts.empty() || !HeaderBB)
385 return false;
386
387 // If an OR condition is detected, try to create call sites with constrained
388 // arguments (e.g., NonNull attribute or constant value).
389 return createCallSitesOnOrPredicatedArgument(CS, NewCallTakenFromHeader,
390 NewCallTakenFromNextCond,
391 BranchInsts, HeaderBB);
392 }
393
394 static bool findPredicatedArgument(CallSite CS, Instruction *&CallInst1,
395 Instruction *&CallInst2,
396 BasicBlock *&PredBB1, BasicBlock *&PredBB2) {
397 BasicBlock *CallSiteBB = CS.getInstruction()->getParent();
398 pred_iterator PII = pred_begin(CallSiteBB);
399 pred_iterator PIE = pred_end(CallSiteBB);
400 assert(std::distance(PII, PIE) == 2 && "Expect only two predecessors.");
401 BasicBlock *Preds[2] = {*PII++, *PII};
402 BasicBlock *&HeaderBB = PredBB1;
403 if (!findPredicatedOnOrCondition(CS, Preds[0], Preds[1], CallInst1, CallInst2,
404 HeaderBB) &&
405 !isPredicatedOnPHI(CS))
406 return false;
407
408 if (!PredBB1)
409 PredBB1 = Preds[0];
410
411 PredBB2 = PredBB1 == Preds[0] ? Preds[1] : Preds[0];
412 return true;
413 }
414
415 static bool tryToSplitCallSite(CallSite CS) {
416 if (!CS.arg_size())
417 return false;
418
419 BasicBlock *PredBB1 = nullptr;
420 BasicBlock *PredBB2 = nullptr;
421 Instruction *CallInst1 = nullptr;
422 Instruction *CallInst2 = nullptr;
423 if (!canSplitCallSite(CS) ||
424 !findPredicatedArgument(CS, CallInst1, CallInst2, PredBB1, PredBB2)) {
425 assert(!CallInst1 && !CallInst2 && "Unexpected new call-sites cloned.");
426 return false;
427 }
428 splitCallSite(CS, PredBB1, PredBB2, CallInst1, CallInst2);
429 return true;
430 }
431
432 static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI) {
433 bool Changed = false;
434 for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE;) {
435 BasicBlock &BB = *BI++;
436 for (BasicBlock::iterator II = BB.begin(), IE = BB.end(); II != IE;) {
437 Instruction *I = &*II++;
438 CallSite CS(cast(I));
439 if (!CS || isa(I) || isInstructionTriviallyDead(I, &TLI))
440 continue;
441
442 Function *Callee = CS.getCalledFunction();
443 if (!Callee || Callee->isDeclaration())
444 continue;
445 Changed |= tryToSplitCallSite(CS);
446 }
447 }
448 return Changed;
449 }
450
451 namespace {
452 struct CallSiteSplittingLegacyPass : public FunctionPass {
453 static char ID;
454 CallSiteSplittingLegacyPass() : FunctionPass(ID) {
455 initializeCallSiteSplittingLegacyPassPass(*PassRegistry::getPassRegistry());
456 }
457
458 void getAnalysisUsage(AnalysisUsage &AU) const override {
459 AU.addRequired();
460 FunctionPass::getAnalysisUsage(AU);
461 }
462
463 bool runOnFunction(Function &F) override {
464 if (skipFunction(F))
465 return false;
466
467 auto &TLI = getAnalysis().getTLI();
468 return doCallSiteSplitting(F, TLI);
469 }
470 };
471 } // namespace
472
473 char CallSiteSplittingLegacyPass::ID = 0;
474 INITIALIZE_PASS_BEGIN(CallSiteSplittingLegacyPass, "callsite-splitting",
475 "Call-site splitting", false, false)
476 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
477 INITIALIZE_PASS_END(CallSiteSplittingLegacyPass, "callsite-splitting",
478 "Call-site splitting", false, false)
479 FunctionPass *llvm::createCallSiteSplittingPass() {
480 return new CallSiteSplittingLegacyPass();
481 }
482
483 PreservedAnalyses CallSiteSplittingPass::run(Function &F,
484 FunctionAnalysisManager &AM) {
485 auto &TLI = AM.getResult(F);
486
487 if (!doCallSiteSplitting(F, TLI))
488 return PreservedAnalyses::all();
489 PreservedAnalyses PA;
490 return PA;
491 }
3434 initializeADCELegacyPassPass(Registry);
3535 initializeBDCELegacyPassPass(Registry);
3636 initializeAlignmentFromAssumptionsPass(Registry);
37 initializeCallSiteSplittingLegacyPassPass(Registry);
3738 initializeConstantHoistingLegacyPassPass(Registry);
3839 initializeConstantPropagationPass(Registry);
3940 initializeCorrelatedValuePropagationPass(Registry);
7575 ; CHECK-O-NEXT: Running pass: EarlyCSEPass
7676 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
7777 ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass
78 ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass
7879 ; CHECK-O-NEXT: Finished llvm::Function pass manager run.
7980 ; CHECK-O-NEXT: Running pass: IPSCCPPass
8081 ; CHECK-O-NEXT: Running pass: CalledValuePropagationPass
2828 ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass
2929 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
3030 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
31 ; CHECK-O2-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}>
32 ; CHECK-O2-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Module
33 ; CHECK-O2-NEXT: Starting llvm::Function pass manager run.
34 ; CHECK-O2-NEXT: Running pass: CallSiteSplittingPass on foo
35 ; CHECK-O2-NEXT: Running analysis: TargetLibraryAnalysis on foo
36 ; CHECK-O2-NEXT: Finished llvm::Function pass manager run.
3137 ; CHECK-O2-NEXT: PGOIndirectCallPromotion
3238 ; CHECK-O2-NEXT: Running analysis: ProfileSummaryAnalysis
33 ; CHECK-O2-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Function
3439 ; CHECK-O2-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
3540 ; CHECK-O2-NEXT: Running pass: IPSCCPPass
3641 ; CHECK-O2-NEXT: Running pass: CalledValuePropagationPass
4146 ; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy
4247 ; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}>
4348 ; CHECK-O-NEXT: Running analysis: AAManager
44 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
49 ; CHECK-O1-NEXT: Running analysis: TargetLibraryAnalysis
4550 ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass
4651 ; CHECK-O-NEXT: Running analysis: CallGraphAnalysis
4752 ; CHECK-O-NEXT: Running pass: GlobalSplitPass
7171 ; CHECK-O-NEXT: Running pass: EarlyCSEPass
7272 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
7373 ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass
74 ; CHECK-O3-NEXT: Running pass: CallSiteSplittingPass
7475 ; CHECK-O-NEXT: Finished llvm::Function pass manager run.
7576 ; CHECK-O-NEXT: Running pass: IPSCCPPass
7677 ; CHECK-O-NEXT: Running pass: CalledValuePropagationPass
0 ; RUN: opt < %s -callsite-splitting -S | FileCheck %s
1 ; RUN: opt < %s -passes='function(callsite-splitting)' -S | FileCheck %s
2
3 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4 target triple = "aarch64-linaro-linux-gnueabi"
5
6 ;CHECK-LABEL: @test_eq_eq
7 ;CHECK-LABEL: Tail.predBB1.split:
8 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
9 ;CHECK-LABEL: Tail.predBB2.split:
10 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
11 ;CHECK-LABEL: Tail
12 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
13 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
14 ;CHECK: ret i32 %[[MERGED]]
15 define i32 @test_eq_eq(i32* %a, i32 %v) {
16 Header:
17 %tobool1 = icmp eq i32* %a, null
18 br i1 %tobool1, label %Tail, label %TBB
19
20 TBB:
21 %cmp = icmp eq i32 %v, 1
22 br i1 %cmp, label %Tail, label %End
23
24 Tail:
25 %p = phi i32[1,%Header], [2, %TBB]
26 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
27 ret i32 %r
28
29 End:
30 ret i32 %v
31 }
32
33 ;CHECK-LABEL: @test_ne_eq
34 ;CHECK-LABEL: Tail.predBB1.split:
35 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
36 ;CHECK-LABEL: Tail.predBB2.split:
37 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2)
38 ;CHECK-LABEL: Tail
39 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
40 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
41 ;CHECK: ret i32 %[[MERGED]]
42 define i32 @test_ne_eq(i32* %a, i32 %v) {
43 Header:
44 %tobool1 = icmp ne i32* %a, null
45 br i1 %tobool1, label %Tail, label %TBB
46
47 TBB:
48 %cmp = icmp eq i32 %v, 1
49 br i1 %cmp, label %Tail, label %End
50
51 Tail:
52 %p = phi i32[1,%Header], [2, %TBB]
53 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
54 ret i32 %r
55
56 End:
57 ret i32 %v
58 }
59
60 ;CHECK-LABEL: @test_ne_ne
61 ;CHECK-LABEL: Tail.predBB1.split:
62 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
63 ;CHECK-LABEL: Tail.predBB2.split:
64 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 %v, i32 2)
65 ;CHECK-LABEL: Tail
66 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
67 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
68 ;CHECK: ret i32 %[[MERGED]]
69 define i32 @test_ne_ne(i32* %a, i32 %v) {
70 Header:
71 %tobool1 = icmp ne i32* %a, null
72 br i1 %tobool1, label %Tail, label %TBB
73
74 TBB:
75 %cmp = icmp ne i32 %v, 1
76 br i1 %cmp, label %Tail, label %End
77
78 Tail:
79 %p = phi i32[1,%Header], [2, %TBB]
80 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
81 ret i32 %r
82
83 End:
84 ret i32 %v
85 }
86
87 ;CHECK-LABEL: @test_eq_eq_untaken
88 ;CHECK-LABEL: Tail.predBB1.split:
89 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* nonnull %a, i32 %v, i32 1)
90 ;CHECK-LABEL: Tail.predBB2.split:
91 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* null, i32 1, i32 2)
92 ;CHECK-LABEL: Tail
93 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
94 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
95 ;CHECK: ret i32 %[[MERGED]]
96 define i32 @test_eq_eq_untaken(i32* %a, i32 %v) {
97 Header:
98 %tobool1 = icmp eq i32* %a, null
99 br i1 %tobool1, label %TBB, label %Tail
100
101 TBB:
102 %cmp = icmp eq i32 %v, 1
103 br i1 %cmp, label %Tail, label %End
104
105 Tail:
106 %p = phi i32[1,%Header], [2, %TBB]
107 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
108 ret i32 %r
109
110 End:
111 ret i32 %v
112 }
113
114 ;CHECK-LABEL: @test_ne_eq_untaken
115 ;CHECK-LABEL: Tail.predBB1.split:
116 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
117 ;CHECK-LABEL: Tail.predBB2.split:
118 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
119 ;CHECK-LABEL: Tail
120 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
121 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
122 ;CHECK: ret i32 %[[MERGED]]
123 define i32 @test_ne_eq_untaken(i32* %a, i32 %v) {
124 Header:
125 %tobool1 = icmp ne i32* %a, null
126 br i1 %tobool1, label %TBB, label %Tail
127
128 TBB:
129 %cmp = icmp eq i32 %v, 1
130 br i1 %cmp, label %Tail, label %End
131
132 Tail:
133 %p = phi i32[1,%Header], [2, %TBB]
134 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
135 ret i32 %r
136
137 End:
138 ret i32 %v
139 }
140
141 ;CHECK-LABEL: @test_ne_ne_untaken
142 ;CHECK-LABEL: Tail.predBB1.split:
143 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* null, i32 %v, i32 1)
144 ;CHECK-LABEL: Tail.predBB2.split:
145 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* nonnull %a, i32 1, i32 2)
146 ;CHECK-LABEL: Tail
147 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
148 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
149 ;CHECK: ret i32 %[[MERGED]]
150 define i32 @test_ne_ne_untaken(i32* %a, i32 %v) {
151 Header:
152 %tobool1 = icmp ne i32* %a, null
153 br i1 %tobool1, label %TBB, label %Tail
154
155 TBB:
156 %cmp = icmp ne i32 %v, 1
157 br i1 %cmp, label %End, label %Tail
158
159 Tail:
160 %p = phi i32[1,%Header], [2, %TBB]
161 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
162 ret i32 %r
163
164 End:
165 ret i32 %v
166 }
167
168 ;CHECK-LABEL: @test_nonconst_const_phi
169 ;CHECK-LABEL: Tail.predBB1.split:
170 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
171 ;CHECK-LABEL: Tail.predBB2.split:
172 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 1, i32 2)
173 ;CHECK-LABEL: Tail
174 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
175 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
176 ;CHECK: ret i32 %[[MERGED]]
177 define i32 @test_nonconst_const_phi(i32* %a, i32* %b, i32 %v) {
178 Header:
179 %tobool1 = icmp eq i32* %a, %b
180 br i1 %tobool1, label %Tail, label %TBB
181
182 TBB:
183 %cmp = icmp eq i32 %v, 1
184 br i1 %cmp, label %Tail, label %End
185
186 Tail:
187 %p = phi i32[1,%Header], [2, %TBB]
188 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
189 ret i32 %r
190
191 End:
192 ret i32 %v
193 }
194
195 ;CHECK-LABEL: @test_nonconst_nonconst_phi
196 ;CHECK-LABEL: Tail.predBB1.split:
197 ;CHECK: %[[CALL1:.*]] = call i32 @callee(i32* %a, i32 %v, i32 1)
198 ;CHECK-LABEL: Tail.predBB2.split:
199 ;CHECK: %[[CALL2:.*]] = call i32 @callee(i32* %a, i32 %v, i32 2)
200 ;CHECK-LABEL: Tail
201 ;CHECK: %p = phi i32 [ 1, %Tail.predBB1.split ], [ 2, %Tail.predBB2.split ]
202 ;CHECK: %[[MERGED:.*]] = phi i32 [ %[[CALL1]], %Tail.predBB1.split ], [ %[[CALL2]], %Tail.predBB2.split ]
203 ;CHECK: ret i32 %[[MERGED]]
204 define i32 @test_nonconst_nonconst_phi(i32* %a, i32* %b, i32 %v, i32 %v2) {
205 Header:
206 %tobool1 = icmp eq i32* %a, %b
207 br i1 %tobool1, label %Tail, label %TBB
208
209 TBB:
210 %cmp = icmp eq i32 %v, %v2
211 br i1 %cmp, label %Tail, label %End
212
213 Tail:
214 %p = phi i32[1,%Header], [2, %TBB]
215 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
216 ret i32 %r
217
218 End:
219 ret i32 %v
220 }
221
222 ;CHECK-LABEL: @test_nonconst_nonconst_phi_noncost
223 ;CHECK-NOT: Tail.predBB1.split:
224 ;CHECK-NOT: Tail.predBB2.split:
225 ;CHECK-LABEL: Tail:
226 ;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
227 ;CHECK: ret i32 %r
228 define i32 @test_nonconst_nonconst_phi_noncost(i32* %a, i32* %b, i32 %v, i32 %v2) {
229 Header:
230 %tobool1 = icmp eq i32* %a, %b
231 br i1 %tobool1, label %Tail, label %TBB
232
233 TBB:
234 %cmp = icmp eq i32 %v, %v2
235 br i1 %cmp, label %Tail, label %End
236
237 Tail:
238 %p = phi i32[%v,%Header], [%v2, %TBB]
239 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
240 ret i32 %r
241
242 End:
243 ret i32 %v
244 }
245
246 ;CHECK-LABEL: @test_fisrtnonphi
247 ;CHECK-NOT: Tail.predBB1.split:
248 ;CHECK-NOT: Tail.predBB2.split:
249 ;CHECK-LABEL: Tail:
250 ;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
251 ;CHECK: ret i32 %r
252 define i32 @test_fisrtnonphi(i32* %a, i32 %v) {
253 Header:
254 %tobool1 = icmp eq i32* %a, null
255 br i1 %tobool1, label %Tail, label %TBB
256
257 TBB:
258 %cmp = icmp eq i32 %v, 1
259 br i1 %cmp, label %Tail, label %End
260
261 Tail:
262 %p = phi i32[1,%Header], [2, %TBB]
263 store i32 %v, i32* %a
264 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
265 ret i32 %r
266
267 End:
268 ret i32 %v
269 }
270
271 ;CHECK-LABEL: @test_3preds_constphi
272 ;CHECK-NOT: Tail.predBB1.split:
273 ;CHECK-NOT: Tail.predBB2.split:
274 ;CHECK-LABEL: Tail:
275 ;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
276 ;CHECK: ret i32 %r
277 define i32 @test_3preds_constphi(i32* %a, i32 %v, i1 %c1, i1 %c2, i1 %c3) {
278 Header:
279 br i1 %c1, label %Tail, label %TBB1
280
281 TBB1:
282 br i1 %c2, label %Tail, label %TBB2
283
284 TBB2:
285 br i1 %c3, label %Tail, label %End
286
287 Tail:
288 %p = phi i32[1,%Header], [2, %TBB1], [3, %TBB2]
289 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
290 ret i32 %r
291
292 End:
293 ret i32 %v
294 }
295
296 ;CHECK-LABEL: @test_indirectbr_phi
297 ;CHECK-NOT: Tail.predBB1.split:
298 ;CHECK-NOT: Tail.predBB2.split:
299 ;CHECK-LABEL: Tail:
300 ;CHECK: %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
301 ;CHECK: ret i32 %r
302 define i32 @test_indirectbr_phi(i8* %address, i32* %a, i32* %b, i32 %v) {
303 Header:
304 %indirect.goto.dest = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
305 indirectbr i8* %indirect.goto.dest, [label %TBB, label %Tail]
306
307 TBB:
308 %indirect.goto.dest2 = select i1 undef, i8* blockaddress(@test_indirectbr_phi, %End), i8* %address
309 indirectbr i8* %indirect.goto.dest2, [label %Tail, label %End]
310
311 Tail:
312 %p = phi i32[1,%Header], [2, %TBB]
313 %r = call i32 @callee(i32* %a, i32 %v, i32 %p)
314 ret i32 %r
315
316 End:
317 ret i32 %v
318 }
319
320 define i32 @callee(i32* %a, i32 %v, i32 %p) {
321 entry:
322 %c = icmp ne i32* %a, null
323 br i1 %c, label %BB1, label %BB2
324
325 BB1:
326 call void @dummy(i32* %a, i32 %p)
327 br label %End
328
329 BB2:
330 call void @dummy2(i32 %v, i32 %p)
331 br label %End
332
333 End:
334 ret i32 %p
335 }
336
337 declare void @dummy(i32*, i32)
338 declare void @dummy2(i32, i32)
0 ; RUN: opt < %s -callsite-splitting -inline -instcombine -jump-threading -S | FileCheck %s
1 ; RUN: opt < %s -passes='function(callsite-splitting),cgscc(inline),function(instcombine,jump-threading)' -S | FileCheck %s
2
3 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
4 target triple = "aarch64-linaro-linux-gnueabi"
5
6 %struct.bitmap = type { i32, %struct.bitmap* }
7
8 ;CHECK-LABEL: @caller
9 ;CHECK-LABEL: NextCond:
10 ;CHECK: br {{.*}} label %callee.exit
11 ;CHECK-LABEL: CallSiteBB.predBB1.split:
12 ;CHECK: call void @callee(%struct.bitmap* null, %struct.bitmap* null, %struct.bitmap* %b_elt, i1 false)
13 ;CHECK-LABEL: callee.exit:
14 ;CHECK: call void @dummy2(%struct.bitmap* %a_elt)
15
16 define void @caller(i1 %c, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt) {
17 entry:
18 br label %Top
19
20 Top:
21 %tobool1 = icmp eq %struct.bitmap* %a_elt, null
22 br i1 %tobool1, label %CallSiteBB, label %NextCond
23
24 NextCond:
25 %cmp = icmp ne %struct.bitmap* %b_elt, null
26 br i1 %cmp, label %CallSiteBB, label %End
27
28 CallSiteBB:
29 %p = phi i1 [0, %Top], [%c, %NextCond]
30 call void @callee(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, i1 %p)
31 br label %End
32
33 End:
34 ret void
35 }
36
37 define void @callee(%struct.bitmap* %dst_elt, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, i1 %c) {
38 entry:
39 %tobool = icmp ne %struct.bitmap* %a_elt, null
40 %tobool1 = icmp ne %struct.bitmap* %b_elt, null
41 %or.cond = and i1 %tobool, %tobool1
42 br i1 %or.cond, label %Cond, label %Big
43
44 Cond:
45 %cmp = icmp eq %struct.bitmap* %dst_elt, %a_elt
46 br i1 %cmp, label %Small, label %Big
47
48 Small:
49 call void @dummy2(%struct.bitmap* %a_elt)
50 br label %End
51
52 Big:
53 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
54 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
55 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
56 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
57 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
58 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
59 call void @dummy1(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %a_elt)
60 br label %End
61
62 End:
63 ret void
64 }
65
66 declare void @dummy2(%struct.bitmap*)
67 declare void @dummy1(%struct.bitmap*, %struct.bitmap*, %struct.bitmap*, %struct.bitmap*, %struct.bitmap*, %struct.bitmap*)
68
69
70 ;CHECK-LABEL: @caller2
71 ;CHECK-LABEL: CallSiteBB.predBB1.split:
72 ;CHECK: call void @dummy4()
73 ;CHECK-LABEL: CallSiteBB.predBB2.split:
74 ;CHECK: call void @dummy3()
75 ;CheCK-LABEL: CallSiteBB:
76 ;CHECK: %phi.call = phi i1 [ false, %CallSiteBB.predBB1.split ], [ true, %CallSiteBB.predBB2.split ]
77 ;CHECK: call void @foo(i1 %phi.call)
78 define void @caller2(i1 %c, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, %struct.bitmap* %c_elt) {
79 entry:
80 br label %Top
81
82 Top:
83 %tobool1 = icmp eq %struct.bitmap* %a_elt, %b_elt
84 br i1 %tobool1, label %CallSiteBB, label %NextCond
85
86 NextCond:
87 %cmp = icmp ne %struct.bitmap* %b_elt, %c_elt
88 br i1 %cmp, label %CallSiteBB, label %End
89
90 CallSiteBB:
91 %phi = phi i1 [0, %Top],[1, %NextCond]
92 %u = call i1 @callee2(i1 %phi)
93 call void @foo(i1 %u)
94 br label %End
95
96 End:
97 ret void
98 }
99
100 define i1 @callee2(i1 %b) {
101 entry:
102 br i1 %b, label %BB1, label %BB2
103
104 BB1:
105 call void @dummy3()
106 br label %End
107
108 BB2:
109 call void @dummy4()
110 br label %End
111
112 End:
113 ret i1 %b
114 }
115
116 declare void @dummy3()
117 declare void @dummy4()
118 declare void @foo(i1)