1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

PTX: Use external symbols to keep track of params and locals. This also fixes

a couple of outstanding issues with frame objects occuring as instruction
operands.

llvm-svn: 140616
This commit is contained in:
Justin Holewinski 2011-09-27 18:12:55 +00:00
parent 08b5751146
commit d7f59a21a7
6 changed files with 64 additions and 55 deletions

View File

@ -66,10 +66,6 @@ public:
void printOperand(const MachineInstr *MI, int opNum, raw_ostream &OS);
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
void printParamOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
void printLocalOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
void printReturnOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
void printPredicateOperand(const MachineInstr *MI, raw_ostream &O);
@ -415,6 +411,9 @@ void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
case MachineOperand::MO_Register:
OS << MFI->getRegisterName(MO.getReg());
break;
case MachineOperand::MO_ExternalSymbol:
OS << MO.getSymbolName();
break;
case MachineOperand::MO_FPImmediate:
APInt constFP = MO.getFPImm()->getValueAPF().bitcastToAPInt();
bool isFloat = MO.getFPImm()->getType()->getTypeID() == Type::FloatTyID;
@ -451,29 +450,12 @@ void PTXAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
printOperand(MI, opNum+1, OS);
}
void PTXAsmPrinter::printParamOperand(const MachineInstr *MI, int opNum,
raw_ostream &OS, const char *Modifier) {
const PTXMachineFunctionInfo *MFI = MI->getParent()->getParent()->
getInfo<PTXMachineFunctionInfo>();
OS << MFI->getParamManager().getParamName(MI->getOperand(opNum).getImm());
}
void PTXAsmPrinter::printReturnOperand(const MachineInstr *MI, int opNum,
raw_ostream &OS, const char *Modifier) {
//OS << RETURN_PREFIX << (int) MI->getOperand(opNum).getImm() + 1;
OS << "__ret";
}
void PTXAsmPrinter::printLocalOperand(const MachineInstr *MI, int opNum,
raw_ostream &OS, const char *Modifier) {
OS << "__local" << MI->getOperand(opNum).getImm();
if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() != 0){
OS << "+";
printOperand(MI, opNum+1, OS);
}
}
void PTXAsmPrinter::EmitVariableDeclaration(const GlobalVariable *gv) {
// Check to see if this is a special global used by LLVM, if so, emit it.
if (EmitSpecialLLVMGlobal(gv))
@ -702,7 +684,7 @@ printCall(const MachineInstr *MI, raw_ostream &O) {
} else {
O << ", ";
}
printParamOperand(MI, Index, O);
printOperand(MI, Index, O);
Index++;
}
@ -718,7 +700,7 @@ printCall(const MachineInstr *MI, raw_ostream &O) {
Index++;
while (Index < MI->getNumOperands()) {
printParamOperand(MI, Index, O);
printOperand(MI, Index, O);
if (Index < MI->getNumOperands()-1) {
O << ", ";
}

View File

@ -12,7 +12,9 @@
//===----------------------------------------------------------------------===//
#include "PTX.h"
#include "PTXMachineFunctionInfo.h"
#include "PTXTargetMachine.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/Debug.h"
@ -180,20 +182,14 @@ SDNode *PTXDAGToDAGISel::SelectWRITEPARAM(SDNode *Node) {
SDNode *PTXDAGToDAGISel::SelectFrameIndex(SDNode *Node) {
int FI = cast<FrameIndexSDNode>(Node)->getIndex();
//dbgs() << "Selecting FrameIndex at index " << FI << "\n";
SDValue TFI = CurDAG->getTargetFrameIndex(FI, Node->getValueType(0));
//SDValue TFI = CurDAG->getTargetFrameIndex(FI, Node->getValueType(0));
//unsigned OpCode = PTX::LOAD_LOCAL_F32;
PTXMachineFunctionInfo *MFI = MF->getInfo<PTXMachineFunctionInfo>();
//for (SDNode::use_iterator i = Node->use_begin(), e = Node->use_end();
// i != e; ++i) {
// SDNode *Use = *i;
// dbgs() << "USE: ";
// Use->dumpr(CurDAG);
//}
SDValue FrameSymbol = CurDAG->getTargetExternalSymbol(MFI->getFrameSymbol(FI),
Node->getValueType(0));
return Node;
//return CurDAG->getMachineNode(OpCode, Node->getDebugLoc(),
// Node->getValueType(0), TFI);
return FrameSymbol.getNode();
}
// Match memory operand of the form [reg+reg]

View File

@ -225,8 +225,11 @@ SDValue PTXTargetLowering::
unsigned ParamSize = Ins[i].VT.getStoreSizeInBits();
unsigned Param = PM.addArgumentParam(ParamSize);
std::string ParamName = PM.getParamName(Param);
SDValue ParamValue = DAG.getTargetExternalSymbol(ParamName.c_str(),
MVT::Other);
SDValue ArgValue = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain,
DAG.getTargetConstant(Param, MVT::i32));
ParamValue);
InVals.push_back(ArgValue);
}
}
@ -319,9 +322,11 @@ SDValue PTXTargetLowering::
if (Outs.size() == 1) {
unsigned ParamSize = OutVals[0].getValueType().getSizeInBits();
unsigned Param = PM.addReturnParam(ParamSize);
SDValue ParamIndex = DAG.getTargetConstant(Param, MVT::i32);
std::string ParamName = PM.getParamName(Param);
SDValue ParamValue = DAG.getTargetExternalSymbol(ParamName.c_str(),
MVT::Other);
Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
ParamIndex, OutVals[0]);
ParamValue, OutVals[0]);
}
} else {
for (unsigned i = 0, e = Outs.size(); i != e; ++i) {
@ -414,21 +419,25 @@ PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
for (unsigned i = 0; i != OutVals.size(); ++i) {
unsigned Size = OutVals[i].getValueType().getSizeInBits();
unsigned Param = PM.addLocalParam(Size);
SDValue Index = DAG.getTargetConstant(Param, MVT::i32);
std::string ParamName = PM.getParamName(Param);
SDValue ParamValue = DAG.getTargetExternalSymbol(ParamName.c_str(),
MVT::Other);
Chain = DAG.getNode(PTXISD::STORE_PARAM, dl, MVT::Other, Chain,
Index, OutVals[i]);
Ops[i+Ins.size()+2] = Index;
ParamValue, OutVals[i]);
Ops[i+Ins.size()+2] = ParamValue;
}
std::vector<unsigned> InParams;
std::vector<SDValue> InParams;
// Generate list of .param variables to hold the return value(s).
for (unsigned i = 0; i < Ins.size(); ++i) {
unsigned Size = Ins[i].VT.getStoreSizeInBits();
unsigned Param = PM.addLocalParam(Size);
SDValue Index = DAG.getTargetConstant(Param, MVT::i32);
Ops[i+1] = Index;
InParams.push_back(Param);
std::string ParamName = PM.getParamName(Param);
SDValue ParamValue = DAG.getTargetExternalSymbol(ParamName.c_str(),
MVT::Other);
Ops[i+1] = ParamValue;
InParams.push_back(ParamValue);
}
Ops[0] = Chain;
@ -438,8 +447,8 @@ PTXTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// Create the LOAD_PARAM nodes that retrieve the function return value(s).
for (unsigned i = 0; i < Ins.size(); ++i) {
SDValue Index = DAG.getTargetConstant(InParams[i], MVT::i32);
SDValue Load = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain, Index);
SDValue Load = DAG.getNode(PTXISD::LOAD_PARAM, dl, Ins[i].VT, Chain,
InParams[i]);
InVals.push_back(Load);
}

View File

@ -88,12 +88,12 @@ def MEMri64 : Operand<i64> {
let MIOperandInfo = (ops RegI64, i64imm);
}
def LOCALri32 : Operand<i32> {
let PrintMethod = "printLocalOperand";
let MIOperandInfo = (ops RegI32, i32imm);
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops i32imm, i32imm);
}
def LOCALri64 : Operand<i64> {
let PrintMethod = "printLocalOperand";
let MIOperandInfo = (ops RegI64, i64imm);
let PrintMethod = "printMemOperand";
let MIOperandInfo = (ops i64imm, i64imm);
}
def MEMii32 : Operand<i32> {
let PrintMethod = "printMemOperand";
@ -117,7 +117,7 @@ def MEMret : Operand<i32> {
// Load/store .param space
def PTXloadparam
: SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisVT<1, i32>]>,
: SDNode<"PTXISD::LOAD_PARAM", SDTypeProfile<1, 1, [SDTCisPtrTy<1>]>,
[SDNPHasChain, SDNPOutGlue, SDNPOptInGlue]>;
def PTXstoreparam
: SDNode<"PTXISD::STORE_PARAM", SDTypeProfile<0, 2, [SDTCisVT<0, i32>]>,
@ -220,12 +220,12 @@ multiclass PTX_LOCAL_LD_ST<string typestr, RegisterClass RC> {
multiclass PTX_PARAM_LD_ST<string typestr, RegisterClass RC> {
let hasSideEffects = 1 in {
def LDpi : InstPTX<(outs RC:$d), (ins MEMpi:$a),
def LDpi : InstPTX<(outs RC:$d), (ins i32imm:$a),
!strconcat("ld.param", !strconcat(typestr, "\t$d, [$a]")),
[(set RC:$d, (PTXloadparam timm:$a))]>;
def STpi : InstPTX<(outs), (ins MEMpi:$d, RC:$a),
[(set RC:$d, (PTXloadparam texternalsym:$a))]>;
def STpi : InstPTX<(outs), (ins i32imm:$d, RC:$a),
!strconcat("st.param", !strconcat(typestr, "\t[$d], $a")),
[(PTXstoreparam timm:$d, RC:$a)]>;
[(PTXstoreparam texternalsym:$d, RC:$a)]>;
}
}

View File

@ -38,9 +38,11 @@ private:
typedef std::vector<unsigned> RegisterList;
typedef DenseMap<const TargetRegisterClass*, RegisterList> RegisterMap;
typedef DenseMap<unsigned, std::string> RegisterNameMap;
typedef DenseMap<int, std::string> FrameMap;
RegisterMap UsedRegs;
RegisterNameMap RegNames;
FrameMap FrameSymbols;
PTXParamManager ParamManager;
@ -141,6 +143,21 @@ public:
return UsedRegs.lookup(TRC).size();
}
/// getFrameSymbol - Returns the symbol name for the given FrameIndex.
const char* getFrameSymbol(int FrameIndex) {
if (FrameSymbols.count(FrameIndex)) {
return FrameSymbols.lookup(FrameIndex).c_str();
} else {
std::string Name = "__local";
Name += utostr(FrameIndex);
// The whole point of caching this name is to ensure the pointer we pass
// to any getExternalSymbol() calls will remain valid for the lifetime of
// the back-end instance. This is to work around an issue in SelectionDAG
// where symbol names are expected to be life-long strings.
FrameSymbols[FrameIndex] = Name;
return FrameSymbols[FrameIndex].c_str();
}
}
}; // class PTXMachineFunctionInfo
} // namespace llvm

View File

@ -42,6 +42,8 @@ void PTXRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
//unsigned Reg = MRI.createVirtualRegister(PTX::RegF32RegisterClass);
llvm_unreachable("FrameIndex should have been previously eliminated!");
Index = 0;
while (!MI.getOperand(Index).isFI()) {
++Index;
@ -63,7 +65,10 @@ void PTXRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
//}
//MI2->dump();
//MachineOperand ESOp = MachineOperand::CreateES("__local__");
// This frame index is post stack slot re-use assignments
//MI.getOperand(Index).ChangeToRegister(Reg, false);
MI.getOperand(Index).ChangeToImmediate(FrameIndex);
//MI.getOperand(Index) = ESOp;
}