llvm.org GIT mirror llvm / 6977e79
Support pointer comparisons against constants, when looking at the inline-cost savings from a pointer argument becoming an alloca. Sometimes callees will even compare a pointer to null and then branch to an otherwise unreachable block! Detect these cases and compute the number of saved instructions, instead of bailing out and reporting no savings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148941 91177308-0d34-0410-b5e6-96231b3b80d8 Nick Lewycky 7 years ago
2 changed file(s) with 94 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
220220 unsigned CodeMetrics::CountCodeReductionForAlloca(Value *V) {
221221 if (!V->getType()->isPointerTy()) return 0; // Not a pointer
222222 unsigned Reduction = 0;
223
224 // Looking at ICmpInsts will never abort the analysis and return zero, and
225 // analyzing them is expensive, so save them for last so that we don't do
226 // extra work that we end up throwing out.
227 SmallVector ICmpInsts;
223228
224229 SmallVector Worklist;
225230 Worklist.push_back(V);
270275 case Intrinsic::memmove:
271276 case Intrinsic::lifetime_start:
272277 case Intrinsic::lifetime_end:
273 // SROA can usually chew through these intrinsics.
278 // SROA can usually chew through these intrinsics.
274279 Reduction += InlineConstants::InstrCost;
275280 break;
276281 }
282 } else if (ICmpInst *ICI = dyn_cast(I)) {
283 if (!isa(ICI->getOperand(1)))
284 return 0;
285 ICmpInsts.push_back(ICI);
277286 } else {
278287 // If there is some other strange instruction, we're not going to be
279288 // able to do much if we inline this.
281290 }
282291 }
283292 } while (!Worklist.empty());
293
294 while (!ICmpInsts.empty()) {
295 ICmpInst *ICI = ICmpInsts.pop_back_val();
296
297 // An icmp pred (alloca, C) becomes true if the predicate is true when
298 // equal and false otherwise.
299 bool Result = ICI->isTrueWhenEqual();
300
301 SmallVector Worklist;
302 Worklist.push_back(ICI);
303 do {
304 Instruction *U = Worklist.pop_back_val();
305 Reduction += InlineConstants::InstrCost;
306 for (Value::use_iterator UI = U->use_begin(), UE = U->use_end();
307 UI != UE; ++UI) {
308 Instruction *I = dyn_cast(*UI);
309 if (!I || I->mayHaveSideEffects()) continue;
310 if (I->getNumOperands() == 1)
311 Worklist.push_back(I);
312 if (BinaryOperator *BO = dyn_cast(I)) {
313 // If BO produces the same value as U, then the other operand is
314 // irrelevant and we can put it into the Worklist to continue
315 // deleting dead instructions. If BO produces the same value as the
316 // other operand, we can delete BO but that's it.
317 if (Result == true) {
318 if (BO->getOpcode() == Instruction::Or)
319 Worklist.push_back(I);
320 if (BO->getOpcode() == Instruction::And)
321 Reduction += InlineConstants::InstrCost;
322 } else {
323 if (BO->getOpcode() == Instruction::Or ||
324 BO->getOpcode() == Instruction::Xor)
325 Reduction += InlineConstants::InstrCost;
326 if (BO->getOpcode() == Instruction::And)
327 Worklist.push_back(I);
328 }
329 }
330 if (BranchInst *BI = dyn_cast(I)) {
331 BasicBlock *BB = BI->getSuccessor(Result ? 0 : 1);
332 if (BB->getSinglePredecessor())
333 Reduction += InlineConstants::InstrCost * BB->size();
334 }
335 }
336 } while (!Worklist.empty());
337 }
284338
285339 return Reduction;
286340 }
4141 call void @llvm.lifetime.start(i64 0, i8* %E)
4242 ret void
4343 }
44
45 define void @outer3() {
46 ; CHECK: @outer3
47 ; CHECK-NOT: call void @inner3
48 %ptr = alloca i32
49 call void @inner3(i32* %ptr, i1 undef)
50 ret void
51 }
52
53 define void @inner3(i32 *%ptr, i1 %x) {
54 %A = icmp eq i32* %ptr, null
55 %B = and i1 %x, %A
56 br i1 %A, label %bb.true, label %bb.false
57 bb.true:
58 ; This block musn't be counted in the inline cost.
59 %t1 = load i32* %ptr
60 %t2 = add i32 %t1, 1
61 %t3 = add i32 %t2, 1
62 %t4 = add i32 %t3, 1
63 %t5 = add i32 %t4, 1
64 %t6 = add i32 %t5, 1
65 %t7 = add i32 %t6, 1
66 %t8 = add i32 %t7, 1
67 %t9 = add i32 %t8, 1
68 %t10 = add i32 %t9, 1
69 %t11 = add i32 %t10, 1
70 %t12 = add i32 %t11, 1
71 %t13 = add i32 %t12, 1
72 %t14 = add i32 %t13, 1
73 %t15 = add i32 %t14, 1
74 %t16 = add i32 %t15, 1
75 %t17 = add i32 %t16, 1
76 %t18 = add i32 %t17, 1
77 %t19 = add i32 %t18, 1
78 %t20 = add i32 %t19, 1
79 ret void
80 bb.false:
81 ret void
82 }