Skip to content

Commit 5e36dff

Browse files
committed
[AArch64][GloablISel] Refactor Combine G_CONCAT_VECTOR
The combine now works using tablegen and checks if new instruction is legal before creating it.
1 parent 1b87ebc commit 5e36dff

File tree

10 files changed

+510
-511
lines changed

10 files changed

+510
-511
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -224,22 +224,22 @@ class CombinerHelper {
224224
/// - concat_vector(undef, undef) => undef
225225
/// - concat_vector(build_vector(A, B), build_vector(C, D)) =>
226226
/// build_vector(A, B, C, D)
227-
///
228-
/// \pre MI.getOpcode() == G_CONCAT_VECTORS.
229-
bool tryCombineConcatVectors(MachineInstr &MI);
227+
/// ==========================================================
230228
/// Check if the G_CONCAT_VECTORS \p MI is undef or if it
231229
/// can be flattened into a build_vector.
232-
/// In the first case \p IsUndef will be true.
233-
/// In the second case \p Ops will contain the operands needed
234-
/// to produce the flattened build_vector.
230+
/// In the first case \p bool will be true.
231+
/// In the second case \p SmallVector<Register> will contain the operands
232+
/// needed to produce the flattened build_vector.
235233
///
236234
/// \pre MI.getOpcode() == G_CONCAT_VECTORS.
237-
bool matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
238-
SmallVectorImpl<Register> &Ops);
239-
/// Replace \p MI with a flattened build_vector with \p Ops or an
240-
/// implicit_def if IsUndef is true.
241-
void applyCombineConcatVectors(MachineInstr &MI, bool IsUndef,
242-
const ArrayRef<Register> Ops);
235+
bool
236+
matchCombineConcatVectors(MachineInstr &MI,
237+
std::pair<bool, SmallVector<Register>> &matchinfo);
238+
/// Replace \p MI with a flattened build_vector with \p SmallVector<Register>
239+
/// or an implicit_def if \p bool is true.
240+
void
241+
applyCombineConcatVectors(MachineInstr &MI,
242+
std::pair<bool, SmallVector<Register>> &matchinfo);
243243

244244
/// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
245245
/// Returns true if MI changed.

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,14 @@ def match_ors : GICombineRule<
12531253
[{ return Helper.matchOr(*${root}, ${matchinfo}); }]),
12541254
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
12551255

1256+
// Combines concat operations
1257+
def concat_matchinfo : GIDefMatchData<"std::pair<bool, SmallVector<Register>>">;
1258+
def combine_concat_vector : GICombineRule<
1259+
(defs root:$root, concat_matchinfo:$matchinfo),
1260+
(match (wip_match_opcode G_CONCAT_VECTORS):$root,
1261+
[{ return Helper.matchCombineConcatVectors(*${root}, ${matchinfo}); }]),
1262+
(apply [{ Helper.applyCombineConcatVectors(*${root}, ${matchinfo}); }])>;
1263+
12561264
// FIXME: These should use the custom predicate feature once it lands.
12571265
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
12581266
undef_to_negative_one,
@@ -1326,7 +1334,8 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
13261334
intdiv_combines, mulh_combines, redundant_neg_operands,
13271335
and_or_disjoint_mask, fma_combines, fold_binop_into_select,
13281336
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
1329-
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors]>;
1337+
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
1338+
combine_concat_vector]>;
13301339

13311340
// A combine group used to for prelegalizer combiners at -O0. The combines in
13321341
// this group have been selected based on experiments to balance code size and

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -222,21 +222,11 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
222222
replaceRegWith(MRI, DstReg, SrcReg);
223223
}
224224

225-
bool CombinerHelper::tryCombineConcatVectors(MachineInstr &MI) {
226-
bool IsUndef = false;
227-
SmallVector<Register, 4> Ops;
228-
if (matchCombineConcatVectors(MI, IsUndef, Ops)) {
229-
applyCombineConcatVectors(MI, IsUndef, Ops);
230-
return true;
231-
}
232-
return false;
233-
}
234-
235-
bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
236-
SmallVectorImpl<Register> &Ops) {
225+
bool CombinerHelper::matchCombineConcatVectors(
226+
MachineInstr &MI, std::pair<bool, SmallVector<Register>> &matchinfo) {
237227
assert(MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS &&
238228
"Invalid instruction");
239-
IsUndef = true;
229+
matchinfo.first = true;
240230
MachineInstr *Undef = nullptr;
241231

242232
// Walk over all the operands of concat vectors and check if they are
@@ -246,13 +236,15 @@ bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
246236
Register Reg = MO.getReg();
247237
MachineInstr *Def = MRI.getVRegDef(Reg);
248238
assert(Def && "Operand not defined");
239+
if (!MRI.hasOneNonDBGUse(Reg))
240+
return false;
249241
switch (Def->getOpcode()) {
250242
case TargetOpcode::G_BUILD_VECTOR:
251-
IsUndef = false;
243+
matchinfo.first = false;
252244
// Remember the operands of the build_vector to fold
253245
// them into the yet-to-build flattened concat vectors.
254246
for (const MachineOperand &BuildVecMO : Def->uses())
255-
Ops.push_back(BuildVecMO.getReg());
247+
matchinfo.second.push_back(BuildVecMO.getReg());
256248
break;
257249
case TargetOpcode::G_IMPLICIT_DEF: {
258250
LLT OpType = MRI.getType(Reg);
@@ -268,17 +260,25 @@ bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI, bool &IsUndef,
268260
// for the flattening.
269261
for (unsigned EltIdx = 0, EltEnd = OpType.getNumElements();
270262
EltIdx != EltEnd; ++EltIdx)
271-
Ops.push_back(Undef->getOperand(0).getReg());
263+
matchinfo.second.push_back(Undef->getOperand(0).getReg());
272264
break;
273265
}
274266
default:
275267
return false;
276268
}
277269
}
270+
271+
// Check if the combine is illegal
272+
LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
273+
if (!isLegalOrBeforeLegalizer({TargetOpcode::G_BUILD_VECTOR,
274+
{DstTy, MRI.getType(matchinfo.second[0])}})) {
275+
return false;
276+
}
277+
278278
return true;
279279
}
280280
void CombinerHelper::applyCombineConcatVectors(
281-
MachineInstr &MI, bool IsUndef, const ArrayRef<Register> Ops) {
281+
MachineInstr &MI, std::pair<bool, SmallVector<Register>> &matchinfo) {
282282
// We determined that the concat_vectors can be flatten.
283283
// Generate the flattened build_vector.
284284
Register DstReg = MI.getOperand(0).getReg();
@@ -289,12 +289,12 @@ void CombinerHelper::applyCombineConcatVectors(
289289
// checking that at all Ops are undef. Alternatively, we could have
290290
// generate a build_vector of undefs and rely on another combine to
291291
// clean that up. For now, given we already gather this information
292-
// in tryCombineConcatVectors, just save compile time and issue the
292+
// in matchCombineConcatVectors, just save compile time and issue the
293293
// right thing.
294-
if (IsUndef)
294+
if (matchinfo.first)
295295
Builder.buildUndef(NewDstReg);
296296
else
297-
Builder.buildBuildVector(NewDstReg, Ops);
297+
Builder.buildBuildVector(NewDstReg, matchinfo.second);
298298
MI.eraseFromParent();
299299
replaceRegWith(MRI, DstReg, NewDstReg);
300300
}

llvm/lib/Target/AArch64/AArch64Combine.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def AArch64PreLegalizerCombiner: GICombiner<
6464
}
6565

6666
def AArch64O0PreLegalizerCombiner: GICombiner<
67-
"AArch64O0PreLegalizerCombinerImpl", [optnone_combines]> {
67+
"AArch64O0PreLegalizerCombinerImpl", [optnone_combines, combine_concat_vector]> {
6868
let CombineAllMethodName = "tryCombineAllImpl";
6969
}
7070

@@ -288,5 +288,5 @@ def AArch64PostLegalizerCombiner
288288
constant_fold_binops, identity_combines,
289289
ptr_add_immed_chain, overlapping_and,
290290
split_store_zero_128, undef_combines,
291-
select_to_minmax, or_to_bsp]> {
291+
select_to_minmax, or_to_bsp, combine_concat_vector]> {
292292
}

llvm/lib/Target/AArch64/GISel/AArch64O0PreLegalizerCombiner.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ bool AArch64O0PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
9191

9292
unsigned Opc = MI.getOpcode();
9393
switch (Opc) {
94-
case TargetOpcode::G_CONCAT_VECTORS:
95-
return Helper.tryCombineConcatVectors(MI);
9694
case TargetOpcode::G_SHUFFLE_VECTOR:
9795
return Helper.tryCombineShuffleVector(MI);
9896
case TargetOpcode::G_MEMCPY_INLINE:

llvm/lib/Target/AArch64/GISel/AArch64PreLegalizerCombiner.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,6 @@ bool AArch64PreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
720720

721721
unsigned Opc = MI.getOpcode();
722722
switch (Opc) {
723-
case TargetOpcode::G_CONCAT_VECTORS:
724-
return Helper.tryCombineConcatVectors(MI);
725723
case TargetOpcode::G_SHUFFLE_VECTOR:
726724
return Helper.tryCombineShuffleVector(MI);
727725
case TargetOpcode::G_UADDO:

llvm/lib/Target/AMDGPU/AMDGPUPreLegalizerCombiner.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ bool AMDGPUPreLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
106106
return true;
107107

108108
switch (MI.getOpcode()) {
109-
case TargetOpcode::G_CONCAT_VECTORS:
110-
return Helper.tryCombineConcatVectors(MI);
111109
case TargetOpcode::G_SHUFFLE_VECTOR:
112110
return Helper.tryCombineShuffleVector(MI);
113111
}

0 commit comments

Comments
 (0)