llvm.org GIT mirror
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).
 338 338 } 339 339 } 340 340 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) 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 371 341 typedef std::pair RepeatedValue; 372 342 373 343 /// LinearizeExprTree - Given an associative binary expression, return the leaf 381 351 /// op 382 352 /// (Ops[N].first op Ops[N].first op ... Ops[N].first) <- Ops[N].second times 383 353 /// 384 /// Note that the values Ops.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.first, ..., Ops[N].first are all distinct.⏎ 387 355 /// 388 356 /// This routine may modify the function, in which case it returns 'true'. The 389 357 /// changes it makes may well be destructive, changing the value computed by 'I' 603 571 604 572 // The leaves, repeated according to their weights, represent the linearized 605 573 // form of the expression. 606 Constant *Cst = 0; // Accumulate constants here. 607 574 for (unsigned i = 0, e = LeafOrder.size(); i != e; ++i) { 608 575 Value *V = LeafOrder[i]; 609 576 LeafMap::iterator It = Leaves.find(V); 617 584 continue; 618 585 // Ensure the leaf is only output once. 619 586 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 627 587 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))); 639 588 } 640 589 641 590 // For nilpotent operations or addition there may be no operands, for example 642 591 // because the expression was "X xor X" or consisted of 2^Bitwidth additions: 643 592 // in both cases the weight reduces to 0 causing the value to be skipped. 644 593 if (Ops.empty()) { 594 Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType()); 645 595 assert(Identity && "Associative operation without identity!"); 646 596 Ops.push_back(std::make_pair(Identity, APInt(Bitwidth, 1))); 647 597 } 1445 1395 SmallVectorImpl &Ops) { 1446 1396 // Now that we have the linearized expression tree, try to optimize it. 1447 1397 // 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 1448 1417 if (Ops.size() == 1) return Ops.Op; 1449 1450 unsigned Opcode = I->getOpcode(); 1451 1418 1452 1419 // Handle destructive annihilation due to identities between elements in the 1453 1420 // argument list here.
 143 143 %t6 = add i32 %t4, %t5 144 144 ret i32 %t6 145 145 } 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 }