llvm.org GIT mirror llvm / b30ce3e
Merging r168035: into 3.2 release branch. Fix a crash observed by Shuxin Yang. The issue here is that LinearizeExprTree, the utility for extracting a chain of operations from the IR, thought that it might as well combine any constants it came across (rather than just returning them along with everything else). On the other hand, the factorization code would like to see the individual constants (this is quite reasonable: it is much easier to pull a factor of 3 out of 2*3 than it is to pull it out of 6; you may think 6/3 isn't so hard, but due to overflow it's not as easy to undo multiplications of constants as it may at first appear). This patch therefore makes LinearizeExprTree stupider: it now leaves optimizing to the optimization part of reassociate, and sticks to just analysing the IR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168446 91177308-0d34-0410-b5e6-96231b3b80d8 Pawel Wodnicki 6 years ago
2 changed file(s) with 30 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
338338 }
339339 }
340340
341 /// EvaluateRepeatedConstant - Compute C op C op ... op C where the constant C
342 /// is repeated Weight times.
343 static Constant *EvaluateRepeatedConstant(unsigned Opcode, Constant *C,
344 APInt Weight) {
345 // For addition the result can be efficiently computed as the product of the
346 // constant and the weight.
347 if (Opcode == Instruction::Add)
348 return ConstantExpr::getMul(C, ConstantInt::get(C->getContext(), Weight));
349
350 // The weight might be huge, so compute by repeated squaring to ensure that
351 // compile time is proportional to the logarithm of the weight.
352 Constant *Result = 0;
353 Constant *Power = C; // Successively C, C op C, (C op C) op (C op C) etc.
354 // Visit the bits in Weight.
355 while (Weight != 0) {
356 // If the current bit in Weight is non-zero do Result = Result op Power.
357 if (Weight[0])
358 Result = Result ? ConstantExpr::get(Opcode, Result, Power) : Power;
359 // Move on to the next bit if any more are non-zero.
360 Weight = Weight.lshr(1);
361 if (Weight.isMinValue())
362 break;
363 // Square the power.
364 Power = ConstantExpr::get(Opcode, Power, Power);
365 }
366
367 assert(Result && "Only positive weights supported!");
368 return Result;
369 }
370
371341 typedef std::pair RepeatedValue;
372342
373343 /// LinearizeExprTree - Given an associative binary expression, return the leaf
381351 /// op
382352 /// (Ops[N].first op Ops[N].first op ... Ops[N].first) <- Ops[N].second times
383353 ///
384 /// Note that the values Ops[0].first, ..., Ops[N].first are all distinct, and
385 /// they are all non-constant except possibly for the last one, which if it is
386 /// constant will have weight one (Ops[N].second === 1).
354 /// Note that the values Ops[0].first, ..., Ops[N].first are all distinct.
387355 ///
388356 /// This routine may modify the function, in which case it returns 'true'. The
389357 /// changes it makes may well be destructive, changing the value computed by 'I'
603571
604572 // The leaves, repeated according to their weights, represent the linearized
605573 // form of the expression.
606 Constant *Cst = 0; // Accumulate constants here.
607574 for (unsigned i = 0, e = LeafOrder.size(); i != e; ++i) {
608575 Value *V = LeafOrder[i];
609576 LeafMap::iterator It = Leaves.find(V);
617584 continue;
618585 // Ensure the leaf is only output once.
619586 It->second = 0;
620 // Glob all constants together into Cst.
621 if (Constant *C = dyn_cast(V)) {
622 C = EvaluateRepeatedConstant(Opcode, C, Weight);
623 Cst = Cst ? ConstantExpr::get(Opcode, Cst, C) : C;
624 continue;
625 }
626 // Add non-constant
627587 Ops.push_back(std::make_pair(V, Weight));
628 }
629
630 // Add any constants back into Ops, all globbed together and reduced to having
631 // weight 1 for the convenience of users.
632 Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType());
633 if (Cst && Cst != Identity) {
634 // If combining multiple constants resulted in the absorber then the entire
635 // expression must evaluate to the absorber.
636 if (Cst == Absorber)
637 Ops.clear();
638 Ops.push_back(std::make_pair(Cst, APInt(Bitwidth, 1)));
639588 }
640589
641590 // For nilpotent operations or addition there may be no operands, for example
642591 // because the expression was "X xor X" or consisted of 2^Bitwidth additions:
643592 // in both cases the weight reduces to 0 causing the value to be skipped.
644593 if (Ops.empty()) {
594 Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType());
645595 assert(Identity && "Associative operation without identity!");
646596 Ops.push_back(std::make_pair(Identity, APInt(Bitwidth, 1)));
647597 }
14451395 SmallVectorImpl &Ops) {
14461396 // Now that we have the linearized expression tree, try to optimize it.
14471397 // Start by folding any constants that we found.
1398 Constant *Cst = 0;
1399 unsigned Opcode = I->getOpcode();
1400 while (!Ops.empty() && isa(Ops.back().Op)) {
1401 Constant *C = cast(Ops.pop_back_val().Op);
1402 Cst = Cst ? ConstantExpr::get(Opcode, C, Cst) : C;
1403 }
1404 // If there was nothing but constants then we are done.
1405 if (Ops.empty())
1406 return Cst;
1407
1408 // Put the combined constant back at the end of the operand list, except if
1409 // there is no point. For example, an add of 0 gets dropped here, while a
1410 // multiplication by zero turns the whole expression into zero.
1411 if (Cst && Cst != ConstantExpr::getBinOpIdentity(Opcode, I->getType())) {
1412 if (Cst == ConstantExpr::getBinOpAbsorber(Opcode, I->getType()))
1413 return Cst;
1414 Ops.push_back(ValueEntry(0, Cst));
1415 }
1416
14481417 if (Ops.size() == 1) return Ops[0].Op;
1449
1450 unsigned Opcode = I->getOpcode();
14511418
14521419 // Handle destructive annihilation due to identities between elements in the
14531420 // argument list here.
143143 %t6 = add i32 %t4, %t5
144144 ret i32 %t6
145145 }
146
147 define i32 @bar(i32 %arg, i32 %arg1, i32 %arg2) {
148 %tmp1 = mul i32 %arg1, 2
149 %tmp2 = mul i32 %tmp1, 3
150 %tmp3 = mul i32 %arg2, 2
151 %tmp4 = add i32 %tmp1, 1 ; dead code
152 %ret = add i32 %tmp2, %tmp3
153 ret i32 %ret
154 }