summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/R600
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-02-05 17:53:52 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-02-05 17:53:52 +0000
commitfdc37670f64615d2d84d3beddee074d7d8151b96 (patch)
tree50b4ab2a41599c18a87faff3ccbeb8bc10e5997a /llvm/lib/Target/R600
parentbf034dbd324380893a09c7ad62ac4ce95c8adff5 (diff)
downloadbcm5719-llvm-fdc37670f64615d2d84d3beddee074d7d8151b96.tar.gz
bcm5719-llvm-fdc37670f64615d2d84d3beddee074d7d8151b96.zip
Don't use MRI liveouts in R600.
Something very strange is going on with the output registers in this target. Its ISelLowering code is inserting dangling CopyToReg nodes, hoping that those physregs won't get clobbered before the RETURN. This patch adds the output registers as implicit uses on RETURN instructions in the custom emission pass. I'd much prefer to have those CopyToReg nodes glued to the RETURNs, but I don't see how. llvm-svn: 174400
Diffstat (limited to 'llvm/lib/Target/R600')
-rw-r--r--llvm/lib/Target/R600/R600ISelLowering.cpp15
-rw-r--r--llvm/lib/Target/R600/R600Instructions.td3
-rw-r--r--llvm/lib/Target/R600/R600MachineFunctionInfo.h1
3 files changed, 14 insertions, 5 deletions
diff --git a/llvm/lib/Target/R600/R600ISelLowering.cpp b/llvm/lib/Target/R600/R600ISelLowering.cpp
index 8fe31e0509b..110dcc18876 100644
--- a/llvm/lib/Target/R600/R600ISelLowering.cpp
+++ b/llvm/lib/Target/R600/R600ISelLowering.cpp
@@ -266,6 +266,15 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
.addImm(EOP);
break;
}
+ case AMDGPU::RETURN: {
+ // RETURN instructions must have the live-out registers as implicit uses,
+ // otherwise they appear dead.
+ R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>();
+ MachineInstrBuilder MIB(*MF, MI);
+ for (unsigned i = 0, e = MFI->LiveOuts.size(); i != e; ++i)
+ MIB.addReg(MFI->LiveOuts[i], RegState::Implicit);
+ return BB;
+ }
}
MI->eraseFromParent();
@@ -348,12 +357,10 @@ SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
switch (IntrinsicID) {
case AMDGPUIntrinsic::AMDGPU_store_output: {
MachineFunction &MF = DAG.getMachineFunction();
- MachineRegisterInfo &MRI = MF.getRegInfo();
+ R600MachineFunctionInfo *MFI = MF.getInfo<R600MachineFunctionInfo>();
int64_t RegIndex = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex);
- if (!MRI.isLiveOut(Reg)) {
- MRI.addLiveOut(Reg);
- }
+ MFI->LiveOuts.push_back(Reg);
return DAG.getCopyToReg(Chain, Op.getDebugLoc(), Reg, Op.getOperand(2));
}
case AMDGPUIntrinsic::R600_store_pixel_color: {
diff --git a/llvm/lib/Target/R600/R600Instructions.td b/llvm/lib/Target/R600/R600Instructions.td
index bcbb5a107b9..f935313fe9b 100644
--- a/llvm/lib/Target/R600/R600Instructions.td
+++ b/llvm/lib/Target/R600/R600Instructions.td
@@ -1580,7 +1580,8 @@ def FNEG_R600 : FNEG<R600_Reg32>;
//===---------------------------------------------------------------------===//
// Return instruction
//===---------------------------------------------------------------------===//
-let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
+let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1,
+ usesCustomInserter = 1 in {
def RETURN : ILFormat<(outs), (ins variable_ops),
"RETURN", [(IL_retflag)]>;
}
diff --git a/llvm/lib/Target/R600/R600MachineFunctionInfo.h b/llvm/lib/Target/R600/R600MachineFunctionInfo.h
index 0cea2117427..ad7b4da45ae 100644
--- a/llvm/lib/Target/R600/R600MachineFunctionInfo.h
+++ b/llvm/lib/Target/R600/R600MachineFunctionInfo.h
@@ -23,6 +23,7 @@ class R600MachineFunctionInfo : public MachineFunctionInfo {
public:
R600MachineFunctionInfo(const MachineFunction &MF);
+ SmallVector<unsigned, 4> LiveOuts;
SDNode *Outputs[16];
};
OpenPOWER on IntegriCloud