summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp60
1 files changed, 57 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index d3a4d353f9a..2bd337814b4 100644
--- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -14,6 +14,7 @@
#include "llvm/Pass.h"
#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/Statistic.h"
@@ -1009,6 +1010,62 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
}
}
+ // Now that we're done with the algorithm, see if we can optimize the
+ // results slightly by reducing the number of new instructions needed.
+ // Arguably, this should be integrated into the algorithm above, but
+ // doing as a post process step is easier to reason about for the moment.
+ DenseMap<Value *, Value *> ReverseMap;
+ SmallPtrSet<Instruction *, 16> NewInsts;
+ SmallSetVector<Instruction *, 16> Worklist;
+ for (auto Item : states) {
+ Value *V = Item.first;
+ Value *Base = Item.second.getBase();
+ assert(V && Base);
+ assert(!isKnownBaseResult(V) && "why did it get added?");
+ assert(isKnownBaseResult(Base) &&
+ "must be something we 'know' is a base pointer");
+ if (!Item.second.isConflict())
+ continue;
+
+ ReverseMap[Base] = V;
+ if (auto *BaseI = dyn_cast<Instruction>(Base)) {
+ NewInsts.insert(BaseI);
+ Worklist.insert(BaseI);
+ }
+ }
+ auto PushNewUsers = [&](Instruction *I) {
+ for (User *U : I->users())
+ if (auto *UI = dyn_cast<Instruction>(U))
+ if (NewInsts.count(UI))
+ Worklist.insert(UI);
+ };
+ const DataLayout &DL = cast<Instruction>(def)->getModule()->getDataLayout();
+ while (!Worklist.empty()) {
+ Instruction *BaseI = Worklist.pop_back_val();
+ Value *Bdv = ReverseMap[BaseI];
+ if (auto *BdvI = dyn_cast<Instruction>(Bdv))
+ if (BaseI->isIdenticalTo(BdvI)) {
+ DEBUG(dbgs() << "Identical Base: " << *BaseI << "\n");
+ PushNewUsers(BaseI);
+ BaseI->replaceAllUsesWith(Bdv);
+ BaseI->eraseFromParent();
+ states[Bdv] = BDVState(BDVState::Conflict, Bdv);
+ NewInsts.erase(BaseI);
+ ReverseMap.erase(BaseI);
+ continue;
+ }
+ if (Value *V = SimplifyInstruction(BaseI, DL)) {
+ DEBUG(dbgs() << "Base " << *BaseI << " simplified to " << *V << "\n");
+ PushNewUsers(BaseI);
+ BaseI->replaceAllUsesWith(V);
+ BaseI->eraseFromParent();
+ states[Bdv] = BDVState(BDVState::Conflict, V);
+ NewInsts.erase(BaseI);
+ ReverseMap.erase(BaseI);
+ continue;
+ }
+ }
+
// Cache all of our results so we can cheaply reuse them
// NOTE: This is actually two caches: one of the base defining value
// relation and one of the base pointer relation! FIXME
@@ -1016,7 +1073,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
Value *v = item.first;
Value *base = item.second.getBase();
assert(v && base);
- assert(!isKnownBaseResult(v) && "why did it get added?");
if (TraceLSP) {
std::string fromstr =
@@ -1028,8 +1084,6 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &cache) {
<< " to: " << (base->hasName() ? base->getName() : "") << "\n";
}
- assert(isKnownBaseResult(base) &&
- "must be something we 'know' is a base pointer");
if (cache.count(v)) {
// Once we transition from the BDV relation being store in the cache to
// the base relation being stored, it must be stable
OpenPOWER on IntegriCloud