ptx: add basic support of predicate execution

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127569 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Che-Liang Chiou 2011-03-13 17:26:00 +00:00
parent 198e97c423
commit c2ec0f974d
4 changed files with 168 additions and 50 deletions

View File

@ -29,6 +29,11 @@ namespace llvm {
PARAMETER = 3,
SHARED = 4
};
enum Predicate {
PRED_IGNORE = 0,
PRED_NEGATE = 1
};
} // namespace PTX
FunctionPass *createPTXISelDag(PTXTargetMachine &TM,

View File

@ -62,6 +62,7 @@ public:
const char *Modifier = 0);
void printParamOperand(const MachineInstr *MI, int opNum, raw_ostream &OS,
const char *Modifier = 0);
void printPredicateOperand(const MachineInstr *MI, raw_ostream &O);
// autogen'd.
void printInstruction(const MachineInstr *MI, raw_ostream &OS);
@ -210,8 +211,12 @@ void PTXAsmPrinter::EmitInstruction(const MachineInstr *MI) {
std::string str;
str.reserve(64);
// Write instruction to str
raw_string_ostream OS(str);
// Emit predicate
printPredicateOperand(MI, OS);
// Write instruction to str
printInstruction(MI, OS);
OS << ';';
OS.flush();
@ -394,6 +399,25 @@ void PTXAsmPrinter::EmitFunctionDeclaration() {
OutStreamer.EmitRawText(Twine(decl));
}
void PTXAsmPrinter::
printPredicateOperand(const MachineInstr *MI, raw_ostream &O) {
int i = MI->findFirstPredOperandIdx();
if (i == -1)
llvm_unreachable("missing predicate operand");
unsigned reg = MI->getOperand(i).getReg();
int predOp = MI->getOperand(i+1).getImm();
DEBUG(dbgs() << "predicate: (" << reg << ", " << predOp << ")\n");
if (reg && predOp != PTX::PRED_IGNORE) {
O << '@';
if (predOp == PTX::PRED_NEGATE)
O << '!';
O << getRegisterName(reg);
}
}
#include "PTXGenAsmWriter.inc"
// Force static initialization.

View File

@ -14,6 +14,8 @@
#include "PTX.h"
#include "PTXInstrInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
using namespace llvm;
@ -41,9 +43,10 @@ void PTXInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool KillSrc) const {
for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i) {
if (map[i].cls->contains(DstReg, SrcReg)) {
BuildMI(MBB, I, DL,
get(map[i].opcode), DstReg).addReg(SrcReg,
getKillRegState(KillSrc));
const TargetInstrDesc &TID = get(map[i].opcode);
MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).
addReg(SrcReg, getKillRegState(KillSrc));
AddDefaultPredicate(MI);
return;
}
}
@ -62,12 +65,9 @@ bool PTXInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
for (int i = 0, e = sizeof(map)/sizeof(map[0]); i != e; ++ i)
if (DstRC == map[i].cls) {
MachineInstr *MI = BuildMI(MBB, I, DL, get(map[i].opcode),
DstReg).addReg(SrcReg);
if (MI->findFirstPredOperandIdx() == -1) {
MI->addOperand(MachineOperand::CreateReg(0, false));
MI->addOperand(MachineOperand::CreateImm(/*IsInv=*/0));
}
const TargetInstrDesc &TID = get(map[i].opcode);
MachineInstr *MI = BuildMI(MBB, I, DL, TID, DstReg).addReg(SrcReg);
AddDefaultPredicate(MI);
return true;
}
@ -95,3 +95,80 @@ bool PTXInstrInfo::isMoveInstr(const MachineInstr& MI,
return true;
}
}
// predicate support
bool PTXInstrInfo::isPredicated(const MachineInstr *MI) const {
int i = MI->findFirstPredOperandIdx();
if (i == -1)
llvm_unreachable("missing predicate operand");
return MI->getOperand(i).getReg() ||
MI->getOperand(i+1).getImm() != PTX::PRED_IGNORE;
}
bool PTXInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
return !isPredicated(MI) && get(MI->getOpcode()).isTerminator();
}
bool PTXInstrInfo::
PredicateInstruction(MachineInstr *MI,
const SmallVectorImpl<MachineOperand> &Pred) const {
if (Pred.size() < 2)
llvm_unreachable("lesser than 2 predicate operands are provided");
int i = MI->findFirstPredOperandIdx();
if (i == -1)
llvm_unreachable("missing predicate operand");
MI->getOperand(i).setReg(Pred[0].getReg());
MI->getOperand(i+1).setImm(Pred[1].getImm());
return true;
}
bool PTXInstrInfo::
SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
const SmallVectorImpl<MachineOperand> &Pred2) const {
// TODO Implement SubsumesPredicate
// Returns true if the first specified predicate subsumes the second,
// e.g. GE subsumes GT.
return false;
}
bool PTXInstrInfo::
DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const {
// TODO Implement DefinesPredicate
// If the specified instruction defines any predicate or condition code
// register(s) used for predication, returns true as well as the definition
// predicate(s) by reference.
return false;
}
// static helper routines
MachineSDNode *PTXInstrInfo::
GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT, SDValue Op1) {
SDValue predReg = DAG->getRegister(0, MVT::i1);
SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1);
SDValue ops[] = { Op1, predReg, predOp };
return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}
MachineSDNode *PTXInstrInfo::
GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT, SDValue Op1, SDValue Op2) {
SDValue predReg = DAG->getRegister(0, MVT::i1);
SDValue predOp = DAG->getTargetConstant(PTX::PRED_IGNORE, MVT::i1);
SDValue ops[] = { Op1, Op2, predReg, predOp };
return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}
void PTXInstrInfo::AddDefaultPredicate(MachineInstr *MI) {
if (MI->findFirstPredOperandIdx() == -1) {
MI->addOperand(MachineOperand::CreateReg(0, /*IsDef=*/false));
MI->addOperand(MachineOperand::CreateImm(PTX::PRED_IGNORE));
}
}

View File

@ -15,61 +15,73 @@
#define PTX_INSTR_INFO_H
#include "PTXRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetInstrInfo.h"
namespace llvm {
class PTXTargetMachine;
class MachineSDNode;
class SDValue;
class SelectionDAG;
class PTXInstrInfo : public TargetInstrInfoImpl {
private:
const PTXRegisterInfo RI;
PTXTargetMachine &TM;
private:
const PTXRegisterInfo RI;
PTXTargetMachine &TM;
public:
explicit PTXInstrInfo(PTXTargetMachine &_TM);
public:
explicit PTXInstrInfo(PTXTargetMachine &_TM);
virtual const PTXRegisterInfo &getRegisterInfo() const { return RI; }
virtual const PTXRegisterInfo &getRegisterInfo() const { return RI; }
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DstReg, unsigned SrcReg,
bool KillSrc) const;
virtual void copyPhysReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, DebugLoc DL,
unsigned DstReg, unsigned SrcReg,
bool KillSrc) const;
virtual bool copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DstReg, unsigned SrcReg,
const TargetRegisterClass *DstRC,
const TargetRegisterClass *SrcRC,
DebugLoc DL) const;
virtual bool copyRegToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I,
unsigned DstReg, unsigned SrcReg,
const TargetRegisterClass *DstRC,
const TargetRegisterClass *SrcRC,
DebugLoc DL) const;
virtual bool isMoveInstr(const MachineInstr& MI,
unsigned &SrcReg, unsigned &DstReg,
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
virtual bool isMoveInstr(const MachineInstr& MI,
unsigned &SrcReg, unsigned &DstReg,
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
// static helper routines
// predicate support
static MachineSDNode *GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT,
SDValue Op1) {
SDValue pred_reg = DAG->getRegister(0, MVT::i1);
SDValue pred_imm = DAG->getTargetConstant(0, MVT::i32);
SDValue ops[] = { Op1, pred_reg, pred_imm };
return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}
virtual bool isPredicated(const MachineInstr *MI) const;
static MachineSDNode *GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT,
SDValue Op1,
SDValue Op2) {
SDValue pred_reg = DAG->getRegister(0, MVT::i1);
SDValue pred_imm = DAG->getTargetConstant(0, MVT::i32);
SDValue ops[] = { Op1, Op2, pred_reg, pred_imm };
return DAG->getMachineNode(Opcode, dl, VT, ops, array_lengthof(ops));
}
virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
}; // class PTXInstrInfo
virtual
bool PredicateInstruction(MachineInstr *MI,
const SmallVectorImpl<MachineOperand> &Pred) const;
virtual
bool SubsumesPredicate(const SmallVectorImpl<MachineOperand> &Pred1,
const SmallVectorImpl<MachineOperand> &Pred2) const;
virtual bool DefinesPredicate(MachineInstr *MI,
std::vector<MachineOperand> &Pred) const;
// PTX is fully-predicable
virtual bool isPredicable(MachineInstr *MI) const { return true; }
// static helper routines
static MachineSDNode *GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT,
SDValue Op1);
static MachineSDNode *GetPTXMachineNode(SelectionDAG *DAG, unsigned Opcode,
DebugLoc dl, EVT VT,
SDValue Op1, SDValue Op2);
static void AddDefaultPredicate(MachineInstr *MI);
}; // class PTXInstrInfo
} // namespace llvm
#endif // PTX_INSTR_INFO_H