From d7f59a21a7479c3821627943a574aa929bebfdf1 Mon Sep 17 00:00:00 2001 From: Justin Holewinski Date: Tue, 27 Sep 2011 18:12:55 +0000 Subject: [PATCH] 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 --- lib/Target/PTX/PTXAsmPrinter.cpp | 28 ++++----------------- lib/Target/PTX/PTXISelDAGToDAG.cpp | 18 ++++++-------- lib/Target/PTX/PTXISelLowering.cpp | 33 ++++++++++++++++--------- lib/Target/PTX/PTXInstrLoadStore.td | 18 +++++++------- lib/Target/PTX/PTXMachineFunctionInfo.h | 17 +++++++++++++ lib/Target/PTX/PTXRegisterInfo.cpp | 5 ++++ 6 files changed, 64 insertions(+), 55 deletions(-) diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp index c09a7626782..cd82d568b38 100644 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ b/lib/Target/PTX/PTXAsmPrinter.cpp @@ -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(); - 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 << ", "; } diff --git a/lib/Target/PTX/PTXISelDAGToDAG.cpp b/lib/Target/PTX/PTXISelDAGToDAG.cpp index d99d49075d8..c722e8acb08 100644 --- a/lib/Target/PTX/PTXISelDAGToDAG.cpp +++ b/lib/Target/PTX/PTXISelDAGToDAG.cpp @@ -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(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(); - //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] diff --git a/lib/Target/PTX/PTXISelLowering.cpp b/lib/Target/PTX/PTXISelLowering.cpp index f22c2716987..7333e99cec2 100644 --- a/lib/Target/PTX/PTXISelLowering.cpp +++ b/lib/Target/PTX/PTXISelLowering.cpp @@ -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 InParams; + std::vector 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); } diff --git a/lib/Target/PTX/PTXInstrLoadStore.td b/lib/Target/PTX/PTXInstrLoadStore.td index bb84bb56969..1de0a2c9987 100644 --- a/lib/Target/PTX/PTXInstrLoadStore.td +++ b/lib/Target/PTX/PTXInstrLoadStore.td @@ -88,12 +88,12 @@ def MEMri64 : Operand { let MIOperandInfo = (ops RegI64, i64imm); } def LOCALri32 : Operand { - let PrintMethod = "printLocalOperand"; - let MIOperandInfo = (ops RegI32, i32imm); + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops i32imm, i32imm); } def LOCALri64 : Operand { - let PrintMethod = "printLocalOperand"; - let MIOperandInfo = (ops RegI64, i64imm); + let PrintMethod = "printMemOperand"; + let MIOperandInfo = (ops i64imm, i64imm); } def MEMii32 : Operand { let PrintMethod = "printMemOperand"; @@ -117,7 +117,7 @@ def MEMret : Operand { // 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 { multiclass PTX_PARAM_LD_ST { 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)]>; } } diff --git a/lib/Target/PTX/PTXMachineFunctionInfo.h b/lib/Target/PTX/PTXMachineFunctionInfo.h index b2d3bb203f7..f40d8ca5011 100644 --- a/lib/Target/PTX/PTXMachineFunctionInfo.h +++ b/lib/Target/PTX/PTXMachineFunctionInfo.h @@ -38,9 +38,11 @@ private: typedef std::vector RegisterList; typedef DenseMap RegisterMap; typedef DenseMap RegisterNameMap; + typedef DenseMap 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 diff --git a/lib/Target/PTX/PTXRegisterInfo.cpp b/lib/Target/PTX/PTXRegisterInfo.cpp index acc74f32ab2..cb1670f28db 100644 --- a/lib/Target/PTX/PTXRegisterInfo.cpp +++ b/lib/Target/PTX/PTXRegisterInfo.cpp @@ -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; }