aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:31:35 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:31:35 +0000
commitfa40418fea35c68de2a358bce3539cdc5cbcd21a (patch)
tree4b9e82662e389ee0f136ea652b5bfdcfb2a29dc2
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
downloadsrc-fa40418fea35c68de2a358bce3539cdc5cbcd21a.tar.gz
src-fa40418fea35c68de2a358bce3539cdc5cbcd21a.zip
Vendor import of llvm-project branch release/13.x llvmorg-13-init-16854-g6b2e4c5a58d7.vendor/llvm-project/llvmorg-13-init-16854-g6b2e4c5a58d7
-rw-r--r--clang/lib/Format/WhitespaceManager.cpp2
-rw-r--r--llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h5
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp2
-rw-r--r--llvm/lib/Target/AArch64/AArch64ISelLowering.cpp6
-rw-r--r--llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp482
-rw-r--r--llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp5
6 files changed, 87 insertions, 415 deletions
diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp
index ca2222d1feff..a822e0aaf1f9 100644
--- a/clang/lib/Format/WhitespaceManager.cpp
+++ b/clang/lib/Format/WhitespaceManager.cpp
@@ -347,7 +347,7 @@ AlignTokenSequence(const FormatStyle &Style, unsigned Start, unsigned End,
if (ScopeStart > Start + 1 &&
Changes[ScopeStart - 2].Tok->is(tok::identifier) &&
Changes[ScopeStart - 1].Tok->is(tok::l_paren))
- return true;
+ return Style.BinPackArguments;
// Ternary operator
if (Changes[i].Tok->is(TT_ConditionalExpr))
diff --git a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index 59bf3a342caa..8662dbf385dc 100644
--- a/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
+++ b/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -83,9 +83,6 @@ class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> {
/// InsertedValues/InsertedPostIncValues.
SmallPtrSet<Value *, 16> ReusedValues;
- // The induction variables generated.
- SmallVector<WeakVH, 2> InsertedIVs;
-
/// A memoization of the "relevant" loop for a given SCEV.
DenseMap<const SCEV *, const Loop *> RelevantLoops;
@@ -202,11 +199,9 @@ public:
InsertedPostIncValues.clear();
ReusedValues.clear();
ChainedPhis.clear();
- InsertedIVs.clear();
}
ScalarEvolution *getSE() { return &SE; }
- const SmallVectorImpl<WeakVH> &getInsertedIVs() const { return InsertedIVs; }
/// Return a vector containing all instructions inserted during expansion.
SmallVector<Instruction *, 32> getAllInsertedInstructions() const {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1415cce3b1df..09627ee6a164 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1660,7 +1660,7 @@ static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
// physical registers if there is debug info associated with the terminator
// of our mbb. We want to include said debug info in our terminator
// sequence, so we return true in that case.
- return MI.isDebugValue();
+ return MI.isDebugInstr();
// We have left the terminator sequence if we are not doing one of the
// following:
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e7282aad05e2..ae702eedcd66 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -4348,6 +4348,9 @@ SDValue AArch64TargetLowering::LowerMGATHER(SDValue Op,
IndexVT = getContainerForFixedLengthVector(DAG, IndexVT);
MemVT = IndexVT.changeVectorElementType(MemVT.getVectorElementType());
InputVT = DAG.getValueType(MemVT.changeTypeToInteger());
+ Mask = DAG.getNode(
+ ISD::ZERO_EXTEND, DL,
+ VT.changeVectorElementType(IndexVT.getVectorElementType()), Mask);
}
if (PassThru->isUndef() || isZerosVector(PassThru.getNode()))
@@ -4452,6 +4455,9 @@ SDValue AArch64TargetLowering::LowerMSCATTER(SDValue Op,
ISD::ANY_EXTEND, DL,
VT.changeVectorElementType(IndexVT.getVectorElementType()), StoreVal);
StoreVal = convertToScalableVector(DAG, IndexVT, StoreVal);
+ Mask = DAG.getNode(
+ ISD::ZERO_EXTEND, DL,
+ VT.changeVectorElementType(IndexVT.getVectorElementType()), Mask);
} else if (VT.isFloatingPoint()) {
// Handle FP data by casting the data so an integer scatter can be used.
EVT StoreValVT = getPackedSVEVectorVT(VT.getVectorElementCount());
diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 5f210380ae5a..b585818af595 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -1981,9 +1981,6 @@ class LSRInstance {
/// IV users that belong to profitable IVChains.
SmallPtrSet<Use*, MaxChains> IVIncSet;
- /// Induction variables that were generated and inserted by the SCEV Expander.
- SmallVector<llvm::WeakVH, 2> ScalarEvolutionIVs;
-
void OptimizeShadowIV();
bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse);
ICmpInst *OptimizeMax(ICmpInst *Cond, IVStrideUse* &CondUse);
@@ -2088,9 +2085,6 @@ public:
TargetLibraryInfo &TLI, MemorySSAUpdater *MSSAU);
bool getChanged() const { return Changed; }
- const SmallVectorImpl<WeakVH> &getScalarEvolutionIVs() const {
- return ScalarEvolutionIVs;
- }
void print_factors_and_types(raw_ostream &OS) const;
void print_fixups(raw_ostream &OS) const;
@@ -5595,11 +5589,6 @@ void LSRInstance::ImplementSolution(
GenerateIVChain(Chain, Rewriter, DeadInsts);
Changed = true;
}
-
- for (const WeakVH &IV : Rewriter.getInsertedIVs())
- if (IV && dyn_cast<Instruction>(&*IV)->getParent())
- ScalarEvolutionIVs.push_back(IV);
-
// Clean up after ourselves. This must be done before deleting any
// instructions.
Rewriter.clear();
@@ -5870,389 +5859,87 @@ void LoopStrengthReduce::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<MemorySSAWrapperPass>();
}
-struct SCEVDbgValueBuilder {
- SCEVDbgValueBuilder() = default;
- SCEVDbgValueBuilder(const SCEVDbgValueBuilder &Base) {
- Values = Base.Values;
- Expr = Base.Expr;
- }
-
- /// The DIExpression as we translate the SCEV.
- SmallVector<uint64_t, 6> Expr;
- /// The location ops of the DIExpression.
- SmallVector<llvm::ValueAsMetadata *, 2> Values;
-
- void pushOperator(uint64_t Op) { Expr.push_back(Op); }
- void pushUInt(uint64_t Operand) { Expr.push_back(Operand); }
-
- /// Add a DW_OP_LLVM_arg to the expression, followed by the index of the value
- /// in the set of values referenced by the expression.
- void pushValue(llvm::Value *V) {
- Expr.push_back(llvm::dwarf::DW_OP_LLVM_arg);
- auto *It =
- std::find(Values.begin(), Values.end(), llvm::ValueAsMetadata::get(V));
- unsigned ArgIndex = 0;
- if (It != Values.end()) {
- ArgIndex = std::distance(Values.begin(), It);
- } else {
- ArgIndex = Values.size();
- Values.push_back(llvm::ValueAsMetadata::get(V));
- }
- Expr.push_back(ArgIndex);
- }
-
- void pushValue(const SCEVUnknown *U) {
- llvm::Value *V = cast<SCEVUnknown>(U)->getValue();
- pushValue(V);
- }
-
- void pushConst(const SCEVConstant *C) {
- Expr.push_back(llvm::dwarf::DW_OP_consts);
- Expr.push_back(C->getAPInt().getSExtValue());
- }
-
- /// Several SCEV types are sequences of the same arithmetic operator applied
- /// to constants and values that may be extended or truncated.
- bool pushArithmeticExpr(const llvm::SCEVCommutativeExpr *CommExpr,
- uint64_t DwarfOp) {
- assert((isa<llvm::SCEVAddExpr>(CommExpr) || isa<SCEVMulExpr>(CommExpr)) &&
- "Expected arithmetic SCEV type");
- bool Success = true;
- unsigned EmitOperator = 0;
- for (auto &Op : CommExpr->operands()) {
- Success &= pushSCEV(Op);
-
- if (EmitOperator >= 1)
- pushOperator(DwarfOp);
- ++EmitOperator;
- }
- return Success;
- }
-
- // TODO: Identify and omit noop casts.
- bool pushCast(const llvm::SCEVCastExpr *C, bool IsSigned) {
- const llvm::SCEV *Inner = C->getOperand(0);
- const llvm::Type *Type = C->getType();
- uint64_t ToWidth = Type->getIntegerBitWidth();
- bool Success = pushSCEV(Inner);
- uint64_t CastOps[] = {dwarf::DW_OP_LLVM_convert, ToWidth,
- IsSigned ? llvm::dwarf::DW_ATE_signed
- : llvm::dwarf::DW_ATE_unsigned};
- for (const auto &Op : CastOps)
- pushOperator(Op);
- return Success;
- }
-
- // TODO: MinMax - although these haven't been encountered in the test suite.
- bool pushSCEV(const llvm::SCEV *S) {
- bool Success = true;
- if (const SCEVConstant *StartInt = dyn_cast<SCEVConstant>(S)) {
- pushConst(StartInt);
-
- } else if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) {
- if(!U->getValue())
- return false;
- pushValue(U->getValue());
-
- } else if (const SCEVMulExpr *MulRec = dyn_cast<SCEVMulExpr>(S)) {
- Success &= pushArithmeticExpr(MulRec, llvm::dwarf::DW_OP_mul);
-
- } else if (const SCEVUDivExpr *UDiv = dyn_cast<SCEVUDivExpr>(S)) {
- Success &= pushSCEV(UDiv->getLHS());
- Success &= pushSCEV(UDiv->getRHS());
- pushOperator(llvm::dwarf::DW_OP_div);
-
- } else if (const SCEVCastExpr *Cast = dyn_cast<SCEVCastExpr>(S)) {
- // Assert if a new and unknown SCEVCastEXpr type is encountered.
- assert((isa<SCEVZeroExtendExpr>(Cast) || isa<SCEVTruncateExpr>(Cast) ||
- isa<SCEVPtrToIntExpr>(Cast) || isa<SCEVSignExtendExpr>(Cast)) &&
- "Unexpected cast type in SCEV.");
- Success &= pushCast(Cast, (isa<SCEVSignExtendExpr>(Cast)));
-
- } else if (const SCEVAddExpr *AddExpr = dyn_cast<SCEVAddExpr>(S)) {
- Success &= pushArithmeticExpr(AddExpr, llvm::dwarf::DW_OP_plus);
-
- } else if (isa<SCEVAddRecExpr>(S)) {
- // Nested SCEVAddRecExpr are generated by nested loops and are currently
- // unsupported.
- return false;
-
- } else {
- return false;
- }
- return Success;
- }
-
- void setFinalExpression(llvm::DbgValueInst &DI, const DIExpression *OldExpr) {
- // Re-state assumption that this dbg.value is not variadic. Any remaining
- // opcodes in its expression operate on a single value already on the
- // expression stack. Prepend our operations, which will re-compute and
- // place that value on the expression stack.
- assert(!DI.hasArgList());
- auto *NewExpr =
- DIExpression::prependOpcodes(OldExpr, Expr, /*StackValue*/ true);
- DI.setExpression(NewExpr);
-
- auto ValArrayRef = llvm::ArrayRef<llvm::ValueAsMetadata *>(Values);
- DI.setRawLocation(llvm::DIArgList::get(DI.getContext(), ValArrayRef));
- }
-
- /// If a DVI can be emitted without a DIArgList, omit DW_OP_llvm_arg and the
- /// location op index 0.
- void setShortFinalExpression(llvm::DbgValueInst &DI,
- const DIExpression *OldExpr) {
- assert((Expr[0] == llvm::dwarf::DW_OP_LLVM_arg && Expr[1] == 0) &&
- "Expected DW_OP_llvm_arg and 0.");
- DI.replaceVariableLocationOp(
- 0u, llvm::MetadataAsValue::get(DI.getContext(), Values[0]));
-
- // See setFinalExpression: prepend our opcodes on the start of any old
- // expression opcodes.
- assert(!DI.hasArgList());
- llvm::SmallVector<uint64_t, 6> FinalExpr(Expr.begin() + 2, Expr.end());
- auto *NewExpr =
- DIExpression::prependOpcodes(OldExpr, FinalExpr, /*StackValue*/ true);
- DI.setExpression(NewExpr);
- }
-
- /// Once the IV and variable SCEV translation is complete, write it to the
- /// source DVI.
- void applyExprToDbgValue(llvm::DbgValueInst &DI,
- const DIExpression *OldExpr) {
- assert(!Expr.empty() && "Unexpected empty expression.");
- // Emit a simpler form if only a single location is referenced.
- if (Values.size() == 1 && Expr[0] == llvm::dwarf::DW_OP_LLVM_arg &&
- Expr[1] == 0) {
- setShortFinalExpression(DI, OldExpr);
- } else {
- setFinalExpression(DI, OldExpr);
- }
- }
-
- /// Return true if the combination of arithmetic operator and underlying
- /// SCEV constant value is an identity function.
- bool isIdentityFunction(uint64_t Op, const SCEV *S) {
- if (const SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
- int64_t I = C->getAPInt().getSExtValue();
- switch (Op) {
- case llvm::dwarf::DW_OP_plus:
- case llvm::dwarf::DW_OP_minus:
- return I == 0;
- case llvm::dwarf::DW_OP_mul:
- case llvm::dwarf::DW_OP_div:
- return I == 1;
- }
- }
- return false;
- }
-
- /// Convert a SCEV of a value to a DIExpression that is pushed onto the
- /// builder's expression stack. The stack should already contain an
- /// expression for the iteration count, so that it can be multiplied by
- /// the stride and added to the start.
- /// Components of the expression are omitted if they are an identity function.
- /// Chain (non-affine) SCEVs are not supported.
- bool SCEVToValueExpr(const llvm::SCEVAddRecExpr &SAR, ScalarEvolution &SE) {
- assert(SAR.isAffine() && "Expected affine SCEV");
- // TODO: Is this check needed?
- if (isa<SCEVAddRecExpr>(SAR.getStart()))
- return false;
-
- const SCEV *Start = SAR.getStart();
- const SCEV *Stride = SAR.getStepRecurrence(SE);
-
- // Skip pushing arithmetic noops.
- if (!isIdentityFunction(llvm::dwarf::DW_OP_mul, Stride)) {
- if (!pushSCEV(Stride))
- return false;
- pushOperator(llvm::dwarf::DW_OP_mul);
- }
- if (!isIdentityFunction(llvm::dwarf::DW_OP_plus, Start)) {
- if (!pushSCEV(Start))
- return false;
- pushOperator(llvm::dwarf::DW_OP_plus);
- }
- return true;
- }
-
- /// Convert a SCEV of a value to a DIExpression that is pushed onto the
- /// builder's expression stack. The stack should already contain an
- /// expression for the iteration count, so that it can be multiplied by
- /// the stride and added to the start.
- /// Components of the expression are omitted if they are an identity function.
- bool SCEVToIterCountExpr(const llvm::SCEVAddRecExpr &SAR,
- ScalarEvolution &SE) {
- assert(SAR.isAffine() && "Expected affine SCEV");
- if (isa<SCEVAddRecExpr>(SAR.getStart())) {
- LLVM_DEBUG(dbgs() << "scev-salvage: IV SCEV. Unsupported nested AddRec: "
- << SAR << '\n');
- return false;
- }
- const SCEV *Start = SAR.getStart();
- const SCEV *Stride = SAR.getStepRecurrence(SE);
-
- // Skip pushing arithmetic noops.
- if (!isIdentityFunction(llvm::dwarf::DW_OP_minus, Start)) {
- if (!pushSCEV(Start))
- return false;
- pushOperator(llvm::dwarf::DW_OP_minus);
- }
- if (!isIdentityFunction(llvm::dwarf::DW_OP_div, Stride)) {
- if (!pushSCEV(Stride))
- return false;
- pushOperator(llvm::dwarf::DW_OP_div);
- }
- return true;
- }
-};
+using EqualValues = SmallVector<std::tuple<WeakVH, int64_t>, 4>;
+using EqualValuesMap =
+ DenseMap<DbgValueInst *, SmallVector<std::pair<unsigned, EqualValues>>>;
+using LocationMap =
+ DenseMap<DbgValueInst *, std::pair<DIExpression *, Metadata *>>;
-struct DVIRecoveryRec {
- DbgValueInst *DVI;
- DIExpression *Expr;
- Metadata *LocationOp;
- const llvm::SCEV *SCEV;
-};
-
-static bool RewriteDVIUsingIterCount(DVIRecoveryRec CachedDVI,
- const SCEVDbgValueBuilder &IterationCount,
- ScalarEvolution &SE) {
- // LSR may add locations to previously single location-op DVIs which
- // are currently not supported.
- if (CachedDVI.DVI->getNumVariableLocationOps() != 1)
- return false;
-
- // SCEVs for SSA values are most frquently of the form
- // {start,+,stride}, but sometimes they are ({start,+,stride} + %a + ..).
- // This is because %a is a PHI node that is not the IV. However, these
- // SCEVs have not been observed to result in debuginfo-lossy optimisations,
- // so its not expected this point will be reached.
- if (!isa<SCEVAddRecExpr>(CachedDVI.SCEV))
- return false;
-
- LLVM_DEBUG(dbgs() << "scev-salvage: Value to salvage SCEV: "
- << *CachedDVI.SCEV << '\n');
-
- const auto *Rec = cast<SCEVAddRecExpr>(CachedDVI.SCEV);
- if (!Rec->isAffine())
- return false;
-
- // Initialise a new builder with the iteration count expression. In
- // combination with the value's SCEV this enables recovery.
- SCEVDbgValueBuilder RecoverValue(IterationCount);
- if (!RecoverValue.SCEVToValueExpr(*Rec, SE))
- return false;
-
- LLVM_DEBUG(dbgs() << "scev-salvage: Updating: " << *CachedDVI.DVI << '\n');
- RecoverValue.applyExprToDbgValue(*CachedDVI.DVI, CachedDVI.Expr);
- LLVM_DEBUG(dbgs() << "scev-salvage: to: " << *CachedDVI.DVI << '\n');
- return true;
-}
-
-static bool
-DbgRewriteSalvageableDVIs(llvm::Loop *L, ScalarEvolution &SE,
- llvm::PHINode *LSRInductionVar,
- SmallVector<DVIRecoveryRec, 2> &DVIToUpdate) {
- if (DVIToUpdate.empty())
- return false;
-
- const llvm::SCEV *SCEVInductionVar = SE.getSCEV(LSRInductionVar);
- assert(SCEVInductionVar &&
- "Anticipated a SCEV for the post-LSR induction variable");
-
- bool Changed = false;
- if (const SCEVAddRecExpr *IVAddRec =
- dyn_cast<SCEVAddRecExpr>(SCEVInductionVar)) {
- SCEVDbgValueBuilder IterCountExpr;
- IterCountExpr.pushValue(LSRInductionVar);
- if (!IterCountExpr.SCEVToIterCountExpr(*IVAddRec, SE))
- return false;
-
- LLVM_DEBUG(dbgs() << "scev-salvage: IV SCEV: " << *SCEVInductionVar
- << '\n');
-
- // Needn't salvage if the location op hasn't been undef'd by LSR.
- for (auto &DVIRec : DVIToUpdate) {
- if (!DVIRec.DVI->isUndef())
- continue;
-
- // Some DVIs that were single location-op when cached are now multi-op,
- // due to LSR optimisations. However, multi-op salvaging is not yet
- // supported by SCEV salvaging. But, we can attempt a salvage by restoring
- // the pre-LSR single-op expression.
- if (DVIRec.DVI->hasArgList()) {
- llvm::Type *Ty = DVIRec.DVI->getVariableLocationOp(0)->getType();
- DVIRec.DVI->setRawLocation(
- llvm::ValueAsMetadata::get(UndefValue::get(Ty)));
- DVIRec.DVI->setExpression(DVIRec.Expr);
- }
-
- Changed |= RewriteDVIUsingIterCount(DVIRec, IterCountExpr, SE);
- }
- }
- return Changed;
-}
-
-/// Identify and cache salvageable DVI locations and expressions along with the
-/// corresponding SCEV(s). Also ensure that the DVI is not deleted before
-static void
-DbgGatherSalvagableDVI(Loop *L, ScalarEvolution &SE,
- SmallVector<DVIRecoveryRec, 2> &SalvageableDVISCEVs,
- SmallSet<AssertingVH<DbgValueInst>, 2> &DVIHandles) {
+static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE,
+ EqualValuesMap &DbgValueToEqualSet,
+ LocationMap &DbgValueToLocation) {
for (auto &B : L->getBlocks()) {
for (auto &I : *B) {
auto DVI = dyn_cast<DbgValueInst>(&I);
if (!DVI)
continue;
-
- if (DVI->hasArgList())
- continue;
-
- if (!SE.isSCEVable(DVI->getVariableLocationOp(0)->getType()))
- continue;
-
- SalvageableDVISCEVs.push_back(
- {DVI, DVI->getExpression(), DVI->getRawLocation(),
- SE.getSCEV(DVI->getVariableLocationOp(0))});
- DVIHandles.insert(DVI);
+ for (unsigned Idx = 0; Idx < DVI->getNumVariableLocationOps(); ++Idx) {
+ // TODO: We can duplicate results if the same arg appears more than
+ // once.
+ Value *V = DVI->getVariableLocationOp(Idx);
+ if (!V || !SE.isSCEVable(V->getType()))
+ continue;
+ auto DbgValueSCEV = SE.getSCEV(V);
+ EqualValues EqSet;
+ for (PHINode &Phi : L->getHeader()->phis()) {
+ if (V->getType() != Phi.getType())
+ continue;
+ if (!SE.isSCEVable(Phi.getType()))
+ continue;
+ auto PhiSCEV = SE.getSCEV(&Phi);
+ Optional<APInt> Offset =
+ SE.computeConstantDifference(DbgValueSCEV, PhiSCEV);
+ if (Offset && Offset->getMinSignedBits() <= 64)
+ EqSet.emplace_back(
+ std::make_tuple(&Phi, Offset.getValue().getSExtValue()));
+ }
+ DbgValueToEqualSet[DVI].push_back({Idx, std::move(EqSet)});
+ // If we fall back to using this raw location, at least one location op
+ // must be dead. A DIArgList will automatically undef arguments when
+ // they become unavailable, but a ValueAsMetadata will not; since we
+ // know the value should be undef, we use the undef value directly here.
+ Metadata *RawLocation =
+ DVI->hasArgList() ? DVI->getRawLocation()
+ : ValueAsMetadata::get(UndefValue::get(
+ DVI->getVariableLocationOp(0)->getType()));
+ DbgValueToLocation[DVI] = {DVI->getExpression(), RawLocation};
+ }
}
}
}
-/// Ideally pick the PHI IV inserted by ScalarEvolutionExpander. As a fallback
-/// any PHi from the loop header is usable, but may have less chance of
-/// surviving subsequent transforms.
-static llvm::PHINode *GetInductionVariable(const Loop &L, ScalarEvolution &SE,
- const LSRInstance &LSR) {
- // For now, just pick the first IV generated and inserted. Ideally pick an IV
- // that is unlikely to be optimised away by subsequent transforms.
- for (const WeakVH &IV : LSR.getScalarEvolutionIVs()) {
- if (!IV)
+static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet,
+ LocationMap &DbgValueToLocation) {
+ for (auto A : DbgValueToEqualSet) {
+ auto *DVI = A.first;
+ // Only update those that are now undef.
+ if (!DVI->isUndef())
continue;
-
- assert(isa<PHINode>(&*IV) && "Expected PhI node.");
- if (SE.isSCEVable((*IV).getType())) {
- PHINode *Phi = dyn_cast<PHINode>(&*IV);
- LLVM_DEBUG(const llvm::SCEV *S = SE.getSCEV(Phi);
- dbgs() << "scev-salvage: IV : " << *IV << "with SCEV: " << *S
- << "\n");
- return Phi;
+ // The dbg.value may have had its value or expression changed during LSR by
+ // a failed salvage attempt; refresh them from the map.
+ auto *DbgDIExpr = DbgValueToLocation[DVI].first;
+ DVI->setRawLocation(DbgValueToLocation[DVI].second);
+ DVI->setExpression(DbgDIExpr);
+ assert(DVI->isUndef() && "dbg.value with non-undef location should not "
+ "have been modified by LSR.");
+ for (auto IdxEV : A.second) {
+ unsigned Idx = IdxEV.first;
+ for (auto EV : IdxEV.second) {
+ auto EVHandle = std::get<WeakVH>(EV);
+ if (!EVHandle)
+ continue;
+ int64_t Offset = std::get<int64_t>(EV);
+ DVI->replaceVariableLocationOp(Idx, EVHandle);
+ if (Offset) {
+ SmallVector<uint64_t, 8> Ops;
+ DIExpression::appendOffset(Ops, Offset);
+ DbgDIExpr = DIExpression::appendOpsToArg(DbgDIExpr, Ops, Idx, true);
+ }
+ DVI->setExpression(DbgDIExpr);
+ break;
+ }
}
}
-
- for (PHINode &Phi : L.getHeader()->phis()) {
- if (!SE.isSCEVable(Phi.getType()))
- continue;
-
- const llvm::SCEV *PhiSCEV = SE.getSCEV(&Phi);
- if (const llvm::SCEVAddRecExpr *Rec = dyn_cast<SCEVAddRecExpr>(PhiSCEV))
- if (!Rec->isAffine())
- continue;
-
- LLVM_DEBUG(dbgs() << "scev-salvage: Selected IV from loop header: " << Phi
- << " with SCEV: " << *PhiSCEV << "\n");
- return &Phi;
- }
- return nullptr;
}
static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
@@ -6261,21 +5948,20 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
AssumptionCache &AC, TargetLibraryInfo &TLI,
MemorySSA *MSSA) {
- // Debug preservation - before we start removing anything identify which DVI
- // meet the salvageable criteria and store their DIExpression and SCEVs.
- SmallVector<DVIRecoveryRec, 2> SalvageableDVI;
- SmallSet<AssertingVH<DbgValueInst>, 2> DVIHandles;
- DbgGatherSalvagableDVI(L, SE, SalvageableDVI, DVIHandles);
-
bool Changed = false;
std::unique_ptr<MemorySSAUpdater> MSSAU;
if (MSSA)
MSSAU = std::make_unique<MemorySSAUpdater>(MSSA);
// Run the main LSR transformation.
- const LSRInstance &Reducer =
- LSRInstance(L, IU, SE, DT, LI, TTI, AC, TLI, MSSAU.get());
- Changed |= Reducer.getChanged();
+ Changed |=
+ LSRInstance(L, IU, SE, DT, LI, TTI, AC, TLI, MSSAU.get()).getChanged();
+
+ // Debug preservation - before we start removing anything create equivalence
+ // sets for the llvm.dbg.value intrinsics.
+ EqualValuesMap DbgValueToEqualSet;
+ LocationMap DbgValueToLocation;
+ DbgGatherEqualValues(L, SE, DbgValueToEqualSet, DbgValueToLocation);
// Remove any extra phis created by processing inner loops.
Changed |= DeleteDeadPHIs(L->getHeader(), &TLI, MSSAU.get());
@@ -6295,22 +5981,8 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
}
}
- if (SalvageableDVI.empty())
- return Changed;
-
- // Obtain relevant IVs and attempt to rewrite the salvageable DVIs with
- // expressions composed using the derived iteration count.
- // TODO: Allow for multiple IV references for nested AddRecSCEVs
- for (auto &L : LI) {
- if (llvm::PHINode *IV = GetInductionVariable(*L, SE, Reducer))
- DbgRewriteSalvageableDVIs(L, SE, IV, SalvageableDVI);
- else {
- LLVM_DEBUG(dbgs() << "scev-salvage: SCEV salvaging not possible. An IV "
- "could not be identified.\n");
- }
- }
+ DbgApplyEqualValues(DbgValueToEqualSet, DbgValueToLocation);
- DVIHandles.clear();
return Changed;
}
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 3978e1e29825..5af1c37e6197 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1393,10 +1393,9 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized,
// can ensure that IVIncrement dominates the current uses.
PostIncLoops = SavedPostIncLoops;
- // Remember this PHI, even in post-inc mode. LSR SCEV-based salvaging is most
- // effective when we are able to use an IV inserted here, so record it.
+ // Remember this PHI, even in post-inc mode.
InsertedValues.insert(PN);
- InsertedIVs.push_back(PN);
+
return PN;
}