#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include <queue>
-#include <set>
-
using namespace llvm;
//===----------------------------------------------------------------------===//
/// TM - Keep a reference to MipsTargetMachine.
MipsTargetMachine &TM;
- /// MipsLowering - This object fully describes how to lower LLVM code to an
- /// Mips-specific SelectionDAG.
- MipsTargetLowering MipsLowering;
-
/// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
/// make the right decision when generating code for different targets.
const MipsSubtarget &Subtarget;
public:
explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
- SelectionDAGISel(MipsLowering),
- TM(tm), MipsLowering(*TM.getTargetLowering()),
- Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
+ SelectionDAGISel(tm),
+ TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
- virtual void InstructionSelect(SelectionDAG &SD);
+ virtual void InstructionSelect();
// Pass Name
virtual const char *getPassName() const {
// Include the pieces autogenerated from the target description.
#include "MipsGenDAGISel.inc"
- SDOperand getGlobalBaseReg();
- SDNode *Select(SDOperand N);
+ SDValue getGlobalBaseReg();
+ SDNode *Select(SDValue N);
// Complex Pattern.
- bool SelectAddr(SDOperand Op, SDOperand N,
- SDOperand &Base, SDOperand &Offset);
+ bool SelectAddr(SDValue Op, SDValue N,
+ SDValue &Base, SDValue &Offset);
// getI32Imm - Return a target constant with the specified
// value, of type i32.
- inline SDOperand getI32Imm(unsigned Imm) {
+ inline SDValue getI32Imm(unsigned Imm) {
return CurDAG->getTargetConstant(Imm, MVT::i32);
}
/// InstructionSelect - This callback is invoked by
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
void MipsDAGToDAGISel::
-InstructionSelect(SelectionDAG &SD)
+InstructionSelect()
{
DEBUG(BB->dump());
// Codegen the basic block.
#endif
// Select target instructions for the DAG.
- SD.setRoot(SelectRoot(SD.getRoot()));
+ SelectRoot(*CurDAG);
#ifndef NDEBUG
DOUT << "===== Instruction selection ends:\n";
#endif
- SD.RemoveDeadNodes();
+ CurDAG->RemoveDeadNodes();
}
/// getGlobalBaseReg - Output the instructions required to put the
/// GOT address into a register.
-SDOperand MipsDAGToDAGISel::getGlobalBaseReg() {
+SDValue MipsDAGToDAGISel::getGlobalBaseReg() {
MachineFunction* MF = BB->getParent();
unsigned GP = 0;
for(MachineRegisterInfo::livein_iterator ii = MF->getRegInfo().livein_begin(),
break;
}
assert(GP && "GOT PTR not in liveins");
+ // FIXME is there a sensible place to get debug info for this?
return CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
- GP, MVT::i32);
+ DebugLoc::getUnknownLoc(), GP, MVT::i32);
}
/// ComplexPattern used on MipsInstrInfo
/// Used on Mips Load/Store instructions
bool MipsDAGToDAGISel::
-SelectAddr(SDOperand Op, SDOperand Addr, SDOperand &Offset, SDOperand &Base)
+SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base)
{
// if Address is FI, get the TargetFrameIndex.
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = Addr.getOperand(0);
}
- Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
+ Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
return true;
}
}
/// Select instructions not customized! Used for
/// expanded, promoted and normal instructions
SDNode* MipsDAGToDAGISel::
-Select(SDOperand N)
+Select(SDValue N)
{
- SDNode *Node = N.Val;
+ SDNode *Node = N.getNode();
unsigned Opcode = Node->getOpcode();
+ DebugLoc dl = Node->getDebugLoc();
// Dump information about the Node being selected
#ifndef NDEBUG
#endif
// If we have a custom node, we already have selected!
- if (Opcode >= ISD::BUILTIN_OP_END && Opcode < MipsISD::FIRST_NUMBER) {
+ if (Node->isMachineOpcode()) {
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "== ";
DEBUG(Node->dump(CurDAG));
case ISD::SUBE:
case ISD::ADDE: {
- SDOperand InFlag = Node->getOperand(2), CmpLHS;
- unsigned Opc = InFlag.getOpcode(), MOp;
-
+ SDValue InFlag = Node->getOperand(2), CmpLHS;
+ unsigned Opc = InFlag.getOpcode(); Opc=Opc;
assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
(Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
"(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
+ unsigned MOp;
if (Opcode == ISD::ADDE) {
CmpLHS = InFlag.getValue(0);
MOp = Mips::ADDu;
MOp = Mips::SUBu;
}
- SDOperand Ops[] = { CmpLHS, InFlag.getOperand(1) };
+ SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
- SDOperand LHS = Node->getOperand(0);
- SDOperand RHS = Node->getOperand(1);
- AddToISelQueue(LHS);
- AddToISelQueue(RHS);
+ SDValue LHS = Node->getOperand(0);
+ SDValue RHS = Node->getOperand(1);
MVT VT = LHS.getValueType();
- SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, VT, Ops, 2);
- SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, VT,
- SDOperand(Carry,0), RHS);
+ SDNode *Carry = CurDAG->getTargetNode(Mips::SLTu, dl, VT, Ops, 2);
+ SDNode *AddCarry = CurDAG->getTargetNode(Mips::ADDu, dl, VT,
+ SDValue(Carry,0), RHS);
- return CurDAG->SelectNodeTo(N.Val, MOp, VT, MVT::Flag,
- LHS, SDOperand(AddCarry,0));
+ return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag,
+ LHS, SDValue(AddCarry,0));
}
/// Mul/Div with two results
case ISD::UDIVREM:
case ISD::SMUL_LOHI:
case ISD::UMUL_LOHI: {
- SDOperand Op1 = Node->getOperand(0);
- SDOperand Op2 = Node->getOperand(1);
- AddToISelQueue(Op1);
- AddToISelQueue(Op2);
+ SDValue Op1 = Node->getOperand(0);
+ SDValue Op2 = Node->getOperand(1);
unsigned Op;
if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI)
else
Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
- SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
+ SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2);
- SDOperand InFlag = SDOperand(Node, 0);
- SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, MVT::i32, MVT::Flag, InFlag);
-
- InFlag = SDOperand(Lo,1);
- SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
+ SDValue InFlag = SDValue(Node, 0);
+ SDNode *Lo = CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32,
+ MVT::Flag, InFlag);
+ InFlag = SDValue(Lo,1);
+ SDNode *Hi = CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag);
if (!N.getValue(0).use_empty())
- ReplaceUses(N.getValue(0), SDOperand(Lo,0));
+ ReplaceUses(N.getValue(0), SDValue(Lo,0));
if (!N.getValue(1).use_empty())
- ReplaceUses(N.getValue(1), SDOperand(Hi,0));
+ ReplaceUses(N.getValue(1), SDValue(Hi,0));
return NULL;
}
case ISD::MUL:
case ISD::MULHS:
case ISD::MULHU: {
- SDOperand MulOp1 = Node->getOperand(0);
- SDOperand MulOp2 = Node->getOperand(1);
- AddToISelQueue(MulOp1);
- AddToISelQueue(MulOp2);
+ SDValue MulOp1 = Node->getOperand(0);
+ SDValue MulOp2 = Node->getOperand(1);
unsigned MulOp = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
- SDNode *MulNode = CurDAG->getTargetNode(MulOp, MVT::Flag, MulOp1, MulOp2);
+ SDNode *MulNode = CurDAG->getTargetNode(MulOp, dl,
+ MVT::Flag, MulOp1, MulOp2);
- SDOperand InFlag = SDOperand(MulNode, 0);
+ SDValue InFlag = SDValue(MulNode, 0);
if (MulOp == ISD::MUL)
- return CurDAG->getTargetNode(Mips::MFLO, MVT::i32, InFlag);
+ return CurDAG->getTargetNode(Mips::MFLO, dl, MVT::i32, InFlag);
else
- return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, InFlag);
+ return CurDAG->getTargetNode(Mips::MFHI, dl, MVT::i32, InFlag);
}
/// Div/Rem operations
case ISD::UREM:
case ISD::SDIV:
case ISD::UDIV: {
- SDOperand Op1 = Node->getOperand(0);
- SDOperand Op2 = Node->getOperand(1);
- AddToISelQueue(Op1);
- AddToISelQueue(Op2);
+ SDValue Op1 = Node->getOperand(0);
+ SDValue Op2 = Node->getOperand(1);
unsigned Op, MOp;
if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) {
Op = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
MOp = Mips::MFHI;
}
- SDNode *Node = CurDAG->getTargetNode(Op, MVT::Flag, Op1, Op2);
+ SDNode *Node = CurDAG->getTargetNode(Op, dl, MVT::Flag, Op1, Op2);
- SDOperand InFlag = SDOperand(Node, 0);
- return CurDAG->getTargetNode(MOp, MVT::i32, InFlag);
+ SDValue InFlag = SDValue(Node, 0);
+ return CurDAG->getTargetNode(MOp, dl, MVT::i32, InFlag);
}
// Get target GOT address.
case ISD::GLOBAL_OFFSET_TABLE: {
- SDOperand Result = getGlobalBaseReg();
+ SDValue Result = getGlobalBaseReg();
ReplaceUses(N, Result);
return NULL;
}
case MipsISD::JmpLink: {
if (TM.getRelocationModel() == Reloc::PIC_) {
//bool isCodeLarge = (TM.getCodeModel() == CodeModel::Large);
- SDOperand Chain = Node->getOperand(0);
- SDOperand Callee = Node->getOperand(1);
- AddToISelQueue(Chain);
- SDOperand T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
- SDOperand InFlag(0, 0);
+ SDValue Chain = Node->getOperand(0);
+ SDValue Callee = Node->getOperand(1);
+ SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
+ SDValue InFlag(0, 0);
if ( (isa<GlobalAddressSDNode>(Callee)) ||
(isa<ExternalSymbolSDNode>(Callee)) )
{
/// Direct call for global addresses and external symbols
- SDOperand GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
+ SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
// Use load to get GOT target
- SDOperand Ops[] = { Callee, GPReg, Chain };
- SDOperand Load = SDOperand(CurDAG->getTargetNode(Mips::LW, MVT::i32,
+ SDValue Ops[] = { Callee, GPReg, Chain };
+ SDValue Load = SDValue(CurDAG->getTargetNode(Mips::LW, dl, MVT::i32,
MVT::Other, Ops, 3), 0);
Chain = Load.getValue(1);
- AddToISelQueue(Chain);
// Call target must be on T9
- Chain = CurDAG->getCopyToReg(Chain, T9Reg, Load, InFlag);
+ Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
} else
/// Indirect call
- Chain = CurDAG->getCopyToReg(Chain, T9Reg, Callee, InFlag);
-
- AddToISelQueue(Chain);
+ Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
// Emit Jump and Link Register
- SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, MVT::Other,
+ SDNode *ResNode = CurDAG->getTargetNode(Mips::JALR, dl, MVT::Other,
MVT::Flag, T9Reg, Chain);
- Chain = SDOperand(ResNode, 0);
- InFlag = SDOperand(ResNode, 1);
- ReplaceUses(SDOperand(Node, 0), Chain);
- ReplaceUses(SDOperand(Node, 1), InFlag);
+ Chain = SDValue(ResNode, 0);
+ InFlag = SDValue(ResNode, 1);
+ ReplaceUses(SDValue(Node, 0), Chain);
+ ReplaceUses(SDValue(Node, 1), InFlag);
return ResNode;
}
}
#ifndef NDEBUG
DOUT << std::string(Indent-2, ' ') << "=> ";
- if (ResNode == NULL || ResNode == N.Val)
- DEBUG(N.Val->dump(CurDAG));
+ if (ResNode == NULL || ResNode == N.getNode())
+ DEBUG(N.getNode()->dump(CurDAG));
else
DEBUG(ResNode->dump(CurDAG));
DOUT << "\n";