fix a long standing wart: all the ComplexPattern's were being

passed the root of the match, even though only a few patterns
actually needed this (one in X86, several in ARM [which should
be refactored anyway], and some in CellSPU that I don't feel 
like detangling).   Instead of requiring all ComplexPatterns to
take the dead root, have targets opt into getting the root by
putting SDNPWantRoot on the ComplexPattern.

llvm-svn: 114471
This commit is contained in:
Chris Lattner 2010-09-21 20:31:19 +00:00
parent f5ab703f68
commit 0e023ea02a
20 changed files with 142 additions and 141 deletions

View File

@ -224,6 +224,8 @@ def SDNPMayLoad : SDNodeProperty; // May read memory, sets 'mayLoad'.
def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'. def SDNPSideEffect : SDNodeProperty; // Sets 'HasUnmodelledSideEffects'.
def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand def SDNPMemOperand : SDNodeProperty; // Touches memory, has assoc MemOperand
def SDNPVariadic : SDNodeProperty; // Node has variable arguments. def SDNPVariadic : SDNodeProperty; // Node has variable arguments.
def SDNPWantRoot : SDNodeProperty; // ComplexPattern gets the root of match
def SDNPWantParent : SDNodeProperty; // ComplexPattern gets the parent
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Selection DAG Node definitions. // Selection DAG Node definitions.

View File

@ -72,48 +72,44 @@ public:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
bool SelectShifterOperandReg(SDNode *Op, SDValue N, SDValue &A, bool SelectShifterOperandReg(SDValue N, SDValue &A,
SDValue &B, SDValue &C); SDValue &B, SDValue &C);
bool SelectAddrMode2(SDNode *Op, SDValue N, SDValue &Base, bool SelectAddrMode2(SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc); SDValue &Offset, SDValue &Opc);
bool SelectAddrMode2Offset(SDNode *Op, SDValue N, bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc); SDValue &Offset, SDValue &Opc);
bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, bool SelectAddrMode3(SDValue N, SDValue &Base,
SDValue &Offset, SDValue &Opc); SDValue &Offset, SDValue &Opc);
bool SelectAddrMode3Offset(SDNode *Op, SDValue N, bool SelectAddrMode3Offset(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc); SDValue &Offset, SDValue &Opc);
bool SelectAddrMode4(SDNode *Op, SDValue N, SDValue &Addr, bool SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode);
SDValue &Mode); bool SelectAddrMode5(SDValue N, SDValue &Base,
bool SelectAddrMode5(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Offset); SDValue &Offset);
bool SelectAddrMode6(SDNode *Op, SDValue N, SDValue &Addr, SDValue &Align); bool SelectAddrMode6(SDValue N, SDValue &Addr, SDValue &Align);
bool SelectAddrModePC(SDNode *Op, SDValue N, SDValue &Offset, bool SelectAddrModePC(SDValue N, SDValue &Offset,
SDValue &Label); SDValue &Label);
bool SelectThumbAddrModeRR(SDNode *Op, SDValue N, SDValue &Base, bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);
SDValue &Offset); bool SelectThumbAddrModeRI5(SDValue N, unsigned Scale,
bool SelectThumbAddrModeRI5(SDNode *Op, SDValue N, unsigned Scale,
SDValue &Base, SDValue &OffImm, SDValue &Base, SDValue &OffImm,
SDValue &Offset); SDValue &Offset);
bool SelectThumbAddrModeS1(SDNode *Op, SDValue N, SDValue &Base, bool SelectThumbAddrModeS1(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset); SDValue &OffImm, SDValue &Offset);
bool SelectThumbAddrModeS2(SDNode *Op, SDValue N, SDValue &Base, bool SelectThumbAddrModeS2(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset); SDValue &OffImm, SDValue &Offset);
bool SelectThumbAddrModeS4(SDNode *Op, SDValue N, SDValue &Base, bool SelectThumbAddrModeS4(SDValue N, SDValue &Base,
SDValue &OffImm, SDValue &Offset); SDValue &OffImm, SDValue &Offset);
bool SelectThumbAddrModeSP(SDNode *Op, SDValue N, SDValue &Base, bool SelectThumbAddrModeSP(SDValue N, SDValue &Base, SDValue &OffImm);
SDValue &OffImm);
bool SelectT2ShifterOperandReg(SDNode *Op, SDValue N, bool SelectT2ShifterOperandReg(SDValue N,
SDValue &BaseReg, SDValue &Opc); SDValue &BaseReg, SDValue &Opc);
bool SelectT2AddrModeImm12(SDNode *Op, SDValue N, SDValue &Base, bool SelectT2AddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
SDValue &OffImm); bool SelectT2AddrModeImm8(SDValue N, SDValue &Base,
bool SelectT2AddrModeImm8(SDNode *Op, SDValue N, SDValue &Base,
SDValue &OffImm); SDValue &OffImm);
bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N, bool SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
SDValue &OffImm); SDValue &OffImm);
bool SelectT2AddrModeSoReg(SDNode *Op, SDValue N, SDValue &Base, bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base,
SDValue &OffReg, SDValue &ShImm); SDValue &OffReg, SDValue &ShImm);
inline bool Pred_so_imm(SDNode *inN) const { inline bool Pred_so_imm(SDNode *inN) const {
@ -223,8 +219,7 @@ static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) {
} }
bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op, bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
SDValue N,
SDValue &BaseReg, SDValue &BaseReg,
SDValue &ShReg, SDValue &ShReg,
SDValue &Opc) { SDValue &Opc) {
@ -250,7 +245,7 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDNode *Op,
return true; return true;
} }
bool ARMDAGToDAGISel::SelectAddrMode2(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
SDValue &Base, SDValue &Offset, SDValue &Base, SDValue &Offset,
SDValue &Opc) { SDValue &Opc) {
if (N.getOpcode() == ISD::MUL) { if (N.getOpcode() == ISD::MUL) {
@ -399,7 +394,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
} }
bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N,
SDValue &Base, SDValue &Offset, SDValue &Base, SDValue &Offset,
SDValue &Opc) { SDValue &Opc) {
if (N.getOpcode() == ISD::SUB) { if (N.getOpcode() == ISD::SUB) {
@ -471,14 +466,13 @@ bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N,
return true; return true;
} }
bool ARMDAGToDAGISel::SelectAddrMode4(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrMode4(SDValue N, SDValue &Addr, SDValue &Mode) {
SDValue &Addr, SDValue &Mode) {
Addr = N; Addr = N;
Mode = CurDAG->getTargetConstant(ARM_AM::getAM4ModeImm(ARM_AM::ia), MVT::i32); Mode = CurDAG->getTargetConstant(ARM_AM::getAM4ModeImm(ARM_AM::ia), MVT::i32);
return true; return true;
} }
bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N,
SDValue &Base, SDValue &Offset) { SDValue &Base, SDValue &Offset) {
if (N.getOpcode() != ISD::ADD) { if (N.getOpcode() != ISD::ADD) {
Base = N; Base = N;
@ -526,15 +520,14 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDNode *Op, SDValue N,
return true; return true;
} }
bool ARMDAGToDAGISel::SelectAddrMode6(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrMode6(SDValue N, SDValue &Addr, SDValue &Align){
SDValue &Addr, SDValue &Align) {
Addr = N; Addr = N;
// Default to no alignment. // Default to no alignment.
Align = CurDAG->getTargetConstant(0, MVT::i32); Align = CurDAG->getTargetConstant(0, MVT::i32);
return true; return true;
} }
bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectAddrModePC(SDValue N,
SDValue &Offset, SDValue &Label) { SDValue &Offset, SDValue &Label) {
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) { if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
Offset = N.getOperand(0); Offset = N.getOperand(0);
@ -546,7 +539,7 @@ bool ARMDAGToDAGISel::SelectAddrModePC(SDNode *Op, SDValue N,
return false; return false;
} }
bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue N,
SDValue &Base, SDValue &Offset){ SDValue &Base, SDValue &Offset){
// FIXME dl should come from the parent load or store, not the address // FIXME dl should come from the parent load or store, not the address
if (N.getOpcode() != ISD::ADD) { if (N.getOpcode() != ISD::ADD) {
@ -564,12 +557,12 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDNode *Op, SDValue N,
} }
bool bool
ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N, ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue N,
unsigned Scale, SDValue &Base, unsigned Scale, SDValue &Base,
SDValue &OffImm, SDValue &Offset) { SDValue &OffImm, SDValue &Offset) {
if (Scale == 4) { if (Scale == 4) {
SDValue TmpBase, TmpOffImm; SDValue TmpBase, TmpOffImm;
if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm)) if (SelectThumbAddrModeSP(N, TmpBase, TmpOffImm))
return false; // We want to select tLDRspi / tSTRspi instead. return false; // We want to select tLDRspi / tSTRspi instead.
if (N.getOpcode() == ARMISD::Wrapper && if (N.getOpcode() == ARMISD::Wrapper &&
N.getOperand(0).getOpcode() == ISD::TargetConstantPool) N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
@ -620,25 +613,25 @@ ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDNode *Op, SDValue N,
return true; return true;
} }
bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue N,
SDValue &Base, SDValue &OffImm, SDValue &Base, SDValue &OffImm,
SDValue &Offset) { SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset); return SelectThumbAddrModeRI5(N, 1, Base, OffImm, Offset);
} }
bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue N,
SDValue &Base, SDValue &OffImm, SDValue &Base, SDValue &OffImm,
SDValue &Offset) { SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset); return SelectThumbAddrModeRI5(N, 2, Base, OffImm, Offset);
} }
bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue N,
SDValue &Base, SDValue &OffImm, SDValue &Base, SDValue &OffImm,
SDValue &Offset) { SDValue &Offset) {
return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset); return SelectThumbAddrModeRI5(N, 4, Base, OffImm, Offset);
} }
bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N,
SDValue &Base, SDValue &OffImm) { SDValue &Base, SDValue &OffImm) {
if (N.getOpcode() == ISD::FrameIndex) { if (N.getOpcode() == ISD::FrameIndex) {
int FI = cast<FrameIndexSDNode>(N)->getIndex(); int FI = cast<FrameIndexSDNode>(N)->getIndex();
@ -674,8 +667,7 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDNode *Op, SDValue N,
return false; return false;
} }
bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg,
SDValue &BaseReg,
SDValue &Opc) { SDValue &Opc) {
if (DisableShifterOp) if (DisableShifterOp)
return false; return false;
@ -697,7 +689,7 @@ bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDNode *Op, SDValue N,
return false; return false;
} }
bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDValue N,
SDValue &Base, SDValue &OffImm) { SDValue &Base, SDValue &OffImm) {
// Match simple R + imm12 operands. // Match simple R + imm12 operands.
@ -722,7 +714,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N,
} }
if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
if (SelectT2AddrModeImm8(Op, N, Base, OffImm)) if (SelectT2AddrModeImm8(N, Base, OffImm))
// Let t2LDRi8 handle (R - imm8). // Let t2LDRi8 handle (R - imm8).
return false; return false;
@ -747,7 +739,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm12(SDNode *Op, SDValue N,
return true; return true;
} }
bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectT2AddrModeImm8(SDValue N,
SDValue &Base, SDValue &OffImm) { SDValue &Base, SDValue &OffImm) {
// Match simple R - imm8 operands. // Match simple R - imm8 operands.
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) { if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::SUB) {
@ -790,7 +782,7 @@ bool ARMDAGToDAGISel::SelectT2AddrModeImm8Offset(SDNode *Op, SDValue N,
return false; return false;
} }
bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDNode *Op, SDValue N, bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N,
SDValue &Base, SDValue &Base,
SDValue &OffReg, SDValue &ShImm) { SDValue &OffReg, SDValue &ShImm) {
// (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12. // (R - imm8) should be handled by t2LDRi8. The rest are handled by t2LDRi12.
@ -1017,7 +1009,7 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDNode *N, unsigned NumVecs,
DebugLoc dl = N->getDebugLoc(); DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align; SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL; return NULL;
SDValue Chain = N->getOperand(0); SDValue Chain = N->getOperand(0);
@ -1128,7 +1120,7 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDNode *N, unsigned NumVecs,
DebugLoc dl = N->getDebugLoc(); DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align; SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL; return NULL;
SDValue Chain = N->getOperand(0); SDValue Chain = N->getOperand(0);
@ -1248,7 +1240,7 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
DebugLoc dl = N->getDebugLoc(); DebugLoc dl = N->getDebugLoc();
SDValue MemAddr, Align; SDValue MemAddr, Align;
if (!SelectAddrMode6(N, N->getOperand(2), MemAddr, Align)) if (!SelectAddrMode6(N->getOperand(2), MemAddr, Align))
return NULL; return NULL;
SDValue Chain = N->getOperand(0); SDValue Chain = N->getOperand(0);
@ -1426,7 +1418,7 @@ SelectT2CMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) {
SDValue CPTmp0; SDValue CPTmp0;
SDValue CPTmp1; SDValue CPTmp1;
if (SelectT2ShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1)) { if (SelectT2ShifterOperandReg(TrueVal, CPTmp0, CPTmp1)) {
unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue(); unsigned SOVal = cast<ConstantSDNode>(CPTmp1)->getZExtValue();
unsigned SOShOp = ARM_AM::getSORegShOp(SOVal); unsigned SOShOp = ARM_AM::getSORegShOp(SOVal);
unsigned Opc = 0; unsigned Opc = 0;
@ -1454,7 +1446,7 @@ SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
SDValue CPTmp0; SDValue CPTmp0;
SDValue CPTmp1; SDValue CPTmp1;
SDValue CPTmp2; SDValue CPTmp2;
if (SelectShifterOperandReg(N, TrueVal, CPTmp0, CPTmp1, CPTmp2)) { if (SelectShifterOperandReg(TrueVal, CPTmp0, CPTmp1, CPTmp2)) {
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag };
return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7);

View File

@ -379,7 +379,8 @@ def addrmode2 : Operand<i32>,
} }
def am2offset : Operand<i32>, def am2offset : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> { ComplexPattern<i32, 2, "SelectAddrMode2Offset",
[], [SDNPWantRoot]> {
let PrintMethod = "printAddrMode2OffsetOperand"; let PrintMethod = "printAddrMode2OffsetOperand";
let MIOperandInfo = (ops GPR, i32imm); let MIOperandInfo = (ops GPR, i32imm);
} }
@ -394,7 +395,8 @@ def addrmode3 : Operand<i32>,
} }
def am3offset : Operand<i32>, def am3offset : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> { ComplexPattern<i32, 2, "SelectAddrMode3Offset",
[], [SDNPWantRoot]> {
let PrintMethod = "printAddrMode3OffsetOperand"; let PrintMethod = "printAddrMode3OffsetOperand";
let MIOperandInfo = (ops GPR, i32imm); let MIOperandInfo = (ops GPR, i32imm);
} }

View File

@ -140,7 +140,8 @@ def t2addrmode_imm8 : Operand<i32>,
} }
def t2am_imm8_offset : Operand<i32>, def t2am_imm8_offset : Operand<i32>,
ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{ ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
[], [SDNPWantRoot]> {
let PrintMethod = "printT2AddrModeImm8OffsetOperand"; let PrintMethod = "printT2AddrModeImm8OffsetOperand";
} }

View File

@ -51,8 +51,7 @@ namespace {
private: private:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
bool SelectADDRspii(SDNode *Op, SDValue Addr, bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
SDValue &Base, SDValue &Offset);
// Walk the DAG after instruction selection, fixing register class issues. // Walk the DAG after instruction selection, fixing register class issues.
void FixRegisterClasses(SelectionDAG &DAG); void FixRegisterClasses(SelectionDAG &DAG);
@ -94,8 +93,7 @@ SDNode *BlackfinDAGToDAGISel::Select(SDNode *N) {
return SelectCode(N); return SelectCode(N);
} }
bool BlackfinDAGToDAGISel::SelectADDRspii(SDNode *Op, bool BlackfinDAGToDAGISel::SelectADDRspii(SDValue Addr,
SDValue Addr,
SDValue &Base, SDValue &Base,
SDValue &Offset) { SDValue &Offset) {
FrameIndexSDNode *FIN = 0; FrameIndexSDNode *FIN = 0;

View File

@ -654,7 +654,11 @@ def memrr : Operand<iPTR> {
// A-form : abs (256K LSA offset) // A-form : abs (256K LSA offset)
// D-form(2): [r+I7] (7-bit signed offset + reg) // D-form(2): [r+I7] (7-bit signed offset + reg)
def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr", [], []>; def dform_addr : ComplexPattern<iPTR, 2, "SelectDFormAddr",
def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr", [], []>; [], [SDNPWantRoot]>;
def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr", [], []>; def xform_addr : ComplexPattern<iPTR, 2, "SelectXFormAddr",
def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr", [], []>; [], [SDNPWantRoot]>;
def aform_addr : ComplexPattern<iPTR, 2, "SelectAFormAddr",
[], [SDNPWantRoot]>;
def dform2_addr : ComplexPattern<iPTR, 2, "SelectDForm2Addr",
[], [SDNPWantRoot]>;

View File

@ -82,8 +82,8 @@ private:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
// Address Selection // Address Selection
bool SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index); bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index);
bool SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base); bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base);
// getI32Imm - Return a target constant with the specified value, of type i32. // getI32Imm - Return a target constant with the specified value, of type i32.
inline SDValue getI32Imm(unsigned Imm) { inline SDValue getI32Imm(unsigned Imm) {
@ -118,7 +118,7 @@ static bool isIntS32Immediate(SDValue Op, int32_t &Imm) {
/// can be represented as an indexed [r+r] operation. Returns false if it /// can be represented as an indexed [r+r] operation. Returns false if it
/// can be more efficiently represented with [r+imm]. /// can be more efficiently represented with [r+imm].
bool MBlazeDAGToDAGISel:: bool MBlazeDAGToDAGISel::
SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) { SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
if (N.getOpcode() == ISD::FrameIndex) return false; if (N.getOpcode() == ISD::FrameIndex) return false;
if (N.getOpcode() == ISD::TargetExternalSymbol || if (N.getOpcode() == ISD::TargetExternalSymbol ||
N.getOpcode() == ISD::TargetGlobalAddress) N.getOpcode() == ISD::TargetGlobalAddress)
@ -145,9 +145,9 @@ SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) {
/// a signed 32-bit displacement [r+imm], and if it is not better /// a signed 32-bit displacement [r+imm], and if it is not better
/// represented as reg+reg. /// represented as reg+reg.
bool MBlazeDAGToDAGISel:: bool MBlazeDAGToDAGISel::
SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) { SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base) {
// If this can be more profitably realized as r+r, fail. // If this can be more profitably realized as r+r, fail.
if (SelectAddrRegReg(Op, N, Disp, Base)) if (SelectAddrRegReg(N, Disp, Base))
return false; return false;
if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {

View File

@ -120,7 +120,7 @@ namespace {
SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2, SDNode *SelectIndexedBinOp(SDNode *Op, SDValue N1, SDValue N2,
unsigned Opc8, unsigned Opc16); unsigned Opc8, unsigned Opc16);
bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Disp); bool SelectAddr(SDValue Addr, SDValue &Base, SDValue &Disp);
}; };
} // end anonymous namespace } // end anonymous namespace
@ -245,7 +245,7 @@ bool MSP430DAGToDAGISel::MatchAddress(SDValue N, MSP430ISelAddressMode &AM) {
/// SelectAddr - returns true if it is able pattern match an addressing mode. /// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can /// It returns the operands which make up the maximal addressing mode it can
/// match by reference. /// match by reference.
bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, bool MSP430DAGToDAGISel::SelectAddr(SDValue N,
SDValue &Base, SDValue &Disp) { SDValue &Base, SDValue &Disp) {
MSP430ISelAddressMode AM; MSP430ISelAddressMode AM;
@ -263,7 +263,7 @@ bool MSP430DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N,
AM.Base.Reg; AM.Base.Reg;
if (AM.GV) if (AM.GV)
Disp = CurDAG->getTargetGlobalAddress(AM.GV, Op->getDebugLoc(), Disp = CurDAG->getTargetGlobalAddress(AM.GV, N->getDebugLoc(),
MVT::i16, AM.Disp, MVT::i16, AM.Disp,
0/*AM.SymbolFlags*/); 0/*AM.SymbolFlags*/);
else if (AM.CP) else if (AM.CP)
@ -289,7 +289,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
switch (ConstraintCode) { switch (ConstraintCode) {
default: return true; default: return true;
case 'm': // memory case 'm': // memory
if (!SelectAddr(Op.getNode(), Op, Op0, Op1)) if (!SelectAddr(Op, Op0, Op1))
return true; return true;
break; break;
} }

View File

@ -84,8 +84,7 @@ private:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
// Complex Pattern. // Complex Pattern.
bool SelectAddr(SDNode *Op, SDValue N, bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset);
SDValue &Base, SDValue &Offset);
SDNode *SelectLoadFp64(SDNode *N); SDNode *SelectLoadFp64(SDNode *N);
SDNode *SelectStoreFp64(SDNode *N); SDNode *SelectStoreFp64(SDNode *N);
@ -110,8 +109,7 @@ SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
/// ComplexPattern used on MipsInstrInfo /// ComplexPattern used on MipsInstrInfo
/// Used on Mips Load/Store instructions /// Used on Mips Load/Store instructions
bool MipsDAGToDAGISel:: bool MipsDAGToDAGISel::
SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base) SelectAddr(SDValue Addr, SDValue &Offset, SDValue &Base) {
{
// if Address is FI, get the TargetFrameIndex. // if Address is FI, get the TargetFrameIndex.
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
@ -193,7 +191,7 @@ SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDNode *N) {
SDValue N1 = N->getOperand(1); SDValue N1 = N->getOperand(1);
SDValue Offset0, Offset1, Base; SDValue Offset0, Offset1, Base;
if (!SelectAddr(N, N1, Offset0, Base) || if (!SelectAddr(N1, Offset0, Base) ||
N1.getValueType() != MVT::i32) N1.getValueType() != MVT::i32)
return NULL; return NULL;
@ -257,7 +255,7 @@ SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDNode *N) {
SDValue N2 = N->getOperand(2); SDValue N2 = N->getOperand(2);
SDValue Offset0, Offset1, Base; SDValue Offset0, Offset1, Base;
if (!SelectAddr(N, N2, Offset0, Base) || if (!SelectAddr(N2, Offset0, Base) ||
N1.getValueType() != MVT::f64 || N1.getValueType() != MVT::f64 ||
N2.getValueType() != MVT::i32) N2.getValueType() != MVT::i32)
return NULL; return NULL;

View File

@ -37,8 +37,7 @@ SDNode* PIC16DAGToDAGISel::Select(SDNode *N) {
// SelectDirectAddr - Match a direct address for DAG. // SelectDirectAddr - Match a direct address for DAG.
// A direct address could be a globaladdress or externalsymbol. // A direct address could be a globaladdress or externalsymbol.
bool PIC16DAGToDAGISel::SelectDirectAddr(SDNode *Op, SDValue N, bool PIC16DAGToDAGISel::SelectDirectAddr(SDValue N, SDValue &Address) {
SDValue &Address) {
// Return true if TGA or ES. // Return true if TGA or ES.
if (N.getOpcode() == ISD::TargetGlobalAddress if (N.getOpcode() == ISD::TargetGlobalAddress
|| N.getOpcode() == ISD::TargetExternalSymbol) { || N.getOpcode() == ISD::TargetExternalSymbol) {

View File

@ -52,7 +52,7 @@ private:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
// Match direct address complex pattern. // Match direct address complex pattern.
bool SelectDirectAddr(SDNode *Op, SDValue N, SDValue &Address); bool SelectDirectAddr(SDValue N, SDValue &Address);
}; };

View File

@ -104,7 +104,7 @@ namespace {
/// SelectAddrImm - Returns true if the address N can be represented by /// SelectAddrImm - Returns true if the address N can be represented by
/// a base register plus a signed 16-bit displacement [r+imm]. /// a base register plus a signed 16-bit displacement [r+imm].
bool SelectAddrImm(SDNode *Op, SDValue N, SDValue &Disp, bool SelectAddrImm(SDValue N, SDValue &Disp,
SDValue &Base) { SDValue &Base) {
return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG); return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
} }
@ -112,7 +112,7 @@ namespace {
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc /// SelectAddrImmOffs - Return true if the operand is valid for a preinc
/// immediate field. Because preinc imms have already been validated, just /// immediate field. Because preinc imms have already been validated, just
/// accept it. /// accept it.
bool SelectAddrImmOffs(SDNode *Op, SDValue N, SDValue &Out) const { bool SelectAddrImmOffs(SDValue N, SDValue &Out) const {
Out = N; Out = N;
return true; return true;
} }
@ -120,23 +120,20 @@ namespace {
/// SelectAddrIdx - Given the specified addressed, check to see if it can be /// SelectAddrIdx - Given the specified addressed, check to see if it can be
/// represented as an indexed [r+r] operation. Returns false if it can /// represented as an indexed [r+r] operation. Returns false if it can
/// be represented by [r+imm], which are preferred. /// be represented by [r+imm], which are preferred.
bool SelectAddrIdx(SDNode *Op, SDValue N, SDValue &Base, bool SelectAddrIdx(SDValue N, SDValue &Base, SDValue &Index) {
SDValue &Index) {
return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG); return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG);
} }
/// SelectAddrIdxOnly - Given the specified addressed, force it to be /// SelectAddrIdxOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation. /// represented as an indexed [r+r] operation.
bool SelectAddrIdxOnly(SDNode *Op, SDValue N, SDValue &Base, bool SelectAddrIdxOnly(SDValue N, SDValue &Base, SDValue &Index) {
SDValue &Index) {
return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG); return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
} }
/// SelectAddrImmShift - Returns true if the address N can be represented by /// SelectAddrImmShift - Returns true if the address N can be represented by
/// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable /// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable
/// for use by STD and friends. /// for use by STD and friends.
bool SelectAddrImmShift(SDNode *Op, SDValue N, SDValue &Disp, bool SelectAddrImmShift(SDValue N, SDValue &Disp, SDValue &Base) {
SDValue &Base) {
return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG); return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG);
} }

View File

@ -44,9 +44,8 @@ public:
SDNode *Select(SDNode *N); SDNode *Select(SDNode *N);
// Complex Pattern Selectors. // Complex Pattern Selectors.
bool SelectADDRrr(SDNode *Op, SDValue N, SDValue &R1, SDValue &R2); bool SelectADDRrr(SDValue N, SDValue &R1, SDValue &R2);
bool SelectADDRri(SDNode *Op, SDValue N, SDValue &Base, bool SelectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
SDValue &Offset);
/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions. /// inline asm expressions.
@ -71,7 +70,7 @@ SDNode* SparcDAGToDAGISel::getGlobalBaseReg() {
return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
} }
bool SparcDAGToDAGISel::SelectADDRri(SDNode *Op, SDValue Addr, bool SparcDAGToDAGISel::SelectADDRri(SDValue Addr,
SDValue &Base, SDValue &Offset) { SDValue &Base, SDValue &Offset) {
if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
@ -112,8 +111,7 @@ bool SparcDAGToDAGISel::SelectADDRri(SDNode *Op, SDValue Addr,
return true; return true;
} }
bool SparcDAGToDAGISel::SelectADDRrr(SDNode *Op, SDValue Addr, bool SparcDAGToDAGISel::SelectADDRrr(SDValue Addr, SDValue &R1, SDValue &R2) {
SDValue &R1, SDValue &R2) {
if (Addr.getOpcode() == ISD::FrameIndex) return false; if (Addr.getOpcode() == ISD::FrameIndex) return false;
if (Addr.getOpcode() == ISD::TargetExternalSymbol || if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress) Addr.getOpcode() == ISD::TargetGlobalAddress)
@ -196,8 +194,8 @@ SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
switch (ConstraintCode) { switch (ConstraintCode) {
default: return true; default: return true;
case 'm': // memory case 'm': // memory
if (!SelectADDRrr(Op.getNode(), Op, Op0, Op1)) if (!SelectADDRrr(Op, Op0, Op1))
SelectADDRri(Op.getNode(), Op, Op0, Op1); SelectADDRri(Op, Op0, Op1);
break; break;
} }

View File

@ -120,18 +120,17 @@ namespace {
#include "SystemZGenDAGISel.inc" #include "SystemZGenDAGISel.inc"
private: private:
bool SelectAddrRI12Only(SDNode *Op, SDValue& Addr, bool SelectAddrRI12Only(SDValue& Addr,
SDValue &Base, SDValue &Disp); SDValue &Base, SDValue &Disp);
bool SelectAddrRI12(SDNode *Op, SDValue& Addr, bool SelectAddrRI12(SDValue& Addr,
SDValue &Base, SDValue &Disp, SDValue &Base, SDValue &Disp,
bool is12BitOnly = false); bool is12BitOnly = false);
bool SelectAddrRI(SDNode *Op, SDValue& Addr, bool SelectAddrRI(SDValue& Addr, SDValue &Base, SDValue &Disp);
SDValue &Base, SDValue &Disp); bool SelectAddrRRI12(SDValue Addr,
bool SelectAddrRRI12(SDNode *Op, SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index); SDValue &Base, SDValue &Disp, SDValue &Index);
bool SelectAddrRRI20(SDNode *Op, SDValue Addr, bool SelectAddrRRI20(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index); SDValue &Base, SDValue &Disp, SDValue &Index);
bool SelectLAAddr(SDNode *Op, SDValue Addr, bool SelectLAAddr(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index); SDValue &Base, SDValue &Disp, SDValue &Index);
SDNode *Select(SDNode *Node); SDNode *Select(SDNode *Node);
@ -353,12 +352,12 @@ void SystemZDAGToDAGISel::getAddressOperands(const SystemZRRIAddressMode &AM,
/// Returns true if the address can be represented by a base register plus /// Returns true if the address can be represented by a base register plus
/// an unsigned 12-bit displacement [r+imm]. /// an unsigned 12-bit displacement [r+imm].
bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDNode *Op, SDValue& Addr, bool SystemZDAGToDAGISel::SelectAddrRI12Only(SDValue &Addr,
SDValue &Base, SDValue &Disp) { SDValue &Base, SDValue &Disp) {
return SelectAddrRI12(Op, Addr, Base, Disp, /*is12BitOnly*/true); return SelectAddrRI12(Addr, Base, Disp, /*is12BitOnly*/true);
} }
bool SystemZDAGToDAGISel::SelectAddrRI12(SDNode *Op, SDValue& Addr, bool SystemZDAGToDAGISel::SelectAddrRI12(SDValue &Addr,
SDValue &Base, SDValue &Disp, SDValue &Base, SDValue &Disp,
bool is12BitOnly) { bool is12BitOnly) {
SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true); SystemZRRIAddressMode AM20(/*isRI*/true), AM12(/*isRI*/true);
@ -408,7 +407,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI12(SDNode *Op, SDValue& Addr,
/// Returns true if the address can be represented by a base register plus /// Returns true if the address can be represented by a base register plus
/// a signed 20-bit displacement [r+imm]. /// a signed 20-bit displacement [r+imm].
bool SystemZDAGToDAGISel::SelectAddrRI(SDNode *Op, SDValue& Addr, bool SystemZDAGToDAGISel::SelectAddrRI(SDValue& Addr,
SDValue &Base, SDValue &Disp) { SDValue &Base, SDValue &Disp) {
SystemZRRIAddressMode AM(/*isRI*/true); SystemZRRIAddressMode AM(/*isRI*/true);
bool Done = false; bool Done = false;
@ -451,7 +450,7 @@ bool SystemZDAGToDAGISel::SelectAddrRI(SDNode *Op, SDValue& Addr,
/// Returns true if the address can be represented by a base register plus /// Returns true if the address can be represented by a base register plus
/// index register plus an unsigned 12-bit displacement [base + idx + imm]. /// index register plus an unsigned 12-bit displacement [base + idx + imm].
bool SystemZDAGToDAGISel::SelectAddrRRI12(SDNode *Op, SDValue Addr, bool SystemZDAGToDAGISel::SelectAddrRRI12(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) { SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM20, AM12; SystemZRRIAddressMode AM20, AM12;
bool Done = false; bool Done = false;
@ -500,7 +499,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI12(SDNode *Op, SDValue Addr,
/// Returns true if the address can be represented by a base register plus /// Returns true if the address can be represented by a base register plus
/// index register plus a signed 20-bit displacement [base + idx + imm]. /// index register plus a signed 20-bit displacement [base + idx + imm].
bool SystemZDAGToDAGISel::SelectAddrRRI20(SDNode *Op, SDValue Addr, bool SystemZDAGToDAGISel::SelectAddrRRI20(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) { SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM; SystemZRRIAddressMode AM;
bool Done = false; bool Done = false;
@ -544,7 +543,7 @@ bool SystemZDAGToDAGISel::SelectAddrRRI20(SDNode *Op, SDValue Addr,
/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing /// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LA/LAY instruction. /// mode it matches can be cost effectively emitted as an LA/LAY instruction.
bool SystemZDAGToDAGISel::SelectLAAddr(SDNode *Op, SDValue Addr, bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Addr,
SDValue &Base, SDValue &Disp, SDValue &Index) { SDValue &Base, SDValue &Disp, SDValue &Index) {
SystemZRRIAddressMode AM; SystemZRRIAddressMode AM;
@ -581,7 +580,7 @@ bool SystemZDAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Disp, SDValue &Index) { SDValue &Base, SDValue &Disp, SDValue &Index) {
if (ISD::isNON_EXTLoad(N.getNode()) && if (ISD::isNON_EXTLoad(N.getNode()) &&
IsLegalToFold(N, P, P, OptLevel)) IsLegalToFold(N, P, P, OptLevel))
return SelectAddrRRI20(P, N.getOperand(1), Base, Disp, Index); return SelectAddrRRI20(N.getOperand(1), Base, Disp, Index);
return false; return false;
} }

View File

@ -197,13 +197,13 @@ namespace {
bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM, bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
unsigned Depth); unsigned Depth);
bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM); bool MatchAddressBase(SDValue N, X86ISelAddressMode &AM);
bool SelectAddr(SDNode *Op, SDValue N, SDValue &Base, bool SelectAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment); SDValue &Segment);
bool SelectLEAAddr(SDNode *Op, SDValue N, SDValue &Base, bool SelectLEAAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment); SDValue &Segment);
bool SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base, bool SelectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Disp, SDValue &Scale, SDValue &Index, SDValue &Disp,
SDValue &Segment); SDValue &Segment);
bool SelectScalarSSELoad(SDNode *Root, SDValue N, bool SelectScalarSSELoad(SDNode *Root, SDValue N,
@ -1147,7 +1147,7 @@ bool X86DAGToDAGISel::MatchAddressBase(SDValue N, X86ISelAddressMode &AM) {
/// SelectAddr - returns true if it is able pattern match an addressing mode. /// SelectAddr - returns true if it is able pattern match an addressing mode.
/// It returns the operands which make up the maximal addressing mode it can /// It returns the operands which make up the maximal addressing mode it can
/// match by reference. /// match by reference.
bool X86DAGToDAGISel::SelectAddr(SDNode *Op, SDValue N, SDValue &Base, bool X86DAGToDAGISel::SelectAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) { SDValue &Disp, SDValue &Segment) {
X86ISelAddressMode AM; X86ISelAddressMode AM;
@ -1186,7 +1186,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Root,
IsProfitableToFold(N.getOperand(0), N.getNode(), Root) && IsProfitableToFold(N.getOperand(0), N.getNode(), Root) &&
IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) { IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) {
LoadSDNode *LD = cast<LoadSDNode>(PatternNodeWithChain); LoadSDNode *LD = cast<LoadSDNode>(PatternNodeWithChain);
if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp,Segment)) if (!SelectAddr(LD->getBasePtr(), Base, Scale, Index, Disp,Segment))
return false; return false;
return true; return true;
} }
@ -1204,7 +1204,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Root,
IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) { IsLegalToFold(N.getOperand(0), N.getNode(), Root, OptLevel)) {
// Okay, this is a zero extending load. Fold it. // Okay, this is a zero extending load. Fold it.
LoadSDNode *LD = cast<LoadSDNode>(N.getOperand(0).getOperand(0)); LoadSDNode *LD = cast<LoadSDNode>(N.getOperand(0).getOperand(0));
if (!SelectAddr(Root, LD->getBasePtr(), Base, Scale, Index, Disp, Segment)) if (!SelectAddr(LD->getBasePtr(), Base, Scale, Index, Disp, Segment))
return false; return false;
PatternNodeWithChain = SDValue(LD, 0); PatternNodeWithChain = SDValue(LD, 0);
return true; return true;
@ -1215,7 +1215,7 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDNode *Root,
/// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing /// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
/// mode it matches can be cost effectively emitted as an LEA instruction. /// mode it matches can be cost effectively emitted as an LEA instruction.
bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N, bool X86DAGToDAGISel::SelectLEAAddr(SDValue N,
SDValue &Base, SDValue &Scale, SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp, SDValue &Index, SDValue &Disp,
SDValue &Segment) { SDValue &Segment) {
@ -1277,7 +1277,7 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDNode *Op, SDValue N,
} }
/// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes. /// SelectTLSADDRAddr - This is only run on TargetGlobalTLSAddress nodes.
bool X86DAGToDAGISel::SelectTLSADDRAddr(SDNode *Op, SDValue N, SDValue &Base, bool X86DAGToDAGISel::SelectTLSADDRAddr(SDValue N, SDValue &Base,
SDValue &Scale, SDValue &Index, SDValue &Scale, SDValue &Index,
SDValue &Disp, SDValue &Segment) { SDValue &Disp, SDValue &Segment) {
assert(N.getOpcode() == ISD::TargetGlobalTLSAddress); assert(N.getOpcode() == ISD::TargetGlobalTLSAddress);
@ -1310,7 +1310,7 @@ bool X86DAGToDAGISel::TryFoldLoad(SDNode *P, SDValue N,
!IsLegalToFold(N, P, P, OptLevel)) !IsLegalToFold(N, P, P, OptLevel))
return false; return false;
return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp, Segment); return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp, Segment);
} }
/// getGlobalBaseReg - Return an SDNode that returns the value of /// getGlobalBaseReg - Return an SDNode that returns the value of
@ -1328,7 +1328,7 @@ SDNode *X86DAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) {
SDValue In2L = Node->getOperand(2); SDValue In2L = Node->getOperand(2);
SDValue In2H = Node->getOperand(3); SDValue In2H = Node->getOperand(3);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
if (!SelectAddr(In1.getNode(), In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) if (!SelectAddr(In1, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return NULL; return NULL;
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = cast<MemSDNode>(Node)->getMemOperand(); MemOp[0] = cast<MemSDNode>(Node)->getMemOperand();
@ -1354,7 +1354,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) {
SDValue Ptr = Node->getOperand(1); SDValue Ptr = Node->getOperand(1);
SDValue Val = Node->getOperand(2); SDValue Val = Node->getOperand(2);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4; SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
if (!SelectAddr(Ptr.getNode(), Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) if (!SelectAddr(Ptr, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4))
return 0; return 0;
bool isInc = false, isDec = false, isSub = false, isCN = false; bool isInc = false, isDec = false, isSub = false, isCN = false;
@ -1970,7 +1970,7 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
case 'v': // not offsetable ?? case 'v': // not offsetable ??
default: return true; default: return true;
case 'm': // memory case 'm': // memory
if (!SelectAddr(Op.getNode(), Op, Op0, Op1, Op2, Op3, Op4)) if (!SelectAddr(Op, Op0, Op1, Op2, Op3, Op4))
return true; return true;
break; break;
} }

View File

@ -181,9 +181,11 @@ def X86Punpckhqdq : SDNode<"X86ISD::PUNPCKHQDQ", SDTShuff2Op>;
// the top elements. These are used for the SSE 'ss' and 'sd' instruction // the top elements. These are used for the SSE 'ss' and 'sd' instruction
// forms. // forms.
def sse_load_f32 : ComplexPattern<v4f32, 5, "SelectScalarSSELoad", [], def sse_load_f32 : ComplexPattern<v4f32, 5, "SelectScalarSSELoad", [],
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; [SDNPHasChain, SDNPMayLoad, SDNPMemOperand,
SDNPWantRoot]>;
def sse_load_f64 : ComplexPattern<v2f64, 5, "SelectScalarSSELoad", [], def sse_load_f64 : ComplexPattern<v2f64, 5, "SelectScalarSSELoad", [],
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; [SDNPHasChain, SDNPMayLoad, SDNPMemOperand,
SDNPWantRoot]>;
def ssmem : Operand<v4f32> { def ssmem : Operand<v4f32> {
let PrintMethod = "printf32mem"; let PrintMethod = "printf32mem";

View File

@ -68,12 +68,9 @@ namespace {
} }
// Complex Pattern Selectors. // Complex Pattern Selectors.
bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset);
SDValue &Offset); bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base, bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset);
SDValue &Offset);
bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base,
SDValue &Offset);
virtual const char *getPassName() const { virtual const char *getPassName() const {
return "XCore DAG->DAG Pattern Instruction Selection"; return "XCore DAG->DAG Pattern Instruction Selection";
@ -91,8 +88,8 @@ FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) {
return new XCoreDAGToDAGISel(TM); return new XCoreDAGToDAGISel(TM);
} }
bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr, bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base,
SDValue &Base, SDValue &Offset) { SDValue &Offset) {
FrameIndexSDNode *FIN = 0; FrameIndexSDNode *FIN = 0;
if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) { if ((FIN = dyn_cast<FrameIndexSDNode>(Addr))) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
@ -113,8 +110,8 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr,
return false; return false;
} }
bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr, bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base,
SDValue &Base, SDValue &Offset) { SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) { if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) {
Base = Addr.getOperand(0); Base = Addr.getOperand(0);
Offset = CurDAG->getTargetConstant(0, MVT::i32); Offset = CurDAG->getTargetConstant(0, MVT::i32);
@ -134,8 +131,8 @@ bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr,
return false; return false;
} }
bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr, bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base,
SDValue &Base, SDValue &Offset) { SDValue &Offset) {
if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) {
Base = Addr.getOperand(0); Base = Addr.getOperand(0);
Offset = CurDAG->getTargetConstant(0, MVT::i32); Offset = CurDAG->getTargetConstant(0, MVT::i32);

View File

@ -407,6 +407,10 @@ ComplexPattern::ComplexPattern(Record *R) {
Properties |= 1 << SDNPMemOperand; Properties |= 1 << SDNPMemOperand;
} else if (PropList[i]->getName() == "SDNPVariadic") { } else if (PropList[i]->getName() == "SDNPVariadic") {
Properties |= 1 << SDNPVariadic; Properties |= 1 << SDNPVariadic;
} else if (PropList[i]->getName() == "SDNPWantRoot") {
Properties |= 1 << SDNPWantRoot;
} else if (PropList[i]->getName() == "SDNPWantParent") {
Properties |= 1 << SDNPWantParent;
} else { } else {
errs() << "Unsupported SD Node property '" << PropList[i]->getName() errs() << "Unsupported SD Node property '" << PropList[i]->getName()
<< "' on ComplexPattern '" << R->getName() << "'!\n"; << "' on ComplexPattern '" << R->getName() << "'!\n";

View File

@ -42,7 +42,9 @@ enum SDNP {
SDNPMayStore, SDNPMayStore,
SDNPSideEffect, SDNPSideEffect,
SDNPMemOperand, SDNPMemOperand,
SDNPVariadic SDNPVariadic,
SDNPWantRoot,
SDNPWantParent
}; };
/// getValueType - Return the MVT::SimpleValueType that the specified TableGen /// getValueType - Return the MVT::SimpleValueType that the specified TableGen

View File

@ -649,7 +649,13 @@ void MatcherTableEmitter::EmitPredicateFunctions(formatted_raw_ostream &OS) {
OS << " Result.resize(NextRes+" << NumOps << ");\n"; OS << " Result.resize(NextRes+" << NumOps << ");\n";
OS << " return " << P.getSelectFunc(); OS << " return " << P.getSelectFunc();
OS << "(Root, N"; OS << "(";
// If the complex pattern wants the root of the match, pass it in as the
// first argument.
if (P.hasProperty(SDNPWantRoot))
OS << "Root, ";
OS << "N";
for (unsigned i = 0; i != NumOps; ++i) for (unsigned i = 0; i != NumOps; ++i)
OS << ", Result[NextRes+" << i << ']'; OS << ", Result[NextRes+" << i << ']';
OS << ");\n"; OS << ");\n";