This is an archive of the discontinued LLVM Phabricator instance.

[MemCpyOpt] implement forward dataflow sensitive stack-move optimization
Needs ReviewPublic

Authored by khei4 on Aug 29 2023, 2:22 AM.

Details

Summary

This extends stack-move optimization https://reviews.llvm.org/D155406 in a more forward dataflow-sensitive way. This patch enables the merging of the following cases.

  • Memory locations are fully overwritten(called a Def) and read from the same alias.
  • Conflicts never happen for any execution path, although both the src and dest are used after the copy.

The implementation difference from https://reviews.llvm.org/D155406 is

  • Add ModState, which represents which of src or dest finally modify the memory location in the dataflow.
    • Propagate it on the CFG, only seeing the same memory location users collected by User tracking on CaptureTracking.
  • Remove reachability or Dominator relations checks on the ModRef checks.

This patch is expected to cover all stack move cases originally covered by pcwalton's patch.

There seem to be almost no compile-time regressions. https://llvm-compile-time-tracker.com/compare.php?from=f61ed5180ebb0dfe840722c6c99244f90d3183f9&to=c0c251970ef118ce15b012ea3d45deab862396c9&stat=instructions:u

Diff Detail

Event Timeline

khei4 created this revision.Aug 29 2023, 2:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2023, 2:22 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
khei4 requested review of this revision.Aug 29 2023, 2:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 29 2023, 2:22 AM
khei4 retitled this revision from [WIP][MemCpyOpt] implement flow sensitive stack-move optimization to [MemCpyOpt] implement forward dataflow sensitive stack-move optimization.Aug 29 2023, 4:15 AM
khei4 edited the summary of this revision. (Show Details)
khei4 added reviewers: nikic, fhahn, pcwalton.
khei4 updated this revision to Diff 554256.Aug 29 2023, 4:17 AM

Update comments and debug macros

khei4 updated this revision to Diff 554547.Aug 29 2023, 7:41 PM
khei4 edited the summary of this revision. (Show Details)
khei4 added reviewers: arsenm, asbirlea.

Rebase for test fix

arsenm added inline comments.Aug 30 2023, 4:46 PM
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
1435

Early return and reduce indent

1445

I think these are supposed to just be unsigned, no < 0 check?

1455

Don't need the .getFixedValue()?

1584–1588

This is redundant with getAllocationSize being nullopt

khei4 updated this revision to Diff 554912.Aug 30 2023, 11:55 PM
khei4 marked 2 inline comments as done.
  • return early
  • remove .getFixedValue for optional TypeSize comparison
  • add comments

Thank you for the review!

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
1445
1455

No. Thanks!

1584–1588

This might not be very clear(I added comment), but this was to bail out for inalloca(stacksave/stackrestore) cases like
https://github.com/llvm/llvm-project/blob/b86d3cbc1288b4d0799746c82611d17888413aec/llvm/test/Transforms/MemCpyOpt/stack-move.ll#L1134-L1139
It seems like the size nullopt check isn't sufficient to bail out for this...

DianQK added a subscriber: DianQK.Aug 31 2023, 4:28 AM
nikic added a comment.Sep 5 2023, 4:34 AM

Just some style notes, I haven't tried to understand the algorithm yet.

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
1425

This should be in an anonymous namespace.

1433

Should be static.

1433

We shouldn't need std::optional here, at this point we know the alloca is sized.

1454

Does this actually do anything? It seems like the lifetime handling in CheckModRefConflict will skip this code path already.

1481

Could use BitmaskEnum.h here instead?

1501

static

Is passing the map by value here intentional?

khei4 updated this revision to Diff 555980.Sep 6 2023, 1:22 AM
khei4 marked 4 inline comments as done.
  • use BitMaskEnum
  • pass by-ref for mistakenly passed by-val
  • unwrap optional on CheckModRefConflict
khei4 added a comment.Sep 6 2023, 1:22 AM

Thank you for the review!

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
1454

Does this actually do anything? It seems like the lifetime handling in CheckModRefConflict will skip this code path already.

No for current cases, as you see! We can erase this for now. Although conceptually current handling for lifetime intrinsic(completely ignore it and shrinkwrap after that) in CheckModRefConflict seems unique, this IsDef concept is not a general method or framework now.

1501

Is passing the map by value here intentional?

No. Thanks for good catch!

khei4 updated this revision to Diff 556991.Sep 18 2023, 8:31 PM

rebase for main and the parent revision change