summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-28 13:40:08 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-28 13:40:08 +0000
commit758399131a90a15fac6a329d3f6b2f35ea006bc7 (patch)
treedf566985e97bb005264c8b66d309ff7918d26055 /llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
parent524f276c744e15e17e2384f03933390d1957b2dc (diff)
downloadbcm5719-llvm-758399131a90a15fac6a329d3f6b2f35ea006bc7.tar.gz
bcm5719-llvm-758399131a90a15fac6a329d3f6b2f35ea006bc7.zip
[SystemZ] Add remaining branch instructions
This patch adds assembler support for the remaining branch instructions: the non-relative branch on count variants, and all variants of branch on index. The only one of those that can be readily exploited for code generation is BRCTH (branch on count using a high 32-bit register as count). Do use it, however, it is necessary to also introduce a hew CHIMux pseudo to allow comparisons of a 32-bit value agains a short immediate to go into a high register as well (implemented via CHI/CIH). This causes a bit of codegen changes overall, but those have proven to be neutral (or even beneficial) in performance measurements. llvm-svn: 288029
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZElimCompare.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZElimCompare.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
index 6b07c540400..b292b554779 100644
--- a/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZElimCompare.cpp
@@ -171,7 +171,7 @@ static unsigned getCompareSourceReg(MachineInstr &Compare) {
// Compare compares the result of MI against zero. If MI is an addition
// of -1 and if CCUsers is a single branch on nonzero, eliminate the addition
-// and convert the branch to a BRCT(G). Return true on success.
+// and convert the branch to a BRCT(G) or BRCTH. Return true on success.
bool SystemZElimCompare::convertToBRCT(
MachineInstr &MI, MachineInstr &Compare,
SmallVectorImpl<MachineInstr *> &CCUsers) {
@@ -182,6 +182,8 @@ bool SystemZElimCompare::convertToBRCT(
BRCT = SystemZ::BRCT;
else if (Opcode == SystemZ::AGHI)
BRCT = SystemZ::BRCTG;
+ else if (Opcode == SystemZ::AIH)
+ BRCT = SystemZ::BRCTH;
else
return false;
if (MI.getOperand(2).getImm() != -1)
@@ -205,16 +207,20 @@ bool SystemZElimCompare::convertToBRCT(
if (getRegReferences(*MBBI, SrcReg))
return false;
- // The transformation is OK. Rebuild Branch as a BRCT(G).
+ // The transformation is OK. Rebuild Branch as a BRCT(G) or BRCTH.
MachineOperand Target(Branch->getOperand(2));
while (Branch->getNumOperands())
Branch->RemoveOperand(0);
Branch->setDesc(TII->get(BRCT));
- MachineInstrBuilder(*Branch->getParent()->getParent(), Branch)
- .addOperand(MI.getOperand(0))
- .addOperand(MI.getOperand(1))
- .addOperand(Target)
- .addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
+ MachineInstrBuilder MIB(*Branch->getParent()->getParent(), Branch);
+ MIB.addOperand(MI.getOperand(0))
+ .addOperand(MI.getOperand(1))
+ .addOperand(Target);
+ // Add a CC def to BRCT(G), since we may have to split them again if the
+ // branch displacement overflows. BRCTH has a 32-bit displacement, so
+ // this is not necessary there.
+ if (BRCT != SystemZ::BRCTH)
+ MIB.addReg(SystemZ::CC, RegState::ImplicitDefine | RegState::Dead);
MI.eraseFromParent();
return true;
}
OpenPOWER on IntegriCloud