[PATCH] D153453: (WIP)[MemCpyOpt] implement inter-BB stack-move optimization which unify the lifetime overlapped fully copied allocas, the src is never modified or referenced

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 2 08:10:51 PDT 2023


nikic added inline comments.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1459
+  // 2. Check that src and dest are never captured, unescaped allocas.
+  if (llvm::PointerMayBeCaptured(SrcAlloca, /* ReturnCaptures=*/true,
+                                 /* StoreCaptures= */ true) ||
----------------
nit: `llvm::` prefix should not be necessary.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1469
+  SmallVector<IntrinsicInst *, 4> LifetimeMarkers;
+  // TODO: non instruction user? -> ConstantExpr. care?
+  std::optional<Instruction *> FirstUser, LastUser;
----------------
Instructions cannot have non-instruction users. You can use `cast<Instruction>`.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1470
+  // TODO: non instruction user? -> ConstantExpr. care?
+  std::optional<Instruction *> FirstUser, LastUser;
+  auto DestLoc = MemoryLocation(DestAlloca, LocationSize::precise(Size));
----------------
For pointers, don't use `std::optional`, initialize with `nullptr` instead.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1471
+  std::optional<Instruction *> FirstUser, LastUser;
+  auto DestLoc = MemoryLocation(DestAlloca, LocationSize::precise(Size));
+  bool DestMod = false, DestRef = false;
----------------



================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1476
+    if (auto *I = dyn_cast<Instruction>(U)) {
+      if (!FirstUser || I->comesBefore(*FirstUser))
+        FirstUser = I;
----------------
comesBefore() will assert if the I and FirstUser are in different blocks -- I don't think anything prevents that from happening here?


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1481
+      if (auto *II = dyn_cast<IntrinsicInst>(I);
+          II && II->isLifetimeStartOrEnd()) {
+        int64_t Size = cast<ConstantInt>(II->getArgOperand(0))->getSExtValue();
----------------
isLifetimeStartOrEnd() is defined on Instruction, so no need to cast to IntrinsicInst.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1488
+      }
+      ModRefInfo Res = AA->getModRefInfo(I, DestLoc);
+      if (I->comesBefore(Store) && isModSet(Res))
----------------
This assumes that only direct users can ModRef the alloca. Consider something like `store v, (getelementptr (alloca))`. Your loop will visit the `getelementptr` and decide it's `NoModRef`, and never see the `store`.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1507
+      if (I->comesBefore(Store) || I == Store)
+        continue;
+      if (auto *II = dyn_cast<IntrinsicInst>(I);
----------------
Don't you want to collect the lifetime intrinsics before the store as well?


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1537
+  auto *NewStart = Builder.CreateLifetimeStart(SrcAlloca, AllocaSize);
+  NewStart->addParamAttr(1, Attribute::NoCapture);
+
----------------
You don't need to add this manually, it is implied by the intrinsic declaration.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1558
+  NumStackMove++;
+  return false;
+}
----------------
`return true`. This should fix the `memcpy`s that get left behind.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1667
+  AllocaInst *DestAlloca = dyn_cast<AllocaInst>(M->getDest());
+  if (DestAlloca == nullptr)
+    return false;
----------------
nit: Use `!DestAlloca` instead. Same below.


================
Comment at: llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp:1675
+    return false;
+  if (performStackMoveOptzn(M, M, DestAlloca, SrcAlloca, Len->getZExtValue())) {
+    // Avoid invalidating the iterator.
----------------
Pass `BAA` to the method and use it instead of `AA`.


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

https://reviews.llvm.org/D153453



More information about the llvm-commits mailing list