Changes in directory llvm/lib/Transforms/Scalar:
GVNPRE.cpp updated: 1.27 -> 1.28 --- Log message: Perform PRE of comparison operators. --- Diffs of the changes: (+155 -24) GVNPRE.cpp | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 155 insertions(+), 24 deletions(-) Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.27 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.28 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.27 Fri Jun 8 17:02:36 2007 +++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Sat Jun 9 13:35:31 2007 @@ -39,20 +39,43 @@ struct ExprLT { bool operator()(Value* left, Value* right) { - if (!isa<BinaryOperator>(left) || !isa<BinaryOperator>(right)) + if (BinaryOperator* leftBO = dyn_cast<BinaryOperator>(left)) { + if (BinaryOperator* rightBO = dyn_cast<BinaryOperator>(right)) + return cmpBinaryOperator(leftBO, rightBO); + else + return left < right; + } else if (CmpInst* leftCmp = dyn_cast<CmpInst>(left)) { + if (CmpInst* rightCmp = dyn_cast<CmpInst>(right)) + return cmpComparison(leftCmp, rightCmp); + else + return left < right; + } else { return left < right; - - BinaryOperator* BO1 = cast<BinaryOperator>(left); - BinaryOperator* BO2 = cast<BinaryOperator>(right); - - if (BO1->getOpcode() != BO2->getOpcode()) - return BO1->getOpcode() < BO2->getOpcode(); - else if ((*this)(BO1->getOperand(0), BO2->getOperand(0))) + } + } + + bool cmpBinaryOperator(BinaryOperator* left, BinaryOperator* right) { + if (left->getOpcode() != right->getOpcode()) + return left->getOpcode() < right->getOpcode(); + else if ((*this)(left->getOperand(0), right->getOperand(0))) + return true; + else if ((*this)(right->getOperand(0), left->getOperand(0))) + return false; + else + return (*this)(left->getOperand(1), right->getOperand(1)); + } + + bool cmpComparison(CmpInst* left, CmpInst* right) { + if (left->getOpcode() != right->getOpcode()) + return left->getOpcode() < right->getOpcode(); + else if (left->getPredicate() != right->getPredicate()) + return left->getPredicate() < right->getPredicate(); + else if ((*this)(left->getOperand(0), right->getOperand(0))) return true; - else if ((*this)(BO2->getOperand(0), BO1->getOperand(0))) + else if ((*this)(right->getOperand(0), left->getOperand(0))) return false; else - return (*this)(BO1->getOperand(1), BO2->getOperand(1)); + return (*this)(left->getOperand(1), right->getOperand(1)); } }; @@ -62,7 +85,7 @@ bool runOnFunction(Function &F); public: static char ID; // Pass identification, replacement for typeid - GVNPRE() : FunctionPass((intptr_t)&ID) { nextValueNumber = 0; } + GVNPRE() : FunctionPass((intptr_t)&ID) { nextValueNumber = 1; } private: uint32_t nextValueNumber; @@ -121,7 +144,7 @@ bool GVNPRE::add(Value* V, uint32_t number) { std::pair<ValueTable::iterator, bool> ret = VN.insert(std::make_pair(V, number)); - if (isa<BinaryOperator>(V) || isa<PHINode>(V)) + if (isa<BinaryOperator>(V) || isa<PHINode>(V) || isa<CmpInst>(V)) MS.insert(V); return ret.second; } @@ -187,6 +210,48 @@ } else if (PHINode* P = dyn_cast<PHINode>(V)) { if (P->getParent() == pred->getTerminator()->getSuccessor(0)) return P->getIncomingValueForBlock(pred); + } else if (CmpInst* C = dyn_cast<CmpInst>(V)) { + Value* newOp1 = isa<Instruction>(C->getOperand(0)) + ? phi_translate(set, + find_leader(set, C->getOperand(0)), + pred) + : C->getOperand(0); + if (newOp1 == 0) + return 0; + + Value* newOp2 = isa<Instruction>(C->getOperand(1)) + ? phi_translate(set, + find_leader(set, C->getOperand(1)), + pred) + : C->getOperand(1); + if (newOp2 == 0) + return 0; + + if (newOp1 != C->getOperand(0) || newOp2 != C->getOperand(1)) { + Instruction* newVal = CmpInst::create(C->getOpcode(), + C->getPredicate(), + newOp1, newOp2, + C->getName()+".gvnpre"); + + if (add(newVal, nextValueNumber)) + nextValueNumber++; + if (!find_leader(set, newVal)) { + DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; + createdExpressions.insert(newVal); + return newVal; + } else { + ValueTable::iterator I = VN.find(newVal); + if (I->first == newVal) + VN.erase(newVal); + + std::set<Value*, ExprLT>::iterator F = MS.find(newVal); + if (*F == newVal) + MS.erase(newVal); + + delete newVal; + return 0; + } + } } return V; @@ -231,6 +296,27 @@ if (!lhsValid || !rhsValid) set.erase(BO); + } else if (CmpInst* C = dyn_cast<CmpInst>(v)) { + bool lhsValid = !isa<Instruction>(C->getOperand(0)); + if (!lhsValid) + for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end(); + I != E; ++I) + if (VN[*I] == VN[C->getOperand(0)]) { + lhsValid = true; + break; + } + + bool rhsValid = !isa<Instruction>(C->getOperand(1)); + if (!rhsValid) + for (std::set<Value*, ExprLT>::iterator I = set.begin(), E = set.end(); + I != E; ++I) + if (VN[*I] == VN[C->getOperand(1)]) { + rhsValid = true; + break; + } + + if (!lhsValid || !rhsValid) + set.erase(C); } } } @@ -246,7 +332,14 @@ VN[BO->getOperand(1)] == VN[*SI]) { toErase.insert(*SI); } - } + } + else if (CmpInst* C = dyn_cast<CmpInst>(*I)) + for (std::set<Value*, ExprLT>::iterator SI = set.begin(); SI != E; ++SI) { + if (VN[C->getOperand(0)] == VN[*SI] || + VN[C->getOperand(1)] == VN[*SI]) { + toErase.insert(*SI); + } + } } std::vector<Value*> Q; @@ -275,6 +368,21 @@ visited.insert(e); Q.pop_back(); } + } else if (CmpInst* C = dyn_cast<CmpInst>(e)) { + Value* l = find_leader(set, C->getOperand(0)); + Value* r = find_leader(set, C->getOperand(1)); + + if (l != 0 && isa<Instruction>(l) && + visited.find(l) == visited.end()) + Q.push_back(l); + else if (r != 0 && isa<Instruction>(r) && + visited.find(r) == visited.end()) + Q.push_back(r); + else { + vec.push_back(e); + visited.insert(e); + Q.pop_back(); + } } else { visited.insert(e); vec.push_back(e); @@ -340,6 +448,20 @@ currExps.insert(rightValue); currExps.insert(BO); + // Handle cmp ops... + } else if (CmpInst* C = dyn_cast<CmpInst>(BI)) { + Value* leftValue = C->getOperand(0); + Value* rightValue = C->getOperand(1); + + if (add(C, nextValueNumber)) + nextValueNumber++; + + if (isa<Instruction>(leftValue)) + currExps.insert(leftValue); + if (isa<Instruction>(rightValue)) + currExps.insert(rightValue); + currExps.insert(C); + // Handle unsupported ops } else if (!BI->isTerminator()){ if (add(BI, nextValueNumber)) @@ -549,7 +671,7 @@ Value* e = workList.back(); workList.pop_back(); - if (isa<BinaryOperator>(e)) { + if (isa<BinaryOperator>(e) || isa<CmpInst>(e)) { if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0) continue; @@ -588,25 +710,34 @@ PI != PE; ++PI) { Value* e2 = avail[*PI]; if (!find_leader(availableOut[*PI], e2)) { - BinaryOperator* BO = cast<BinaryOperator>(e2); + User* U = cast<User>(e2); Value* s1 = 0; - if (isa<Instruction>(BO->getOperand(0))) - s1 = find_leader(availableOut[*PI], BO->getOperand(0)); + if (isa<Instruction>(U->getOperand(0))) + s1 = find_leader(availableOut[*PI], U->getOperand(0)); else - s1 = BO->getOperand(0); + s1 = U->getOperand(0); Value* s2 = 0; - if (isa<Instruction>(BO->getOperand(1))) - s2 = find_leader(availableOut[*PI], BO->getOperand(1)); + if (isa<Instruction>(U->getOperand(1))) + s2 = find_leader(availableOut[*PI], U->getOperand(1)); else - s2 = BO->getOperand(1); + s2 = U->getOperand(1); - Value* newVal = BinaryOperator::create(BO->getOpcode(), + Value* newVal = 0; + if (BinaryOperator* BO = dyn_cast<BinaryOperator>(U)) + newVal = BinaryOperator::create(BO->getOpcode(), s1, s2, BO->getName()+".gvnpre", (*PI)->getTerminator()); - add(newVal, VN[BO]); + else if (CmpInst* C = dyn_cast<CmpInst>(U)) + newVal = CmpInst::create(C->getOpcode(), + C->getPredicate(), + s1, s2, + C->getName()+".gvnpre", + (*PI)->getTerminator()); + + add(newVal, VN[U]); std::set<Value*, ExprLT>& predAvail = availableOut[*PI]; Value* val = find_leader(predAvail, newVal); @@ -688,7 +819,7 @@ for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { - if (isa<BinaryOperator>(BI)) { + if (isa<BinaryOperator>(BI) || isa<CmpInst>(BI)) { Value *leader = find_leader(availableOut[BB], BI); if (leader != 0) _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits