mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-28 22:00:30 +00:00
Reland "[SCEVExpander] Add option to preserve LCSSA directly."
This reverts the revert commit dc2867576886247cbe351e7c63618c09ab6af808. It includes a fix for Polly, which uses SCEVExpander on IR that is not in LCSSA form. Set PreserveLCSSA = false in that case, to ensure we do not introduce LCSSA phis where there were none before.
This commit is contained in:
parent
d6bf6e55ee
commit
bf9e3782d5
@ -52,6 +52,9 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
|
||||
// New instructions receive a name to identify them with the current pass.
|
||||
const char *IVName;
|
||||
|
||||
/// Indicates whether LCSSA phis should be created for inserted values.
|
||||
bool PreserveLCSSA;
|
||||
|
||||
// InsertedExpressions caches Values for reuse, so must track RAUW.
|
||||
DenseMap<std::pair<const SCEV *, Instruction *>, TrackingVH<Value>>
|
||||
InsertedExpressions;
|
||||
@ -146,9 +149,10 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
|
||||
public:
|
||||
/// Construct a SCEVExpander in "canonical" mode.
|
||||
explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
|
||||
const char *name)
|
||||
: SE(se), DL(DL), IVName(name), IVIncInsertLoop(nullptr),
|
||||
IVIncInsertPos(nullptr), CanonicalMode(true), LSRMode(false),
|
||||
const char *name, bool PreserveLCSSA = true)
|
||||
: SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA),
|
||||
IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true),
|
||||
LSRMode(false),
|
||||
Builder(se.getContext(), TargetFolder(DL),
|
||||
IRBuilderCallbackInserter(
|
||||
[this](Instruction *I) { rememberInstruction(I); })) {
|
||||
@ -223,14 +227,18 @@ public:
|
||||
const TargetTransformInfo *TTI = nullptr);
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
/// program. The inserted code is inserted into the specified block.
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I);
|
||||
/// program. The code is inserted into the specified block.
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) {
|
||||
return expandCodeForImpl(SH, Ty, I, true);
|
||||
}
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
/// program. The inserted code is inserted into the SCEVExpander's current
|
||||
/// program. The code is inserted into the SCEVExpander's current
|
||||
/// insertion point. If a type is specified, the result will be expanded to
|
||||
/// have that type, with a cast if necessary.
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr);
|
||||
Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr) {
|
||||
return expandCodeForImpl(SH, Ty, true);
|
||||
}
|
||||
|
||||
/// Generates a code sequence that evaluates this predicate. The inserted
|
||||
/// instructions will be at position \p Loc. The result will be of type i1
|
||||
@ -338,6 +346,20 @@ public:
|
||||
private:
|
||||
LLVMContext &getContext() const { return SE.getContext(); }
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
/// program. The code is inserted into the SCEVExpander's current
|
||||
/// insertion point. If a type is specified, the result will be expanded to
|
||||
/// have that type, with a cast if necessary. If \p Root is true, this
|
||||
/// indicates that \p SH is the top-level expression to expand passed from
|
||||
/// an external client call.
|
||||
Value *expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root);
|
||||
|
||||
/// Insert code to directly compute the specified SCEV expression into the
|
||||
/// program. The code is inserted into the specified block. If \p
|
||||
/// Root is true, this indicates that \p SH is the top-level expression to
|
||||
/// expand passed from an external client call.
|
||||
Value *expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *I, bool Root);
|
||||
|
||||
/// Recursive helper function for isHighCostExpansion.
|
||||
bool isHighCostExpansionHelper(const SCEV *S, Loop *L, const Instruction &At,
|
||||
int &BudgetRemaining,
|
||||
@ -419,6 +441,11 @@ private:
|
||||
Instruction *Pos, PHINode *LoopPhi);
|
||||
|
||||
void fixupInsertPoints(Instruction *I);
|
||||
|
||||
/// If required, create LCSSA PHIs for \p Users' operand \p OpIdx. If new
|
||||
/// LCSSA PHIs have been created, return the LCSSA PHI available at \p User.
|
||||
/// If no PHIs have been created, return the unchanged operand \p OpIdx.
|
||||
Value *fixupLCSSAFormFor(Instruction *User, unsigned OpIdx);
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
|
@ -5514,8 +5514,8 @@ void LSRInstance::ImplementSolution(
|
||||
// we can remove them after we are done working.
|
||||
SmallVector<WeakTrackingVH, 16> DeadInsts;
|
||||
|
||||
SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(),
|
||||
"lsr");
|
||||
SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), "lsr",
|
||||
false);
|
||||
#ifndef NDEBUG
|
||||
Rewriter.setDebugType(DEBUG_TYPE);
|
||||
#endif
|
||||
@ -5780,7 +5780,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
|
||||
if (EnablePhiElim && L->isLoopSimplifyForm()) {
|
||||
SmallVector<WeakTrackingVH, 16> DeadInsts;
|
||||
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
|
||||
SCEVExpander Rewriter(SE, DL, "lsr");
|
||||
SCEVExpander Rewriter(SE, DL, "lsr", false);
|
||||
#ifndef NDEBUG
|
||||
Rewriter.setDebugType(DEBUG_TYPE);
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Transforms/Utils/LoopUtils.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -461,9 +462,10 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
|
||||
// we didn't find any operands that could be factored, tentatively
|
||||
// assume that element zero was selected (since the zero offset
|
||||
// would obviously be folded away).
|
||||
Value *Scaled = ScaledOps.empty() ?
|
||||
Constant::getNullValue(Ty) :
|
||||
expandCodeFor(SE.getAddExpr(ScaledOps), Ty);
|
||||
Value *Scaled =
|
||||
ScaledOps.empty()
|
||||
? Constant::getNullValue(Ty)
|
||||
: expandCodeForImpl(SE.getAddExpr(ScaledOps), Ty, false);
|
||||
GepIndices.push_back(Scaled);
|
||||
|
||||
// Collect struct field index operands.
|
||||
@ -522,7 +524,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin,
|
||||
SE.DT.dominates(cast<Instruction>(V), &*Builder.GetInsertPoint()));
|
||||
|
||||
// Expand the operands for a plain byte offset.
|
||||
Value *Idx = expandCodeFor(SE.getAddExpr(Ops), Ty);
|
||||
Value *Idx = expandCodeForImpl(SE.getAddExpr(Ops), Ty, false);
|
||||
|
||||
// Fold a GEP with constant operands.
|
||||
if (Constant *CLHS = dyn_cast<Constant>(V))
|
||||
@ -743,14 +745,14 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) {
|
||||
Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, expand(Op));
|
||||
} else if (Op->isNonConstantNegative()) {
|
||||
// Instead of doing a negate and add, just do a subtract.
|
||||
Value *W = expandCodeFor(SE.getNegativeSCEV(Op), Ty);
|
||||
Value *W = expandCodeForImpl(SE.getNegativeSCEV(Op), Ty, false);
|
||||
Sum = InsertNoopCastOfTo(Sum, Ty);
|
||||
Sum = InsertBinop(Instruction::Sub, Sum, W, SCEV::FlagAnyWrap,
|
||||
/*IsSafeToHoist*/ true);
|
||||
++I;
|
||||
} else {
|
||||
// A simple add.
|
||||
Value *W = expandCodeFor(Op, Ty);
|
||||
Value *W = expandCodeForImpl(Op, Ty, false);
|
||||
Sum = InsertNoopCastOfTo(Sum, Ty);
|
||||
// Canonicalize a constant to the RHS.
|
||||
if (isa<Constant>(Sum)) std::swap(Sum, W);
|
||||
@ -802,7 +804,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
|
||||
|
||||
// Calculate powers with exponents 1, 2, 4, 8 etc. and include those of them
|
||||
// that are needed into the result.
|
||||
Value *P = expandCodeFor(I->second, Ty);
|
||||
Value *P = expandCodeForImpl(I->second, Ty, false);
|
||||
Value *Result = nullptr;
|
||||
if (Exponent & 1)
|
||||
Result = P;
|
||||
@ -861,7 +863,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) {
|
||||
Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
|
||||
Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
|
||||
Value *LHS = expandCodeFor(S->getLHS(), Ty);
|
||||
Value *LHS = expandCodeForImpl(S->getLHS(), Ty, false);
|
||||
if (const SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getRHS())) {
|
||||
const APInt &RHS = SC->getAPInt();
|
||||
if (RHS.isPowerOf2())
|
||||
@ -870,7 +872,7 @@ Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) {
|
||||
SCEV::FlagAnyWrap, /*IsSafeToHoist*/ true);
|
||||
}
|
||||
|
||||
Value *RHS = expandCodeFor(S->getRHS(), Ty);
|
||||
Value *RHS = expandCodeForImpl(S->getRHS(), Ty, false);
|
||||
return InsertBinop(Instruction::UDiv, LHS, RHS, SCEV::FlagAnyWrap,
|
||||
/*IsSafeToHoist*/ SE.isKnownNonZero(S->getRHS()));
|
||||
}
|
||||
@ -1265,8 +1267,9 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
|
||||
// Expand code for the start value into the loop preheader.
|
||||
assert(L->getLoopPreheader() &&
|
||||
"Can't expand add recurrences without a loop preheader!");
|
||||
Value *StartV = expandCodeFor(Normalized->getStart(), ExpandTy,
|
||||
L->getLoopPreheader()->getTerminator());
|
||||
Value *StartV =
|
||||
expandCodeForImpl(Normalized->getStart(), ExpandTy,
|
||||
L->getLoopPreheader()->getTerminator(), false);
|
||||
|
||||
// StartV must have been be inserted into L's preheader to dominate the new
|
||||
// phi.
|
||||
@ -1284,8 +1287,8 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
|
||||
if (useSubtract)
|
||||
Step = SE.getNegativeSCEV(Step);
|
||||
// Expand the step somewhere that dominates the loop header.
|
||||
Value *StepV = expandCodeFor(Step, IntTy,
|
||||
&*L->getHeader()->getFirstInsertionPt());
|
||||
Value *StepV = expandCodeForImpl(
|
||||
Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
|
||||
|
||||
// The no-wrap behavior proved by IsIncrement(NUW|NSW) is only applicable if
|
||||
// we actually do emit an addition. It does not apply if we emit a
|
||||
@ -1430,8 +1433,8 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
|
||||
{
|
||||
// Expand the step somewhere that dominates the loop header.
|
||||
SCEVInsertPointGuard Guard(Builder, this);
|
||||
StepV = expandCodeFor(Step, IntTy,
|
||||
&*L->getHeader()->getFirstInsertionPt());
|
||||
StepV = expandCodeForImpl(
|
||||
Step, IntTy, &*L->getHeader()->getFirstInsertionPt(), false);
|
||||
}
|
||||
Result = expandIVInc(PN, StepV, L, ExpandTy, IntTy, useSubtract);
|
||||
}
|
||||
@ -1450,8 +1453,8 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
|
||||
|
||||
// Invert the result.
|
||||
if (InvertStep)
|
||||
Result = Builder.CreateSub(expandCodeFor(Normalized->getStart(), TruncTy),
|
||||
Result);
|
||||
Result = Builder.CreateSub(
|
||||
expandCodeForImpl(Normalized->getStart(), TruncTy, false), Result);
|
||||
}
|
||||
|
||||
// Re-apply any non-loop-dominating scale.
|
||||
@ -1459,22 +1462,22 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) {
|
||||
assert(S->isAffine() && "Can't linearly scale non-affine recurrences.");
|
||||
Result = InsertNoopCastOfTo(Result, IntTy);
|
||||
Result = Builder.CreateMul(Result,
|
||||
expandCodeFor(PostLoopScale, IntTy));
|
||||
expandCodeForImpl(PostLoopScale, IntTy, false));
|
||||
}
|
||||
|
||||
// Re-apply any non-loop-dominating offset.
|
||||
if (PostLoopOffset) {
|
||||
if (PointerType *PTy = dyn_cast<PointerType>(ExpandTy)) {
|
||||
if (Result->getType()->isIntegerTy()) {
|
||||
Value *Base = expandCodeFor(PostLoopOffset, ExpandTy);
|
||||
Value *Base = expandCodeForImpl(PostLoopOffset, ExpandTy, false);
|
||||
Result = expandAddToGEP(SE.getUnknown(Result), PTy, IntTy, Base);
|
||||
} else {
|
||||
Result = expandAddToGEP(PostLoopOffset, PTy, IntTy, Result);
|
||||
}
|
||||
} else {
|
||||
Result = InsertNoopCastOfTo(Result, IntTy);
|
||||
Result = Builder.CreateAdd(Result,
|
||||
expandCodeFor(PostLoopOffset, IntTy));
|
||||
Result = Builder.CreateAdd(
|
||||
Result, expandCodeForImpl(PostLoopOffset, IntTy, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1516,8 +1519,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
S->getNoWrapFlags(SCEV::FlagNW)));
|
||||
BasicBlock::iterator NewInsertPt =
|
||||
findInsertPointAfter(cast<Instruction>(V), Builder.GetInsertBlock());
|
||||
V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr,
|
||||
&*NewInsertPt);
|
||||
V = expandCodeForImpl(SE.getTruncateExpr(SE.getUnknown(V), Ty), nullptr,
|
||||
&*NewInsertPt, false);
|
||||
return V;
|
||||
}
|
||||
|
||||
@ -1632,22 +1635,25 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) {
|
||||
|
||||
Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) {
|
||||
Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Value *V = expandCodeForImpl(
|
||||
S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
|
||||
false);
|
||||
return Builder.CreateTrunc(V, Ty);
|
||||
}
|
||||
|
||||
Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) {
|
||||
Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Value *V = expandCodeForImpl(
|
||||
S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
|
||||
false);
|
||||
return Builder.CreateZExt(V, Ty);
|
||||
}
|
||||
|
||||
Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) {
|
||||
Type *Ty = SE.getEffectiveSCEVType(S->getType());
|
||||
Value *V = expandCodeFor(S->getOperand(),
|
||||
SE.getEffectiveSCEVType(S->getOperand()->getType()));
|
||||
Value *V = expandCodeForImpl(
|
||||
S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType()),
|
||||
false);
|
||||
return Builder.CreateSExt(V, Ty);
|
||||
}
|
||||
|
||||
@ -1662,7 +1668,7 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) {
|
||||
Ty = SE.getEffectiveSCEVType(Ty);
|
||||
LHS = InsertNoopCastOfTo(LHS, Ty);
|
||||
}
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
|
||||
Value *ICmp = Builder.CreateICmpSGT(LHS, RHS);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax");
|
||||
LHS = Sel;
|
||||
@ -1685,7 +1691,7 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) {
|
||||
Ty = SE.getEffectiveSCEVType(Ty);
|
||||
LHS = InsertNoopCastOfTo(LHS, Ty);
|
||||
}
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
|
||||
Value *ICmp = Builder.CreateICmpUGT(LHS, RHS);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax");
|
||||
LHS = Sel;
|
||||
@ -1708,7 +1714,7 @@ Value *SCEVExpander::visitSMinExpr(const SCEVSMinExpr *S) {
|
||||
Ty = SE.getEffectiveSCEVType(Ty);
|
||||
LHS = InsertNoopCastOfTo(LHS, Ty);
|
||||
}
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
|
||||
Value *ICmp = Builder.CreateICmpSLT(LHS, RHS);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smin");
|
||||
LHS = Sel;
|
||||
@ -1731,7 +1737,7 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
|
||||
Ty = SE.getEffectiveSCEVType(Ty);
|
||||
LHS = InsertNoopCastOfTo(LHS, Ty);
|
||||
}
|
||||
Value *RHS = expandCodeFor(S->getOperand(i), Ty);
|
||||
Value *RHS = expandCodeForImpl(S->getOperand(i), Ty, false);
|
||||
Value *ICmp = Builder.CreateICmpULT(LHS, RHS);
|
||||
Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umin");
|
||||
LHS = Sel;
|
||||
@ -1743,15 +1749,43 @@ Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) {
|
||||
return LHS;
|
||||
}
|
||||
|
||||
Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty,
|
||||
Instruction *IP) {
|
||||
Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty,
|
||||
Instruction *IP, bool Root) {
|
||||
setInsertPoint(IP);
|
||||
return expandCodeFor(SH, Ty);
|
||||
Value *V = expandCodeForImpl(SH, Ty, Root);
|
||||
return V;
|
||||
}
|
||||
|
||||
Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty) {
|
||||
Value *SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, bool Root) {
|
||||
// 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.
|
||||
Instruction *Tmp;
|
||||
if (Inst->getType()->isIntegerTy())
|
||||
Tmp = cast<Instruction>(Builder.CreateAdd(Inst, Inst));
|
||||
else {
|
||||
assert(Inst->getType()->isPointerTy());
|
||||
Tmp = cast<Instruction>(Builder.CreateGEP(Inst, Builder.getInt32(1)));
|
||||
}
|
||||
V = fixupLCSSAFormFor(Tmp, 0);
|
||||
|
||||
// Clean up temporary instruction.
|
||||
InsertedValues.erase(Tmp);
|
||||
InsertedPostIncValues.erase(Tmp);
|
||||
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!");
|
||||
@ -1891,10 +1925,28 @@ Value *SCEVExpander::expand(const SCEV *S) {
|
||||
}
|
||||
|
||||
void SCEVExpander::rememberInstruction(Value *I) {
|
||||
if (!PostIncLoops.empty())
|
||||
InsertedPostIncValues.insert(I);
|
||||
else
|
||||
InsertedValues.insert(I);
|
||||
auto DoInsert = [this](Value *V) {
|
||||
if (!PostIncLoops.empty())
|
||||
InsertedPostIncValues.insert(V);
|
||||
else
|
||||
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++) {
|
||||
auto *V = fixupLCSSAFormFor(Inst, OpIdx);
|
||||
if (V != I)
|
||||
DoInsert(V);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// getOrInsertCanonicalInductionVariable - This method returns the
|
||||
@ -1913,9 +1965,8 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
|
||||
|
||||
// Emit code for it.
|
||||
SCEVInsertPointGuard Guard(Builder, this);
|
||||
PHINode *V =
|
||||
cast<PHINode>(expandCodeFor(H, nullptr,
|
||||
&*L->getHeader()->getFirstInsertionPt()));
|
||||
PHINode *V = cast<PHINode>(expandCodeForImpl(
|
||||
H, nullptr, &*L->getHeader()->getFirstInsertionPt(), false));
|
||||
|
||||
return V;
|
||||
}
|
||||
@ -2315,8 +2366,10 @@ Value *SCEVExpander::expandCodeForPredicate(const SCEVPredicate *Pred,
|
||||
|
||||
Value *SCEVExpander::expandEqualPredicate(const SCEVEqualPredicate *Pred,
|
||||
Instruction *IP) {
|
||||
Value *Expr0 = expandCodeFor(Pred->getLHS(), Pred->getLHS()->getType(), IP);
|
||||
Value *Expr1 = expandCodeFor(Pred->getRHS(), Pred->getRHS()->getType(), IP);
|
||||
Value *Expr0 =
|
||||
expandCodeForImpl(Pred->getLHS(), Pred->getLHS()->getType(), IP, false);
|
||||
Value *Expr1 =
|
||||
expandCodeForImpl(Pred->getRHS(), Pred->getRHS()->getType(), IP, false);
|
||||
|
||||
Builder.SetInsertPoint(IP);
|
||||
auto *I = Builder.CreateICmpNE(Expr0, Expr1, "ident.check");
|
||||
@ -2348,15 +2401,16 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR,
|
||||
|
||||
IntegerType *CountTy = IntegerType::get(Loc->getContext(), SrcBits);
|
||||
Builder.SetInsertPoint(Loc);
|
||||
Value *TripCountVal = expandCodeFor(ExitCount, CountTy, Loc);
|
||||
Value *TripCountVal = expandCodeForImpl(ExitCount, CountTy, Loc, false);
|
||||
|
||||
IntegerType *Ty =
|
||||
IntegerType::get(Loc->getContext(), SE.getTypeSizeInBits(ARTy));
|
||||
Type *ARExpandTy = DL.isNonIntegralPointerType(ARTy) ? ARTy : Ty;
|
||||
|
||||
Value *StepValue = expandCodeFor(Step, Ty, Loc);
|
||||
Value *NegStepValue = expandCodeFor(SE.getNegativeSCEV(Step), Ty, Loc);
|
||||
Value *StartValue = expandCodeFor(Start, ARExpandTy, Loc);
|
||||
Value *StepValue = expandCodeForImpl(Step, Ty, Loc, false);
|
||||
Value *NegStepValue =
|
||||
expandCodeForImpl(SE.getNegativeSCEV(Step), Ty, Loc, false);
|
||||
Value *StartValue = expandCodeForImpl(Start, ARExpandTy, Loc, false);
|
||||
|
||||
ConstantInt *Zero =
|
||||
ConstantInt::get(Loc->getContext(), APInt::getNullValue(DstBits));
|
||||
@ -2459,6 +2513,25 @@ Value *SCEVExpander::expandUnionPredicate(const SCEVUnionPredicate *Union,
|
||||
return Check;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Loop *DefLoop = SE.LI.getLoopFor(OpI->getParent());
|
||||
Loop *UseLoop = SE.LI.getLoopFor(User->getParent());
|
||||
if (!DefLoop || UseLoop == DefLoop || DefLoop->contains(UseLoop))
|
||||
return OpV;
|
||||
|
||||
ToUpdate.push_back(OpI);
|
||||
formLCSSAForInstructions(ToUpdate, SE.DT, SE.LI, &SE);
|
||||
return User->getOperand(OpIdx);
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Search for a SCEV subexpression that is not safe to expand. Any expression
|
||||
// that may expand to a !isSafeToSpeculativelyExecute value is unsafe, namely
|
||||
|
@ -265,7 +265,7 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpanderIsSafeToExpandAt) {
|
||||
Phi->addIncoming(Add, L);
|
||||
|
||||
Builder.SetInsertPoint(Post);
|
||||
Builder.CreateRetVoid();
|
||||
Instruction *Ret = Builder.CreateRetVoid();
|
||||
|
||||
ScalarEvolution SE = buildSE(*F);
|
||||
const SCEV *S = SE.getSCEV(Phi);
|
||||
@ -276,6 +276,11 @@ TEST_F(ScalarEvolutionExpanderTest, SCEVExpanderIsSafeToExpandAt) {
|
||||
EXPECT_FALSE(isSafeToExpandAt(AR, LPh->getTerminator(), SE));
|
||||
EXPECT_TRUE(isSafeToExpandAt(AR, L->getTerminator(), SE));
|
||||
EXPECT_TRUE(isSafeToExpandAt(AR, Post->getTerminator(), SE));
|
||||
|
||||
EXPECT_TRUE(LI->getLoopFor(L)->isLCSSAForm(*DT));
|
||||
SCEVExpander Exp(SE, M.getDataLayout(), "expander");
|
||||
Exp.expandCodeFor(SE.getSCEV(Add), nullptr, Ret);
|
||||
EXPECT_TRUE(LI->getLoopFor(L)->isLCSSAForm(*DT));
|
||||
}
|
||||
|
||||
// Check that SCEV expander does not use the nuw instruction
|
||||
|
Loading…
Reference in New Issue
Block a user