Skip to content

Commit 99166fd

Browse files
committed
[SCEVExpander] Add option to preserve LCSSA directly.
This patch teaches SCEVExpander to directly preserve LCSSA. As it is currently, SCEV does not look through PHI nodes in loops, as it might break LCSSA form. Once SCEVExpander can preserve LCSSA form, it should be safe for SCEV to look through PHIs. To preserve LCSSA form, this patch uses formLCSSAForInstructions on operands of newly created instructions, if the definition is inside a different loop than the new instruction. The final value we return from expandCodeFor may also need LCSSA phis, depending on the insert point. As no user for it exists there yet, create a temporary instruction at the insert point, which can be passed to formLCSSAForInstructions. This temporary instruction is removed after LCSSA construction. Reviewed By: mkazantsev Differential Revision: https://reviews.llvm.org/D71538
1 parent 6673c6c commit 99166fd

File tree

4 files changed

+166
-61
lines changed

4 files changed

+166
-61
lines changed

llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
5252
// New instructions receive a name to identify them with the current pass.
5353
const char *IVName;
5454

55+
/// Indicates whether LCSSA phis should be created for inserted values.
56+
bool PreserveLCSSA;
57+
5558
// InsertedExpressions caches Values for reuse, so must track RAUW.
5659
DenseMap<std::pair<const SCEV *, Instruction *>, TrackingVH<Value>>
5760
InsertedExpressions;
@@ -146,9 +149,10 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
146149
public:
147150
/// Construct a SCEVExpander in "canonical" mode.
148151
explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
149-
const char *name)
150-
: SE(se), DL(DL), IVName(name), IVIncInsertLoop(nullptr),
151-
IVIncInsertPos(nullptr), CanonicalMode(true), LSRMode(false),
152+
const char *name, bool PreserveLCSSA = true)
153+
: SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA),
154+
IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true),
155+
LSRMode(false),
152156
Builder(se.getContext(), TargetFolder(DL),
153157
IRBuilderCallbackInserter(
154158
[this](Instruction *I) { rememberInstruction(I); })) {
@@ -223,14 +227,18 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
223227
const TargetTransformInfo *TTI = nullptr);
224228

225229
/// Insert code to directly compute the specified SCEV expression into the
226-
/// program. The inserted code is inserted into the specified block.
227-
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
230+
/// program. The code is inserted into the specified block.
231+
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) {
232+
return expandCodeForImpl(SH, Ty, I, true);
233+
}
228234

229235
/// Insert code to directly compute the specified SCEV expression into the
230-
/// program. The inserted code is inserted into the SCEVExpander's current
236+
/// program. The code is inserted into the SCEVExpander's current
231237
/// insertion point. If a type is specified, the result will be expanded to
232238
/// have that type, with a cast if necessary.
233-
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
239+
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr) {
240+
return expandCodeForImpl(SH, Ty, true);
241+
}
234242

235243
/// Generates a code sequence that evaluates this predicate. The inserted
236244
/// instructions will be at position \p Loc. The result will be of type i1
@@ -338,6 +346,20 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
338346
private:
339347
LLVMContext &getContext() const { return SE.getContext(); }
340348

349+
/// Insert code to directly compute the specified SCEV expression into the
350+
/// program. The code is inserted into the SCEVExpander's current
351+
/// insertion point. If a type is specified, the result will be expanded to
352+
/// have that type, with a cast if necessary. If \p Root is true, this
353+
/// indicates that \p SH is the top-level expression to expand passed from
354+
/// an external client call.
355+
Value *expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root);
356+
357+
/// Insert code to directly compute the specified SCEV expression into the
358+
/// program. The code is inserted into the specified block. If \p
359+
/// Root is true, this indicates that \p SH is the top-level expression to
360+
/// expand passed from an external client call.
361+
Value *expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *I, bool Root);
362+
341363
/// Recursive helper function for isHighCostExpansion.
342364
bool isHighCostExpansionHelper(const SCEV *S, Loop *L, const Instruction &At,
343365
int &BudgetRemaining,
@@ -419,6 +441,11 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
419441
Instruction *Pos, PHINode *LoopPhi);
420442

421443
void fixupInsertPoints(Instruction *I);
444+
445+
/// If required, create LCSSA PHIs for \p Users' operand \p OpIdx. If new
446+
/// LCSSA PHIs have been created, return the LCSSA PHI available at \p User.
447+
/// If no PHIs have been created, return the unchanged operand \p OpIdx.
448+
Value *fixupLCSSAFormFor(Instruction *User, unsigned OpIdx);
422449
};
423450
} // namespace llvm
424451

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5514,8 +5514,8 @@ void LSRInstance::ImplementSolution(
55145514
// we can remove them after we are done working.
55155515
SmallVector<WeakTrackingVH, 16> DeadInsts;
55165516

5517-
SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(),
5518-
"lsr");
5517+
SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), "lsr",
5518+
false);
55195519
#ifndef NDEBUG
55205520
Rewriter.setDebugType(DEBUG_TYPE);
55215521
#endif
@@ -5780,7 +5780,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
57805780
if (EnablePhiElim && L->isLoopSimplifyForm()) {
57815781
SmallVector<WeakTrackingVH, 16> DeadInsts;
57825782
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
5783-
SCEVExpander Rewriter(SE, DL, "lsr");
5783+
SCEVExpander Rewriter(SE, DL, "lsr", false);
57845784
#ifndef NDEBUG
57855785
Rewriter.setDebugType(DEBUG_TYPE);
57865786
#endif

0 commit comments

Comments
 (0)