This is an archive of the discontinued LLVM Phabricator instance.

MachineCopyPropagation: Keep scanning through instructions with regmasks
ClosedPublic

Authored by MatzeB on Feb 19 2016, 8:06 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

MatzeB updated this revision to Diff 48572.Feb 19 2016, 8:06 PM
MatzeB retitled this revision from to MachineCopyPropagation: Keep scanning through instructions with regmasks.
MatzeB updated this object.
MatzeB added a reviewer: qcolombet.
MatzeB set the repository for this revision to rL LLVM.
MatzeB added a subscriber: llvm-commits.
qcolombet added inline comments.Feb 22 2016, 10:44 AM
lib/CodeGen/MachineCopyPropagation.cpp
99 ↗(On Diff #48572)

Period.

105 ↗(On Diff #48572)

Although I doubt it happens in practice, MIs might have several RegMask operands.
(After scanning through the uses of getRegMask(), it looks to me that this pass is the only one that would do wrong thing with several regmasks. It happened before this patch, e.g., line 238, and thus we can fix as a follow-up patch.)
Can’t we just return false if Reg is clobbered instead of checking if it is preserved?

278 ↗(On Diff #48572)

Update this comment, the end is no more relevant.

307 ↗(On Diff #48572)

We could factorize the two previous loops into a helper function.

MatzeB updated this revision to Diff 48771.Feb 22 2016, 7:34 PM
MatzeB marked 3 inline comments as done.

This is an updated version which simply removes the NoInterveningSideEffects(). From the commit description:

This also simplifies the code by removing the overly conservative
NoInterveningSideEffect() function. This function checked:

  • That the two copies belong to the same block: We only process one block at a time and clear our maps in between it is impossible to find a copy from a different block.
  • There is no terminator between the two copy instructions: This is not allowed anyway (the MachineVerifier would complain)
  • Does not have instructions with hasUnmodeledSideEffects() or isCall() set: Even for those instructuction we must have all clobbers/defs of registers explicit as an operand. If the register is explicitely clobbered we would never come to the point of checking for NoInterveningSideEffect() anyway.

(I also checked this with a temporary build of the test-suite with all
potentially failing conditions in NoInterveningSideEffect() turned into
asserts)

junbuml added inline comments.Feb 23 2016, 10:24 AM
lib/CodeGen/MachineCopyPropagation.cpp
281–286 ↗(On Diff #48771)

This code looks same as the last part of SourceNoLongerAvailable(). We could make a helper function shared in here and in SourceNoLongerAvailable().

qcolombet edited edge metadata.Feb 23 2016, 11:23 AM

Hi Matthias,

Nice clean up.

Looks good to me, modulo my inlined comments for the test cases.
Please also look into Jun's comment.

Thanks,
-Quentin

test/CodeGen/X86/machine-copy-prop.mir
8 ↗(On Diff #48771)

Could you add a comment on what this function is testing?
Something pretty obvious like check that copy propagation manages to propagate across calls when the registers are preserved.

21 ↗(On Diff #48771)

Add another test where the copy cannot be propagated because of clobbered registers.

MatzeB updated this revision to Diff 48855.Feb 23 2016, 4:00 PM
MatzeB edited edge metadata.

New revision which splits SourceNoLongerAvailable() into two new functions: ClobberCopySources(), ClobberRegister() so the code that is now in ClobberCopySources() can be reused for the regmask case.
The tests have also been extended to cover negative cases and check for kill flag clearing.

qcolombet accepted this revision.Feb 23 2016, 5:44 PM
qcolombet edited edge metadata.
qcolombet added inline comments.
lib/CodeGen/MachineCopyPropagation.cpp
93 ↗(On Diff #48855)

Any reason why the two loops are not merged?

129 ↗(On Diff #48855)

I was wondering if it would be more efficient to traverse the clobbered registers and erase the entries in the map accordingly, but I figured the map is usually pretty small.
Maybe add a comment on that so that we don't have to think about it when we come across the code again.

test/CodeGen/X86/machine-copy-prop.mir
1 ↗(On Diff #48855)

-verify-machineinstrs?

13 ↗(On Diff #48855)

typo -> redundant

This revision is now accepted and ready to land.Feb 23 2016, 5:44 PM
junbuml added inline comments.Feb 23 2016, 8:12 PM
lib/CodeGen/MachineCopyPropagation.cpp
74 ↗(On Diff #48855)

I doubt if this method name well describe what it does. For me this method seems simply erase all (sub)regs in RegList from AvailCopyMap.

286 ↗(On Diff #48855)

Maybe ?

if (RegMask->clobbersPhysReg(I->first)) {
  ClobberCopySources(I->second);
  SrcMap.erase(I);
}
MatzeB updated this revision to Diff 48984.Feb 24 2016, 2:56 PM
MatzeB edited edge metadata.
MatzeB marked 8 inline comments as done.

Thanks for the reviews. New version addressing the comments.

lib/CodeGen/MachineCopyPropagation.cpp
74 ↗(On Diff #48855)

Renamed it to removeRegsFromMap() and transformed it into a static function similar to removeClobberedRegsFromMap()

93 ↗(On Diff #48855)

No, they previously just haven't been that close together and not 100% the same, so I didn't see it.

129 ↗(On Diff #48855)

Yes that it is indeed the reason, I will add a comment.

286 ↗(On Diff #48855)

indeed, fixed.

test/CodeGen/X86/machine-copy-prop.mir
1 ↗(On Diff #48855)

Turned out -verify-machineinstrs is a separate pass and won't run anyway when "llc -run-pass XXX" is used. Fixing that is for another commit.

Even more LGTM now :).

This revision was automatically updated to reflect the committed changes.