[llvm] 9fcebad - [SystemZ] Add a mapping from "select register" to "load on condition" (2-addr).
Jonas Paulsson via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 20 10:46:00 PST 2019
Author: Jonas Paulsson
Date: 2019-12-20T10:44:58-08:00
New Revision: 9fcebad5e5c1530d6d63a2b3d137dd1473b3b615
URL: https://github.com/llvm/llvm-project/commit/9fcebad5e5c1530d6d63a2b3d137dd1473b3b615
DIFF: https://github.com/llvm/llvm-project/commit/9fcebad5e5c1530d6d63a2b3d137dd1473b3b615.diff
LOG: [SystemZ] Add a mapping from "select register" to "load on condition" (2-addr).
The SELR(Mux) instructions can be converted to two-address form as LOCR(Mux)
instructions whenever one of the sources are the same reg as dest. By adding
this mapping in getTwoOperandOpcode(), we get:
- Two-address hints in getRegAllocationHints() for select register
instructions.
- No need anymore for special handling in SystemZShortenInst.cpp -
shortenSelect() removed.
The two-address hints are now added before the GRX32 hints, which should be
preferred.
Review: Ulrich Weigand
https://reviews.llvm.org/D68870
Added:
llvm/test/CodeGen/SystemZ/cond-move-regalloc-hints-02.mir
Modified:
llvm/lib/Target/SystemZ/SystemZInstrFormats.td
llvm/lib/Target/SystemZ/SystemZInstrInfo.td
llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
llvm/test/CodeGen/SystemZ/cond-move-08.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
index ba87ddb20f95..f064d33ac2f3 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -3209,6 +3209,8 @@ class CondBinaryRRF<string mnemonic, bits<16> opcode, RegisterOperand cls1,
let Constraints = "$R1 = $R1src";
let DisableEncoding = "$R1src";
let CCMaskLast = 1;
+ let NumOpsKey = !subst("loc", "sel", mnemonic);
+ let NumOpsValue = "2";
}
// Like CondBinaryRRF, but used for the raw assembly form. The condition-code
@@ -3248,6 +3250,8 @@ class CondBinaryRRFa<string mnemonic, bits<16> opcode, RegisterOperand cls1,
[(set cls1:$R1, (z_select_ccmask cls2:$R2, cls3:$R3,
cond4:$valid, cond4:$M4))]> {
let CCMaskLast = 1;
+ let NumOpsKey = mnemonic;
+ let NumOpsValue = "3";
}
// Like CondBinaryRRFa, but used for the raw assembly form. The condition-code
@@ -4798,7 +4802,8 @@ class TestBinarySILPseudo<SDPatternOperator operator, ImmOpWithPattern imm>
// Like CondBinaryRRF, but expanded after RA depending on the choice of
// register.
-class CondBinaryRRFPseudo<RegisterOperand cls1, RegisterOperand cls2>
+class CondBinaryRRFPseudo<string mnemonic, RegisterOperand cls1,
+ RegisterOperand cls2>
: Pseudo<(outs cls1:$R1),
(ins cls1:$R1src, cls2:$R2, cond4:$valid, cond4:$M3),
[(set cls1:$R1, (z_select_ccmask cls2:$R2, cls1:$R1src,
@@ -4806,17 +4811,21 @@ class CondBinaryRRFPseudo<RegisterOperand cls1, RegisterOperand cls2>
let Constraints = "$R1 = $R1src";
let DisableEncoding = "$R1src";
let CCMaskLast = 1;
+ let NumOpsKey = !subst("loc", "sel", mnemonic);
+ let NumOpsValue = "2";
}
// Like CondBinaryRRFa, but expanded after RA depending on the choice of
// register.
-class CondBinaryRRFaPseudo<RegisterOperand cls1, RegisterOperand cls2,
- RegisterOperand cls3>
+class CondBinaryRRFaPseudo<string mnemonic, RegisterOperand cls1,
+ RegisterOperand cls2, RegisterOperand cls3>
: Pseudo<(outs cls1:$R1),
(ins cls3:$R3, cls2:$R2, cond4:$valid, cond4:$M4),
[(set cls1:$R1, (z_select_ccmask cls2:$R2, cls3:$R3,
cond4:$valid, cond4:$M4))]> {
let CCMaskLast = 1;
+ let NumOpsKey = mnemonic;
+ let NumOpsValue = "3";
}
// Like CondBinaryRIE, but expanded after RA depending on the choice of
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
index aa981e718b5f..9579dcc0d1b6 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -492,7 +492,7 @@ let Predicates = [FeatureMiscellaneousExtensions3], Uses = [CC] in {
let isCommutable = 1 in {
// Expands to SELR or SELFHR or a branch-and-move sequence,
// depending on the choice of registers.
- def SELRMux : CondBinaryRRFaPseudo<GRX32, GRX32, GRX32>;
+ def SELRMux : CondBinaryRRFaPseudo<"selrmux", GRX32, GRX32, GRX32>;
defm SELFHR : CondBinaryRRFaPair<"selfhr", 0xB9C0, GRH32, GRH32, GRH32>;
defm SELR : CondBinaryRRFaPair<"selr", 0xB9F0, GR32, GR32, GR32>;
defm SELGR : CondBinaryRRFaPair<"selgr", 0xB9E3, GR64, GR64, GR64>;
@@ -525,7 +525,7 @@ let Predicates = [FeatureLoadStoreOnCond2], Uses = [CC] in {
let isCommutable = 1 in {
// Expands to LOCR or LOCFHR or a branch-and-move sequence,
// depending on the choice of registers.
- def LOCRMux : CondBinaryRRFPseudo<GRX32, GRX32>;
+ def LOCRMux : CondBinaryRRFPseudo<"locrmux", GRX32, GRX32>;
defm LOCFHR : CondBinaryRRFPair<"locfhr", 0xB9E0, GRH32, GRH32>;
}
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index cbcfc07f2b16..0d5e7af92523 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -87,6 +87,52 @@ SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
bool BaseImplRetVal = TargetRegisterInfo::getRegAllocationHints(
VirtReg, Order, Hints, MF, VRM, Matrix);
+ if (VRM != nullptr) {
+ // Add any two address hints after any copy hints.
+ SmallSet<unsigned, 4> TwoAddrHints;
+ for (auto &Use : MRI->reg_nodbg_instructions(VirtReg))
+ if (SystemZ::getTwoOperandOpcode(Use.getOpcode()) != -1) {
+ const MachineOperand *VRRegMO = nullptr;
+ const MachineOperand *OtherMO = nullptr;
+ const MachineOperand *CommuMO = nullptr;
+ if (VirtReg == Use.getOperand(0).getReg()) {
+ VRRegMO = &Use.getOperand(0);
+ OtherMO = &Use.getOperand(1);
+ if (Use.isCommutable())
+ CommuMO = &Use.getOperand(2);
+ } else if (VirtReg == Use.getOperand(1).getReg()) {
+ VRRegMO = &Use.getOperand(1);
+ OtherMO = &Use.getOperand(0);
+ } else if (VirtReg == Use.getOperand(2).getReg() &&
+ Use.isCommutable()) {
+ VRRegMO = &Use.getOperand(2);
+ OtherMO = &Use.getOperand(0);
+ } else
+ continue;
+
+ auto tryAddHint = [&](const MachineOperand *MO) -> void {
+ Register Reg = MO->getReg();
+ Register PhysReg =
+ Register::isPhysicalRegister(Reg) ? Reg : VRM->getPhys(Reg);
+ if (PhysReg) {
+ if (MO->getSubReg())
+ PhysReg = getSubReg(PhysReg, MO->getSubReg());
+ if (VRRegMO->getSubReg())
+ PhysReg = getMatchingSuperReg(PhysReg, VRRegMO->getSubReg(),
+ MRI->getRegClass(VirtReg));
+ if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
+ TwoAddrHints.insert(PhysReg);
+ }
+ };
+ tryAddHint(OtherMO);
+ if (CommuMO)
+ tryAddHint(CommuMO);
+ }
+ for (MCPhysReg OrderReg : Order)
+ if (TwoAddrHints.count(OrderReg))
+ Hints.push_back(OrderReg);
+ }
+
if (MRI->getRegClass(VirtReg) == &SystemZ::GRX32BitRegClass) {
SmallVector<unsigned, 8> Worklist;
SmallSet<unsigned, 4> DoneRegs;
@@ -143,52 +189,6 @@ SystemZRegisterInfo::getRegAllocationHints(unsigned VirtReg,
}
}
- if (VRM == nullptr)
- return BaseImplRetVal;
-
- // Add any two address hints after any copy hints.
- SmallSet<unsigned, 4> TwoAddrHints;
- for (auto &Use : MRI->reg_nodbg_instructions(VirtReg))
- if (SystemZ::getTwoOperandOpcode(Use.getOpcode()) != -1) {
- const MachineOperand *VRRegMO = nullptr;
- const MachineOperand *OtherMO = nullptr;
- const MachineOperand *CommuMO = nullptr;
- if (VirtReg == Use.getOperand(0).getReg()) {
- VRRegMO = &Use.getOperand(0);
- OtherMO = &Use.getOperand(1);
- if (Use.isCommutable())
- CommuMO = &Use.getOperand(2);
- } else if (VirtReg == Use.getOperand(1).getReg()) {
- VRRegMO = &Use.getOperand(1);
- OtherMO = &Use.getOperand(0);
- } else if (VirtReg == Use.getOperand(2).getReg() && Use.isCommutable()) {
- VRRegMO = &Use.getOperand(2);
- OtherMO = &Use.getOperand(0);
- } else
- continue;
-
- auto tryAddHint = [&](const MachineOperand *MO) -> void {
- Register Reg = MO->getReg();
- Register PhysReg =
- Register::isPhysicalRegister(Reg) ? Reg : VRM->getPhys(Reg);
- if (PhysReg) {
- if (MO->getSubReg())
- PhysReg = getSubReg(PhysReg, MO->getSubReg());
- if (VRRegMO->getSubReg())
- PhysReg = getMatchingSuperReg(PhysReg, VRRegMO->getSubReg(),
- MRI->getRegClass(VirtReg));
- if (!MRI->isReserved(PhysReg) && !is_contained(Hints, PhysReg))
- TwoAddrHints.insert(PhysReg);
- }
- };
- tryAddHint(OtherMO);
- if (CommuMO)
- tryAddHint(CommuMO);
- }
- for (MCPhysReg OrderReg : Order)
- if (TwoAddrHints.count(OrderReg))
- Hints.push_back(OrderReg);
-
return BaseImplRetVal;
}
diff --git a/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp b/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
index 1b9c8ea2759a..f6184cec795a 100644
--- a/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZShortenInst.cpp
@@ -46,7 +46,6 @@ class SystemZShortenInst : public MachineFunctionPass {
bool shortenOn001(MachineInstr &MI, unsigned Opcode);
bool shortenOn001AddCC(MachineInstr &MI, unsigned Opcode);
bool shortenFPConv(MachineInstr &MI, unsigned Opcode);
- bool shortenSelect(MachineInstr &MI, unsigned Opcode);
const SystemZInstrInfo *TII;
const TargetRegisterInfo *TRI;
@@ -176,23 +175,6 @@ bool SystemZShortenInst::shortenFPConv(MachineInstr &MI, unsigned Opcode) {
return false;
}
-// MI is a three-operand select instruction. If one of the sources match
-// the destination, convert to the equivalent load-on-condition.
-bool SystemZShortenInst::shortenSelect(MachineInstr &MI, unsigned Opcode) {
- if (MI.getOperand(0).getReg() == MI.getOperand(1).getReg()) {
- MI.setDesc(TII->get(Opcode));
- MI.tieOperands(0, 1);
- return true;
- }
- if (MI.getOperand(0).getReg() == MI.getOperand(2).getReg()) {
- TII->commuteInstruction(MI, false, 1, 2);
- MI.setDesc(TII->get(Opcode));
- MI.tieOperands(0, 1);
- return true;
- }
- return false;
-}
-
// Process all instructions in MBB. Return true if something changed.
bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
bool Changed = false;
@@ -213,18 +195,6 @@ bool SystemZShortenInst::processBlock(MachineBasicBlock &MBB) {
Changed |= shortenIIF(MI, SystemZ::LLIHL, SystemZ::LLIHH);
break;
- case SystemZ::SELR:
- Changed |= shortenSelect(MI, SystemZ::LOCR);
- break;
-
- case SystemZ::SELFHR:
- Changed |= shortenSelect(MI, SystemZ::LOCFHR);
- break;
-
- case SystemZ::SELGR:
- Changed |= shortenSelect(MI, SystemZ::LOCGR);
- break;
-
case SystemZ::WFADB:
Changed |= shortenOn001AddCC(MI, SystemZ::ADBR);
break;
diff --git a/llvm/test/CodeGen/SystemZ/cond-move-08.mir b/llvm/test/CodeGen/SystemZ/cond-move-08.mir
index aed611036015..c82e3e258ad9 100644
--- a/llvm/test/CodeGen/SystemZ/cond-move-08.mir
+++ b/llvm/test/CodeGen/SystemZ/cond-move-08.mir
@@ -2,7 +2,7 @@
# RUN: | FileCheck %s
#
# Test that regalloc manages (via regalloc hints) to avoid a LOCRMux jump
-# sequence expansion, and a SELR instuction is emitted.
+# sequence expansion, and a SELR/LOCR instuction is emitted.
--- |
; ModuleID = 'tc.ll'
@@ -78,7 +78,7 @@
...
-# CHECK: selr
+# CHECK: locr
# CHECK-NOT: risblg
---
diff --git a/llvm/test/CodeGen/SystemZ/cond-move-regalloc-hints-02.mir b/llvm/test/CodeGen/SystemZ/cond-move-regalloc-hints-02.mir
new file mode 100644
index 000000000000..8acf0197a7f4
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/cond-move-regalloc-hints-02.mir
@@ -0,0 +1,54 @@
+# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z15 -start-before=greedy %s -o - \
+# RUN: | FileCheck %s
+#
+# Test that two-address reg alloc hints are given so that a SELR becomes LOCR.
+
+
+--- |
+ define i32 @fun(i32 %arg, i32 %arg1, i32 %arg2, i32* %arg3) { ret i32 0 }
+ declare void @foo(i32)
+...
+# CHECK-LABEL: fun
+# CHECK: locr
+
+---
+name: fun
+alignment: 16
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gr32bit }
+ - { id: 1, class: gr32bit }
+ - { id: 2, class: gr32bit }
+ - { id: 3, class: gr32bit }
+ - { id: 4, class: gr64bit }
+ - { id: 5, class: grx32bit }
+ - { id: 6, class: grx32bit }
+ - { id: 7, class: addr64bit }
+ - { id: 8, class: grx32bit }
+ - { id: 9, class: grx32bit }
+ - { id: 10, class: gr64bit }
+ - { id: 11, class: gr32bit }
+frameInfo:
+ maxAlignment: 1
+ hasCalls: true
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ %5:grx32bit = LHIMux 88
+ %8:grx32bit = LHIMux 77
+ %9:grx32bit = LHIMux 66
+
+ bb.1:
+ %6:grx32bit = LLCMux undef %7:addr64bit, 0, $noreg :: (load 1 from `i8* undef`)
+ CHIMux %6, 1, implicit-def $cc
+ %11:gr32bit = SELRMux %8, %9:grx32bit, 14, 6, implicit killed $cc
+ CHIMux %6, 2, implicit-def $cc
+ %0:gr32bit = SELRMux %11, %5, 14, 8, implicit killed $cc
+ ADJCALLSTACKDOWN 0, 0
+ %10:gr64bit = LGFR %0
+ $r2d = COPY %10
+ CallBRASL @foo, killed $r2d, csr_systemz, implicit-def dead $r14d, implicit-def dead $cc, implicit $fpc
+ ADJCALLSTACKUP 0, 0
+ J %bb.1
+
+...
More information about the llvm-commits
mailing list