mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 21:34:23 +00:00
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:
parent
198e97c423
commit
c2ec0f974d
@ -29,6 +29,11 @@ namespace llvm {
|
||||
PARAMETER = 3,
|
||||
SHARED = 4
|
||||
};
|
||||
|
||||
enum Predicate {
|
||||
PRED_IGNORE = 0,
|
||||
PRED_NEGATE = 1
|
||||
};
|
||||
} // namespace PTX
|
||||
|
||||
FunctionPass *createPTXISelDag(PTXTargetMachine &TM,
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user