[llvm] r280155 - GlobalISel: combine extracts & sequences created for legalization
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 30 13:51:25 PDT 2016
Author: tnorthover
Date: Tue Aug 30 15:51:25 2016
New Revision: 280155
URL: http://llvm.org/viewvc/llvm-project?rev=280155&view=rev
Log:
GlobalISel: combine extracts & sequences created for legalization
Legalization ends up creating many G_SEQUENCE/G_EXTRACT pairs which leads to
inefficient codegen (even for -O0), so add a quick pass over the function to
remove them again.
Added:
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h
llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h?rev=280155&r1=280154&r2=280155&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h Tue Aug 30 15:51:25 2016
@@ -293,6 +293,7 @@ public:
/// Idxs[0] + N)` of \p Src and similarly for subsequent bit-indexes.
///
/// \pre setBasicBlock or setMI must have been called.
+ /// \pre \p Indices must be in ascending order of bit position.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildExtract(ArrayRef<LLT> ResTys,
@@ -311,7 +312,7 @@ public:
/// destination register.
/// \pre The bits defined by each Op (derived from index and scalar size) must
/// not overlap.
- /// \pre Each source operand must have a
+ /// \pre \p Indices must be in ascending order of bit position.
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildSequence(LLT ResTy, unsigned Res,
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h?rev=280155&r1=280154&r2=280155&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/MachineLegalizePass.h Tue Aug 30 15:51:25 2016
@@ -26,6 +26,8 @@
namespace llvm {
+class MachineRegisterInfo;
+
class MachineLegalizePass : public MachineFunctionPass {
public:
static char ID;
@@ -55,6 +57,9 @@ public:
MachineFunctionProperties::Property::Legalized);
}
+ bool combineExtracts(MachineInstr &MI, MachineRegisterInfo &MRI,
+ const TargetInstrInfo &TII);
+
bool runOnMachineFunction(MachineFunction &MF) override;
};
} // End namespace llvm.
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp?rev=280155&r1=280154&r2=280155&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp Tue Aug 30 15:51:25 2016
@@ -193,6 +193,8 @@ MachineInstrBuilder MachineIRBuilder::bu
assert(ResTys.size() == Results.size() && Results.size() == Indices.size() &&
"inconsistent number of regs");
assert(!Results.empty() && "invalid trivial extract");
+ assert(std::is_sorted(Indices.begin(), Indices.end()) &&
+ "extract offsets must be in ascending order");
auto MIB = BuildMI(getMF(), DL, getTII().get(TargetOpcode::G_EXTRACT));
for (unsigned i = 0; i < ResTys.size(); ++i)
@@ -222,6 +224,8 @@ MachineIRBuilder::buildSequence(LLT ResT
assert(OpTys.size() == Ops.size() && Ops.size() == Indices.size() &&
"incompatible args");
assert(!Ops.empty() && "invalid trivial sequence");
+ assert(std::is_sorted(Indices.begin(), Indices.end()) &&
+ "sequence offsets must be in ascending order");
MachineInstrBuilder MIB =
buildInstr(TargetOpcode::G_SEQUENCE, LLT::scalar(ResTy.getSizeInBits()));
Modified: llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp?rev=280155&r1=280154&r2=280155&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/MachineLegalizePass.cpp Tue Aug 30 15:51:25 2016
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#define DEBUG_TYPE "legalize-mir"
@@ -46,6 +47,70 @@ void MachineLegalizePass::getAnalysisUsa
void MachineLegalizePass::init(MachineFunction &MF) {
}
+bool MachineLegalizePass::combineExtracts(MachineInstr &MI,
+ MachineRegisterInfo &MRI,
+ const TargetInstrInfo &TII) {
+ bool Changed = false;
+ if (MI.getOpcode() != TargetOpcode::G_EXTRACT)
+ return Changed;
+
+ unsigned NumDefs = (MI.getNumOperands() - 1) / 2;
+ unsigned SrcReg = MI.getOperand(NumDefs).getReg();
+ MachineInstr &SeqI = *MRI.def_instr_begin(SrcReg);
+ if (SeqI.getOpcode() != TargetOpcode::G_SEQUENCE)
+ return Changed;
+
+ unsigned NumSeqSrcs = (SeqI.getNumOperands() - 1) / 2;
+ bool AllDefsReplaced = true;
+
+ // Try to match each register extracted with a corresponding insertion formed
+ // by the G_SEQUENCE.
+ for (unsigned Idx = 0, SeqIdx = 0; Idx < NumDefs; ++Idx) {
+ MachineOperand &ExtractMO = MI.getOperand(Idx);
+ assert(ExtractMO.isReg() && ExtractMO.isDef() &&
+ "unexpected extract operand");
+
+ unsigned ExtractReg = ExtractMO.getReg();
+ unsigned ExtractPos = MI.getOperand(NumDefs + Idx + 1).getImm();
+
+ while (SeqIdx < NumSeqSrcs &&
+ SeqI.getOperand(2 * SeqIdx + 2).getImm() < ExtractPos)
+ ++SeqIdx;
+
+ if (SeqIdx == NumSeqSrcs ||
+ SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
+ SeqI.getType(SeqIdx + 1) != MI.getType(Idx)) {
+ AllDefsReplaced = false;
+ continue;
+ }
+
+ unsigned OrigReg = SeqI.getOperand(2 * SeqIdx + 1).getReg();
+ assert(!TargetRegisterInfo::isPhysicalRegister(OrigReg) &&
+ "unexpected physical register in G_SEQUENCE");
+
+ // Finally we can replace the uses.
+ for (auto &Use : MRI.use_operands(ExtractReg)) {
+ Changed = true;
+ Use.setReg(OrigReg);
+ }
+ }
+
+ if (AllDefsReplaced) {
+ // If SeqI was the next instruction in the BB and we removed it, we'd break
+ // the outer iteration.
+ assert(std::next(MachineBasicBlock::iterator(MI)) != SeqI &&
+ "G_SEQUENCE does not dominate G_EXTRACT");
+
+ MI.eraseFromParent();
+
+ if (MRI.use_empty(SrcReg))
+ SeqI.eraseFromParent();
+ Changed = true;
+ }
+
+ return Changed;
+}
+
bool MachineLegalizePass::runOnMachineFunction(MachineFunction &MF) {
// If the ISel pipeline failed, do not bother running that pass.
if (MF.getProperties().hasProperty(
@@ -94,5 +159,19 @@ bool MachineLegalizePass::runOnMachineFu
Changed |= Res == MachineLegalizeHelper::Legalized;
}
+
+
+ MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
+ for (auto &MBB : MF) {
+ for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) {
+ // Get the next Instruction before we try to legalize, because there's a
+ // good chance MI will be deleted.
+ NextMI = std::next(MI);
+
+ Changed |= combineExtracts(*MI, MRI, TII);
+ }
+ }
+
return Changed;
}
Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir?rev=280155&r1=280154&r2=280155&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-add.mir Tue Aug 30 15:51:25 2016
@@ -33,13 +33,16 @@ body: |
bb.0.entry:
liveins: %x0, %x1, %x2, %x3
; CHECK-LABEL: name: test_scalar_add_big
- ; CHECK-DAG: [[LHS_LO:%.*]](64), [[LHS_HI:%.*]](64) = G_EXTRACT { s64, s64, s128 } %4, 0, 64
- ; CHECK-DAG: [[RHS_LO:%.*]](64), [[RHS_HI:%.*]](64) = G_EXTRACT { s64, s64, s128 } %5, 0, 64
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK-NOT: G_SEQUENCE
; CHECK-DAG: [[CARRY0_32:%.*]](32) = G_CONSTANT s32 0
; CHECK-DAG: [[CARRY0:%[0-9]+]](1) = G_TRUNC { s1, s32 } [[CARRY0_32]]
- ; CHECK: [[RES_LO:%.*]](64), [[CARRY:%.*]](1) = G_UADDE s64 [[LHS_LO]], [[RHS_LO]], [[CARRY0]]
- ; CHECK: [[RES_HI:%.*]](64), {{%.*}}(1) = G_UADDE s64 [[LHS_HI]], [[RHS_HI]], [[CARRY]]
- ; CHECK: %6(128) = G_SEQUENCE { s128, s64, s64 } [[RES_LO]], 0, [[RES_HI]], 64
+ ; CHECK: [[RES_LO:%.*]](64), [[CARRY:%.*]](1) = G_UADDE s64 %0, %2, [[CARRY0]]
+ ; CHECK: [[RES_HI:%.*]](64), {{%.*}}(1) = G_UADDE s64 %1, %3, [[CARRY]]
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK-NOT: G_SEQUENCE
+ ; CHECK: %x0 = COPY [[RES_LO]]
+ ; CHECK: %x1 = COPY [[RES_HI]]
%0(64) = COPY %x0
%1(64) = COPY %x1
@@ -93,11 +96,14 @@ body: |
bb.0.entry:
liveins: %q0, %q1, %q2, %q3
; CHECK-LABEL: name: test_vector_add
- ; CHECK-DAG: [[LHS_LO:%.*]](128), [[LHS_HI:%.*]](128) = G_EXTRACT { s128, s128, s256 } %4, 0, 128
- ; CHECK-DAG: [[RHS_LO:%.*]](128), [[RHS_HI:%.*]](128) = G_EXTRACT { s128, s128, s256 } %5, 0, 128
- ; CHECK: [[RES_LO:%.*]](128) = G_ADD <2 x s64> [[LHS_LO]], [[RHS_LO]]
- ; CHECK: [[RES_HI:%.*]](128) = G_ADD <2 x s64> [[LHS_HI]], [[RHS_HI]]
- ; CHECK: %6(256) = G_SEQUENCE { s256, s128, s128 } [[RES_LO]], 0, [[RES_HI]], 128
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK-NOT: G_SEQUENCE
+ ; CHECK: [[RES_LO:%.*]](128) = G_ADD <2 x s64> %0, %2
+ ; CHECK: [[RES_HI:%.*]](128) = G_ADD <2 x s64> %1, %3
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK-NOT: G_SEQUENCE
+ ; CHECK: %q0 = COPY [[RES_LO]]
+ ; CHECK: %q1 = COPY [[RES_HI]]
%0(128) = COPY %q0
%1(128) = COPY %q1
Added: llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir?rev=280155&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir (added)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/legalize-combines.mir Tue Aug 30 15:51:25 2016
@@ -0,0 +1,92 @@
+# RUN: llc -O0 -run-pass=legalize-mir -global-isel %s -o - 2>&1 | FileCheck %s
+
+--- |
+ target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64-apple-ios"
+ define void @test_combines() {
+ entry:
+ ret void
+ }
+...
+
+---
+name: test_combines
+registers:
+ - { id: 0, class: _ }
+ - { id: 1, class: _ }
+ - { id: 2, class: _ }
+ - { id: 3, class: _ }
+ - { id: 4, class: _ }
+ - { id: 5, class: _ }
+ - { id: 6, class: _ }
+ - { id: 7, class: _ }
+ - { id: 8, class: _ }
+ - { id: 9, class: _ }
+ - { id: 10, class: _ }
+ - { id: 11, class: _ }
+ - { id: 12, class: _ }
+ - { id: 13, class: _ }
+ - { id: 14, class: _ }
+ - { id: 15, class: _ }
+ - { id: 16, class: _ }
+ - { id: 17, class: _ }
+ - { id: 18, class: _ }
+ - { id: 19, class: _ }
+ - { id: 20, class: _ }
+ - { id: 21, class: _ }
+ - { id: 22, class: _ }
+ - { id: 23, class: _ }
+ - { id: 24, class: _ }
+body: |
+ bb.0.entry:
+ liveins: %w0, %w1, %x2, %x3
+
+ %0(32) = COPY %w0
+ %1(32) = COPY %w1
+ %2(8) = G_TRUNC { s8, s32 } %0
+
+ ; Only one of these extracts can be eliminated, the offsets don't match
+ ; properly in the other cases.
+ ; CHECK-LABEL: name: test_combines
+ ; CHECK: %3(32) = G_SEQUENCE { s32, s8 } %2, 1
+ ; CHECK: %4(8) = G_EXTRACT { s8, s32 } %3, 0
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK: %6(8) = G_EXTRACT { s8, s32 } %3, 2
+ ; CHECK: %7(32) = G_ZEXT { s32, s8 } %2
+ %3(32) = G_SEQUENCE { s32, s8 } %2, 1
+ %4(8) = G_EXTRACT { s8, s32 } %3, 0
+ %5(8) = G_EXTRACT { s8, s32 } %3, 1
+ %6(8) = G_EXTRACT { s8, s32 } %3, 2
+ %7(32) = G_ZEXT { s32, s8 } %5
+
+ ; Similarly, here the types don't match.
+ ; CHECK: %10(32) = G_SEQUENCE { s32, s16, s16 } %8, 0, %9, 16
+ ; CHECK: %11(1) = G_EXTRACT { s1, s32 } %10, 0
+ ; CHECK: %12(32) = G_EXTRACT { s32, s32 } %10, 0
+ %8(16) = G_TRUNC { s16, s32 } %0
+ %9(16) = G_ADD s16 %8, %8
+ %10(32) = G_SEQUENCE { s32, s16, s16 } %8, 0, %9, 16
+ %11(1) = G_EXTRACT { s1, s32 } %10, 0
+ %12(32) = G_EXTRACT { s32, s32 } %10, 0
+
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK: %15(16) = G_ADD s16 %8, %9
+ %13(16), %14(16) = G_EXTRACT { s16, s16, s32 } %10, 0, 16
+ %15(16) = G_ADD s16 %13, %14
+
+ ; CHECK: %18(64) = G_EXTRACT { <2 x s32>, s128 } %17, 0
+ ; CHECK: %19(64) = G_ADD <2 x s32> %18, %18
+ %16(64) = COPY %x0
+ %17(128) = G_SEQUENCE { s128, s64, s64 } %16, 0, %16, 64
+ %18(64) = G_EXTRACT { <2 x s32>, s128 } %17, 0
+ %19(64) = G_ADD <2 x s32> %18, %18
+
+ ; CHECK-NOT: G_SEQUENCE
+ ; CHECK-NOT: G_EXTRACT
+ ; CHECK: %24(32) = G_ADD s32 %0, %20
+ %20(32) = G_ADD s32 %0, %0
+ %21(64) = G_SEQUENCE { s64, s32, s32 } %0, 0, %20, 32
+ %22(32) = G_EXTRACT { s32, s64 } %21, 0
+ %23(32) = G_EXTRACT { s32, s64 } %21, 32
+ %24(32) = G_ADD s32 %22, %23
+...
More information about the llvm-commits
mailing list