diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-05-08 00:08:33 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-05-08 00:08:33 +0000 | 
| commit | 6e2086d7e49778a3b05227601fec762ec7a265cd (patch) | |
| tree | 6ba957e0c33b9174ed91a0deeb2db6f75a097920 /llvm/lib/Transforms | |
| parent | 4294cec0f1575232c99efcd13a2ed87015744864 (diff) | |
| download | bcm5719-llvm-6e2086d7e49778a3b05227601fec762ec7a265cd.tar.gz bcm5719-llvm-6e2086d7e49778a3b05227601fec762ec7a265cd.zip | |
Handle some simple cases where we can see that values get annihilated.
llvm-svn: 21771
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 49 | 
1 files changed, 42 insertions, 7 deletions
| diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 341cac64c77..0e55ec1ddf4 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -113,10 +113,16 @@ unsigned Reassociate::getRank(Value *V) {         i != e && Rank != MaxRank; ++i)      Rank = std::max(Rank, getRank(I->getOperand(i))); +  // If this is a not or neg instruction, do not count it for rank.  This +  // assures us that X and ~X will have the same rank. +  if (!I->getType()->isIntegral() || +      (!BinaryOperator::isNot(I) && !BinaryOperator::isNeg(I))) +    ++Rank; +    DEBUG(std::cerr << "Calculated Rank[" << V->getName() << "] = " -        << Rank+1 << "\n"); +        << Rank << "\n"); -  return CachedRank = Rank+1; +  return CachedRank = Rank;  }  /// isReassociableOp - Return true if V is an instruction of the specified @@ -388,11 +394,40 @@ void Reassociate::ReassociateBB(BasicBlock *BB) {            goto FoldConstants;          } -    // FIXME: Handle destructive annihilation here.  Ensure RANK(neg(x)) == -    // RANK(x) [and not].  Handle case when Cst = 0 and op = AND f.e. - -    // FIXME: Handle +0,*1,&~0,... at end of the list. - +    // Check for destructive annihilation due to a constant being used. +    if (Ops.size() != 1) {  // Nothing to annihilate? +      if (ConstantIntegral *CstVal = dyn_cast<ConstantIntegral>(Ops.back().Op)) +        switch (I->getOpcode()) { +        default: break; +        case Instruction::And: +          if (CstVal->isNullValue()) {           // ... & 0 -> 0 +            Ops[0].Op = CstVal; +            Ops.erase(Ops.begin()+1, Ops.end()); +          } else if (CstVal->isAllOnesValue()) { // ... & -1 -> ... +            Ops.pop_back(); +          } +          break; +        case Instruction::Mul: +          if (CstVal->isNullValue()) {           // ... * 0 -> 0 +            Ops[0].Op = CstVal; +            Ops.erase(Ops.begin()+1, Ops.end()); +          } else if (cast<ConstantInt>(CstVal)->getRawValue() == 1) { +            Ops.pop_back();                      // ... * 1 -> ... +          } +          break; +        case Instruction::Or: +          if (CstVal->isAllOnesValue()) {        // ... | -1 -> -1 +            Ops[0].Op = CstVal; +            Ops.erase(Ops.begin()+1, Ops.end()); +          } +          // FALLTHROUGH! +        case Instruction::Add: +        case Instruction::Xor: +          if (CstVal->isNullValue())             // ... [|^+] 0 -> ... +            Ops.pop_back(); +          break; +        } +    }      if (Ops.size() == 1) {        // This expression tree simplified to something that isn't a tree, | 

