summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/lib/Transforms/Utils/LCSSA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/llvm/lib/Transforms/Utils/LCSSA.cpp')
-rw-r--r--gnu/llvm/lib/Transforms/Utils/LCSSA.cpp51
1 files changed, 39 insertions, 12 deletions
diff --git a/gnu/llvm/lib/Transforms/Utils/LCSSA.cpp b/gnu/llvm/lib/Transforms/Utils/LCSSA.cpp
index ae0e2bb6c28..53d444b309d 100644
--- a/gnu/llvm/lib/Transforms/Utils/LCSSA.cpp
+++ b/gnu/llvm/lib/Transforms/Utils/LCSSA.cpp
@@ -10,7 +10,7 @@
// This pass transforms loops by placing phi nodes at the end of the loops for
// all values that are live across the loop boundary. For example, it turns
// the left into the right code:
-//
+//
// for (...) for (...)
// if (c) if (c)
// X1 = ... X1 = ...
@@ -21,8 +21,8 @@
// ... = X4 + 4
//
// This is still valid LLVM; the extra phi nodes are purely redundant, and will
-// be trivially eliminated by InstCombine. The major benefit of this
-// transformation is that it makes many other loop optimizations, such as
+// be trivially eliminated by InstCombine. The major benefit of this
+// transformation is that it makes many other loop optimizations, such as
// LoopUnswitching, simpler.
//
//===----------------------------------------------------------------------===//
@@ -36,13 +36,15 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PredIteratorCache.h"
#include "llvm/Pass.h"
-#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
using namespace llvm;
@@ -143,7 +145,8 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
PHINode *PN = PHINode::Create(I->getType(), PredCache.size(ExitBB),
I->getName() + ".lcssa", &ExitBB->front());
-
+ // Get the debug location from the original instruction.
+ PN->setDebugLoc(I->getDebugLoc());
// Add inputs from inside the loop for this PHI.
for (BasicBlock *Pred : PredCache.get(ExitBB)) {
PN->addIncoming(I, Pred);
@@ -199,6 +202,21 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
SSAUpdate.RewriteUse(*UseToRewrite);
}
+ SmallVector<DbgValueInst *, 4> DbgValues;
+ llvm::findDbgValues(DbgValues, I);
+
+ // Update pre-existing debug value uses that reside outside the loop.
+ auto &Ctx = I->getContext();
+ for (auto DVI : DbgValues) {
+ BasicBlock *UserBB = DVI->getParent();
+ if (InstBB == UserBB || L->contains(UserBB))
+ continue;
+ // We currently only handle debug values residing in blocks where we have
+ // inserted a PHI instruction.
+ if (Value *V = SSAUpdate.FindValueForBlock(UserBB))
+ DVI->setOperand(0, MetadataAsValue::get(Ctx, ValueAsMetadata::get(V)));
+ }
+
// SSAUpdater might have inserted phi-nodes inside other loops. We'll need
// to post-process them to keep LCSSA form.
for (PHINode *InsertedPN : InsertedPHIs) {
@@ -214,18 +232,27 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
Worklist.push_back(PostProcessPN);
// Keep track of PHI nodes that we want to remove because they did not have
- // any uses rewritten.
+ // any uses rewritten. If the new PHI is used, store it so that we can
+ // try to propagate dbg.value intrinsics to it.
+ SmallVector<PHINode *, 2> NeedDbgValues;
for (PHINode *PN : AddedPHIs)
if (PN->use_empty())
PHIsToRemove.insert(PN);
-
+ else
+ NeedDbgValues.push_back(PN);
+ insertDebugValuesForPHIs(InstBB, NeedDbgValues);
Changed = true;
}
- // Remove PHI nodes that did not have any uses rewritten.
- for (PHINode *PN : PHIsToRemove) {
- assert (PN->use_empty() && "Trying to remove a phi with uses.");
- PN->eraseFromParent();
- }
+ // Remove PHI nodes that did not have any uses rewritten. We need to redo the
+ // use_empty() check here, because even if the PHI node wasn't used when added
+ // to PHIsToRemove, later added PHI nodes can be using it. This cleanup is
+ // not guaranteed to handle trees/cycles of PHI nodes that only are used by
+ // each other. Such situations has only been noticed when the input IR
+ // contains unreachable code, and leaving some extra redundant PHI nodes in
+ // such situations is considered a minor problem.
+ for (PHINode *PN : PHIsToRemove)
+ if (PN->use_empty())
+ PN->eraseFromParent();
return Changed;
}