From cc8a2b98f28c10d93f45489b8c6f0c8b8205bb3b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 8 May 2005 00:08:33 +0000 Subject: [PATCH] Handle some simple cases where we can see that values get annihilated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21771 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/Reassociate.cpp | 49 +++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 341cac64c77..0e55ec1ddf4 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/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(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(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, -- 2.34.1