diff options
author | Che-Liang Chiou <clchiou@gmail.com> | 2011-03-18 11:08:52 +0000 |
---|---|---|
committer | Che-Liang Chiou <clchiou@gmail.com> | 2011-03-18 11:08:52 +0000 |
commit | 88d3367baa066b4924a9303291aee084c154fff1 (patch) | |
tree | b9f5248897f67abbcb6e01a981eb95af18543426 /lib/Target/PTX | |
parent | d4f4e6ee2c1eb80b8a1d3199e7747405fee956a3 (diff) | |
download | external_llvm-88d3367baa066b4924a9303291aee084c154fff1.zip external_llvm-88d3367baa066b4924a9303291aee084c154fff1.tar.gz external_llvm-88d3367baa066b4924a9303291aee084c154fff1.tar.bz2 |
ptx: add unconditional and conditional branch
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PTX')
-rw-r--r-- | lib/Target/PTX/PTXAsmPrinter.cpp | 19 | ||||
-rw-r--r-- | lib/Target/PTX/PTXISelDAGToDAG.cpp | 33 | ||||
-rw-r--r-- | lib/Target/PTX/PTXISelLowering.cpp | 11 | ||||
-rw-r--r-- | lib/Target/PTX/PTXInstrInfo.td | 18 | ||||
-rw-r--r-- | lib/Target/PTX/PTXMCAsmStreamer.cpp | 2 |
5 files changed, 57 insertions, 26 deletions
diff --git a/lib/Target/PTX/PTXAsmPrinter.cpp b/lib/Target/PTX/PTXAsmPrinter.cpp index 0b07f74..19a699e 100644 --- a/lib/Target/PTX/PTXAsmPrinter.cpp +++ b/lib/Target/PTX/PTXAsmPrinter.cpp @@ -91,17 +91,6 @@ static const char *getRegisterTypeName(unsigned RegNo) { return NULL; } -static const char *getInstructionTypeName(const MachineInstr *MI) { - for (int i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (MO.getType() == MachineOperand::MO_Register) - return getRegisterTypeName(MO.getReg()); - } - - llvm_unreachable("No reg operand found in instruction!"); - return NULL; -} - static const char *getStateSpaceName(unsigned addressSpace) { switch (addressSpace) { default: llvm_unreachable("Unknown state space"); @@ -221,11 +210,6 @@ void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) { OS << ';'; OS.flush(); - // Replace "%type" if found - size_t pos; - if ((pos = str.find("%type")) != std::string::npos) - str.replace(pos, /*strlen("%type")==*/5, getInstructionTypeName(MI)); - StringRef strref = StringRef(str); OutStreamer.EmitRawText(strref); } @@ -244,6 +228,9 @@ void PTXAsmPrinter::printOperand(const MachineInstr *MI, int opNum, case MachineOperand::MO_Immediate: OS << (int) MO.getImm(); break; + case MachineOperand::MO_MachineBasicBlock: + OS << *MO.getMBB()->getSymbol(); + break; case MachineOperand::MO_Register: OS << getRegisterName(MO.getReg()); break; diff --git a/lib/Target/PTX/PTXISelDAGToDAG.cpp b/lib/Target/PTX/PTXISelDAGToDAG.cpp index fe2d25a..5be1224 100644 --- a/lib/Target/PTX/PTXISelDAGToDAG.cpp +++ b/lib/Target/PTX/PTXISelDAGToDAG.cpp @@ -43,6 +43,10 @@ class PTXDAGToDAGISel : public SelectionDAGISel { private: SDNode *SelectREAD_PARAM(SDNode *Node); + // We need this only because we can't match intruction BRAdp + // pattern (PTXbrcond bb:$d, ...) in PTXInstrInfo.td + SDNode *SelectBRCOND(SDNode *Node); + bool isImm(const SDValue &operand); bool SelectImm(const SDValue &operand, SDValue &imm); @@ -62,10 +66,14 @@ PTXDAGToDAGISel::PTXDAGToDAGISel(PTXTargetMachine &TM, : SelectionDAGISel(TM, OptLevel) {} SDNode *PTXDAGToDAGISel::Select(SDNode *Node) { - if (Node->getOpcode() == PTXISD::READ_PARAM) - return SelectREAD_PARAM(Node); - else - return SelectCode(Node); + switch (Node->getOpcode()) { + case PTXISD::READ_PARAM: + return SelectREAD_PARAM(Node); + case ISD::BRCOND: + return SelectBRCOND(Node); + default: + return SelectCode(Node); + } } SDNode *PTXDAGToDAGISel::SelectREAD_PARAM(SDNode *Node) { @@ -99,6 +107,23 @@ SDNode *PTXDAGToDAGISel::SelectREAD_PARAM(SDNode *Node) { GetPTXMachineNode(CurDAG, opcode, dl, Node->getValueType(0), index); } +SDNode *PTXDAGToDAGISel::SelectBRCOND(SDNode *Node) { + assert(Node->getNumOperands() >= 3); + + SDValue Chain = Node->getOperand(0); + SDValue Pred = Node->getOperand(1); + SDValue Target = Node->getOperand(2); // branch target + SDValue PredOp = CurDAG->getTargetConstant(PTX::PRED_NORMAL, MVT::i32); + DebugLoc dl = Node->getDebugLoc(); + + assert(Target.getOpcode() == ISD::BasicBlock); + assert(Pred.getValueType() == MVT::i1); + + // Emit BRAdp + SDValue Ops[] = { Target, Pred, PredOp, Chain }; + return CurDAG->getMachineNode(PTX::BRAdp, dl, MVT::Other, Ops, 4); +} + // Match memory operand of the form [reg+reg] bool PTXDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1, SDValue &R2) { if (Addr.getOpcode() != ISD::ADD || Addr.getNumOperands() < 2 || diff --git a/lib/Target/PTX/PTXISelLowering.cpp b/lib/Target/PTX/PTXISelLowering.cpp index 1b4b7e6..159a27a 100644 --- a/lib/Target/PTX/PTXISelLowering.cpp +++ b/lib/Target/PTX/PTXISelLowering.cpp @@ -42,14 +42,21 @@ PTXTargetLowering::PTXTargetLowering(TargetMachine &TM) // Customize translation of memory addresses setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); + // Expand BR_CC into BRCOND + setOperationAction(ISD::BR_CC, MVT::Other, Expand); + // Compute derived properties from the register classes computeRegisterProperties(); } SDValue PTXTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { - default: llvm_unreachable("Unimplemented operand"); - case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + default: + llvm_unreachable("Unimplemented operand"); + case ISD::GlobalAddress: + return LowerGlobalAddress(Op, DAG); + case ISD::BRCOND: + return LowerGlobalAddress(Op, DAG); } } diff --git a/lib/Target/PTX/PTXInstrInfo.td b/lib/Target/PTX/PTXInstrInfo.td index dc96914..42671b6 100644 --- a/lib/Target/PTX/PTXInstrInfo.td +++ b/lib/Target/PTX/PTXInstrInfo.td @@ -37,7 +37,6 @@ def DoesNotSupportPTX21 : Predicate<"!getSubtarget().supportsPTX21()">; def SupportsPTX22 : Predicate<"getSubtarget().supportsPTX22()">; def DoesNotSupportPTX22 : Predicate<"!getSubtarget().supportsPTX22()">; - //===----------------------------------------------------------------------===// // Instruction Pattern Stuff //===----------------------------------------------------------------------===// @@ -135,7 +134,6 @@ def ADDRri64 : ComplexPattern<i64, 2, "SelectADDRri", [], []>; def ADDRii32 : ComplexPattern<i32, 2, "SelectADDRii", [], []>; def ADDRii64 : ComplexPattern<i64, 2, "SelectADDRii", [], []>; - // Address operands def MEMri32 : Operand<i32> { let PrintMethod = "printMemOperand"; @@ -160,6 +158,9 @@ def MEMpi : Operand<i32> { let MIOperandInfo = (ops i32imm); } +// Branch & call targets have OtherVT type. +def brtarget : Operand<OtherVT>; +def calltarget : Operand<i32>; //===----------------------------------------------------------------------===// // PTX Specific Node Definitions @@ -281,7 +282,6 @@ multiclass PTX_LOGIC<string opcstr, SDNode opnode> { [(set RRegu64:$d, (opnode RRegu64:$a, imm:$b))]>; } -// no %type directive, non-communtable multiclass INT3ntnc<string opcstr, SDNode opnode> { def rr : InstPTX<(outs RRegu32:$d), (ins RRegu32:$a, RRegu32:$b), @@ -566,6 +566,18 @@ def CVT_u32_pred ///===- Control Flow Instructions -----------------------------------------===// +let isBranch = 1, isTerminator = 1 in { + def BRAd + : InstPTX<(outs), (ins brtarget:$d), "bra\t$d", [(br bb:$d)]>; + + // FIXME: should be able to write a pattern for brcond, but can't use + // a two-value operand where a dag node expects two operands. :( + // NOTE: ARM & PowerPC backend also report the same problem + def BRAdp + : InstPTX<(outs), (ins brtarget:$d), "bra\t$d", + [/*(brcond bb:$d, Preds:$p, i32imm:$c)*/]>; +} + let isReturn = 1, isTerminator = 1, isBarrier = 1 in { def EXIT : InstPTX<(outs), (ins), "exit", [(PTXexit)]>; def RET : InstPTX<(outs), (ins), "ret", [(PTXret)]>; diff --git a/lib/Target/PTX/PTXMCAsmStreamer.cpp b/lib/Target/PTX/PTXMCAsmStreamer.cpp index 1c5d418..cf743e4 100644 --- a/lib/Target/PTX/PTXMCAsmStreamer.cpp +++ b/lib/Target/PTX/PTXMCAsmStreamer.cpp @@ -233,7 +233,7 @@ void PTXMCAsmStreamer::ChangeSection(const MCSection *Section) { void PTXMCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); - assert(getCurrentSection() && "Cannot emit before setting section!"); + //assert(getCurrentSection() && "Cannot emit before setting section!"); OS << *Symbol << MAI.getLabelSuffix(); EmitEOL(); |