summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2015-04-23 23:24:36 +0000
committerMatthias Braun <matze@braunis.de>2015-04-23 23:24:36 +0000
commit43fb8a157b270e70d553231c8561a2efd012c774 (patch)
tree048d7dca4e10e4a18d3a806111fd229179a35984 /llvm/lib/CodeGen
parent5c5facc2ce1b8469494e37c07f69223e3bc45d2c (diff)
downloadbcm5719-llvm-43fb8a157b270e70d553231c8561a2efd012c774.tar.gz
bcm5719-llvm-43fb8a157b270e70d553231c8561a2efd012c774.zip
RegisterCoalescer: Avoid unnecessary register class widening for some rematerializations
I couldn't provide a testcase as none of the public targets has wide register classes with alot of subregisters and at the same time an instruction which "ReMaterializable" and "AsCheapAsAMove" (could probably be added for R600). llvm-svn: 235668
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 5d958a61e6a..a8fcd950268 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -194,7 +194,7 @@ namespace {
/// If the source of a copy is defined by a
/// trivial computation, replace the copy by rematerialize the definition.
- bool reMaterializeTrivialDef(CoalescerPair &CP, MachineInstr *CopyMI,
+ bool reMaterializeTrivialDef(const CoalescerPair &CP, MachineInstr *CopyMI,
bool &IsDefCopy);
/// Return true if a copy involving a physreg should be joined.
@@ -851,7 +851,7 @@ static bool definesFullReg(const MachineInstr &MI, unsigned Reg) {
return false;
}
-bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
+bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
MachineInstr *CopyMI,
bool &IsDefCopy) {
IsDefCopy = false;
@@ -929,6 +929,29 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, DefMI, *TRI);
MachineInstr *NewMI = std::prev(MII);
+ // A situation like the following:
+ // %vreg0:subX = instr ; DefMI
+ // %vregY = copy %vreg:subX ; CopyMI
+ // does not need subregisters/regclass widening after rematerialization, just
+ // do:
+ // %vregY = instr
+ const TargetRegisterClass *NewRC = CP.getNewRC();
+ if (DstIdx != 0) {
+ MachineOperand &DefMO = NewMI->getOperand(0);
+ if (DefMO.getSubReg() == DstIdx) {
+ assert(SrcIdx == 0 && CP.isFlipped()
+ && "Shouldn't have SrcIdx+DstIdx at this point");
+ const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg);
+ const TargetRegisterClass *CommonRC =
+ TRI->getCommonSubClass(DefRC, DstRC);
+ if (CommonRC != nullptr) {
+ NewRC = CommonRC;
+ DstIdx = 0;
+ DefMO.setSubReg(0);
+ }
+ }
+ }
+
LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI);
CopyMI->eraseFromParent();
ErasedInstrs.insert(CopyMI);
@@ -948,7 +971,6 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP,
}
if (TargetRegisterInfo::isVirtualRegister(DstReg)) {
- const TargetRegisterClass *NewRC = CP.getNewRC();
unsigned NewIdx = NewMI->getOperand(0).getSubReg();
if (DefRC != nullptr) {
OpenPOWER on IntegriCloud