From 66fd906074cc677d449e2da83d156338c047b7a7 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 21 Jun 2007 17:57:53 +0000 Subject: [PATCH] Change lots of sets from std::set to SmallPtrSet. This reduces the time required to optimize 253.perlbmk from 10.9s to 5.3s. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37690 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/GVNPRE.cpp | 191 ++++++++++++++++--------------- 1 file changed, 99 insertions(+), 92 deletions(-) diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp index b1b096e3504..9f7fc4d8e7c 100644 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ b/lib/Transforms/Scalar/GVNPRE.cpp @@ -27,6 +27,7 @@ #include "llvm/Analysis/PostDominators.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" @@ -85,7 +86,7 @@ namespace { std::map expressionNumbering; std::set maximalExpressions; - std::set maximalValues; + SmallPtrSet maximalValues; uint32_t nextValueNumber; @@ -103,7 +104,7 @@ namespace { return maximalExpressions; } - std::set& getMaximalValues() { return maximalValues; } + SmallPtrSet& getMaximalValues() { return maximalValues; } void erase(Value* v); }; } @@ -346,8 +347,8 @@ namespace { ValueTable VN; std::vector createdExpressions; - std::map > availableOut; - std::map > anticipatedIn; + std::map > availableOut; + std::map > anticipatedIn; // This transformation requires dominator postdominator info virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -358,44 +359,44 @@ namespace { // Helper fuctions // FIXME: eliminate or document these better - void dump(const std::set& s) const; - void clean(std::set& set); - Value* find_leader(std::set& vals, + void dump(const SmallPtrSet& s) const; + void clean(SmallPtrSet& set); + Value* find_leader(SmallPtrSet& vals, uint32_t v); Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ); - void phi_translate_set(std::set& anticIn, BasicBlock* pred, - BasicBlock* succ, std::set& out); + void phi_translate_set(SmallPtrSet& anticIn, BasicBlock* pred, + BasicBlock* succ, SmallPtrSet& out); - void topo_sort(std::set& set, + void topo_sort(SmallPtrSet& set, std::vector& vec); void cleanup(); bool elimination(); - void val_insert(std::set& s, Value* v); - void val_replace(std::set& s, Value* v); + void val_insert(SmallPtrSet& s, Value* v); + void val_replace(SmallPtrSet& s, Value* v); bool dependsOnInvoke(Value* V); void buildsets_availout(BasicBlock::iterator I, - std::set& currAvail, - std::set& currPhis, - std::set& currExps, - std::set& currTemps); + SmallPtrSet& currAvail, + SmallPtrSet& currPhis, + SmallPtrSet& currExps, + SmallPtrSet& currTemps); void buildsets_anticout(BasicBlock* BB, - std::set& anticOut, + SmallPtrSet& anticOut, std::set& visited); bool buildsets_anticin(BasicBlock* BB, - std::set& anticOut, - std::set& currExps, - std::set& currTemps, + SmallPtrSet& anticOut, + SmallPtrSet& currExps, + SmallPtrSet& currTemps, std::set& visited); unsigned buildsets(Function& F); void insertion_pre(Value* e, BasicBlock* BB, std::map& avail, - std::set& new_set); + SmallPtrSet& new_set); unsigned insertion_mergepoint(std::vector& workList, df_iterator D, - std::set& new_set); + SmallPtrSet& new_set); bool insertion(Function& F); }; @@ -418,8 +419,8 @@ STATISTIC(NumEliminated, "Number of redundant instructions eliminated"); /// find_leader - Given a set and a value number, return the first /// element of the set with that value number, or 0 if no such element /// is present -Value* GVNPRE::find_leader(std::set& vals, uint32_t v) { - for (std::set::iterator I = vals.begin(), E = vals.end(); +Value* GVNPRE::find_leader(SmallPtrSet& vals, uint32_t v) { + for (SmallPtrSet::iterator I = vals.begin(), E = vals.end(); I != E; ++I) if (v == VN.lookup(*I)) return *I; @@ -429,7 +430,7 @@ Value* GVNPRE::find_leader(std::set& vals, uint32_t v) { /// val_insert - Insert a value into a set only if there is not a value /// with the same value number already in the set -void GVNPRE::val_insert(std::set& s, Value* v) { +void GVNPRE::val_insert(SmallPtrSet& s, Value* v) { uint32_t num = VN.lookup(v); Value* leader = find_leader(s, num); if (leader == 0) @@ -438,7 +439,7 @@ void GVNPRE::val_insert(std::set& s, Value* v) { /// val_replace - Insert a value into a set, replacing any values already in /// the set that have the same value number -void GVNPRE::val_replace(std::set& s, Value* v) { +void GVNPRE::val_replace(SmallPtrSet& s, Value* v) { uint32_t num = VN.lookup(v); Value* leader = find_leader(s, num); while (leader != 0) { @@ -546,10 +547,10 @@ Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) { } /// phi_translate_set - Perform phi translation on every element of a set -void GVNPRE::phi_translate_set(std::set& anticIn, +void GVNPRE::phi_translate_set(SmallPtrSet& anticIn, BasicBlock* pred, BasicBlock* succ, - std::set& out) { - for (std::set::iterator I = anticIn.begin(), + SmallPtrSet& out) { + for (SmallPtrSet::iterator I = anticIn.begin(), E = anticIn.end(); I != E; ++I) { Value* V = phi_translate(*I, pred, succ); if (V != 0) @@ -574,7 +575,7 @@ bool GVNPRE::dependsOnInvoke(Value* V) { /// clean - Remove all non-opaque values from the set whose operands are not /// themselves in the set, as well as all values that depend on invokes (see /// above) -void GVNPRE::clean(std::set& set) { +void GVNPRE::clean(SmallPtrSet& set) { std::vector worklist; topo_sort(set, worklist); @@ -584,7 +585,7 @@ void GVNPRE::clean(std::set& set) { if (BinaryOperator* BO = dyn_cast(v)) { bool lhsValid = !isa(BO->getOperand(0)); if (!lhsValid) - for (std::set::iterator I = set.begin(), E = set.end(); + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) if (VN.lookup(*I) == VN.lookup(BO->getOperand(0))) { lhsValid = true; @@ -595,7 +596,7 @@ void GVNPRE::clean(std::set& set) { bool rhsValid = !isa(BO->getOperand(1)); if (!rhsValid) - for (std::set::iterator I = set.begin(), E = set.end(); + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) if (VN.lookup(*I) == VN.lookup(BO->getOperand(1))) { rhsValid = true; @@ -609,7 +610,7 @@ void GVNPRE::clean(std::set& set) { } else if (CmpInst* C = dyn_cast(v)) { bool lhsValid = !isa(C->getOperand(0)); if (!lhsValid) - for (std::set::iterator I = set.begin(), E = set.end(); + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) if (VN.lookup(*I) == VN.lookup(C->getOperand(0))) { lhsValid = true; @@ -620,7 +621,7 @@ void GVNPRE::clean(std::set& set) { bool rhsValid = !isa(C->getOperand(1)); if (!rhsValid) - for (std::set::iterator I = set.begin(), E = set.end(); + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) if (VN.lookup(*I) == VN.lookup(C->getOperand(1))) { rhsValid = true; @@ -637,19 +638,19 @@ void GVNPRE::clean(std::set& set) { /// topo_sort - Given a set of values, sort them by topological /// order into the provided vector. -void GVNPRE::topo_sort(std::set& set, std::vector& vec) { - std::set toErase; - for (std::set::iterator I = set.begin(), E = set.end(); +void GVNPRE::topo_sort(SmallPtrSet& set, std::vector& vec) { + SmallPtrSet toErase; + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) { if (BinaryOperator* BO = dyn_cast(*I)) - for (std::set::iterator SI = set.begin(); SI != E; ++SI) { + for (SmallPtrSet::iterator SI = set.begin(); SI != E; ++SI) { if (VN.lookup(BO->getOperand(0)) == VN.lookup(*SI) || VN.lookup(BO->getOperand(1)) == VN.lookup(*SI)) { toErase.insert(*SI); } } else if (CmpInst* C = dyn_cast(*I)) - for (std::set::iterator SI = set.begin(); SI != E; ++SI) { + for (SmallPtrSet::iterator SI = set.begin(); SI != E; ++SI) { if (VN.lookup(C->getOperand(0)) == VN.lookup(*SI) || VN.lookup(C->getOperand(1)) == VN.lookup(*SI)) { toErase.insert(*SI); @@ -658,13 +659,13 @@ void GVNPRE::topo_sort(std::set& set, std::vector& vec) { } std::vector Q; - for (std::set::iterator I = set.begin(), E = set.end(); + for (SmallPtrSet::iterator I = set.begin(), E = set.end(); I != E; ++I) { - if (toErase.find(*I) == toErase.end()) + if (toErase.count(*I) == 0) Q.push_back(*I); } - std::set visited; + SmallPtrSet visited; while (!Q.empty()) { Value* e = Q.back(); @@ -673,10 +674,10 @@ void GVNPRE::topo_sort(std::set& set, std::vector& vec) { Value* r = find_leader(set, VN.lookup(BO->getOperand(1))); if (l != 0 && isa(l) && - visited.find(l) == visited.end()) + visited.count(l) == 0) Q.push_back(l); else if (r != 0 && isa(r) && - visited.find(r) == visited.end()) + visited.count(r) == 0) Q.push_back(r); else { vec.push_back(e); @@ -688,10 +689,10 @@ void GVNPRE::topo_sort(std::set& set, std::vector& vec) { Value* r = find_leader(set, VN.lookup(C->getOperand(1))); if (l != 0 && isa(l) && - visited.find(l) == visited.end()) + visited.count(l) == 0) Q.push_back(l); else if (r != 0 && isa(r) && - visited.find(r) == visited.end()) + visited.count(r) == 0) Q.push_back(r); else { vec.push_back(e); @@ -707,9 +708,9 @@ void GVNPRE::topo_sort(std::set& set, std::vector& vec) { } /// dump - Dump a set of values to standard error -void GVNPRE::dump(const std::set& s) const { +void GVNPRE::dump(const SmallPtrSet& s) const { DOUT << "{ "; - for (std::set::iterator I = s.begin(), E = s.end(); + for (SmallPtrSet::iterator I = s.begin(), E = s.end(); I != E; ++I) { DEBUG((*I)->dump()); } @@ -782,10 +783,10 @@ void GVNPRE::cleanup() { /// buildsets_availout - When calculating availability, handle an instruction /// by inserting it into the appropriate sets void GVNPRE::buildsets_availout(BasicBlock::iterator I, - std::set& currAvail, - std::set& currPhis, - std::set& currExps, - std::set& currTemps) { + SmallPtrSet& currAvail, + SmallPtrSet& currPhis, + SmallPtrSet& currExps, + SmallPtrSet& currTemps) { // Handle PHI nodes... if (PHINode* p = dyn_cast(I)) { VN.lookup_or_add(p); @@ -830,7 +831,7 @@ void GVNPRE::buildsets_availout(BasicBlock::iterator I, /// buildsets_anticout - When walking the postdom tree, calculate the ANTIC_OUT /// set as a function of the ANTIC_IN set of the block's predecessors void GVNPRE::buildsets_anticout(BasicBlock* BB, - std::set& anticOut, + SmallPtrSet& anticOut, std::set& visited) { if (BB->getTerminator()->getNumSuccessors() == 1) { if (visited.find(BB->getTerminator()->getSuccessor(0)) == visited.end()) @@ -845,15 +846,18 @@ void GVNPRE::buildsets_anticout(BasicBlock* BB, for (unsigned i = 1; i < BB->getTerminator()->getNumSuccessors(); ++i) { BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i); - std::set& succAnticIn = anticipatedIn[currSucc]; + SmallPtrSet& succAnticIn = anticipatedIn[currSucc]; - std::set temp; - std::insert_iterator > temp_ins(temp, temp.begin()); - std::set_intersection(anticOut.begin(), anticOut.end(), - succAnticIn.begin(), succAnticIn.end(), temp_ins); - - anticOut.clear(); - anticOut.insert(temp.begin(), temp.end()); + std::vector temp; + + for (SmallPtrSet::iterator I = anticOut.begin(), + E = anticOut.end(); I != E; ++I) + if (succAnticIn.count(*I) == 0) + temp.push_back(*I); + + for (std::vector::iterator I = temp.begin(), E = temp.end(); + I != E; ++I) + anticOut.erase(*I); } } } @@ -862,26 +866,29 @@ void GVNPRE::buildsets_anticout(BasicBlock* BB, /// each block. ANTIC_IN is then a function of ANTIC_OUT and the GEN /// sets populated in buildsets_availout bool GVNPRE::buildsets_anticin(BasicBlock* BB, - std::set& anticOut, - std::set& currExps, - std::set& currTemps, + SmallPtrSet& anticOut, + SmallPtrSet& currExps, + SmallPtrSet& currTemps, std::set& visited) { - std::set& anticIn = anticipatedIn[BB]; - std::set old (anticIn.begin(), anticIn.end()); + SmallPtrSet& anticIn = anticipatedIn[BB]; + SmallPtrSet old (anticIn.begin(), anticIn.end()); buildsets_anticout(BB, anticOut, visited); - std::set S; - std::insert_iterator > s_ins(S, S.begin()); - std::set_difference(anticOut.begin(), anticOut.end(), - currTemps.begin(), currTemps.end(), s_ins); - + SmallPtrSet S; + for (SmallPtrSet::iterator I = anticOut.begin(), + E = anticOut.end(); I != E; ++I) + if (currTemps.count(*I) == 0) + S.insert(*I); + anticIn.clear(); - std::insert_iterator > ai_ins(anticIn, anticIn.begin()); - std::set_difference(currExps.begin(), currExps.end(), - currTemps.begin(), currTemps.end(), ai_ins); + + for (SmallPtrSet::iterator I = currExps.begin(), + E = currExps.end(); I != E; ++I) + if (currTemps.count(*I) == 0) + anticIn.insert(*I); - for (std::set::iterator I = S.begin(), E = S.end(); + for (SmallPtrSet::iterator I = S.begin(), E = S.end(); I != E; ++I) { // For non-opaque values, we should already have a value numbering. // However, for opaques, such as constants within PHI nodes, it is @@ -904,9 +911,9 @@ bool GVNPRE::buildsets_anticin(BasicBlock* BB, /// buildsets - Phase 1 of the main algorithm. Construct the AVAIL_OUT /// and the ANTIC_IN sets. unsigned GVNPRE::buildsets(Function& F) { - std::map > generatedExpressions; - std::map > generatedPhis; - std::map > generatedTemporaries; + std::map > generatedExpressions; + std::map > generatedPhis; + std::map > generatedTemporaries; DominatorTree &DT = getAnalysis(); @@ -917,10 +924,10 @@ unsigned GVNPRE::buildsets(Function& F) { E = df_end(DT.getRootNode()); DI != E; ++DI) { // Get the sets to update for this block - std::set& currExps = generatedExpressions[DI->getBlock()]; - std::set& currPhis = generatedPhis[DI->getBlock()]; - std::set& currTemps = generatedTemporaries[DI->getBlock()]; - std::set& currAvail = availableOut[DI->getBlock()]; + SmallPtrSet& currExps = generatedExpressions[DI->getBlock()]; + SmallPtrSet& currPhis = generatedPhis[DI->getBlock()]; + SmallPtrSet& currTemps = generatedTemporaries[DI->getBlock()]; + SmallPtrSet& currAvail = availableOut[DI->getBlock()]; BasicBlock* BB = DI->getBlock(); @@ -957,7 +964,7 @@ unsigned GVNPRE::buildsets(Function& F) { unsigned iterations = 0; while (changed) { changed = false; - std::set anticOut; + SmallPtrSet anticOut; // Top-down walk of the postdominator tree for (df_iterator PDI = @@ -984,7 +991,7 @@ unsigned GVNPRE::buildsets(Function& F) { /// the main block void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, std::map& avail, - std::set& new_set) { + SmallPtrSet& new_set) { for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { Value* e2 = avail[*PI]; if (!find_leader(availableOut[*PI], VN.lookup(e2))) { @@ -1016,7 +1023,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, VN.add(newVal, VN.lookup(U)); - std::set& predAvail = availableOut[*PI]; + SmallPtrSet& predAvail = availableOut[*PI]; val_replace(predAvail, newVal); std::map::iterator av = avail.find(*PI); @@ -1048,7 +1055,7 @@ void GVNPRE::insertion_pre(Value* e, BasicBlock* BB, /// block for the possibility of a partial redundancy. If present, eliminate it unsigned GVNPRE::insertion_mergepoint(std::vector& workList, df_iterator D, - std::set& new_set) { + SmallPtrSet& new_set) { bool changed_function = false; bool new_stuff = false; @@ -1112,7 +1119,7 @@ bool GVNPRE::insertion(Function& F) { DominatorTree &DT = getAnalysis(); - std::map > new_sets; + std::map > new_sets; bool new_stuff = true; while (new_stuff) { new_stuff = false; @@ -1123,16 +1130,16 @@ bool GVNPRE::insertion(Function& F) { if (BB == 0) continue; - std::set& new_set = new_sets[BB]; - std::set& availOut = availableOut[BB]; - std::set& anticIn = anticipatedIn[BB]; + SmallPtrSet& new_set = new_sets[BB]; + SmallPtrSet& availOut = availableOut[BB]; + SmallPtrSet& anticIn = anticipatedIn[BB]; new_set.clear(); // Replace leaders with leaders inherited from dominator if (DI->getIDom() != 0) { - std::set& dom_set = new_sets[DI->getIDom()->getBlock()]; - for (std::set::iterator I = dom_set.begin(), + SmallPtrSet& dom_set = new_sets[DI->getIDom()->getBlock()]; + for (SmallPtrSet::iterator I = dom_set.begin(), E = dom_set.end(); I != E; ++I) { new_set.insert(*I); val_replace(availOut, *I);