Skip to content

Commit 8cfae93

Browse files
committed
Find dead register to use to prevent save-reload
1 parent f7a15e0 commit 8cfae93

File tree

1 file changed

+51
-15
lines changed

1 file changed

+51
-15
lines changed

llvm/lib/Target/X86/X86LowerTileCopy.cpp

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "X86InstrBuilder.h"
2121
#include "X86InstrInfo.h"
2222
#include "X86Subtarget.h"
23+
#include "llvm/CodeGen/LivePhysRegs.h"
2324
#include "llvm/CodeGen/MachineBasicBlock.h"
2425
#include "llvm/CodeGen/MachineFrameInfo.h"
2526
#include "llvm/CodeGen/MachineFunction.h"
@@ -73,6 +74,7 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
7374
const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>();
7475
const X86InstrInfo *TII = ST.getInstrInfo();
7576
bool Changed = false;
77+
MachineRegisterInfo &MRI = MF.getRegInfo();
7678

7779
for (MachineBasicBlock &MBB : MF) {
7880
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
@@ -90,22 +92,54 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
9092
unsigned Size = TRI->getSpillSize(X86::TILERegClass);
9193
Align Alignment = TRI->getSpillAlign(X86::TILERegClass);
9294
int TileSS = MF.getFrameInfo().CreateSpillStackObject(Size, Alignment);
93-
// Allocate stack slot for stride register
94-
Size = TRI->getSpillSize(X86::GR64RegClass);
95-
Alignment = TRI->getSpillAlign(X86::GR64RegClass);
96-
int StrideSS = MF.getFrameInfo().CreateSpillStackObject(Size, Alignment);
95+
int StrideSS = 0;
9796

98-
// TODO: Pick a killed regiter to avoid save/reload. There is problem
97+
LivePhysRegs UsedRegs(*TRI);
98+
UsedRegs.addLiveOuts(MBB);
99+
100+
const MCPhysReg *CSRegs = TRI->getCalleeSavedRegs(&MF);
101+
for (unsigned i = 0; CSRegs[i]; ++i)
102+
UsedRegs.addReg(CSRegs[i]);
103+
104+
auto InstUpToMI = MBB.end();
105+
while (InstUpToMI != MI)
106+
// The pre-decrement is on purpose here.
107+
// We want to have the liveness right before I.
108+
UsedRegs.stepBackward(*--InstUpToMI);
109+
110+
// Look for a temporary register to use.
111+
BitVector GR64Regs =
112+
TRI->getAllocatableSet(MF, TRI->getRegClass(X86::GR64RegClassID));
113+
// Pick a killed regiter to avoid save/reload. There is problem
99114
// to get live interval in this stage.
100115
Register GR64Cand = X86::RAX;
101116

117+
// Find the first available-register that is available
118+
bool found = false;
119+
for (auto RegT : GR64Regs.set_bits()) {
120+
if (UsedRegs.available(MRI, RegT)) {
121+
GR64Cand = RegT;
122+
break;
123+
}
124+
}
125+
102126
const DebugLoc &DL = MI.getDebugLoc();
103-
// mov %rax (%sp)
104-
BuildMI(MBB, MI, DL, TII->get(X86::IMPLICIT_DEF), GR64Cand);
105-
addFrameReference(BuildMI(MBB, MI, DL, TII->get(X86::MOV64mr)), StrideSS)
106-
.addReg(GR64Cand);
107-
// mov 64 %rax
108-
BuildMI(MBB, MI, DL, TII->get(X86::MOV64ri), GR64Cand).addImm(64);
127+
if (found) {
128+
// mov 64 %reg
129+
BuildMI(MBB, MI, DL, TII->get(X86::MOV64ri), GR64Cand).addImm(64);
130+
} else {
131+
// Allocate stack slot for stride register
132+
Size = TRI->getSpillSize(X86::GR64RegClass);
133+
Alignment = TRI->getSpillAlign(X86::GR64RegClass);
134+
StrideSS = MF.getFrameInfo().CreateSpillStackObject(Size, Alignment);
135+
// mov %rax (%sp)
136+
BuildMI(MBB, MI, DL, TII->get(X86::IMPLICIT_DEF), GR64Cand);
137+
addFrameReference(BuildMI(MBB, MI, DL, TII->get(X86::MOV64mr)),
138+
StrideSS)
139+
.addReg(GR64Cand);
140+
// mov 64 %rax
141+
BuildMI(MBB, MI, DL, TII->get(X86::MOV64ri), GR64Cand).addImm(64);
142+
}
109143
// tilestored %tmm, (%sp, %idx)
110144
#define GET_EGPR_IF_ENABLED(OPC) (ST.hasEGPR() ? OPC##_EVEX : OPC)
111145
unsigned Opc = GET_EGPR_IF_ENABLED(X86::TILESTORED);
@@ -120,10 +154,12 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
120154
#undef GET_EGPR_IF_ENABLED
121155
NewMI = addFrameReference(BuildMI(MBB, MI, DL, TII->get(Opc), DstReg),
122156
TileSS);
123-
// restore %rax
124-
// mov (%sp) %rax
125-
addFrameReference(BuildMI(MBB, MI, DL, TII->get(X86::MOV64rm), GR64Cand),
126-
StrideSS);
157+
if (!found) {
158+
// restore %rax
159+
// mov (%sp) %rax
160+
addFrameReference(
161+
BuildMI(MBB, MI, DL, TII->get(X86::MOV64rm), GR64Cand), StrideSS);
162+
}
127163
MI.eraseFromParent();
128164
Changed = true;
129165
}

0 commit comments

Comments
 (0)