20
20
#include " X86InstrBuilder.h"
21
21
#include " X86InstrInfo.h"
22
22
#include " X86Subtarget.h"
23
+ #include " llvm/CodeGen/LivePhysRegs.h"
23
24
#include " llvm/CodeGen/MachineBasicBlock.h"
24
25
#include " llvm/CodeGen/MachineFrameInfo.h"
25
26
#include " llvm/CodeGen/MachineFunction.h"
@@ -73,6 +74,7 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
73
74
const X86Subtarget &ST = MF.getSubtarget <X86Subtarget>();
74
75
const X86InstrInfo *TII = ST.getInstrInfo ();
75
76
bool Changed = false ;
77
+ MachineRegisterInfo &MRI = MF.getRegInfo ();
76
78
77
79
for (MachineBasicBlock &MBB : MF) {
78
80
for (MachineInstr &MI : llvm::make_early_inc_range (MBB)) {
@@ -90,22 +92,54 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
90
92
unsigned Size = TRI->getSpillSize (X86::TILERegClass);
91
93
Align Alignment = TRI->getSpillAlign (X86::TILERegClass);
92
94
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 ;
97
96
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
99
114
// to get live interval in this stage.
100
115
Register GR64Cand = X86::RAX;
101
116
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
+
102
126
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
+ }
109
143
// tilestored %tmm, (%sp, %idx)
110
144
#define GET_EGPR_IF_ENABLED (OPC ) (ST.hasEGPR() ? OPC##_EVEX : OPC)
111
145
unsigned Opc = GET_EGPR_IF_ENABLED (X86::TILESTORED);
@@ -120,10 +154,12 @@ bool X86LowerTileCopy::runOnMachineFunction(MachineFunction &MF) {
120
154
#undef GET_EGPR_IF_ENABLED
121
155
NewMI = addFrameReference (BuildMI (MBB, MI, DL, TII->get (Opc), DstReg),
122
156
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
+ }
127
163
MI.eraseFromParent ();
128
164
Changed = true ;
129
165
}
0 commit comments