GlobalISel: remove G_SEQUENCE instruction.
It was trying to do too many things. The basic lumping together of values for legalization purposes is now handled by G_MERGE_VALUES. More complex things involving gaps and odd sizes are handled by G_INSERT sequences. llvm-svn: 306120
This commit is contained in:
parent
b57bf2ac79
commit
4b4eec7009
|
@ -465,15 +465,6 @@ def G_INSERT : Instruction {
|
|||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
// Combine a sequence of generic vregs into a single larger value (starting at
|
||||
// bit 0). Essentially a G_INSERT where $src is an IMPLICIT_DEF, but it's so
|
||||
// important to legalization it probably deserves its own instruction.
|
||||
def G_SEQUENCE : Instruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins variable_ops);
|
||||
let hasSideEffects = 0;
|
||||
}
|
||||
|
||||
def G_MERGE_VALUES : Instruction {
|
||||
let OutOperandList = (outs type0:$dst);
|
||||
let InOperandList = (ins variable_ops);
|
||||
|
|
|
@ -241,8 +241,6 @@ HANDLE_TARGET_OPCODE(G_INSERT)
|
|||
|
||||
/// Generic instruction to paste a variable number of components together into a
|
||||
/// larger register.
|
||||
HANDLE_TARGET_OPCODE(G_SEQUENCE)
|
||||
|
||||
HANDLE_TARGET_OPCODE(G_MERGE_VALUES)
|
||||
|
||||
/// Generic pointer to int conversion.
|
||||
|
|
|
@ -50,70 +50,6 @@ void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
|
|||
void Legalizer::init(MachineFunction &MF) {
|
||||
}
|
||||
|
||||
bool Legalizer::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) {
|
||||
AllDefsReplaced = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned OrigReg = SeqI.getOperand(2 * SeqIdx + 1).getReg();
|
||||
if (SeqI.getOperand(2 * SeqIdx + 2).getImm() != ExtractPos ||
|
||||
MRI.getType(OrigReg) != MRI.getType(ExtractReg)) {
|
||||
AllDefsReplaced = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(!TargetRegisterInfo::isPhysicalRegister(OrigReg) &&
|
||||
"unexpected physical register in G_SEQUENCE");
|
||||
|
||||
// Finally we can replace the uses.
|
||||
MRI.replaceRegWith(ExtractReg, 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 Legalizer::combineMerges(MachineInstr &MI, MachineRegisterInfo &MRI,
|
||||
const TargetInstrInfo &TII,
|
||||
MachineIRBuilder &MIRBuilder) {
|
||||
|
@ -271,12 +207,6 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
|
|||
// Get the next Instruction before we try to legalize, because there's a
|
||||
// good chance MI will be deleted.
|
||||
NextMI = std::next(MI);
|
||||
|
||||
// combineExtracts erases MI.
|
||||
if (combineExtracts(*MI, MRI, TII)) {
|
||||
Changed = true;
|
||||
continue;
|
||||
}
|
||||
Changed |= combineMerges(*MI, MRI, TII, Helper.MIRBuilder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,8 +75,7 @@ LegalizerInfo::getAction(const InstrAspect &Aspect) const {
|
|||
|
||||
// FIXME: the long-term plan calls for expansion in terms of load/store (if
|
||||
// they're not legal).
|
||||
if (Aspect.Opcode == TargetOpcode::G_SEQUENCE ||
|
||||
Aspect.Opcode == TargetOpcode::G_EXTRACT ||
|
||||
if (Aspect.Opcode == TargetOpcode::G_EXTRACT ||
|
||||
Aspect.Opcode == TargetOpcode::G_MERGE_VALUES ||
|
||||
Aspect.Opcode == TargetOpcode::G_UNMERGE_VALUES)
|
||||
return std::make_pair(Legal, Aspect.Type);
|
||||
|
|
|
@ -469,10 +469,6 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
|
|||
getCopyMapping(DstRB.getID(), SrcRB.getID(), Size),
|
||||
/*NumOperands*/ 2);
|
||||
}
|
||||
case TargetOpcode::G_SEQUENCE:
|
||||
// FIXME: support this, but the generic code is really not going to do
|
||||
// anything sane.
|
||||
return getInvalidInstructionMapping();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
--- |
|
||||
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
||||
target triple = "aarch64--"
|
||||
define void @test_combines_1() { ret void }
|
||||
define void @test_combines_2() { ret void }
|
||||
define void @test_combines_3() { ret void }
|
||||
define void @test_combines_4() { ret void }
|
||||
|
@ -11,31 +10,6 @@
|
|||
define void @test_combines_6() { ret void }
|
||||
...
|
||||
|
||||
---
|
||||
name: test_combines_1
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %w0
|
||||
|
||||
%0:_(s32) = COPY %w0
|
||||
%1:_(s8) = G_TRUNC %0
|
||||
|
||||
; Only one of these extracts can be eliminated, the offsets don't match
|
||||
; properly in the other cases.
|
||||
; CHECK-LABEL: name: test_combines_1
|
||||
; CHECK: %2(s32) = G_SEQUENCE %1(s8), 1
|
||||
; CHECK: %3(s8) = G_EXTRACT %2(s32), 0
|
||||
; CHECK-NOT: G_EXTRACT
|
||||
; CHECK: %5(s8) = G_EXTRACT %2(s32), 2
|
||||
; CHECK: %6(s32) = G_ZEXT %1(s8)
|
||||
|
||||
%2:_(s32) = G_SEQUENCE %1, 1
|
||||
%3:_(s8) = G_EXTRACT %2, 0
|
||||
%4:_(s8) = G_EXTRACT %2, 1
|
||||
%5:_(s8) = G_EXTRACT %2, 2
|
||||
%6:_(s32) = G_ZEXT %4
|
||||
...
|
||||
|
||||
---
|
||||
name: test_combines_2
|
||||
body: |
|
||||
|
@ -46,11 +20,11 @@ body: |
|
|||
|
||||
; Similarly, here the types don't match.
|
||||
; CHECK-LABEL: name: test_combines_2
|
||||
; CHECK: %2(s64) = G_SEQUENCE %0(s32), 0, %1(s32), 32
|
||||
; CHECK: %2(s64) = G_MERGE_VALUES %0(s32), %1(s32)
|
||||
; CHECK: %3(s1) = G_EXTRACT %2(s64), 0
|
||||
; CHECK: %4(s64) = G_EXTRACT %2(s64), 0
|
||||
%1:_(s32) = G_ADD %0, %0
|
||||
%2:_(s64) = G_SEQUENCE %0, 0, %1, 32
|
||||
%2:_(s64) = G_MERGE_VALUES %0, %1
|
||||
%3:_(s1) = G_EXTRACT %2, 0
|
||||
%4:_(s64) = G_EXTRACT %2, 0
|
||||
...
|
||||
|
@ -69,9 +43,8 @@ body: |
|
|||
; CHECK-NOT: G_EXTRACT
|
||||
; CHECK: %5(s32) = G_ADD %0, %1
|
||||
%1:_(s32) = G_ADD %0, %0
|
||||
%2:_(s64) = G_SEQUENCE %0, 0, %1, 32
|
||||
%3:_(s32) = G_EXTRACT %2, 0
|
||||
%4:_(s32) = G_EXTRACT %2, 32
|
||||
%2:_(s64) = G_MERGE_VALUES %0, %1
|
||||
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2
|
||||
%5:_(s32) = G_ADD %3, %4
|
||||
...
|
||||
|
||||
|
@ -86,7 +59,7 @@ body: |
|
|||
; CHECK-LABEL: name: test_combines_4
|
||||
; CHECK: %2(<2 x s32>) = G_EXTRACT %1(s128), 0
|
||||
; CHECK: %3(<2 x s32>) = G_ADD %2, %2
|
||||
%1:_(s128) = G_SEQUENCE %0, 0, %0, 64
|
||||
%1:_(s128) = G_MERGE_VALUES %0, %0
|
||||
%2:_(<2 x s32>) = G_EXTRACT %1, 0
|
||||
%3:_(<2 x s32>) = G_ADD %2, %2
|
||||
...
|
||||
|
@ -100,13 +73,12 @@ body: |
|
|||
%0:_(s32) = COPY %w0
|
||||
|
||||
; CHECK-LABEL: name: test_combines_5
|
||||
; CHECK-NOT: G_SEQUENCE
|
||||
; CHECK-NOT: G_MERGE_VALUES
|
||||
; CHECK-NOT: G_EXTRACT
|
||||
; CHECK: %5(s32) = G_ADD %0, %1
|
||||
%1:_(s32) = G_ADD %0, %0
|
||||
%2:_(s64) = G_SEQUENCE %0, 0, %1, 32
|
||||
%3:_(s32) = G_EXTRACT %2, 0
|
||||
%4:_(s32) = G_EXTRACT %2, 32
|
||||
%2:_(s64) = G_MERGE_VALUES %0, %1
|
||||
%3:_(s32), %4:_(s32) = G_UNMERGE_VALUES %2
|
||||
%5:_(s32) = G_ADD %3, %4
|
||||
...
|
||||
|
||||
|
@ -121,12 +93,12 @@ body: |
|
|||
%0:_(s32) = COPY %w0
|
||||
|
||||
; Check that we replace all the uses of a G_EXTRACT.
|
||||
; CHECK-NOT: G_SEQUENCE
|
||||
; CHECK-NOT: G_MERGE_VALUES
|
||||
; CHECK-NOT: G_EXTRACT
|
||||
; CHECK: %3(s32) = G_MUL %0, %0
|
||||
; CHECK: %4(s32) = G_ADD %0, %3
|
||||
%1:_(s32) = G_SEQUENCE %0, 0
|
||||
%2:_(s32) = G_EXTRACT %1, 0
|
||||
%1:_(s32) = G_MERGE_VALUES %0
|
||||
%2:_(s32) = G_UNMERGE_VALUES %1
|
||||
%3:_(s32) = G_MUL %2, %2
|
||||
%4:_(s32) = G_ADD %2, %3
|
||||
...
|
||||
|
|
|
@ -24,7 +24,7 @@ body: |
|
|||
bb.0:
|
||||
liveins: %w0
|
||||
%0:gpr(s32) = COPY %w0
|
||||
%1:gpr(s32) = G_SEQUENCE %0(s32), 0
|
||||
%2:gpr(s32) = G_EXTRACT %1(s32), 0
|
||||
%1:gpr(s32) = G_MERGE_VALUES %0(s32)
|
||||
%2:gpr(s32) = G_UNMERGE_VALUES %1(s32)
|
||||
%w0 = COPY %2(s32)
|
||||
...
|
||||
|
|
Loading…
Reference in New Issue