-
Notifications
You must be signed in to change notification settings - Fork 30
[GlobalISel] Match G_SHUFFLE_VECTORs representing sub-vector extracts #224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -1527,6 +1527,16 @@ def combine_shuffle_concat : GICombineRule< | |||
| [{ return Helper.matchCombineShuffleConcat(*${root}, ${matchinfo}); }]), | ||||
| (apply [{ Helper.applyCombineShuffleConcat(*${root}, ${matchinfo}); }])>; | ||||
|
|
||||
| // Combines Shuffles representing vector extracts into Unmerges | ||||
| // res = G_SHUFFLE_VECTORS a, b, <0, 1> | ||||
| // ===> | ||||
| // res, undef = G_UNMERGE_VALUES a | ||||
| def combine_shuffle_to_extract_vector : GICombineRule< | ||||
| (defs root:$root, build_fn_matchinfo:$matchinfo), | ||||
| (match (wip_match_opcode G_SHUFFLE_VECTOR):$root, | ||||
| [{ return Helper.matchShuffleToExtractSubvector(*${root}, ${matchinfo}); }]), | ||||
| (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>; | ||||
|
|
||||
| def combine_inttoptr_constant : GICombineRule< | ||||
| (defs root:$root, build_fn_matchinfo:$info), | ||||
| (match (wip_match_opcode G_INTTOPTR):$root, | ||||
|
|
@@ -1642,7 +1652,7 @@ def all_combines : GICombineGroup<[trivial_combines, vector_ops_combines, | |||
| sub_add_reg, select_to_minmax, redundant_binop_in_equality, | ||||
| fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors, | ||||
| combine_concat_vector, double_icmp_zero_and_or_combine, match_addos, | ||||
| combine_shuffle_concat]>; | ||||
| combine_shuffle_concat, combine_shuffle_to_extract_vector]>; | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: this is a bit of an expensive combiner to run since it iterates through a decent chunk of elements twice. Previously, this was an explicitly opt in combiner that a target enabled by calling a specific function. This will now run it on all targets, this is probably worth it. Also, upstream will probably be running those checks now anyways, so it doesn't matter as much.
See MR linked in: #41 (comment)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What upstream checks are you referring to? I think the current
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, checking elements to the shuffle vector is just an O(n²) operations unless you use a hashmap. At the moment, this is done in |
||||
|
|
||||
| // A combine group used to for prelegalizer combiners at -O0. The combines in | ||||
| // this group have been selected based on experiments to balance code size and | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #include "llvm/ADT/SetVector.h" | ||
| #include "llvm/ADT/SmallBitVector.h" | ||
| #include "llvm/Analysis/CmpInstAnalysis.h" | ||
| #include "llvm/Analysis/VectorUtils.h" | ||
| #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" | ||
| #include "llvm/CodeGen/GlobalISel/GISelKnownBits.h" | ||
| #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" | ||
|
|
@@ -7254,6 +7255,60 @@ bool CombinerHelper::matchAddOverflow(MachineInstr &MI, BuildFnTy &MatchInfo) { | |
| return false; | ||
| } | ||
|
|
||
| bool CombinerHelper::matchShuffleToExtractSubvector(MachineInstr &MI, | ||
| BuildFnTy &MatchInfo) { | ||
|
|
||
| assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR); | ||
| const Register DstReg = MI.getOperand(0).getReg(); | ||
| const Register Src1Reg = MI.getOperand(1).getReg(); | ||
| ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
|
|
||
| const LLT DstTy = MRI.getType(DstReg); | ||
| const LLT Src1Ty = MRI.getType(Src1Reg); | ||
|
|
||
| if (!DstTy.isVector() || !Src1Ty.isVector()) | ||
| return false; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this needed?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually,
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that this misses the following edge case: In this case, you could unmerge the first array into the destination. Since the target is not a vector, this would skip it. How useful this is? Who knows.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that case could even be matched to a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it is a bit obscure and the overhead it would cause is minimal. |
||
|
|
||
| const unsigned NumDstElems = DstTy.getNumElements(); | ||
| const unsigned NumSrc1Elems = Src1Ty.getNumElements(); | ||
|
|
||
| if (NumDstElems * 2 != NumSrc1Elems) | ||
| return false; | ||
|
|
||
| auto CheckExtractMask = [=](unsigned Start, unsigned NumElems) -> bool { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: we can use by-reference capture and automatic return type deduction. |
||
| auto ExtractMask = createSequentialMask(Start, NumElems, 0); | ||
|
|
||
| for (unsigned I = 0; I < NumDstElems; I++) { | ||
| if (Mask[I] == -1) | ||
| continue; | ||
|
|
||
| if (Mask[I] != ExtractMask[I]) | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| }; | ||
|
Comment on lines
+7278
to
+7290
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this is a lot, this is great. |
||
|
|
||
| const Register UndefReg = MRI.createGenericVirtualRegister(DstTy); | ||
| Register UnmergeDst1; | ||
| Register UnmergeDst2; | ||
| if (CheckExtractMask(0, NumDstElems)) { | ||
| UnmergeDst1 = DstReg; | ||
| UnmergeDst2 = UndefReg; | ||
| } else if (CheckExtractMask(NumDstElems, NumDstElems)) { | ||
| UnmergeDst1 = UndefReg; | ||
| UnmergeDst2 = DstReg; | ||
| } else { | ||
| return false; | ||
| } | ||
|
|
||
| MatchInfo = [=](MachineIRBuilder &B) { | ||
| B.buildUnmerge({UnmergeDst1, UnmergeDst2}, Src1Reg); | ||
| }; | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| bool CombinerHelper::matchIntToPtrContant(MachineInstr &MI, | ||
| MachineRegisterInfo &MRI, | ||
| BuildFnTy &MatchInfo) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using
wip_match_opcode, upstream really doesn't like this since it causes imprecise patterns and slows down the compilation. In this case, it should be very little difference compared to just matching SHUFFLE_VECTOR directly.https://llvm.org/docs/GlobalISel/MIRPatterns.html#gallery
See MR linked in: #41 (comment)