diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:54:30 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:54:30 +0000 |
commit | 20e856b2a58d12231aa42d5d13888b15ac03e5a4 (patch) | |
tree | cf5763d092b81cecc168fa28032247ee495d06e2 /lib/Transforms/Scalar | |
parent | 2f2afc1aae898651e26987a5c71f3febb19bca98 (diff) | |
download | FreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.zip FreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.tar.gz |
Update LLVM to r100181.
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/ABCD.cpp | 253 | ||||
-rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 8 | ||||
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 14 | ||||
-rw-r--r-- | lib/Transforms/Scalar/IndVarSimplify.cpp | 34 | ||||
-rw-r--r-- | lib/Transforms/Scalar/LoopStrengthReduce.cpp | 7 | ||||
-rw-r--r-- | lib/Transforms/Scalar/Reg2Mem.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 19 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyCFGPass.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SimplifyLibCalls.cpp | 26 |
9 files changed, 199 insertions, 166 deletions
diff --git a/lib/Transforms/Scalar/ABCD.cpp b/lib/Transforms/Scalar/ABCD.cpp index ea8e5c3..6135992 100644 --- a/lib/Transforms/Scalar/ABCD.cpp +++ b/lib/Transforms/Scalar/ABCD.cpp @@ -27,6 +27,7 @@ #define DEBUG_TYPE "abcd" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Constants.h" @@ -77,10 +78,10 @@ class ABCD : public FunctionPass { class Bound { public: Bound(APInt v, bool upper) : value(v), upper_bound(upper) {} - Bound(const Bound *b, int cnst) - : value(b->value - cnst), upper_bound(b->upper_bound) {} - Bound(const Bound *b, const APInt &cnst) - : value(b->value - cnst), upper_bound(b->upper_bound) {} + Bound(const Bound &b, int cnst) + : value(b.value - cnst), upper_bound(b.upper_bound) {} + Bound(const Bound &b, const APInt &cnst) + : value(b.value - cnst), upper_bound(b.upper_bound) {} /// Test if Bound is an upper bound bool isUpperBound() const { return upper_bound; } @@ -89,15 +90,15 @@ class ABCD : public FunctionPass { int32_t getBitWidth() const { return value.getBitWidth(); } /// Creates a Bound incrementing the one received - static Bound *createIncrement(const Bound *b) { - return new Bound(b->isUpperBound() ? b->value+1 : b->value-1, - b->upper_bound); + static Bound createIncrement(const Bound &b) { + return Bound(b.isUpperBound() ? b.value+1 : b.value-1, + b.upper_bound); } /// Creates a Bound decrementing the one received - static Bound *createDecrement(const Bound *b) { - return new Bound(b->isUpperBound() ? b->value-1 : b->value+1, - b->upper_bound); + static Bound createDecrement(const Bound &b) { + return Bound(b.isUpperBound() ? b.value-1 : b.value+1, + b.upper_bound); } /// Test if two bounds are equal @@ -109,36 +110,31 @@ class ABCD : public FunctionPass { } /// Test if val is less than or equal to Bound b - static bool leq(APInt val, const Bound *b) { - if (!b) return false; - return b->isUpperBound() ? val.sle(b->value) : val.sge(b->value); + static bool leq(APInt val, const Bound &b) { + return b.isUpperBound() ? val.sle(b.value) : val.sge(b.value); } /// Test if Bound a is less then or equal to Bound - static bool leq(const Bound *a, const Bound *b) { - if (!a || !b) return false; - - assert(a->isUpperBound() == b->isUpperBound()); - return a->isUpperBound() ? a->value.sle(b->value) : - a->value.sge(b->value); + static bool leq(const Bound &a, const Bound &b) { + assert(a.isUpperBound() == b.isUpperBound()); + return a.isUpperBound() ? a.value.sle(b.value) : + a.value.sge(b.value); } /// Test if Bound a is less then Bound b - static bool lt(const Bound *a, const Bound *b) { - if (!a || !b) return false; - - assert(a->isUpperBound() == b->isUpperBound()); - return a->isUpperBound() ? a->value.slt(b->value) : - a->value.sgt(b->value); + static bool lt(const Bound &a, const Bound &b) { + assert(a.isUpperBound() == b.isUpperBound()); + return a.isUpperBound() ? a.value.slt(b.value) : + a.value.sgt(b.value); } /// Test if Bound b is greater then or equal val - static bool geq(const Bound *b, APInt val) { + static bool geq(const Bound &b, APInt val) { return leq(val, b); } /// Test if Bound a is greater then or equal Bound b - static bool geq(const Bound *a, const Bound *b) { + static bool geq(const Bound &a, const Bound &b) { return leq(b, a); } @@ -152,29 +148,36 @@ class ABCD : public FunctionPass { /// minimum true and minimum reduced results are stored class MemoizedResultChart { public: - MemoizedResultChart() - : max_false(NULL), min_true(NULL), min_reduced(NULL) {} + MemoizedResultChart() {} + MemoizedResultChart(const MemoizedResultChart &other) { + if (other.max_false) + max_false.reset(new Bound(*other.max_false)); + if (other.min_true) + min_true.reset(new Bound(*other.min_true)); + if (other.min_reduced) + min_reduced.reset(new Bound(*other.min_reduced)); + } /// Returns the max false - Bound *getFalse() const { return max_false; } + const Bound *getFalse() const { return max_false.get(); } /// Returns the min true - Bound *getTrue() const { return min_true; } + const Bound *getTrue() const { return min_true.get(); } /// Returns the min reduced - Bound *getReduced() const { return min_reduced; } + const Bound *getReduced() const { return min_reduced.get(); } /// Return the stored result for this bound - ProveResult getResult(const Bound *bound) const; + ProveResult getResult(const Bound &bound) const; /// Stores a false found - void addFalse(Bound *bound); + void addFalse(const Bound &bound); /// Stores a true found - void addTrue(Bound *bound); + void addTrue(const Bound &bound); /// Stores a Reduced found - void addReduced(Bound *bound); + void addReduced(const Bound &bound); /// Clears redundant reduced /// If a min_true is smaller than a min_reduced then the min_reduced @@ -183,13 +186,13 @@ class ABCD : public FunctionPass { void clearRedundantReduced(); void clear() { - delete max_false; - delete min_true; - delete min_reduced; + max_false.reset(); + min_true.reset(); + min_reduced.reset(); } private: - Bound *max_false, *min_true, *min_reduced; + OwningPtr<Bound> max_false, min_true, min_reduced; }; /// This class stores the result found for a node of the graph, @@ -198,27 +201,27 @@ class ABCD : public FunctionPass { public: /// Test if there is true result stored from b to a /// that is less then the bound - bool hasTrue(Value *b, const Bound *bound) const { - Bound *trueBound = map.lookup(b).getTrue(); - return trueBound && Bound::leq(trueBound, bound); + bool hasTrue(Value *b, const Bound &bound) const { + const Bound *trueBound = map.lookup(b).getTrue(); + return trueBound && Bound::leq(*trueBound, bound); } /// Test if there is false result stored from b to a /// that is less then the bound - bool hasFalse(Value *b, const Bound *bound) const { - Bound *falseBound = map.lookup(b).getFalse(); - return falseBound && Bound::leq(falseBound, bound); + bool hasFalse(Value *b, const Bound &bound) const { + const Bound *falseBound = map.lookup(b).getFalse(); + return falseBound && Bound::leq(*falseBound, bound); } /// Test if there is reduced result stored from b to a /// that is less then the bound - bool hasReduced(Value *b, const Bound *bound) const { - Bound *reducedBound = map.lookup(b).getReduced(); - return reducedBound && Bound::leq(reducedBound, bound); + bool hasReduced(Value *b, const Bound &bound) const { + const Bound *reducedBound = map.lookup(b).getReduced(); + return reducedBound && Bound::leq(*reducedBound, bound); } /// Returns the stored bound for b - ProveResult getBoundResult(Value *b, Bound *bound) { + ProveResult getBoundResult(Value *b, const Bound &bound) { return map[b].getResult(bound); } @@ -233,7 +236,7 @@ class ABCD : public FunctionPass { } /// Stores the bound found - void updateBound(Value *b, Bound *bound, const ProveResult res); + void updateBound(Value *b, const Bound &bound, const ProveResult res); private: // Maps a nod in the graph with its results found. @@ -274,7 +277,7 @@ class ABCD : public FunctionPass { bool hasEdge(Value *V, bool upper) const; /// Returns all edges pointed by vertex V - SmallPtrSet<Edge *, 16> getEdges(Value *V) const { + SmallVector<Edge, 16> getEdges(Value *V) const { return graph.lookup(V); } @@ -292,13 +295,7 @@ class ABCD : public FunctionPass { } private: - DenseMap<Value *, SmallPtrSet<Edge *, 16> > graph; - - /// Adds a Node to the graph. - DenseMap<Value *, SmallPtrSet<Edge *, 16> >::iterator addNode(Value *V) { - SmallPtrSet<Edge *, 16> p; - return graph.insert(std::make_pair(V, p)).first; - } + DenseMap<Value *, SmallVector<Edge, 16> > graph; /// Prints the header of the dot file void printHeader(raw_ostream &OS, Function &F) const; @@ -315,7 +312,7 @@ class ABCD : public FunctionPass { void printVertex(raw_ostream &OS, Value *source) const; /// Prints the edge to the dot file - void printEdge(raw_ostream &OS, Value *source, Edge *edge) const; + void printEdge(raw_ostream &OS, Value *source, const Edge &edge) const; void printName(raw_ostream &OS, Value *info) const; }; @@ -428,15 +425,15 @@ class ABCD : public FunctionPass { bool demandProve(Value *a, Value *b, int c, bool upper_bound); /// Prove that distance between b and a is <= bound - ProveResult prove(Value *a, Value *b, Bound *bound, unsigned level); + ProveResult prove(Value *a, Value *b, const Bound &bound, unsigned level); /// Updates the distance value for a and b - void updateMemDistance(Value *a, Value *b, Bound *bound, unsigned level, + void updateMemDistance(Value *a, Value *b, const Bound &bound, unsigned level, meet_function meet); InequalityGraph inequality_graph; MemoizedResult mem_result; - DenseMap<Value*, Bound*> active; + DenseMap<Value*, const Bound*> active; SmallPtrSet<Value*, 16> created; SmallVector<PHINode *, 16> phis_to_remove; }; @@ -857,7 +854,7 @@ PHINode *ABCD::findSigma(BasicBlock *BB, Instruction *I) { /// This implementation works on any kind of inequality branch. bool ABCD::demandProve(Value *a, Value *b, int c, bool upper_bound) { int32_t width = cast<IntegerType>(a->getType())->getBitWidth(); - Bound *bound = new Bound(APInt(width, c), upper_bound); + Bound bound(APInt(width, c), upper_bound); mem_result.clear(); active.clear(); @@ -867,7 +864,7 @@ bool ABCD::demandProve(Value *a, Value *b, int c, bool upper_bound) { } /// Prove that distance between b and a is <= bound -ABCD::ProveResult ABCD::prove(Value *a, Value *b, Bound *bound, +ABCD::ProveResult ABCD::prove(Value *a, Value *b, const Bound &bound, unsigned level) { // if (C[b-a<=e] == True for some e <= bound // Same or stronger difference was already proven @@ -885,22 +882,22 @@ ABCD::ProveResult ABCD::prove(Value *a, Value *b, Bound *bound, return Reduced; // traversal reached the source vertex - if (a == b && Bound::geq(bound, APInt(bound->getBitWidth(), 0, true))) + if (a == b && Bound::geq(bound, APInt(bound.getBitWidth(), 0, true))) return True; // if b has no predecessor then fail - if (!inequality_graph.hasEdge(b, bound->isUpperBound())) + if (!inequality_graph.hasEdge(b, bound.isUpperBound())) return False; // a cycle was encountered if (active.count(b)) { - if (Bound::leq(active.lookup(b), bound)) + if (Bound::leq(*active.lookup(b), bound)) return Reduced; // a "harmless" cycle return False; // an amplifying cycle } - active[b] = bound; + active[b] = &bound; PHINode *PN = dyn_cast<PHINode>(b); // Test if a Value is a Phi. If it is a PHINode with more than 1 incoming @@ -917,23 +914,23 @@ ABCD::ProveResult ABCD::prove(Value *a, Value *b, Bound *bound, } /// Updates the distance value for a and b -void ABCD::updateMemDistance(Value *a, Value *b, Bound *bound, unsigned level, - meet_function meet) { +void ABCD::updateMemDistance(Value *a, Value *b, const Bound &bound, + unsigned level, meet_function meet) { ABCD::ProveResult res = (meet == max) ? False : True; - SmallPtrSet<Edge *, 16> Edges = inequality_graph.getEdges(b); - SmallPtrSet<Edge *, 16>::iterator begin = Edges.begin(), end = Edges.end(); + SmallVector<Edge, 16> Edges = inequality_graph.getEdges(b); + SmallVector<Edge, 16>::iterator begin = Edges.begin(), end = Edges.end(); for (; begin != end ; ++begin) { if (((res >= Reduced) && (meet == max)) || ((res == False) && (meet == min))) { break; } - Edge *in = *begin; - if (in->isUpperBound() == bound->isUpperBound()) { - Value *succ = in->getVertex(); - res = meet(res, prove(a, succ, new Bound(bound, in->getValue()), - level+1)); + const Edge &in = *begin; + if (in.isUpperBound() == bound.isUpperBound()) { + Value *succ = in.getVertex(); + res = meet(res, prove(a, succ, Bound(bound, in.getValue()), + level+1)); } } @@ -941,53 +938,53 @@ void ABCD::updateMemDistance(Value *a, Value *b, Bound *bound, unsigned level, } /// Return the stored result for this bound -ABCD::ProveResult ABCD::MemoizedResultChart::getResult(const Bound *bound)const{ - if (max_false && Bound::leq(bound, max_false)) +ABCD::ProveResult ABCD::MemoizedResultChart::getResult(const Bound &bound)const{ + if (max_false && Bound::leq(bound, *max_false)) return False; - if (min_true && Bound::leq(min_true, bound)) + if (min_true && Bound::leq(*min_true, bound)) return True; - if (min_reduced && Bound::leq(min_reduced, bound)) + if (min_reduced && Bound::leq(*min_reduced, bound)) return Reduced; return False; } /// Stores a false found -void ABCD::MemoizedResultChart::addFalse(Bound *bound) { - if (!max_false || Bound::leq(max_false, bound)) - max_false = bound; - - if (Bound::eq(max_false, min_reduced)) - min_reduced = Bound::createIncrement(min_reduced); - if (Bound::eq(max_false, min_true)) - min_true = Bound::createIncrement(min_true); - if (Bound::eq(min_reduced, min_true)) - min_reduced = NULL; +void ABCD::MemoizedResultChart::addFalse(const Bound &bound) { + if (!max_false || Bound::leq(*max_false, bound)) + max_false.reset(new Bound(bound)); + + if (Bound::eq(max_false.get(), min_reduced.get())) + min_reduced.reset(new Bound(Bound::createIncrement(*min_reduced))); + if (Bound::eq(max_false.get(), min_true.get())) + min_true.reset(new Bound(Bound::createIncrement(*min_true))); + if (Bound::eq(min_reduced.get(), min_true.get())) + min_reduced.reset(); clearRedundantReduced(); } /// Stores a true found -void ABCD::MemoizedResultChart::addTrue(Bound *bound) { - if (!min_true || Bound::leq(bound, min_true)) - min_true = bound; - - if (Bound::eq(min_true, min_reduced)) - min_reduced = Bound::createDecrement(min_reduced); - if (Bound::eq(min_true, max_false)) - max_false = Bound::createDecrement(max_false); - if (Bound::eq(max_false, min_reduced)) - min_reduced = NULL; +void ABCD::MemoizedResultChart::addTrue(const Bound &bound) { + if (!min_true || Bound::leq(bound, *min_true)) + min_true.reset(new Bound(bound)); + + if (Bound::eq(min_true.get(), min_reduced.get())) + min_reduced.reset(new Bound(Bound::createDecrement(*min_reduced))); + if (Bound::eq(min_true.get(), max_false.get())) + max_false.reset(new Bound(Bound::createDecrement(*max_false))); + if (Bound::eq(max_false.get(), min_reduced.get())) + min_reduced.reset(); clearRedundantReduced(); } /// Stores a Reduced found -void ABCD::MemoizedResultChart::addReduced(Bound *bound) { - if (!min_reduced || Bound::leq(bound, min_reduced)) - min_reduced = bound; - - if (Bound::eq(min_reduced, min_true)) - min_true = Bound::createIncrement(min_true); - if (Bound::eq(min_reduced, max_false)) - max_false = Bound::createDecrement(max_false); +void ABCD::MemoizedResultChart::addReduced(const Bound &bound) { + if (!min_reduced || Bound::leq(bound, *min_reduced)) + min_reduced.reset(new Bound(bound)); + + if (Bound::eq(min_reduced.get(), min_true.get())) + min_true.reset(new Bound(Bound::createIncrement(*min_true))); + if (Bound::eq(min_reduced.get(), max_false.get())) + max_false.reset(new Bound(Bound::createDecrement(*max_false))); } /// Clears redundant reduced @@ -995,14 +992,14 @@ void ABCD::MemoizedResultChart::addReduced(Bound *bound) { /// is unnecessary and then removed. It also works for min_reduced /// begin smaller than max_false. void ABCD::MemoizedResultChart::clearRedundantReduced() { - if (min_true && min_reduced && Bound::lt(min_true, min_reduced)) - min_reduced = NULL; - if (max_false && min_reduced && Bound::lt(min_reduced, max_false)) - min_reduced = NULL; + if (min_true && min_reduced && Bound::lt(*min_true, *min_reduced)) + min_reduced.reset(); + if (max_false && min_reduced && Bound::lt(*min_reduced, *max_false)) + min_reduced.reset(); } /// Stores the bound found -void ABCD::MemoizedResult::updateBound(Value *b, Bound *bound, +void ABCD::MemoizedResult::updateBound(Value *b, const Bound &bound, const ProveResult res) { if (res == False) { map[b].addFalse(bound); @@ -1020,19 +1017,17 @@ void ABCD::InequalityGraph::addEdge(Value *V_to, Value *V_from, assert(cast<IntegerType>(V_from->getType())->getBitWidth() == value.getBitWidth()); - DenseMap<Value *, SmallPtrSet<Edge *, 16> >::iterator from; - from = addNode(V_from); - from->second.insert(new Edge(V_to, value, upper)); + graph[V_from].push_back(Edge(V_to, value, upper)); } /// Test if there is any edge from V in the upper direction bool ABCD::InequalityGraph::hasEdge(Value *V, bool upper) const { - SmallPtrSet<Edge *, 16> it = graph.lookup(V); + SmallVector<Edge, 16> it = graph.lookup(V); - SmallPtrSet<Edge *, 16>::iterator begin = it.begin(); - SmallPtrSet<Edge *, 16>::iterator end = it.end(); + SmallVector<Edge, 16>::iterator begin = it.begin(); + SmallVector<Edge, 16>::iterator end = it.end(); for (; begin != end; ++begin) { - if ((*begin)->isUpperBound() == upper) { + if (begin->isUpperBound() == upper) { return true; } } @@ -1049,18 +1044,18 @@ void ABCD::InequalityGraph::printHeader(raw_ostream &OS, Function &F) const { /// Prints the body of the dot file void ABCD::InequalityGraph::printBody(raw_ostream &OS) const { - DenseMap<Value *, SmallPtrSet<Edge *, 16> >::const_iterator begin = + DenseMap<Value *, SmallVector<Edge, 16> >::const_iterator begin = graph.begin(), end = graph.end(); for (; begin != end ; ++begin) { - SmallPtrSet<Edge *, 16>::iterator begin_par = + SmallVector<Edge, 16>::const_iterator begin_par = begin->second.begin(), end_par = begin->second.end(); Value *source = begin->first; printVertex(OS, source); for (; begin_par != end_par ; ++begin_par) { - Edge *edge = *begin_par; + const Edge &edge = *begin_par; printEdge(OS, source, edge); } } @@ -1079,10 +1074,10 @@ void ABCD::InequalityGraph::printVertex(raw_ostream &OS, Value *source) const { /// Prints the edge to the dot file void ABCD::InequalityGraph::printEdge(raw_ostream &OS, Value *source, - Edge *edge) const { - Value *dest = edge->getVertex(); - APInt value = edge->getValue(); - bool upper = edge->isUpperBound(); + const Edge &edge) const { + Value *dest = edge.getVertex(); + APInt value = edge.getValue(); + bool upper = edge.isUpperBound(); OS << "\""; printName(OS, source); diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index 50c9630..93e9bfb 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -174,7 +174,7 @@ bool CodeGenPrepare::CanMergeBlocks(const BasicBlock *BB, // don't mess around with them. BasicBlock::const_iterator BBI = BB->begin(); while (const PHINode *PN = dyn_cast<PHINode>(BBI++)) { - for (Value::use_const_iterator UI = PN->use_begin(), E = PN->use_end(); + for (Value::const_use_iterator UI = PN->use_begin(), E = PN->use_end(); UI != E; ++UI) { const Instruction *User = cast<Instruction>(*UI); if (User->getParent() != DestBB || !isa<PHINode>(User)) @@ -714,8 +714,12 @@ bool CodeGenPrepare::OptimizeMemoryInst(Instruction *MemoryInst, Value *Addr, MemoryInst->replaceUsesOfWith(Addr, SunkAddr); - if (Addr->use_empty()) + if (Addr->use_empty()) { RecursivelyDeleteTriviallyDeadInstructions(Addr); + // This address is now available for reassignment, so erase the table entry; + // we don't want to match some completely different instruction. + SunkAddrs[Addr] = 0; + } return true; } diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index fcb802a..642d59d 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1004,18 +1004,18 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr, // If the load and store are to the exact same address, they should have been // a must alias. AA must have gotten confused. - // FIXME: Study to see if/when this happens. - if (LoadOffset == StoreOffset) { + // FIXME: Study to see if/when this happens. One case is forwarding a memset + // to a load from the base of the memset. #if 0 + if (LoadOffset == StoreOffset) { dbgs() << "STORE/LOAD DEP WITH COMMON POINTER MISSED:\n" << "Base = " << *StoreBase << "\n" << "Store Ptr = " << *WritePtr << "\n" << "Store Offs = " << StoreOffset << "\n" << "Load Ptr = " << *LoadPtr << "\n"; abort(); -#endif - return -1; } +#endif // If the load and store don't overlap at all, the store doesn't provide // anything to the load. In this case, they really don't alias at all, AA @@ -1031,11 +1031,11 @@ static int AnalyzeLoadFromClobberingWrite(const Type *LoadTy, Value *LoadPtr, bool isAAFailure = false; - if (StoreOffset < LoadOffset) { + if (StoreOffset < LoadOffset) isAAFailure = StoreOffset+int64_t(StoreSize) <= LoadOffset; - } else { + else isAAFailure = LoadOffset+int64_t(LoadSize) <= StoreOffset; - } + if (isAAFailure) { #if 0 dbgs() << "STORE LOAD DEP WITH COMMON BASE:\n" diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index eb04d94..988a4cb 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -553,22 +553,26 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) { // New instructions were inserted at the end of the preheader. if (isa<PHINode>(I)) break; + // Don't move instructions which might have side effects, since the side - // effects need to complete before instructions inside the loop. Also - // don't move instructions which might read memory, since the loop may - // modify memory. Note that it's okay if the instruction might have - // undefined behavior: LoopSimplify guarantees that the preheader - // dominates the exit block. + // effects need to complete before instructions inside the loop. Also don't + // move instructions which might read memory, since the loop may modify + // memory. Note that it's okay if the instruction might have undefined + // behavior: LoopSimplify guarantees that the preheader dominates the exit + // block. if (I->mayHaveSideEffects() || I->mayReadFromMemory()) continue; + // Skip debug info intrinsics. if (isa<DbgInfoIntrinsic>(I)) continue; + // Don't sink static AllocaInsts out of the entry block, which would // turn them into dynamic allocas! if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) if (AI->isStaticAlloca()) continue; + // Determine if there is a use in or before the loop (direct or // otherwise). bool UsedInLoop = false; @@ -585,19 +589,29 @@ void IndVarSimplify::SinkUnusedInvariants(Loop *L) { break; } } + // If there is, the def must remain in the preheader. if (UsedInLoop) continue; + // Otherwise, sink it to the exit block. Instruction *ToMove = I; bool Done = false; - if (I != Preheader->begin()) - --I; - else + + if (I != Preheader->begin()) { + // Skip debug info intrinsics. + do { + --I; + } while (isa<DbgInfoIntrinsic>(I) && I != Preheader->begin()); + + if (isa<DbgInfoIntrinsic>(I) && I == Preheader->begin()) + Done = true; + } else { Done = true; + } + ToMove->moveBefore(InsertPt); - if (Done) - break; + if (Done) break; InsertPt = ToMove; } } diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index f920dca..625a75d 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -1899,7 +1899,7 @@ LSRInstance::CollectLoopInvariantFixupsAndFormulae() { const Value *V = U->getValue(); if (const Instruction *Inst = dyn_cast<Instruction>(V)) if (L->contains(Inst)) continue; - for (Value::use_const_iterator UI = V->use_begin(), UE = V->use_end(); + for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE; ++UI) { const Instruction *UserInst = dyn_cast<Instruction>(*UI); // Ignore non-instructions. @@ -2827,6 +2827,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF, IP = Tentative; } while (isa<PHINode>(IP)) ++IP; + while (isa<DbgInfoIntrinsic>(IP)) ++IP; // Inform the Rewriter if we have a post-increment use, so that it can // perform an advantageous expansion. @@ -2864,8 +2865,10 @@ Value *LSRInstance::Expand(const LSRFixup &LF, // so that it is dominated by its operand. If the original insert point // was already dominated by the increment, keep it, because there may // be loop-variant operands that need to be respected also. - if (L->contains(LF.UserInst) && !DT.dominates(IVIncInsertPos, IP)) + if (L->contains(LF.UserInst) && !DT.dominates(IVIncInsertPos, IP)) { IP = IVIncInsertPos; + while (isa<DbgInfoIntrinsic>(IP)) ++IP; + } break; } Start = AR->getStart(); diff --git a/lib/Transforms/Scalar/Reg2Mem.cpp b/lib/Transforms/Scalar/Reg2Mem.cpp index 99e1252..7a6eec3 100644 --- a/lib/Transforms/Scalar/Reg2Mem.cpp +++ b/lib/Transforms/Scalar/Reg2Mem.cpp @@ -45,7 +45,7 @@ namespace { bool valueEscapes(const Instruction *Inst) const { const BasicBlock *BB = Inst->getParent(); - for (Value::use_const_iterator UI = Inst->use_begin(),E = Inst->use_end(); + for (Value::const_use_iterator UI = Inst->use_begin(),E = Inst->use_end(); UI != E; ++UI) if (cast<Instruction>(*UI)->getParent() != BB || isa<PHINode>(*UI)) diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 7e37938..546b7b6 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -1705,28 +1705,31 @@ ModulePass *llvm::createIPSCCPPass() { } -static bool AddressIsTaken(GlobalValue *GV) { +static bool AddressIsTaken(const GlobalValue *GV) { // Delete any dead constantexpr klingons. GV->removeDeadConstantUsers(); - for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); - UI != E; ++UI) - if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) { + for (Value::const_use_iterator UI = GV->use_begin(), E = GV->use_end(); + UI != E; ++UI) { + const User *U = *UI; + if (const StoreInst *SI = dyn_cast<StoreInst>(U)) { if (SI->getOperand(0) == GV || SI->isVolatile()) return true; // Storing addr of GV. - } else if (isa<InvokeInst>(*UI) || isa<CallInst>(*UI)) { + } else if (isa<InvokeInst>(U) || isa<CallInst>(U)) { // Make sure we are calling the function, not passing the address. - if (UI.getOperandNo() != 0) + ImmutableCallSite CS(cast<Instruction>(U)); + if (!CS.isCallee(UI)) return true; - } else if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) { + } else if (const LoadInst *LI = dyn_cast<LoadInst>(U)) { if (LI->isVolatile()) return true; - } else if (isa<BlockAddress>(*UI)) { + } else if (isa<BlockAddress>(U)) { // blockaddress doesn't take the address of the function, it takes addr // of label. } else { return true; } + } return false; } diff --git a/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/lib/Transforms/Scalar/SimplifyCFGPass.cpp index 738c5e8..b621e8d 100644 --- a/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -79,7 +79,7 @@ static void ChangeToUnreachable(Instruction *I) { /// ChangeToCall - Convert the specified invoke into a normal call. static void ChangeToCall(InvokeInst *II) { BasicBlock *BB = II->getParent(); - SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end()); + SmallVector<Value*, 8> Args(II->op_begin(), II->op_end() - 3); CallInst *NewCall = CallInst::Create(II->getCalledValue(), Args.begin(), Args.end(), "", II); NewCall->takeName(II); diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 22f3628..5941ea6 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -350,10 +350,16 @@ struct StrNCmpOpt : public LibCallOptimization { // 'strcpy' Optimizations struct StrCpyOpt : public LibCallOptimization { + bool OptChkCall; // True if it's optimizing a __strcpy_chk libcall. + + StrCpyOpt(bool c) : OptChkCall(c) {} + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { // Verify the "strcpy" function prototype. + unsigned NumParams = OptChkCall ? 3 : 2; const FunctionType *FT = Callee->getFunctionType(); - if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || + if (FT->getNumParams() != NumParams || + FT->getReturnType() != FT->getParamType(0) || FT->getParamType(0) != FT->getParamType(1) || FT->getParamType(0) != Type::getInt8PtrTy(*Context)) return 0; @@ -371,8 +377,13 @@ struct StrCpyOpt : public LibCallOptimization { // We have enough information to now generate the memcpy call to do the // concatenation for us. Make a memcpy to copy the nul byte with align = 1. - EmitMemCpy(Dst, Src, - ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD); + if (OptChkCall) + EmitMemCpyChk(Dst, Src, + ConstantInt::get(TD->getIntPtrType(*Context), Len), + CI->getOperand(3), B, TD); + else + EmitMemCpy(Dst, Src, + ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B, TD); return Dst; } }; @@ -1162,7 +1173,8 @@ namespace { StringMap<LibCallOptimization*> Optimizations; // String and Memory LibCall Optimizations StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrCmpOpt StrCmp; - StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrNCpyOpt StrNCpy; StrLenOpt StrLen; + StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrCpyOpt StrCpyChk; + StrNCpyOpt StrNCpy; StrLenOpt StrLen; StrToOpt StrTo; StrStrOpt StrStr; MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet; // Math Library Optimizations @@ -1177,8 +1189,7 @@ namespace { bool Modified; // This is only used by doInitialization. public: static char ID; // Pass identification - SimplifyLibCalls() : FunctionPass(&ID) {} - + SimplifyLibCalls() : FunctionPass(&ID), StrCpy(false), StrCpyChk(true) {} void InitOptimizations(); bool runOnFunction(Function &F); @@ -1228,6 +1239,9 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["memmove"] = &MemMove; Optimizations["memset"] = &MemSet; + // _chk variants of String and Memory LibCall Optimizations. + Optimizations["__strcpy_chk"] = &StrCpyChk; + // Math Library Optimizations Optimizations["powf"] = &Pow; Optimizations["pow"] = &Pow; |