aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
diff options
context:
space:
mode:
authorFlorian Hahn <flo@fhahn.com>2022-09-29 20:49:55 +0100
committerFlorian Hahn <flo@fhahn.com>2022-09-29 20:49:56 +0100
commit9933a2e9fd0c37dcdce5952fab7e486d3cf2d336 (patch)
treee4e9d9112b1f2b3806223649f6fdd44a43e9b389 /llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
parent0513b0305acde91a0a5f7f5ea4061476011f0d1d (diff)
downloadllvm-9933a2e9fd0c37dcdce5952fab7e486d3cf2d336.zip
llvm-9933a2e9fd0c37dcdce5952fab7e486d3cf2d336.tar.gz
llvm-9933a2e9fd0c37dcdce5952fab7e486d3cf2d336.tar.bz2
[SCEVExpander] Move LCSSA fixup to ::expand.
Move LCSSA fixup from ::expandCodeForImpl to ::expand(). This has the advantage that we directly preserve LCSSA nodes here instead of relying on doing so in rememberInstruction. It also ensures that we don't add the non-LCSSA-safe value to InsertedExpressions. Alternative to D132704. Fixes #57000. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D134739
Diffstat (limited to 'llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp83
1 files changed, 32 insertions, 51 deletions
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index bc2779a..84db277 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -14,6 +14,7 @@
#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
@@ -1742,30 +1743,6 @@ Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty) {
// Expand the code for this SCEV.
Value *V = expand(SH);
- if (PreserveLCSSA) {
- if (auto *Inst = dyn_cast<Instruction>(V)) {
- // Create a temporary instruction to at the current insertion point, so we
- // can hand it off to the helper to create LCSSA PHIs if required for the
- // new use.
- // FIXME: Ideally formLCSSAForInstructions (used in fixupLCSSAFormFor)
- // would accept a insertion point and return an LCSSA phi for that
- // insertion point, so there is no need to insert & remove the temporary
- // instruction.
- Type *ToTy;
- if (Inst->getType()->isIntegerTy())
- ToTy = Inst->getType()->getPointerTo();
- else
- ToTy = Type::getInt32Ty(Inst->getContext());
- Instruction *Tmp = CastInst::CreateBitOrPointerCast(
- Inst, ToTy, "tmp.lcssa.user", &*Builder.GetInsertPoint());
- V = fixupLCSSAFormFor(Tmp, 0);
-
- // Clean up temporary instruction.
- Tmp->eraseFromParent();
- }
- }
-
- InsertedExpressions[std::make_pair(SH, &*Builder.GetInsertPoint())] = V;
if (Ty) {
assert(SE.getTypeSizeInBits(Ty) == SE.getTypeSizeInBits(SH->getType()) &&
"non-trivial casts should be done with the SCEVs directly!");
@@ -1870,9 +1847,10 @@ Value *SCEVExpander::expand(const SCEV *S) {
// Expand the expression into instructions.
Value *V = FindValueInExprValueMap(S, InsertPt);
- if (!V)
+ if (!V) {
V = visit(S);
- else {
+ V = fixupLCSSAFormFor(V);
+ } else {
// If we're reusing an existing instruction, we are effectively CSEing two
// copies of the instruction (with potentially different flags). As such,
// we need to drop any poison generating flags unless we can prove that
@@ -1899,18 +1877,6 @@ void SCEVExpander::rememberInstruction(Value *I) {
InsertedValues.insert(V);
};
DoInsert(I);
-
- if (!PreserveLCSSA)
- return;
-
- if (auto *Inst = dyn_cast<Instruction>(I)) {
- // A new instruction has been added, which might introduce new uses outside
- // a defining loop. Fix LCSSA from for each operand of the new instruction,
- // if required.
- for (unsigned OpIdx = 0, OpEnd = Inst->getNumOperands(); OpIdx != OpEnd;
- OpIdx++)
- fixupLCSSAFormFor(Inst, OpIdx);
- }
}
/// replaceCongruentIVs - Check for congruent phis in this loop header and
@@ -2541,21 +2507,36 @@ Value *SCEVExpander::expandUnionPredicate(const SCEVUnionPredicate *Union,
return Builder.CreateOr(Checks);
}
-Value *SCEVExpander::fixupLCSSAFormFor(Instruction *User, unsigned OpIdx) {
- assert(PreserveLCSSA);
- SmallVector<Instruction *, 1> ToUpdate;
-
- auto *OpV = User->getOperand(OpIdx);
- auto *OpI = dyn_cast<Instruction>(OpV);
- if (!OpI)
- return OpV;
+Value *SCEVExpander::fixupLCSSAFormFor(Value *V) {
+ auto *DefI = dyn_cast<Instruction>(V);
+ if (!PreserveLCSSA || !DefI)
+ return V;
- Loop *DefLoop = SE.LI.getLoopFor(OpI->getParent());
- Loop *UseLoop = SE.LI.getLoopFor(User->getParent());
+ Instruction *InsertPt = &*Builder.GetInsertPoint();
+ Loop *DefLoop = SE.LI.getLoopFor(DefI->getParent());
+ Loop *UseLoop = SE.LI.getLoopFor(InsertPt->getParent());
if (!DefLoop || UseLoop == DefLoop || DefLoop->contains(UseLoop))
- return OpV;
+ return V;
- ToUpdate.push_back(OpI);
+ // Create a temporary instruction to at the current insertion point, so we
+ // can hand it off to the helper to create LCSSA PHIs if required for the
+ // new use.
+ // FIXME: Ideally formLCSSAForInstructions (used in fixupLCSSAFormFor)
+ // would accept a insertion point and return an LCSSA phi for that
+ // insertion point, so there is no need to insert & remove the temporary
+ // instruction.
+ Type *ToTy;
+ if (DefI->getType()->isIntegerTy())
+ ToTy = DefI->getType()->getPointerTo();
+ else
+ ToTy = Type::getInt32Ty(DefI->getContext());
+ Instruction *User =
+ CastInst::CreateBitOrPointerCast(DefI, ToTy, "tmp.lcssa.user", InsertPt);
+ auto RemoveUserOnExit =
+ make_scope_exit([User]() { User->eraseFromParent(); });
+
+ SmallVector<Instruction *, 1> ToUpdate;
+ ToUpdate.push_back(DefI);
SmallVector<PHINode *, 16> PHIsToRemove;
formLCSSAForInstructions(ToUpdate, SE.DT, SE.LI, &SE, Builder, &PHIsToRemove);
for (PHINode *PN : PHIsToRemove) {
@@ -2566,7 +2547,7 @@ Value *SCEVExpander::fixupLCSSAFormFor(Instruction *User, unsigned OpIdx) {
PN->eraseFromParent();
}
- return User->getOperand(OpIdx);
+ return User->getOperand(0);
}
namespace {