[PATCH] D105207: [debuginfo][lsr] SCEV-based salvaging for LoopStrengthReduction

Jeremy Morse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 23 04:44:28 PDT 2021


jmorse added subscribers: fhahn, reames.
jmorse added a comment.

Looks good in principle; I've added some nits, and there are a couple of things that need to be revised,

- I think the DWARF stack operands go on in the wrong order for casts, plus it needs test coverage,
- Fail gracefully with unrecognised casts rather than asserting.
- InsertedIVs needs to be clear()'able from SCEVExpander

CC @reames and @fhahn who appear to frequently touch SCEV -- this patch exports a vector of induction variables from SCEVExpander, which we assume is OK as SCEVExpander already exports inserted instructions and similar. The induction variables are used to salvage variable locations when a Value is optimised out of a loop during strength reduction. CCing to make you aware of the API change.



================
Comment at: llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h:193-195
+  // THe IVs generated by the expander e.g. "%lsr.iv".
+  SmallVector<WeakVH, 2> InsertedIVs;
+
----------------
The style in this class appears to be that data fields are private and at the top of the class declaration; public accessors near the bottom. IMO, to fit in with the style, this vector should move towards where InsertedValues is declared, with a public accessor that returns a const reference.


================
Comment at: llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h:204
     ReusedValues.clear();
     ChainedPhis.clear();
   }
----------------
You're going to need to clear  InsertedIVs here.


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5582
+  // Select IV as a candidate if it has been inserted.
+  for (WeakVH IV : Rewriter.InsertedIVs)
+    if (IV && dyn_cast<Instruction>(&*IV)->getParent())
----------------
Performance-nit: could be a const reference to WeakVH instead of constructing a new one each time around the loop.


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5910
+        pushOperator(DwarfOp);
+      EmitOperator++;
+    }
----------------
Mega nit, I think the style convention is to pre-increment


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5923-5924
+                                   : llvm::dwarf::DW_ATE_unsigned};
+    for (const auto &Op : CastOps)
+      pushOperator(Op);
+
----------------
Doesn't the DWARF stack work by operating on things already pushed onto the stack; and thus shouldn't the Inner value be pushed onto the stack before the convert operation is? (Like you do with "div" below).

Possibly I've missed something; but there should also definitely be a test that covers such casting, and it doesn't look like the tests cover anything that produces DW_OP_LLVM_convert.


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5927-5930
+    if (const llvm::SCEVUnknown *U = dyn_cast<SCEVUnknown>(Inner)) {
+      pushValue(cast<SCEVUnknown>(U)->getValue());
+    } else if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Inner)) {
+      pushUInt(C->getAPInt().trunc(ToWidth).getZExtValue());
----------------
Can we not use pushSCEV for Inner in all circumstances and not expand the if/else cases?


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5942-5943
+      Success &= pushCastImpl(Cast, (isa<SCEVSignExtendExpr>(Cast)));
+    else
+      llvm_unreachable("Unrecognised SCEVCastExpr type.");
+
----------------
This probably wants to return false, rather than assert, better to drop debug-info than stop compiling.

(If the four casts listed cover all cast types, even better would be putting that in a call to assert, rather than using a conditional).


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:5949
+  // TODO: MinMax - although these haven't been encountered in the test suite.
+  bool pushSCEV(const llvm::SCEV *S) {
+    bool Success = true;
----------------
clang-format? I suspect the empty line doesn't meet the style guidelines.


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:6115
+                                     ScalarEvolution &SE) {
+  // LSR may add locations to previous;y single location-op DVIs which
+  // are currently not supported.
----------------



================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:6120-6121
+
+  assert(CachedDVI.DVI->getNumVariableLocationOps() == 1 &&
+         "Expected only one location op.");
+
----------------
Redundant given the above conditional?


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:6162-6163
+  bool Changed = false;
+  if (const SCEVAddRecExpr *IVAddRec =
+          dyn_cast<SCEVAddRecExpr>(SCEVInductionVar)) {
+
----------------
clang-format


================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:6211
+/// 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.
----------------



================
Comment at: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:6219
+  for (WeakVH IV : LSR.ScalarEvolutionIVs) {
+    if (IV) {
+      assert(isa<PHINode>(&*IV) && "Expected Phi node.");
----------------
`if (!IV) continue;`? Avoid extra indentation, same with the extra condition below.


================
Comment at: llvm/test/Transforms/LoopStrengthReduce/debuginfo-scev-variadic-value-0.ll:62
+
+attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
+
----------------
NB, we usually strip un-necessary attributes to avoid needless maintenance; see also @djtodoro 's meta-burn tool on the mailing list. (Probably not necessary for these tests as they're fairly small already).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105207/new/

https://reviews.llvm.org/D105207



More information about the llvm-commits mailing list