From ef2aa193d60a4082a9cefb780db1ba9f73dc15f0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Oct 2006 00:36:21 +0000 Subject: [PATCH] Revert back to r1.21, which was the last revision of predsimplify that passes llvm-gcc bootstrap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31146 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/PredicateSimplifier.cpp | 243 ++++++++---------- 1 file changed, 109 insertions(+), 134 deletions(-) diff --git a/lib/Transforms/Scalar/PredicateSimplifier.cpp b/lib/Transforms/Scalar/PredicateSimplifier.cpp index c91642fd136..4d86f6aa46c 100644 --- a/lib/Transforms/Scalar/PredicateSimplifier.cpp +++ b/lib/Transforms/Scalar/PredicateSimplifier.cpp @@ -41,7 +41,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/InstVisitor.h" #include -#include using namespace llvm; typedef DominatorTree::Node DTNodeType; @@ -75,14 +74,14 @@ namespace { return leaders.empty(); } - iterator findLeader(ElemTy &e) { + iterator findLeader(ElemTy e) { typename std::map::iterator MI = mapping.find(e); if (MI == mapping.end()) return 0; return MI->second; } - const_iterator findLeader(ElemTy &e) const { + const_iterator findLeader(ElemTy e) const { typename std::map::const_iterator MI = mapping.find(e); if (MI == mapping.end()) return 0; @@ -117,11 +116,6 @@ namespace { // Mutators - void remove(ElemTy &e) { - ElemTy E = e; // The parameter to erase must not be a reference to - mapping.erase(E); // an element contained in the map. - } - /// Combine two sets referring to the same element, inserting the /// elements as needed. Returns a valid iterator iff two already /// existing disjoint synonym sets were combined. The iterator @@ -130,7 +124,7 @@ namespace { /// Returns an iterator pointing to the synonym set containing /// element e. If none exists, a new one is created and returned. - iterator findOrInsert(ElemTy &e) { + iterator findOrInsert(ElemTy e) { iterator I = findLeader(e); if (I) return I; @@ -209,19 +203,6 @@ namespace { return union_find.empty(); } - void remove(Value *V) { - SynonymIterator I = union_find.findLeader(V); - if (!I) return; - - union_find.remove(V); - - for (PropertyIterator PI = Properties.begin(), PE = Properties.end(); - PI != PE;) { - Property &P = *PI++; - if (P.I1 == I || P.I2 == I) Properties.erase(PI); - } - } - void addEqual(Value *V1, Value *V2) { // If %x = 0. and %y = -0., seteq %x, %y is true, but // copysign(%x) is not the same as copysign(%y). @@ -230,10 +211,6 @@ namespace { order(V1, V2); if (isa(V2)) return; // refuse to set false == true. - if (union_find.findLeader(V1) && - union_find.findLeader(V1) == union_find.findLeader(V2)) - return; // no-op - SynonymIterator deleted = union_find.unionSets(V1, V2); if (deleted) { SynonymIterator replacement = union_find.findLeader(V1); @@ -257,7 +234,7 @@ namespace { if (isa(V1) && isa(V2)) return; if (findProperty(NE, V1, V2) != Properties.end()) - return; // no-op. + return; // found. // Add the property. SynonymIterator I1 = union_find.findOrInsert(V1), @@ -331,73 +308,6 @@ namespace { } } - void addToResolve(Value *V, std::list &WorkList) { - if (!isa(V) && !isa(V)) { - for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); - UI != UE; ++UI) { - if (!isa(*UI) && !isa(*UI)) { - WorkList.push_back(*UI); - } - } - } - } - - void resolve(std::list &WorkList) { - if (WorkList.empty()) return; - - Value *V = WorkList.front(); - WorkList.pop_front(); - - if (empty()) return; - - Instruction *I = dyn_cast(V); - if (!I) return; - - if (BinaryOperator *BO = dyn_cast(I)) { - Value *lhs = canonicalize(BO->getOperand(0)), - *rhs = canonicalize(BO->getOperand(1)); - - ConstantIntegral *CI1 = dyn_cast(lhs), - *CI2 = dyn_cast(rhs); - - if (CI1 && CI2) { - addToResolve(BO, WorkList); - addEqual(BO, ConstantExpr::get(BO->getOpcode(), CI1, CI2)); - } else if (SetCondInst *SCI = dyn_cast(BO)) { - PropertySet::ConstPropertyIterator NE = - findProperty(PropertySet::NE, lhs, rhs); - - if (NE != Properties.end()) { - switch (SCI->getOpcode()) { - case Instruction::SetEQ: - addToResolve(SCI, WorkList); - addEqual(SCI, ConstantBool::getFalse()); - break; - case Instruction::SetNE: - addToResolve(SCI, WorkList); - addEqual(SCI, ConstantBool::getTrue()); - break; - case Instruction::SetLE: - case Instruction::SetGE: - case Instruction::SetLT: - case Instruction::SetGT: - break; - default: - assert(0 && "Unknown opcode in SetCondInst."); - break; - } - } - } - } else if (SelectInst *SI = dyn_cast(I)) { - Value *Condition = canonicalize(SI->getCondition()); - if (ConstantBool *CB = dyn_cast(Condition)) { - addToResolve(SI, WorkList); - addEqual(SI, CB->getValue() ? SI->getTrueValue() : SI->getFalseValue()); - } - } - if (!WorkList.empty()) resolve(WorkList); - } - // Finds the properties implied by an equivalence and adds them too. // Example: ("seteq %a, %b", true, EQ) --> (%a, %b, EQ) // ("seteq %a, %b", false, EQ) --> (%a, %b, NE) @@ -424,45 +334,32 @@ namespace { if (V1 == ConstantBool::getFalse()) add(Opcode, BO->getOperand(0), BO->getOperand(1), true); break; - case Instruction::And: { - ConstantIntegral *CI = dyn_cast(V1); - if (CI && CI->isAllOnesValue()) { + case Instruction::And: + if (V1 == ConstantBool::getTrue()) { add(Opcode, V1, BO->getOperand(0), false); add(Opcode, V1, BO->getOperand(1), false); } - } break; - case Instruction::Or: { - ConstantIntegral *CI = dyn_cast(V1); - if (CI && CI->isNullValue()) { + break; + case Instruction::Or: + if (V1 == ConstantBool::getFalse()) { add(Opcode, V1, BO->getOperand(0), false); add(Opcode, V1, BO->getOperand(1), false); } - } break; - case Instruction::Xor: { - if (ConstantIntegral *CI = dyn_cast(V1)) { - const Type *Ty = BO->getType(); - if (CI->isAllOnesValue()) { - if (BO->getOperand(0) == V1) - add(Opcode, Constant::getNullValue(Ty), - BO->getOperand(1), false); - if (BO->getOperand(1) == V1) - add(Opcode, Constant::getNullValue(Ty), - BO->getOperand(0), false); - } - if (CI->isNullValue()) { - ConstantIntegral *Op0 = - dyn_cast(BO->getOperand(0)); - ConstantIntegral *Op1 = - dyn_cast(BO->getOperand(1)); - if (Op0 && Op0->isAllOnesValue()) - add(Opcode, ConstantIntegral::getAllOnesValue(Ty), - BO->getOperand(1), false); - if (Op1 && Op1->isAllOnesValue()) - add(Opcode, ConstantIntegral::getAllOnesValue(Ty), - BO->getOperand(0), false); - } + break; + case Instruction::Xor: + if (V1 == ConstantBool::getTrue()) { + if (BO->getOperand(0) == V1) + add(Opcode, ConstantBool::getFalse(), BO->getOperand(1), false); + if (BO->getOperand(1) == V1) + add(Opcode, ConstantBool::getFalse(), BO->getOperand(0), false); } - } break; + if (V1 == ConstantBool::getFalse()) { + if (BO->getOperand(0) == ConstantBool::getTrue()) + add(Opcode, ConstantBool::getTrue(), BO->getOperand(1), false); + if (BO->getOperand(1) == ConstantBool::getTrue()) + add(Opcode, ConstantBool::getTrue(), BO->getOperand(0), false); + } + break; default: break; } @@ -479,11 +376,6 @@ namespace { else if (Opcode == EQ) assert("Result of select not equal to either value."); } - - std::list WorkList; - addToResolve(V1, WorkList); - addToResolve(V2, WorkList); - resolve(WorkList); } DominatorTree *DT; @@ -514,6 +406,26 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const; private: + /// Backwards - Try to replace the Use of the instruction with + /// something simpler. This resolves a value by walking backwards + /// through its definition and the operands of that definition to + /// see if any values can now be solved for with the properties + /// that are in effect now, but weren't at definition time. + class Backwards : public InstVisitor { + friend class InstVisitor; + const PropertySet &KP; + + Value &visitSetCondInst(SetCondInst &SCI); + Value &visitBinaryOperator(BinaryOperator &BO); + Value &visitSelectInst(SelectInst &SI); + Value &visitInstruction(Instruction &I); + + public: + explicit Backwards(const PropertySet &KP) : KP(KP) {} + + Value *resolve(Value *V); + }; + /// Forwards - Adds new properties into PropertySet and uses them to /// simplify instructions. Because new properties sometimes apply to /// a transition from one BasicBlock to another, this will use the @@ -628,6 +540,69 @@ void PredicateSimplifier::getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreservedID(BreakCriticalEdgesID); } +Value &PredicateSimplifier::Backwards::visitSetCondInst(SetCondInst &SCI) { + Value &vBO = visitBinaryOperator(SCI); + if (&vBO != &SCI) return vBO; + + Value *SCI0 = resolve(SCI.getOperand(0)), + *SCI1 = resolve(SCI.getOperand(1)); + + PropertySet::ConstPropertyIterator NE = + KP.findProperty(PropertySet::NE, SCI0, SCI1); + + if (NE != KP.Properties.end()) { + switch (SCI.getOpcode()) { + case Instruction::SetEQ: return *ConstantBool::getFalse(); + case Instruction::SetNE: return *ConstantBool::getTrue(); + case Instruction::SetLE: + case Instruction::SetGE: + case Instruction::SetLT: + case Instruction::SetGT: + break; + default: + assert(0 && "Unknown opcode in SetCondInst."); + break; + } + } + return SCI; +} + +Value &PredicateSimplifier::Backwards::visitBinaryOperator(BinaryOperator &BO) { + Value *V = KP.canonicalize(&BO); + if (V != &BO) return *V; + + Value *lhs = resolve(BO.getOperand(0)), + *rhs = resolve(BO.getOperand(1)); + + ConstantIntegral *CI1 = dyn_cast(lhs), + *CI2 = dyn_cast(rhs); + + if (CI1 && CI2) return *ConstantExpr::get(BO.getOpcode(), CI1, CI2); + + return BO; +} + +Value &PredicateSimplifier::Backwards::visitSelectInst(SelectInst &SI) { + Value *V = KP.canonicalize(&SI); + if (V != &SI) return *V; + + Value *Condition = resolve(SI.getCondition()); + if (ConstantBool *CB = dyn_cast(Condition)) + return *resolve(CB->getValue() ? SI.getTrueValue() : SI.getFalseValue()); + return SI; +} + +Value &PredicateSimplifier::Backwards::visitInstruction(Instruction &I) { + return *KP.canonicalize(&I); +} + +Value *PredicateSimplifier::Backwards::resolve(Value *V) { + if (isa(V) || isa(V) || KP.empty()) return V; + + if (Instruction *I = dyn_cast(V)) return &visit(*I); + return KP.canonicalize(V); +} + void PredicateSimplifier::visitBasicBlock(BasicBlock *BB, PropertySet &KnownProperties) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) { @@ -638,12 +613,12 @@ void PredicateSimplifier::visitBasicBlock(BasicBlock *BB, void PredicateSimplifier::visitInstruction(Instruction *I, PropertySet &KnownProperties) { // Try to replace the whole instruction. - Value *V = KnownProperties.canonicalize(I); + Backwards resolve(KnownProperties); + Value *V = resolve.resolve(I); if (V != I) { modified = true; ++NumInstruction; DEBUG(std::cerr << "Removing " << *I); - KnownProperties.remove(I); I->replaceAllUsesWith(V); I->eraseFromParent(); return; @@ -652,7 +627,7 @@ void PredicateSimplifier::visitInstruction(Instruction *I, // Try to substitute operands. for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { Value *Oper = I->getOperand(i); - Value *V = KnownProperties.canonicalize(Oper); + Value *V = resolve.resolve(Oper); if (V != Oper) { modified = true; ++NumVarsReplaced;