Skip to content

Commit 0597273

Browse files
committed
Eliminate copies
1 parent 53f6715 commit 0597273

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

llvm/test/TableGen/GlobalISelEmitter/gisel-physreg-input.td

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,47 @@ def MULM_PHYS : I<(outs), (ins GPR32:$src0, GPR32:$src1),
6161
let Uses = [SPECIAL];
6262
}
6363

64+
// Try nested physical registers and check on duplicated copies
65+
66+
// GISEL: GIM_Try,
67+
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
68+
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
69+
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
70+
// GISEL-NEXT: // MIs[0] src0
71+
// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
72+
// GISEL-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
73+
// GISEL-NEXT: // MIs[0] Operand 1
74+
// GISEL-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
75+
// GISEL-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
76+
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
77+
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_MUL),
78+
// GISEL-NEXT: // MIs[1] Operand 0
79+
// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
80+
// GISEL-NEXT: // MIs[1] Operand 1
81+
// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
82+
// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
83+
// GISEL-NEXT: // MIs[1] Operand 2
84+
// GISEL-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
85+
// GISEL-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/GIMT_Encode2(MyTarget::Special32RegClassID),
86+
// GISEL-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
87+
// GISEL-NEXT: // (st GPR32:{ *:[i32] }:$src0, (mul:{ *:[i32] } R0:{ *:[i32] }, SPECIAL:{ *:[i32] })) => (MULMR0_PHYS GPR32:{ *:[i32] }:$src0)
88+
// GISEL-NEXT: GIR_BuildMI, /*InsnID*/2, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
89+
// GISEL-NEXT: GIR_AddRegister, /*InsnID*/2, GIMT_Encode2(MyTarget::SPECIAL), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
90+
// GISEL-NEXT: GIR_Copy, /*NewInsnID*/2, /*OldInsnID*/1, /*OpIdx*/2, // SPECIAL
91+
// GISEL-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::COPY),
92+
// GISEL-NEXT: GIR_AddRegister, /*InsnID*/1, GIMT_Encode2(MyTarget::R0), /*AddRegisterRegFlags*/GIMT_Encode2(RegState::Define),
93+
// GISEL-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/1, /*OpIdx*/1, // R0
94+
// GISEL-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::MULMR0_PHYS),
95+
// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // src0
96+
// GISEL-NEXT: GIR_MergeMemOperands, /*InsnID*/0, /*NumInsns*/2, /*MergeInsnID's*/0, 1,
97+
// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,
98+
// GISEL-NEXT: // GIR_Coverage, 1,
99+
// GISEL-NEXT: GIR_EraseRootFromParent_Done,
100+
def MULMR0_PHYS : I<(outs), (ins GPR32:$src0),
101+
[(st GPR32:$src0, (mul R0, SPECIAL))]> {
102+
let Uses = [R0, SPECIAL];
103+
}
104+
64105
// Try a normal physical register use.
65106

66107
// GISEL: GIM_Try,
@@ -83,7 +124,7 @@ def MULM_PHYS : I<(outs), (ins GPR32:$src0, GPR32:$src1),
83124
// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
84125
// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src0
85126
// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,
86-
// GISEL-NEXT: // GIR_Coverage, 1,
127+
// GISEL-NEXT: // GIR_Coverage, 2,
87128
// GISEL-NEXT: GIR_EraseRootFromParent_Done,
88129
def ADD_PHYS : I<(outs GPR32:$dst), (ins GPR32:$src0),
89130
[(set GPR32:$dst, (add GPR32:$src0, SPECIAL))]> {
@@ -112,7 +153,7 @@ def ADD_PHYS : I<(outs GPR32:$dst), (ins GPR32:$src0),
112153
// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
113154
// GISEL-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // SPECIAL
114155
// GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,
115-
// GISEL-NEXT: // GIR_Coverage, 2,
156+
// GISEL-NEXT: // GIR_Coverage, 3,
116157
// GISEL-NEXT: GIR_EraseRootFromParent_Done,
117158
def MUL_PHYS : I<(outs GPR32:$dst), (ins GPR32:$SPECIAL),
118159
[(set GPR32:$dst, (mul GPR32:$SPECIAL, SPECIAL))]> {

llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "Common/CodeGenDAGPatterns.h"
2020
#include "llvm/ADT/ArrayRef.h"
2121
#include "llvm/ADT/DenseMap.h"
22+
#include "llvm/ADT/MapVector.h"
2223
#include "llvm/ADT/SmallPtrSet.h"
2324
#include "llvm/ADT/StringMap.h"
2425
#include "llvm/ADT/StringRef.h"
@@ -492,7 +493,7 @@ class RuleMatcher : public Matcher {
492493
/// the renderers.
493494
StringMap<OperandMatcher *> DefinedOperands;
494495

495-
using PhysRegOperandsTy = DenseMap<const Record *, OperandMatcher *>;
496+
using PhysRegOperandsTy = MapVector<const Record *, OperandMatcher *>;
496497

497498
/// A map of anonymous physical register operands defined by the matchers that
498499
/// may be referenced by the renderers.

llvm/utils/TableGen/GlobalISelEmitter.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,17 +1413,14 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer(
14131413
BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get());
14141414

14151415
for (auto PhysOp : M.physoperands()) {
1416-
auto &OpInsnMatcher = PhysOp.second->getInstructionMatcher();
1417-
for (auto PhysInput : OpInsnMatcher.getPhysRegInputs()) {
1418-
InsertPt = M.insertAction<BuildMIAction>(
1419-
InsertPt, M.allocateOutputInsnID(),
1420-
&Target.getInstruction(RK.getDef("COPY")));
1421-
BuildMIAction &CopyToPhysRegMIBuilder =
1422-
*static_cast<BuildMIAction *>(InsertPt->get());
1423-
CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(
1424-
Target, PhysInput.first, true);
1425-
CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first);
1426-
}
1416+
InsertPt = M.insertAction<BuildMIAction>(
1417+
InsertPt, M.allocateOutputInsnID(),
1418+
&Target.getInstruction(RK.getDef("COPY")));
1419+
BuildMIAction &CopyToPhysRegMIBuilder =
1420+
*static_cast<BuildMIAction *>(InsertPt->get());
1421+
CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target,
1422+
PhysOp.first, true);
1423+
CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysOp.first);
14271424
}
14281425

14291426
if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst,

0 commit comments

Comments
 (0)