Details
Diff Detail
Event Timeline
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
431 | I think we're going to see this pattern multiple places. It would be unfortunate if we replicate this everywhere. I'd rather generate copies always and let the Combiner clean up redundant copies. Alternatively we could make a common function and make sure it's used everywhere (say replaceRegWithNewReg or something). |
RegbankSelect doesn't track newly created instruction and I had to set reg bank manually. Here is the patch that sets regbank for newly created COPY instructions
.llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
431 | As far as I understand COPY should turn to cross bank move instruction.
%ToReg = G_ABC %123 = G_MERGE %ToReg, ToReg1, ToReg2 %FromReg(Bank) , FromReg1, FromReg2 ... = G_UNMERGE %123 ... = G_XYZ %FromReg(Bank) -> %ToReg(Bank) = G_ABC ... = G_XYZ %ToReg(Bank)
%ToReg(Bank) = G_ABC %123 = G_MERGE %ToReg, ToReg1, ToReg2 %FromReg , FromReg1, FromReg2 ... = G_UNMERGE %123 ... = G_XYZ %FromReg -> %ToReg(Bank) = G_ABC ... = G_XYZ %ToReg(Bank)
In summary don't make copy if its likely to be redundant(i.e. not a cross register bank move). Also I we could use replaceRegWithNewRegOrCopy in all places where COPY is made during legalizer to reduce number or generated COPYs , e.g. MachineIRBuilder::buildAnyExtOrTrunc (used in trunc+anyext combine). | |
llvm/test/CodeGen/AArch64/GlobalISel/artifact-combine-merge-with-constraints.mir | ||
2 ↗ | (On Diff #230524) | What is the motivation for this in legalizer? |
Thanks, I'll update the patch.
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
431 | I'll add a separate function for this and try to eliminate redundant COPY instructions. | |
llvm/test/CodeGen/AArch64/GlobalISel/artifact-combine-merge-with-constraints.mir | ||
2 ↗ | (On Diff #230524) |
The patch doesn't do anything special in the legalizer. This tests is running legalizer because LegalizationArtifactCombiner is a part of the legalizer pass.
I don't think that's the case. It's possible to build target instructions with register constraints in (or before) the legalizer.
I don't have any other tests as this is failing on our out-of-tree target, but I'm not sure why we need a test case running the whole pipeline. |
Actually, I think Mips changes should be a separate commit. Could you create a differential revision for it?
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
431 | Looks like we need to fix CombinerHelper::matchCombineCopy too. I'll create a differential revision for it first, then we share the same code. |
- Added a function called canReplaceReg to share the code.
- Added a function called replaceRegOrBuildCopy that tries to replace the registers if the constraints match, and builds a COPY otherwise.
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
289 | We should probably be notifying the observer here... |
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
289 | Right, updated the patch. |
With removed xfail from tests, this looks good to me. I would like to hear if other reviewers have comments.
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
285 | Where will we use replaceRegOrBuildCopy so it has to be static? | |
llvm/test/CodeGen/Mips/GlobalISel/regbankselect/long_ambiguous_chain_s32.mir | ||
3–6 ↗ | (On Diff #230734) | With updated patch there are no changes in regbankselect tests, you can remove XFAIL. Register we are replacing in combine has no constraints. |
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
285 | I'm not sure if we need to have a separate function for this, I added it based on the initial review. I can move this logic into tryCombineMerges as an alternative. Regarding the observer, it makes sense to pass the observer to simplify the functions, but it probably shouldn't be a part of this change. Also, I'm not sure if we still want to keep LegalizationArtifactCombiner as discussed in D65894. | |
llvm/test/CodeGen/Mips/GlobalISel/regbankselect/long_ambiguous_chain_s32.mir | ||
3–6 ↗ | (On Diff #230734) | I'll do that, thanks! |
llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h | ||
---|---|---|
289 | I think we can simplify the logic a bit here: if (!llvm::canReplaceReg(DstReg, SrcReg, MRI) { Builder.buildCopy(DstReg, SrcReg); return; } SmallVector<MachineInstr *, 4> UseMIs; // ... | |
llvm/lib/CodeGen/GlobalISel/Utils.cpp | ||
165 | Redundant comment? | |
172 | Don't need to check both DstTy.isValid() and SrcTy.isValid(), since DstTy.isValid() == SrcTy.isValid() at this point. |
llvm/lib/CodeGen/GlobalISel/Utils.cpp | ||
---|---|---|
162 | You can do .isPhysical() | |
171–172 | This still looks redundant to me. (DstTy.isValid() != SrcTy.isValid()) is implied by DstTy != SrcTy | |
175–178 | Just check getRegClassOrRegBank(Src) == getRegClassOrRegBank(Dst)? | |
183–185 | Check these first and short circuit the source checks? | |
183–185 | This can also use getRegClassOrRegBank instead of checking the two separately? |
llvm/lib/CodeGen/GlobalISel/Utils.cpp | ||
---|---|---|
168–171 | You can fold this into return x || (... |
Where will we use replaceRegOrBuildCopy so it has to be static?
I think that eventually Observer should end up as field in LegalizationArtifactCombiner like in LegalizerHelper. There are a few LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI;); around and Observer could handle them.