From lattner at cs.uiuc.edu Mon Jan 30 00:09:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 00:09:14 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200601300609.AAA28588@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.44 -> 1.45 --- Log message: Clear the OpAction field before setting it. This allows a target to set an instruction operation action to Expand, then set it to Legal later. --- Diffs of the changes: (+1 -0) TargetLowering.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.44 llvm/include/llvm/Target/TargetLowering.h:1.45 --- llvm/include/llvm/Target/TargetLowering.h:1.44 Sun Jan 29 22:08:18 2006 +++ llvm/include/llvm/Target/TargetLowering.h Mon Jan 30 00:09:03 2006 @@ -368,6 +368,7 @@ LegalizeAction Action) { assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) && "Table isn't big enough!"); + OpActions[Op] &= ~(3ULL << VT*2); OpActions[Op] |= Action << VT*2; } From lattner at cs.uiuc.edu Mon Jan 30 00:11:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 00:11:48 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SparcV8/ctpop.ll Message-ID: <200601300611.AAA28674@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SparcV8: ctpop.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+11 -0) ctpop.ll | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/test/Regression/CodeGen/SparcV8/ctpop.ll diff -c /dev/null llvm/test/Regression/CodeGen/SparcV8/ctpop.ll:1.1 *** /dev/null Mon Jan 30 00:11:46 2006 --- llvm/test/Regression/CodeGen/SparcV8/ctpop.ll Mon Jan 30 00:11:36 2006 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s | llc -march=sparcv8 -mattr=-v9 && + ; RUN: llvm-as < %s | llc -march=sparcv8 -mattr=v9 -enable-sparc-v9-insts && + ; RUN: llvm-as < %s | llc -march=sparcv8 -mattr=-v9 | not grep popc && + ; RUN: llvm-as < %s | llc -march=sparcv8 -mattr=v9 -enable-sparc-v9-insts | grep popc + + declare uint %llvm.ctpop.i32(uint) + uint %test(uint %X) { + %Y = call uint %llvm.ctpop.i32(uint %X) + ret uint %Y + } + From lattner at cs.uiuc.edu Mon Jan 30 00:14:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 00:14:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp SparcV8InstrInfo.td Message-ID: <200601300614.AAA28709@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.66 -> 1.67 SparcV8InstrInfo.td updated: 1.107 -> 1.108 --- Log message: Compile: uint %test(uint %X) { %Y = call uint %llvm.ctpop.i32(uint %X) ret uint %Y } to: test: save -96, %o6, %o6 sll %i0, 0, %l0 popc %l0, %i0 restore %g0, %g0, %g0 retl nop instead of to 40 logical ops. Note the shift-by-zero that clears the top part of the 64-bit V9 register. Testcase here: CodeGen/SparcV8/ctpop.ll --- Diffs of the changes: (+27 -16) SparcV8ISelDAGToDAG.cpp | 35 +++++++++++++++++++---------------- SparcV8InstrInfo.td | 8 ++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.66 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.67 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.66 Sun Jan 29 23:35:57 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Mon Jan 30 00:14:02 2006 @@ -33,21 +33,20 @@ namespace V8ISD { enum { FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END, - CMPICC, // Compare two GPR operands, set icc. - CMPFCC, // Compare two FP operands, set fcc. - BRICC, // Branch to dest on icc condition - BRFCC, // Branch to dest on fcc condition + CMPICC, // Compare two GPR operands, set icc. + CMPFCC, // Compare two FP operands, set fcc. + BRICC, // Branch to dest on icc condition + BRFCC, // Branch to dest on fcc condition + SELECT_ICC, // Select between two values using the current ICC flags. + SELECT_FCC, // Select between two values using the current FCC flags. - Hi, Lo, // Hi/Lo operations, typically on a global address. + Hi, Lo, // Hi/Lo operations, typically on a global address. - FTOI, // FP to Int within a FP register. - ITOF, // Int to FP within a FP register. - - SELECT_ICC, // Select between two values using the current ICC flags. - SELECT_FCC, // Select between two values using the current FCC flags. - - CALL, // A V8 call instruction. - RET_FLAG, // Return with a flag operand. + FTOI, // FP to Int within a FP register. + ITOF, // Int to FP within a FP register. + + CALL, // A V8 call instruction. + RET_FLAG, // Return with a flag operand. }; } @@ -173,10 +172,14 @@ setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); - setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); setStackPointerRegisterToSaveRestore(V8::O6); + if (TM.getSubtarget().isV9()) { + setOperationAction(ISD::CTPOP, MVT::i32, Legal); + } + computeRegisterProperties(); } @@ -187,12 +190,12 @@ case V8ISD::CMPFCC: return "V8ISD::CMPFCC"; case V8ISD::BRICC: return "V8ISD::BRICC"; case V8ISD::BRFCC: return "V8ISD::BRFCC"; + case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; + case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; case V8ISD::Hi: return "V8ISD::Hi"; case V8ISD::Lo: return "V8ISD::Lo"; case V8ISD::FTOI: return "V8ISD::FTOI"; case V8ISD::ITOF: return "V8ISD::ITOF"; - case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; - case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; case V8ISD::CALL: return "V8ISD::CALL"; case V8ISD::RET_FLAG: return "V8ISD::RET_FLAG"; } Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.107 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.108 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.107 Sun Jan 29 23:48:37 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Mon Jan 30 00:14:02 2006 @@ -764,6 +764,14 @@ [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>; } +// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear +// the top 32-bits before using it. To do this clearing, we use a SLLri X,0. +def POPCrr : F3_1<2, 0b101110, + (ops IntRegs:$dst, IntRegs:$src), + "popc $src, $dst", []>, Requires<[HasV9]>; +def : Pat<(ctpop IntRegs:$src), + (POPCrr (SLLri IntRegs:$src, 0))>; + //===----------------------------------------------------------------------===// // Non-Instruction Patterns //===----------------------------------------------------------------------===// From lattner at cs.uiuc.edu Mon Jan 30 01:43:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 01:43:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp SparcV8InstrInfo.td Message-ID: <200601300743.BAA29202@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.67 -> 1.68 SparcV8InstrInfo.td updated: 1.108 -> 1.109 --- Log message: Revamp the ICC/FCC reading instructions to be parameterized in terms of the SPARC condition codes, not in terms of the DAG condcodes. This allows us to write nice clean patterns for cmovs/branches. --- Diffs of the changes: (+212 -71) SparcV8ISelDAGToDAG.cpp | 172 ++++++++++++++++++++++++++++++++++++------------ SparcV8InstrInfo.td | 111 ++++++++++++++++++++++-------- 2 files changed, 212 insertions(+), 71 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.67 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.68 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.67 Mon Jan 30 00:14:02 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Mon Jan 30 01:43:04 2006 @@ -50,6 +50,123 @@ }; } +// Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These +// values must be kept in sync with the ones in the .td file. +namespace V8CC { + enum CondCodes { + //ICC_A = 8 , // Always + //ICC_N = 0 , // Never + ICC_NE = 9 , // Not Equal + ICC_E = 1 , // Equal + ICC_G = 10 , // Greater + ICC_LE = 2 , // Less or Equal + ICC_GE = 11 , // Greater or Equal + ICC_L = 3 , // Less + ICC_GU = 12 , // Greater Unsigned + ICC_LEU = 4 , // Less or Equal Unsigned + ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned + ICC_CS = 5 , // Carry Set/Less Unsigned + ICC_POS = 14 , // Positive + ICC_NEG = 6 , // Negative + ICC_VC = 15 , // Overflow Clear + ICC_VS = 7 , // Overflow Set + + //FCC_A = 8+16, // Always + //FCC_N = 0+16, // Never + FCC_U = 7+16, // Unordered + FCC_G = 6+16, // Greater + FCC_UG = 5+16, // Unordered or Greater + FCC_L = 4+16, // Less + FCC_UL = 3+16, // Unordered or Less + FCC_LG = 2+16, // Less or Greater + FCC_NE = 1+16, // Not Equal + FCC_E = 9+16, // Equal + FCC_UE = 10+16, // Unordered or Equal + FCC_GE = 11+16, // Greater or Equal + FCC_UGE = 12+16, // Unordered or Greater or Equal + FCC_LE = 13+16, // Less or Equal + FCC_ULE = 14+16, // Unordered or Less or Equal + FCC_O = 15+16, // Ordered + }; +} + + +/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC +/// condition. +static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { + switch (CC) { + default: assert(0 && "Unknown integer condition code!"); + case ISD::SETEQ: return V8CC::ICC_E; + case ISD::SETNE: return V8CC::ICC_NE; + case ISD::SETLT: return V8CC::ICC_L; + case ISD::SETGT: return V8CC::ICC_G; + case ISD::SETLE: return V8CC::ICC_LE; + case ISD::SETGE: return V8CC::ICC_GE; + case ISD::SETULT: return V8CC::ICC_CS; + case ISD::SETULE: return V8CC::ICC_LEU; + case ISD::SETUGT: return V8CC::ICC_GU; + case ISD::SETUGE: return V8CC::ICC_CC; + } +} + +/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC +/// FCC condition. +static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { + switch (CC) { + default: assert(0 && "Unknown fp condition code!"); + case ISD::SETEQ: return V8CC::FCC_E; + case ISD::SETNE: return V8CC::FCC_NE; + case ISD::SETLT: return V8CC::FCC_L; + case ISD::SETGT: return V8CC::FCC_G; + case ISD::SETLE: return V8CC::FCC_LE; + case ISD::SETGE: return V8CC::FCC_GE; + case ISD::SETULT: return V8CC::FCC_UL; + case ISD::SETULE: return V8CC::FCC_ULE; + case ISD::SETUGT: return V8CC::FCC_UG; + case ISD::SETUGE: return V8CC::FCC_UGE; + case ISD::SETUO: return V8CC::FCC_U; + case ISD::SETO: return V8CC::FCC_O; + case ISD::SETONE: return V8CC::FCC_LG; + case ISD::SETUEQ: return V8CC::FCC_UE; + } +} + + +static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return V8::BNE; + case V8CC::ICC_E: return V8::BE; + case V8CC::ICC_G: return V8::BG; + case V8CC::ICC_LE: return V8::BLE; + case V8CC::ICC_GE: return V8::BGE; + case V8CC::ICC_L: return V8::BL; + case V8CC::ICC_GU: return V8::BGU; + case V8CC::ICC_LEU: return V8::BLEU; + case V8CC::ICC_CC: return V8::BCC; + case V8CC::ICC_CS: return V8::BCS; + case V8CC::ICC_POS: return V8::BPOS; + case V8CC::ICC_NEG: return V8::BNEG; + case V8CC::ICC_VC: return V8::BVC; + case V8CC::ICC_VS: return V8::BVS; + case V8CC::FCC_U: return V8::FBU; + case V8CC::FCC_G: return V8::FBG; + case V8CC::FCC_UG: return V8::FBUG; + case V8CC::FCC_L: return V8::FBL; + case V8CC::FCC_UL: return V8::FBUL; + case V8CC::FCC_LG: return V8::FBLG; + case V8CC::FCC_NE: return V8::FBNE; + case V8CC::FCC_E: return V8::FBE; + case V8CC::FCC_UE: return V8::FBUE; + case V8CC::FCC_GE: return V8::FBGE; + case V8CC::FCC_UGE: return V8::FBUGE; + case V8CC::FCC_LE: return V8::FBLE; + case V8CC::FCC_ULE: return V8::FBULE; + case V8CC::FCC_O: return V8::FBO; + } +} + + namespace { class SparcV8TargetLowering : public TargetLowering { int VarArgsFrameOffset; // Frame offset to start of varargs area. @@ -645,7 +762,7 @@ } case ISD::BR_CC: { SDOperand Chain = Op.getOperand(0); - SDOperand CC = Op.getOperand(1); + ISD::CondCode CC = cast(Op.getOperand(1))->get(); SDOperand LHS = Op.getOperand(2); SDOperand RHS = Op.getOperand(3); SDOperand Dest = Op.getOperand(4); @@ -659,19 +776,22 @@ Ops.push_back(LHS); Ops.push_back(RHS); SDOperand Cond = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); - return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond); + SDOperand CCN = DAG.getConstant(IntCondCCodeToICC(CC), MVT::i32); + return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CCN, Cond); } else { SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); - return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond); + SDOperand CCN = DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32); + return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CCN, Cond); } } case ISD::SELECT_CC: { SDOperand LHS = Op.getOperand(0); SDOperand RHS = Op.getOperand(1); - unsigned CC = cast(Op.getOperand(4))->get(); + ISD::CondCode CC = cast(Op.getOperand(4))->get(); SDOperand TrueVal = Op.getOperand(2); SDOperand FalseVal = Op.getOperand(3); - + unsigned Opc, V8CC = ~0U; + // If this is a select_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. if (isa(RHS) && cast(RHS)->getValue() == 0&& @@ -685,13 +805,12 @@ cast(LHS.getOperand(0))->getValue() == 1 && cast(LHS.getOperand(1))->getValue() == 0) { SDOperand CMPCC = LHS.getOperand(3); - CC = cast(LHS.getOperand(2))->getValue(); + V8CC = cast(LHS.getOperand(2))->getValue(); LHS = CMPCC.getOperand(0); RHS = CMPCC.getOperand(1); } SDOperand CompareFlag; - unsigned Opc; if (LHS.getValueType() == MVT::i32) { std::vector VTs; VTs.push_back(LHS.getValueType()); // subcc returns a value @@ -701,12 +820,14 @@ Ops.push_back(RHS); CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); Opc = V8ISD::SELECT_ICC; + if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); } else { CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); Opc = V8ISD::SELECT_FCC; + if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); } return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, - DAG.getConstant(CC, MVT::i32), CompareFlag); + DAG.getConstant(V8CC, MVT::i32), CompareFlag); } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the @@ -759,42 +880,11 @@ case V8::SELECT_CC_Int_ICC: case V8::SELECT_CC_FP_ICC: case V8::SELECT_CC_DFP_ICC: - // Integer compare. - switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) { - default: assert(0 && "Unknown integer condition code!"); - case ISD::SETEQ: BROpcode = V8::BE; break; - case ISD::SETNE: BROpcode = V8::BNE; break; - case ISD::SETLT: BROpcode = V8::BL; break; - case ISD::SETGT: BROpcode = V8::BG; break; - case ISD::SETLE: BROpcode = V8::BLE; break; - case ISD::SETGE: BROpcode = V8::BGE; break; - case ISD::SETULT: BROpcode = V8::BCS; break; - case ISD::SETULE: BROpcode = V8::BLEU; break; - case ISD::SETUGT: BROpcode = V8::BGU; break; - case ISD::SETUGE: BROpcode = V8::BCC; break; - } - break; case V8::SELECT_CC_Int_FCC: case V8::SELECT_CC_FP_FCC: case V8::SELECT_CC_DFP_FCC: - // FP compare. - switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) { - default: assert(0 && "Unknown fp condition code!"); - case ISD::SETEQ: BROpcode = V8::FBE; break; - case ISD::SETNE: BROpcode = V8::FBNE; break; - case ISD::SETLT: BROpcode = V8::FBL; break; - case ISD::SETGT: BROpcode = V8::FBG; break; - case ISD::SETLE: BROpcode = V8::FBLE; break; - case ISD::SETGE: BROpcode = V8::FBGE; break; - case ISD::SETULT: BROpcode = V8::FBUL; break; - case ISD::SETULE: BROpcode = V8::FBULE; break; - case ISD::SETUGT: BROpcode = V8::FBUG; break; - case ISD::SETUGE: BROpcode = V8::FBUGE; break; - case ISD::SETUO: BROpcode = V8::FBU; break; - case ISD::SETO: BROpcode = V8::FBO; break; - case ISD::SETONE: BROpcode = V8::FBLG; break; - case ISD::SETUEQ: BROpcode = V8::FBUE; break; - } + V8CC::CondCodes CC = (V8CC::CondCodes)MI->getOperand(3).getImmedValue(); + BROpcode = SPARCCondCodeToBranchInstr(CC); break; } Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.108 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.109 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.108 Mon Jan 30 00:14:02 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Mon Jan 30 01:43:04 2006 @@ -84,7 +84,7 @@ def SDTV8cmpfcc : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>; def SDTV8brcc : -SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT>, +SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>, SDTCisVT<2, FlagVT>]>; def SDTV8selectcc : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, @@ -122,6 +122,43 @@ [SDNPHasChain, SDNPOptInFlag]>; //===----------------------------------------------------------------------===// +// SPARC Flag Conditions +//===----------------------------------------------------------------------===// + +// Note that these values must be kept in sync with the V8CC::CondCode enum +// values. +def ICC_NE : PatLeaf<(i32 9)>; // Not Equal +def ICC_E : PatLeaf<(i32 1)>; // Equal +def ICC_G : PatLeaf<(i32 10)>; // Greater +def ICC_LE : PatLeaf<(i32 2)>; // Less or Equal +def ICC_GE : PatLeaf<(i32 11)>; // Greater or Equal +def ICC_L : PatLeaf<(i32 3)>; // Less +def ICC_GU : PatLeaf<(i32 12)>; // Greater Unsigned +def ICC_LEU : PatLeaf<(i32 4)>; // Less or Equal Unsigned +def ICC_CC : PatLeaf<(i32 13)>; // Carry Clear/Great or Equal Unsigned +def ICC_CS : PatLeaf<(i32 5)>; // Carry Set/Less Unsigned +def ICC_POS : PatLeaf<(i32 14)>; // Positive +def ICC_NEG : PatLeaf<(i32 6)>; // Negative +def ICC_VC : PatLeaf<(i32 15)>; // Overflow Clear +def ICC_VS : PatLeaf<(i32 7)>; // Overflow Set + +def FCC_U : PatLeaf<(i32 23)>; // Unordered +def FCC_G : PatLeaf<(i32 22)>; // Greater +def FCC_UG : PatLeaf<(i32 21)>; // Unordered or Greater +def FCC_L : PatLeaf<(i32 20)>; // Less +def FCC_UL : PatLeaf<(i32 19)>; // Unordered or Less +def FCC_LG : PatLeaf<(i32 18)>; // Less or Greater +def FCC_NE : PatLeaf<(i32 17)>; // Not Equal +def FCC_E : PatLeaf<(i32 25)>; // Equal +def FCC_UE : PatLeaf<(i32 24)>; // Unordered or Equal +def FCC_GE : PatLeaf<(i32 25)>; // Greater or Equal +def FCC_UGE : PatLeaf<(i32 26)>; // Unordered or Greater or Equal +def FCC_LE : PatLeaf<(i32 27)>; // Less or Equal +def FCC_ULE : PatLeaf<(i32 28)>; // Unordered or Less or Equal +def FCC_O : PatLeaf<(i32 29)>; // Ordered + + +//===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -498,34 +535,48 @@ [(br bb:$dst)]>; def BNE : BranchV8<0b1001, (ops brtarget:$dst), "bne $dst", - [(V8bricc bb:$dst, SETNE, ICC)]>; + [(V8bricc bb:$dst, ICC_NE, ICC)]>; def BE : BranchV8<0b0001, (ops brtarget:$dst), "be $dst", - [(V8bricc bb:$dst, SETEQ, ICC)]>; + [(V8bricc bb:$dst, ICC_E, ICC)]>; def BG : BranchV8<0b1010, (ops brtarget:$dst), "bg $dst", - [(V8bricc bb:$dst, SETGT, ICC)]>; + [(V8bricc bb:$dst, ICC_G, ICC)]>; def BLE : BranchV8<0b0010, (ops brtarget:$dst), "ble $dst", - [(V8bricc bb:$dst, SETLE, ICC)]>; + [(V8bricc bb:$dst, ICC_LE, ICC)]>; def BGE : BranchV8<0b1011, (ops brtarget:$dst), "bge $dst", - [(V8bricc bb:$dst, SETGE, ICC)]>; + [(V8bricc bb:$dst, ICC_GE, ICC)]>; def BL : BranchV8<0b0011, (ops brtarget:$dst), "bl $dst", - [(V8bricc bb:$dst, SETLT, ICC)]>; + [(V8bricc bb:$dst, ICC_L, ICC)]>; def BGU : BranchV8<0b1100, (ops brtarget:$dst), "bgu $dst", - [(V8bricc bb:$dst, SETUGT, ICC)]>; + [(V8bricc bb:$dst, ICC_GU, ICC)]>; def BLEU : BranchV8<0b0100, (ops brtarget:$dst), "bleu $dst", - [(V8bricc bb:$dst, SETULE, ICC)]>; + [(V8bricc bb:$dst, ICC_LEU, ICC)]>; def BCC : BranchV8<0b1101, (ops brtarget:$dst), "bcc $dst", - [(V8bricc bb:$dst, SETUGE, ICC)]>; + [(V8bricc bb:$dst, ICC_CC, ICC)]>; def BCS : BranchV8<0b0101, (ops brtarget:$dst), "bcs $dst", - [(V8bricc bb:$dst, SETULT, ICC)]>; + [(V8bricc bb:$dst, ICC_CS, ICC)]>; +def BPOS : BranchV8<0b1110, (ops brtarget:$dst), + "bpos $dst", + [(V8bricc bb:$dst, ICC_POS, ICC)]>; +def BNEG : BranchV8<0b0110, (ops brtarget:$dst), + "bneg $dst", + [(V8bricc bb:$dst, ICC_NEG, ICC)]>; +def BVC : BranchV8<0b1111, (ops brtarget:$dst), + "bvc $dst", + [(V8bricc bb:$dst, ICC_VC, ICC)]>; +def BVS : BranchV8<0b0111, (ops brtarget:$dst), + "bvs $dst", + [(V8bricc bb:$dst, ICC_VS, ICC)]>; + + // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 @@ -540,46 +591,46 @@ def FBU : FPBranchV8<0b0111, (ops brtarget:$dst), "fbu $dst", - [(V8brfcc bb:$dst, SETUO, FCC)]>; + [(V8brfcc bb:$dst, FCC_U, FCC)]>; def FBG : FPBranchV8<0b0110, (ops brtarget:$dst), "fbg $dst", - [(V8brfcc bb:$dst, SETGT, FCC)]>; + [(V8brfcc bb:$dst, FCC_G, FCC)]>; def FBUG : FPBranchV8<0b0101, (ops brtarget:$dst), "fbug $dst", - [(V8brfcc bb:$dst, SETUGT, FCC)]>; + [(V8brfcc bb:$dst, FCC_UG, FCC)]>; def FBL : FPBranchV8<0b0100, (ops brtarget:$dst), "fbl $dst", - [(V8brfcc bb:$dst, SETLT, FCC)]>; + [(V8brfcc bb:$dst, FCC_L, FCC)]>; def FBUL : FPBranchV8<0b0011, (ops brtarget:$dst), "fbul $dst", - [(V8brfcc bb:$dst, SETULT, FCC)]>; + [(V8brfcc bb:$dst, FCC_UL, FCC)]>; def FBLG : FPBranchV8<0b0010, (ops brtarget:$dst), "fblg $dst", - [(V8brfcc bb:$dst, SETONE, FCC)]>; + [(V8brfcc bb:$dst, FCC_LG, FCC)]>; def FBNE : FPBranchV8<0b0001, (ops brtarget:$dst), "fbne $dst", - [(V8brfcc bb:$dst, SETNE, FCC)]>; + [(V8brfcc bb:$dst, FCC_NE, FCC)]>; def FBE : FPBranchV8<0b1001, (ops brtarget:$dst), "fbe $dst", - [(V8brfcc bb:$dst, SETEQ, FCC)]>; + [(V8brfcc bb:$dst, FCC_E, FCC)]>; def FBUE : FPBranchV8<0b1010, (ops brtarget:$dst), "fbue $dst", - [(V8brfcc bb:$dst, SETUEQ, FCC)]>; + [(V8brfcc bb:$dst, FCC_UE, FCC)]>; def FBGE : FPBranchV8<0b1011, (ops brtarget:$dst), "fbge $dst", - [(V8brfcc bb:$dst, SETGE, FCC)]>; + [(V8brfcc bb:$dst, FCC_GE, FCC)]>; def FBUGE: FPBranchV8<0b1100, (ops brtarget:$dst), "fbuge $dst", - [(V8brfcc bb:$dst, SETUGE, FCC)]>; + [(V8brfcc bb:$dst, FCC_UGE, FCC)]>; def FBLE : FPBranchV8<0b1101, (ops brtarget:$dst), "fble $dst", - [(V8brfcc bb:$dst, SETLE, FCC)]>; + [(V8brfcc bb:$dst, FCC_LE, FCC)]>; def FBULE: FPBranchV8<0b1110, (ops brtarget:$dst), "fbule $dst", - [(V8brfcc bb:$dst, SETULE, FCC)]>; + [(V8brfcc bb:$dst, FCC_ULE, FCC)]>; def FBO : FPBranchV8<0b1111, (ops brtarget:$dst), "fbo $dst", - [(V8brfcc bb:$dst, SETO, FCC)]>; + [(V8brfcc bb:$dst, FCC_O, FCC)]>; @@ -742,11 +793,11 @@ def MOVNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), "movne %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, 22, ICC))]>; - def MOVEQ : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "move %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, 17, ICC))]>; + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NE, ICC))]>; + def MOVE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "move %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_E, ICC))]>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. From evan.cheng at apple.com Mon Jan 30 01:47:58 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 01:47:58 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAG.h Message-ID: <200601300747.BAA29235@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAG.h updated: 1.93 -> 1.94 --- Log message: One more getTargetNode() variant shouldn't hurt... --- Diffs of the changes: (+16 -0) SelectionDAG.h | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.93 llvm/include/llvm/CodeGen/SelectionDAG.h:1.94 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.93 Sun Jan 29 00:24:40 2006 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Mon Jan 30 01:47:47 2006 @@ -484,6 +484,22 @@ SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, MVT::ValueType VT2, MVT::ValueType VT3, SDOperand Op1, SDOperand Op2, + SDOperand Op3, SDOperand Op4, SDOperand Op5) { + std::vector ResultTys; + ResultTys.push_back(VT1); + ResultTys.push_back(VT2); + ResultTys.push_back(VT3); + std::vector Ops; + Ops.push_back(Op1); + Ops.push_back(Op2); + Ops.push_back(Op3); + Ops.push_back(Op4); + Ops.push_back(Op5); + return getNode(ISD::BUILTIN_OP_END+Opcode, ResultTys, Ops); + } + SDOperand getTargetNode(unsigned Opcode, MVT::ValueType VT1, + MVT::ValueType VT2, MVT::ValueType VT3, + SDOperand Op1, SDOperand Op2, SDOperand Op3, SDOperand Op4, SDOperand Op5, SDOperand Op6) { std::vector ResultTys; From evan.cheng at apple.com Mon Jan 30 02:03:10 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 02:03:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td Message-ID: <200601300803.CAA29317@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.66 -> 1.67 X86ISelLowering.h updated: 1.20 -> 1.21 X86InstrInfo.td updated: 1.222 -> 1.223 --- Log message: Always use FP stack instructions to perform i64 to f64 as well as f64 to i64 conversions. SSE does not have instructions to handle these tasks. --- Diffs of the changes: (+64 -17) X86ISelLowering.cpp | 72 +++++++++++++++++++++++++++++++++++++++++----------- X86ISelLowering.h | 2 - X86InstrInfo.td | 7 +++-- 3 files changed, 64 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 llvm/lib/Target/X86/X86ISelLowering.cpp:1.67 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.66 Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 02:02:57 2006 @@ -68,11 +68,12 @@ setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64 + // isn't legal. + setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); + if (!X86ScalarSSE) { - // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64 - // isn't legal. - setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); - setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); } @@ -526,12 +527,11 @@ Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); if (X86ScalarSSE) { - // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except for RFP cannot be live across + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across // multiple blocks. When stackifier is fixed, they can be uncoupled. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); Tys.clear(); Tys.push_back(MVT::Other); @@ -1027,12 +1027,11 @@ Chain = RetVal.getValue(1); InFlag = RetVal.getValue(2); if (X86ScalarSSE) { - // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This - // shouldn't be necessary except for RFP cannot be live across + // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This + // shouldn't be necessary except that RFP cannot be live across // multiple blocks. When stackifier is fixed, they can be uncoupled. - unsigned Size = MVT::getSizeInBits(MVT::f64)/8; MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); Tys.clear(); Tys.push_back(MVT::Other); @@ -1461,12 +1460,38 @@ // Build the FILD std::vector Tys; Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); Tys.push_back(MVT::Flag); std::vector Ops; Ops.push_back(Chain); Ops.push_back(StackSlot); Ops.push_back(DAG.getValueType(SrcVT)); Result = DAG.getNode(X86ISD::FILD, Tys, Ops); + + if (X86ScalarSSE) { + assert(Op.getValueType() == MVT::f64 && "Invalid SINT_TO_FP to lower!"); + Chain = Result.getValue(1); + SDOperand InFlag = Result.getValue(2); + + // FIXME: Currently the FST is flagged to the FILD. This + // shouldn't be necessary except that RFP cannot be live across + // multiple blocks. When stackifier is fixed, they can be uncoupled. + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); + SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + std::vector Tys; + Tys.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(Result); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(MVT::f64)); + Ops.push_back(InFlag); + Chain = DAG.getNode(X86ISD::FST, Tys, Ops); + Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, + DAG.getSrcValue(NULL)); + } + return Result; } case ISD::FP_TO_SINT: { @@ -1488,10 +1513,29 @@ case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; } + SDOperand Chain = DAG.getEntryNode(); + SDOperand Value = Op.getOperand(0); + if (X86ScalarSSE) { + assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!"); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, StackSlot, + DAG.getSrcValue(0)); + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(StackSlot); + Ops.push_back(DAG.getValueType(MVT::f64)); + Value = DAG.getNode(X86ISD::FLD, Tys, Ops); + Chain = Value.getValue(1); + SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); + StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); + } + // Build the FP_TO_INT*_IN_MEM std::vector Ops; - Ops.push_back(DAG.getEntryNode()); - Ops.push_back(Op.getOperand(0)); + Ops.push_back(Chain); + Ops.push_back(Value); Ops.push_back(StackSlot); SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.20 llvm/lib/Target/X86/X86ISelLowering.h:1.21 --- llvm/lib/Target/X86/X86ISelLowering.h:1.20 Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Jan 30 02:02:57 2006 @@ -44,7 +44,7 @@ /// FILD - This instruction implements SINT_TO_FP with the integer source /// in memory and FP reg result. This corresponds to the X86::FILD*m /// instructions. It has three inputs (token chain, address, and source - /// type) and two outputs (FP value and token chain). + /// type) and three outputs (FP value, token chain, and a flag). FILD, /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.222 llvm/lib/Target/X86/X86InstrInfo.td:1.223 --- llvm/lib/Target/X86/X86InstrInfo.td:1.222 Sun Jan 29 00:44:22 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Jan 30 02:02:57 2006 @@ -103,7 +103,7 @@ def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, [SDNPHasChain, SDNPInFlag]>; def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, - [SDNPHasChain]>; + [SDNPHasChain, SDNPOutFlag]>; def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, [SDNPHasChain]>; def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem, @@ -3018,10 +3018,13 @@ def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>; def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>; -// Floatin point constant -0.0 and -1.0 +// Floating point constant -0.0 and -1.0 def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>; def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; +// Used to conv. i64 to f64 since there isn't a SSE version. +def : Pat<(X86fild addr:$src, i64), (FpILD64m addr:$src)>, Requires<[HasSSE2]>; + //===----------------------------------------------------------------------===// // Some peepholes //===----------------------------------------------------------------------===// From evan.cheng at apple.com Mon Jan 30 16:13:34 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 16:13:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200601302213.QAA17180@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.67 -> 1.68 --- Log message: i64 -> f32, f32 -> i64 and some clean up. --- Diffs of the changes: (+27 -31) X86ISelLowering.cpp | 58 ++++++++++++++++++++++++---------------------------- 1 files changed, 27 insertions(+), 31 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.67 llvm/lib/Target/X86/X86ISelLowering.cpp:1.68 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.67 Mon Jan 30 02:02:57 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 16:13:22 2006 @@ -67,15 +67,29 @@ // this operation. setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote); setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote); + if (X86ScalarSSE) + // SSE has no i16 to fp conversion, only i32 + setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote); + else if (!X86PatIsel) { + setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Custom); + setOperationAction(ISD::SINT_TO_FP , MVT::i32 , Custom); + } // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64 // isn't legal. setOperationAction(ISD::SINT_TO_FP , MVT::i64 , Custom); setOperationAction(ISD::FP_TO_SINT , MVT::i64 , Custom); - if (!X86ScalarSSE) { - setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); + // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have + // this operation. + setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); + setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); + + if (X86ScalarSSE) { + setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); + } else { setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Custom); + setOperationAction(ISD::FP_TO_SINT , MVT::i32 , Custom); } // Handle FP_TO_UINT by promoting the destination to a larger signed @@ -84,17 +98,16 @@ setOperationAction(ISD::FP_TO_UINT , MVT::i8 , Promote); setOperationAction(ISD::FP_TO_UINT , MVT::i16 , Promote); - if (!X86ScalarSSE) + if (X86ScalarSSE) + // Expand FP_TO_UINT into a select. + // FIXME: We would like to use a Custom expander here eventually to do + // the optimal thing for SSE vs. the default expansion in the legalizer. + setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); + else setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote); - // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have - // this operation. - setOperationAction(ISD::FP_TO_SINT , MVT::i1 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i8 , Promote); - setOperationAction(ISD::FP_TO_SINT , MVT::i16 , Promote); - - setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); - setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); + setOperationAction(ISD::BIT_CONVERT , MVT::f32 , Expand); + setOperationAction(ISD::BIT_CONVERT , MVT::i32 , Expand); if (!X86PatIsel) { setOperationAction(ISD::BRCOND , MVT::Other, Custom); @@ -193,15 +206,6 @@ setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); - // SSE has no i16 to fp conversion, only i32 - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); - - // Expand FP_TO_UINT into a select. - // FIXME: We would like to use a Custom expander here eventually to do - // the optimal thing for SSE vs. the default expansion in the legalizer. - setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Expand); - // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); @@ -225,11 +229,6 @@ setOperationAction(ISD::UNDEF, MVT::f64, Expand); - if (!X86PatIsel) { - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Custom); - setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); - } - if (!UnsafeFPMath) { setOperationAction(ISD::FSIN , MVT::f64 , Expand); setOperationAction(ISD::FCOS , MVT::f64 , Expand); @@ -1442,8 +1441,7 @@ return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); } case ISD::SINT_TO_FP: { - assert(Op.getValueType() == MVT::f64 && - Op.getOperand(0).getValueType() <= MVT::i64 && + assert(Op.getOperand(0).getValueType() <= MVT::i64 && Op.getOperand(0).getValueType() >= MVT::i16 && "Unknown SINT_TO_FP to lower!"); @@ -1469,7 +1467,6 @@ Result = DAG.getNode(X86ISD::FILD, Tys, Ops); if (X86ScalarSSE) { - assert(Op.getValueType() == MVT::f64 && "Invalid SINT_TO_FP to lower!"); Chain = Result.getValue(1); SDOperand InFlag = Result.getValue(2); @@ -1485,7 +1482,7 @@ Ops.push_back(Chain); Ops.push_back(Result); Ops.push_back(StackSlot); - Ops.push_back(DAG.getValueType(MVT::f64)); + Ops.push_back(DAG.getValueType(Op.getValueType())); Ops.push_back(InFlag); Chain = DAG.getNode(X86ISD::FST, Tys, Ops); Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, @@ -1496,7 +1493,6 @@ } case ISD::FP_TO_SINT: { assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && - Op.getOperand(0).getValueType() == MVT::f64 && "Unknown FP_TO_SINT to lower!"); // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary // stack slot. @@ -1525,7 +1521,7 @@ std::vector Ops; Ops.push_back(Chain); Ops.push_back(StackSlot); - Ops.push_back(DAG.getValueType(MVT::f64)); + Ops.push_back(DAG.getValueType(Op.getOperand(0).getValueType())); Value = DAG.getNode(X86ISD::FLD, Tys, Ops); Chain = Value.getValue(1); SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize); From lattner at cs.uiuc.edu Mon Jan 30 16:21:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 16:21:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601302221.QAA17233@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.68 -> 1.69 --- Log message: Fix FP constants, and the SparcV8/2006-01-22-BitConvertLegalize.ll failure from last night --- Diffs of the changes: (+3 -0) SparcV8ISelDAGToDAG.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.68 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.69 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.68 Mon Jan 30 01:43:04 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Mon Jan 30 16:20:49 2006 @@ -291,6 +291,9 @@ setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); + setOperationAction(ISD::ConstantFP, MVT::f64, Expand); + setOperationAction(ISD::ConstantFP, MVT::f32, Expand); + setStackPointerRegisterToSaveRestore(V8::O6); if (TM.getSubtarget().isV9()) { From lattner at cs.uiuc.edu Mon Jan 30 16:43:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 16:43:21 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/2006-01-30-LongSetcc.ll Message-ID: <200601302243.QAA17548@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: 2006-01-30-LongSetcc.ll added (r1.1) --- Log message: new testcase for the 'C++' failures last night. --- Diffs of the changes: (+6 -0) 2006-01-30-LongSetcc.ll | 6 ++++++ 1 files changed, 6 insertions(+) Index: llvm/test/Regression/CodeGen/X86/2006-01-30-LongSetcc.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/2006-01-30-LongSetcc.ll:1.1 *** /dev/null Mon Jan 30 16:43:20 2006 --- llvm/test/Regression/CodeGen/X86/2006-01-30-LongSetcc.ll Mon Jan 30 16:43:10 2006 *************** *** 0 **** --- 1,6 ---- + ; RUN: llvm-as < %s | llc -march=x86 + + bool %test(long %X) { + %B = setlt long %X, 0 ; [#uses=1] + ret bool %B + } From lattner at cs.uiuc.edu Mon Jan 30 16:44:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 16:44:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601302244.QAA17558@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.296 -> 1.297 --- Log message: Fix a bug in my legalizer reworking that caused the X86 backend to not get a chance to custom legalize setcc, which broke a bunch of C++ Codes. Testcase here: CodeGen/X86/2006-01-30-LongSetcc.ll --- Diffs of the changes: (+1 -2) LegalizeDAG.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.296 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.297 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.296 Sun Jan 29 22:22:28 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Jan 30 16:43:50 2006 @@ -1465,8 +1465,7 @@ } } - switch (TLI.getOperationAction(ISD::SETCC, - Node->getOperand(0).getValueType())) { + switch (TLI.getOperationAction(ISD::SETCC, Tmp1.getValueType())) { default: assert(0 && "Cannot handle this action for SETCC yet!"); case TargetLowering::Custom: isCustom = true; From lattner at cs.uiuc.edu Mon Jan 30 17:00:19 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 17:00:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200601302300.RAA18724@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.41 -> 1.42 --- Log message: Print the most trivial inline asms. --- Diffs of the changes: (+12 -1) AsmPrinter.cpp | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.41 llvm/lib/CodeGen/AsmPrinter.cpp:1.42 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.41 Thu Jan 26 20:10:10 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Mon Jan 30 17:00:08 2006 @@ -456,5 +456,16 @@ /// printInlineAsm - This method formats and prints the specified machine /// instruction that is an inline asm. void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { - O << "INLINE ASM NOT EMITTED YET!\n"; + unsigned NumOperands = MI->getNumOperands(); + + // Count the number of register definitions. + unsigned NumDefs = 0; + for (; MI->getOperand(NumDefs).isDef(); ++NumDefs) + assert(NumDefs != NumOperands-1 && "No asm string?"); + + assert(MI->getOperand(NumDefs).isExternalSymbol() && "No asm string?"); + + const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); + + O << AsmStr << "\n"; } From evan.cheng at apple.com Mon Jan 30 17:39:52 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 17:39:52 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/setuge.ll Message-ID: <200601302339.RAA18865@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: setuge.ll added (r1.1) --- Log message: Don't generate (or setp, setae) for SETUGE. Simply flip the operands around and generate SETULT instead. --- Diffs of the changes: (+12 -0) setuge.ll | 12 ++++++++++++ 1 files changed, 12 insertions(+) Index: llvm/test/Regression/CodeGen/X86/setuge.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/setuge.ll:1.1 *** /dev/null Mon Jan 30 17:39:50 2006 --- llvm/test/Regression/CodeGen/X86/setuge.ll Mon Jan 30 17:39:40 2006 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=x86 | not grep 'set' + + declare bool %llvm.isunordered.f32(float, float) + + float %cmp(float %A, float %B, float %C, float %D) { + entry: + %tmp.1 = call bool %llvm.isunordered.f32(float %A, float %B) + %tmp.2 = setge float %A, %B + %tmp.3 = or bool %tmp.1, %tmp.2 + %tmp.4 = select bool %tmp.3, float %C, float %D + ret float %tmp.4 + } From evan.cheng at apple.com Mon Jan 30 17:41:47 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 17:41:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200601302341.RAA18885@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.68 -> 1.69 --- Log message: Don't generate complex sequence for SETOLE, SETOLT, SETULT, and SETUGT. Flip the order of the compare operands and generate SETOGT, SETOGE, SETUGE, and SETULE instead. --- Diffs of the changes: (+32 -69) X86ISelLowering.cpp | 101 ++++++++++++++++------------------------------------ 1 files changed, 32 insertions(+), 69 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.68 llvm/lib/Target/X86/X86ISelLowering.cpp:1.69 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.68 Mon Jan 30 16:13:22 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 17:41:35 2006 @@ -1152,12 +1152,14 @@ } } -/// getX86CC - do a one to one translation of a ISD::CondCode to the X86 -/// specific condition code. It returns a X86ISD::COND_INVALID if it cannot -/// do a direct translation. -static unsigned getX86CC(SDOperand CC, bool isFP) { +/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86 +/// specific condition code. It returns a false if it cannot do a direct +/// translation. X86CC is the translated CondCode. Flip is set to true if the +/// the order of comparison operands should be flipped. +static bool translateX86CC(SDOperand CC, bool isFP, unsigned &X86CC, bool &Flip) { ISD::CondCode SetCCOpcode = cast(CC)->get(); - unsigned X86CC = X86ISD::COND_INVALID; + Flip = false; + X86CC = X86ISD::COND_INVALID; if (!isFP) { switch (SetCCOpcode) { default: break; @@ -1183,12 +1185,16 @@ default: break; case ISD::SETUEQ: case ISD::SETEQ: X86CC = X86ISD::COND_E; break; + case ISD::SETOLE: Flip = true; // Fallthrough case ISD::SETOGT: case ISD::SETGT: X86CC = X86ISD::COND_A; break; + case ISD::SETOLT: Flip = true; // Fallthrough case ISD::SETOGE: case ISD::SETGE: X86CC = X86ISD::COND_AE; break; + case ISD::SETUGE: Flip = true; // Fallthrough case ISD::SETULT: case ISD::SETLT: X86CC = X86ISD::COND_B; break; + case ISD::SETUGT: Flip = true; // Fallthrough case ISD::SETULE: case ISD::SETLE: X86CC = X86ISD::COND_BE; break; case ISD::SETONE: @@ -1197,7 +1203,8 @@ case ISD::SETO: X86CC = X86ISD::COND_NP; break; } } - return X86CC; + + return X86CC != X86ISD::COND_INVALID; } /// hasFPCMov - is there a floating point cmov for the specific X86 condition @@ -1557,18 +1564,26 @@ } case ISD::SETCC: { assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); - SDOperand CC = Op.getOperand(2); - SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, - Op.getOperand(0), Op.getOperand(1)); + SDOperand Cond; + SDOperand CC = Op.getOperand(2); ISD::CondCode SetCCOpcode = cast(CC)->get(); bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); - unsigned X86CC = getX86CC(CC, isFP); - if (X86CC != X86ISD::COND_INVALID) { + bool Flip; + unsigned X86CC; + if (translateX86CC(CC, isFP, X86CC, Flip)) { + if (Flip) + Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Op.getOperand(1), Op.getOperand(0)); + else + Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Op.getOperand(0), Op.getOperand(1)); return DAG.getNode(X86ISD::SETCC, MVT::i8, DAG.getConstant(X86CC, MVT::i8), Cond); } else { assert(isFP && "Illegal integer SetCC!"); + Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, + Op.getOperand(0), Op.getOperand(1)); std::vector Tys; std::vector Ops; switch (SetCCOpcode) { @@ -1584,50 +1599,6 @@ Tmp1.getValue(1)); return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); } - case ISD::SETOLT: { // !PF & CF - Tys.push_back(MVT::i8); - Tys.push_back(MVT::Flag); - Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8)); - Ops.push_back(Cond); - SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); - SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, - DAG.getConstant(X86ISD::COND_B, MVT::i8), - Tmp1.getValue(1)); - return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); - } - case ISD::SETOLE: { // !PF & (CF || ZF) - Tys.push_back(MVT::i8); - Tys.push_back(MVT::Flag); - Ops.push_back(DAG.getConstant(X86ISD::COND_NP, MVT::i8)); - Ops.push_back(Cond); - SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); - SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, - DAG.getConstant(X86ISD::COND_BE, MVT::i8), - Tmp1.getValue(1)); - return DAG.getNode(ISD::AND, MVT::i8, Tmp1, Tmp2); - } - case ISD::SETUGT: { // PF | (!ZF & !CF) - Tys.push_back(MVT::i8); - Tys.push_back(MVT::Flag); - Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8)); - Ops.push_back(Cond); - SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); - SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, - DAG.getConstant(X86ISD::COND_A, MVT::i8), - Tmp1.getValue(1)); - return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); - } - case ISD::SETUGE: { // PF | !CF - Tys.push_back(MVT::i8); - Tys.push_back(MVT::Flag); - Ops.push_back(DAG.getConstant(X86ISD::COND_P, MVT::i8)); - Ops.push_back(Cond); - SDOperand Tmp1 = DAG.getNode(X86ISD::SETCC, Tys, Ops); - SDOperand Tmp2 = DAG.getNode(X86ISD::SETCC, MVT::i8, - DAG.getConstant(X86ISD::COND_AE, MVT::i8), - Tmp1.getValue(1)); - return DAG.getNode(ISD::OR, MVT::i8, Tmp1, Tmp2); - } case ISD::SETUNE: { // PF | !ZF Tys.push_back(MVT::i8); Tys.push_back(MVT::Flag); @@ -1650,6 +1621,9 @@ bool addTest = false; SDOperand Op0 = Op.getOperand(0); SDOperand Cond, CC; + if (Op0.getOpcode() == ISD::SETCC) + Op0 = LowerOperation(Op0, DAG); + if (Op0.getOpcode() == X86ISD::SETCC) { // If condition flag is set by a X86ISD::CMP, then make a copy of it // (since flag operand cannot be shared). If the X86ISD::SETCC does not @@ -1677,13 +1651,6 @@ isFPStack && !hasFPCMov(cast(CC)->getSignExtended()); } else addTest = true; - } else if (Op0.getOpcode() == ISD::SETCC) { - CC = Op0.getOperand(2); - bool isFP = MVT::isFloatingPoint(Op0.getOperand(1).getValueType()); - unsigned X86CC = getX86CC(CC, isFP); - CC = DAG.getConstant(X86CC, MVT::i8); - Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, - Op0.getOperand(0), Op0.getOperand(1)); } else addTest = true; @@ -1709,6 +1676,9 @@ SDOperand Cond = Op.getOperand(1); SDOperand Dest = Op.getOperand(2); SDOperand CC; + if (Cond.getOpcode() == ISD::SETCC) + Cond = LowerOperation(Cond, DAG); + if (Cond.getOpcode() == X86ISD::SETCC) { // If condition flag is set by a X86ISD::CMP, then make a copy of it // (since flag operand cannot be shared). If the X86ISD::SETCC does not @@ -1734,13 +1704,6 @@ Cond.getOperand(0), Cond.getOperand(1)); } else addTest = true; - } else if (Cond.getOpcode() == ISD::SETCC) { - CC = Cond.getOperand(2); - bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType()); - unsigned X86CC = getX86CC(CC, isFP); - CC = DAG.getConstant(X86CC, MVT::i8); - Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, - Cond.getOperand(0), Cond.getOperand(1)); } else addTest = true; From lattner at cs.uiuc.edu Mon Jan 30 18:20:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 18:20:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200601310020.SAA19115@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.30 -> 1.31 --- Log message: add some notes --- Diffs of the changes: (+24 -0) README.txt | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.30 llvm/lib/Target/X86/README.txt:1.31 --- llvm/lib/Target/X86/README.txt:1.30 Sun Jan 29 03:46:06 2006 +++ llvm/lib/Target/X86/README.txt Mon Jan 30 18:20:38 2006 @@ -286,3 +286,27 @@ When compiled with unsafemath enabled, "main" should enable SSE DAZ mode and other fast SSE modes. + +//===---------------------------------------------------------------------===// + +cd Regression/CodeGen/X86 +llvm-as < setuge.ll | llc -march=x86 -mcpu=yonah -enable-x86-sse + +_cmp: + subl $4, %esp +1) leal 20(%esp), %eax + movss 12(%esp), %xmm0 +1) leal 16(%esp), %ecx + ucomiss 8(%esp), %xmm0 + cmovb %ecx, %eax +2) movss (%eax), %xmm0 +2) movss %xmm0, (%esp) + flds (%esp) + addl $4, %esp + ret + + +1) These LEA's should be adds. This is tricky because they are FrameIndex's + before prolog-epilog rewriting. +2) We shouldn't load into XMM regs only to store it back. + From lattner at cs.uiuc.edu Mon Jan 30 18:45:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 18:45:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200601310045.SAA19223@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.31 -> 1.32 --- Log message: more mumbling --- Diffs of the changes: (+4 -0) README.txt | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.31 llvm/lib/Target/X86/README.txt:1.32 --- llvm/lib/Target/X86/README.txt:1.31 Mon Jan 30 18:20:38 2006 +++ llvm/lib/Target/X86/README.txt Mon Jan 30 18:45:37 2006 @@ -310,3 +310,7 @@ before prolog-epilog rewriting. 2) We shouldn't load into XMM regs only to store it back. +//===---------------------------------------------------------------------===// + +Think about doing i64 math in SSE regs. + From lattner at cs.uiuc.edu Mon Jan 30 20:03:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 20:03:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200601310203.UAA19598@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.60 -> 1.61 SelectionDAGISel.cpp updated: 1.142 -> 1.143 --- Log message: Handle physreg input/outputs. We now compile this: int %test_cpuid(int %op) { %B = alloca int %C = alloca int %D = alloca int %A = call int asm "cpuid", "=eax,==ebx,==ecx,==edx,eax"(int* %B, int* %C, int* %D, int %op) %Bv = load int* %B %Cv = load int* %C %Dv = load int* %D %x = add int %A, %Bv %y = add int %x, %Cv %z = add int %y, %Dv ret int %z } to this: _test_cpuid: sub %ESP, 16 mov DWORD PTR [%ESP], %EBX mov %EAX, DWORD PTR [%ESP + 20] cpuid mov DWORD PTR [%ESP + 8], %ECX mov DWORD PTR [%ESP + 12], %EBX mov DWORD PTR [%ESP + 4], %EDX mov %ECX, DWORD PTR [%ESP + 12] add %EAX, %ECX mov %ECX, DWORD PTR [%ESP + 8] add %EAX, %ECX mov %ECX, DWORD PTR [%ESP + 4] add %EAX, %ECX mov %EBX, DWORD PTR [%ESP] add %ESP, 16 ret ... note the proper register allocation. :) it is unclear to me why the loads aren't folded into the adds. --- Diffs of the changes: (+98 -5) ScheduleDAG.cpp | 2 - SelectionDAGISel.cpp | 101 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.60 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.61 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.60 Thu Jan 26 17:28:04 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Mon Jan 30 20:03:41 2006 @@ -300,7 +300,7 @@ // Add all of the operand registers to the instruction. for (unsigned i = 2; i != NumOps; i += 2) { unsigned Reg = cast(Node->getOperand(i))->getReg(); - unsigned Flags = cast(Node->getOperand(i))->getValue(); + unsigned Flags =cast(Node->getOperand(i+1))->getValue(); MachineOperand::UseType UseTy; switch (Flags) { default: assert(0 && "Bad flags!"); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.142 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.143 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.142 Fri Jan 27 21:43:09 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Jan 30 20:03:41 2006 @@ -1158,7 +1158,6 @@ std::vector > Constraints = IA->ParseConstraints(); - /// AsmNodeOperands - A list of pairs. The first element is a register, the /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set @@ -1170,7 +1169,69 @@ SDOperand Chain = getRoot(); SDOperand Flag; - // FIXME: input copies. + // Loop over all of the inputs, copying the operand values into the + // appropriate registers and processing the output regs. + unsigned RetValReg = 0; + std::vector > IndirectStoresToEmit; + unsigned OpNum = 1; + bool FoundOutputConstraint = false; + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + switch (Constraints[i].first) { + case InlineAsm::isOutput: { + assert(!FoundOutputConstraint && + "Cannot have multiple output constraints yet!"); + FoundOutputConstraint = true; + assert(I.getType() != Type::VoidTy && "Bad inline asm!"); + // Copy the output from the appropriate register. + std::vector Regs = + TLI.getRegForInlineAsmConstraint(Constraints[i].second); + assert(Regs.size() == 1 && "Only handle simple regs right now!"); + RetValReg = Regs[0]; + + // Add information to the INLINEASM node to know that this register is + // set. + AsmNodeOperands.push_back(DAG.getRegister(RetValReg, + TLI.getValueType(I.getType()))); + AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF + break; + } + case InlineAsm::isIndirectOutput: { + // Copy the output from the appropriate register. + std::vector Regs = + TLI.getRegForInlineAsmConstraint(Constraints[i].second); + assert(Regs.size() == 1 && "Only handle simple regs right now!"); + IndirectStoresToEmit.push_back(std::make_pair(Regs[0], + I.getOperand(OpNum))); + OpNum++; // Consumes a call operand. + + // Add information to the INLINEASM node to know that this register is + // set. + AsmNodeOperands.push_back(DAG.getRegister(Regs[0], + TLI.getValueType(I.getType()))); + AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF + break; + } + case InlineAsm::isInput: { + // Copy the input into the appropriate register. + std::vector Regs = + TLI.getRegForInlineAsmConstraint(Constraints[i].second); + assert(Regs.size() == 1 && "Only handle simple regs right now!"); + Chain = DAG.getCopyToReg(Chain, Regs[0], + getValue(I.getOperand(OpNum)), Flag); + Flag = Chain.getValue(1); + + // Add information to the INLINEASM node to know that this register is + // read. + AsmNodeOperands.push_back(DAG.getRegister(Regs[0], + TLI.getValueType(I.getType()))); + AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE + break; + } + case InlineAsm::isClobber: + // Nothing to do. + break; + } + } // Finish up input operands. AsmNodeOperands[0] = Chain; @@ -1182,8 +1243,40 @@ Chain = DAG.getNode(ISD::INLINEASM, VTs, AsmNodeOperands); Flag = Chain.getValue(1); - // FIXME: Copies out of registers here, setValue(CI). - + // If this asm returns a register value, copy the result from that register + // and set it as the value of the call. + if (RetValReg) { + SDOperand Val = DAG.getCopyFromReg(Chain, RetValReg, + TLI.getValueType(I.getType()), Flag); + Chain = Val.getValue(1); + Flag = Val.getValue(2); + setValue(&I, Val); + } + + std::vector > StoresToEmit; + + // Process indirect outputs, first output all of the flagged copies out of + // physregs. + for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) { + Value *Ptr = IndirectStoresToEmit[i].second; + const Type *Ty = cast(Ptr->getType())->getElementType(); + SDOperand Val = DAG.getCopyFromReg(Chain, IndirectStoresToEmit[i].first, + TLI.getValueType(Ty), Flag); + Chain = Val.getValue(1); + Flag = Val.getValue(2); + StoresToEmit.push_back(std::make_pair(Val, Ptr)); + OpNum++; // Consumes a call operand. + } + + // Emit the non-flagged stores from the physregs. + std::vector OutChains; + for (unsigned i = 0, e = StoresToEmit.size(); i != e; ++i) + OutChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, + StoresToEmit[i].first, + getValue(StoresToEmit[i].second), + DAG.getSrcValue(StoresToEmit[i].second))); + if (!OutChains.empty()) + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains); DAG.setRoot(Chain); } From lattner at cs.uiuc.edu Mon Jan 30 20:10:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 20:10:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200601310210.UAA19664@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.32 -> 1.33 --- Log message: Another high-prio selection performance bug --- Diffs of the changes: (+46 -0) README.txt | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 46 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.32 llvm/lib/Target/X86/README.txt:1.33 --- llvm/lib/Target/X86/README.txt:1.32 Mon Jan 30 18:45:37 2006 +++ llvm/lib/Target/X86/README.txt Mon Jan 30 20:10:06 2006 @@ -314,3 +314,49 @@ Think about doing i64 math in SSE regs. +//===---------------------------------------------------------------------===// + +The DAG Isel doesn't fold the loads into the adds in this testcase. The +pattern selector does. This is because the chain value of the load gets +selected first, and the loads aren't checking to see if they are only used by +and add. + +.ll: + +int %test(int* %x, int* %y, int* %z) { + %X = load int* %x + %Y = load int* %y + %Z = load int* %z + %a = add int %X, %Y + %b = add int %a, %Z + ret int %b +} + +dag isel: + +_test: + movl 4(%esp), %eax + movl (%eax), %eax + movl 8(%esp), %ecx + movl (%ecx), %ecx + addl %ecx, %eax + movl 12(%esp), %ecx + movl (%ecx), %ecx + addl %ecx, %eax + ret + +pattern isel: + +_test: + movl 12(%esp), %ecx + movl 4(%esp), %edx + movl 8(%esp), %eax + movl (%eax), %eax + addl (%edx), %eax + addl (%ecx), %eax + ret + +This is bad for register pressure, though the dag isel is producing a +better schedule. :) + + From lattner at cs.uiuc.edu Mon Jan 30 20:46:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 20:46:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601310246.UAA19787@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.69 -> 1.70 --- Log message: I don't see why this optimization isn't safe, but it isn't, so disable it --- Diffs of the changes: (+2 -1) SparcV8ISelDAGToDAG.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.69 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.70 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.69 Mon Jan 30 16:20:49 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Mon Jan 30 20:45:52 2006 @@ -431,7 +431,8 @@ if (CurArgReg < ArgRegEnd) ++CurArgReg; if (CurArgReg < ArgRegEnd) ++CurArgReg; ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); - } else if (CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 && + } else if (/* FIXME: Apparently this isn't safe?? */ + 0 && CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 && ((CurArgReg-ArgRegs) & 1) == 0) { // If this is a double argument and the whole thing lives on the stack, // and the argument is aligned, load the double straight from the stack. From lattner at cs.uiuc.edu Mon Jan 30 20:55:39 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 20:55:39 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200601310255.UAA19847@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.48 -> 1.49 --- Log message: add the 'lucas' optimization --- Diffs of the changes: (+25 -0) README.txt | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.48 llvm/lib/Target/PowerPC/README.txt:1.49 --- llvm/lib/Target/PowerPC/README.txt:1.48 Fri Jan 27 23:40:47 2006 +++ llvm/lib/Target/PowerPC/README.txt Mon Jan 30 20:55:28 2006 @@ -402,3 +402,28 @@ TargetConstantVec's if it's one of the many forms that are algorithmically computable using the spiffy altivec instructions. +===-------------------------------------------------------------------------=== + +Compile this: + +double %test(double %X) { + %Y = cast double %X to long + %Z = cast long %Y to double + ret double %Z +} + +to this: + +_test: + fctidz f0, f1 + stfd f0, -8(r1) + lwz r2, -4(r1) + lwz r3, -8(r1) + stw r2, -12(r1) + stw r3, -16(r1) + lfd f0, -16(r1) + fcfid f1, f0 + blr + +without the lwz/stw's. + From evan.cheng at apple.com Mon Jan 30 21:14:41 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 30 Jan 2006 21:14:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.h X86ISelLowering.cpp X86InstrInfo.td Message-ID: <200601310314.VAA19923@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.h updated: 1.21 -> 1.22 X86ISelLowering.cpp updated: 1.69 -> 1.70 X86InstrInfo.td updated: 1.223 -> 1.224 --- Log message: Added custom lowering of fabs --- Diffs of the changes: (+49 -4) X86ISelLowering.cpp | 13 +++++++++++-- X86ISelLowering.h | 4 ++++ X86InstrInfo.td | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.21 llvm/lib/Target/X86/X86ISelLowering.h:1.22 --- llvm/lib/Target/X86/X86ISelLowering.h:1.21 Mon Jan 30 02:02:57 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Mon Jan 30 21:14:29 2006 @@ -41,6 +41,10 @@ SHLD, SHRD, + /// FAND - Bitwise logical AND of floating point values. This corresponds + /// to X86::ANDPS or X86::ANDPD. + FAND, + /// FILD - This instruction implements SINT_TO_FP with the integer source /// in memory and FP reg result. This corresponds to the X86::FILD*m /// instructions. It has three inputs (token chain, address, and source Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.69 llvm/lib/Target/X86/X86ISelLowering.cpp:1.70 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.69 Mon Jan 30 17:41:35 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Mon Jan 30 21:14:29 2006 @@ -23,6 +23,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" using namespace llvm; @@ -209,12 +210,12 @@ // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FABS , MVT::f64, Expand); + setOperationAction(ISD::FABS , MVT::f64, Custom); setOperationAction(ISD::FNEG , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FABS , MVT::f32, Expand); + setOperationAction(ISD::FABS , MVT::f32, Custom); setOperationAction(ISD::FNEG , MVT::f32, Expand); setOperationAction(ISD::FREM , MVT::f32, Expand); @@ -1562,6 +1563,13 @@ Tys.push_back(MVT::Other); return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); } + case ISD::FABS: { + MVT::ValueType VT = Op.getValueType(); + SDOperand Mask = (VT == MVT::f64) + ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), MVT::f64) + : DAG.getConstantFP(BitsToFloat (~(1U << 31)), MVT::f32); + return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask); + } case ISD::SETCC: { assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); SDOperand Cond; @@ -1912,6 +1920,7 @@ case X86ISD::SBB: return "X86ISD::SBB"; case X86ISD::SHLD: return "X86ISD::SHLD"; case X86ISD::SHRD: return "X86ISD::SHRD"; + case X86ISD::FAND: return "X86ISD::FAND"; case X86ISD::FILD: return "X86ISD::FILD"; case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM"; case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.223 llvm/lib/Target/X86/X86InstrInfo.td:1.224 --- llvm/lib/Target/X86/X86InstrInfo.td:1.223 Mon Jan 30 02:02:57 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Mon Jan 30 21:14:29 2006 @@ -68,6 +68,9 @@ def X86shld : SDNode<"X86ISD::SHLD", SDTIntShiftDOp>; def X86shrd : SDNode<"X86ISD::SHRD", SDTIntShiftDOp>; +def X86fand : SDNode<"X86ISD::FAND", SDTFPBinOp, + [SDNPCommutative, SDNPAssociative]>; + def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, [SDNPOutFlag]>; def X86test : SDNode<"X86ISD::TEST", SDTX86CmpTest, @@ -2549,10 +2552,12 @@ // SSE Logical let isCommutable = 1 in { def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "andps {$src2, $dst|$dst, $src2}", []>, + "andps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fand FR32:$src1, FR32:$src2))]>, Requires<[HasSSE1]>, TB; def ANDPDrr : I<0x54, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "andpd {$src2, $dst|$dst, $src2}", []>, + "andpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fand FR64:$src1, FR64:$src2))]>, Requires<[HasSSE2]>, TB, OpSize; def ORPSrr : I<0x56, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "orps {$src2, $dst|$dst, $src2}", []>, @@ -2567,12 +2572,39 @@ "xorpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; } +def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "andps {$src2, $dst|$dst, $src2}", + []>, + Requires<[HasSSE1]>, TB; +def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "andpd {$src2, $dst|$dst, $src2}", + []>, + Requires<[HasSSE2]>, TB, OpSize; +def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "orps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "orpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; +def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; +def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; + def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "andnps {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE1]>, TB; +def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), + "andnps {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE1]>, TB; def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; +def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), + "andnpd {$src2, $dst|$dst, $src2}", []>, + Requires<[HasSSE2]>, TB, OpSize; def CMPSSrr : I<0xC2, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), From lattner at cs.uiuc.edu Mon Jan 30 23:05:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 23:05:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601310505.XAA20474@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.297 -> 1.298 --- Log message: Only insert an AND when converting from BR_COND to BRCC if needed. --- Diffs of the changes: (+3 -1) LegalizeDAG.cpp | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.297 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.298 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.297 Mon Jan 30 16:43:50 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Jan 30 23:04:52 2006 @@ -703,7 +703,9 @@ } else { // Make sure the condition is either zero or one. It may have been // promoted from something else. - Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1); + unsigned NumBits = MVT::getSizeInBits(Tmp2.getValueType()); + if (!TLI.MaskedValueIsZero(Tmp2, (~0ULL >> (64-NumBits))^1)) + Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1); Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, DAG.getCondCode(ISD::SETNE), Tmp2, From lattner at cs.uiuc.edu Mon Jan 30 23:06:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 23:06:03 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601310506.XAA20543@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.70 -> 1.71 --- Log message: Compile this: void %X(int %A) { %C = setlt int %A, 123 ; [#uses=1] br bool %C, label %T, label %F T: ; preds = %0 call int %main( int 0 ) ; :0 [#uses=0] ret void F: ; preds = %0 ret void } to this: X: save -96, %o6, %o6 subcc %i0, 122, %l0 bg .LBBX_2 ! F nop ... not this: X: save -96, %o6, %o6 sethi 0, %l0 or %g0, 1, %l1 subcc %i0, 122, %l2 bg .LBBX_4 ! nop .LBBX_3: ! or %g0, %l0, %l1 .LBBX_4: ! subcc %l1, 0, %l0 bne .LBBX_2 ! F nop --- Diffs of the changes: (+37 -21) SparcV8ISelDAGToDAG.cpp | 58 ++++++++++++++++++++++++++++++------------------ 1 files changed, 37 insertions(+), 21 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.70 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.71 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.70 Mon Jan 30 20:45:52 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Mon Jan 30 23:05:52 2006 @@ -735,6 +735,28 @@ abort(); } +// Look at LHS/RHS/CC and see if they are a lowered V8 setcc instruction. If so +// set LHS/RHS and V8CC to the LHS/RHS of the setcc and V8CC to the condition. +static void LookThroughSetCC(SDOperand &LHS, SDOperand &RHS, + ISD::CondCode CC, unsigned &V8CC) { + if (isa(RHS) && cast(RHS)->getValue() == 0 && + CC == ISD::SETNE && + ((LHS.getOpcode() == V8ISD::SELECT_ICC && + LHS.getOperand(3).getOpcode() == V8ISD::CMPICC) || + (LHS.getOpcode() == V8ISD::SELECT_FCC && + LHS.getOperand(3).getOpcode() == V8ISD::CMPFCC)) && + isa(LHS.getOperand(0)) && + isa(LHS.getOperand(1)) && + cast(LHS.getOperand(0))->getValue() == 1 && + cast(LHS.getOperand(1))->getValue() == 0) { + SDOperand CMPCC = LHS.getOperand(3); + V8CC = cast(LHS.getOperand(2))->getValue(); + LHS = CMPCC.getOperand(0); + RHS = CMPCC.getOperand(1); + } +} + + SDOperand SparcV8TargetLowering:: LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { @@ -770,8 +792,14 @@ SDOperand LHS = Op.getOperand(2); SDOperand RHS = Op.getOperand(3); SDOperand Dest = Op.getOperand(4); + unsigned Opc, V8CC = ~0U; + + // If this is a br_cc of a "setcc", and if the setcc got lowered into + // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. + LookThroughSetCC(LHS, RHS, CC, V8CC); // Get the condition flag. + SDOperand CompareFlag; if (LHS.getValueType() == MVT::i32) { std::vector VTs; VTs.push_back(MVT::i32); @@ -779,14 +807,16 @@ std::vector Ops; Ops.push_back(LHS); Ops.push_back(RHS); - SDOperand Cond = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); - SDOperand CCN = DAG.getConstant(IntCondCCodeToICC(CC), MVT::i32); - return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CCN, Cond); + CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); + if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); + Opc = V8ISD::BRICC; } else { - SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); - SDOperand CCN = DAG.getConstant(FPCondCCodeToFCC(CC), MVT::i32); - return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CCN, Cond); + CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); + if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); + Opc = V8ISD::BRFCC; } + return DAG.getNode(Opc, MVT::Other, Chain, Dest, + DAG.getConstant(V8CC, MVT::i32), CompareFlag); } case ISD::SELECT_CC: { SDOperand LHS = Op.getOperand(0); @@ -798,21 +828,7 @@ // If this is a select_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. - if (isa(RHS) && cast(RHS)->getValue() == 0&& - CC == ISD::SETNE && - ((LHS.getOpcode() == V8ISD::SELECT_ICC && - LHS.getOperand(3).getOpcode() == V8ISD::CMPICC) || - (LHS.getOpcode() == V8ISD::SELECT_FCC && - LHS.getOperand(3).getOpcode() == V8ISD::CMPFCC)) && - isa(LHS.getOperand(0)) && - isa(LHS.getOperand(1)) && - cast(LHS.getOperand(0))->getValue() == 1 && - cast(LHS.getOperand(1))->getValue() == 0) { - SDOperand CMPCC = LHS.getOperand(3); - V8CC = cast(LHS.getOperand(2))->getValue(); - LHS = CMPCC.getOperand(0); - RHS = CMPCC.getOperand(1); - } + LookThroughSetCC(LHS, RHS, CC, V8CC); SDOperand CompareFlag; if (LHS.getValueType() == MVT::i32) { From lattner at cs.uiuc.edu Mon Jan 30 23:26:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon, 30 Jan 2006 23:26:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200601310526.XAA20632@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.109 -> 1.110 --- Log message: Add the full complement of conditional moves of integer registers. --- Diffs of the changes: (+115 -7) SparcV8InstrInfo.td | 122 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 115 insertions(+), 7 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.109 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.110 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.109 Mon Jan 30 01:43:04 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Mon Jan 30 23:26:36 2006 @@ -790,14 +790,122 @@ // V9 Conditional Moves. let Predicates = [HasV9], isTwoAddress = 1 in { // FIXME: Add instruction encodings for the JIT some day. - def MOVNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movne %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NE, ICC))]>; - def MOVE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "move %icc, $F, $dst", - [(set IntRegs:$dst, + // FIXME: Allow regalloc of the condition code some day. + + // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. + def MOVNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movne %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NE, ICC))]>; + def MOVE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "move %icc, $F, $dst", + [(set IntRegs:$dst, (V8selecticc IntRegs:$F, IntRegs:$T, ICC_E, ICC))]>; + def MOVG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movg %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_G, ICC))]>; + def MOVLE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movle %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_LE, ICC))]>; + def MOVGE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movge %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_GE, ICC))]>; + def MOVL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movl %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_L, ICC))]>; + def MOVGU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movgu %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_GU, ICC))]>; + def MOVLEU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movleu %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_LEU, ICC))]>; + def MOVCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movcc %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CC, ICC))]>; + def MOVCS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movcs %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CS, ICC))]>; + def MOVPOS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movpos %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_POS, ICC))]>; + def MOVNEG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movneg %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NEG, ICC))]>; + def MOVVC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movvc %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_VC, ICC))]>; + def MOVVS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movvs %icc, $F, $dst", + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CS, ICC))]>; + + def MOVFU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfu %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_U, FCC))]>; + def MOVFG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfg %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_G, FCC))]>; + def MOVFUG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfug %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UG, FCC))]>; + def MOVFL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfl %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_L, FCC))]>; + def MOVFUL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movful %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UL, FCC))]>; + def MOVFLG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movflg %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_LG, FCC))]>; + def MOVFNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfne %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_NE, FCC))]>; + def MOVFE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfe %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_E, FCC))]>; + def MOVFUE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfue %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UE, FCC))]>; + def MOVFGE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfge %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_GE, FCC))]>; + def MOVFUGE: Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfuge %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UGE, FCC))]>; + def MOVFLE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfle %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_LE, FCC))]>; + def MOVFULE: Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfule %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_ULE, FCC))]>; + def MOVFO : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + "movfo %fcc, $F, $dst", + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_O, FCC))]>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. From lattner at cs.uiuc.edu Tue Jan 31 00:01:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:01:52 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/TableGen/DagIntSubst.ll Message-ID: <200601310601.AAA20912@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/TableGen: DagIntSubst.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+10 -0) DagIntSubst.ll | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/test/Regression/TableGen/DagIntSubst.ll diff -c /dev/null llvm/test/Regression/TableGen/DagIntSubst.ll:1.1 *** /dev/null Tue Jan 31 00:01:50 2006 --- llvm/test/Regression/TableGen/DagIntSubst.ll Tue Jan 31 00:01:40 2006 *************** *** 0 **** --- 1,10 ---- + // RUN: tblgen %s | grep 'dag d = (X 13)' + def X; + + class C { + dag d = (X N); + } + + def VAL : C<13>; + + From lattner at cs.uiuc.edu Tue Jan 31 00:02:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:02:47 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/FileParser.y Record.cpp Record.h Message-ID: <200601310602.AAA21003@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: FileParser.y updated: 1.39 -> 1.40 Record.cpp updated: 1.49 -> 1.50 Record.h updated: 1.54 -> 1.55 --- Log message: implement test/Regression/TableGen/DagIntSubst.ll --- Diffs of the changes: (+19 -2) FileParser.y | 2 +- Record.cpp | 11 +++++++++++ Record.h | 8 +++++++- 3 files changed, 19 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.39 llvm/utils/TableGen/FileParser.y:1.40 --- llvm/utils/TableGen/FileParser.y:1.39 Thu Sep 29 23:53:04 2005 +++ llvm/utils/TableGen/FileParser.y Tue Jan 31 00:02:35 2006 @@ -68,7 +68,7 @@ } static void setValue(const std::string &ValName, - std::vector *BitList, Init *V) { + std::vector *BitList, Init *V) { if (!V) return; RecordVal *RV = CurRec->getValue(ValName); Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.49 llvm/utils/TableGen/Record.cpp:1.50 --- llvm/utils/TableGen/Record.cpp:1.49 Sun Dec 25 23:08:55 2005 +++ llvm/utils/TableGen/Record.cpp Tue Jan 31 00:02:35 2006 @@ -554,6 +554,17 @@ return this; } +Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) { + std::vector NewArgs; + for (unsigned i = 0, e = Args.size(); i != e; ++i) + NewArgs.push_back(Args[i]->resolveReferences(R, RV)); + + if (Args != NewArgs) + return new DagInit(NodeTypeDef, NewArgs, ArgNames); + + return this; +} + void DagInit::print(std::ostream &OS) const { OS << "(" << NodeTypeDef->getName(); Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.54 llvm/utils/TableGen/Record.h:1.55 --- llvm/utils/TableGen/Record.h:1.54 Fri Oct 28 17:49:02 2005 +++ llvm/utils/TableGen/Record.h Tue Jan 31 00:02:35 2006 @@ -826,7 +826,11 @@ ArgNames.push_back(args[i].second); } } - + DagInit(Record *D, const std::vector &args, + const std::vector &argNames) + : NodeTypeDef(D), Args(args), ArgNames(argNames) { + } + virtual Init *convertInitializerTo(RecTy *Ty) { return Ty->convertValue(this); } @@ -847,6 +851,8 @@ assert(Num < Args.size() && "Arg number out of range!"); Args[Num] = I; } + + virtual Init *resolveReferences(Record &R, const RecordVal *RV); virtual void print(std::ostream &OS) const; }; From lattner at cs.uiuc.edu Tue Jan 31 00:18:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:18:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200601310618.AAA21119@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.110 -> 1.111 --- Log message: Shrinkify --- Diffs of the changes: (+86 -143) SparcV8InstrInfo.td | 229 +++++++++++++++++++--------------------------------- 1 files changed, 86 insertions(+), 143 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.110 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.111 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.110 Mon Jan 30 23:26:36 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Tue Jan 31 00:18:16 2006 @@ -43,6 +43,11 @@ // Instruction Pattern Stuff //===----------------------------------------------------------------------===// +def simm11 : PatLeaf<(imm), [{ + // simm11 predicate - True if the imm fits in a 11-bit sign extended field. + return (((int)N->getValue() << (32-11)) >> (32-11)) == (int)N->getValue(); +}]>; + def simm13 : PatLeaf<(imm), [{ // simm13 predicate - True if the imm fits in a 13-bit sign extended field. return (((int)N->getValue() << (32-13)) >> (32-13)) == (int)N->getValue(); @@ -127,35 +132,41 @@ // Note that these values must be kept in sync with the V8CC::CondCode enum // values. -def ICC_NE : PatLeaf<(i32 9)>; // Not Equal -def ICC_E : PatLeaf<(i32 1)>; // Equal -def ICC_G : PatLeaf<(i32 10)>; // Greater -def ICC_LE : PatLeaf<(i32 2)>; // Less or Equal -def ICC_GE : PatLeaf<(i32 11)>; // Greater or Equal -def ICC_L : PatLeaf<(i32 3)>; // Less -def ICC_GU : PatLeaf<(i32 12)>; // Greater Unsigned -def ICC_LEU : PatLeaf<(i32 4)>; // Less or Equal Unsigned -def ICC_CC : PatLeaf<(i32 13)>; // Carry Clear/Great or Equal Unsigned -def ICC_CS : PatLeaf<(i32 5)>; // Carry Set/Less Unsigned -def ICC_POS : PatLeaf<(i32 14)>; // Positive -def ICC_NEG : PatLeaf<(i32 6)>; // Negative -def ICC_VC : PatLeaf<(i32 15)>; // Overflow Clear -def ICC_VS : PatLeaf<(i32 7)>; // Overflow Set - -def FCC_U : PatLeaf<(i32 23)>; // Unordered -def FCC_G : PatLeaf<(i32 22)>; // Greater -def FCC_UG : PatLeaf<(i32 21)>; // Unordered or Greater -def FCC_L : PatLeaf<(i32 20)>; // Less -def FCC_UL : PatLeaf<(i32 19)>; // Unordered or Less -def FCC_LG : PatLeaf<(i32 18)>; // Less or Greater -def FCC_NE : PatLeaf<(i32 17)>; // Not Equal -def FCC_E : PatLeaf<(i32 25)>; // Equal -def FCC_UE : PatLeaf<(i32 24)>; // Unordered or Equal -def FCC_GE : PatLeaf<(i32 25)>; // Greater or Equal -def FCC_UGE : PatLeaf<(i32 26)>; // Unordered or Greater or Equal -def FCC_LE : PatLeaf<(i32 27)>; // Less or Equal -def FCC_ULE : PatLeaf<(i32 28)>; // Unordered or Less or Equal -def FCC_O : PatLeaf<(i32 29)>; // Ordered +class ICC_VAL : PatLeaf<(i32 N)> { + int ICCVal = N; +} +def ICC_NE : ICC_VAL< 9>; // Not Equal +def ICC_E : ICC_VAL< 1>; // Equal +def ICC_G : ICC_VAL<10>; // Greater +def ICC_LE : ICC_VAL< 2>; // Less or Equal +def ICC_GE : ICC_VAL<11>; // Greater or Equal +def ICC_L : ICC_VAL< 3>; // Less +def ICC_GU : ICC_VAL<12>; // Greater Unsigned +def ICC_LEU : ICC_VAL< 4>; // Less or Equal Unsigned +def ICC_CC : ICC_VAL<13>; // Carry Clear/Great or Equal Unsigned +def ICC_CS : ICC_VAL< 5>; // Carry Set/Less Unsigned +def ICC_POS : ICC_VAL<14>; // Positive +def ICC_NEG : ICC_VAL< 6>; // Negative +def ICC_VC : ICC_VAL<15>; // Overflow Clear +def ICC_VS : ICC_VAL< 7>; // Overflow Set + +class FCC_VAL : PatLeaf<(i32 N)> { + int FCCVal = N; +} +def FCC_U : FCC_VAL<23>; // Unordered +def FCC_G : FCC_VAL<22>; // Greater +def FCC_UG : FCC_VAL<21>; // Unordered or Greater +def FCC_L : FCC_VAL<20>; // Less +def FCC_UL : FCC_VAL<19>; // Unordered or Less +def FCC_LG : FCC_VAL<18>; // Less or Greater +def FCC_NE : FCC_VAL<17>; // Not Equal +def FCC_E : FCC_VAL<25>; // Equal +def FCC_UE : FCC_VAL<24>; // Unordered or Equal +def FCC_GE : FCC_VAL<25>; // Greater or Equal +def FCC_UGE : FCC_VAL<26>; // Unordered or Greater or Equal +def FCC_LE : FCC_VAL<27>; // Less or Equal +def FCC_ULE : FCC_VAL<28>; // Unordered or Less or Equal +def FCC_O : FCC_VAL<29>; // Ordered //===----------------------------------------------------------------------===// @@ -790,122 +801,54 @@ // V9 Conditional Moves. let Predicates = [HasV9], isTwoAddress = 1 in { // FIXME: Add instruction encodings for the JIT some day. - // FIXME: Allow regalloc of the condition code some day. + class IntCMOVICCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + asmstr, + [(set IntRegs:$dst, + (V8selecticc IntRegs:$F, IntRegs:$T, CC, ICC))]> { + int CondBits = CC.ICCVal; + } + // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. - def MOVNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movne %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NE, ICC))]>; - def MOVE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "move %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_E, ICC))]>; - def MOVG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movg %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_G, ICC))]>; - def MOVLE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movle %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_LE, ICC))]>; - def MOVGE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movge %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_GE, ICC))]>; - def MOVL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movl %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_L, ICC))]>; - def MOVGU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movgu %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_GU, ICC))]>; - def MOVLEU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movleu %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_LEU, ICC))]>; - def MOVCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movcc %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CC, ICC))]>; - def MOVCS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movcs %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CS, ICC))]>; - def MOVPOS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movpos %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_POS, ICC))]>; - def MOVNEG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movneg %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_NEG, ICC))]>; - def MOVVC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movvc %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_VC, ICC))]>; - def MOVVS : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movvs %icc, $F, $dst", - [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, ICC_CS, ICC))]>; - - def MOVFU : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfu %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_U, FCC))]>; - def MOVFG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfg %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_G, FCC))]>; - def MOVFUG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfug %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UG, FCC))]>; - def MOVFL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfl %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_L, FCC))]>; - def MOVFUL : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movful %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UL, FCC))]>; - def MOVFLG : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movflg %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_LG, FCC))]>; - def MOVFNE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfne %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_NE, FCC))]>; - def MOVFE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfe %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_E, FCC))]>; - def MOVFUE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfue %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UE, FCC))]>; - def MOVFGE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfge %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_GE, FCC))]>; - def MOVFUGE: Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfuge %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_UGE, FCC))]>; - def MOVFLE : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfle %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_LE, FCC))]>; - def MOVFULE: Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfule %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_ULE, FCC))]>; - def MOVFO : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - "movfo %fcc, $F, $dst", - [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, FCC_O, FCC))]>; + def MOVNErr : IntCMOVICCrr< "movne %icc, $F, $dst", ICC_NE>; + def MOVErr : IntCMOVICCrr< "move %icc, $F, $dst", ICC_E>; + def MOVGrr : IntCMOVICCrr< "movg %icc, $F, $dst", ICC_G>; + def MOVLErr : IntCMOVICCrr< "movle %icc, $F, $dst", ICC_LE>; + def MOVGErr : IntCMOVICCrr< "movge %icc, $F, $dst", ICC_GE>; + def MOVLrr : IntCMOVICCrr< "movl %icc, $F, $dst", ICC_L>; + def MOVGUrr : IntCMOVICCrr< "movgu %icc, $F, $dst", ICC_GU>; + def MOVLEUrr : IntCMOVICCrr<"movleu %icc, $F, $dst", ICC_LEU>; + def MOVCCrr : IntCMOVICCrr< "movcc %icc, $F, $dst", ICC_CC>; + def MOVCSrr : IntCMOVICCrr< "movcs %icc, $F, $dst", ICC_CS>; + def MOVPOSrr : IntCMOVICCrr<"movpos %icc, $F, $dst", ICC_POS>; + def MOVNEGrr : IntCMOVICCrr<"movneg %icc, $F, $dst", ICC_NEG>; + def MOVVCrr : IntCMOVICCrr< "movvc %icc, $F, $dst", ICC_VC>; + def MOVVSrr : IntCMOVICCrr< "movvs %icc, $F, $dst", ICC_VS>; + + // FIXME: Allow regalloc of the fcc condition code some day. + class IntCMOVFCCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), + asmstr, + [(set IntRegs:$dst, + (V8selectfcc IntRegs:$F, IntRegs:$T, CC, FCC))]> { + int CondBits = CC.FCCVal; + } + + def MOVFUrr : IntCMOVFCCrr< "movfu %fcc, $F, $dst", FCC_U>; + def MOVFGrr : IntCMOVFCCrr< "movfg %fcc, $F, $dst", FCC_G>; + def MOVFUGrr : IntCMOVFCCrr< "movfug %fcc, $F, $dst", FCC_UG>; + def MOVFLrr : IntCMOVFCCrr< "movfl %fcc, $F, $dst", FCC_L>; + def MOVFULrr : IntCMOVFCCrr< "movful %fcc, $F, $dst", FCC_UL>; + def MOVFLGrr : IntCMOVFCCrr< "movflg %fcc, $F, $dst", FCC_LG>; + def MOVFNErr : IntCMOVFCCrr< "movfne %fcc, $F, $dst", FCC_NE>; + def MOVFErr : IntCMOVFCCrr< "movfe %fcc, $F, $dst", FCC_E>; + def MOVFUErr : IntCMOVFCCrr< "movfue %fcc, $F, $dst", FCC_UE>; + def MOVFGErr : IntCMOVFCCrr< "movfge %fcc, $F, $dst", FCC_GE>; + def MOVFUGErr : IntCMOVFCCrr<"movfuge %fcc, $F, $dst", FCC_UGE>; + def MOVFLErr : IntCMOVFCCrr< "movfle %fcc, $F, $dst", FCC_LE>; + def MOVFULErr : IntCMOVFCCrr<"movfule %fcc, $F, $dst", FCC_ULE>; + def MOVFOrr : IntCMOVFCCrr< "movfo %fcc, $F, $dst", FCC_O>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. From lattner at cs.uiuc.edu Tue Jan 31 00:24:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:24:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200601310624.AAA21194@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.111 -> 1.112 --- Log message: Add immediate forms of integer cmovs --- Diffs of the changes: (+49 -6) SparcV8InstrInfo.td | 55 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 49 insertions(+), 6 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.111 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.112 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.111 Tue Jan 31 00:18:16 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Tue Jan 31 00:24:29 2006 @@ -800,17 +800,22 @@ // V9 Conditional Moves. let Predicates = [HasV9], isTwoAddress = 1 in { + // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. // FIXME: Add instruction encodings for the JIT some day. class IntCMOVICCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - asmstr, + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, [(set IntRegs:$dst, (V8selecticc IntRegs:$F, IntRegs:$T, CC, ICC))]> { int CondBits = CC.ICCVal; } + class IntCMOVICCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + [(set IntRegs:$dst, + (V8selecticc simm11:$F, IntRegs:$T, CC, ICC))]> { + int CondBits = CC.ICCVal; + } - - // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. + // MOV*rr instructions. def MOVNErr : IntCMOVICCrr< "movne %icc, $F, $dst", ICC_NE>; def MOVErr : IntCMOVICCrr< "move %icc, $F, $dst", ICC_E>; def MOVGrr : IntCMOVICCrr< "movg %icc, $F, $dst", ICC_G>; @@ -825,16 +830,38 @@ def MOVNEGrr : IntCMOVICCrr<"movneg %icc, $F, $dst", ICC_NEG>; def MOVVCrr : IntCMOVICCrr< "movvc %icc, $F, $dst", ICC_VC>; def MOVVSrr : IntCMOVICCrr< "movvs %icc, $F, $dst", ICC_VS>; + + // MOV*ri instructions. + def MOVNEri : IntCMOVICCri< "movne %icc, $F, $dst", ICC_NE>; + def MOVEri : IntCMOVICCri< "move %icc, $F, $dst", ICC_E>; + def MOVGri : IntCMOVICCri< "movg %icc, $F, $dst", ICC_G>; + def MOVLEri : IntCMOVICCri< "movle %icc, $F, $dst", ICC_LE>; + def MOVGEri : IntCMOVICCri< "movge %icc, $F, $dst", ICC_GE>; + def MOVLri : IntCMOVICCri< "movl %icc, $F, $dst", ICC_L>; + def MOVGUri : IntCMOVICCri< "movgu %icc, $F, $dst", ICC_GU>; + def MOVLEUri : IntCMOVICCri<"movleu %icc, $F, $dst", ICC_LEU>; + def MOVCCri : IntCMOVICCri< "movcc %icc, $F, $dst", ICC_CC>; + def MOVCSri : IntCMOVICCri< "movcs %icc, $F, $dst", ICC_CS>; + def MOVPOSri : IntCMOVICCri<"movpos %icc, $F, $dst", ICC_POS>; + def MOVNEGri : IntCMOVICCri<"movneg %icc, $F, $dst", ICC_NEG>; + def MOVVCri : IntCMOVICCri< "movvc %icc, $F, $dst", ICC_VC>; + def MOVVSri : IntCMOVICCri< "movvs %icc, $F, $dst", ICC_VS>; // FIXME: Allow regalloc of the fcc condition code some day. class IntCMOVFCCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), - asmstr, + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, [(set IntRegs:$dst, (V8selectfcc IntRegs:$F, IntRegs:$T, CC, FCC))]> { int CondBits = CC.FCCVal; } + class IntCMOVFCCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + [(set IntRegs:$dst, + (V8selectfcc simm11:$F, IntRegs:$T, CC, FCC))]> { + int CondBits = CC.FCCVal; + } + // MOVF*rr instructions. def MOVFUrr : IntCMOVFCCrr< "movfu %fcc, $F, $dst", FCC_U>; def MOVFGrr : IntCMOVFCCrr< "movfg %fcc, $F, $dst", FCC_G>; def MOVFUGrr : IntCMOVFCCrr< "movfug %fcc, $F, $dst", FCC_UG>; @@ -849,6 +876,22 @@ def MOVFLErr : IntCMOVFCCrr< "movfle %fcc, $F, $dst", FCC_LE>; def MOVFULErr : IntCMOVFCCrr<"movfule %fcc, $F, $dst", FCC_ULE>; def MOVFOrr : IntCMOVFCCrr< "movfo %fcc, $F, $dst", FCC_O>; + + // MOVF*ri instructions. + def MOVFUri : IntCMOVFCCri< "movfu %fcc, $F, $dst", FCC_U>; + def MOVFGri : IntCMOVFCCri< "movfg %fcc, $F, $dst", FCC_G>; + def MOVFUGri : IntCMOVFCCri< "movfug %fcc, $F, $dst", FCC_UG>; + def MOVFLri : IntCMOVFCCri< "movfl %fcc, $F, $dst", FCC_L>; + def MOVFULri : IntCMOVFCCri< "movful %fcc, $F, $dst", FCC_UL>; + def MOVFLGri : IntCMOVFCCri< "movflg %fcc, $F, $dst", FCC_LG>; + def MOVFNEri : IntCMOVFCCri< "movfne %fcc, $F, $dst", FCC_NE>; + def MOVFEri : IntCMOVFCCri< "movfe %fcc, $F, $dst", FCC_E>; + def MOVFUEri : IntCMOVFCCri< "movfue %fcc, $F, $dst", FCC_UE>; + def MOVFGEri : IntCMOVFCCri< "movfge %fcc, $F, $dst", FCC_GE>; + def MOVFUGEri : IntCMOVFCCri<"movfuge %fcc, $F, $dst", FCC_UGE>; + def MOVFLEri : IntCMOVFCCri< "movfle %fcc, $F, $dst", FCC_LE>; + def MOVFULEri : IntCMOVFCCri<"movfule %fcc, $F, $dst", FCC_ULE>; + def MOVFOri : IntCMOVFCCri< "movfo %fcc, $F, $dst", FCC_O>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. From lattner at cs.uiuc.edu Tue Jan 31 00:49:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:49:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8.h SparcV8AsmPrinter.cpp SparcV8ISelDAGToDAG.cpp SparcV8InstrInfo.td Message-ID: <200601310649.AAA21375@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8.h updated: 1.8 -> 1.9 SparcV8AsmPrinter.cpp updated: 1.51 -> 1.52 SparcV8ISelDAGToDAG.cpp updated: 1.71 -> 1.72 SparcV8InstrInfo.td updated: 1.112 -> 1.113 --- Log message: compactify all of the integer conditional moves into one instruction that takes a CC as an operand. Much smaller, much happier. --- Diffs of the changes: (+144 -166) SparcV8.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++ SparcV8AsmPrinter.cpp | 8 +++ SparcV8ISelDAGToDAG.cpp | 77 -------------------------------- SparcV8InstrInfo.td | 113 ++++++++++-------------------------------------- 4 files changed, 144 insertions(+), 166 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8.h diff -u llvm/lib/Target/SparcV8/SparcV8.h:1.8 llvm/lib/Target/SparcV8/SparcV8.h:1.9 --- llvm/lib/Target/SparcV8/SparcV8.h:1.8 Mon Jan 23 01:20:15 2006 +++ llvm/lib/Target/SparcV8/SparcV8.h Tue Jan 31 00:49:09 2006 @@ -16,6 +16,7 @@ #define TARGET_SPARCV8_H #include +#include namespace llvm { @@ -28,7 +29,6 @@ TargetMachine &TM); FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM); - } // end namespace llvm; // Defines symbolic names for SparcV8 registers. This defines a mapping from @@ -40,4 +40,114 @@ // #include "SparcV8GenInstrNames.inc" + +namespace llvm { + // Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These + // values must be kept in sync with the ones in the .td file. + namespace V8CC { + enum CondCodes { + //ICC_A = 8 , // Always + //ICC_N = 0 , // Never + ICC_NE = 9 , // Not Equal + ICC_E = 1 , // Equal + ICC_G = 10 , // Greater + ICC_LE = 2 , // Less or Equal + ICC_GE = 11 , // Greater or Equal + ICC_L = 3 , // Less + ICC_GU = 12 , // Greater Unsigned + ICC_LEU = 4 , // Less or Equal Unsigned + ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned + ICC_CS = 5 , // Carry Set/Less Unsigned + ICC_POS = 14 , // Positive + ICC_NEG = 6 , // Negative + ICC_VC = 15 , // Overflow Clear + ICC_VS = 7 , // Overflow Set + + //FCC_A = 8+16, // Always + //FCC_N = 0+16, // Never + FCC_U = 7+16, // Unordered + FCC_G = 6+16, // Greater + FCC_UG = 5+16, // Unordered or Greater + FCC_L = 4+16, // Less + FCC_UL = 3+16, // Unordered or Less + FCC_LG = 2+16, // Less or Greater + FCC_NE = 1+16, // Not Equal + FCC_E = 9+16, // Equal + FCC_UE = 10+16, // Unordered or Equal + FCC_GE = 11+16, // Greater or Equal + FCC_UGE = 12+16, // Unordered or Greater or Equal + FCC_LE = 13+16, // Less or Equal + FCC_ULE = 14+16, // Unordered or Less or Equal + FCC_O = 15+16, // Ordered + }; + } + + static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return V8::BNE; + case V8CC::ICC_E: return V8::BE; + case V8CC::ICC_G: return V8::BG; + case V8CC::ICC_LE: return V8::BLE; + case V8CC::ICC_GE: return V8::BGE; + case V8CC::ICC_L: return V8::BL; + case V8CC::ICC_GU: return V8::BGU; + case V8CC::ICC_LEU: return V8::BLEU; + case V8CC::ICC_CC: return V8::BCC; + case V8CC::ICC_CS: return V8::BCS; + case V8CC::ICC_POS: return V8::BPOS; + case V8CC::ICC_NEG: return V8::BNEG; + case V8CC::ICC_VC: return V8::BVC; + case V8CC::ICC_VS: return V8::BVS; + case V8CC::FCC_U: return V8::FBU; + case V8CC::FCC_G: return V8::FBG; + case V8CC::FCC_UG: return V8::FBUG; + case V8CC::FCC_L: return V8::FBL; + case V8CC::FCC_UL: return V8::FBUL; + case V8CC::FCC_LG: return V8::FBLG; + case V8CC::FCC_NE: return V8::FBNE; + case V8CC::FCC_E: return V8::FBE; + case V8CC::FCC_UE: return V8::FBUE; + case V8CC::FCC_GE: return V8::FBGE; + case V8CC::FCC_UGE: return V8::FBUGE; + case V8CC::FCC_LE: return V8::FBLE; + case V8CC::FCC_ULE: return V8::FBULE; + case V8CC::FCC_O: return V8::FBO; + } + } + + static const char *SPARCCondCodeToString(V8CC::CondCodes CC) { + switch (CC) { + default: assert(0 && "Unknown condition code"); + case V8CC::ICC_NE: return "ne"; + case V8CC::ICC_E: return "e"; + case V8CC::ICC_G: return "g"; + case V8CC::ICC_LE: return "le"; + case V8CC::ICC_GE: return "ge"; + case V8CC::ICC_L: return "l"; + case V8CC::ICC_GU: return "gu"; + case V8CC::ICC_LEU: return "leu"; + case V8CC::ICC_CC: return "cc"; + case V8CC::ICC_CS: return "cs"; + case V8CC::ICC_POS: return "pos"; + case V8CC::ICC_NEG: return "neg"; + case V8CC::ICC_VC: return "vc"; + case V8CC::ICC_VS: return "vs"; + case V8CC::FCC_U: return "u"; + case V8CC::FCC_G: return "g"; + case V8CC::FCC_UG: return "ug"; + case V8CC::FCC_L: return "l"; + case V8CC::FCC_UL: return "ul"; + case V8CC::FCC_LG: return "lg"; + case V8CC::FCC_NE: return "ne"; + case V8CC::FCC_E: return "e"; + case V8CC::FCC_UE: return "ue"; + case V8CC::FCC_GE: return "ge"; + case V8CC::FCC_UGE: return "uge"; + case V8CC::FCC_LE: return "le"; + case V8CC::FCC_ULE: return "ule"; + case V8CC::FCC_O: return "o"; + } + } +} // end namespace llvm #endif Index: llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp diff -u llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp:1.51 llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp:1.52 --- llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp:1.51 Sun Jan 22 17:37:17 2006 +++ llvm/lib/Target/SparcV8/SparcV8AsmPrinter.cpp Tue Jan 31 00:49:09 2006 @@ -58,6 +58,8 @@ void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum); + void printV8CCOperand(const MachineInstr *MI, int opNum); + bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); @@ -211,6 +213,12 @@ } } +void SparcV8AsmPrinter::printV8CCOperand(const MachineInstr *MI, int opNum) { + int CC = (int)MI->getOperand(opNum).getImmedValue(); + O << SPARCCondCodeToString((V8CC::CondCodes)CC); +} + + bool SparcV8AsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.71 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.72 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.71 Mon Jan 30 23:05:52 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Tue Jan 31 00:49:09 2006 @@ -50,47 +50,6 @@ }; } -// Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These -// values must be kept in sync with the ones in the .td file. -namespace V8CC { - enum CondCodes { - //ICC_A = 8 , // Always - //ICC_N = 0 , // Never - ICC_NE = 9 , // Not Equal - ICC_E = 1 , // Equal - ICC_G = 10 , // Greater - ICC_LE = 2 , // Less or Equal - ICC_GE = 11 , // Greater or Equal - ICC_L = 3 , // Less - ICC_GU = 12 , // Greater Unsigned - ICC_LEU = 4 , // Less or Equal Unsigned - ICC_CC = 13 , // Carry Clear/Great or Equal Unsigned - ICC_CS = 5 , // Carry Set/Less Unsigned - ICC_POS = 14 , // Positive - ICC_NEG = 6 , // Negative - ICC_VC = 15 , // Overflow Clear - ICC_VS = 7 , // Overflow Set - - //FCC_A = 8+16, // Always - //FCC_N = 0+16, // Never - FCC_U = 7+16, // Unordered - FCC_G = 6+16, // Greater - FCC_UG = 5+16, // Unordered or Greater - FCC_L = 4+16, // Less - FCC_UL = 3+16, // Unordered or Less - FCC_LG = 2+16, // Less or Greater - FCC_NE = 1+16, // Not Equal - FCC_E = 9+16, // Equal - FCC_UE = 10+16, // Unordered or Equal - FCC_GE = 11+16, // Greater or Equal - FCC_UGE = 12+16, // Unordered or Greater or Equal - FCC_LE = 13+16, // Less or Equal - FCC_ULE = 14+16, // Unordered or Less or Equal - FCC_O = 15+16, // Ordered - }; -} - - /// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC /// condition. static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { @@ -130,42 +89,6 @@ case ISD::SETUEQ: return V8CC::FCC_UE; } } - - -static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { - switch (CC) { - default: assert(0 && "Unknown condition code"); - case V8CC::ICC_NE: return V8::BNE; - case V8CC::ICC_E: return V8::BE; - case V8CC::ICC_G: return V8::BG; - case V8CC::ICC_LE: return V8::BLE; - case V8CC::ICC_GE: return V8::BGE; - case V8CC::ICC_L: return V8::BL; - case V8CC::ICC_GU: return V8::BGU; - case V8CC::ICC_LEU: return V8::BLEU; - case V8CC::ICC_CC: return V8::BCC; - case V8CC::ICC_CS: return V8::BCS; - case V8CC::ICC_POS: return V8::BPOS; - case V8CC::ICC_NEG: return V8::BNEG; - case V8CC::ICC_VC: return V8::BVC; - case V8CC::ICC_VS: return V8::BVS; - case V8CC::FCC_U: return V8::FBU; - case V8CC::FCC_G: return V8::FBG; - case V8CC::FCC_UG: return V8::FBUG; - case V8CC::FCC_L: return V8::FBL; - case V8CC::FCC_UL: return V8::FBUL; - case V8CC::FCC_LG: return V8::FBLG; - case V8CC::FCC_NE: return V8::FBNE; - case V8CC::FCC_E: return V8::FBE; - case V8CC::FCC_UE: return V8::FBUE; - case V8CC::FCC_GE: return V8::FBGE; - case V8CC::FCC_UGE: return V8::FBUGE; - case V8CC::FCC_LE: return V8::FBLE; - case V8CC::FCC_ULE: return V8::FBULE; - case V8CC::FCC_O: return V8::FBO; - } -} - namespace { class SparcV8TargetLowering : public TargetLowering { Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.112 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.113 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.112 Tue Jan 31 00:24:29 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Tue Jan 31 00:49:09 2006 @@ -86,6 +86,10 @@ def brtarget : Operand; def calltarget : Operand; +// Operand for printing out a condition code. +let PrintMethod = "printV8CCOperand" in + def V8CC : Operand; + def SDTV8cmpfcc : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>; def SDTV8brcc : @@ -212,12 +216,14 @@ : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F, - imm:$Cond, ICC))]>; + imm:$Cond, ICC))]>, + Requires<[HasNoV9]>; def SELECT_CC_Int_FCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_FCC PSEUDO!", [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F, - imm:$Cond, FCC))]>; + imm:$Cond, FCC))]>, + Requires<[HasNoV9]>; def SELECT_CC_FP_ICC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", @@ -802,96 +808,27 @@ let Predicates = [HasV9], isTwoAddress = 1 in { // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. // FIXME: Add instruction encodings for the JIT some day. - class IntCMOVICCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + def MOVICCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - class IntCMOVICCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>; + def MOVICCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc simm11:$F, IntRegs:$T, CC, ICC))]> { - int CondBits = CC.ICCVal; - } - - // MOV*rr instructions. - def MOVNErr : IntCMOVICCrr< "movne %icc, $F, $dst", ICC_NE>; - def MOVErr : IntCMOVICCrr< "move %icc, $F, $dst", ICC_E>; - def MOVGrr : IntCMOVICCrr< "movg %icc, $F, $dst", ICC_G>; - def MOVLErr : IntCMOVICCrr< "movle %icc, $F, $dst", ICC_LE>; - def MOVGErr : IntCMOVICCrr< "movge %icc, $F, $dst", ICC_GE>; - def MOVLrr : IntCMOVICCrr< "movl %icc, $F, $dst", ICC_L>; - def MOVGUrr : IntCMOVICCrr< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUrr : IntCMOVICCrr<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCrr : IntCMOVICCrr< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSrr : IntCMOVICCrr< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSrr : IntCMOVICCrr<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGrr : IntCMOVICCrr<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCrr : IntCMOVICCrr< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSrr : IntCMOVICCrr< "movvs %icc, $F, $dst", ICC_VS>; - - // MOV*ri instructions. - def MOVNEri : IntCMOVICCri< "movne %icc, $F, $dst", ICC_NE>; - def MOVEri : IntCMOVICCri< "move %icc, $F, $dst", ICC_E>; - def MOVGri : IntCMOVICCri< "movg %icc, $F, $dst", ICC_G>; - def MOVLEri : IntCMOVICCri< "movle %icc, $F, $dst", ICC_LE>; - def MOVGEri : IntCMOVICCri< "movge %icc, $F, $dst", ICC_GE>; - def MOVLri : IntCMOVICCri< "movl %icc, $F, $dst", ICC_L>; - def MOVGUri : IntCMOVICCri< "movgu %icc, $F, $dst", ICC_GU>; - def MOVLEUri : IntCMOVICCri<"movleu %icc, $F, $dst", ICC_LEU>; - def MOVCCri : IntCMOVICCri< "movcc %icc, $F, $dst", ICC_CC>; - def MOVCSri : IntCMOVICCri< "movcs %icc, $F, $dst", ICC_CS>; - def MOVPOSri : IntCMOVICCri<"movpos %icc, $F, $dst", ICC_POS>; - def MOVNEGri : IntCMOVICCri<"movneg %icc, $F, $dst", ICC_NEG>; - def MOVVCri : IntCMOVICCri< "movvc %icc, $F, $dst", ICC_VC>; - def MOVVSri : IntCMOVICCri< "movvs %icc, $F, $dst", ICC_VS>; - - // FIXME: Allow regalloc of the fcc condition code some day. - class IntCMOVFCCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F), asmstr, + (V8selecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>; + + def MOVFCCrr + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - class IntCMOVFCCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F), asmstr, + (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; + def MOVFCCri + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc simm11:$F, IntRegs:$T, CC, FCC))]> { - int CondBits = CC.FCCVal; - } - - // MOVF*rr instructions. - def MOVFUrr : IntCMOVFCCrr< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGrr : IntCMOVFCCrr< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGrr : IntCMOVFCCrr< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLrr : IntCMOVFCCrr< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULrr : IntCMOVFCCrr< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGrr : IntCMOVFCCrr< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNErr : IntCMOVFCCrr< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFErr : IntCMOVFCCrr< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUErr : IntCMOVFCCrr< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGErr : IntCMOVFCCrr< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGErr : IntCMOVFCCrr<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLErr : IntCMOVFCCrr< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULErr : IntCMOVFCCrr<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOrr : IntCMOVFCCrr< "movfo %fcc, $F, $dst", FCC_O>; - - // MOVF*ri instructions. - def MOVFUri : IntCMOVFCCri< "movfu %fcc, $F, $dst", FCC_U>; - def MOVFGri : IntCMOVFCCri< "movfg %fcc, $F, $dst", FCC_G>; - def MOVFUGri : IntCMOVFCCri< "movfug %fcc, $F, $dst", FCC_UG>; - def MOVFLri : IntCMOVFCCri< "movfl %fcc, $F, $dst", FCC_L>; - def MOVFULri : IntCMOVFCCri< "movful %fcc, $F, $dst", FCC_UL>; - def MOVFLGri : IntCMOVFCCri< "movflg %fcc, $F, $dst", FCC_LG>; - def MOVFNEri : IntCMOVFCCri< "movfne %fcc, $F, $dst", FCC_NE>; - def MOVFEri : IntCMOVFCCri< "movfe %fcc, $F, $dst", FCC_E>; - def MOVFUEri : IntCMOVFCCri< "movfue %fcc, $F, $dst", FCC_UE>; - def MOVFGEri : IntCMOVFCCri< "movfge %fcc, $F, $dst", FCC_GE>; - def MOVFUGEri : IntCMOVFCCri<"movfuge %fcc, $F, $dst", FCC_UGE>; - def MOVFLEri : IntCMOVFCCri< "movfle %fcc, $F, $dst", FCC_LE>; - def MOVFULEri : IntCMOVFCCri<"movfule %fcc, $F, $dst", FCC_ULE>; - def MOVFOri : IntCMOVFCCri< "movfo %fcc, $F, $dst", FCC_O>; + (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; } // Floating-Point Move Instructions, p. 164 of the V9 manual. From lattner at cs.uiuc.edu Tue Jan 31 00:56:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 00:56:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8.h SparcV8ISelDAGToDAG.cpp SparcV8InstrInfo.td Message-ID: <200601310656.AAA21461@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8.h updated: 1.9 -> 1.10 SparcV8ISelDAGToDAG.cpp updated: 1.72 -> 1.73 SparcV8InstrInfo.td updated: 1.113 -> 1.114 --- Log message: treat conditional branches the same way as conditional moves (giving them an operand that contains the condcode), making things significantly simpler. --- Diffs of the changes: (+17 -129) SparcV8.h | 34 --------------- SparcV8ISelDAGToDAG.cpp | 9 ++-- SparcV8InstrInfo.td | 103 +++++------------------------------------------- 3 files changed, 17 insertions(+), 129 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8.h diff -u llvm/lib/Target/SparcV8/SparcV8.h:1.9 llvm/lib/Target/SparcV8/SparcV8.h:1.10 --- llvm/lib/Target/SparcV8/SparcV8.h:1.9 Tue Jan 31 00:49:09 2006 +++ llvm/lib/Target/SparcV8/SparcV8.h Tue Jan 31 00:56:30 2006 @@ -82,40 +82,6 @@ }; } - static unsigned SPARCCondCodeToBranchInstr(V8CC::CondCodes CC) { - switch (CC) { - default: assert(0 && "Unknown condition code"); - case V8CC::ICC_NE: return V8::BNE; - case V8CC::ICC_E: return V8::BE; - case V8CC::ICC_G: return V8::BG; - case V8CC::ICC_LE: return V8::BLE; - case V8CC::ICC_GE: return V8::BGE; - case V8CC::ICC_L: return V8::BL; - case V8CC::ICC_GU: return V8::BGU; - case V8CC::ICC_LEU: return V8::BLEU; - case V8CC::ICC_CC: return V8::BCC; - case V8CC::ICC_CS: return V8::BCS; - case V8CC::ICC_POS: return V8::BPOS; - case V8CC::ICC_NEG: return V8::BNEG; - case V8CC::ICC_VC: return V8::BVC; - case V8CC::ICC_VS: return V8::BVS; - case V8CC::FCC_U: return V8::FBU; - case V8CC::FCC_G: return V8::FBG; - case V8CC::FCC_UG: return V8::FBUG; - case V8CC::FCC_L: return V8::FBL; - case V8CC::FCC_UL: return V8::FBUL; - case V8CC::FCC_LG: return V8::FBLG; - case V8CC::FCC_NE: return V8::FBNE; - case V8CC::FCC_E: return V8::FBE; - case V8CC::FCC_UE: return V8::FBUE; - case V8CC::FCC_GE: return V8::FBGE; - case V8CC::FCC_UGE: return V8::FBUGE; - case V8CC::FCC_LE: return V8::FBLE; - case V8CC::FCC_ULE: return V8::FBULE; - case V8CC::FCC_O: return V8::FBO; - } - } - static const char *SPARCCondCodeToString(V8CC::CondCodes CC) { switch (CC) { default: assert(0 && "Unknown condition code"); Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.72 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.73 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.72 Tue Jan 31 00:49:09 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Tue Jan 31 00:56:30 2006 @@ -817,19 +817,22 @@ SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *BB) { unsigned BROpcode; + unsigned CC; // Figure out the conditional branch opcode to use for this select_cc. switch (MI->getOpcode()) { default: assert(0 && "Unknown SELECT_CC!"); case V8::SELECT_CC_Int_ICC: case V8::SELECT_CC_FP_ICC: case V8::SELECT_CC_DFP_ICC: + BROpcode = V8::BCOND; case V8::SELECT_CC_Int_FCC: case V8::SELECT_CC_FP_FCC: case V8::SELECT_CC_DFP_FCC: - V8CC::CondCodes CC = (V8CC::CondCodes)MI->getOperand(3).getImmedValue(); - BROpcode = SPARCCondCodeToBranchInstr(CC); + BROpcode = V8::FBCOND; break; } + + CC = (V8CC::CondCodes)MI->getOperand(3).getImmedValue(); // To "insert" a SELECT_CC instruction, we actually have to insert the diamond // control-flow pattern. The incoming instruction knows the destination vreg @@ -847,7 +850,7 @@ MachineBasicBlock *thisMBB = BB; MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); - BuildMI(BB, BROpcode, 1).addMBB(sinkMBB); + BuildMI(BB, BROpcode, 2).addMBB(sinkMBB).addImm(CC); MachineFunction *F = BB->getParent(); F->getBasicBlockList().insert(It, copy0MBB); F->getBasicBlockList().insert(It, sinkMBB); Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.113 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.114 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.113 Tue Jan 31 00:49:09 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Tue Jan 31 00:56:30 2006 @@ -136,9 +136,7 @@ // Note that these values must be kept in sync with the V8CC::CondCode enum // values. -class ICC_VAL : PatLeaf<(i32 N)> { - int ICCVal = N; -} +class ICC_VAL : PatLeaf<(i32 N)>; def ICC_NE : ICC_VAL< 9>; // Not Equal def ICC_E : ICC_VAL< 1>; // Equal def ICC_G : ICC_VAL<10>; // Greater @@ -154,9 +152,7 @@ def ICC_VC : ICC_VAL<15>; // Overflow Clear def ICC_VS : ICC_VAL< 7>; // Overflow Set -class FCC_VAL : PatLeaf<(i32 N)> { - int FCCVal = N; -} +class FCC_VAL : PatLeaf<(i32 N)>; def FCC_U : FCC_VAL<23>; // Unordered def FCC_G : FCC_VAL<22>; // Greater def FCC_UG : FCC_VAL<21>; // Unordered or Greater @@ -550,49 +546,11 @@ def BA : BranchV8<0b1000, (ops brtarget:$dst), "ba $dst", [(br bb:$dst)]>; -def BNE : BranchV8<0b1001, (ops brtarget:$dst), - "bne $dst", - [(V8bricc bb:$dst, ICC_NE, ICC)]>; -def BE : BranchV8<0b0001, (ops brtarget:$dst), - "be $dst", - [(V8bricc bb:$dst, ICC_E, ICC)]>; -def BG : BranchV8<0b1010, (ops brtarget:$dst), - "bg $dst", - [(V8bricc bb:$dst, ICC_G, ICC)]>; -def BLE : BranchV8<0b0010, (ops brtarget:$dst), - "ble $dst", - [(V8bricc bb:$dst, ICC_LE, ICC)]>; -def BGE : BranchV8<0b1011, (ops brtarget:$dst), - "bge $dst", - [(V8bricc bb:$dst, ICC_GE, ICC)]>; -def BL : BranchV8<0b0011, (ops brtarget:$dst), - "bl $dst", - [(V8bricc bb:$dst, ICC_L, ICC)]>; -def BGU : BranchV8<0b1100, (ops brtarget:$dst), - "bgu $dst", - [(V8bricc bb:$dst, ICC_GU, ICC)]>; -def BLEU : BranchV8<0b0100, (ops brtarget:$dst), - "bleu $dst", - [(V8bricc bb:$dst, ICC_LEU, ICC)]>; -def BCC : BranchV8<0b1101, (ops brtarget:$dst), - "bcc $dst", - [(V8bricc bb:$dst, ICC_CC, ICC)]>; -def BCS : BranchV8<0b0101, (ops brtarget:$dst), - "bcs $dst", - [(V8bricc bb:$dst, ICC_CS, ICC)]>; -def BPOS : BranchV8<0b1110, (ops brtarget:$dst), - "bpos $dst", - [(V8bricc bb:$dst, ICC_POS, ICC)]>; -def BNEG : BranchV8<0b0110, (ops brtarget:$dst), - "bneg $dst", - [(V8bricc bb:$dst, ICC_NEG, ICC)]>; -def BVC : BranchV8<0b1111, (ops brtarget:$dst), - "bvc $dst", - [(V8bricc bb:$dst, ICC_VC, ICC)]>; -def BVS : BranchV8<0b0111, (ops brtarget:$dst), - "bvs $dst", - [(V8bricc bb:$dst, ICC_VS, ICC)]>; - + +// FIXME: the encoding for the JIT should look at the condition field. +def BCOND : BranchV8<0, (ops brtarget:$dst, V8CC:$cc), + "b$cc $dst", + [(V8bricc bb:$dst, imm:$cc, ICC)]>; // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 @@ -606,49 +564,10 @@ let noResults = 1; } -def FBU : FPBranchV8<0b0111, (ops brtarget:$dst), - "fbu $dst", - [(V8brfcc bb:$dst, FCC_U, FCC)]>; -def FBG : FPBranchV8<0b0110, (ops brtarget:$dst), - "fbg $dst", - [(V8brfcc bb:$dst, FCC_G, FCC)]>; -def FBUG : FPBranchV8<0b0101, (ops brtarget:$dst), - "fbug $dst", - [(V8brfcc bb:$dst, FCC_UG, FCC)]>; -def FBL : FPBranchV8<0b0100, (ops brtarget:$dst), - "fbl $dst", - [(V8brfcc bb:$dst, FCC_L, FCC)]>; -def FBUL : FPBranchV8<0b0011, (ops brtarget:$dst), - "fbul $dst", - [(V8brfcc bb:$dst, FCC_UL, FCC)]>; -def FBLG : FPBranchV8<0b0010, (ops brtarget:$dst), - "fblg $dst", - [(V8brfcc bb:$dst, FCC_LG, FCC)]>; -def FBNE : FPBranchV8<0b0001, (ops brtarget:$dst), - "fbne $dst", - [(V8brfcc bb:$dst, FCC_NE, FCC)]>; -def FBE : FPBranchV8<0b1001, (ops brtarget:$dst), - "fbe $dst", - [(V8brfcc bb:$dst, FCC_E, FCC)]>; -def FBUE : FPBranchV8<0b1010, (ops brtarget:$dst), - "fbue $dst", - [(V8brfcc bb:$dst, FCC_UE, FCC)]>; -def FBGE : FPBranchV8<0b1011, (ops brtarget:$dst), - "fbge $dst", - [(V8brfcc bb:$dst, FCC_GE, FCC)]>; -def FBUGE: FPBranchV8<0b1100, (ops brtarget:$dst), - "fbuge $dst", - [(V8brfcc bb:$dst, FCC_UGE, FCC)]>; -def FBLE : FPBranchV8<0b1101, (ops brtarget:$dst), - "fble $dst", - [(V8brfcc bb:$dst, FCC_LE, FCC)]>; -def FBULE: FPBranchV8<0b1110, (ops brtarget:$dst), - "fbule $dst", - [(V8brfcc bb:$dst, FCC_ULE, FCC)]>; -def FBO : FPBranchV8<0b1111, (ops brtarget:$dst), - "fbo $dst", - [(V8brfcc bb:$dst, FCC_O, FCC)]>; - +// FIXME: the encoding for the JIT should look at the condition field. +def FBCOND : FPBranchV8<0, (ops brtarget:$dst, V8CC:$cc), + "f$cc $dst", + [(V8brfcc bb:$dst, imm:$cc, FCC)]>; // Section B.24 - Call and Link Instruction, p. 125 From lattner at cs.uiuc.edu Tue Jan 31 01:16:46 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:16:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200601310716.BAA21638@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.49 -> 1.50 --- Log message: example nate pointed out --- Diffs of the changes: (+33 -0) README.txt | 33 +++++++++++++++++++++++++++++++++ 1 files changed, 33 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.49 llvm/lib/Target/PowerPC/README.txt:1.50 --- llvm/lib/Target/PowerPC/README.txt:1.49 Mon Jan 30 20:55:28 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Jan 31 01:16:34 2006 @@ -427,3 +427,36 @@ without the lwz/stw's. +===-------------------------------------------------------------------------=== + +Compile this: + +int foo(int a) { + int b = (a < 8); + if (b) { + return b * 3; // ignore the fact that this is always 3. + } else { + return 2; + } +} + +into something not this: + +_foo: +1) cmpwi cr7, r3, 8 + mfcr r2, 1 + rlwinm r2, r2, 29, 31, 31 +1) cmpwi cr0, r3, 7 + bgt cr0, LBB1_2 ; UnifiedReturnBlock +LBB1_1: ; then + rlwinm r2, r2, 0, 31, 31 + mulli r3, r2, 3 + blr +LBB1_2: ; UnifiedReturnBlock + li r3, 2 + blr + +In particular, the two compares (marked 1) could be shared by reversing one. +This could be done in the dag combiner, by swapping a BR_CC when a SETCC of the +same operands (but backwards) exists. In this case, this wouldn't save us +anything though, because the compares still wouldn't be shared. From lattner at cs.uiuc.edu Tue Jan 31 01:27:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:27:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200601310727.BAA21722@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.114 -> 1.115 --- Log message: add conditional moves of float and double values on int/fp condition codes. --- Diffs of the changes: (+27 -6) SparcV8InstrInfo.td | 33 +++++++++++++++++++++++++++------ 1 files changed, 27 insertions(+), 6 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.114 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.115 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.114 Tue Jan 31 00:56:30 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Tue Jan 31 01:26:55 2006 @@ -207,19 +207,18 @@ // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. This has to handle all permutations of // selection between i32/f32/f64 on ICC and FCC. -let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. +let usesCustomDAGSchedInserter = 1, // Expanded by the scheduler. + Predicates = [HasNoV9] in { // V9 has conditional moves def SELECT_CC_Int_ICC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F, - imm:$Cond, ICC))]>, - Requires<[HasNoV9]>; + imm:$Cond, ICC))]>; def SELECT_CC_Int_FCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_FCC PSEUDO!", [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F, - imm:$Cond, FCC))]>, - Requires<[HasNoV9]>; + imm:$Cond, FCC))]>; def SELECT_CC_FP_ICC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", @@ -566,7 +565,7 @@ // FIXME: the encoding for the JIT should look at the condition field. def FBCOND : FPBranchV8<0, (ops brtarget:$dst, V8CC:$cc), - "f$cc $dst", + "fb$cc $dst", [(V8brfcc bb:$dst, imm:$cc, FCC)]>; @@ -748,6 +747,28 @@ "movf$cc %fcc, $F, $dst", [(set IntRegs:$dst, (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; + + def FMOVS_ICC + : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, V8CC:$cc), + "fmovs$cc %icc, $F, $dst", + [(set FPRegs:$dst, + (V8selecticc FPRegs:$F, FPRegs:$T, imm:$cc, ICC))]>; + def FMOVD_ICC + : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, V8CC:$cc), + "fmovd$cc %icc, $F, $dst", + [(set DFPRegs:$dst, + (V8selecticc DFPRegs:$F, DFPRegs:$T, imm:$cc, ICC))]>; + def FMOVS_FCC + : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, V8CC:$cc), + "fmovs$cc %fcc, $F, $dst", + [(set FPRegs:$dst, + (V8selectfcc FPRegs:$F, FPRegs:$T, imm:$cc, FCC))]>; + def FMOVD_FCC + : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, V8CC:$cc), + "fmovd$cc %fcc, $F, $dst", + [(set DFPRegs:$dst, + (V8selectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc, FCC))]>; + } // Floating-Point Move Instructions, p. 164 of the V9 manual. From lattner at cs.uiuc.edu Tue Jan 31 01:37:32 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:37:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200601310737.BAA21784@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.43 -> 1.44 --- Log message: add a note --- Diffs of the changes: (+29 -0) README.txt | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.43 llvm/lib/Target/SparcV8/README.txt:1.44 --- llvm/lib/Target/SparcV8/README.txt:1.43 Sun Jan 29 23:35:57 2006 +++ llvm/lib/Target/SparcV8/README.txt Tue Jan 31 01:37:20 2006 @@ -7,4 +7,33 @@ * We can fold small constant offsets into the %hi/%lo references to constant pool addresses as well. * When in V9 mode, register allocate %icc[0-3]. +* Emit the 'Branch on Integer Register with Prediction' instructions. It's + not clear how to write a pattern for this though: + +float %t1(int %a, int* %p) { + %C = seteq int %a, 0 + br bool %C, label %T, label %F +T: + store int 123, int* %p + br label %F +F: + ret float undef +} + +codegens to this: + +t1: + save -96, %o6, %o6 +1) subcc %i0, 0, %l0 +1) bne .LBBt1_2 ! F + nop +.LBBt1_1: ! T + or %g0, 123, %l0 + st %l0, [%i1] +.LBBt1_2: ! F + restore %g0, %g0, %g0 + retl + nop + +1) should be replaced with a brz in V9 mode. From lattner at cs.uiuc.edu Tue Jan 31 01:38:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:38:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200601310738.BAA21817@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.44 -> 1.45 --- Log message: another one --- Diffs of the changes: (+1 -0) README.txt | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.44 llvm/lib/Target/SparcV8/README.txt:1.45 --- llvm/lib/Target/SparcV8/README.txt:1.44 Tue Jan 31 01:37:20 2006 +++ llvm/lib/Target/SparcV8/README.txt Tue Jan 31 01:38:32 2006 @@ -37,3 +37,4 @@ 1) should be replaced with a brz in V9 mode. +* Same as above, but emit conditional move on register zero (p192) in V9 mode. From lattner at cs.uiuc.edu Tue Jan 31 01:43:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:43:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200601310743.BAA21861@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.45 -> 1.46 --- Log message: More notes --- Diffs of the changes: (+15 -1) README.txt | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.45 llvm/lib/Target/SparcV8/README.txt:1.46 --- llvm/lib/Target/SparcV8/README.txt:1.45 Tue Jan 31 01:38:32 2006 +++ llvm/lib/Target/SparcV8/README.txt Tue Jan 31 01:43:33 2006 @@ -37,4 +37,18 @@ 1) should be replaced with a brz in V9 mode. -* Same as above, but emit conditional move on register zero (p192) in V9 mode. +* Same as above, but emit conditional move on register zero (p192) in V9 + mode. Testcase: + +int %t1(int %a, int %b) { + %C = seteq int %a, 0 + %D = select bool %C, int %a, int %b + ret int %D +} + +* Emit MULX/[SU]DIVX instructions in V9 mode instead of fiddling + with the Y register, if they are faster. + +* Codegen bswap(load)/store(bswap) -> load/store ASI + + From lattner at cs.uiuc.edu Tue Jan 31 01:45:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:45:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200601310745.BAA21900@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.46 -> 1.47 --- Log message: another note --- Diffs of the changes: (+2 -1) README.txt | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.46 llvm/lib/Target/SparcV8/README.txt:1.47 --- llvm/lib/Target/SparcV8/README.txt:1.46 Tue Jan 31 01:43:33 2006 +++ llvm/lib/Target/SparcV8/README.txt Tue Jan 31 01:45:08 2006 @@ -51,4 +51,5 @@ * Codegen bswap(load)/store(bswap) -> load/store ASI - +* Implement frame pointer elimination, e.g. eliminate save/restore for + leaf fns. From lattner at cs.uiuc.edu Tue Jan 31 01:45:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 01:45:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200601310745.BAA21933@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.47 -> 1.48 --- Log message: okay, one more --- Diffs of the changes: (+2 -0) README.txt | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.47 llvm/lib/Target/SparcV8/README.txt:1.48 --- llvm/lib/Target/SparcV8/README.txt:1.47 Tue Jan 31 01:45:08 2006 +++ llvm/lib/Target/SparcV8/README.txt Tue Jan 31 01:45:45 2006 @@ -53,3 +53,5 @@ * Implement frame pointer elimination, e.g. eliminate save/restore for leaf fns. +* Fill delay slots + From natebegeman at mac.com Tue Jan 31 02:17:41 2006 From: natebegeman at mac.com (Nate Begeman) Date: Tue, 31 Jan 2006 02:17:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200601310817.CAA26210@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.80 -> 1.81 --- Log message: Codegen bool %test(int %X) { %Y = seteq int %X, 13 ret bool %Y } as _test: addi r2, r3, -13 cntlzw r2, r2 srwi r3, r2, 5 blr rather than _test: cmpwi cr7, r3, 13 mfcr r2 rlwinm r3, r2, 31, 31, 31 blr This has very little effect on most code, but speeds up analyzer 23% and mason 11% --- Diffs of the changes: (+16 -0) PPCISelLowering.cpp | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.80 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.81 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.80 Sun Jan 29 14:49:17 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Jan 31 02:17:29 2006 @@ -83,6 +83,9 @@ // PowerPC wants to turn select_cc of FP into fsel when possible. setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); + + // PowerPC wants to optimize setcc i32, imm a bit. + setOperationAction(ISD::SETCC, MVT::i32, Custom); // PowerPC does not have BRCOND* which requires SetCC setOperationAction(ISD::BRCOND, MVT::Other, Expand); @@ -445,6 +448,19 @@ // resolution stub. return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0)); } + case ISD::SETCC: { + ISD::CondCode CC = cast(Op.getOperand(2))->get(); + if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) + if (C->getValue() && !C->isAllOnesValue()) + if (CC == ISD::SETEQ || CC == ISD::SETNE || + CC == ISD::SETLT || CC == ISD::SETGT) { + MVT::ValueType VT = Op.getValueType(); + SDOperand SUB = DAG.getNode(ISD::SUB, Op.getOperand(0).getValueType(), + Op.getOperand(0), Op.getOperand(1)); + return DAG.getSetCC(VT, SUB, DAG.getConstant(0, VT), CC); + } + break; + } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. From lattner at cs.uiuc.edu Tue Jan 31 10:09:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 10:09:58 -0600 Subject: [llvm-commits] CVS: llvm-www/testresults/index.html Message-ID: <200601311609.KAA02064@zion.cs.uiuc.edu> Changes in directory llvm-www/testresults: index.html updated: 1.40 -> 1.41 --- Log message: add v8 tester --- Diffs of the changes: (+3 -1) index.html | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-) Index: llvm-www/testresults/index.html diff -u llvm-www/testresults/index.html:1.40 llvm-www/testresults/index.html:1.41 --- llvm-www/testresults/index.html:1.40 Mon Nov 7 10:23:24 2005 +++ llvm-www/testresults/index.html Tue Jan 31 10:09:35 2006 @@ -48,8 +48,10 @@

Sparc V9

    +
  1. SunOS 5.8 on +Sun Fire V240 (dual 1Ghz CPU) -- debug build ("V8" backend)
  2. SunOS 5.8 on Sun Fire V240 (dual 1Ghz CPU) -- debug -build
  3. +build (dead)

X86

From lattner at cs.uiuc.edu Tue Jan 31 10:11:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 10:11:05 -0600 Subject: [llvm-commits] CVS: llvm/utils/NightlyTest.pl Message-ID: <200601311611.KAA02102@zion.cs.uiuc.edu> Changes in directory llvm/utils: NightlyTest.pl updated: 1.101 -> 1.102 --- Log message: solaris won't clobber an existing symlink with ln -sf apparently --- Diffs of the changes: (+4 -1) NightlyTest.pl | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/utils/NightlyTest.pl diff -u llvm/utils/NightlyTest.pl:1.101 llvm/utils/NightlyTest.pl:1.102 --- llvm/utils/NightlyTest.pl:1.101 Sun Dec 11 13:55:39 2005 +++ llvm/utils/NightlyTest.pl Tue Jan 31 10:10:53 2006 @@ -847,7 +847,10 @@ my $TestPlatform = `uname -a`; eval "\$Output = < Changes in directory llvm-test/SingleSource/Benchmarks/Misc-C++: mandel-text.cpp updated: 1.1 -> 1.2 --- Log message: allow this test to pass on x86 --- Diffs of the changes: (+5 -0) mandel-text.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm-test/SingleSource/Benchmarks/Misc-C++/mandel-text.cpp diff -u llvm-test/SingleSource/Benchmarks/Misc-C++/mandel-text.cpp:1.1 llvm-test/SingleSource/Benchmarks/Misc-C++/mandel-text.cpp:1.2 --- llvm-test/SingleSource/Benchmarks/Misc-C++/mandel-text.cpp:1.1 Sat Sep 24 23:39:49 2005 +++ llvm-test/SingleSource/Benchmarks/Misc-C++/mandel-text.cpp Tue Jan 31 10:39:37 2006 @@ -47,6 +47,11 @@ } } +/* NOTE: This has been disabled, due to fp-precision sensitivity. This test + is effectively now just a performance test, not a correctness test. */ + if (n < 100000) + putchar('X'); + else if (bInside) putchar(' '); else if (n > 4) From lattner at cs.uiuc.edu Tue Jan 31 11:20:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 11:20:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601311720.LAA02546@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.73 -> 1.74 --- Log message: add a missing break that caused a lot of failures last night :( --- Diffs of the changes: (+1 -0) SparcV8ISelDAGToDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.73 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.74 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.73 Tue Jan 31 00:56:30 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Tue Jan 31 11:20:06 2006 @@ -825,6 +825,7 @@ case V8::SELECT_CC_FP_ICC: case V8::SELECT_CC_DFP_ICC: BROpcode = V8::BCOND; + break; case V8::SELECT_CC_Int_FCC: case V8::SELECT_CC_FP_FCC: case V8::SELECT_CC_DFP_FCC: From evan.cheng at apple.com Tue Jan 31 12:14:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 12:14:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200601311814.MAA02731@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.298 -> 1.299 --- Log message: Allow custom lowering of fabs. I forgot to check in this change which caused several test failures. --- Diffs of the changes: (+6 -1) LegalizeDAG.cpp | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.298 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.299 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.298 Mon Jan 30 23:04:52 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue Jan 31 12:14:25 2006 @@ -2022,9 +2022,14 @@ switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { case TargetLowering::Promote: case TargetLowering::Custom: - assert(0 && "Cannot promote/custom handle this yet!"); + isCustom = true; + // FALLTHROUGH case TargetLowering::Legal: Result = DAG.UpdateNodeOperands(Result, Tmp1); + if (isCustom) { + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.Val) Result = Tmp1; + } break; case TargetLowering::Expand: switch (Node->getOpcode()) { From lattner at cs.uiuc.edu Tue Jan 31 13:20:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 13:20:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp PPCISelLowering.h Message-ID: <200601311920.NAA03031@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.81 -> 1.82 PPCISelLowering.h updated: 1.18 -> 1.19 --- Log message: add info about the inline asm register constraints for PPC --- Diffs of the changes: (+60 -0) PPCISelLowering.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ PPCISelLowering.h | 4 +++ 2 files changed, 60 insertions(+) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.81 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.82 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.81 Tue Jan 31 02:17:29 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Jan 31 13:20:21 2006 @@ -20,6 +20,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Constants.h" #include "llvm/Function.h" +#include "llvm/ADT/VectorExtras.h" using namespace llvm; PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) @@ -951,3 +952,58 @@ return BB; } +std::vector PPCTargetLowering:: +getRegForInlineAsmConstraint(const std::string &Constraint) const { + if (Constraint.size() == 1) { + switch (Constraint[0]) { // GCC RS6000 Constraint Letters + default: break; // Unknown constriant letter + case 'b': + return make_vector(/*no R0*/ PPC::R1 , PPC::R2 , PPC::R3 , + PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 , + PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, + PPC::R12, PPC::R13, PPC::R14, PPC::R15, + PPC::R16, PPC::R17, PPC::R18, PPC::R19, + PPC::R20, PPC::R21, PPC::R22, PPC::R23, + PPC::R24, PPC::R25, PPC::R26, PPC::R27, + PPC::R28, PPC::R29, PPC::R30, PPC::R31, + 0); + case 'r': + return make_vector(PPC::R0 , PPC::R1 , PPC::R2 , PPC::R3 , + PPC::R4 , PPC::R5 , PPC::R6 , PPC::R7 , + PPC::R8 , PPC::R9 , PPC::R10, PPC::R11, + PPC::R12, PPC::R13, PPC::R14, PPC::R15, + PPC::R16, PPC::R17, PPC::R18, PPC::R19, + PPC::R20, PPC::R21, PPC::R22, PPC::R23, + PPC::R24, PPC::R25, PPC::R26, PPC::R27, + PPC::R28, PPC::R29, PPC::R30, PPC::R31, + 0); + case 'f': + return make_vector(PPC::F0 , PPC::F1 , PPC::F2 , PPC::F3 , + PPC::F4 , PPC::F5 , PPC::F6 , PPC::F7 , + PPC::F8 , PPC::F9 , PPC::F10, PPC::F11, + PPC::F12, PPC::F13, PPC::F14, PPC::F15, + PPC::F16, PPC::F17, PPC::F18, PPC::F19, + PPC::F20, PPC::F21, PPC::F22, PPC::F23, + PPC::F24, PPC::F25, PPC::F26, PPC::F27, + PPC::F28, PPC::F29, PPC::F30, PPC::F31, + 0); + case 'v': + return make_vector(PPC::V0 , PPC::V1 , PPC::V2 , PPC::V3 , + PPC::V4 , PPC::V5 , PPC::V6 , PPC::V7 , + PPC::V8 , PPC::V9 , PPC::V10, PPC::V11, + PPC::V12, PPC::V13, PPC::V14, PPC::V15, + PPC::V16, PPC::V17, PPC::V18, PPC::V19, + PPC::V20, PPC::V21, PPC::V22, PPC::V23, + PPC::V24, PPC::V25, PPC::V26, PPC::V27, + PPC::V28, PPC::V29, PPC::V30, PPC::V31, + 0); + case 'y': + return make_vector(PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, + PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7, + 0); + } + } + + // Handle explicit register names. + return TargetLowering::getRegForInlineAsmConstraint(Constraint); +} Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.18 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.19 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.18 Fri Jan 27 17:34:02 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Tue Jan 31 13:20:21 2006 @@ -96,6 +96,10 @@ virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *MBB); + + std::vector + getRegForInlineAsmConstraint(const std::string &Constraint) const; + }; } From lattner at cs.uiuc.edu Tue Jan 31 13:43:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 13:43:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86Subtarget.h Message-ID: <200601311943.NAA03210@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td updated: 1.20 -> 1.21 X86ISelLowering.cpp updated: 1.70 -> 1.71 X86ISelLowering.h updated: 1.22 -> 1.23 X86InstrInfo.td updated: 1.224 -> 1.225 X86Subtarget.h updated: 1.9 -> 1.10 --- Log message: * Fix 80-column violations * Rename hasSSE -> hasSSE1 to avoid my continual confusion with 'has any SSE'. * Add inline asm constraint specification. --- Diffs of the changes: (+67 -27) X86.td | 32 ++++++++++++++++---------------- X86ISelLowering.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++------- X86ISelLowering.h | 2 ++ X86InstrInfo.td | 2 +- X86Subtarget.h | 6 +++--- 5 files changed, 67 insertions(+), 27 deletions(-) Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.20 llvm/lib/Target/X86/X86.td:1.21 --- llvm/lib/Target/X86/X86.td:1.20 Sat Jan 28 21:45:35 2006 +++ llvm/lib/Target/X86/X86.td Tue Jan 31 13:43:35 2006 @@ -24,7 +24,7 @@ "Enable 64-bit instructions">; def FeatureMMX : SubtargetFeature<"mmx","X86SSELevel", "MMX", "Enable MMX instructions">; -def FeatureSSE : SubtargetFeature<"sse", "X86SSELevel", "SSE", +def FeatureSSE1 : SubtargetFeature<"sse", "X86SSELevel", "SSE1", "Enable SSE instructions">; def FeatureSSE2 : SubtargetFeature<"sse2", "X86SSELevel", "SSE2", "Enable SSE2 instructions">; @@ -50,16 +50,16 @@ def : Proc<"i686", []>; def : Proc<"pentiumpro", []>; def : Proc<"pentium2", [FeatureMMX]>; -def : Proc<"pentium3", [FeatureMMX, FeatureSSE]>; -def : Proc<"pentium-m", [FeatureMMX, FeatureSSE, FeatureSSE2]>; -def : Proc<"pentium4", [FeatureMMX, FeatureSSE, FeatureSSE2]>; -def : Proc<"x86-64", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"pentium3", [FeatureMMX, FeatureSSE1]>; +def : Proc<"pentium-m", [FeatureMMX, FeatureSSE1, FeatureSSE2]>; +def : Proc<"pentium4", [FeatureMMX, FeatureSSE1, FeatureSSE2]>; +def : Proc<"x86-64", [FeatureMMX, FeatureSSE1, FeatureSSE2, Feature64Bit]>; -def : Proc<"yonah", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"yonah", [FeatureMMX, FeatureSSE1, FeatureSSE2, FeatureSSE3]>; -def : Proc<"prescott", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"prescott", [FeatureMMX, FeatureSSE1, FeatureSSE2, FeatureSSE3]>; -def : Proc<"nocona", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"nocona", [FeatureMMX, FeatureSSE1, FeatureSSE2, FeatureSSE3, Feature64Bit]>; def : Proc<"k6", [FeatureMMX]>; @@ -67,25 +67,25 @@ def : Proc<"k6-3", [FeatureMMX, Feature3DNow]>; def : Proc<"athlon", [FeatureMMX, Feature3DNow, Feature3DNowA]>; def : Proc<"athlon-tbird", [FeatureMMX, Feature3DNow, Feature3DNowA]>; -def : Proc<"athlon-4", [FeatureMMX, FeatureSSE, Feature3DNow, +def : Proc<"athlon-4", [FeatureMMX, FeatureSSE1, Feature3DNow, Feature3DNowA]>; -def : Proc<"athlon-xp", [FeatureMMX, FeatureSSE, Feature3DNow, +def : Proc<"athlon-xp", [FeatureMMX, FeatureSSE1, Feature3DNow, Feature3DNowA]>; -def : Proc<"athlon-mp", [FeatureMMX, FeatureSSE, Feature3DNow, +def : Proc<"athlon-mp", [FeatureMMX, FeatureSSE1, Feature3DNow, Feature3DNowA]>; -def : Proc<"k8", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"k8", [FeatureMMX, FeatureSSE1, FeatureSSE2, Feature3DNow, Feature3DNowA, Feature64Bit]>; -def : Proc<"opteron", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"opteron", [FeatureMMX, FeatureSSE1, FeatureSSE2, Feature3DNow, Feature3DNowA, Feature64Bit]>; -def : Proc<"athlon64", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"athlon64", [FeatureMMX, FeatureSSE1, FeatureSSE2, Feature3DNow, Feature3DNowA, Feature64Bit]>; -def : Proc<"athlon-fx", [FeatureMMX, FeatureSSE, FeatureSSE2, +def : Proc<"athlon-fx", [FeatureMMX, FeatureSSE1, FeatureSSE2, Feature3DNow, Feature3DNowA, Feature64Bit]>; def : Proc<"winchip-c6", [FeatureMMX]>; def : Proc<"winchip2", [FeatureMMX, Feature3DNow]>; def : Proc<"c3", [FeatureMMX, Feature3DNow]>; -def : Proc<"c3-2", [FeatureMMX, FeatureSSE]>; +def : Proc<"c3-2", [FeatureMMX, FeatureSSE1]>; //===----------------------------------------------------------------------===// // Register File Description Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.70 llvm/lib/Target/X86/X86ISelLowering.cpp:1.71 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.70 Mon Jan 30 21:14:29 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 31 13:43:35 2006 @@ -25,6 +25,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/VectorExtras.h" using namespace llvm; // FIXME: temporary. @@ -564,7 +565,7 @@ Ops.push_back(DAG.getConstant(NumBytes, getPointerTy())); Ops.push_back(DAG.getConstant(0, getPointerTy())); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL :X86ISD::CALL, RetVals, Ops); SDOperand ResultVal; @@ -1068,7 +1069,7 @@ // Pass register arguments as needed. Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end()); - SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL, + SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL :X86ISD::CALL, RetVals, Ops); Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall); @@ -1157,7 +1158,8 @@ /// specific condition code. It returns a false if it cannot do a direct /// translation. X86CC is the translated CondCode. Flip is set to true if the /// the order of comparison operands should be flipped. -static bool translateX86CC(SDOperand CC, bool isFP, unsigned &X86CC, bool &Flip) { +static bool translateX86CC(SDOperand CC, bool isFP, unsigned &X86CC, + bool &Flip) { ISD::CondCode SetCCOpcode = cast(CC)->get(); Flip = false; X86CC = X86ISD::COND_INVALID; @@ -1234,10 +1236,10 @@ default: assert(false && "Unexpected instr type to insert"); case X86::CMOV_FR32: case X86::CMOV_FR64: { - // To "insert" a SELECT_CC instruction, we actually have to insert the diamond - // control-flow pattern. The incoming instruction knows the destination vreg - // to set, the condition code register to branch on, the true/false values to - // select between, and a branch opcode to use. + // To "insert" a SELECT_CC instruction, we actually have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // destination vreg to set, the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. const BasicBlock *LLVM_BB = BB->getBasicBlock(); ilist::iterator It = BB; ++It; @@ -1957,3 +1959,39 @@ return false; } + +std::vector X86TargetLowering:: +getRegForInlineAsmConstraint(const std::string &Constraint) const { + if (Constraint.size() == 1) { + // FIXME: not handling fp-stack yet! + // FIXME: not handling MMX registers yet ('y' constraint). + switch (Constraint[0]) { // GCC X86 Constraint Letters + default: break; // Unknown constriant letter + case 'r': // GENERAL_REGS + case 'R': // LEGACY_REGS + return make_vector(X86::EAX, X86::EBX, X86::ECX, X86::EDX, + X86::ESI, X86::EDI, X86::EBP, X86::ESP, 0); + case 'l': // INDEX_REGS + return make_vector(X86::EAX, X86::EBX, X86::ECX, X86::EDX, + X86::ESI, X86::EDI, X86::EBP, 0); + case 'q': // Q_REGS (GENERAL_REGS in 64-bit mode) + case 'Q': // Q_REGS + return make_vector(X86::EAX, X86::EBX, X86::ECX, X86::EDX, 0); + case 'x': // SSE_REGS if SSE1 allowed + if (Subtarget->hasSSE1()) + return make_vector(X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3, + X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7, + 0); + return std::vector(); + case 'Y': // SSE_REGS if SSE2 allowed + if (Subtarget->hasSSE2()) + return make_vector(X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3, + X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7, + 0); + return std::vector(); + } + } + + // Handle explicit register names. + return TargetLowering::getRegForInlineAsmConstraint(Constraint); +} Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.22 llvm/lib/Target/X86/X86ISelLowering.h:1.23 --- llvm/lib/Target/X86/X86ISelLowering.h:1.22 Mon Jan 30 21:14:29 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Jan 31 13:43:35 2006 @@ -216,6 +216,8 @@ SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG); + std::vector + getRegForInlineAsmConstraint(const std::string &Constraint) const; private: // C Calling Convention implementation. std::vector LowerCCCArguments(Function &F, SelectionDAG &DAG); Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.224 llvm/lib/Target/X86/X86InstrInfo.td:1.225 --- llvm/lib/Target/X86/X86InstrInfo.td:1.224 Mon Jan 30 21:14:29 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Jan 31 13:43:35 2006 @@ -192,7 +192,7 @@ //===----------------------------------------------------------------------===// // X86 Instruction Predicate Definitions. -def HasSSE1 : Predicate<"Subtarget->hasSSE()">; +def HasSSE1 : Predicate<"Subtarget->hasSSE1()">; def HasSSE2 : Predicate<"Subtarget->hasSSE2()">; def HasSSE3 : Predicate<"Subtarget->hasSSE3()">; def FPStack : Predicate<"!Subtarget->hasSSE2()">; Index: llvm/lib/Target/X86/X86Subtarget.h diff -u llvm/lib/Target/X86/X86Subtarget.h:1.9 llvm/lib/Target/X86/X86Subtarget.h:1.10 --- llvm/lib/Target/X86/X86Subtarget.h:1.9 Fri Jan 27 02:10:46 2006 +++ llvm/lib/Target/X86/X86Subtarget.h Tue Jan 31 13:43:35 2006 @@ -24,14 +24,14 @@ class X86Subtarget : public TargetSubtarget { protected: enum X86SSEEnum { - NoMMXSSE, MMX, SSE, SSE2, SSE3 + NoMMXSSE, MMX, SSE1, SSE2, SSE3 }; enum X863DNowEnum { NoThreeDNow, ThreeDNow, ThreeDNowA }; - /// X86SSELevel - MMX, SSE, SSE2, SSE3, or none supported. + /// X86SSELevel - MMX, SSE1, SSE2, SSE3, or none supported. X86SSEEnum X86SSELevel; /// X863DNowLevel - 3DNow or 3DNow Athlon, or none supported. @@ -76,7 +76,7 @@ bool is64Bit() const { return Is64Bit; } bool hasMMX() const { return X86SSELevel >= MMX; } - bool hasSSE() const { return X86SSELevel >= SSE; } + bool hasSSE1() const { return X86SSELevel >= SSE1; } bool hasSSE2() const { return X86SSELevel >= SSE2; } bool hasSSE3() const { return X86SSELevel >= SSE3; } bool has3DNow() const { return X863DNowLevel >= ThreeDNow; } From evan.cheng at apple.com Tue Jan 31 16:21:49 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/MachineConstantPool.h SelectionDAG.h SelectionDAGNodes.h Message-ID: <200601312221.QAA03927@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: MachineConstantPool.h updated: 1.9 -> 1.10 SelectionDAG.h updated: 1.94 -> 1.95 SelectionDAGNodes.h updated: 1.98 -> 1.99 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+24 -11) MachineConstantPool.h | 17 +++++++++++------ SelectionDAG.h | 10 ++++++---- SelectionDAGNodes.h | 8 +++++++- 3 files changed, 24 insertions(+), 11 deletions(-) Index: llvm/include/llvm/CodeGen/MachineConstantPool.h diff -u llvm/include/llvm/CodeGen/MachineConstantPool.h:1.9 llvm/include/llvm/CodeGen/MachineConstantPool.h:1.10 --- llvm/include/llvm/CodeGen/MachineConstantPool.h:1.9 Wed Dec 28 00:47:33 2005 +++ llvm/include/llvm/CodeGen/MachineConstantPool.h Tue Jan 31 16:21:33 2006 @@ -30,20 +30,23 @@ class Constant; class MachineConstantPool { - std::vector Constants; + std::vector > Constants; public: /// getConstantPoolIndex - Create a new entry in the constant pool or return - /// an existing one. + /// an existing one. User may specify an alignment that is greater than the + /// default alignment. If one is not specified, it will be 0. /// - unsigned getConstantPoolIndex(Constant *C) { + unsigned getConstantPoolIndex(Constant *C, unsigned Alignment = 0) { // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. for (unsigned i = 0, e = Constants.size(); i != e; ++i) - if (Constants[i] == C) + if (Constants[i].first == C) { + Constants[i].second = std::max(Constants[i].second, Alignment); return i; - Constants.push_back(C); + } + Constants.push_back(std::make_pair(C, Alignment)); return Constants.size()-1; } @@ -51,7 +54,9 @@ /// bool isEmpty() const { return Constants.empty(); } - const std::vector &getConstants() const { return Constants; } + const std::vector > &getConstants() const { + return Constants; + } /// print - Used by the MachineFunction printer to print information about /// stack objects. Implemented in MachineFunction.cpp Index: llvm/include/llvm/CodeGen/SelectionDAG.h diff -u llvm/include/llvm/CodeGen/SelectionDAG.h:1.94 llvm/include/llvm/CodeGen/SelectionDAG.h:1.95 --- llvm/include/llvm/CodeGen/SelectionDAG.h:1.94 Mon Jan 30 01:47:47 2006 +++ llvm/include/llvm/CodeGen/SelectionDAG.h Tue Jan 31 16:21:33 2006 @@ -120,8 +120,10 @@ int offset = 0); SDOperand getFrameIndex(int FI, MVT::ValueType VT); SDOperand getTargetFrameIndex(int FI, MVT::ValueType VT); - SDOperand getConstantPool(Constant *C, MVT::ValueType VT); - SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT); + SDOperand getConstantPool(Constant *C, MVT::ValueType VT, + unsigned Alignment=0); + SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT, + unsigned Alignment=0); SDOperand getBasicBlock(MachineBasicBlock *MBB); SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT); SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT); @@ -606,8 +608,8 @@ std::map, SDNode*> ConstantFPs; std::map, SDNode*> TargetConstantFPs; std::map FrameIndices, TargetFrameIndices; - std::map ConstantPoolIndices; - std::map TargetConstantPoolIndices; + std::map, SDNode*> ConstantPoolIndices; + std::map, SDNode*> TargetConstantPoolIndices; std::map BBNodes; std::vector ValueTypeNodes; std::map ExternalSymbols; Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.98 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.99 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.98 Sun Jan 29 01:57:11 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Tue Jan 31 16:21:33 2006 @@ -1058,14 +1058,20 @@ class ConstantPoolSDNode : public SDNode { Constant *C; + unsigned Alignment; protected: friend class SelectionDAG; ConstantPoolSDNode(Constant *c, MVT::ValueType VT, bool isTarget) : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT), - C(c) {} + C(c), Alignment(0) {} + ConstantPoolSDNode(Constant *c, MVT::ValueType VT, unsigned Align, + bool isTarget) + : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, VT), + C(c), Alignment(Align) {} public: Constant *get() const { return C; } + unsigned getAlignment() const { return Alignment; } static bool classof(const ConstantPoolSDNode *) { return true; } static bool classof(const SDNode *N) { From evan.cheng at apple.com Tue Jan 31 16:21:49 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp MachineFunction.cpp Message-ID: <200601312221.QAA03933@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.42 -> 1.43 MachineFunction.cpp updated: 1.83 -> 1.84 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+14 -7) AsmPrinter.cpp | 14 +++++++++----- MachineFunction.cpp | 7 +++++-- 2 files changed, 14 insertions(+), 7 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.42 llvm/lib/CodeGen/AsmPrinter.cpp:1.43 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.42 Mon Jan 30 17:00:08 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue Jan 31 16:21:33 2006 @@ -103,7 +103,7 @@ /// the code generator. /// void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { - const std::vector &CP = MCP->getConstants(); + const std::vector > &CP = MCP->getConstants(); if (CP.empty()) return; const TargetData &TD = TM.getTargetData(); @@ -111,13 +111,17 @@ for (unsigned i = 0, e = CP.size(); i != e; ++i) { // FIXME: force doubles to be naturally aligned. We should handle this // more correctly in the future. - unsigned Alignment = TD.getTypeAlignmentShift(CP[i]->getType()); - if (CP[i]->getType() == Type::DoubleTy && Alignment < 3) Alignment = 3; + unsigned Alignment = CP[i].second; + if (Alignment == 0) { + Alignment = TD.getTypeAlignmentShift(CP[i].first->getType()); + if (CP[i].first->getType() == Type::DoubleTy && Alignment < 3) + Alignment = 3; + } EmitAlignment(Alignment); O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << i - << ":\t\t\t\t\t" << CommentString << *CP[i] << '\n'; - EmitGlobalConstant(CP[i]); + << ":\t\t\t\t\t" << CommentString << *CP[i].first << '\n'; + EmitGlobalConstant(CP[i].first); } } Index: llvm/lib/CodeGen/MachineFunction.cpp diff -u llvm/lib/CodeGen/MachineFunction.cpp:1.83 llvm/lib/CodeGen/MachineFunction.cpp:1.84 --- llvm/lib/CodeGen/MachineFunction.cpp:1.83 Wed Jan 4 07:43:56 2006 +++ llvm/lib/CodeGen/MachineFunction.cpp Tue Jan 31 16:21:33 2006 @@ -346,8 +346,11 @@ //===----------------------------------------------------------------------===// void MachineConstantPool::print(std::ostream &OS) const { - for (unsigned i = 0, e = Constants.size(); i != e; ++i) - OS << " is" << *(Value*)Constants[i] << "\n"; + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + OS << " is" << *(Value*)Constants[i].first; + if (Constants[i].second != 0) OS << " , align=" << Constants[i].second; + OS << "\n"; + } } void MachineConstantPool::dump() const { print(std::cerr); } From evan.cheng at apple.com Tue Jan 31 16:21:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Message-ID: <200601312221.QAA03939@zion.cs.uiuc.edu> Changes in directory llvm/lib/ExecutionEngine/JIT: JITEmitter.cpp updated: 1.78 -> 1.79 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+6 -4) JITEmitter.cpp | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-) Index: llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp diff -u llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.78 llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.79 --- llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp:1.78 Sun Jan 22 17:41:42 2006 +++ llvm/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Jan 31 16:21:33 2006 @@ -566,16 +566,18 @@ } void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { - const std::vector &Constants = MCP->getConstants(); + const std::vector > &Constants = MCP->getConstants(); if (Constants.empty()) return; for (unsigned i = 0, e = Constants.size(); i != e; ++i) { - const Type *Ty = Constants[i]->getType(); + const Type *Ty = Constants[i].first->getType(); unsigned Size = (unsigned)TheJIT->getTargetData().getTypeSize(Ty); - unsigned Alignment = TheJIT->getTargetData().getTypeAlignment(Ty); + unsigned Alignment = (Constants[i].second == 0) + ? TheJIT->getTargetData().getTypeAlignment(Ty) + : Constants[i].second; void *Addr = MemMgr.allocateConstant(Size, Alignment); - TheJIT->InitializeMemory(Constants[i], Addr); + TheJIT->InitializeMemory(Constants[i].first, Addr); ConstantPoolAddresses.push_back(Addr); } } From evan.cheng at apple.com Tue Jan 31 16:21:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Message-ID: <200601312221.QAA03937@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelDAGToDAG.cpp updated: 1.32 -> 1.33 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+4 -2) IA64ISelDAGToDAG.cpp | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) Index: llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp diff -u llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.32 llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.33 --- llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp:1.32 Sun Jan 29 00:26:07 2006 +++ llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp Tue Jan 31 16:21:34 2006 @@ -442,8 +442,10 @@ case ISD::ConstantPool: { // TODO: nuke the constant pool // (ia64 doesn't need one) - Constant *C = cast(N)->get(); - SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64); + ConstantPoolSDNode *CP = cast(N); + Constant *C = CP->get(); + SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64, + CP->getAlignment()); return CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ? CurDAG->getRegister(IA64::r1, MVT::i64), CPI); } From evan.cheng at apple.com Tue Jan 31 16:21:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200601312221.QAA03953@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.82 -> 1.83 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+3 -2) PPCISelLowering.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.82 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.83 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.82 Tue Jan 31 13:20:21 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Jan 31 16:21:34 2006 @@ -389,8 +389,9 @@ return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi); } case ISD::ConstantPool: { - Constant *C = cast(Op)->get(); - SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32); + ConstantPoolSDNode *CP = cast(Op); + Constant *C = CP->get(); + SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment()); SDOperand Zero = DAG.getConstant(0, MVT::i32); if (PPCGenerateStaticCode) { From evan.cheng at apple.com Tue Jan 31 16:21:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp Message-ID: <200601312221.QAA03945@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.35 -> 1.36 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+3 -2) AlphaISelLowering.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.35 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.36 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.35 Sun Jan 29 00:25:22 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Tue Jan 31 16:21:34 2006 @@ -482,8 +482,9 @@ } } case ISD::ConstantPool: { - Constant *C = cast(Op)->get(); - SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i64); + ConstantPoolSDNode *CP = cast(Op); + Constant *C = CP->get(); + SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment()); SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, CPI, DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); From evan.cheng at apple.com Tue Jan 31 16:21:50 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:21:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200601312221.QAA03947@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.74 -> 1.75 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+2 -1) SparcV8ISelDAGToDAG.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.74 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.75 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.74 Tue Jan 31 11:20:06 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Tue Jan 31 16:21:34 2006 @@ -693,7 +693,8 @@ } case ISD::ConstantPool: { Constant *C = cast(Op)->get(); - SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32); + SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, + cast(Op)->getAlignment()); SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP); SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); From evan.cheng at apple.com Tue Jan 31 16:23:27 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:23:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Message-ID: <200601312223.QAA03977@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV9: SparcV9AsmPrinter.cpp updated: 1.127 -> 1.128 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+8 -5) SparcV9AsmPrinter.cpp | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-) Index: llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp diff -u llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.127 llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.128 --- llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp:1.127 Thu Apr 21 18:25:42 2005 +++ llvm/lib/Target/SparcV9/SparcV9AsmPrinter.cpp Tue Jan 31 16:23:14 2006 @@ -209,11 +209,14 @@ // Print a constant (which may be an aggregate) prefixed by all the // appropriate directives. Uses printConstantValueOnly() to print the // value or values. - void printConstant(const Constant* CV, std::string valID = "") { + void printConstant(const Constant* CV, unsigned Alignment, + std::string valID = "") { if (valID.length() == 0) valID = getID(CV); - O << "\t.align\t" << ConstantToAlignment(CV, TM) << "\n"; + if (Alignment == 0) + Alignment = ConstantToAlignment(CV, TM); + O << "\t.align\t" << Alignment << "\n"; // Print .size and .type only if it is not a string. if (const ConstantArray *CVA = dyn_cast(CV)) @@ -721,12 +724,12 @@ // Emit constant pool for this function const MachineConstantPool *MCP = MF.getConstantPool(); - const std::vector &CP = MCP->getConstants(); + const std::vector > &CP = MCP->getConstants(); enterSection(ReadOnlyData); for (unsigned i = 0, e = CP.size(); i != e; ++i) { std::string cpiName = ".CPI_" + CurrentFnName + "_" + utostr(i); - printConstant(CP[i], cpiName); + printConstant(CP[i].first, CP[i].second, cpiName); } enterSection(Text); @@ -755,7 +758,7 @@ if (GV->hasInitializer() && !(GV->getInitializer()->isNullValue() || isa(GV->getInitializer()))) { - printConstant(GV->getInitializer(), getID(GV)); + printConstant(GV->getInitializer(), 0, getID(GV)); } else { O << "\t.align\t" << TypeToAlignment(GV->getType()->getElementType(), TM) << "\n"; From evan.cheng at apple.com Tue Jan 31 16:23:27 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:23:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAG.cpp Message-ID: <200601312223.QAA03983@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.61 -> 1.62 SelectionDAG.cpp updated: 1.250 -> 1.251 --- Log message: Allow the specification of explicit alignments for constant pool entries. --- Diffs of the changes: (+16 -9) ScheduleDAG.cpp | 3 ++- SelectionDAG.cpp | 22 ++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.61 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.62 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.61 Mon Jan 30 20:03:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Tue Jan 31 16:23:14 2006 @@ -194,7 +194,8 @@ MI->addFrameIndexOperand(FI->getIndex()); } else if (ConstantPoolSDNode *CP = dyn_cast(Node->getOperand(i))) { - unsigned Idx = ConstPool->getConstantPoolIndex(CP->get()); + unsigned Idx = ConstPool->getConstantPoolIndex(CP->get(), + CP->getAlignment()); MI->addConstantPoolIndexOperand(Idx); } else if (ExternalSymbolSDNode *ES = dyn_cast(Node->getOperand(i))) { Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.250 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.251 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.250 Sun Jan 29 01:58:15 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Tue Jan 31 16:23:14 2006 @@ -310,10 +310,14 @@ Erased = TargetFrameIndices.erase(cast(N)->getIndex()); break; case ISD::ConstantPool: - Erased = ConstantPoolIndices.erase(cast(N)->get()); + Erased = ConstantPoolIndices. + erase(std::make_pair(cast(N)->get(), + cast(N)->getAlignment())); break; case ISD::TargetConstantPool: - Erased =TargetConstantPoolIndices.erase(cast(N)->get()); + Erased = TargetConstantPoolIndices. + erase(std::make_pair(cast(N)->get(), + cast(N)->getAlignment())); break; case ISD::BasicBlock: Erased = BBNodes.erase(cast(N)->getBasicBlock()); @@ -655,18 +659,20 @@ return SDOperand(N, 0); } -SDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT) { - SDNode *&N = ConstantPoolIndices[C]; +SDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT, + unsigned Alignment) { + SDNode *&N = ConstantPoolIndices[std::make_pair(C, Alignment)]; if (N) return SDOperand(N, 0); - N = new ConstantPoolSDNode(C, VT, false); + N = new ConstantPoolSDNode(C, VT, Alignment, false); AllNodes.push_back(N); return SDOperand(N, 0); } -SDOperand SelectionDAG::getTargetConstantPool(Constant *C, MVT::ValueType VT) { - SDNode *&N = TargetConstantPoolIndices[C]; +SDOperand SelectionDAG::getTargetConstantPool(Constant *C, MVT::ValueType VT, + unsigned Alignment) { + SDNode *&N = TargetConstantPoolIndices[std::make_pair(C, Alignment)]; if (N) return SDOperand(N, 0); - N = new ConstantPoolSDNode(C, VT, true); + N = new ConstantPoolSDNode(C, VT, Alignment, true); AllNodes.push_back(N); return SDOperand(N, 0); } From evan.cheng at apple.com Tue Jan 31 16:26:32 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:26:32 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200601312226.QAA04004@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.33 -> 1.34 --- Log message: Remove entries on fabs and fneg. These are done. --- Diffs of the changes: (+0 -49) README.txt | 49 ------------------------------------------------- 1 files changed, 49 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.33 llvm/lib/Target/X86/README.txt:1.34 --- llvm/lib/Target/X86/README.txt:1.33 Mon Jan 30 20:10:06 2006 +++ llvm/lib/Target/X86/README.txt Tue Jan 31 16:26:21 2006 @@ -215,53 +215,6 @@ //===---------------------------------------------------------------------===// -The code generated for 'abs' is truly aweful: - -float %foo(float %tmp.38) { - %tmp.39 = setgt float %tmp.38, 0.000000e+00 - %tmp.45 = sub float -0.000000e+00, %tmp.38 - %mem_tmp.0.0 = select bool %tmp.39, float %tmp.38, float %tmp.45 - ret float %mem_tmp.0.0 -} - -_foo: - subl $4, %esp - movss LCPI1_0, %xmm0 - movss 8(%esp), %xmm1 - subss %xmm1, %xmm0 - xorps %xmm2, %xmm2 - ucomiss %xmm2, %xmm1 - setp %al - seta %cl - orb %cl, %al - testb %al, %al - jne LBB_foo_2 # -LBB_foo_1: # - movss %xmm0, %xmm1 -LBB_foo_2: # - movss %xmm1, (%esp) - flds (%esp) - addl $4, %esp - ret - -This should be a high-priority to fix. With the fp-stack, this is a single -instruction. With SSE it could be far better than this. Why is the sequence -above using 'setp'? It shouldn't care about nan's. - -//===---------------------------------------------------------------------===// - -Is there a better way to implement Y = -X (fneg) than the literal code: - -float %test(float %X) { - %Y = sub float -0.0, %X - ret float %Y -} - - movss LCPI1_0, %xmm0 ;; load -0.0 - subss 8(%esp), %xmm0 ;; subtract - -//===---------------------------------------------------------------------===// - None of the SSE instructions are handled in X86RegisterInfo::foldMemoryOperand, which prevents the spiller from folding spill code into the instructions. @@ -358,5 +311,3 @@ This is bad for register pressure, though the dag isel is producing a better schedule. :) - - From evan.cheng at apple.com Tue Jan 31 16:28:42 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 16:28:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.h X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86IntelAsmPrinter.h Message-ID: <200601312228.QAA04062@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ATTAsmPrinter.h updated: 1.4 -> 1.5 X86ISelDAGToDAG.cpp updated: 1.37 -> 1.38 X86ISelLowering.cpp updated: 1.71 -> 1.72 X86ISelLowering.h updated: 1.23 -> 1.24 X86InstrInfo.td updated: 1.225 -> 1.226 X86IntelAsmPrinter.h updated: 1.5 -> 1.6 --- Log message: - Allow XMM load (for scalar use) to be folded into ANDP* and XORP*. - Use XORP* to implement fneg. --- Diffs of the changes: (+127 -26) X86ATTAsmPrinter.h | 2 - X86ISelDAGToDAG.cpp | 3 + X86ISelLowering.cpp | 54 +++++++++++++++++++++++++++++---- X86ISelLowering.h | 8 ++++ X86InstrInfo.td | 82 +++++++++++++++++++++++++++++++++++++++++---------- X86IntelAsmPrinter.h | 4 +- 6 files changed, 127 insertions(+), 26 deletions(-) Index: llvm/lib/Target/X86/X86ATTAsmPrinter.h diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.4 llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.5 --- llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.4 Fri Dec 16 19:03:57 2005 +++ llvm/lib/Target/X86/X86ATTAsmPrinter.h Tue Jan 31 16:28:30 2006 @@ -59,7 +59,7 @@ void printf64mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { + void printf128mem(const MachineInstr *MI, unsigned OpNo) { printMemReference(MI, OpNo); } Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.37 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.38 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.37 Fri Jan 27 02:10:46 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Tue Jan 31 16:28:30 2006 @@ -253,7 +253,8 @@ if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) { if (ConstantPoolSDNode *CP = dyn_cast(N)) { AM.BaseType = X86ISelAddressMode::ConstantPoolBase; - AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32); + AM.Base.Reg = CurDAG->getTargetConstantPool(CP->get(), MVT::i32, + CP->getAlignment()); return false; } } Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.71 llvm/lib/Target/X86/X86ISelLowering.cpp:1.72 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.71 Tue Jan 31 13:43:35 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 31 16:28:30 2006 @@ -17,6 +17,7 @@ #include "X86ISelLowering.h" #include "X86TargetMachine.h" #include "llvm/CallingConv.h" +#include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -208,16 +209,20 @@ setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand); + // Use ANDPD to simulate FABS. + setOperationAction(ISD::FABS , MVT::f64, Custom); + setOperationAction(ISD::FABS , MVT::f32, Custom); + + // Use XORP to simulate FNEG. + setOperationAction(ISD::FNEG , MVT::f64, Custom); + setOperationAction(ISD::FNEG , MVT::f32, Custom); + // We don't support sin/cos/sqrt/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); - setOperationAction(ISD::FABS , MVT::f64, Custom); - setOperationAction(ISD::FNEG , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f64, Expand); setOperationAction(ISD::FSIN , MVT::f32, Expand); setOperationAction(ISD::FCOS , MVT::f32, Expand); - setOperationAction(ISD::FABS , MVT::f32, Custom); - setOperationAction(ISD::FNEG , MVT::f32, Expand); setOperationAction(ISD::FREM , MVT::f32, Expand); // Expand FP immediates into loads from the stack, except for the special @@ -1567,11 +1572,44 @@ } case ISD::FABS: { MVT::ValueType VT = Op.getValueType(); - SDOperand Mask = (VT == MVT::f64) - ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), MVT::f64) - : DAG.getConstantFP(BitsToFloat (~(1U << 31)), MVT::f32); + const Type *OpNTy = MVT::getTypeForValueType(VT); + std::vector CV; + if (VT == MVT::f64) { + CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(~(1ULL << 63)))); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + } else { + CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(~(1U << 31)))); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + } + Constant *CS = ConstantStruct::get(CV); + SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4); + SDOperand Mask + = DAG.getNode(X86ISD::LOAD_PACK, + VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask); } + case ISD::FNEG: { + MVT::ValueType VT = Op.getValueType(); + const Type *OpNTy = MVT::getTypeForValueType(VT); + std::vector CV; + if (VT == MVT::f64) { + CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(1ULL << 63))); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + } else { + CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(1U << 31))); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + CV.push_back(ConstantFP::get(OpNTy, 0.0)); + } + Constant *CS = ConstantStruct::get(CV); + SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4); + SDOperand Mask + = DAG.getNode(X86ISD::LOAD_PACK, + VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL)); + return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask); + } case ISD::SETCC: { assert(Op.getValueType() == MVT::i8 && "SetCC type must be 8-bit integer"); SDOperand Cond; @@ -1923,6 +1961,7 @@ case X86ISD::SHLD: return "X86ISD::SHLD"; case X86ISD::SHRD: return "X86ISD::SHRD"; case X86ISD::FAND: return "X86ISD::FAND"; + case X86ISD::FXOR: return "X86ISD::FXOR"; case X86ISD::FILD: return "X86ISD::FILD"; case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM"; case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; @@ -1942,6 +1981,7 @@ case X86ISD::RET_FLAG: return "X86ISD::RET_FLAG"; case X86ISD::REP_STOS: return "X86ISD::RET_STOS"; case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS"; + case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK"; } } Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.23 llvm/lib/Target/X86/X86ISelLowering.h:1.24 --- llvm/lib/Target/X86/X86ISelLowering.h:1.23 Tue Jan 31 13:43:35 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Jan 31 16:28:30 2006 @@ -45,6 +45,10 @@ /// to X86::ANDPS or X86::ANDPD. FAND, + /// FXOR - Bitwise logical XOR of floating point values. This corresponds + /// to X86::XORPS or X86::XORPD. + FXOR, + /// FILD - This instruction implements SINT_TO_FP with the integer source /// in memory and FP reg result. This corresponds to the X86::FILD*m /// instructions. It has three inputs (token chain, address, and source @@ -137,6 +141,10 @@ /// REP_MOVS - Repeat move, corresponds to X86::REP_MOVSx. REP_MOVS, + + /// LOAD_PACK Load a 128-bit packed float / double value. It has the same + /// operands as a normal load. + LOAD_PACK, }; // X86 specific condition code. These correspond to X86_*_COND in Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.225 llvm/lib/Target/X86/X86InstrInfo.td:1.226 --- llvm/lib/Target/X86/X86InstrInfo.td:1.225 Tue Jan 31 13:43:35 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Jan 31 16:28:30 2006 @@ -70,6 +70,8 @@ def X86fand : SDNode<"X86ISD::FAND", SDTFPBinOp, [SDNPCommutative, SDNPAssociative]>; +def X86fxor : SDNode<"X86ISD::FXOR", SDTFPBinOp, + [SDNPCommutative, SDNPAssociative]>; def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest, [SDNPOutFlag]>; @@ -122,6 +124,9 @@ def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc, [SDNPHasChain, SDNPOutFlag]>; +def X86loadp : SDNode<"X86ISD::LOAD_PACK", SDTLoad, + [SDNPHasChain]>; + //===----------------------------------------------------------------------===// // X86 Operand Definitions. // @@ -140,7 +145,7 @@ def i64mem : X86MemOperand<"printi64mem">; def f32mem : X86MemOperand<"printf32mem">; def f64mem : X86MemOperand<"printf64mem">; -def f80mem : X86MemOperand<"printf80mem">; +def f128mem : X86MemOperand<"printf128mem">; def SSECC : Operand { let PrintMethod = "printSSECC"; @@ -357,6 +362,9 @@ def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extload node:$ptr, i1))>; def extloadf64f32 : PatFrag<(ops node:$ptr), (f64 (extload node:$ptr, f32))>; +def X86loadpf32 : PatFrag<(ops node:$ptr), (f32 (X86loadp node:$ptr))>; +def X86loadpf64 : PatFrag<(ops node:$ptr), (f64 (X86loadp node:$ptr))>; + //===----------------------------------------------------------------------===// // Instruction templates... @@ -2566,43 +2574,51 @@ "orpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; def XORPSrr : I<0x57, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), - "xorps {$src2, $dst|$dst, $src2}", []>, + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, FR32:$src2))]>, Requires<[HasSSE1]>, TB; def XORPDrr : I<0x57, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), - "xorpd {$src2, $dst|$dst, $src2}", []>, + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, FR64:$src2))]>, Requires<[HasSSE2]>, TB, OpSize; } -def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), +def ANDPSrm : I<0x54, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), "andps {$src2, $dst|$dst, $src2}", - []>, + [(set FR32:$dst, (X86fand FR32:$src1, + (X86loadpf32 addr:$src2)))]>, Requires<[HasSSE1]>, TB; -def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), +def ANDPDrm : I<0x54, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "andpd {$src2, $dst|$dst, $src2}", - []>, + [(set FR64:$dst, (X86fand FR64:$src1, + (X86loadpf64 addr:$src2)))]>, Requires<[HasSSE2]>, TB, OpSize; -def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), +def ORPSrm : I<0x56, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), "orps {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE1]>, TB; -def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), +def ORPDrm : I<0x56, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "orpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; -def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), - "xorps {$src2, $dst|$dst, $src2}", []>, +def XORPSrm : I<0x57, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), + "xorps {$src2, $dst|$dst, $src2}", + [(set FR32:$dst, (X86fxor FR32:$src1, + (X86loadpf32 addr:$src2)))]>, Requires<[HasSSE1]>, TB; -def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), - "xorpd {$src2, $dst|$dst, $src2}", []>, +def XORPDrm : I<0x57, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), + "xorpd {$src2, $dst|$dst, $src2}", + [(set FR64:$dst, (X86fxor FR64:$src1, + (X86loadpf64 addr:$src2)))]>, Requires<[HasSSE2]>, TB, OpSize; def ANDNPSrr : I<0x55, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "andnps {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE1]>, TB; -def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f32mem:$src2), +def ANDNPSrm : I<0x55, MRMSrcMem, (ops FR32:$dst, FR32:$src1, f128mem:$src2), "andnps {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE1]>, TB; def ANDNPDrr : I<0x55, MRMSrcReg, (ops FR64:$dst, FR64:$src1, FR64:$src2), "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; -def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f64mem:$src2), +def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; @@ -2982,6 +2998,42 @@ //===----------------------------------------------------------------------===// +// XMM Packed Floating point support (requires SSE / SSE2) +//===----------------------------------------------------------------------===// + +def MOVAPSrr : I<0x28, MRMSrcMem, (ops V4F4:$dst, V4F4:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def MOVAPDrr : I<0x28, MRMSrcMem, (ops V2F8:$dst, V2F8:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, XD; + +def MOVAPSrm : I<0x28, MRMSrcMem, (ops V4F4:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def MOVAPSmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V4F4:$src), + "movaps {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE1]>, XD; +def MOVAPDrm : I<0x28, MRMSrcMem, (ops V2F8:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XD; +def MOVAPDmr : I<0x29, MRMDestMem, (ops f128mem:$dst, V2F8:$src), + "movapd {$src, $dst|$dst, $src}",[]>, + Requires<[HasSSE2]>, XD; + +// Pseudo-instructions to load FR32 / FR64 from f128mem using movaps / movapd. +// Upper bits are disregarded. +def MOVSAPSrm : I<0x28, MRMSrcMem, (ops FR32:$dst, f128mem:$src), + "movaps {$src, $dst|$dst, $src}", + [(set FR32:$dst, (X86loadpf32 addr:$src))]>, + Requires<[HasSSE1]>, XS; +def MOVSAPDrm : I<0x28, MRMSrcMem, (ops FR64:$dst, f128mem:$src), + "movapd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (X86loadpf64 addr:$src))]>, + Requires<[HasSSE1]>, XD; + + +//===----------------------------------------------------------------------===// // Miscellaneous Instructions //===----------------------------------------------------------------------===// Index: llvm/lib/Target/X86/X86IntelAsmPrinter.h diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.5 llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.6 --- llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.5 Fri Dec 16 19:03:57 2005 +++ llvm/lib/Target/X86/X86IntelAsmPrinter.h Tue Jan 31 16:28:30 2006 @@ -76,8 +76,8 @@ O << "QWORD PTR "; printMemReference(MI, OpNo); } - void printf80mem(const MachineInstr *MI, unsigned OpNo) { - O << "XWORD PTR "; + void printf128mem(const MachineInstr *MI, unsigned OpNo) { + O << "XMMWORD PTR "; printMemReference(MI, OpNo); } From lattner at cs.uiuc.edu Tue Jan 31 16:59:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 16:59:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200601312259.QAA04210@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.34 -> 1.35 --- Log message: turning these into 'adds' would require extra copies --- Diffs of the changes: (+5 -7) README.txt | 12 +++++------- 1 files changed, 5 insertions(+), 7 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.34 llvm/lib/Target/X86/README.txt:1.35 --- llvm/lib/Target/X86/README.txt:1.34 Tue Jan 31 16:26:21 2006 +++ llvm/lib/Target/X86/README.txt Tue Jan 31 16:59:46 2006 @@ -247,21 +247,19 @@ _cmp: subl $4, %esp -1) leal 20(%esp), %eax + leal 20(%esp), %eax movss 12(%esp), %xmm0 -1) leal 16(%esp), %ecx + leal 16(%esp), %ecx ucomiss 8(%esp), %xmm0 cmovb %ecx, %eax -2) movss (%eax), %xmm0 -2) movss %xmm0, (%esp) +1) movss (%eax), %xmm0 +1) movss %xmm0, (%esp) flds (%esp) addl $4, %esp ret -1) These LEA's should be adds. This is tricky because they are FrameIndex's - before prolog-epilog rewriting. -2) We shouldn't load into XMM regs only to store it back. +1) We shouldn't load into XMM regs only to store it back. //===---------------------------------------------------------------------===// From evan.cheng at apple.com Tue Jan 31 17:20:06 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 17:20:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200601312320.RAA04325@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.72 -> 1.73 --- Log message: Be smarter about whether to store the SSE return value in memory. If it is already available in memory, do a fld directly from there. --- Diffs of the changes: (+16 -9) X86ISelLowering.cpp | 25 ++++++++++++++++--------- 1 files changed, 16 insertions(+), 9 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.72 llvm/lib/Target/X86/X86ISelLowering.cpp:1.73 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.72 Tue Jan 31 16:28:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 31 17:19:54 2006 @@ -1912,20 +1912,27 @@ Ops.push_back(Op.getOperand(1)); Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); } else { - // Spill the value to memory and reload it into top of stack. - unsigned Size = MVT::getSizeInBits(ArgVT)/8; - MachineFunction &MF = DAG.getMachineFunction(); - int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); - SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); - SDOperand Chain = DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), - Op.getOperand(1), StackSlot, - DAG.getSrcValue(0)); + SDOperand MemLoc, Chain; + SDOperand Value = Op.getOperand(1); + + if (Value.getOpcode() == ISD::LOAD) { + Chain = Value.getOperand(0); + MemLoc = Value.getOperand(1); + } else { + // Spill the value to memory and reload it into top of stack. + unsigned Size = MVT::getSizeInBits(ArgVT)/8; + MachineFunction &MF = DAG.getMachineFunction(); + int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size); + MemLoc = DAG.getFrameIndex(SSFI, getPointerTy()); + Chain = DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), + Value, MemLoc, DAG.getSrcValue(0)); + } std::vector Tys; Tys.push_back(MVT::f64); Tys.push_back(MVT::Other); std::vector Ops; Ops.push_back(Chain); - Ops.push_back(StackSlot); + Ops.push_back(MemLoc); Ops.push_back(DAG.getValueType(ArgVT)); Copy = DAG.getNode(X86ISD::FLD, Tys, Ops); Tys.clear(); From evan.cheng at apple.com Tue Jan 31 18:16:05 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 18:16:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602010016.SAA04596@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.35 -> 1.36 --- Log message: Remove an item. It's done. --- Diffs of the changes: (+0 -21) README.txt | 21 --------------------- 1 files changed, 21 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.35 llvm/lib/Target/X86/README.txt:1.36 --- llvm/lib/Target/X86/README.txt:1.35 Tue Jan 31 16:59:46 2006 +++ llvm/lib/Target/X86/README.txt Tue Jan 31 18:15:53 2006 @@ -242,27 +242,6 @@ //===---------------------------------------------------------------------===// -cd Regression/CodeGen/X86 -llvm-as < setuge.ll | llc -march=x86 -mcpu=yonah -enable-x86-sse - -_cmp: - subl $4, %esp - leal 20(%esp), %eax - movss 12(%esp), %xmm0 - leal 16(%esp), %ecx - ucomiss 8(%esp), %xmm0 - cmovb %ecx, %eax -1) movss (%eax), %xmm0 -1) movss %xmm0, (%esp) - flds (%esp) - addl $4, %esp - ret - - -1) We shouldn't load into XMM regs only to store it back. - -//===---------------------------------------------------------------------===// - Think about doing i64 math in SSE regs. //===---------------------------------------------------------------------===// From evan.cheng at apple.com Tue Jan 31 18:20:33 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 18:20:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200602010020.SAA04676@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.73 -> 1.74 --- Log message: When folding a load into a return of SSE value, check the chain to ensure the memory location has not been clobbered. --- Diffs of the changes: (+3 -2) X86ISelLowering.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.73 llvm/lib/Target/X86/X86ISelLowering.cpp:1.74 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.73 Tue Jan 31 17:19:54 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 31 18:20:21 2006 @@ -1912,10 +1912,11 @@ Ops.push_back(Op.getOperand(1)); Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops); } else { - SDOperand MemLoc, Chain; + SDOperand MemLoc; + SDOperand Chain = Op.getOperand(0); SDOperand Value = Op.getOperand(1); - if (Value.getOpcode() == ISD::LOAD) { + if (Value.getOpcode() == ISD::LOAD && Chain == Value.getOperand(0)) { Chain = Value.getOperand(0); MemLoc = Value.getOperand(1); } else { From lattner at cs.uiuc.edu Tue Jan 31 18:28:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 18:28:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602010028.SAA04730@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.50 -> 1.51 --- Log message: another testcase. --- Diffs of the changes: (+17 -0) README.txt | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.50 llvm/lib/Target/PowerPC/README.txt:1.51 --- llvm/lib/Target/PowerPC/README.txt:1.50 Tue Jan 31 01:16:34 2006 +++ llvm/lib/Target/PowerPC/README.txt Tue Jan 31 18:28:12 2006 @@ -460,3 +460,20 @@ This could be done in the dag combiner, by swapping a BR_CC when a SETCC of the same operands (but backwards) exists. In this case, this wouldn't save us anything though, because the compares still wouldn't be shared. + +===-------------------------------------------------------------------------=== + +A simple case we generate suboptimal code on: + +int test(int X) { + return X == 0 ? 32 : 0; +} + +_test: + cntlzw r2, r3 + srwi r2, r2, 5 + slwi r3, r2, 5 + blr + +The shifts should be one 'andi'. + From evan.cheng at apple.com Tue Jan 31 19:19:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 31 Jan 2006 19:19:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200602010119.TAA04974@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.74 -> 1.75 --- Log message: Return's chain should be matching either the chain produced by the value or the chain going into the load. --- Diffs of the changes: (+2 -1) X86ISelLowering.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.74 llvm/lib/Target/X86/X86ISelLowering.cpp:1.75 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.74 Tue Jan 31 18:20:21 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 31 19:19:32 2006 @@ -1916,7 +1916,8 @@ SDOperand Chain = Op.getOperand(0); SDOperand Value = Op.getOperand(1); - if (Value.getOpcode() == ISD::LOAD && Chain == Value.getOperand(0)) { + if (Value.getOpcode() == ISD::LOAD && + (Chain == Value.getValue(1) || Chain == Value.getOperand(0))) { Chain = Value.getOperand(0); MemLoc = Value.getOperand(1); } else { From lattner at cs.uiuc.edu Tue Jan 31 19:27:49 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:27:49 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/InlineAsm.h Message-ID: <200602010127.TAA05080@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: InlineAsm.h updated: 1.6 -> 1.7 --- Log message: Beef up the interface to inline asm constraint parsing, making it more general, useful, and easier to use. --- Diffs of the changes: (+27 -3) InlineAsm.h | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) Index: llvm/include/llvm/InlineAsm.h diff -u llvm/include/llvm/InlineAsm.h:1.6 llvm/include/llvm/InlineAsm.h:1.7 --- llvm/include/llvm/InlineAsm.h:1.6 Wed Jan 25 20:21:42 2006 +++ llvm/include/llvm/InlineAsm.h Tue Jan 31 19:27:37 2006 @@ -70,17 +70,41 @@ enum ConstraintPrefix { isInput, // 'x' isOutput, // '=x' - isIndirectOutput, // '==x' isClobber, // '~x' }; + struct ConstraintInfo { + /// Type - The basic type of the constraint: input/output/clobber + /// + ConstraintPrefix Type; + + /// isEarlyClobber - "&": output operand writes result before inputs are all + /// read. This is only ever set for an output operand. + bool isEarlyClobber; + + /// isIndirectOutput - If this is true for an output constraint, the address + /// to store the output result is passed as an operand to the call. + bool isIndirectOutput; + + /// Code - The constraint code, either the register name (in braces) or the + /// constraint letter/number. + std::vector Codes; + + /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the + /// fields in this structure. If the constraint string is not understood, + /// return true, otherwise return false. + bool Parse(const std::string &Str); + }; + /// ParseConstraints - Split up the constraint string into the specific /// constraints and their prefixes. If this returns an empty vector, and if /// the constraint string itself isn't empty, there was an error parsing. - static std::vector > + static std::vector ParseConstraints(const std::string &ConstraintString); - std::vector > + /// ParseConstraints - Parse the constraints of this inlineasm object, + /// returning them the same way that ParseConstraints(str) does. + std::vector ParseConstraints() const { return ParseConstraints(Constraints); } From lattner at cs.uiuc.edu Tue Jan 31 19:28:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:28:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602010128.TAA05160@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.43 -> 1.44 --- Log message: adjust to changes in InlineAsm interface. Fix a few minor bugs. --- Diffs of the changes: (+4 -0) AsmPrinter.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.43 llvm/lib/CodeGen/AsmPrinter.cpp:1.44 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.43 Tue Jan 31 16:21:33 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Tue Jan 31 19:28:23 2006 @@ -472,4 +472,8 @@ const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); O << AsmStr << "\n"; + + // Use a virtual "printAsmOperand" method, which takes the constraint + // string? Must pass the constraint string to here if needed. + } From lattner at cs.uiuc.edu Tue Jan 31 19:28:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:28:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602010128.TAA05164@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.143 -> 1.144 --- Log message: adjust to changes in InlineAsm interface. Fix a few minor bugs. --- Diffs of the changes: (+38 -32) SelectionDAGISel.cpp | 70 +++++++++++++++++++++++++++------------------------ 1 files changed, 38 insertions(+), 32 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.143 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.144 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.143 Mon Jan 30 20:03:41 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jan 31 19:28:23 2006 @@ -1156,8 +1156,7 @@ // could not choose to not chain it. bool hasSideEffects = IA->hasSideEffects(); - std::vector > - Constraints = IA->ParseConstraints(); + std::vector Constraints = IA->ParseConstraints(); /// AsmNodeOperands - A list of pairs. The first element is a register, the /// second is a bitfield where bit #0 is set if it is a use and bit #1 is set @@ -1175,55 +1174,62 @@ std::vector > IndirectStoresToEmit; unsigned OpNum = 1; bool FoundOutputConstraint = false; + //std::set OutputRegs; + //std::set InputRegs; + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - switch (Constraints[i].first) { - case InlineAsm::isOutput: { - assert(!FoundOutputConstraint && - "Cannot have multiple output constraints yet!"); - FoundOutputConstraint = true; - assert(I.getType() != Type::VoidTy && "Bad inline asm!"); - // Copy the output from the appropriate register. - std::vector Regs = - TLI.getRegForInlineAsmConstraint(Constraints[i].second); - assert(Regs.size() == 1 && "Only handle simple regs right now!"); - RetValReg = Regs[0]; + assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); + std::string &ConstraintCode = Constraints[i].Codes[0]; + switch (Constraints[i].Type) { + case InlineAsm::isOutput: { + bool isEarlyClobber = Constraints[i].isEarlyClobber; - // Add information to the INLINEASM node to know that this register is - // set. - AsmNodeOperands.push_back(DAG.getRegister(RetValReg, - TLI.getValueType(I.getType()))); - AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF - break; - } - case InlineAsm::isIndirectOutput: { // Copy the output from the appropriate register. std::vector Regs = - TLI.getRegForInlineAsmConstraint(Constraints[i].second); + TLI.getRegForInlineAsmConstraint(ConstraintCode); assert(Regs.size() == 1 && "Only handle simple regs right now!"); - IndirectStoresToEmit.push_back(std::make_pair(Regs[0], - I.getOperand(OpNum))); - OpNum++; // Consumes a call operand. + unsigned DestReg = Regs[0]; + + const Type *OpTy; + if (!Constraints[i].isIndirectOutput) { + assert(!FoundOutputConstraint && + "Cannot have multiple output constraints yet!"); + FoundOutputConstraint = true; + assert(I.getType() != Type::VoidTy && "Bad inline asm!"); + + RetValReg = DestReg; + OpTy = I.getType(); + } else { + IndirectStoresToEmit.push_back(std::make_pair(DestReg, + I.getOperand(OpNum))); + OpTy = I.getOperand(OpNum)->getType(); + OpTy = cast(OpTy)->getElementType(); + OpNum++; // Consumes a call operand. + } // Add information to the INLINEASM node to know that this register is // set. - AsmNodeOperands.push_back(DAG.getRegister(Regs[0], - TLI.getValueType(I.getType()))); + AsmNodeOperands.push_back(DAG.getRegister(DestReg, + TLI.getValueType(OpTy))); AsmNodeOperands.push_back(DAG.getConstant(2, MVT::i32)); // ISDEF + break; } case InlineAsm::isInput: { + Value *Operand = I.getOperand(OpNum); + const Type *OpTy = Operand->getType(); + // Copy the input into the appropriate register. std::vector Regs = - TLI.getRegForInlineAsmConstraint(Constraints[i].second); + TLI.getRegForInlineAsmConstraint(ConstraintCode); assert(Regs.size() == 1 && "Only handle simple regs right now!"); - Chain = DAG.getCopyToReg(Chain, Regs[0], - getValue(I.getOperand(OpNum)), Flag); + unsigned SrcReg = Regs[0]; + Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag); Flag = Chain.getValue(1); // Add information to the INLINEASM node to know that this register is // read. - AsmNodeOperands.push_back(DAG.getRegister(Regs[0], - TLI.getValueType(I.getType()))); + AsmNodeOperands.push_back(DAG.getRegister(SrcReg,TLI.getValueType(OpTy))); AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE break; } From lattner at cs.uiuc.edu Tue Jan 31 19:29:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:29:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602010129.TAA05230@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.24 -> 1.25 --- Log message: Beef up the interface to inline asm constraint parsing, making it more general, useful, and easier to use. --- Diffs of the changes: (+10 -3) TargetLowering.cpp | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.24 llvm/lib/Target/TargetLowering.cpp:1.25 --- llvm/lib/Target/TargetLowering.cpp:1.24 Sun Jan 29 22:09:04 2006 +++ llvm/lib/Target/TargetLowering.cpp Tue Jan 31 19:29:22 2006 @@ -243,15 +243,22 @@ std::vector TargetLowering:: getRegForInlineAsmConstraint(const std::string &Constraint) const { + // Not a physreg, must not be a register reference or something. + if (Constraint[0] != '{') return std::vector(); + assert(*(Constraint.end()-1) == '}' && "Not a brace enclosed constraint?"); + + // Remove the braces from around the name. + std::string RegName(Constraint.begin()+1, Constraint.end()-1); + // Scan to see if this constraint is a register name. const MRegisterInfo *RI = TM.getRegisterInfo(); for (unsigned i = 1, e = RI->getNumRegs(); i != e; ++i) { if (const char *Name = RI->get(i).Name) - if (StringsEqualNoCase(Constraint, Name)) + if (StringsEqualNoCase(RegName, Name)) return std::vector(1, i); } - - // Not a physreg, must not be a register reference or something. + + // Unknown physreg. return std::vector(); } From lattner at cs.uiuc.edu Tue Jan 31 19:29:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:29:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/InlineAsm.cpp Message-ID: <200602010129.TAA05291@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: InlineAsm.cpp updated: 1.5 -> 1.6 --- Log message: Beef up the interface to inline asm constraint parsing, making it more general, useful, and easier to use. --- Diffs of the changes: (+96 -44) InlineAsm.cpp | 140 +++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 96 insertions(+), 44 deletions(-) Index: llvm/lib/VMCore/InlineAsm.cpp diff -u llvm/lib/VMCore/InlineAsm.cpp:1.5 llvm/lib/VMCore/InlineAsm.cpp:1.6 --- llvm/lib/VMCore/InlineAsm.cpp:1.5 Wed Jan 25 20:21:59 2006 +++ llvm/lib/VMCore/InlineAsm.cpp Tue Jan 31 19:29:47 2006 @@ -38,50 +38,101 @@ return cast(getType()->getElementType()); } -std::vector > -InlineAsm::ParseConstraints(const std::string &Constraints) { - std::vector > Result; +/// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the +/// fields in this structure. If the constraint string is not understood, +/// return true, otherwise return false. +bool InlineAsm::ConstraintInfo::Parse(const std::string &Str) { + std::string::const_iterator I = Str.begin(), E = Str.end(); + + // Initialize + Type = isInput; + isEarlyClobber = false; + isIndirectOutput =false; + + // Parse the prefix. + if (*I == '~') { + Type = isClobber; + ++I; + } else if (*I == '=') { + ++I; + Type = isOutput; + if (I != E && *I == '=') { + isIndirectOutput = true; + ++I; + } + } - // Scan the constraints string. - for (std::string::const_iterator I = Constraints.begin(), - E = Constraints.end(); I != E; ) { - if (*I == ',') { Result.clear(); break; } // Empty constraint like ",," - - // Parse the prefix. - ConstraintPrefix ConstraintType = isInput; + if (I == E) return true; // Just a prefix, like "==" or "~". + + // Parse the modifiers. + bool DoneWithModifiers = false; + while (!DoneWithModifiers) { + switch (*I) { + default: + DoneWithModifiers = true; + break; + case '&': + if (Type != isOutput || // Cannot early clobber anything but output. + isEarlyClobber) // Reject &&&&&& + return true; + isEarlyClobber = true; + break; + } - if (*I == '~') { - ConstraintType = isClobber; + if (!DoneWithModifiers) { ++I; - } else if (*I == '=') { - ++I; - if (I != E && *I == '=') { - ConstraintType = isIndirectOutput; + if (I == E) return true; // Just prefixes and modifiers! + } + } + + // Parse the various constraints. + while (I != E) { + if (*I == '{') { // Physical register reference. + // Find the end of the register name. + std::string::const_iterator ConstraintEnd = std::find(I+1, E, '}'); + if (ConstraintEnd == E) return true; // "{foo" + Codes.push_back(std::string(I, ConstraintEnd+1)); + I = ConstraintEnd+1; + } else if (isdigit(*I)) { + // Maximal munch numbers. + std::string::const_iterator NumStart = I; + while (I != E && isdigit(*I)) ++I; - } else { - ConstraintType = isOutput; - } + Codes.push_back(std::string(NumStart, I)); + } else { + // Single letter constraint. + Codes.push_back(std::string(I, I+1)); + ++I; } - - if (I == E) { Result.clear(); break; } // Just a prefix, like "==" or "~". - - std::string::const_iterator IdStart = I; - - // Parse the id. We accept [a-zA-Z0-9] currently. - while (I != E && isalnum(*I)) ++I; - - if (IdStart == I) { // Requires more than just a prefix + } + + return false; +} + +std::vector +InlineAsm::ParseConstraints(const std::string &Constraints) { + std::vector Result; + + // Scan the constraints string. + for (std::string::const_iterator I = Constraints.begin(), + E = Constraints.end(); I != E; ) { + ConstraintInfo Info; + + // Find the end of this constraint. + std::string::const_iterator ConstraintEnd = std::find(I, E, ','); + + if (ConstraintEnd == I || // Empty constraint like ",," + Info.Parse(std::string(I, ConstraintEnd))) { // Erroneous constraint? Result.clear(); break; } + + Result.push_back(Info); - // Remember this constraint. - Result.push_back(std::make_pair(ConstraintType, std::string(IdStart, I))); - - // If we reached the end of the ID, we must have the end of the string or a - // comma, which we skip now. + // ConstraintEnd may be either the next comma or the end of the string. In + // the former case, we skip the comma. + I = ConstraintEnd; if (I != E) { - if (*I != ',') { Result.clear(); break; } ++I; if (I == E) { Result.clear(); break; } // don't allow "xyz," } @@ -96,8 +147,7 @@ bool InlineAsm::Verify(const FunctionType *Ty, const std::string &ConstStr) { if (Ty->isVarArg()) return false; - std::vector > - Constraints = ParseConstraints(ConstStr); + std::vector Constraints = ParseConstraints(ConstStr); // Error parsing constraints. if (Constraints.empty() && !ConstStr.empty()) return false; @@ -105,17 +155,19 @@ unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { - switch (Constraints[i].first) { - case isOutput: - if (NumInputs || NumClobbers) return false; // outputs come first. - ++NumOutputs; - break; - case isInput: - case isIndirectOutput: + switch (Constraints[i].Type) { + case InlineAsm::isOutput: + if (!Constraints[i].isIndirectOutput) { + if (NumInputs || NumClobbers) return false; // outputs come first. + ++NumOutputs; + break; + } + // FALLTHROUGH for IndirectOutputs. + case InlineAsm::isInput: if (NumClobbers) return false; // inputs before clobbers. ++NumInputs; break; - case isClobber: + case InlineAsm::isClobber: ++NumClobbers; break; } From lattner at cs.uiuc.edu Tue Jan 31 19:44:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:44:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602010144.TAA05562@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.36 -> 1.37 --- Log message: Another regression from the pattern isel --- Diffs of the changes: (+16 -0) README.txt | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.36 llvm/lib/Target/X86/README.txt:1.37 --- llvm/lib/Target/X86/README.txt:1.36 Tue Jan 31 18:15:53 2006 +++ llvm/lib/Target/X86/README.txt Tue Jan 31 19:44:25 2006 @@ -288,3 +288,19 @@ This is bad for register pressure, though the dag isel is producing a better schedule. :) + +//===---------------------------------------------------------------------===// + +This testcase should have no SSE instructions in it, and only one load from +a constant pool: + +double %test3(bool %B) { + %C = select bool %B, double 123.412, double 523.01123123 + ret double %C +} + +Currently, the select is being lowered, which prevents the dag combiner from +turning 'select (load CPI1), (load CPI2)' -> 'load (select CPI1, CPI2)' + +The pattern isel got this one right. + From lattner at cs.uiuc.edu Tue Jan 31 19:45:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue, 31 Jan 2006 19:45:14 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/sse-load-ret.ll Message-ID: <200602010145.TAA05629@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: sse-load-ret.ll added (r1.1) --- Log message: new testcase for the 'ret double folding with load' opzn --- Diffs of the changes: (+19 -0) sse-load-ret.ll | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/test/Regression/CodeGen/X86/sse-load-ret.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/sse-load-ret.ll:1.1 *** /dev/null Tue Jan 31 19:45:12 2006 --- llvm/test/Regression/CodeGen/X86/sse-load-ret.ll Tue Jan 31 19:45:02 2006 *************** *** 0 **** --- 1,19 ---- + ; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah -enable-x86-sse && + ; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah -enable-x86-sse | not grep movss + ; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah -enable-x86-sse | not grep xmm + + double %test1(double *%P) { + %X = load double* %P + ret double %X + } + + double %test2() { + ret double 1234.56 + } + + ; FIXME: Todo + ;double %test3(bool %B) { + ; %C = select bool %B, double 123.412, double 523.01123123 + ; ret double %C + ;} + From jeffc at jolt-lang.org Tue Jan 31 22:37:15 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Tue, 31 Jan 2006 22:37:15 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/InlineAsm.cpp Message-ID: <200602010437.WAA06126@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: InlineAsm.cpp updated: 1.6 -> 1.7 --- Log message: Fix VC++ compilation error. --- Diffs of the changes: (+1 -0) InlineAsm.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/VMCore/InlineAsm.cpp diff -u llvm/lib/VMCore/InlineAsm.cpp:1.6 llvm/lib/VMCore/InlineAsm.cpp:1.7 --- llvm/lib/VMCore/InlineAsm.cpp:1.6 Tue Jan 31 19:29:47 2006 +++ llvm/lib/VMCore/InlineAsm.cpp Tue Jan 31 22:37:04 2006 @@ -13,6 +13,7 @@ #include "llvm/InlineAsm.h" #include "llvm/DerivedTypes.h" +#include #include using namespace llvm; From evan.cheng at apple.com Wed Feb 1 00:06:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 00:06:43 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602010606.AAA06474@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.158 -> 1.159 --- Log message: If a pattern's root node is a constant, its size should be 3 rather than 2. --- Diffs of the changes: (+4 -0) DAGISelEmitter.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.158 llvm/utils/TableGen/DAGISelEmitter.cpp:1.159 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.158 Sun Jan 29 14:01:35 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Wed Feb 1 00:06:31 2006 @@ -1709,6 +1709,10 @@ P->getExtTypeNum(0) == MVT::Flag && "Not a valid pattern node to size!"); unsigned Size = 2; // The node itself. + // If the root node is a ConstantSDNode, increases its size. + // e.g. (set R32:$dst, 0). + if (P->isLeaf() && dynamic_cast(P->getLeafValue())) + Size++; // FIXME: This is a hack to statically increase the priority of patterns // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. From evan.cheng at apple.com Wed Feb 1 00:09:00 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 00:09:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602010609.AAA06507@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.37 -> 1.38 --- Log message: Remove another entry. --- Diffs of the changes: (+0 -5) README.txt | 5 ----- 1 files changed, 5 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.37 llvm/lib/Target/X86/README.txt:1.38 --- llvm/lib/Target/X86/README.txt:1.37 Tue Jan 31 19:44:25 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 1 00:08:48 2006 @@ -227,11 +227,6 @@ //===---------------------------------------------------------------------===// -This instruction selector selects 'int X = 0' as 'mov Reg, 0' not 'xor Reg,Reg' -This is bigger and slower. - -//===---------------------------------------------------------------------===// - LSR should be turned on for the X86 backend and tuned to take advantage of its addressing modes. From evan.cheng at apple.com Wed Feb 1 00:14:02 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 00:14:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.td X86CodeEmitter.cpp X86InstrInfo.h X86InstrInfo.td Message-ID: <200602010614.AAA06609@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.td updated: 1.21 -> 1.22 X86CodeEmitter.cpp updated: 1.86 -> 1.87 X86InstrInfo.h updated: 1.48 -> 1.49 X86InstrInfo.td updated: 1.226 -> 1.227 --- Log message: - Use xor to clear integer registers (set R, 0). - Added a new format for instructions where the source register is implied and it is same as the destination register. Used for pseudo instructions that clear the destination register. --- Diffs of the changes: (+39 -17) X86.td | 8 ++++---- X86CodeEmitter.cpp | 7 ++++++- X86InstrInfo.h | 18 +++++++++++------- X86InstrInfo.td | 23 ++++++++++++++++++----- 4 files changed, 39 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86.td diff -u llvm/lib/Target/X86/X86.td:1.21 llvm/lib/Target/X86/X86.td:1.22 --- llvm/lib/Target/X86/X86.td:1.21 Tue Jan 31 13:43:35 2006 +++ llvm/lib/Target/X86/X86.td Wed Feb 1 00:13:50 2006 @@ -110,11 +110,11 @@ "FPFormBits", "Opcode"]; let TSFlagsShifts = [0, - 5, 6, - 10, - 12, - 16]; + 7, + 11, + 13, + 17]; } // The X86 target supports two different syntaxes for emitting machine code. Index: llvm/lib/Target/X86/X86CodeEmitter.cpp diff -u llvm/lib/Target/X86/X86CodeEmitter.cpp:1.86 llvm/lib/Target/X86/X86CodeEmitter.cpp:1.87 --- llvm/lib/Target/X86/X86CodeEmitter.cpp:1.86 Sat Jan 28 12:19:37 2006 +++ llvm/lib/Target/X86/X86CodeEmitter.cpp Wed Feb 1 00:13:50 2006 @@ -473,7 +473,6 @@ case X86II::MRMSrcReg: MCE.emitByte(BaseOpcode); - emitRegModRMByte(MI.getOperand(1).getReg(), getX86RegNum(MI.getOperand(0).getReg())); if (MI.getNumOperands() == 3) @@ -518,5 +517,11 @@ assert(0 && "Unknown operand!"); } break; + + case X86II::MRMInitReg: + MCE.emitByte(BaseOpcode); + emitRegModRMByte(MI.getOperand(0).getReg(), + getX86RegNum(MI.getOperand(0).getReg())); + break; } } Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.48 llvm/lib/Target/X86/X86InstrInfo.h:1.49 --- llvm/lib/Target/X86/X86InstrInfo.h:1.48 Wed Jul 27 00:53:44 2005 +++ llvm/lib/Target/X86/X86InstrInfo.h Wed Feb 1 00:13:50 2006 @@ -75,7 +75,11 @@ MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27, // Format /0 /1 /2 /3 MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31, // Format /4 /5 /6 /7 - FormMask = 31, + // MRMInitReg - This form is used for instructions whose source and + // destinations are the same register. + MRMInitReg = 32, + + FormMask = 63, //===------------------------------------------------------------------===// // Actual flags... @@ -83,14 +87,14 @@ // OpSize - Set if this instruction requires an operand size prefix (0x66), // which most often indicates that the instruction operates on 16 bit data // instead of 32 bit data. - OpSize = 1 << 5, + OpSize = 1 << 6, // Op0Mask - There are several prefix bytes that are used to form two byte // opcodes. These are currently 0x0F, 0xF3, and 0xD8-0xDF. This mask is // used to obtain the setting of this field. If no bits in this field is // set, there is no prefix byte for obtaining a multibyte opcode. // - Op0Shift = 6, + Op0Shift = 7, Op0Mask = 0xF << Op0Shift, // TB - TwoByte - Set if this instruction has a two byte opcode, which @@ -115,7 +119,7 @@ //===------------------------------------------------------------------===// // This two-bit field describes the size of an immediate operand. Zero is // unused so that we can tell if we forgot to set a value. - ImmShift = 10, + ImmShift = 11, ImmMask = 7 << ImmShift, Imm8 = 1 << ImmShift, Imm16 = 2 << ImmShift, @@ -125,7 +129,7 @@ // FP Instruction Classification... Zero is non-fp instruction. // FPTypeMask - Mask for all of the FP types... - FPTypeShift = 12, + FPTypeShift = 13, FPTypeMask = 7 << FPTypeShift, // NotFP - The default, set for instructions that do not use FP registers. @@ -158,9 +162,9 @@ SpecialFP = 7 << FPTypeShift, // Bit 15 is unused. - OpcodeShift = 16, + OpcodeShift = 17, OpcodeMask = 0xFF << OpcodeShift, - // Bits 24 -> 31 are unused + // Bits 25 -> 31 are unused }; } Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.226 llvm/lib/Target/X86/X86InstrInfo.td:1.227 --- llvm/lib/Target/X86/X86InstrInfo.td:1.226 Tue Jan 31 16:28:30 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Feb 1 00:13:50 2006 @@ -180,8 +180,8 @@ // Format specifies the encoding used by the instruction. This is part of the // ad-hoc solution used to emit machine instruction encodings by our machine // code emitter. -class Format val> { - bits<5> Value = val; +class Format val> { + bits<6> Value = val; } def Pseudo : Format<0>; def RawFrm : Format<1>; @@ -194,6 +194,7 @@ def MRM0m : Format<24>; def MRM1m : Format<25>; def MRM2m : Format<26>; def MRM3m : Format<27>; def MRM4m : Format<28>; def MRM5m : Format<29>; def MRM6m : Format<30>; def MRM7m : Format<31>; +def MRMInitReg : Format<32>; //===----------------------------------------------------------------------===// // X86 Instruction Predicate Definitions. @@ -238,7 +239,7 @@ bits<8> Opcode = opcod; Format Form = f; - bits<5> FormBits = Form.Value; + bits<6> FormBits = Form.Value; ImmType ImmT = i; bits<2> ImmTypeBits = ImmT.Value; @@ -708,6 +709,18 @@ "mov{l} {$src, $dst|$dst, $src}", [(store R32:$src, addr:$dst)]>; +// Pseudo-instructions that map movr0 to xor. +// FIXME: remove when we can teach regalloc that xor reg, reg is ok. +def MOV8r0 : I<0x30, MRMInitReg, (ops R8 :$dst), + "xor{b} $dst, $dst", + [(set R8:$dst, 0)]>; +def MOV16r0 : I<0x31, MRMInitReg, (ops R16:$dst), + "xor{w} $dst, $dst", + [(set R16:$dst, 0)]>, OpSize; +def MOV32r0 : I<0x31, MRMInitReg, (ops R32:$dst), + "xor{l} $dst, $dst", + [(set R32:$dst, 0)]>; + //===----------------------------------------------------------------------===// // Fixed-Register Multiplication and Division Instructions... // @@ -2478,10 +2491,10 @@ // Pseudo-instructions that map fld0 to xorps/xorpd for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. -def FLD0SS : I<0x57, MRMSrcReg, (ops FR32:$dst), +def FLD0SS : I<0x57, MRMInitReg, (ops FR32:$dst), "xorps $dst, $dst", [(set FR32:$dst, fp32imm0)]>, Requires<[HasSSE1]>, TB; -def FLD0SD : I<0x57, MRMSrcReg, (ops FR64:$dst), +def FLD0SD : I<0x57, MRMInitReg, (ops FR64:$dst), "xorpd $dst, $dst", [(set FR64:$dst, fp64imm0)]>, Requires<[HasSSE2]>, TB, OpSize; From lattner at cs.uiuc.edu Wed Feb 1 00:40:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 00:40:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602010640.AAA06810@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.38 -> 1.39 --- Log message: add a note, I'll take care of this after nate commits his big patch --- Diffs of the changes: (+10 -0) README.txt | 10 ++++++++++ 1 files changed, 10 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.38 llvm/lib/Target/X86/README.txt:1.39 --- llvm/lib/Target/X86/README.txt:1.38 Wed Feb 1 00:08:48 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 1 00:40:32 2006 @@ -299,3 +299,13 @@ The pattern isel got this one right. +//===---------------------------------------------------------------------===// + +This shouldn't have an explicit ADD (target independent dag combiner hack): + +bool %X(int %X) { + %Y = add int %X, 14 + %Z = setne int %Y, 12345 + ret bool %Z +} + From evan.cheng at apple.com Wed Feb 1 00:51:08 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 00:51:08 -0600 Subject: [llvm-commits] CVS: llvm-test/MultiSource/Makefile.multisrc Message-ID: <200602010651.AAA06845@zion.cs.uiuc.edu> Changes in directory llvm-test/MultiSource: Makefile.multisrc updated: 1.49 -> 1.50 --- Log message: Link with instead of . This fixes a bunch of link failures on Darwin. --- Diffs of the changes: (+1 -1) Makefile.multisrc | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm-test/MultiSource/Makefile.multisrc diff -u llvm-test/MultiSource/Makefile.multisrc:1.49 llvm-test/MultiSource/Makefile.multisrc:1.50 --- llvm-test/MultiSource/Makefile.multisrc:1.49 Mon Jul 25 15:32:00 2005 +++ llvm-test/MultiSource/Makefile.multisrc Wed Feb 1 00:50:56 2006 @@ -69,4 +69,4 @@ endif Output/%.native: $(NObjects) - -$(CC) -o $@ $(NObjects) $(LDFLAGS) $(CFLAGS) + -$(CXX) -o $@ $(NObjects) $(LDFLAGS) $(CFLAGS) From natebegeman at mac.com Wed Feb 1 01:19:57 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 01:19:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelLowering.cpp README.txt Message-ID: <200602010719.BAA07034@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelLowering.cpp updated: 1.83 -> 1.84 README.txt updated: 1.51 -> 1.52 --- Log message: Fix some of the stuff in the PPC README file, and clean up legalization of the SELECT_CC, BR_CC, and BRTWOWAY_CC nodes. --- Diffs of the changes: (+38 -53) PPCISelLowering.cpp | 49 ++++++++++++++++++++++++++++++++++++++----------- README.txt | 42 ------------------------------------------ 2 files changed, 38 insertions(+), 53 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.83 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.84 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.83 Tue Jan 31 16:21:34 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed Feb 1 01:19:44 2006 @@ -13,6 +13,7 @@ #include "PPCISelLowering.h" #include "PPCTargetMachine.h" +#include "llvm/ADT/VectorExtras.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -20,7 +21,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Constants.h" #include "llvm/Function.h" -#include "llvm/ADT/VectorExtras.h" +#include "llvm/Support/MathExtras.h" using namespace llvm; PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) @@ -85,7 +86,7 @@ setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); - // PowerPC wants to optimize setcc i32, imm a bit. + // PowerPC wants to optimize integer setcc a bit setOperationAction(ISD::SETCC, MVT::i32, Custom); // PowerPC does not have BRCOND* which requires SetCC @@ -452,15 +453,41 @@ } case ISD::SETCC: { ISD::CondCode CC = cast(Op.getOperand(2))->get(); - if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) - if (C->getValue() && !C->isAllOnesValue()) - if (CC == ISD::SETEQ || CC == ISD::SETNE || - CC == ISD::SETLT || CC == ISD::SETGT) { - MVT::ValueType VT = Op.getValueType(); - SDOperand SUB = DAG.getNode(ISD::SUB, Op.getOperand(0).getValueType(), - Op.getOperand(0), Op.getOperand(1)); - return DAG.getSetCC(VT, SUB, DAG.getConstant(0, VT), CC); - } + + // If we're comparing for equality to zero, expose the fact that this is + // implented as a ctlz/srl pair on ppc, so that the dag combiner can + // fold the new nodes. + if (ConstantSDNode *C = dyn_cast(Op.getOperand(1))) { + if (C->isNullValue() && CC == ISD::SETEQ) { + MVT::ValueType VT = Op.getOperand(0).getValueType(); + SDOperand Zext = Op.getOperand(0); + if (VT < MVT::i32) { + VT = MVT::i32; + Zext = DAG.getNode(ISD::ZERO_EXTEND, VT, Op.getOperand(0)); + } + unsigned Log2b = Log2_32(MVT::getSizeInBits(VT)); + SDOperand Clz = DAG.getNode(ISD::CTLZ, VT, Zext); + SDOperand Scc = DAG.getNode(ISD::SRL, VT, Clz, + DAG.getConstant(Log2b, getShiftAmountTy())); + return DAG.getNode(ISD::TRUNCATE, getSetCCResultTy(), Scc); + } + // Leave comparisons against 0 and -1 alone for now, since they're usually + // optimized. FIXME: revisit this when we can custom lower all setcc + // optimizations. + if (C->isAllOnesValue() || C->isNullValue()) + break; + } + + // If we have an integer seteq/setne, turn it into a compare against zero + // by subtracting the rhs from the lhs, which is faster than setting a + // condition register, reading it back out, and masking the correct bit. + MVT::ValueType LHSVT = Op.getOperand(0).getValueType(); + if (MVT::isInteger(LHSVT) && (CC == ISD::SETEQ || CC == ISD::SETNE)) { + MVT::ValueType VT = Op.getValueType(); + SDOperand Sub = DAG.getNode(ISD::SUB, LHSVT, Op.getOperand(0), + Op.getOperand(1)); + return DAG.getSetCC(VT, Sub, DAG.getConstant(0, LHSVT), CC); + } break; } case ISD::VASTART: { Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.51 llvm/lib/Target/PowerPC/README.txt:1.52 --- llvm/lib/Target/PowerPC/README.txt:1.51 Tue Jan 31 18:28:12 2006 +++ llvm/lib/Target/PowerPC/README.txt Wed Feb 1 01:19:44 2006 @@ -280,32 +280,6 @@ ===-------------------------------------------------------------------------=== -For this: - -int h(int i, int j, int k) { - return (i==0||j==0||k == 0); -} - -We currently emit this: - -_h: - cntlzw r2, r3 - cntlzw r3, r4 - cntlzw r4, r5 - srwi r2, r2, 5 - srwi r3, r3, 5 - srwi r4, r4, 5 - or r2, r3, r2 - or r3, r2, r4 - blr - -The ctlz/shift instructions are created by the isel, so the dag combiner doesn't -have a chance to pull the shifts through the or's (eliminating two -instructions). SETCC nodes should be custom lowered in this case, not expanded -by the isel. - -===-------------------------------------------------------------------------=== - Darwin Stub LICM optimization: Loops like this: @@ -461,19 +435,3 @@ same operands (but backwards) exists. In this case, this wouldn't save us anything though, because the compares still wouldn't be shared. -===-------------------------------------------------------------------------=== - -A simple case we generate suboptimal code on: - -int test(int X) { - return X == 0 ? 32 : 0; -} - -_test: - cntlzw r2, r3 - srwi r2, r2, 5 - slwi r3, r2, 5 - blr - -The shifts should be one 'andi'. - From natebegeman at mac.com Wed Feb 1 01:19:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 01:19:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200602010719.BAA07038@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.75 -> 1.76 --- Log message: Fix some of the stuff in the PPC README file, and clean up legalization of the SELECT_CC, BR_CC, and BRTWOWAY_CC nodes. --- Diffs of the changes: (+2 -0) X86ISelLowering.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.75 llvm/lib/Target/X86/X86ISelLowering.cpp:1.76 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.75 Tue Jan 31 19:19:32 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Feb 1 01:19:44 2006 @@ -117,6 +117,8 @@ } setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); + setOperationAction(ISD::BR_CC , MVT::Other, Expand); + setOperationAction(ISD::SELECT_CC , MVT::Other, Expand); setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16 , Expand); setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); From natebegeman at mac.com Wed Feb 1 01:19:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 01:19:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/IA64/IA64ISelLowering.cpp Message-ID: <200602010719.BAA07042@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/IA64: IA64ISelLowering.cpp updated: 1.32 -> 1.33 --- Log message: Fix some of the stuff in the PPC README file, and clean up legalization of the SELECT_CC, BR_CC, and BRTWOWAY_CC nodes. --- Diffs of the changes: (+4 -0) IA64ISelLowering.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/IA64/IA64ISelLowering.cpp diff -u llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.32 llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.33 --- llvm/lib/Target/IA64/IA64ISelLowering.cpp:1.32 Sun Jan 29 00:26:07 2006 +++ llvm/lib/Target/IA64/IA64ISelLowering.cpp Wed Feb 1 01:19:44 2006 @@ -35,10 +35,14 @@ // register class for predicate registers addRegisterClass(MVT::i1, IA64::PRRegisterClass); + setOperationAction(ISD::BR_CC , MVT::Other, Expand); setOperationAction(ISD::BRCONDTWOWAY , MVT::Other, Expand); setOperationAction(ISD::BRTWOWAY_CC , MVT::Other, Expand); setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand); + // ia64 uses SELECT not SELECT_CC + setOperationAction(ISD::SELECT_CC , MVT::Other, Expand); + // We need to handle ISD::RET for void functions ourselves, // so we get a chance to restore ar.pfs before adding a // br.ret insn From natebegeman at mac.com Wed Feb 1 01:19:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 01:19:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaISelLowering.cpp Message-ID: <200602010719.BAA07052@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaISelLowering.cpp updated: 1.36 -> 1.37 --- Log message: Fix some of the stuff in the PPC README file, and clean up legalization of the SELECT_CC, BR_CC, and BRTWOWAY_CC nodes. --- Diffs of the changes: (+2 -0) AlphaISelLowering.cpp | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/Alpha/AlphaISelLowering.cpp diff -u llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.36 llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.37 --- llvm/lib/Target/Alpha/AlphaISelLowering.cpp:1.36 Tue Jan 31 16:21:34 2006 +++ llvm/lib/Target/Alpha/AlphaISelLowering.cpp Wed Feb 1 01:19:44 2006 @@ -56,6 +56,8 @@ setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); + setOperationAction(ISD::BR_CC, MVT::Other, Expand); + setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); From natebegeman at mac.com Wed Feb 1 01:19:58 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 01:19:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp Message-ID: <200602010719.BAA07048@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.90 -> 1.91 LegalizeDAG.cpp updated: 1.299 -> 1.300 --- Log message: Fix some of the stuff in the PPC README file, and clean up legalization of the SELECT_CC, BR_CC, and BRTWOWAY_CC nodes. --- Diffs of the changes: (+254 -222) DAGCombiner.cpp | 52 ++++++ LegalizeDAG.cpp | 424 +++++++++++++++++++++++++++----------------------------- 2 files changed, 254 insertions(+), 222 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.90 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.91 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.90 Sun Jan 29 22:09:27 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Feb 1 01:19:44 2006 @@ -1081,6 +1081,16 @@ WorkList.push_back(ORNode.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode); } + // fold (or (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (or x, y)) + if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) || + (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) || + (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) && + N0.getOperand(1) == N1.getOperand(1)) { + SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(ORNode.Val); + return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1)); + } // canonicalize shl to left side in a shl/srl pair, to match rotate if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL) std::swap(N0, N1); @@ -1196,6 +1206,16 @@ WorkList.push_back(XORNode.Val); return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode); } + // fold (xor (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (xor x, y)) + if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) || + (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) || + (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) && + N0.getOperand(1) == N1.getOperand(1)) { + SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); + WorkList.push_back(XORNode.Val); + return DAG.getNode(N0.getOpcode(), VT, XORNode, N0.getOperand(1)); + } return SDOperand(); } @@ -1396,14 +1416,20 @@ // fold X ? Y : X --> X ? Y : 0 --> X & Y if (MVT::i1 == VT && N0 == N2) return DAG.getNode(ISD::AND, VT, N0, N1); - // If we can fold this based on the true/false value, do so. if (SimplifySelectOps(N, N1, N2)) return SDOperand(); - // fold selects based on a setcc into other things, such as min/max/abs if (N0.getOpcode() == ISD::SETCC) - return SimplifySelect(N0, N1, N2); + // FIXME: + // Check against MVT::Other for SELECT_CC, which is a workaround for targets + // having to say they don't support SELECT_CC on every type the DAG knows + // about, since there is no way to mark an opcode illegal at all value types + if (TLI.isOperationLegal(ISD::SELECT_CC, MVT::Other)) + return DAG.getNode(ISD::SELECT_CC, VT, N0.getOperand(0), N0.getOperand(1), + N1, N2, N0.getOperand(2)); + else + return SimplifySelect(N0, N1, N2); return SDOperand(); } @@ -1927,6 +1953,13 @@ // unconditional branch if (N1C && N1C->getValue() == 1) return DAG.getNode(ISD::BR, MVT::Other, Chain, N2); + // fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal + // on the target. + if (N1.getOpcode() == ISD::SETCC && + TLI.isOperationLegal(ISD::BR_CC, MVT::Other)) { + return DAG.getNode(ISD::BR_CC, MVT::Other, Chain, N1.getOperand(2), + N1.getOperand(0), N1.getOperand(1), N2); + } return SDOperand(); } @@ -1943,6 +1976,19 @@ // unconditional branch to false mbb if (N1C && N1C->isNullValue()) return DAG.getNode(ISD::BR, MVT::Other, Chain, N3); + // fold a brcondtwoway with a setcc condition into a BRTWOWAY_CC node if + // BRTWOWAY_CC is legal on the target. + if (N1.getOpcode() == ISD::SETCC && + TLI.isOperationLegal(ISD::BRTWOWAY_CC, MVT::Other)) { + std::vector Ops; + Ops.push_back(Chain); + Ops.push_back(N1.getOperand(2)); + Ops.push_back(N1.getOperand(0)); + Ops.push_back(N1.getOperand(1)); + Ops.push_back(N2); + Ops.push_back(N3); + return DAG.getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops); + } return SDOperand(); } Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.299 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.300 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.299 Tue Jan 31 12:14:25 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Feb 1 01:19:44 2006 @@ -106,6 +106,8 @@ void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi); SDOperand PromoteOp(SDOperand O); + void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC); + SDOperand ExpandLibCall(const char *Name, SDNode *Node, SDOperand &Hi); SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, @@ -717,33 +719,22 @@ break; case ISD::BR_CC: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - if (!isTypeLegal(Node->getOperand(2).getValueType())) { - Tmp2 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), - Node->getOperand(2), // LHS - Node->getOperand(3), // RHS - Node->getOperand(1))); - // If we get a SETCC back from legalizing the SETCC node we just - // created, then use its LHS, RHS, and CC directly in creating a new - // node. Otherwise, select between the true and false value based on - // comparing the result of the legalized with zero. - if (Tmp2.getOpcode() == ISD::SETCC) { - Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Tmp2.getOperand(2), - Tmp2.getOperand(0), Tmp2.getOperand(1), - Node->getOperand(4)); - } else { - Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, - DAG.getCondCode(ISD::SETNE), - Tmp2, DAG.getConstant(0, Tmp2.getValueType()), - Node->getOperand(4)); - } - break; + Tmp2 = Node->getOperand(2); // LHS + Tmp3 = Node->getOperand(3); // RHS + Tmp4 = Node->getOperand(1); // CC + + LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4); + + // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands, + // the LHS is a legal SETCC itself. In this case, we need to compare + // the result against zero to select between true and false values. + if (Tmp3.Val == 0) { + Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); + Tmp4 = DAG.getCondCode(ISD::SETNE); } - - Tmp2 = LegalizeOp(Node->getOperand(2)); // LHS - Tmp3 = LegalizeOp(Node->getOperand(3)); // RHS - - Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1), Tmp2, - Tmp3, Node->getOperand(4)); + + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp4, Tmp2, Tmp3, + Node->getOperand(4)); switch (TLI.getOperationAction(ISD::BR_CC, Tmp3.getValueType())) { default: assert(0 && "Unexpected action for BR_CC!"); @@ -805,61 +796,44 @@ break; } break; - case ISD::BRTWOWAY_CC: + case ISD::BRTWOWAY_CC: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. - if (isTypeLegal(Node->getOperand(2).getValueType())) { - Tmp2 = LegalizeOp(Node->getOperand(2)); // LHS - Tmp3 = LegalizeOp(Node->getOperand(3)); // RHS - if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2) || - Tmp3 != Node->getOperand(3)) { - std::vector Ops; - Ops.push_back(Tmp1); - Ops.push_back(Node->getOperand(1)); - Ops.push_back(Tmp2); - Ops.push_back(Tmp3); - Ops.push_back(Node->getOperand(4)); - Ops.push_back(Node->getOperand(5)); - Result = DAG.UpdateNodeOperands(Result, Ops); - } + Tmp2 = Node->getOperand(2); // LHS + Tmp3 = Node->getOperand(3); // RHS + Tmp4 = Node->getOperand(1); // CC + + LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4); + + // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands, + // the LHS is a legal SETCC itself. In this case, we need to compare + // the result against zero to select between true and false values. + if (Tmp3.Val == 0) { + Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); + Tmp4 = DAG.getCondCode(ISD::SETNE); + } + std::vector Ops; + Ops.push_back(Tmp1); + Ops.push_back(Tmp4); + Ops.push_back(Tmp2); + Ops.push_back(Tmp3); + Ops.push_back(Node->getOperand(4)); + Ops.push_back(Node->getOperand(5)); + Result = DAG.UpdateNodeOperands(Result, Ops); + + // Everything is legal, see if we should expand this op or something. + switch (TLI.getOperationAction(ISD::BRTWOWAY_CC, MVT::Other)) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: break; + case TargetLowering::Expand: + Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, + DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), Tmp2, + Tmp3, Tmp4), + Result.getOperand(4)); + Result = DAG.getNode(ISD::BR, MVT::Other, Result, Result.getOperand(5)); break; - } else { - Tmp2 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), - Node->getOperand(2), // LHS - Node->getOperand(3), // RHS - Node->getOperand(1))); - // If this target does not support BRTWOWAY_CC, lower it to a BRCOND/BR - // pair. - switch (TLI.getOperationAction(ISD::BRTWOWAY_CC, MVT::Other)) { - default: assert(0 && "This action is not supported yet!"); - case TargetLowering::Legal: { - // If we get a SETCC back from legalizing the SETCC node we just - // created, then use its LHS, RHS, and CC directly in creating a new - // node. Otherwise, select between the true and false value based on - // comparing the result of the legalized with zero. - std::vector Ops; - Ops.push_back(Tmp1); - if (Tmp2.getOpcode() == ISD::SETCC) { - Ops.push_back(Tmp2.getOperand(2)); - Ops.push_back(Tmp2.getOperand(0)); - Ops.push_back(Tmp2.getOperand(1)); - } else { - Ops.push_back(DAG.getCondCode(ISD::SETNE)); - Ops.push_back(Tmp2); - Ops.push_back(DAG.getConstant(0, Tmp2.getValueType())); - } - Ops.push_back(Node->getOperand(4)); - Ops.push_back(Node->getOperand(5)); - Result = DAG.UpdateNodeOperands(Result, Ops); - break; - } - case TargetLowering::Expand: - Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2, - Node->getOperand(4)); - Result = DAG.getNode(ISD::BR, MVT::Other, Result, Node->getOperand(5)); - break; - } } break; + } case ISD::LOAD: { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. @@ -1315,156 +1289,47 @@ } } break; - case ISD::SELECT_CC: + case ISD::SELECT_CC: { + Tmp1 = Node->getOperand(0); // LHS + Tmp2 = Node->getOperand(1); // RHS Tmp3 = LegalizeOp(Node->getOperand(2)); // True Tmp4 = LegalizeOp(Node->getOperand(3)); // False + SDOperand CC = Node->getOperand(4); - if (isTypeLegal(Node->getOperand(0).getValueType())) { - Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS - Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS - - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, - Node->getOperand(4)); - - // Everything is legal, see if we should expand this op or something. - switch (TLI.getOperationAction(ISD::SELECT_CC, - Node->getOperand(0).getValueType())) { - default: assert(0 && "This action is not supported yet!"); - case TargetLowering::Legal: break; - case TargetLowering::Custom: - Tmp1 = TLI.LowerOperation(Result, DAG); - if (Tmp1.Val) Result = Tmp1; - break; - } + LegalizeSetCCOperands(Tmp1, Tmp2, CC); + + // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands, + // the LHS is a legal SETCC itself. In this case, we need to compare + // the result against zero to select between true and false values. + if (Tmp2.Val == 0) { + Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); + CC = DAG.getCondCode(ISD::SETNE); + } + Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, CC); + + // Everything is legal, see if we should expand this op or something. + switch (TLI.getOperationAction(ISD::SELECT_CC, Tmp3.getValueType())) { + default: assert(0 && "This action is not supported yet!"); + case TargetLowering::Legal: break; + case TargetLowering::Custom: + Tmp1 = TLI.LowerOperation(Result, DAG); + if (Tmp1.Val) Result = Tmp1; break; - } else { - Tmp1 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), - Node->getOperand(0), // LHS - Node->getOperand(1), // RHS - Node->getOperand(4))); - // If we get a SETCC back from legalizing the SETCC node we just - // created, then use its LHS, RHS, and CC directly in creating a new - // node. Otherwise, select between the true and false value based on - // comparing the result of the legalized with zero. - if (Tmp1.getOpcode() == ISD::SETCC) { - Result = DAG.getNode(ISD::SELECT_CC, Tmp3.getValueType(), - Tmp1.getOperand(0), Tmp1.getOperand(1), - Tmp3, Tmp4, Tmp1.getOperand(2)); - } else { - Result = DAG.getSelectCC(Tmp1, - DAG.getConstant(0, Tmp1.getValueType()), - Tmp3, Tmp4, ISD::SETNE); - } } break; + } case ISD::SETCC: - switch (getTypeAction(Node->getOperand(0).getValueType())) { - case Legal: - Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS - Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS - break; - case Promote: - Tmp1 = PromoteOp(Node->getOperand(0)); // LHS - Tmp2 = PromoteOp(Node->getOperand(1)); // RHS - - // If this is an FP compare, the operands have already been extended. - if (MVT::isInteger(Node->getOperand(0).getValueType())) { - MVT::ValueType VT = Node->getOperand(0).getValueType(); - MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); - - // Otherwise, we have to insert explicit sign or zero extends. Note - // that we could insert sign extends for ALL conditions, but zero extend - // is cheaper on many machines (an AND instead of two shifts), so prefer - // it. - switch (cast(Node->getOperand(2))->get()) { - default: assert(0 && "Unknown integer comparison!"); - case ISD::SETEQ: - case ISD::SETNE: - case ISD::SETUGE: - case ISD::SETUGT: - case ISD::SETULE: - case ISD::SETULT: - // ALL of these operations will work if we either sign or zero extend - // the operands (including the unsigned comparisons!). Zero extend is - // usually a simpler/cheaper operation, so prefer it. - Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT); - Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT); - break; - case ISD::SETGE: - case ISD::SETGT: - case ISD::SETLT: - case ISD::SETLE: - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, - DAG.getValueType(VT)); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, - DAG.getValueType(VT)); - break; - } - } + Tmp1 = Node->getOperand(0); + Tmp2 = Node->getOperand(1); + Tmp3 = Node->getOperand(2); + LegalizeSetCCOperands(Tmp1, Tmp2, Tmp3); + + // If we had to Expand the SetCC operands into a SELECT node, then it may + // not always be possible to return a true LHS & RHS. In this case, just + // return the value we legalized, returned in the LHS + if (Tmp2.Val == 0) { + Result = Tmp1; break; - case Expand: - SDOperand LHSLo, LHSHi, RHSLo, RHSHi; - ExpandOp(Node->getOperand(0), LHSLo, LHSHi); - ExpandOp(Node->getOperand(1), RHSLo, RHSHi); - switch (cast(Node->getOperand(2))->get()) { - case ISD::SETEQ: - case ISD::SETNE: - if (RHSLo == RHSHi) - if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) - if (RHSCST->isAllOnesValue()) { - // Comparison to -1. - Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); - Tmp2 = RHSLo; - break; - } - - Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); - Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); - Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); - break; - default: - // If this is a comparison of the sign bit, just look at the top part. - // X > -1, x < 0 - if (ConstantSDNode *CST = dyn_cast(Node->getOperand(1))) - if ((cast(Node->getOperand(2))->get() == ISD::SETLT && - CST->getValue() == 0) || // X < 0 - (cast(Node->getOperand(2))->get() == ISD::SETGT && - (CST->isAllOnesValue()))) { // X > -1 - Tmp1 = LHSHi; - Tmp2 = RHSHi; - break; - } - - // FIXME: This generated code sucks. - ISD::CondCode LowCC; - switch (cast(Node->getOperand(2))->get()) { - default: assert(0 && "Unknown integer setcc!"); - case ISD::SETLT: - case ISD::SETULT: LowCC = ISD::SETULT; break; - case ISD::SETGT: - case ISD::SETUGT: LowCC = ISD::SETUGT; break; - case ISD::SETLE: - case ISD::SETULE: LowCC = ISD::SETULE; break; - case ISD::SETGE: - case ISD::SETUGE: LowCC = ISD::SETUGE; break; - } - - // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison - // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands - // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; - - // NOTE: on targets without efficient SELECT of bools, we can always use - // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) - Tmp1 = DAG.getSetCC(Node->getValueType(0), LHSLo, RHSLo, LowCC); - Tmp2 = DAG.getNode(ISD::SETCC, Node->getValueType(0), LHSHi, RHSHi, - Node->getOperand(2)); - Result = DAG.getSetCC(Node->getValueType(0), LHSHi, RHSHi, ISD::SETEQ); - Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(), - Result, Tmp1, Tmp2)); - AddLegalizedOperand(SDOperand(Node, 0), Result); - return Result; - } } switch (TLI.getOperationAction(ISD::SETCC, Tmp1.getValueType())) { @@ -2699,6 +2564,127 @@ return Result; } +/// LegalizeSetCCOperands - Attempts to create a legal LHS and RHS for a SETCC +/// with condition CC on the current target. This usually involves legalizing +/// or promoting the arguments. In the case where LHS and RHS must be expanded, +/// there may be no choice but to create a new SetCC node to represent the +/// legalized value of setcc lhs, rhs. In this case, the value is returned in +/// LHS, and the SDOperand returned in RHS has a nil SDNode value. +void SelectionDAGLegalize::LegalizeSetCCOperands(SDOperand &LHS, + SDOperand &RHS, + SDOperand &CC) { + SDOperand Tmp1, Tmp2, Result; + + switch (getTypeAction(LHS.getValueType())) { + case Legal: + Tmp1 = LegalizeOp(LHS); // LHS + Tmp2 = LegalizeOp(RHS); // RHS + break; + case Promote: + Tmp1 = PromoteOp(LHS); // LHS + Tmp2 = PromoteOp(RHS); // RHS + + // If this is an FP compare, the operands have already been extended. + if (MVT::isInteger(LHS.getValueType())) { + MVT::ValueType VT = LHS.getValueType(); + MVT::ValueType NVT = TLI.getTypeToTransformTo(VT); + + // Otherwise, we have to insert explicit sign or zero extends. Note + // that we could insert sign extends for ALL conditions, but zero extend + // is cheaper on many machines (an AND instead of two shifts), so prefer + // it. + switch (cast(CC)->get()) { + default: assert(0 && "Unknown integer comparison!"); + case ISD::SETEQ: + case ISD::SETNE: + case ISD::SETUGE: + case ISD::SETUGT: + case ISD::SETULE: + case ISD::SETULT: + // ALL of these operations will work if we either sign or zero extend + // the operands (including the unsigned comparisons!). Zero extend is + // usually a simpler/cheaper operation, so prefer it. + Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT); + Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT); + break; + case ISD::SETGE: + case ISD::SETGT: + case ISD::SETLT: + case ISD::SETLE: + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + DAG.getValueType(VT)); + Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, + DAG.getValueType(VT)); + break; + } + } + break; + case Expand: + SDOperand LHSLo, LHSHi, RHSLo, RHSHi; + ExpandOp(LHS, LHSLo, LHSHi); + ExpandOp(RHS, RHSLo, RHSHi); + switch (cast(CC)->get()) { + case ISD::SETEQ: + case ISD::SETNE: + if (RHSLo == RHSHi) + if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) + if (RHSCST->isAllOnesValue()) { + // Comparison to -1. + Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); + Tmp2 = RHSLo; + break; + } + + Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); + Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); + Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); + break; + default: + // If this is a comparison of the sign bit, just look at the top part. + // X > -1, x < 0 + if (ConstantSDNode *CST = dyn_cast(RHS)) + if ((cast(CC)->get() == ISD::SETLT && + CST->getValue() == 0) || // X < 0 + (cast(CC)->get() == ISD::SETGT && + CST->isAllOnesValue())) { // X > -1 + Tmp1 = LHSHi; + Tmp2 = RHSHi; + break; + } + + // FIXME: This generated code sucks. + ISD::CondCode LowCC; + switch (cast(CC)->get()) { + default: assert(0 && "Unknown integer setcc!"); + case ISD::SETLT: + case ISD::SETULT: LowCC = ISD::SETULT; break; + case ISD::SETGT: + case ISD::SETUGT: LowCC = ISD::SETUGT; break; + case ISD::SETLE: + case ISD::SETULE: LowCC = ISD::SETULE; break; + case ISD::SETGE: + case ISD::SETUGE: LowCC = ISD::SETUGE; break; + } + + // Tmp1 = lo(op1) < lo(op2) // Always unsigned comparison + // Tmp2 = hi(op1) < hi(op2) // Signedness depends on operands + // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2; + + // NOTE: on targets without efficient SELECT of bools, we can always use + // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) + Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC); + Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, CC); + Result = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ); + Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + Result, Tmp1, Tmp2)); + Tmp1 = Result; + } + } + LHS = Tmp1; + RHS = Tmp2; +} + /// ExpandBIT_CONVERT - Expand a BIT_CONVERT node into a store/load combination. /// The resultant code need not be legal. Note that SrcOp is the input operand /// to the BIT_CONVERT, not the BIT_CONVERT node itself. From lattner at cs.uiuc.edu Wed Feb 1 11:54:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 11:54:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602011754.LAA21882@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.52 -> 1.53 --- Log message: add a note --- Diffs of the changes: (+29 -0) README.txt | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.52 llvm/lib/Target/PowerPC/README.txt:1.53 --- llvm/lib/Target/PowerPC/README.txt:1.52 Wed Feb 1 01:19:44 2006 +++ llvm/lib/Target/PowerPC/README.txt Wed Feb 1 11:54:23 2006 @@ -435,3 +435,32 @@ same operands (but backwards) exists. In this case, this wouldn't save us anything though, because the compares still wouldn't be shared. +===-------------------------------------------------------------------------=== + +The legalizer should lower this: + +bool %test(ulong %x) { + %tmp = setlt ulong %x, 4294967296 + ret bool %tmp +} + +into "if x.high == 0", not: + +_test: + addi r2, r3, -1 + cntlzw r2, r2 + cntlzw r3, r3 + srwi r2, r2, 5 + srwi r3, r3, 5 + li r4, 0 + cmpwi cr0, r2, 0 + bne cr0, LBB1_2 ; +LBB1_1: + or r4, r3, r3 +LBB1_2: + cmplw cr7, r4, r3 + mfcr r2, 1 + rlwinm r3, r2, 29, 31, 31 + blr + +noticed in 2005-05-11-Popcount-ffs-fls.c. From lattner at cs.uiuc.edu Wed Feb 1 12:11:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 12:11:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/MRegisterInfo.cpp Message-ID: <200602011811.MAA22043@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: MRegisterInfo.cpp updated: 1.11 -> 1.12 --- Log message: Finegrainify namespacification --- Diffs of the changes: (+1 -4) MRegisterInfo.cpp | 5 +---- 1 files changed, 1 insertion(+), 4 deletions(-) Index: llvm/lib/Target/MRegisterInfo.cpp diff -u llvm/lib/Target/MRegisterInfo.cpp:1.11 llvm/lib/Target/MRegisterInfo.cpp:1.12 --- llvm/lib/Target/MRegisterInfo.cpp:1.11 Fri Sep 30 12:48:18 2005 +++ llvm/lib/Target/MRegisterInfo.cpp Wed Feb 1 12:10:56 2006 @@ -12,8 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/MRegisterInfo.h" - -namespace llvm { +using namespace llvm; MRegisterInfo::MRegisterInfo(const TargetRegisterDesc *D, unsigned NR, regclass_iterator RCB, regclass_iterator RCE, @@ -39,5 +38,3 @@ } return Allocatable; } - -} // End llvm namespace From lattner at cs.uiuc.edu Wed Feb 1 12:59:59 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 12:59:59 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602011859.MAA22310@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.144 -> 1.145 --- Log message: Implement simple register assignment for inline asms. This allows us to compile: int %test(int %A, int %B) { %C = call int asm "xyz $0, $1, $2", "=r,r,r"(int %A, int %B) ret int %C } into: (0x8906130, LLVM BB @0x8902220): %r2 = OR4 %r3, %r3 %r3 = OR4 %r4, %r4 INLINEASM , %r2, %r2, %r3 %r3 = OR4 %r2, %r2 BLR which asmprints as: _test: or r2, r3, r3 or r3, r4, r4 xyz $0, $1, $2 ;; need to print the operands now :) or r3, r2, r2 blr --- Diffs of the changes: (+103 -8) SelectionDAGISel.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 103 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.144 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.145 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.144 Tue Jan 31 19:28:23 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 1 12:59:47 2006 @@ -40,6 +40,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Debug.h" #include +#include #include using namespace llvm; @@ -410,6 +411,11 @@ assert(N.Val == 0 && "Already set a value for this node!"); return N = NewN; } + + unsigned GetAvailableRegister(bool OutReg, bool InReg, + const std::vector &RegChoices, + std::set &OutputRegs, + std::set &InputRegs); // Terminator instructions. void visitRet(ReturnInst &I); @@ -1143,6 +1149,49 @@ DAG.setRoot(Result.second); } +/// GetAvailableRegister - Pick a register from RegChoices that is available +/// for input and/or output as specified by isOutReg/isInReg. If an allocatable +/// register is found, it is returned and added to the specified set of used +/// registers. If not, zero is returned. +unsigned SelectionDAGLowering:: +GetAvailableRegister(bool isOutReg, bool isInReg, + const std::vector &RegChoices, + std::set &OutputRegs, + std::set &InputRegs) { + const MRegisterInfo *MRI = DAG.getTarget().getRegisterInfo(); + MachineFunction &MF = *CurMBB->getParent(); + for (unsigned i = 0, e = RegChoices.size(); i != e; ++i) { + unsigned Reg = RegChoices[i]; + // See if this register is available. + if (isOutReg && OutputRegs.count(Reg)) continue; // Already used. + if (isInReg && InputRegs.count(Reg)) continue; // Already used. + + // Check to see if this register is allocatable (i.e. don't give out the + // stack pointer). + bool Found = false; + for (MRegisterInfo::regclass_iterator RC = MRI->regclass_begin(), + E = MRI->regclass_end(); !Found && RC != E; ++RC) { + // NOTE: This isn't ideal. In particular, this might allocate the + // frame pointer in functions that need it (due to them not being taken + // out of allocation, because a variable sized allocation hasn't been seen + // yet). This is a slight code pessimization, but should still work. + for (TargetRegisterClass::iterator I = (*RC)->allocation_order_begin(MF), + E = (*RC)->allocation_order_end(MF); I != E; ++I) + if (*I == Reg) { + Found = true; + break; + } + } + if (!Found) continue; + + // Okay, this register is good, return it. + if (isOutReg) OutputRegs.insert(Reg); // Mark used. + if (isInReg) InputRegs.insert(Reg); // Mark used. + return Reg; + } + return 0; +} + /// visitInlineAsm - Handle a call to an InlineAsm object. /// void SelectionDAGLowering::visitInlineAsm(CallInst &I) { @@ -1174,21 +1223,60 @@ std::vector > IndirectStoresToEmit; unsigned OpNum = 1; bool FoundOutputConstraint = false; - //std::set OutputRegs; - //std::set InputRegs; + + // We fully assign registers here at isel time. This is not optimal, but + // should work. For register classes that correspond to LLVM classes, we + // could let the LLVM RA do its thing, but we currently don't. Do a prepass + // over the constraints, collecting fixed registers that we know we can't use. + std::set OutputRegs, InputRegs; + for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { + assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); + std::string &ConstraintCode = Constraints[i].Codes[0]; + std::vector Regs = + TLI.getRegForInlineAsmConstraint(ConstraintCode); + if (Regs.size() != 1) continue; // Not assigned a fixed reg. + unsigned TheReg = Regs[0]; + + switch (Constraints[i].Type) { + case InlineAsm::isOutput: + // We can't assign any other output to this register. + OutputRegs.insert(TheReg); + // If this is an early-clobber output, it cannot be assigned to the same + // value as the input reg. + if (Constraints[i].isEarlyClobber) + InputRegs.insert(TheReg); + break; + case InlineAsm::isClobber: + // Clobbered regs cannot be used as inputs or outputs. + InputRegs.insert(TheReg); + OutputRegs.insert(TheReg); + break; + case InlineAsm::isInput: + // We can't assign any other input to this register. + InputRegs.insert(TheReg); + break; + } + } for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); std::string &ConstraintCode = Constraints[i].Codes[0]; switch (Constraints[i].Type) { case InlineAsm::isOutput: { - bool isEarlyClobber = Constraints[i].isEarlyClobber; // Copy the output from the appropriate register. std::vector Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); - assert(Regs.size() == 1 && "Only handle simple regs right now!"); - unsigned DestReg = Regs[0]; + + // Find a regsister that we can use. + unsigned DestReg; + if (Regs.size() == 1) + DestReg = Regs[0]; + else + DestReg = GetAvailableRegister(true, Constraints[i].isEarlyClobber, + Regs, OutputRegs, InputRegs); + + assert(DestReg && "Couldn't allocate output reg!"); const Type *OpTy; if (!Constraints[i].isIndirectOutput) { @@ -1218,12 +1306,20 @@ case InlineAsm::isInput: { Value *Operand = I.getOperand(OpNum); const Type *OpTy = Operand->getType(); + OpNum++; // Consumes a call operand. // Copy the input into the appropriate register. std::vector Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); - assert(Regs.size() == 1 && "Only handle simple regs right now!"); - unsigned SrcReg = Regs[0]; + unsigned SrcReg; + if (Regs.size() == 1) + SrcReg = Regs[0]; + else + SrcReg = GetAvailableRegister(false, true, Regs, + OutputRegs, InputRegs); + + assert(SrcReg && "Couldn't allocate input reg!"); + Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag); Flag = Chain.getValue(1); @@ -1271,7 +1367,6 @@ Chain = Val.getValue(1); Flag = Val.getValue(2); StoresToEmit.push_back(std::make_pair(Val, Ptr)); - OpNum++; // Consumes a call operand. } // Emit the non-flagged stores from the physregs. From natebegeman at mac.com Wed Feb 1 13:05:27 2006 From: natebegeman at mac.com (Nate Begeman) Date: Wed, 1 Feb 2006 13:05:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200602011905.NAA22386@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: LegalizeDAG.cpp updated: 1.300 -> 1.301 --- Log message: --- Diffs of the changes: (+1 -0) LegalizeDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.300 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.301 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.300 Wed Feb 1 01:19:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Feb 1 13:05:15 2006 @@ -2679,6 +2679,7 @@ Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(), Result, Tmp1, Tmp2)); Tmp1 = Result; + Tmp2 = SDOperand(); } } LHS = Tmp1; From lattner at cs.uiuc.edu Wed Feb 1 13:12:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 13:12:35 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/AsmWriterEmitter.cpp Message-ID: <200602011912.NAA22520@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: AsmWriterEmitter.cpp updated: 1.24 -> 1.25 --- Log message: add a note, ya knoe --- Diffs of the changes: (+3 -0) AsmWriterEmitter.cpp | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/utils/TableGen/AsmWriterEmitter.cpp diff -u llvm/utils/TableGen/AsmWriterEmitter.cpp:1.24 llvm/utils/TableGen/AsmWriterEmitter.cpp:1.25 --- llvm/utils/TableGen/AsmWriterEmitter.cpp:1.24 Thu Jan 26 20:10:50 2006 +++ llvm/utils/TableGen/AsmWriterEmitter.cpp Wed Feb 1 13:12:23 2006 @@ -96,6 +96,9 @@ this->CGI = &CGI; bool inVariant = false; // True if we are inside a {.|.|.} region. + // NOTE: Any extensions to this code need to be mirrored in the + // AsmPrinter::printInlineAsm code that executes as compile time (assuming + // that inline asm strings should also get the new feature)! const std::string &AsmString = CGI.AsmString; std::string::size_type LastEmitted = 0; while (LastEmitted != AsmString.size()) { From alenhar2 at cs.uiuc.edu Wed Feb 1 13:37:04 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 1 Feb 2006 13:37:04 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/Alpha/cmov.ll Message-ID: <200602011937.NAA22672@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/Alpha: cmov.ll added (r1.1) --- Log message: test cmov immediate form --- Diffs of the changes: (+17 -0) cmov.ll | 17 +++++++++++++++++ 1 files changed, 17 insertions(+) Index: llvm/test/Regression/CodeGen/Alpha/cmov.ll diff -c /dev/null llvm/test/Regression/CodeGen/Alpha/cmov.ll:1.1 *** /dev/null Wed Feb 1 13:37:02 2006 --- llvm/test/Regression/CodeGen/Alpha/cmov.ll Wed Feb 1 13:36:52 2006 *************** *** 0 **** --- 1,17 ---- + ; RUN: llvm-as < %s | llc -march=alpha | not grep cmovlt + ; RUN: llvm-as < %s | llc -march=alpha | grep cmoveq + + long %cmovlt_(long %a, long %c) { + entry: + %tmp.1 = setlt long %c, 0 + %retval = select bool %tmp.1, long %a, long 10 + ret long %retval + } + + long %cmov_const(long %a, long %b, long %c) { + entry: + %tmp.1 = setlt long %a, %b + %retval = select bool %tmp.1, long %c, long 10 + ret long %retval + } + From alenhar2 at cs.uiuc.edu Wed Feb 1 13:37:45 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Wed, 1 Feb 2006 13:37:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrFormats.td AlphaInstrInfo.td AlphaRegisterInfo.cpp Message-ID: <200602011937.NAA22694@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrFormats.td updated: 1.25 -> 1.26 AlphaInstrInfo.td updated: 1.111 -> 1.112 AlphaRegisterInfo.cpp updated: 1.33 -> 1.34 --- Log message: Add immediate forms of cmov and remove some cruft --- Diffs of the changes: (+26 -39) AlphaInstrFormats.td | 8 ++++--- AlphaInstrInfo.td | 55 ++++++++++++++++++-------------------------------- AlphaRegisterInfo.cpp | 2 - 3 files changed, 26 insertions(+), 39 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrFormats.td diff -u llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.25 llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.26 --- llvm/lib/Target/Alpha/AlphaInstrFormats.td:1.25 Wed Jan 25 21:24:15 2006 +++ llvm/lib/Target/Alpha/AlphaInstrFormats.td Wed Feb 1 13:37:33 2006 @@ -148,7 +148,7 @@ } class OForm4 opcode, bits<7> fun, string asmstr, list pattern> - : InstAlphaAlt { + : InstAlpha { let Pattern = pattern; bits<5> Rc; @@ -182,8 +182,10 @@ let Inst{4-0} = Rc; } -class OForm4L opcode, bits<7> fun, string asmstr> - : InstAlpha { +class OForm4L opcode, bits<7> fun, string asmstr, list pattern> + : InstAlpha { + let Pattern = pattern; + bits<5> Rc; bits<8> LIT; bits<5> Ra; Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.111 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.112 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.111 Sat Jan 28 21:47:30 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Wed Feb 1 13:37:33 2006 @@ -134,28 +134,6 @@ "LSMARKER$$$i$$$j$$$k$$$m:", []>; - -//An even better improvement on the Int = SetCC(FP): SelectCC! -//These are evil because they hide control flow in a MBB -//really the ISel should emit multiple MBB -let isTwoAddress = 1 in { -//Conditional move of an int based on a FP CC - def CMOVEQ_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "fbne $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; - def CMOVEQi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), - "fbne $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>; - - def CMOVNE_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "fbeq $RCOND, 42f\n\tbis $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; - def CMOVNEi_FP : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, u8imm:$L, F8RC:$RCOND), - "fbeq $RCOND, 42f\n\taddq $$31,$L,$RDEST\n42:\n", []>; -//Conditional move of an FP based on a Int CC - def FCMOVEQ_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "bne $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; - def FCMOVNE_INT : PseudoInstAlpha<(ops GPRC:$RDEST, GPRC:$RSRC_F, GPRC:$RSRC_T, F8RC:$RCOND), - "beq $RCOND, 42f\n\tcpys $RSRC_T,$RSRC_T,$RDEST\n42:\n", []>; -} - //*********************** //Real instructions //*********************** @@ -163,16 +141,7 @@ //Operation Form: //conditional moves, int -def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$L,$RDEST">; //CMOVE if RCOND = zero -def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$L,$RDEST">; //CMOVE if RCOND >= zero -def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$L,$RDEST">; //CMOVE if RCOND > zero -def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit clear -def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$L,$RDEST">; //CMOVE if RCOND low bit set -def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$L,$RDEST">; //CMOVE if RCOND <= zero -def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND < zero -def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero -let OperandList = (ops GPRC:$RDEST, GPRC:$RFALSE, GPRC:$RTRUE, GPRC:$RCOND) in { def CMOVLBC : OForm4< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RTRUE, GPRC:$RFALSE))]>; def CMOVLBS : OForm4< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST", @@ -189,13 +158,32 @@ [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; def CMOVNE : OForm4< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST", [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RTRUE, GPRC:$RFALSE))]>; -} + +def CMOVEQi : OForm4L< 0x11, 0x24, "cmoveq $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (setne GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVGEi : OForm4L< 0x11, 0x46, "cmovge $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (setlt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVGTi : OForm4L< 0x11, 0x66, "cmovgt $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (setle GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVLEi : OForm4L< 0x11, 0x64, "cmovle $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (setgt GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVLTi : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (setge GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVNEi : OForm4L< 0x11, 0x26, "cmovne $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (seteq GPRC:$RCOND, 0), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVLBCi : OForm4L< 0x11, 0x16, "cmovlbc $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (and GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))]>; +def CMOVLBSi : OForm4L< 0x11, 0x14, "cmovlbs $RCOND,$RTRUE,$RDEST", + [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))]>; + //FIXME: fold setcc with select for all cases. clearly I need patterns for inverted conditions // and constants (which require inverted conditions as legalize puts the constant in the // wrong field for the instruction definition def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2), (CMOVNE GPRC:$src2, GPRC:$src1, GPRC:$which)>; +def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2), + (CMOVEQi GPRC:$src1, immUExt8:$src2, GPRC:$which)>; def ADDL : OForm< 0x10, 0x00, "addl $RA,$RB,$RC", @@ -413,9 +401,6 @@ def : Pat<(setune GPRC:$X, immUExt8:$Y), (CMPEQi (CMPEQ GPRC:$X, immUExt8:$Y), 0)>; -let isReturn = 1, isTerminator = 1, noResults = 1 in - def RET : MbrForm< 0x1A, 0x02, (ops GPRC:$RD, GPRC:$RS, s64imm:$DISP), "ret $RD,($RS),$DISP">; //Return from subroutine -//DAG Version: let isReturn = 1, isTerminator = 1, noResults = 1, Ra = 31, Rb = 26, disp = 1, Uses = [R26] in def RETDAG : MbrForm< 0x1A, 0x02, (ops), "ret $$31,($$26),1">; //Return from subroutine Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.33 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.34 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.33 Wed Jan 25 21:22:07 2006 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Wed Feb 1 13:37:33 2006 @@ -350,7 +350,7 @@ MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert(((MBBI->getOpcode() == Alpha::RET) || (MBBI->getOpcode() == Alpha::RETDAG)) + assert(MBBI->getOpcode() == Alpha::RETDAG && "Can only insert epilog into returning blocks"); bool FP = hasFP(MF); From lattner at cs.uiuc.edu Wed Feb 1 15:45:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 15:45:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602012145.PAA23203@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.39 -> 1.40 --- Log message: another note --- Diffs of the changes: (+4 -0) README.txt | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.39 llvm/lib/Target/X86/README.txt:1.40 --- llvm/lib/Target/X86/README.txt:1.39 Wed Feb 1 00:40:32 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 1 15:44:48 2006 @@ -309,3 +309,7 @@ ret bool %Z } +//===---------------------------------------------------------------------===// + +We need to lower switch statements to tablejumps when appropriate instead of +always into binary branch trees. From lattner at cs.uiuc.edu Wed Feb 1 16:38:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 16:38:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200602012238.QAA23472@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.143 -> 1.144 --- Log message: add a method --- Diffs of the changes: (+8 -2) PPCAsmPrinter.cpp | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.143 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.144 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.143 Thu Jan 26 14:21:46 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Wed Feb 1 16:38:46 2006 @@ -83,7 +83,7 @@ void printMachineInstruction(const MachineInstr *MI); void printOp(const MachineOperand &MO); - void printOperand(const MachineInstr *MI, unsigned OpNo){ + void printOperand(const MachineInstr *MI, unsigned OpNo) { const MachineOperand &MO = MI->getOperand(OpNo); if (MO.getType() == MachineOperand::MO_MachineRegister) { assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); @@ -94,7 +94,13 @@ printOp(MO); } } - + + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant) { + printOperand(MI, OpNo); + return false; + } + void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) { unsigned char value = MI->getOperand(OpNo).getImmedValue(); assert(value <= 31 && "Invalid u5imm argument!"); From lattner at cs.uiuc.edu Wed Feb 1 16:39:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 16:39:42 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200602012239.QAA23562@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.26 -> 1.27 --- Log message: add a new PrintAsmOperand method, move some stuff around for ease of reading. --- Diffs of the changes: (+16 -9) AsmPrinter.h | 25 ++++++++++++++++--------- 1 files changed, 16 insertions(+), 9 deletions(-) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.26 llvm/include/llvm/CodeGen/AsmPrinter.h:1.27 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.26 Thu Jan 26 20:09:16 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Wed Feb 1 16:39:30 2006 @@ -178,15 +178,6 @@ void SwitchSection(const char *NewSection, const GlobalValue *GV); protected: - /// getFunctionNumber - Return a unique ID for the current function. - /// - unsigned getFunctionNumber() const { return FunctionNumber; } - - /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should - /// not normally call this, as the counter is automatically bumped by - /// SetupMachineFunction. - void IncrementFunctionNumber() { FunctionNumber++; } - /// doInitialization - Set up the AsmPrinter when we are working on a new /// module. If your pass overrides this, it must make sure to explicitly /// call this implementation. @@ -195,11 +186,27 @@ /// doFinalization - Shut down the asmprinter. If you override this in your /// pass, you must make sure to call it explicitly. bool doFinalization(Module &M); + + /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM + /// instruction, using the specified assembler variant. Targets should + /// overried this to format as appropriate. This method can return true if + /// the operand is erroneous. + virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant); /// SetupMachineFunction - This should be called when a new MachineFunction /// is being processed from runOnMachineFunction. void SetupMachineFunction(MachineFunction &MF); + /// getFunctionNumber - Return a unique ID for the current function. + /// + unsigned getFunctionNumber() const { return FunctionNumber; } + + /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should + /// not normally call this, as the counter is automatically bumped by + /// SetupMachineFunction. + void IncrementFunctionNumber() { FunctionNumber++; } + /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by From lattner at cs.uiuc.edu Wed Feb 1 16:41:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 16:41:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602012241.QAA23606@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.44 -> 1.45 --- Log message: Implement smart printing of inline asm strings, handling variants and substituted operands. For this testcase: int %test(int %A, int %B) { %C = call int asm "xyz $0, $1, $2", "=r,r,r"(int %A, int %B) ret int %C } we now emit: _test: or r2, r3, r3 or r3, r4, r4 xyz r2, r2, r3 ;; look here or r3, r2, r2 blr ... note the substituted operands. :) --- Diffs of the changes: (+112 -5) AsmPrinter.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 112 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.44 llvm/lib/CodeGen/AsmPrinter.cpp:1.45 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.44 Tue Jan 31 19:28:23 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Wed Feb 1 16:41:11 2006 @@ -20,6 +20,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetMachine.h" #include +#include using namespace llvm; AsmPrinter::AsmPrinter(std::ostream &o, TargetMachine &tm) @@ -468,12 +469,118 @@ assert(NumDefs != NumOperands-1 && "No asm string?"); assert(MI->getOperand(NumDefs).isExternalSymbol() && "No asm string?"); - + + // Disassemble the AsmStr, printing out the literal pieces, the operands, etc. const char *AsmStr = MI->getOperand(NumDefs).getSymbolName(); + + // The variant of the current asmprinter: FIXME: change. + int AsmPrinterVariant = 0; - O << AsmStr << "\n"; - - // Use a virtual "printAsmOperand" method, which takes the constraint - // string? Must pass the constraint string to here if needed. + int CurVariant = -1; // The number of the {.|.|.} region we are in. + const char *LastEmitted = AsmStr; // One past the last character emitted. + while (*LastEmitted) { + switch (*LastEmitted) { + default: { + // Not a special case, emit the string section literally. + const char *LiteralEnd = LastEmitted+1; + while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' && + *LiteralEnd != '}' && *LiteralEnd != '$') + ++LiteralEnd; + if (CurVariant == -1 || CurVariant == AsmPrinterVariant) + O.write(LastEmitted, LiteralEnd-LastEmitted); + LastEmitted = LiteralEnd; + break; + } + case '$': { + ++LastEmitted; // Consume '$' character. + if (*LastEmitted == '$') { // $$ -> $ + if (CurVariant == -1 || CurVariant == AsmPrinterVariant) + O << '$'; + ++LastEmitted; // Consume second '$' character. + break; + } + + bool HasCurlyBraces = false; + if (*LastEmitted == '{') { // ${variable} + ++LastEmitted; // Consume '{' character. + HasCurlyBraces = true; + } + + const char *IDStart = LastEmitted; + char *IDEnd; + long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs. + if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) { + std::cerr << "Bad $ operand number in inline asm string: '" + << AsmStr << "'\n"; + exit(1); + } + LastEmitted = IDEnd; + + if (HasCurlyBraces) { + if (*LastEmitted != '}') { + std::cerr << "Bad ${} expression in inline asm string: '" + << AsmStr << "'\n"; + exit(1); + } + ++LastEmitted; // Consume '}' character. + } + + if ((unsigned)Val >= NumOperands-1) { + std::cerr << "Invalid $ operand number in inline asm string: '" + << AsmStr << "'\n"; + exit(1); + } + + // Okay, we finally have an operand number. Ask the target to print this + // operand! + if (CurVariant == -1 || CurVariant == AsmPrinterVariant) + if (const_cast(this)-> + PrintAsmOperand(MI, Val+1, AsmPrinterVariant)) { + std::cerr << "Invalid operand found in inline asm: '" + << AsmStr << "'\n"; + MI->dump(); + exit(1); + } + break; + } + case '{': + ++LastEmitted; // Consume '{' character. + if (CurVariant != -1) { + std::cerr << "Nested variants found in inline asm string: '" + << AsmStr << "'\n"; + exit(1); + } + CurVariant = 0; // We're in the first variant now. + break; + case '|': + ++LastEmitted; // consume '|' character. + if (CurVariant == -1) { + std::cerr << "Found '|' character outside of variant in inline asm " + << "string: '" << AsmStr << "'\n"; + exit(1); + } + ++CurVariant; // We're in the next variant. + break; + case '}': + ++LastEmitted; // consume '}' character. + if (CurVariant == -1) { + std::cerr << "Found '}' character outside of variant in inline asm " + << "string: '" << AsmStr << "'\n"; + exit(1); + } + CurVariant = -1; + break; + } + } + O << "\n"; +} + +/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM +/// instruction, using the specified assembler variant. Targets should +/// overried this to format as appropriate. +bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant) { + // Target doesn't support this yet! + return true; } From evan.cheng at apple.com Wed Feb 1 17:02:08 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 17:02:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200602012302.RAA23848@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.227 -> 1.228 --- Log message: Rearrange code to my liking. :) --- Diffs of the changes: (+51 -50) X86InstrInfo.td | 101 ++++++++++++++++++++++++++++---------------------------- 1 files changed, 51 insertions(+), 50 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.227 llvm/lib/Target/X86/X86InstrInfo.td:1.228 --- llvm/lib/Target/X86/X86InstrInfo.td:1.227 Wed Feb 1 00:13:50 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Wed Feb 1 17:01:57 2006 @@ -2406,14 +2406,6 @@ [(store FR64:$src, addr:$dst)]>, Requires<[HasSSE2]>, XD; -def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), - "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint FR64:$src))]>, - Requires<[HasSSE2]>, XD; -def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), - "cvttsd2si {$src, $dst|$dst, $src}", - [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; def CVTTSS2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR32:$src), "cvttss2si {$src, $dst|$dst, $src}", [(set R32:$dst, (fp_to_sint FR32:$src))]>, @@ -2422,14 +2414,14 @@ "cvttss2si {$src, $dst|$dst, $src}", [(set R32:$dst, (fp_to_sint (loadf32 addr:$src)))]>, Requires<[HasSSE1]>, XS; -def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), - "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround FR64:$src))]>, - Requires<[HasSSE2]>, XS; -def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), - "cvtsd2ss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XS; +def CVTTSD2SIrr: I<0x2C, MRMSrcReg, (ops R32:$dst, FR64:$src), + "cvttsd2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint FR64:$src))]>, + Requires<[HasSSE2]>, XD; +def CVTTSD2SIrm: I<0x2C, MRMSrcMem, (ops R32:$dst, f64mem:$src), + "cvttsd2si {$src, $dst|$dst, $src}", + [(set R32:$dst, (fp_to_sint (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; def CVTSS2SDrr: I<0x5A, MRMSrcReg, (ops FR64:$dst, FR32:$src), "cvtss2sd {$src, $dst|$dst, $src}", [(set FR64:$dst, (fextend FR32:$src))]>, @@ -2438,6 +2430,14 @@ "cvtss2sd {$src, $dst|$dst, $src}", [(set FR64:$dst, (fextend (loadf32 addr:$src)))]>, Requires<[HasSSE2]>, XD; +def CVTSD2SSrr: I<0x5A, MRMSrcReg, (ops FR32:$dst, FR64:$src), + "cvtsd2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fround FR64:$src))]>, + Requires<[HasSSE2]>, XS; +def CVTSD2SSrm: I<0x5A, MRMSrcMem, (ops FR32:$dst, f64mem:$src), + "cvtsd2ss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fround (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XS; def CVTSI2SSrr: I<0x2A, MRMSrcReg, (ops FR32:$dst, R32:$src), "cvtsi2ss {$src, $dst|$dst, $src}", [(set FR32:$dst, (sint_to_fp R32:$src))]>, @@ -2455,31 +2455,23 @@ [(set FR64:$dst, (sint_to_fp (loadi32 addr:$src)))]>, Requires<[HasSSE2]>, XD; -def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), - "sqrtss {$src, $dst|$dst, $src}", - [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, - Requires<[HasSSE1]>, XS; def SQRTSSrr : I<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src), "sqrtss {$src, $dst|$dst, $src}", [(set FR32:$dst, (fsqrt FR32:$src))]>, Requires<[HasSSE1]>, XS; -def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), - "sqrtsd {$src, $dst|$dst, $src}", - [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, - Requires<[HasSSE2]>, XD; +def SQRTSSrm : I<0x51, MRMSrcMem, (ops FR32:$dst, f32mem:$src), + "sqrtss {$src, $dst|$dst, $src}", + [(set FR32:$dst, (fsqrt (loadf32 addr:$src)))]>, + Requires<[HasSSE1]>, XS; def SQRTSDrr : I<0x51, MRMSrcReg, (ops FR64:$dst, FR64:$src), "sqrtsd {$src, $dst|$dst, $src}", [(set FR64:$dst, (fsqrt FR64:$src))]>, Requires<[HasSSE2]>, XD; +def SQRTSDrm : I<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src), + "sqrtsd {$src, $dst|$dst, $src}", + [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>, + Requires<[HasSSE2]>, XD; -def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, FR64:$src2)]>, - Requires<[HasSSE2]>, TB, OpSize; -def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), - "ucomisd {$src2, $src1|$src1, $src2}", - [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, - Requires<[HasSSE2]>, TB, OpSize; def UCOMISSrr: I<0x2E, MRMSrcReg, (ops FR32:$src1, FR32:$src2), "ucomiss {$src2, $src1|$src1, $src2}", [(X86cmp FR32:$src1, FR32:$src2)]>, @@ -2488,6 +2480,14 @@ "ucomiss {$src2, $src1|$src1, $src2}", [(X86cmp FR32:$src1, (loadf32 addr:$src2))]>, Requires<[HasSSE1]>, TB; +def UCOMISDrr: I<0x2E, MRMSrcReg, (ops FR64:$src1, FR64:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, FR64:$src2)]>, + Requires<[HasSSE2]>, TB, OpSize; +def UCOMISDrm: I<0x2E, MRMSrcMem, (ops FR64:$src1, f64mem:$src2), + "ucomisd {$src2, $src1|$src1, $src2}", + [(X86cmp FR64:$src1, (loadf64 addr:$src2))]>, + Requires<[HasSSE2]>, TB, OpSize; // Pseudo-instructions that map fld0 to xorps/xorpd for sse. // FIXME: remove when we can teach regalloc that xor reg, reg is ok. @@ -2570,7 +2570,25 @@ [(set FR64:$dst, (fsub FR64:$src1, (loadf64 addr:$src2)))]>, Requires<[HasSSE2]>, XD; -// SSE Logical +// SSE compare +def CMPSSrr : I<0xC2, MRMSrcReg, + (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), + "cmp${cc}ss {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def CMPSSrm : I<0xC2, MRMSrcMem, + (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc), + "cmp${cc}ss {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XS; +def CMPSDrr : I<0xC2, MRMSrcReg, + (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc), + "cmp${cc}sd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE1]>, XD; +def CMPSDrm : I<0xC2, MRMSrcMem, + (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), + "cmp${cc}sd {$src, $dst|$dst, $src}", []>, + Requires<[HasSSE2]>, XD; + +// SSE Logical - these all operate on packed values let isCommutable = 1 in { def ANDPSrr : I<0x54, MRMSrcReg, (ops FR32:$dst, FR32:$src1, FR32:$src2), "andps {$src2, $dst|$dst, $src2}", @@ -2634,23 +2652,6 @@ def ANDNPDrm : I<0x55, MRMSrcMem, (ops FR64:$dst, FR64:$src1, f128mem:$src2), "andnpd {$src2, $dst|$dst, $src2}", []>, Requires<[HasSSE2]>, TB, OpSize; - -def CMPSSrr : I<0xC2, MRMSrcReg, - (ops FR32:$dst, FR32:$src1, FR32:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSSrm : I<0xC2, MRMSrcMem, - (ops FR32:$dst, FR32:$src1, f32mem:$src, SSECC:$cc), - "cmp${cc}ss {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XS; -def CMPSDrr : I<0xC2, MRMSrcReg, - (ops FR64:$dst, FR64:$src1, FR64:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE1]>, XD; -def CMPSDrm : I<0xC2, MRMSrcMem, - (ops FR64:$dst, FR64:$src1, f64mem:$src, SSECC:$cc), - "cmp${cc}sd {$src, $dst|$dst, $src}", []>, - Requires<[HasSSE2]>, XD; } //===----------------------------------------------------------------------===// From evan.cheng at apple.com Wed Feb 1 17:02:37 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 17:02:37 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200602012302.RAA23868@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.117 -> 1.118 --- Log message: Added SSE entries to foldMemoryOperand(). --- Diffs of the changes: (+49 -1) X86RegisterInfo.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 49 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.117 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.118 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.117 Mon Jan 9 12:33:28 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Wed Feb 1 17:02:25 2006 @@ -328,6 +328,16 @@ case X86::CMP8ri: return MakeMIInst(X86::CMP8mi , FrameIndex, MI); case X86::CMP16ri: return MakeMIInst(X86::CMP16mi, FrameIndex, MI); case X86::CMP32ri: return MakeMIInst(X86::CMP32mi, FrameIndex, MI); + // Scalar SSE instructions + case X86::MOVSSrr: return MakeMRInst(X86::MOVSSmr, FrameIndex, MI); + case X86::MOVSDrr: return MakeMRInst(X86::MOVSDmr, FrameIndex, MI); +#if 0 + // Packed SSE instructions + // FIXME: Can't use these until we are spilling XMM registers to + // 128-bit locations. + case X86::MOVAPSrr: return MakeMRInst(X86::MOVAPSmr, FrameIndex, MI); + case X86::MOVAPDrr: return MakeMRInst(X86::MOVAPDmr, FrameIndex, MI); +#endif } } else if (i == 1) { switch(MI->getOpcode()) { @@ -396,8 +406,46 @@ case X86::MOVSX32rr8:return MakeRMInst(X86::MOVSX32rm8, FrameIndex, MI); case X86::MOVSX32rr16:return MakeRMInst(X86::MOVSX32rm16, FrameIndex, MI); case X86::MOVZX16rr8:return MakeRMInst(X86::MOVZX16rm8 , FrameIndex, MI); - case X86::MOVZX32rr8: return MakeRMInst(X86::MOVZX32rm8, FrameIndex, MI); + case X86::MOVZX32rr8:return MakeRMInst(X86::MOVZX32rm8, FrameIndex, MI); case X86::MOVZX32rr16:return MakeRMInst(X86::MOVZX32rm16, FrameIndex, MI); + // Scalar SSE instructions + case X86::MOVSSrr: return MakeRMInst(X86::MOVSSrm, FrameIndex, MI); + case X86::MOVSDrr: return MakeRMInst(X86::MOVSDrm, FrameIndex, MI); + case X86::CVTTSS2SIrr:return MakeRMInst(X86::CVTTSS2SIrm, FrameIndex, MI); + case X86::CVTTSD2SIrr:return MakeRMInst(X86::CVTTSD2SIrm, FrameIndex, MI); + case X86::CVTSS2SDrr:return MakeRMInst(X86::CVTSS2SDrm, FrameIndex, MI); + case X86::CVTSD2SSrr:return MakeRMInst(X86::CVTSD2SSrm, FrameIndex, MI); + case X86::CVTSI2SSrr:return MakeRMInst(X86::CVTSI2SSrm, FrameIndex, MI); + case X86::CVTSI2SDrr:return MakeRMInst(X86::CVTSI2SDrm, FrameIndex, MI); + case X86::SQRTSSrr: return MakeRMInst(X86::SQRTSSrm, FrameIndex, MI); + case X86::SQRTSDrr: return MakeRMInst(X86::SQRTSDrm, FrameIndex, MI); + case X86::UCOMISSrr: return MakeRMInst(X86::UCOMISSrm, FrameIndex, MI); + case X86::UCOMISDrr: return MakeRMInst(X86::UCOMISDrm, FrameIndex, MI); + case X86::ADDSSrr: return MakeRMInst(X86::ADDSSrm, FrameIndex, MI); + case X86::ADDSDrr: return MakeRMInst(X86::ADDSDrm, FrameIndex, MI); + case X86::MULSSrr: return MakeRMInst(X86::MULSSrm, FrameIndex, MI); + case X86::MULSDrr: return MakeRMInst(X86::MULSDrm, FrameIndex, MI); + case X86::DIVSSrr: return MakeRMInst(X86::DIVSSrm, FrameIndex, MI); + case X86::DIVSDrr: return MakeRMInst(X86::DIVSDrm, FrameIndex, MI); + case X86::SUBSSrr: return MakeRMInst(X86::SUBSSrm, FrameIndex, MI); + case X86::SUBSDrr: return MakeRMInst(X86::SUBSDrm, FrameIndex, MI); + case X86::CMPSSrr: return MakeRMInst(X86::CMPSSrm, FrameIndex, MI); + case X86::CMPSDrr: return MakeRMInst(X86::CMPSDrm, FrameIndex, MI); +#if 0 + // Packed SSE instructions + // FIXME: Can't use these until we are spilling XMM registers to + // 128-bit locations. + case X86::ANDPSrr: return MakeRMInst(X86::ANDPSrm, FrameIndex, MI); + case X86::ANDPDrr: return MakeRMInst(X86::ANDPDrm, FrameIndex, MI); + case X86::ORPSrr: return MakeRMInst(X86::ORPSrm, FrameIndex, MI); + case X86::ORPDrr: return MakeRMInst(X86::ORPDrm, FrameIndex, MI); + case X86::XORPSrr: return MakeRMInst(X86::XORPSrm, FrameIndex, MI); + case X86::XORPDrr: return MakeRMInst(X86::XORPDrm, FrameIndex, MI); + case X86::ANDNPSrr: return MakeRMInst(X86::ANDNPSrm, FrameIndex, MI); + case X86::ANDNPDrr: return MakeRMInst(X86::ANDNPDrm, FrameIndex, MI); + case X86::MOVAPSrr: return MakeRMInst(X86::MOVAPSrm, FrameIndex, MI); + case X86::MOVAPDrr: return MakeRMInst(X86::MOVAPDrm, FrameIndex, MI); +#endif } } if (PrintFailedFusing) From evan.cheng at apple.com Wed Feb 1 17:03:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 17:03:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200602012303.RAA23886@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.41 -> 1.42 --- Log message: Tell codegen MOVAPSrr and MOVAPDrr are copies. --- Diffs of the changes: (+2 -1) X86InstrInfo.cpp | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.41 llvm/lib/Target/X86/X86InstrInfo.cpp:1.42 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.41 Fri Oct 14 17:06:00 2005 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Wed Feb 1 17:03:16 2006 @@ -28,7 +28,8 @@ unsigned& destReg) const { MachineOpCode oc = MI.getOpcode(); if (oc == X86::MOV8rr || oc == X86::MOV16rr || oc == X86::MOV32rr || - oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr) { + oc == X86::FpMOV || oc == X86::MOVSSrr || oc == X86::MOVSDrr || + oc == X86::MOVAPSrr || oc == X86::MOVAPDrr) { assert(MI.getNumOperands() == 2 && MI.getOperand(0).isRegister() && MI.getOperand(1).isRegister() && From lattner at cs.uiuc.edu Wed Feb 1 17:38:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 17:38:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602012338.RAA24177@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.40 -> 1.41 --- Log message: more notes --- Diffs of the changes: (+54 -0) README.txt | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 54 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.40 llvm/lib/Target/X86/README.txt:1.41 --- llvm/lib/Target/X86/README.txt:1.40 Wed Feb 1 15:44:48 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 1 17:38:08 2006 @@ -313,3 +313,57 @@ We need to lower switch statements to tablejumps when appropriate instead of always into binary branch trees. + +//===---------------------------------------------------------------------===// + +SSE doesn't have [mem] op= reg instructions. If we have an SSE instruction +like this: + + X += y + +and the register allocator decides to spill X, it is cheaper to emit this as: + +Y += [xslot] +store Y -> [xslot] + +than as: + +tmp = [xslot] +tmp += y +store tmp -> [xslot] + +..and this uses one fewer register (so this should be done at load folding +time, not at spiller time). *Note* however that this can only be done +if Y is dead. Here's a testcase: + +%.str_3 = external global [15 x sbyte] ; <[15 x sbyte]*> [#uses=0] +implementation ; Functions: +declare void %printf(int, ...) +void %main() { +build_tree.exit: + br label %no_exit.i7 +no_exit.i7: ; preds = %no_exit.i7, %build_tree.exit + %tmp.0.1.0.i9 = phi double [ 0.000000e+00, %build_tree.exit ], [ %tmp.34.i18, %no_exit.i7 ] ; [#uses=1] + %tmp.0.0.0.i10 = phi double [ 0.000000e+00, %build_tree.exit ], [ %tmp.28.i16, %no_exit.i7 ] ; [#uses=1] + %tmp.28.i16 = add double %tmp.0.0.0.i10, 0.000000e+00 + %tmp.34.i18 = add double %tmp.0.1.0.i9, 0.000000e+00 + br bool false, label %Compute_Tree.exit23, label %no_exit.i7 +Compute_Tree.exit23: ; preds = %no_exit.i7 + tail call void (int, ...)* %printf( int 0 ) + store double %tmp.34.i18, double* null + ret void +} + +We currently emit: + +.BBmain_1: + xorpd %XMM1, %XMM1 + addsd %XMM0, %XMM1 +*** movsd %XMM2, QWORD PTR [%ESP + 8] +*** addsd %XMM2, %XMM1 +*** movsd QWORD PTR [%ESP + 8], %XMM2 + jmp .BBmain_1 # no_exit.i7 + +This is a bugpoint reduced testcase, which is why the testcase doesn't make +much sense (e.g. its an infinite loop). :) + From lattner at cs.uiuc.edu Wed Feb 1 18:23:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 18:23:24 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/InlineAsm.h Message-ID: <200602020023.SAA24401@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm: InlineAsm.h updated: 1.7 -> 1.8 --- Log message: add an instance var and argument. --- Diffs of the changes: (+6 -1) InlineAsm.h | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletion(-) Index: llvm/include/llvm/InlineAsm.h diff -u llvm/include/llvm/InlineAsm.h:1.7 llvm/include/llvm/InlineAsm.h:1.8 --- llvm/include/llvm/InlineAsm.h:1.7 Tue Jan 31 19:27:37 2006 +++ llvm/include/llvm/InlineAsm.h Wed Feb 1 18:23:12 2006 @@ -86,6 +86,10 @@ /// to store the output result is passed as an operand to the call. bool isIndirectOutput; + /// hasMatchingInput - This is set to true for an output constraint iff + /// there is an input constraint that is required to match it (e.g. "0"). + bool hasMatchingInput; + /// Code - The constraint code, either the register name (in braces) or the /// constraint letter/number. std::vector Codes; @@ -93,7 +97,8 @@ /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. - bool Parse(const std::string &Str); + bool Parse(const std::string &Str, + std::vector &ConstraintsSoFar); }; /// ParseConstraints - Split up the constraint string into the specific From lattner at cs.uiuc.edu Wed Feb 1 18:24:05 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 18:24:05 -0600 Subject: [llvm-commits] CVS: llvm/lib/VMCore/InlineAsm.cpp Message-ID: <200602020024.SAA24462@zion.cs.uiuc.edu> Changes in directory llvm/lib/VMCore: InlineAsm.cpp updated: 1.7 -> 1.8 --- Log message: validate matching constraints and remember when we see them. --- Diffs of the changes: (+15 -5) InlineAsm.cpp | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) Index: llvm/lib/VMCore/InlineAsm.cpp diff -u llvm/lib/VMCore/InlineAsm.cpp:1.7 llvm/lib/VMCore/InlineAsm.cpp:1.8 --- llvm/lib/VMCore/InlineAsm.cpp:1.7 Tue Jan 31 22:37:04 2006 +++ llvm/lib/VMCore/InlineAsm.cpp Wed Feb 1 18:23:53 2006 @@ -42,13 +42,15 @@ /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the /// fields in this structure. If the constraint string is not understood, /// return true, otherwise return false. -bool InlineAsm::ConstraintInfo::Parse(const std::string &Str) { +bool InlineAsm::ConstraintInfo::Parse(const std::string &Str, + std::vector &ConstraintsSoFar) { std::string::const_iterator I = Str.begin(), E = Str.end(); // Initialize Type = isInput; isEarlyClobber = false; - isIndirectOutput =false; + isIndirectOutput = false; + hasMatchingInput = false; // Parse the prefix. if (*I == '~') { @@ -94,12 +96,20 @@ if (ConstraintEnd == E) return true; // "{foo" Codes.push_back(std::string(I, ConstraintEnd+1)); I = ConstraintEnd+1; - } else if (isdigit(*I)) { + } else if (isdigit(*I)) { // Matching Constraint // Maximal munch numbers. std::string::const_iterator NumStart = I; while (I != E && isdigit(*I)) ++I; Codes.push_back(std::string(NumStart, I)); + unsigned N = atoi(Codes.back().c_str()); + // Check that this is a valid matching constraint! + if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput|| + Type != isInput) + return true; // Invalid constraint number. + + // Note that operand #n has a matching input. + ConstraintsSoFar[N].hasMatchingInput = true; } else { // Single letter constraint. Codes.push_back(std::string(I, I+1)); @@ -123,8 +133,8 @@ std::string::const_iterator ConstraintEnd = std::find(I, E, ','); if (ConstraintEnd == I || // Empty constraint like ",," - Info.Parse(std::string(I, ConstraintEnd))) { // Erroneous constraint? - Result.clear(); + Info.Parse(std::string(I, ConstraintEnd), Result)) { + Result.clear(); // Erroneous constraint? break; } From lattner at cs.uiuc.edu Wed Feb 1 18:25:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 18:25:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602020025.SAA24561@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.145 -> 1.146 --- Log message: Implement matching constraints. We can now say things like this: %C = call int asm "xyz $0, $1, $2, $3", "=r,r,r,0"(int %A, int %B, int 4) and get: xyz r2, r3, r4, r2 note that the r2's are pinned together. Yaay for 2-address instructions. 2342 ---------------------------------------------------------------------- --- Diffs of the changes: (+28 -15) SelectionDAGISel.cpp | 43 ++++++++++++++++++++++++++++--------------- 1 files changed, 28 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.145 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.146 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.145 Wed Feb 1 12:59:47 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Wed Feb 1 18:25:23 2006 @@ -1232,6 +1232,7 @@ for (unsigned i = 0, e = Constraints.size(); i != e; ++i) { assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!"); std::string &ConstraintCode = Constraints[i].Codes[0]; + std::vector Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); if (Regs.size() != 1) continue; // Not assigned a fixed reg. @@ -1243,7 +1244,7 @@ OutputRegs.insert(TheReg); // If this is an early-clobber output, it cannot be assigned to the same // value as the input reg. - if (Constraints[i].isEarlyClobber) + if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) InputRegs.insert(TheReg); break; case InlineAsm::isClobber: @@ -1263,7 +1264,6 @@ std::string &ConstraintCode = Constraints[i].Codes[0]; switch (Constraints[i].Type) { case InlineAsm::isOutput: { - // Copy the output from the appropriate register. std::vector Regs = TLI.getRegForInlineAsmConstraint(ConstraintCode); @@ -1272,10 +1272,17 @@ unsigned DestReg; if (Regs.size() == 1) DestReg = Regs[0]; - else - DestReg = GetAvailableRegister(true, Constraints[i].isEarlyClobber, + else { + bool UsesInputRegister = false; + // If this is an early-clobber output, or if there is an input + // constraint that matches this, we need to reserve the input register + // so no other inputs allocate to it. + if (Constraints[i].isEarlyClobber || Constraints[i].hasMatchingInput) + UsesInputRegister = true; + DestReg = GetAvailableRegister(true, UsesInputRegister, Regs, OutputRegs, InputRegs); - + } + assert(DestReg && "Couldn't allocate output reg!"); const Type *OpTy; @@ -1307,17 +1314,23 @@ Value *Operand = I.getOperand(OpNum); const Type *OpTy = Operand->getType(); OpNum++; // Consumes a call operand. - - // Copy the input into the appropriate register. - std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode); + unsigned SrcReg; - if (Regs.size() == 1) - SrcReg = Regs[0]; - else - SrcReg = GetAvailableRegister(false, true, Regs, - OutputRegs, InputRegs); - + if (isdigit(ConstraintCode[0])) { // Matching constraint? + // If this is required to match an output register we have already set, + // just use its register. + unsigned OperandNo = atoi(ConstraintCode.c_str()); + SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); + } else { + // Copy the input into the appropriate register. + std::vector Regs = + TLI.getRegForInlineAsmConstraint(ConstraintCode); + if (Regs.size() == 1) + SrcReg = Regs[0]; + else + SrcReg = GetAvailableRegister(false, true, Regs, + OutputRegs, InputRegs); + } assert(SrcReg && "Couldn't allocate input reg!"); Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag); From evan.cheng at apple.com Wed Feb 1 18:28:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 18:28:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200602020028.SAA24579@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.76 -> 1.77 --- Log message: Fix a erroneous comment. --- Diffs of the changes: (+1 -1) X86ISelLowering.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.76 llvm/lib/Target/X86/X86ISelLowering.cpp:1.77 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.76 Wed Feb 1 01:19:44 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Wed Feb 1 18:28:23 2006 @@ -219,7 +219,7 @@ setOperationAction(ISD::FNEG , MVT::f64, Custom); setOperationAction(ISD::FNEG , MVT::f32, Custom); - // We don't support sin/cos/sqrt/fmod + // We don't support sin/cos/fmod setOperationAction(ISD::FSIN , MVT::f64, Expand); setOperationAction(ISD::FCOS , MVT::f64, Expand); setOperationAction(ISD::FREM , MVT::f64, Expand); From lattner at cs.uiuc.edu Wed Feb 1 18:38:20 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed, 1 Feb 2006 18:38:20 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Message-ID: <200602020038.SAA24663@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAGList.cpp updated: 1.5 -> 1.6 --- Log message: make -debug output less newliney --- Diffs of the changes: (+1 -2) ScheduleDAGList.cpp | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.5 llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.6 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp:1.5 Wed Jan 25 18:30:29 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp Wed Feb 1 18:38:08 2006 @@ -257,9 +257,8 @@ for (unsigned i = 0, e = NotReady.size(); i != e; ++i) Available.push(NotReady[i]); - DEBUG(std::cerr << "\n*** Scheduling: "); + DEBUG(std::cerr << "*** Scheduling: "); DEBUG(CurrNode->dump(&DAG, false)); - DEBUG(std::cerr << "\n"); ScheduleNode(CurrNode); } From evan.cheng at apple.com Wed Feb 1 20:40:28 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 1 Feb 2006 20:40:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602020240.UAA25296@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.41 -> 1.42 --- Log message: Update. --- Diffs of the changes: (+5 -12) README.txt | 17 +++++------------ 1 files changed, 5 insertions(+), 12 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.41 llvm/lib/Target/X86/README.txt:1.42 --- llvm/lib/Target/X86/README.txt:1.41 Wed Feb 1 17:38:08 2006 +++ llvm/lib/Target/X86/README.txt Wed Feb 1 20:40:17 2006 @@ -215,18 +215,6 @@ //===---------------------------------------------------------------------===// -None of the SSE instructions are handled in X86RegisterInfo::foldMemoryOperand, -which prevents the spiller from folding spill code into the instructions. - -This leads to code like this: - -mov %eax, 8(%esp) -cvtsi2sd %eax, %xmm0 -instead of: -cvtsi2sd 8(%esp), %xmm0 - -//===---------------------------------------------------------------------===// - LSR should be turned on for the X86 backend and tuned to take advantage of its addressing modes. @@ -367,3 +355,8 @@ This is a bugpoint reduced testcase, which is why the testcase doesn't make much sense (e.g. its an infinite loop). :) +//===---------------------------------------------------------------------===// + +None of the FPStack instructions are handled in +X86RegisterInfo::foldMemoryOperand, which prevents the spiller from +folding spill code into the instructions. From lattner at cs.uiuc.edu Thu Feb 2 00:35:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 00:35:50 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/compare-add.ll Message-ID: <200602020635.AAA26419@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: compare-add.ll added (r1.1) --- Log message: new testcase --- Diffs of the changes: (+8 -0) compare-add.ll | 8 ++++++++ 1 files changed, 8 insertions(+) Index: llvm/test/Regression/CodeGen/X86/compare-add.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/compare-add.ll:1.1 *** /dev/null Thu Feb 2 00:35:48 2006 --- llvm/test/Regression/CodeGen/X86/compare-add.ll Thu Feb 2 00:35:38 2006 *************** *** 0 **** --- 1,8 ---- + ; RUN: llvm-as < %s | llc -march=x86 && + ; RUN: llvm-as < %s | llc -march=x86 | not grep add + bool %X(int %X) { + %Y = add int %X, 14 + %Z = setne int %Y, 12345 + ret bool %Z + } + From lattner at cs.uiuc.edu Thu Feb 2 00:36:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 00:36:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602020636.AAA26429@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.91 -> 1.92 --- Log message: add two dag combines: (C1-X) == C2 --> X == C1-C2 (X+C1) == C2 --> X == C2-C1 This allows us to compile this: bool %X(int %X) { %Y = add int %X, 14 %Z = setne int %Y, 12345 ret bool %Z } into this: _X: cmpl $12331, 4(%esp) setne %al movzbl %al, %eax andl $1, %eax ret not this: _X: movl $14, %eax addl 4(%esp), %eax cmpl $12345, %eax setne %al movzbl %al, %eax andl $1, %eax ret Testcase here: Regression/CodeGen/X86/compare-add.ll nukage of the and coming up next. --- Diffs of the changes: (+25 -8) DAGCombiner.cpp | 33 +++++++++++++++++++++++++-------- 1 files changed, 25 insertions(+), 8 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.91 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.92 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.91 Wed Feb 1 01:19:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Feb 2 00:36:13 2006 @@ -2623,19 +2623,36 @@ return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(1), Cond); } } - - // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0. Common for condcodes. - if (N0.getOpcode() == ISD::XOR) - if (ConstantSDNode *XORC = dyn_cast(N0.getOperand(1))) - if (ConstantSDNode *RHSC = dyn_cast(N1)) { + + if (ConstantSDNode *RHSC = dyn_cast(N1)) { + if (ConstantSDNode *LHSR = dyn_cast(N0.getOperand(1))) { + // Turn (X+C1) == C2 --> X == C2-C1 + if (N0.getOpcode() == ISD::ADD && N0.Val->hasOneUse()) { + return DAG.getSetCC(VT, N0.getOperand(0), + DAG.getConstant(RHSC->getValue()-LHSR->getValue(), + N0.getValueType()), Cond); + } + + // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0. + if (N0.getOpcode() == ISD::XOR) // If we know that all of the inverted bits are zero, don't bother // performing the inversion. - if (TLI.MaskedValueIsZero(N0.getOperand(0), ~XORC->getValue())) + if (TLI.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getValue())) return DAG.getSetCC(VT, N0.getOperand(0), - DAG.getConstant(XORC->getValue()^RHSC->getValue(), + DAG.getConstant(LHSR->getValue()^RHSC->getValue(), N0.getValueType()), Cond); + } + + // Turn (C1-X) == C2 --> X == C1-C2 + if (ConstantSDNode *SUBC = dyn_cast(N0.getOperand(0))) { + if (N0.getOpcode() == ISD::SUB && N0.Val->hasOneUse()) { + return DAG.getSetCC(VT, N0.getOperand(1), + DAG.getConstant(SUBC->getValue()-RHSC->getValue(), + N0.getValueType()), Cond); } - + } + } + // Simplify (X+Z) == X --> Z == 0 if (N0.getOperand(0) == N1) return DAG.getSetCC(VT, N0.getOperand(1), From lattner at cs.uiuc.edu Thu Feb 2 00:37:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 00:37:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602020637.AAA26462@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.42 -> 1.43 --- Log message: implemented, testcase here: test/Regression/CodeGen/X86/compare-add.ll --- Diffs of the changes: (+0 -10) README.txt | 10 ---------- 1 files changed, 10 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.42 llvm/lib/Target/X86/README.txt:1.43 --- llvm/lib/Target/X86/README.txt:1.42 Wed Feb 1 20:40:17 2006 +++ llvm/lib/Target/X86/README.txt Thu Feb 2 00:36:48 2006 @@ -289,16 +289,6 @@ //===---------------------------------------------------------------------===// -This shouldn't have an explicit ADD (target independent dag combiner hack): - -bool %X(int %X) { - %Y = add int %X, 14 - %Z = setne int %Y, 12345 - ret bool %Z -} - -//===---------------------------------------------------------------------===// - We need to lower switch statements to tablejumps when appropriate instead of always into binary branch trees. From lattner at cs.uiuc.edu Thu Feb 2 00:43:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 00:43:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602020643.AAA26527@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.25 -> 1.26 --- Log message: Implement MaskedValueIsZero for ANY_EXTEND nodes --- Diffs of the changes: (+5 -0) TargetLowering.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.25 llvm/lib/Target/TargetLowering.cpp:1.26 --- llvm/lib/Target/TargetLowering.cpp:1.25 Tue Jan 31 19:29:22 2006 +++ llvm/lib/Target/TargetLowering.cpp Thu Feb 2 00:43:15 2006 @@ -154,6 +154,11 @@ case ISD::ZERO_EXTEND: SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); return MaskedValueIsZero(Op.getOperand(0),Mask & (~0ULL >> (64-SrcBits))); + case ISD::ANY_EXTEND: + // If the mask only includes bits in the low part, recurse. + SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType()); + if (Mask >> SrcBits) return false; // Use of unknown top bits. + return MaskedValueIsZero(Op.getOperand(0), Mask); case ISD::AssertZext: SrcBits = MVT::getSizeInBits(cast(Op.getOperand(1))->getVT()); return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits. From lattner at cs.uiuc.edu Thu Feb 2 01:17:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 01:17:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602020717.BAA26701@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.92 -> 1.93 --- Log message: Turn any_extend nodes into zero_extend nodes when it allows us to remove an and instruction. This allows us to compile stuff like this: bool %X(int %X) { %Y = add int %X, 14 %Z = setne int %Y, 12345 ret bool %Z } to this: _X: cmpl $12331, 4(%esp) setne %al movzbl %al, %eax ret instead of this: _X: cmpl $12331, 4(%esp) setne %al movzbl %al, %eax andl $1, %eax ret This occurs quite a bit with the X86 backend. For example, 25 times in lambda, 30 times in 177.mesa, 14 times in galgel, 70 times in fma3d, 25 times in vpr, several hundred times in gcc, ~45 times in crafty, ~60 times in parser, ~140 times in eon, 110 times in perlbmk, 55 on gap, 16 times on bzip2, 14 times on twolf, and 1-2 times in many other SPEC2K programs. --- Diffs of the changes: (+13 -0) DAGCombiner.cpp | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.92 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.92 Thu Feb 2 00:36:13 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Feb 2 01:17:31 2006 @@ -889,6 +889,19 @@ if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) if ((ORI->getValue() & N1C->getValue()) == N1C->getValue()) return N1; + // fold (and (any_ext V), c) -> (zero_ext V) if 'and' only clears top bits. + if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) { + unsigned InBits = MVT::getSizeInBits(N0.getOperand(0).getValueType()); + if (TLI.MaskedValueIsZero(N0.getOperand(0), + ~N1C->getValue() & ((1ULL << InBits)-1))) { + // We actually want to replace all uses of the any_extend with the + // zero_extend, to avoid duplicating things. This will later cause this + // AND to be folded. + CombineTo(N0.Val, DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(), + N0.getOperand(0))); + return SDOperand(); + } + } // fold (and (setcc x), (setcc y)) -> (setcc (and x, y)) if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ ISD::CondCode Op0 = cast(CC0)->get(); From natebegeman at mac.com Thu Feb 2 01:28:08 2006 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 2 Feb 2006 01:28:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602020728.BAA26790@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.53 -> 1.54 --- Log message: Update the README --- Diffs of the changes: (+3 -19) README.txt | 22 +++------------------- 1 files changed, 3 insertions(+), 19 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.53 llvm/lib/Target/PowerPC/README.txt:1.54 --- llvm/lib/Target/PowerPC/README.txt:1.53 Wed Feb 1 11:54:23 2006 +++ llvm/lib/Target/PowerPC/README.txt Thu Feb 2 01:27:56 2006 @@ -94,19 +94,6 @@ ===-------------------------------------------------------------------------=== -int foo(int a, int b) { return a == b ? 16 : 0; } -_foo: - cmpw cr7, r3, r4 - mfcr r2 - rlwinm r2, r2, 31, 31, 31 - slwi r3, r2, 4 - blr - -If we exposed the srl & mask ops after the MFCR that we are doing to select -the correct CR bit, then we could fold the slwi into the rlwinm before it. - -===-------------------------------------------------------------------------=== - #define ARRAY_LENGTH 16 union bitfield { @@ -451,16 +438,13 @@ cntlzw r2, r2 cntlzw r3, r3 srwi r2, r2, 5 - srwi r3, r3, 5 - li r4, 0 + srwi r4, r3, 5 + li r3, 0 cmpwi cr0, r2, 0 bne cr0, LBB1_2 ; LBB1_1: - or r4, r3, r3 + or r3, r4, r4 LBB1_2: - cmplw cr7, r4, r3 - mfcr r2, 1 - rlwinm r3, r2, 29, 31, 31 blr noticed in 2005-05-11-Popcount-ffs-fls.c. From lattner at cs.uiuc.edu Thu Feb 2 01:37:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 01:37:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602020737.BAA26869@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.54 -> 1.55 --- Log message: new example --- Diffs of the changes: (+19 -0) README.txt | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.54 llvm/lib/Target/PowerPC/README.txt:1.55 --- llvm/lib/Target/PowerPC/README.txt:1.54 Thu Feb 2 01:27:56 2006 +++ llvm/lib/Target/PowerPC/README.txt Thu Feb 2 01:37:11 2006 @@ -448,3 +448,22 @@ blr noticed in 2005-05-11-Popcount-ffs-fls.c. + + +===-------------------------------------------------------------------------=== + +We should custom expand setcc instead of pretending that we have it. That +would allow us to expose the access of the crbit after the mfcr, allowing +that access to be trivially folded into other ops. A simple example: + +int foo(int a, int b) { return (a < b) << 4; } + +compiles into: + +_foo: + cmpw cr7, r3, r4 + mfcr r2, 1 + rlwinm r2, r2, 29, 31, 31 + slwi r3, r2, 4 + blr + From lattner at cs.uiuc.edu Thu Feb 2 01:56:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 01:56:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200602020756.BAA26960@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.115 -> 1.116 --- Log message: correct an opcode --- Diffs of the changes: (+2 -2) SparcV8InstrInfo.td | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.115 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.116 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.115 Tue Jan 31 01:26:55 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Thu Feb 2 01:56:15 2006 @@ -739,12 +739,12 @@ def MOVFCCrr : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), - "movf$cc %fcc, $F, $dst", + "mov$cc %fcc, $F, $dst", [(set IntRegs:$dst, (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; def MOVFCCri : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), - "movf$cc %fcc, $F, $dst", + "mov$cc %fcc, $F, $dst", [(set IntRegs:$dst, (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; From lattner at cs.uiuc.edu Thu Feb 2 02:02:31 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 02:02:31 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Message-ID: <200602020802.CAA27035@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.td updated: 1.116 -> 1.117 --- Log message: %fcc is not an alias for %fcc0 --- Diffs of the changes: (+4 -4) SparcV8InstrInfo.td | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.td diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.116 llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.117 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.td:1.116 Thu Feb 2 01:56:15 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.td Thu Feb 2 02:02:20 2006 @@ -739,12 +739,12 @@ def MOVFCCrr : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), - "mov$cc %fcc, $F, $dst", + "mov$cc %fcc0, $F, $dst", [(set IntRegs:$dst, (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; def MOVFCCri : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), - "mov$cc %fcc, $F, $dst", + "mov$cc %fcc0, $F, $dst", [(set IntRegs:$dst, (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; @@ -760,12 +760,12 @@ (V8selecticc DFPRegs:$F, DFPRegs:$T, imm:$cc, ICC))]>; def FMOVS_FCC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, V8CC:$cc), - "fmovs$cc %fcc, $F, $dst", + "fmovs$cc %fcc0, $F, $dst", [(set FPRegs:$dst, (V8selectfcc FPRegs:$F, FPRegs:$T, imm:$cc, FCC))]>; def FMOVD_FCC : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, V8CC:$cc), - "fmovd$cc %fcc, $F, $dst", + "fmovd$cc %fcc0, $F, $dst", [(set DFPRegs:$dst, (V8selectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc, FCC))]>; From lattner at cs.uiuc.edu Thu Feb 2 13:16:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 13:16:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602021916.NAA07132@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.43 -> 1.44 --- Log message: add a note, I have no idea how important this is. --- Diffs of the changes: (+24 -0) README.txt | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.43 llvm/lib/Target/X86/README.txt:1.44 --- llvm/lib/Target/X86/README.txt:1.43 Thu Feb 2 00:36:48 2006 +++ llvm/lib/Target/X86/README.txt Thu Feb 2 13:16:34 2006 @@ -350,3 +350,27 @@ None of the FPStack instructions are handled in X86RegisterInfo::foldMemoryOperand, which prevents the spiller from folding spill code into the instructions. + +//===---------------------------------------------------------------------===// + +In many cases, LLVM generates code like this: + +_test: + movl 8(%esp), %eax + cmpl %eax, 4(%esp) + setl %al + movzbl %al, %eax + ret + +on some processors (which ones?), it is more efficient to do this: + +_test: + movl 8(%esp), %ebx + xor %eax, %eax + cmpl %ebx, 4(%esp) + setl %al + ret + +Doing this correctly is tricky though, as the xor clobbers the flags. + + From lattner at cs.uiuc.edu Thu Feb 2 13:43:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 13:43:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602021943.NAA07326@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.44 -> 1.45 --- Log message: more notes --- Diffs of the changes: (+52 -0) README.txt | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 52 insertions(+) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.44 llvm/lib/Target/X86/README.txt:1.45 --- llvm/lib/Target/X86/README.txt:1.44 Thu Feb 2 13:16:34 2006 +++ llvm/lib/Target/X86/README.txt Thu Feb 2 13:43:28 2006 @@ -373,4 +373,56 @@ Doing this correctly is tricky though, as the xor clobbers the flags. +//===---------------------------------------------------------------------===// + +We should generate 'test' instead of 'cmp' in various cases, e.g.: + +bool %test(int %X) { + %Y = shl int %X, ubyte 1 + %C = seteq int %Y, 0 + ret bool %C +} +bool %test(int %X) { + %Y = and int %X, 8 + %C = seteq int %Y, 0 + ret bool %C +} + +This may just be a matter of using 'test' to write bigger patterns for X86cmp. + +//===---------------------------------------------------------------------===// + +Evaluate whether using movapd for SSE reg-reg moves is faster than using +movsd/movss for them. It may eliminate false partial register dependences by +writing the whole result register. + +//===---------------------------------------------------------------------===// + +SSE should implement 'select_cc' using 'emulated conditional moves' that use +pcmp/pand/pandn/por to do a selection instead of a conditional branch: + +double %X(double %Y, double %Z, double %A, double %B) { + %C = setlt double %A, %B + %z = add double %Z, 0.0 ;; select operand is not a load + %D = select bool %C, double %Y, double %z + ret double %D +} + +We currently emit: + +_X: + subl $12, %esp + xorpd %xmm0, %xmm0 + addsd 24(%esp), %xmm0 + movsd 32(%esp), %xmm1 + movsd 16(%esp), %xmm2 + ucomisd 40(%esp), %xmm1 + jb LBB_X_2 +LBB_X_1: + movsd %xmm0, %xmm2 +LBB_X_2: + movsd %xmm2, (%esp) + fldl (%esp) + addl $12, %esp + ret From lattner at cs.uiuc.edu Thu Feb 2 13:55:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 13:55:41 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h Message-ID: <200602021955.NAA07417@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.66 -> 1.67 --- Log message: add a new isStoreToStackSlot method --- Diffs of the changes: (+10 -1) MRegisterInfo.h | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletion(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.66 llvm/include/llvm/Target/MRegisterInfo.h:1.67 --- llvm/include/llvm/Target/MRegisterInfo.h:1.66 Wed Nov 30 22:51:06 2005 +++ llvm/include/llvm/Target/MRegisterInfo.h Thu Feb 2 13:55:29 2006 @@ -262,12 +262,21 @@ /// isLoadFromStackSlot - If the specified machine instruction is a direct /// load from a stack slot, return the virtual or physical register number of /// the destination along with the FrameIndex of the loaded stack slot. If - /// not, return 0. This predicate must return false if the instruction has + /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ return 0; } + /// isStoreToStackSlot - If the specified machine instruction is a direct + /// store to a stack slot, return the virtual or physical register number of + /// the source reg along with the FrameIndex of the loaded stack slot. If + /// not, return 0. This predicate must return 0 if the instruction has + /// any side effects other than storing to the stack slot. + virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + return 0; + } + /// foldMemoryOperand - Attempt to fold a load or store of the /// specified stack slot into the specified machine instruction for /// the specified operand. If this is possible, a new instruction From lattner at cs.uiuc.edu Thu Feb 2 13:57:27 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 13:57:27 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.h Message-ID: <200602021957.NAA07483@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.h updated: 1.32 -> 1.33 --- Log message: add a method --- Diffs of the changes: (+1 -0) X86RegisterInfo.h | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.32 llvm/lib/Target/X86/X86RegisterInfo.h:1.33 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.32 Thu Sep 29 20:29:42 2005 +++ llvm/lib/Target/X86/X86RegisterInfo.h Thu Feb 2 13:57:16 2006 @@ -42,6 +42,7 @@ const TargetRegisterClass *RC) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; /// foldMemoryOperand - If this target supports it, fold a load or store of From lattner at cs.uiuc.edu Thu Feb 2 14:00:53 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:00:53 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200602022000.OAA07549@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86RegisterInfo.cpp updated: 1.118 -> 1.119 --- Log message: implement isStoreToStackSlot --- Diffs of the changes: (+23 -0) X86RegisterInfo.cpp | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+) Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.118 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.119 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.118 Wed Feb 1 17:02:25 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Thu Feb 2 14:00:41 2006 @@ -139,6 +139,29 @@ return 0; } +unsigned X86RegisterInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8mr: + case X86::MOV16mr: + case X86::MOV32mr: + case X86::FpSTP64m: + case X86::MOVSSmr: + case X86::MOVSDmr: + if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && + MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && + MI->getOperand(3).getImmedValue() == 1 && + MI->getOperand(4).getReg() == 0 && + MI->getOperand(5).getImmedValue() == 0) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(4).getReg(); + } + break; + } + return 0; +} + static MachineInstr *MakeMInst(unsigned Opcode, unsigned FrameIndex, MachineInstr *MI) { From lattner at cs.uiuc.edu Thu Feb 2 14:12:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:12:07 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/MRegisterInfo.h TargetInstrInfo.h Message-ID: <200602022012.OAA07669@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: MRegisterInfo.h updated: 1.67 -> 1.68 TargetInstrInfo.h updated: 1.82 -> 1.83 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo, a far more logical place. Other methods should also be moved if anyone is interested. :) --- Diffs of the changes: (+18 -18) MRegisterInfo.h | 18 ------------------ TargetInstrInfo.h | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) Index: llvm/include/llvm/Target/MRegisterInfo.h diff -u llvm/include/llvm/Target/MRegisterInfo.h:1.67 llvm/include/llvm/Target/MRegisterInfo.h:1.68 --- llvm/include/llvm/Target/MRegisterInfo.h:1.67 Thu Feb 2 13:55:29 2006 +++ llvm/include/llvm/Target/MRegisterInfo.h Thu Feb 2 14:11:55 2006 @@ -259,24 +259,6 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const = 0; - /// isLoadFromStackSlot - If the specified machine instruction is a direct - /// load from a stack slot, return the virtual or physical register number of - /// the destination along with the FrameIndex of the loaded stack slot. If - /// not, return 0. This predicate must return 0 if the instruction has - /// any side effects other than loading from the stack slot. - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ - return 0; - } - - /// isStoreToStackSlot - If the specified machine instruction is a direct - /// store to a stack slot, return the virtual or physical register number of - /// the source reg along with the FrameIndex of the loaded stack slot. If - /// not, return 0. This predicate must return 0 if the instruction has - /// any side effects other than storing to the stack slot. - virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { - return 0; - } - /// foldMemoryOperand - Attempt to fold a load or store of the /// specified stack slot into the specified machine instruction for /// the specified operand. If this is possible, a new instruction Index: llvm/include/llvm/Target/TargetInstrInfo.h diff -u llvm/include/llvm/Target/TargetInstrInfo.h:1.82 llvm/include/llvm/Target/TargetInstrInfo.h:1.83 --- llvm/include/llvm/Target/TargetInstrInfo.h:1.82 Thu Jan 26 17:27:02 2006 +++ llvm/include/llvm/Target/TargetInstrInfo.h Thu Feb 2 14:11:55 2006 @@ -212,6 +212,24 @@ unsigned& destReg) const { return false; } + + /// isLoadFromStackSlot - If the specified machine instruction is a direct + /// load from a stack slot, return the virtual or physical register number of + /// the destination along with the FrameIndex of the loaded stack slot. If + /// not, return 0. This predicate must return 0 if the instruction has + /// any side effects other than loading from the stack slot. + virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{ + return 0; + } + + /// isStoreToStackSlot - If the specified machine instruction is a direct + /// store to a stack slot, return the virtual or physical register number of + /// the source reg along with the FrameIndex of the loaded stack slot. If + /// not, return 0. This predicate must return 0 if the instruction has + /// any side effects other than storing to the stack slot. + virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + return 0; + } /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target From lattner at cs.uiuc.edu Thu Feb 2 14:12:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:12:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602022012.OAA07730@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.44 -> 1.45 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far more logical place. Other methods should also be moved if anyoneis interested. :) --- Diffs of the changes: (+3 -2) VirtRegMap.cpp | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.44 llvm/lib/CodeGen/VirtRegMap.cpp:1.45 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.44 Sun Jan 22 17:41:00 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 14:12:13 2006 @@ -490,8 +490,9 @@ // straight load from the virt reg slot. if ((MR & VirtRegMap::isRef) && !(MR & VirtRegMap::isMod)) { int FrameIdx; - if (unsigned DestReg = MRI->isLoadFromStackSlot(&MI, FrameIdx)) { - // If this spill slot is available, insert a copy for it! + if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { + // If this spill slot is available, turn it into a copy (or nothing) + // instead of leaving it as a load! std::map::iterator It = SpillSlotsAvailable.find(SS); if (FrameIdx == SS && It != SpillSlotsAvailable.end()) { DEBUG(std::cerr << "Promoted Load To Copy: " << MI); From lattner at cs.uiuc.edu Thu Feb 2 14:12:44 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:12:44 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp X86InstrInfo.h X86RegisterInfo.cpp X86RegisterInfo.h Message-ID: <200602022012.OAA07781@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.42 -> 1.43 X86InstrInfo.h updated: 1.49 -> 1.50 X86RegisterInfo.cpp updated: 1.119 -> 1.120 X86RegisterInfo.h updated: 1.33 -> 1.34 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far more logical place. Other methods should also be moved if anyoneis interested. :) --- Diffs of the changes: (+53 -55) X86InstrInfo.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ X86InstrInfo.h | 10 +++++----- X86RegisterInfo.cpp | 46 ---------------------------------------------- X86RegisterInfo.h | 4 ---- 4 files changed, 53 insertions(+), 55 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.42 llvm/lib/Target/X86/X86InstrInfo.cpp:1.43 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.42 Wed Feb 1 17:03:16 2006 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Thu Feb 2 14:12:32 2006 @@ -41,6 +41,54 @@ return false; } +unsigned X86InstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8rm: + case X86::MOV16rm: + case X86::MOV32rm: + case X86::FpLD64m: + case X86::MOVSSrm: + case X86::MOVSDrm: + if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && + MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() && + MI->getOperand(2).getImmedValue() == 1 && + MI->getOperand(3).getReg() == 0 && + MI->getOperand(4).getImmedValue() == 0) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} + +unsigned X86InstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case X86::MOV8mr: + case X86::MOV16mr: + case X86::MOV32mr: + case X86::FpSTP64m: + case X86::MOVSSmr: + case X86::MOVSDmr: + if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && + MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && + MI->getOperand(3).getImmedValue() == 1 && + MI->getOperand(4).getReg() == 0 && + MI->getOperand(5).getImmedValue() == 0) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(4).getReg(); + } + break; + } + return 0; +} + + + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into a true Index: llvm/lib/Target/X86/X86InstrInfo.h diff -u llvm/lib/Target/X86/X86InstrInfo.h:1.49 llvm/lib/Target/X86/X86InstrInfo.h:1.50 --- llvm/lib/Target/X86/X86InstrInfo.h:1.49 Wed Feb 1 00:13:50 2006 +++ llvm/lib/Target/X86/X86InstrInfo.h Thu Feb 2 14:12:32 2006 @@ -179,14 +179,14 @@ /// virtual const MRegisterInfo &getRegisterInfo() const { return RI; } - // // Return true if the instruction is a register to register move and // leave the source and dest operands in the passed parameters. // - virtual bool isMoveInstr(const MachineInstr& MI, - unsigned& sourceReg, - unsigned& destReg) const; - + bool isMoveInstr(const MachineInstr& MI, unsigned& sourceReg, + unsigned& destReg) const; + unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; + /// convertToThreeAddress - This method must be implemented by targets that /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target /// may be able to convert a two-address instruction into a true Index: llvm/lib/Target/X86/X86RegisterInfo.cpp diff -u llvm/lib/Target/X86/X86RegisterInfo.cpp:1.119 llvm/lib/Target/X86/X86RegisterInfo.cpp:1.120 --- llvm/lib/Target/X86/X86RegisterInfo.cpp:1.119 Thu Feb 2 14:00:41 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.cpp Thu Feb 2 14:12:32 2006 @@ -116,52 +116,6 @@ BuildMI(MBB, MI, Opc, 1, DestReg).addReg(SrcReg); } -unsigned X86RegisterInfo::isLoadFromStackSlot(MachineInstr *MI, - int &FrameIndex) const { - switch (MI->getOpcode()) { - default: break; - case X86::MOV8rm: - case X86::MOV16rm: - case X86::MOV32rm: - case X86::FpLD64m: - case X86::MOVSSrm: - case X86::MOVSDrm: - if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && - MI->getOperand(3).isRegister() && MI->getOperand(4).isImmediate() && - MI->getOperand(2).getImmedValue() == 1 && - MI->getOperand(3).getReg() == 0 && - MI->getOperand(4).getImmedValue() == 0) { - FrameIndex = MI->getOperand(1).getFrameIndex(); - return MI->getOperand(0).getReg(); - } - break; - } - return 0; -} - -unsigned X86RegisterInfo::isStoreToStackSlot(MachineInstr *MI, - int &FrameIndex) const { - switch (MI->getOpcode()) { - default: break; - case X86::MOV8mr: - case X86::MOV16mr: - case X86::MOV32mr: - case X86::FpSTP64m: - case X86::MOVSSmr: - case X86::MOVSDmr: - if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && - MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && - MI->getOperand(3).getImmedValue() == 1 && - MI->getOperand(4).getReg() == 0 && - MI->getOperand(5).getImmedValue() == 0) { - FrameIndex = MI->getOperand(1).getFrameIndex(); - return MI->getOperand(4).getReg(); - } - break; - } - return 0; -} - static MachineInstr *MakeMInst(unsigned Opcode, unsigned FrameIndex, MachineInstr *MI) { Index: llvm/lib/Target/X86/X86RegisterInfo.h diff -u llvm/lib/Target/X86/X86RegisterInfo.h:1.33 llvm/lib/Target/X86/X86RegisterInfo.h:1.34 --- llvm/lib/Target/X86/X86RegisterInfo.h:1.33 Thu Feb 2 13:57:16 2006 +++ llvm/lib/Target/X86/X86RegisterInfo.h Thu Feb 2 14:12:32 2006 @@ -41,10 +41,6 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; - unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; - - /// foldMemoryOperand - If this target supports it, fold a load or store of /// the specified stack slot into the specified machine instruction for the /// specified operand. If this is possible, the target should perform the From lattner at cs.uiuc.edu Thu Feb 2 14:12:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:12:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp AlphaInstrInfo.h AlphaRegisterInfo.cpp AlphaRegisterInfo.h Message-ID: <200602022012.OAA07791@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.cpp updated: 1.6 -> 1.7 AlphaInstrInfo.h updated: 1.3 -> 1.4 AlphaRegisterInfo.cpp updated: 1.34 -> 1.35 AlphaRegisterInfo.h updated: 1.8 -> 1.9 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far more logical place. Other methods should also be moved if anyoneis interested. :) --- Diffs of the changes: (+21 -21) AlphaInstrInfo.cpp | 19 +++++++++++++++++++ AlphaInstrInfo.h | 2 ++ AlphaRegisterInfo.cpp | 19 ------------------- AlphaRegisterInfo.h | 2 -- 4 files changed, 21 insertions(+), 21 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.6 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.7 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.6 Wed Nov 9 13:17:08 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Thu Feb 2 14:12:32 2006 @@ -42,3 +42,22 @@ } return false; } + +unsigned +AlphaInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const { + switch (MI->getOpcode()) { + case Alpha::LDL: + case Alpha::LDQ: + case Alpha::LDBU: + case Alpha::LDWU: + case Alpha::LDS: + case Alpha::LDT: + if (MI->getOperand(1).isFrameIndex()) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} + Index: llvm/lib/Target/Alpha/AlphaInstrInfo.h diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.3 llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.4 --- llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.3 Thu Apr 21 18:10:23 2005 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.h Thu Feb 2 14:12:32 2006 @@ -35,6 +35,8 @@ /// virtual bool isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const; + + virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; }; } Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.34 llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.35 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp:1.34 Wed Feb 1 13:37:33 2006 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.cpp Thu Feb 2 14:12:32 2006 @@ -104,25 +104,6 @@ abort(); } -unsigned -AlphaRegisterInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const -{ - switch (MI->getOpcode()) { - case Alpha::LDL: - case Alpha::LDQ: - case Alpha::LDBU: - case Alpha::LDWU: - case Alpha::LDS: - case Alpha::LDT: - if (MI->getOperand(1).isFrameIndex()) { - FrameIndex = MI->getOperand(1).getFrameIndex(); - return MI->getOperand(0).getReg(); - } - break; - } - return 0; -} - MachineInstr *AlphaRegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum, int FrameIndex) const { Index: llvm/lib/Target/Alpha/AlphaRegisterInfo.h diff -u llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.8 llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.9 --- llvm/lib/Target/Alpha/AlphaRegisterInfo.h:1.8 Wed Nov 9 13:17:08 2005 +++ llvm/lib/Target/Alpha/AlphaRegisterInfo.h Thu Feb 2 14:12:32 2006 @@ -35,8 +35,6 @@ unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; - virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - MachineInstr* foldMemoryOperand(MachineInstr *MI, unsigned OpNum, int FrameIndex) const; From lattner at cs.uiuc.edu Thu Feb 2 14:12:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:12:45 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp PPCInstrInfo.h PPCRegisterInfo.cpp PPCRegisterInfo.h Message-ID: <200602022012.OAA07801@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.cpp updated: 1.13 -> 1.14 PPCInstrInfo.h updated: 1.9 -> 1.10 PPCRegisterInfo.cpp updated: 1.42 -> 1.43 PPCRegisterInfo.h updated: 1.9 -> 1.10 --- Log message: Move isLoadFrom/StoreToStackSlot from MRegisterInfo to TargetInstrInfo,a far more logical place. Other methods should also be moved if anyoneis interested. :) --- Diffs of the changes: (+21 -20) PPCInstrInfo.cpp | 19 +++++++++++++++++++ PPCInstrInfo.h | 2 ++ PPCRegisterInfo.cpp | 18 ------------------ PPCRegisterInfo.h | 2 -- 4 files changed, 21 insertions(+), 20 deletions(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.13 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.14 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.13 Tue Oct 18 20:50:36 2005 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Feb 2 14:12:32 2006 @@ -79,6 +79,25 @@ return false; } +unsigned PPCInstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + case PPC::LD: + case PPC::LWZ: + case PPC::LFS: + case PPC::LFD: + if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && + MI->getOperand(2).isFrameIndex()) { + FrameIndex = MI->getOperand(2).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; + } + + // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. MachineInstr *PPCInstrInfo::commuteInstruction(MachineInstr *MI) const { Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.9 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.10 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.9 Wed Jan 18 13:37:44 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Thu Feb 2 14:12:32 2006 @@ -39,6 +39,8 @@ unsigned& sourceReg, unsigned& destReg) const; + unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. virtual MachineInstr *commuteInstruction(MachineInstr *MI) const; Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.42 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.43 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.42 Wed Jan 11 17:16:29 2006 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Thu Feb 2 14:12:32 2006 @@ -116,24 +116,6 @@ } } -unsigned PPCRegisterInfo::isLoadFromStackSlot(MachineInstr *MI, - int &FrameIndex) const { - switch (MI->getOpcode()) { - default: break; - case PPC::LD: - case PPC::LWZ: - case PPC::LFS: - case PPC::LFD: - if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && - MI->getOperand(2).isFrameIndex()) { - FrameIndex = MI->getOperand(2).getFrameIndex(); - return MI->getOperand(0).getReg(); - } - break; - } - return 0; -} - /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr *PPCRegisterInfo::foldMemoryOperand(MachineInstr *MI, Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.h diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.9 llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.10 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.h:1.9 Sun Oct 16 00:39:50 2005 +++ llvm/lib/Target/PowerPC/PPCRegisterInfo.h Thu Feb 2 14:12:32 2006 @@ -42,8 +42,6 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; - unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; - /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum, From lattner at cs.uiuc.edu Thu Feb 2 14:16:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:16:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp PPCInstrInfo.h Message-ID: <200602022016.OAA07904@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.cpp updated: 1.14 -> 1.15 PPCInstrInfo.h updated: 1.10 -> 1.11 --- Log message: implement isStoreToStackSlot for PPC --- Diffs of the changes: (+19 -1) PPCInstrInfo.cpp | 19 ++++++++++++++++++- PPCInstrInfo.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.14 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.15 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.14 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Feb 2 14:16:12 2006 @@ -95,8 +95,25 @@ break; } return 0; - } +} +unsigned PPCInstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + switch (MI->getOpcode()) { + default: break; + //case PPC::ST: ? + case PPC::STW: + case PPC::STFS: + case PPC::STFD: + if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() && + MI->getOperand(2).isFrameIndex()) { + FrameIndex = MI->getOperand(2).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. Index: llvm/lib/Target/PowerPC/PPCInstrInfo.h diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.10 llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.11 --- llvm/lib/Target/PowerPC/PPCInstrInfo.h:1.10 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.h Thu Feb 2 14:16:12 2006 @@ -40,6 +40,7 @@ unsigned& destReg) const; unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; // commuteInstruction - We can commute rlwimi instructions, but only if the // rotate amt is zero. We also have to munge the immediates a bit. From lattner at cs.uiuc.edu Thu Feb 2 14:38:23 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 14:38:23 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.cpp Message-ID: <200602022038.OAA08128@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.cpp updated: 1.43 -> 1.44 --- Log message: fix operand numbers --- Diffs of the changes: (+4 -4) X86InstrInfo.cpp | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.cpp diff -u llvm/lib/Target/X86/X86InstrInfo.cpp:1.43 llvm/lib/Target/X86/X86InstrInfo.cpp:1.44 --- llvm/lib/Target/X86/X86InstrInfo.cpp:1.43 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/X86/X86InstrInfo.cpp Thu Feb 2 14:38:12 2006 @@ -76,10 +76,10 @@ case X86::MOVSDmr: if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && MI->getOperand(2).isRegister() && MI->getOperand(3).isImmediate() && - MI->getOperand(3).getImmedValue() == 1 && - MI->getOperand(4).getReg() == 0 && - MI->getOperand(5).getImmedValue() == 0) { - FrameIndex = MI->getOperand(1).getFrameIndex(); + MI->getOperand(1).getImmedValue() == 1 && + MI->getOperand(2).getReg() == 0 && + MI->getOperand(3).getImmedValue() == 0) { + FrameIndex = MI->getOperand(0).getFrameIndex(); return MI->getOperand(4).getReg(); } break; From natebegeman at mac.com Thu Feb 2 15:08:02 2006 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 2 Feb 2006 15:08:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Message-ID: <200602022108.PAA08308@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCInstrInfo.cpp updated: 1.15 -> 1.16 --- Log message: add 64b gpr store to the possible list of isStoreToStackSlot opcodes. --- Diffs of the changes: (+1 -1) PPCInstrInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.15 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.16 --- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp:1.15 Thu Feb 2 14:16:12 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp Thu Feb 2 15:07:50 2006 @@ -101,7 +101,7 @@ int &FrameIndex) const { switch (MI->getOpcode()) { default: break; - //case PPC::ST: ? + case PPC::STD: case PPC::STW: case PPC::STFS: case PPC::STFD: From lattner at cs.uiuc.edu Thu Feb 2 17:29:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 17:29:48 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602022329.RAA08841@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.45 -> 1.46 --- Log message: Fix a deficiency in the spiller that Evan noticed. In particular, consider this code: store [stack slot #0], R10 = add R14, [stack slot #0] The spiller didn't know that the store made the value of [stackslot#0] available in R10 *IF* the store came from a copy instruction with the store folded into it. This patch teaches VirtRegMap to look at these stores and recognize the values they make available. In one case Evan provided, this code: divsd %XMM0, %XMM1 movsd %XMM1, QWORD PTR [%ESP + 40] 1) movsd QWORD PTR [%ESP + 48], %XMM1 2) movsd %XMM1, QWORD PTR [%ESP + 48] addsd %XMM1, %XMM0 3) movsd QWORD PTR [%ESP + 48], %XMM1 movsd QWORD PTR [%ESP + 4], %XMM0 turns into: divsd %XMM0, %XMM1 movsd %XMM1, QWORD PTR [%ESP + 40] addsd %XMM1, %XMM0 3) movsd QWORD PTR [%ESP + 48], %XMM1 movsd QWORD PTR [%ESP + 4], %XMM0 In this case, instruction #2 was removed because of the value made available by #1, and inst #1 was later deleted because it is now never used before the stack slot is redefined by #3. This occurs here and there in a lot of code with high spilling, on PPC most of the removed loads/stores are LSU-reject-causing loads, which is nice. On X86, things are much better (because it spills more), where we nuke about 1% of the instructions from SMG2000 and several hundred from eon. More improvements to come... --- Diffs of the changes: (+31 -1) VirtRegMap.cpp | 32 +++++++++++++++++++++++++++++++- 1 files changed, 31 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.45 llvm/lib/CodeGen/VirtRegMap.cpp:1.46 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.45 Thu Feb 2 14:12:13 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 17:29:36 2006 @@ -284,7 +284,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) { // SpillSlotsAvailable - This map keeps track of all of the spilled virtual - // register values that are still available, due to being loaded to stored to, + // register values that are still available, due to being loaded or stored to, // but not invalidated yet. std::map SpillSlotsAvailable; @@ -535,6 +535,36 @@ PhysRegsAvailable.erase(It->second); SpillSlotsAvailable.erase(It); } + + // If this is *just* a mod of the value, check to see if this is just a + // store to the spill slot (i.e. the spill got merged into the copy). If + // so, realize that the vreg is available now, and add the store to the + // MaybeDeadStore info. + int StackSlot; + if (!(MR & VirtRegMap::isRef)) { + if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) { + assert(MRegisterInfo::isPhysicalRegister(SrcReg) && + "Src hasn't been allocated yet?"); + // Okay, this is certainly a store of SrcReg to [FrameIdx]. Mark + // this as a potentially dead store in case there is a subsequent + // store into the stack slot without a read from it. + MaybeDeadStores[StackSlot] = &MI; + + // FIXME: PhysRegsAvailable is a 1-1 map, not a N-1 map, which means + // that we have to *forget* that SrcReg contains the old value it + // does. + ClobberPhysRegOnly(SrcReg, SpillSlotsAvailable, PhysRegsAvailable); + + // If the stack slot value was previously available in some other + // register, change it now. Otherwise, make the register available, + // in PhysReg. + SpillSlotsAvailable[StackSlot] = SrcReg; + PhysRegsAvailable[SrcReg] = StackSlot; + DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg " + << MRI->getName(SrcReg) << " for virtreg #" + << VirtReg << "\n" << MI); + } + } } } From lattner at cs.uiuc.edu Thu Feb 2 17:50:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 17:50:34 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602022350.RAA08918@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.55 -> 1.56 --- Log message: update a note --- Diffs of the changes: (+3 -0) README.txt | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.55 llvm/lib/Target/PowerPC/README.txt:1.56 --- llvm/lib/Target/PowerPC/README.txt:1.55 Thu Feb 2 01:37:11 2006 +++ llvm/lib/Target/PowerPC/README.txt Thu Feb 2 17:50:22 2006 @@ -86,6 +86,9 @@ off of the register to avoid the lis's. This is even more important in PIC mode. +Note that this (and the static variable version) is discussed here for GCC: +http://gcc.gnu.org/ml/gcc-patches/2006-02/msg00133.html + ===-------------------------------------------------------------------------=== Implement Newton-Rhapson method for improving estimate instructions to the From lattner at cs.uiuc.edu Thu Feb 2 18:36:42 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 18:36:42 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602030036.SAA09087@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.46 -> 1.47 --- Log message: Physregs may hold multiple stack slot values at the same time. Keep track of this, and use it to our advantage (bwahahah). This allows us to eliminate another 60 instructions from smg2000 on PPC (probably significantly more on X86). A common old-new diff looks like this: stw r2, 3304(r1) - lwz r2, 3192(r1) stw r2, 3300(r1) - lwz r2, 3192(r1) stw r2, 3296(r1) - lwz r2, 3192(r1) stw r2, 3200(r1) - lwz r2, 3192(r1) stw r2, 3196(r1) - lwz r2, 3192(r1) + or r2, r2, r2 stw r2, 3188(r1) and - lwz r31, 604(r1) - lwz r13, 604(r1) - lwz r14, 604(r1) - lwz r15, 604(r1) - lwz r16, 604(r1) - lwz r30, 604(r1) + or r31, r30, r30 + or r13, r30, r30 + or r14, r30, r30 + or r15, r30, r30 + or r16, r30, r30 + or r30, r30, r30 Removal of the R = R copies is coming next... --- Diffs of the changes: (+49 -37) VirtRegMap.cpp | 86 ++++++++++++++++++++++++++++++++------------------------- 1 files changed, 49 insertions(+), 37 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.46 llvm/lib/CodeGen/VirtRegMap.cpp:1.47 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.46 Thu Feb 2 17:29:36 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 18:36:31 2006 @@ -222,36 +222,60 @@ private: void RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM); void ClobberPhysReg(unsigned PR, std::map &SpillSlots, - std::map &PhysRegs); + std::multimap &PhysRegs); void ClobberPhysRegOnly(unsigned PR, std::map &SpillSlots, - std::map &PhysRegs); + std::multimap &PhysRegs); + void ModifyStackSlot(int Slot, std::map &SpillSlots, + std::multimap &PhysRegs); }; } void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, std::map &SpillSlots, - std::map &PhysRegs) { - std::map::iterator I = PhysRegs.find(PhysReg); - if (I != PhysRegs.end()) { + std::multimap &PhysRegsAvailable) { + std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg); + while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; - PhysRegs.erase(I); + PhysRegsAvailable.erase(I++); assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!"); SpillSlots.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) - << " clobbered, invalidating SS#" << Slot << "\n"); + << " clobbered, invalidating SS#" << Slot << "\n"); } } void LocalSpiller::ClobberPhysReg(unsigned PhysReg, std::map &SpillSlots, - std::map &PhysRegs) { + std::multimap &PhysRegsAvailable) { for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS) - ClobberPhysRegOnly(*AS, SpillSlots, PhysRegs); - ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegs); + ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable); + ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable); +} + +/// ModifyStackSlot - This method is called when the value in a stack slot +/// changes. This removes information about which register the previous value +/// for this slot lives in (as the previous value is dead now). +void LocalSpiller::ModifyStackSlot(int Slot, std::map &SpillSlots, + std::multimap &PhysRegsAvailable) { + std::map::iterator It = SpillSlots.find(Slot); + if (It == SpillSlots.end()) return; + unsigned Reg = It->second; + SpillSlots.erase(It); + + // This register may hold the value of multiple stack slots, only remove this + // stack slot from the set of values the register contains. + std::multimap::iterator I = PhysRegsAvailable.lower_bound(Reg); + for (; ; ++I) { + assert(I != PhysRegsAvailable.end() && I->first == Reg && + "Map inverse broken!"); + if (I->second == Slot) break; + } + PhysRegsAvailable.erase(I); } + // ReusedOp - For each reused operand, we keep track of a bit of information, in // case we need to rollback upon processing a new operand. See comments below. namespace { @@ -289,8 +313,9 @@ std::map SpillSlotsAvailable; // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating - // which physregs are in use holding a stack slot value. - std::map PhysRegsAvailable; + // which stack slot values are currently held by a physreg. This is used to + // invalidate entries in SpillSlotsAvailable when a physreg is modified. + std::multimap PhysRegsAvailable; DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n"); @@ -427,12 +452,13 @@ MaybeDeadStores.erase(Op.StackSlot); MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); - PhysRegsAvailable[Op.AssignedPhysReg] = Op.StackSlot; + PhysRegsAvailable.insert(std::make_pair(Op.AssignedPhysReg, + Op.StackSlot)); SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg; PhysRegsAvailable.erase(Op.PhysRegReused); DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot - << " in physreg " - << MRI->getName(Op.AssignedPhysReg) << "\n"); + << " in physreg " + << MRI->getName(Op.AssignedPhysReg) << "\n"); ++NumLoads; DEBUG(std::cerr << '\t' << *prior(MII)); @@ -452,7 +478,7 @@ MaybeDeadStores.erase(StackSlot); MI.SetMachineOperandReg(i, PhysReg); - PhysRegsAvailable[PhysReg] = StackSlot; + PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); SpillSlotsAvailable[StackSlot] = PhysReg; DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg " << MRI->getName(PhysReg) << "\n"); @@ -530,11 +556,8 @@ // If the spill slot value is available, and this is a new definition of // the value, the value is not available anymore. if (MR & VirtRegMap::isMod) { - std::map::iterator It = SpillSlotsAvailable.find(SS); - if (It != SpillSlotsAvailable.end()) { - PhysRegsAvailable.erase(It->second); - SpillSlotsAvailable.erase(It); - } + // Notice that the value in this stack slot has been modified. + ModifyStackSlot(SS, SpillSlotsAvailable, PhysRegsAvailable); // If this is *just* a mod of the value, check to see if this is just a // store to the spill slot (i.e. the spill got merged into the copy). If @@ -545,21 +568,16 @@ if (unsigned SrcReg = TII->isStoreToStackSlot(&MI, StackSlot)) { assert(MRegisterInfo::isPhysicalRegister(SrcReg) && "Src hasn't been allocated yet?"); - // Okay, this is certainly a store of SrcReg to [FrameIdx]. Mark + // Okay, this is certainly a store of SrcReg to [StackSlot]. Mark // this as a potentially dead store in case there is a subsequent // store into the stack slot without a read from it. MaybeDeadStores[StackSlot] = &MI; - // FIXME: PhysRegsAvailable is a 1-1 map, not a N-1 map, which means - // that we have to *forget* that SrcReg contains the old value it - // does. - ClobberPhysRegOnly(SrcReg, SpillSlotsAvailable, PhysRegsAvailable); - // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. SpillSlotsAvailable[StackSlot] = SrcReg; - PhysRegsAvailable[SrcReg] = StackSlot; + PhysRegsAvailable.insert(std::make_pair(SrcReg, StackSlot)); DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg " << MRI->getName(SrcReg) << " for virtreg #" << VirtReg << "\n" << MI); @@ -596,7 +614,7 @@ if (!TakenCareOf) { // The only vregs left are stack slot definitions. - int StackSlot = VRM.getStackSlot(VirtReg); + int StackSlot = VRM.getStackSlot(VirtReg); const TargetRegisterClass *RC = MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); unsigned PhysReg; @@ -626,16 +644,10 @@ // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. - std::map::iterator SSA = - SpillSlotsAvailable.find(StackSlot); - if (SSA != SpillSlotsAvailable.end()) { - // Remove the record for physreg. - PhysRegsAvailable.erase(SSA->second); - SpillSlotsAvailable.erase(SSA); - } + ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); - PhysRegsAvailable[PhysReg] = StackSlot; + PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); SpillSlotsAvailable[StackSlot] = PhysReg; DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " << MRI->getName(PhysReg) << " for virtreg #" From evan.cheng at apple.com Thu Feb 2 19:33:13 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 2 Feb 2006 19:33:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200602030133.TAA09290@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.251 -> 1.252 --- Log message: Added case HANDLENODE to getOperationName(). --- Diffs of the changes: (+1 -0) SelectionDAG.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.251 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.252 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.251 Tue Jan 31 16:23:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Feb 2 19:33:01 2006 @@ -2266,6 +2266,7 @@ case ISD::UNDEF: return "undef"; case ISD::MERGE_VALUES: return "mergevalues"; case ISD::INLINEASM: return "inlineasm"; + case ISD::HANDLENODE: return "handlenode"; // Unary operators case ISD::FABS: return "fabs"; From lattner at cs.uiuc.edu Thu Feb 2 19:50:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 19:50:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602030150.TAA09369@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.56 -> 1.57 --- Log message: Add a note --- Diffs of the changes: (+5 -0) README.txt | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.56 llvm/lib/Target/PowerPC/README.txt:1.57 --- llvm/lib/Target/PowerPC/README.txt:1.56 Thu Feb 2 17:50:22 2006 +++ llvm/lib/Target/PowerPC/README.txt Thu Feb 2 19:49:49 2006 @@ -470,3 +470,8 @@ slwi r3, r2, 4 blr +===-------------------------------------------------------------------------=== + +Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and +precision don't matter (ffastmath). Misc/mandel will like this. :) + From lattner at cs.uiuc.edu Thu Feb 2 20:03:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 20:03:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602030203.UAA09442@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.47 -> 1.48 --- Log message: Add code that checks for noop copies, which triggers when either: 1. a target doesn't know how to fold load/stores into copies, or 2. the spiller rewrites the input to a copy to the same register as the dest instead of to the reloaded reg. This will be moved/improved in the near future, but allows elimination of some ancient x86 hacks. This eliminates 92 copies from SMG2000 on X86 and 163 copies from 252.eon. --- Diffs of the changes: (+13 -0) VirtRegMap.cpp | 13 +++++++++++++ 1 files changed, 13 insertions(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.47 llvm/lib/CodeGen/VirtRegMap.cpp:1.48 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.47 Thu Feb 2 18:36:31 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 20:02:59 2006 @@ -38,6 +38,7 @@ Statistic<> NumLoads ("spiller", "Number of loads added"); Statistic<> NumReused("spiller", "Number of values reused"); Statistic<> NumDSE ("spiller", "Number of dead stores elided"); + Statistic<> NumDCE ("spiller", "Number of copies elided"); enum SpillerName { simple, local }; @@ -658,6 +659,18 @@ } } } + + // Okay, the instruction has been completely processed, input and output + // registers have been added. As a final sanity check, make sure this is + // not a noop-copy. If it is, nuke it. + { + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { + ++NumDCE; + DEBUG(std::cerr << "Removing now-noop copy: " << MI); + MBB.erase(&MI); + } + } ProcessNextInst: MII = NextMII; } From lattner at cs.uiuc.edu Thu Feb 2 21:00:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 21:00:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86PeepholeOpt.cpp Message-ID: <200602030300.VAA09965@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86PeepholeOpt.cpp updated: 1.41 -> 1.42 --- Log message: the X86 backend no longer needs to delete its own noop copies --- Diffs of the changes: (+2 -10) X86PeepholeOpt.cpp | 12 ++---------- 1 files changed, 2 insertions(+), 10 deletions(-) Index: llvm/lib/Target/X86/X86PeepholeOpt.cpp diff -u llvm/lib/Target/X86/X86PeepholeOpt.cpp:1.41 llvm/lib/Target/X86/X86PeepholeOpt.cpp:1.42 --- llvm/lib/Target/X86/X86PeepholeOpt.cpp:1.41 Mon Dec 12 14:12:20 2005 +++ llvm/lib/Target/X86/X86PeepholeOpt.cpp Thu Feb 2 20:59:58 2006 @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file contains a peephole optimizer for the X86. +// This file contains an immediate shrinker for the X86. FIXME: Remove when +// the dag isel makes this obsolete! // //===----------------------------------------------------------------------===// @@ -61,15 +62,6 @@ MachineInstr *Next = (NextI != MBB.end()) ? &*NextI : (MachineInstr*)0; unsigned Size = 0; switch (MI->getOpcode()) { - case X86::MOV8rr: - case X86::MOV16rr: - case X86::MOV32rr: // Destroy X = X copies... - if (MI->getOperand(0).getReg() == MI->getOperand(1).getReg()) { - I = MBB.erase(I); - return true; - } - return false; - // A large number of X86 instructions have forms which take an 8-bit // immediate despite the fact that the operands are 16 or 32 bits. Because // this can save three bytes of code size (and icache space), we want to From lattner at cs.uiuc.edu Thu Feb 2 21:07:01 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 21:07:01 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602030307.VAA10096@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.48 -> 1.49 --- Log message: Simplify some code --- Diffs of the changes: (+40 -45) VirtRegMap.cpp | 85 ++++++++++++++++++++++++++------------------------------- 1 files changed, 40 insertions(+), 45 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.48 llvm/lib/CodeGen/VirtRegMap.cpp:1.49 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.48 Thu Feb 2 20:02:59 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:06:49 2006 @@ -593,7 +593,6 @@ if (MO.isRegister() && MO.getReg() && MO.isDef()) { unsigned VirtReg = MO.getReg(); - bool TakenCareOf = false; if (!MRegisterInfo::isVirtualRegister(VirtReg)) { // Check to see if this is a def-and-use vreg operand that we do need // to insert a store for. @@ -609,54 +608,50 @@ if (!OpTakenCareOf) { ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable); - TakenCareOf = true; + continue; } } - if (!TakenCareOf) { - // The only vregs left are stack slot definitions. - int StackSlot = VRM.getStackSlot(VirtReg); - const TargetRegisterClass *RC = - MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); - unsigned PhysReg; - - // If this is a def&use operand, and we used a different physreg for - // it than the one assigned, make sure to execute the store from the - // correct physical register. - if (MO.getReg() == VirtReg) - PhysReg = VRM.getPhys(VirtReg); - else - PhysReg = MO.getReg(); - - PhysRegsUsed[PhysReg] = true; - MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); - DEBUG(std::cerr << "Store:\t" << *next(MII)); - MI.SetMachineOperandReg(i, PhysReg); - - // If there is a dead store to this stack slot, nuke it now. - MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; - if (LastStore) { - DEBUG(std::cerr << " Killed store:\t" << *LastStore); - ++NumDSE; - MBB.erase(LastStore); - } - LastStore = next(MII); - - // If the stack slot value was previously available in some other - // register, change it now. Otherwise, make the register available, - // in PhysReg. - ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); - ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); - - PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); - SpillSlotsAvailable[StackSlot] = PhysReg; - DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " - << MRI->getName(PhysReg) << " for virtreg #" - << VirtReg << "\n"); - - ++NumStores; - VirtReg = PhysReg; + // The only vregs left are stack slot definitions. + int StackSlot = VRM.getStackSlot(VirtReg); + const TargetRegisterClass *RC = + MBB.getParent()->getSSARegMap()->getRegClass(VirtReg); + unsigned PhysReg; + + // If this is a def&use operand, and we used a different physreg for + // it than the one assigned, make sure to execute the store from the + // correct physical register. + if (MO.getReg() == VirtReg) + PhysReg = VRM.getPhys(VirtReg); + else + PhysReg = MO.getReg(); + + PhysRegsUsed[PhysReg] = true; + MRI->storeRegToStackSlot(MBB, next(MII), PhysReg, StackSlot, RC); + DEBUG(std::cerr << "Store:\t" << *next(MII)); + MI.SetMachineOperandReg(i, PhysReg); + + // If there is a dead store to this stack slot, nuke it now. + MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; + if (LastStore) { + DEBUG(std::cerr << " Killed store:\t" << *LastStore); + ++NumDSE; + MBB.erase(LastStore); } + LastStore = next(MII); + + // If the stack slot value was previously available in some other + // register, change it now. Otherwise, make the register available, + // in PhysReg. + ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); + ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + + PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); + SpillSlotsAvailable[StackSlot] = PhysReg; + DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " + << MRI->getName(PhysReg) << " for virtreg #" + << VirtReg << "\n"); + ++NumStores; } } From alenhar2 at cs.uiuc.edu Thu Feb 2 21:07:49 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Thu, 2 Feb 2006 21:07:49 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp AlphaInstrInfo.h AlphaInstrInfo.td Message-ID: <200602030307.VAA10131@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaInstrInfo.cpp updated: 1.7 -> 1.8 AlphaInstrInfo.h updated: 1.4 -> 1.5 AlphaInstrInfo.td updated: 1.112 -> 1.113 --- Log message: isStoreToStackSlot --- Diffs of the changes: (+20 -3) AlphaInstrInfo.cpp | 18 ++++++++++++++++++ AlphaInstrInfo.h | 1 + AlphaInstrInfo.td | 4 +--- 3 files changed, 20 insertions(+), 3 deletions(-) Index: llvm/lib/Target/Alpha/AlphaInstrInfo.cpp diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.7 llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.8 --- llvm/lib/Target/Alpha/AlphaInstrInfo.cpp:1.7 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.cpp Thu Feb 2 21:07:37 2006 @@ -61,3 +61,21 @@ return 0; } +unsigned +AlphaInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const { + switch (MI->getOpcode()) { + case Alpha::STL: + case Alpha::STQ: + case Alpha::STB: + case Alpha::STW: + case Alpha::STS: + case Alpha::STT: + if (MI->getOperand(1).isFrameIndex()) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + break; + } + return 0; +} + Index: llvm/lib/Target/Alpha/AlphaInstrInfo.h diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.4 llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.5 --- llvm/lib/Target/Alpha/AlphaInstrInfo.h:1.4 Thu Feb 2 14:12:32 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.h Thu Feb 2 21:07:37 2006 @@ -37,6 +37,7 @@ unsigned &SrcReg, unsigned &DstReg) const; virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; }; } Index: llvm/lib/Target/Alpha/AlphaInstrInfo.td diff -u llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.112 llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.113 --- llvm/lib/Target/Alpha/AlphaInstrInfo.td:1.112 Wed Feb 1 13:37:33 2006 +++ llvm/lib/Target/Alpha/AlphaInstrInfo.td Thu Feb 2 21:07:37 2006 @@ -177,9 +177,7 @@ [(set GPRC:$RDEST, (select (xor GPRC:$RCOND, 1), GPRC:$RFALSE, immUExt8:$RTRUE))]>; -//FIXME: fold setcc with select for all cases. clearly I need patterns for inverted conditions -// and constants (which require inverted conditions as legalize puts the constant in the -// wrong field for the instruction definition +//General pattern for cmov def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2), (CMOVNE GPRC:$src2, GPRC:$src1, GPRC:$which)>; def : Pat<(select GPRC:$which, GPRC:$src1, immUExt8:$src2), From lattner at cs.uiuc.edu Thu Feb 2 21:16:26 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu, 2 Feb 2006 21:16:26 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602030316.VAA10212@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.49 -> 1.50 --- Log message: Remove move copies and dead stuff by not clobbering the result reg of a noop copy. --- Diffs of the changes: (+21 -12) VirtRegMap.cpp | 33 +++++++++++++++++++++------------ 1 files changed, 21 insertions(+), 12 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.49 llvm/lib/CodeGen/VirtRegMap.cpp:1.50 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.49 Thu Feb 2 21:06:49 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:16:14 2006 @@ -607,6 +607,15 @@ } if (!OpTakenCareOf) { + // Check to see if this is a noop copy. If so, eliminate the + // instruction before considering the dest reg to be changed. + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { + ++NumDCE; + DEBUG(std::cerr << "Removing now-noop copy: " << MI); + MBB.erase(&MI); + goto ProcessNextInst; + } ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable); continue; } @@ -631,6 +640,18 @@ DEBUG(std::cerr << "Store:\t" << *next(MII)); MI.SetMachineOperandReg(i, PhysReg); + // Check to see if this is a noop copy. If so, eliminate the + // instruction before considering the dest reg to be changed. + { + unsigned Src, Dst; + if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { + ++NumDCE; + DEBUG(std::cerr << "Removing now-noop copy: " << MI); + MBB.erase(&MI); + goto ProcessNextInst; + } + } + // If there is a dead store to this stack slot, nuke it now. MachineInstr *&LastStore = MaybeDeadStores[StackSlot]; if (LastStore) { @@ -654,18 +675,6 @@ ++NumStores; } } - - // Okay, the instruction has been completely processed, input and output - // registers have been added. As a final sanity check, make sure this is - // not a noop-copy. If it is, nuke it. - { - unsigned Src, Dst; - if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) { - ++NumDCE; - DEBUG(std::cerr << "Removing now-noop copy: " << MI); - MBB.erase(&MI); - } - } ProcessNextInst: MII = NextMII; } From jeffc at jolt-lang.org Thu Feb 2 21:49:06 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Thu, 2 Feb 2006 21:49:06 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602030349.VAA10298@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.50 -> 1.51 --- Log message: Fix VC++ compilation error caused by using a std::map iterator variable to receive a std::multimap iterator value. For some reason, GCC doesn't have a problem with this. --- Diffs of the changes: (+1 -1) VirtRegMap.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.50 llvm/lib/CodeGen/VirtRegMap.cpp:1.51 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.50 Thu Feb 2 21:16:14 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Thu Feb 2 21:48:54 2006 @@ -234,7 +234,7 @@ void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, std::map &SpillSlots, std::multimap &PhysRegsAvailable) { - std::map::iterator I = PhysRegsAvailable.lower_bound(PhysReg); + std::multimap::iterator I = PhysRegsAvailable.lower_bound(PhysReg); while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); From natebegeman at mac.com Thu Feb 2 23:17:17 2006 From: natebegeman at mac.com (Nate Begeman) Date: Thu, 2 Feb 2006 23:17:17 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602030517.XAA10682@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.57 -> 1.58 --- Log message: Flesh out a couple of the items in the README --- Diffs of the changes: (+41 -14) README.txt | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 41 insertions(+), 14 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.57 llvm/lib/Target/PowerPC/README.txt:1.58 --- llvm/lib/Target/PowerPC/README.txt:1.57 Thu Feb 2 19:49:49 2006 +++ llvm/lib/Target/PowerPC/README.txt Thu Feb 2 23:17:06 2006 @@ -2,20 +2,17 @@ * gpr0 allocation * implement do-loop -> bdnz transform * implement powerpc-64 for darwin -* use stfiwx in float->int -* Fold add and sub with constant into non-extern, non-weak addresses so this: - lis r2, ha16(l2__ZTV4Cell) - la r2, lo16(l2__ZTV4Cell)(r2) - addi r2, r2, 8 -becomes: - lis r2, ha16(l2__ZTV4Cell+8) - la r2, lo16(l2__ZTV4Cell+8)(r2) +===-------------------------------------------------------------------------=== + +Use the stfiwx instruction for: +void foo(float a, int *b) { *b = a; } + +===-------------------------------------------------------------------------=== -* Teach LLVM how to codegen this: unsigned short foo(float a) { return a; } -as: +should be: _foo: fctiwz f0,f1 stfd f0,-8(r1) @@ -29,11 +26,15 @@ rlwinm r3, r2, 0, 16, 31 blr -* Support 'update' load/store instructions. These are cracked on the G5, but - are still a codesize win. +===-------------------------------------------------------------------------=== + +Support 'update' load/store instructions. These are cracked on the G5, but are +still a codesize win. + +===-------------------------------------------------------------------------=== -* should hint to the branch select pass that it doesn't need to print the - second unconditional branch, so we don't end up with things like: +Should hint to the branch select pass that it doesn't need to print the second +unconditional branch, so we don't end up with things like: b .LBBl42__2E_expand_function_8_674 ; loopentry.24 b .LBBl42__2E_expand_function_8_42 ; NewDefault b .LBBl42__2E_expand_function_8_42 ; NewDefault @@ -475,3 +476,29 @@ Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and precision don't matter (ffastmath). Misc/mandel will like this. :) +===-------------------------------------------------------------------------=== + +Fold add and sub with constant into non-extern, non-weak addresses so this: + +static int a; +void bar(int b) { a = b; } +void foo(unsigned char *c) { + *c = a; +} + +So that + +_foo: + lis r2, ha16(_a) + la r2, lo16(_a)(r2) + lbz r2, 3(r2) + stb r2, 0(r3) + blr + +Becomes + +_foo: + lis r2, ha16(_a+3) + lbz r2, lo16(_a+3)(r2) + stb r2, 0(r3) + blr From lattner at cs.uiuc.edu Fri Feb 3 00:21:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 00:21:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200602030621.AAA10976@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt added (r1.1) --- Log message: target independent notes --- Diffs of the changes: (+67 -0) README.txt | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 67 insertions(+) Index: llvm/lib/Target/README.txt diff -c /dev/null llvm/lib/Target/README.txt:1.1 *** /dev/null Fri Feb 3 00:21:53 2006 --- llvm/lib/Target/README.txt Fri Feb 3 00:21:43 2006 *************** *** 0 **** --- 1,67 ---- + Target Independent Opportunities: + + ===-------------------------------------------------------------------------=== + + FreeBench/mason contains code like this: + + static p_type m0u(p_type p) { + int m[]={0, 8, 1, 2, 16, 5, 13, 7, 14, 9, 3, 4, 11, 12, 15, 10, 17, 6}; + p_type pu; + pu.a = m[p.a]; + pu.b = m[p.b]; + pu.c = m[p.c]; + return pu; + } + + We currently compile this into a memcpy from a static array into 'm', then + a bunch of loads from m. It would be better to avoid the memcpy and just do + loads from the static array. + + ===-------------------------------------------------------------------------=== + + Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and + precision don't matter (ffastmath). Misc/mandel will like this. :) + + ===-------------------------------------------------------------------------=== + + For all targets, not just X86: + When llvm.memcpy, llvm.memset, or llvm.memmove are lowered, they should be + optimized to a few store instructions if the source is constant and the length + is smallish (< 8). This will greatly help some tests like Shootout/strcat.c + and fldry. + + //===---------------------------------------------------------------------===// + + Solve this DAG isel folding deficiency: + + int X, Y; + + void fn1(void) + { + X = X | (Y << 3); + } + + compiles to + + fn1: + movl Y, %eax + shll $3, %eax + orl X, %eax + movl %eax, X + ret + + The problem is the store's chain operand is not the load X but rather + a TokenFactor of the load X and load Y, which prevents the folding. + + There are two ways to fix this: + + 1. The dag combiner can start using alias analysis to realize that y/x + don't alias, making the store to X not dependent on the load from Y. + 2. The generated isel could be made smarter in the case it can't + disambiguate the pointers. + + Number 1 is the preferred solution. + + //===---------------------------------------------------------------------===// + + From lattner at cs.uiuc.edu Fri Feb 3 00:22:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 00:22:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/README.txt Message-ID: <200602030622.AAA11018@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: README.txt updated: 1.45 -> 1.46 --- Log message: remove some target-indep and implemented notes --- Diffs of the changes: (+0 -44) README.txt | 44 -------------------------------------------- 1 files changed, 44 deletions(-) Index: llvm/lib/Target/X86/README.txt diff -u llvm/lib/Target/X86/README.txt:1.45 llvm/lib/Target/X86/README.txt:1.46 --- llvm/lib/Target/X86/README.txt:1.45 Thu Feb 2 13:43:28 2006 +++ llvm/lib/Target/X86/README.txt Fri Feb 3 00:22:11 2006 @@ -76,11 +76,6 @@ //===---------------------------------------------------------------------===// -Should support emission of the bswap instruction, probably by adding a new -DAG node for byte swapping. Also useful on PPC which has byte-swapping loads. - -//===---------------------------------------------------------------------===// - Compile this: _Bool f(_Bool a) { return a!=1; } @@ -168,45 +163,6 @@ //===---------------------------------------------------------------------===// -For all targets, not just X86: -When llvm.memcpy, llvm.memset, or llvm.memmove are lowered, they should be -optimized to a few store instructions if the source is constant and the length -is smallish (< 8). This will greatly help some tests like Shootout/strcat.c - -//===---------------------------------------------------------------------===// - -Solve this DAG isel folding deficiency: - -int X, Y; - -void fn1(void) -{ - X = X | (Y << 3); -} - -compiles to - -fn1: - movl Y, %eax - shll $3, %eax - orl X, %eax - movl %eax, X - ret - -The problem is the store's chain operand is not the load X but rather -a TokenFactor of the load X and load Y, which prevents the folding. - -There are two ways to fix this: - -1. The dag combiner can start using alias analysis to realize that y/x - don't alias, making the store to X not dependent on the load from Y. -2. The generated isel could be made smarter in the case it can't - disambiguate the pointers. - -Number 1 is the preferred solution. - -//===---------------------------------------------------------------------===// - The instruction selector sometimes misses folding a load into a compare. The pattern is written as (cmp reg, (load p)). Because the compare isn't commutative, it is not matched with the load on both sides. The dag combiner From lattner at cs.uiuc.edu Fri Feb 3 00:22:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 00:22:24 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602030622.AAA11014@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.58 -> 1.59 --- Log message: remove some target-indep and implemented notes --- Diffs of the changes: (+11 -13) README.txt | 24 +++++++++++------------- 1 files changed, 11 insertions(+), 13 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.58 llvm/lib/Target/PowerPC/README.txt:1.59 --- llvm/lib/Target/PowerPC/README.txt:1.58 Thu Feb 2 23:17:06 2006 +++ llvm/lib/Target/PowerPC/README.txt Fri Feb 3 00:22:11 2006 @@ -92,6 +92,17 @@ ===-------------------------------------------------------------------------=== +PIC Code Gen IPO optimization: + +Squish small scalar globals together into a single global struct, allowing the +address of the struct to be CSE'd, avoiding PIC accesses (also reduces the size +of the GOT on targets with one). + +Note that this is discussed here for GCC: +http://gcc.gnu.org/ml/gcc-patches/2006-02/msg00133.html + +===-------------------------------------------------------------------------=== + Implement Newton-Rhapson method for improving estimate instructions to the correct accuracy, and implementing divide as multiply by reciprocal when it has more than one use. Itanium will want this too. @@ -351,14 +362,6 @@ ===-------------------------------------------------------------------------=== -Code Gen IPO optimization: - -Squish small scalar globals together into a single global struct, allowing the -address of the struct to be CSE'd, avoiding PIC accesses (also reduces the size -of the GOT on targets with one). - -===-------------------------------------------------------------------------=== - Generate lwbrx and other byteswapping load/store instructions when reasonable. ===-------------------------------------------------------------------------=== @@ -473,11 +476,6 @@ ===-------------------------------------------------------------------------=== -Get the C front-end to expand hypot(x,y) -> llvm.sqrt(x*x+y*y) when errno and -precision don't matter (ffastmath). Misc/mandel will like this. :) - -===-------------------------------------------------------------------------=== - Fold add and sub with constant into non-extern, non-weak addresses so this: static int a; From evan.cheng at apple.com Fri Feb 3 00:22:53 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Feb 2006 00:22:53 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602030622.AAA11028@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.159 -> 1.160 --- Log message: (store (op (load ...))) folding problem. In the generated matching code, Chain is initially set to the chain operand of store node, when it reaches load, if it matches the load then Chain is set to the chain operand of the load. However, if the matching code that follows this fails, isel moves on to the next pattern but it does not restore Chain to the chain operand of the store. So when it tries to match the next store / op / load pattern it would fail on the Chain == load.getOperand(0) test. The solution is for each chain operand to get a unique name. e.g. Chain10. --- Diffs of the changes: (+30 -23) DAGISelEmitter.cpp | 53 ++++++++++++++++++++++++++++++----------------------- 1 files changed, 30 insertions(+), 23 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.159 llvm/utils/TableGen/DAGISelEmitter.cpp:1.160 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.159 Wed Feb 1 00:06:31 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Feb 3 00:22:41 2006 @@ -1848,6 +1848,7 @@ /// [when false]. std::vector > &GeneratedCode; + std::string ChainName; unsigned TmpNo; void emitCheck(const std::string &S) { @@ -1869,7 +1870,8 @@ /// if the match fails. At this point, we already know that the opcode for N /// matches, and the SDNode for the result has the RootName specified name. void EmitMatchCode(TreePatternNode *N, const std::string &RootName, - bool &FoundChain, bool isRoot = false) { + const std::string &ChainSuffix, bool &FoundChain, + bool isRoot = false) { // Emit instruction predicates. Each predicate is just a string for now. if (isRoot) { @@ -1947,13 +1949,13 @@ utostr(CInfo.getNumResults()) + "))"); } if (NodeHasChain) { - if (!FoundChain) { - emitCode("SDOperand Chain = " + RootName + ".getOperand(0);"); - FoundChain = true; - } else { + if (FoundChain) emitCheck("Chain.Val == " + RootName + ".Val"); - emitCode("Chain = " + RootName + ".getOperand(0);"); - } + else + FoundChain = true; + ChainName = "Chain" + ChainSuffix; + emitCode("SDOperand " + ChainName + " = " + RootName + + ".getOperand(0);"); } } @@ -1988,7 +1990,8 @@ const SDNodeInfo &CInfo = ISE.getSDNodeInfo(Child->getOperator()); emitCheck(RootName + utostr(OpNo) + ".getOpcode() == " + CInfo.getEnumName()); - EmitMatchCode(Child, RootName + utostr(OpNo), FoundChain); + EmitMatchCode(Child, RootName + utostr(OpNo), ChainSuffix + utostr(OpNo), + FoundChain); if (NodeHasProperty(Child, SDNodeInfo::SDNPHasChain, ISE)) FoldedChains.push_back(std::make_pair(RootName + utostr(OpNo), CInfo.getNumResults())); @@ -2225,7 +2228,7 @@ // Emit all the chain and CopyToReg stuff. bool ChainEmitted = HasChain; if (HasChain) - emitCode("Chain = Select(Chain);"); + emitCode(ChainName + " = Select(" + ChainName + ");"); if (HasInFlag || HasOptInFlag || HasImpInputs) EmitInFlagSelectCode(Pattern, "N", ChainEmitted, true); @@ -2248,7 +2251,7 @@ emitCode(Code + ");"); if (HasChain) { // Must have at least one result - emitCode("Chain = Tmp" + utostr(LastOp) + ".getValue(" + + emitCode(ChainName + " = Tmp" + utostr(LastOp) + ".getValue(" + utostr(NumResults) + ");"); } } else if (HasChain || NodeHasOutFlag) { @@ -2273,7 +2276,7 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", Chain"; + if (HasChain) Code += ", " + ChainName; emitCode(Code + ", InFlag);"); emitCode("else"); @@ -2292,7 +2295,7 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", Chain);"; + if (HasChain) Code += ", " + ChainName + ");"; emitCode(Code); } else { std::string Code = "SDOperand Result = CurDAG->getTargetNode(" + @@ -2310,7 +2313,7 @@ // Inputs. for (unsigned i = 0, e = Ops.size(); i != e; ++i) Code += ", Tmp" + utostr(Ops[i]); - if (HasChain) Code += ", Chain"; + if (HasChain) Code += ", " + ChainName; if (HasInFlag || HasImpInputs) Code += ", InFlag"; emitCode(Code + ");"); } @@ -2323,7 +2326,7 @@ } if (HasChain) - emitCode("Chain = Result.getValue(" + utostr(ValNo) + ");"); + emitCode(ChainName + " = Result.getValue(" + utostr(ValNo) + ");"); if (NodeHasOutFlag) emitCode("InFlag = Result.getValue(" + @@ -2338,14 +2341,15 @@ // User does not expect that the instruction produces a chain! bool AddedChain = HasChain && !NodeHasChain; if (NodeHasChain) - emitCode("CodeGenMap[N.getValue(" + utostr(ValNo++) + ")] = Chain;"); + emitCode("CodeGenMap[N.getValue(" + utostr(ValNo++) + ")] = " + + ChainName + ";"); if (FoldedChains.size() > 0) { std::string Code; for (unsigned j = 0, e = FoldedChains.size(); j < e; j++) Code += "CodeGenMap[" + FoldedChains[j].first + ".getValue(" + utostr(FoldedChains[j].second) + ")] = "; - emitCode(Code + "Chain;"); + emitCode(Code + ChainName + ";"); } if (NodeHasOutFlag) @@ -2467,14 +2471,16 @@ } else { if (!ChainEmitted) { emitCode("SDOperand Chain = CurDAG->getEntryNode();"); + ChainName = "Chain"; ChainEmitted = true; } emitCode("SDOperand " + RootName + "CR" + utostr(i) + ";"); emitCode(RootName + "CR" + utostr(i) + - " = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(" + - ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + - "), Select(" + RootName + utostr(OpNo) + "), InFlag);"); - emitCode("Chain = " + RootName + "CR" + utostr(i) + + " = CurDAG->getCopyToReg(" + ChainName + + ", CurDAG->getRegister(" + ISE.getQualifiedName(RR) + + ", MVT::" + getEnumName(RVT) + "), Select(" + RootName + + utostr(OpNo) + "), InFlag);"); + emitCode(ChainName + " = " + RootName + "CR" + utostr(i) + ".getValue(0);"); emitCode("InFlag = " + RootName + "CR" + utostr(i) + ".getValue(1);"); @@ -2519,11 +2525,12 @@ if (!ChainEmitted) { emitCode("SDOperand Chain = CurDAG->getEntryNode();"); ChainEmitted = true; + ChainName = "Chain"; } - emitCode("Result = CurDAG->getCopyFromReg(Chain, " + + emitCode("Result = CurDAG->getCopyFromReg(" + ChainName + ", " + ISE.getQualifiedName(RR) + ", MVT::" + getEnumName(RVT) + ", InFlag);"); - emitCode("Chain = Result.getValue(1);"); + emitCode(ChainName + " = Result.getValue(1);"); emitCode("InFlag = Result.getValue(2);"); RetVal = true; } @@ -2545,7 +2552,7 @@ // Emit the matcher, capturing named arguments in VariableMap. bool FoundChain = false; - Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", FoundChain, + Emitter.EmitMatchCode(Pattern.getSrcPattern(), "N", "", FoundChain, true /*the root*/); // TP - Get *SOME* tree pattern, we don't care which. From lattner at cs.uiuc.edu Fri Feb 3 00:45:07 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 00:45:07 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp SparcV8InstrInfo.h Message-ID: <200602030645.AAA11158@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.cpp updated: 1.9 -> 1.10 SparcV8InstrInfo.h updated: 1.5 -> 1.6 --- Log message: Implement isLoadFromStackSlot and isStoreToStackSlot --- Diffs of the changes: (+52 -0) SparcV8InstrInfo.cpp | 38 ++++++++++++++++++++++++++++++++++++++ SparcV8InstrInfo.h | 14 ++++++++++++++ 2 files changed, 52 insertions(+) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.9 llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.10 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.9 Sun Dec 18 00:40:34 2005 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp Fri Feb 3 00:44:54 2006 @@ -57,3 +57,41 @@ } return false; } + +/// isLoadFromStackSlot - If the specified machine instruction is a direct +/// load from a stack slot, return the virtual or physical register number of +/// the destination along with the FrameIndex of the loaded stack slot. If +/// not, return 0. This predicate must return 0 if the instruction has +/// any side effects other than loading from the stack slot. +unsigned SparcV8InstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == V8::LDri || + MI->getOpcode() == V8::LDFri || + MI->getOpcode() == V8::LDDFri) { + if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && + MI->getOperand(2).getImmedValue() == 0) { + FrameIndex = MI->getOperand(1).getFrameIndex(); + return MI->getOperand(0).getReg(); + } + } + return 0; +} + +/// isStoreToStackSlot - If the specified machine instruction is a direct +/// store to a stack slot, return the virtual or physical register number of +/// the source reg along with the FrameIndex of the loaded stack slot. If +/// not, return 0. This predicate must return 0 if the instruction has +/// any side effects other than storing to the stack slot. +unsigned SparcV8InstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == V8::STri || + MI->getOpcode() == V8::STFri || + MI->getOpcode() == V8::STDFri) { + if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && + MI->getOperand(1).getImmedValue() == 0) { + FrameIndex = MI->getOperand(0).getFrameIndex(); + return MI->getOperand(2).getReg(); + } + } + return 0; +} Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.h diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.5 llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.6 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.5 Thu Apr 21 18:21:30 2005 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.h Fri Feb 3 00:44:54 2006 @@ -47,6 +47,20 @@ /// virtual bool isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const; + + /// isLoadFromStackSlot - If the specified machine instruction is a direct + /// load from a stack slot, return the virtual or physical register number of + /// the destination along with the FrameIndex of the loaded stack slot. If + /// not, return 0. This predicate must return 0 if the instruction has + /// any side effects other than loading from the stack slot. + virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const; + + /// isStoreToStackSlot - If the specified machine instruction is a direct + /// store to a stack slot, return the virtual or physical register number of + /// the source reg along with the FrameIndex of the loaded stack slot. If + /// not, return 0. This predicate must return 0 if the instruction has + /// any side effects other than storing to the stack slot. + virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const; }; } From evan.cheng at apple.com Fri Feb 3 00:46:53 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Feb 2006 00:46:53 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll Message-ID: <200602030646.AAA11220@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/X86: store_op_load_fold.ll added (r1.1) --- Log message: Added a (store (op (load ...) ...) ...) folding test case. --- Diffs of the changes: (+14 -0) store_op_load_fold.ll | 14 ++++++++++++++ 1 files changed, 14 insertions(+) Index: llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll diff -c /dev/null llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll:1.1 *** /dev/null Fri Feb 3 00:46:51 2006 --- llvm/test/Regression/CodeGen/X86/store_op_load_fold.ll Fri Feb 3 00:46:41 2006 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | llc -march=x86 | not grep 'mov' + ; + ; Test the add and load are folded into the store instruction. + + target triple = "i686-pc-linux-gnu" + + %X = weak global short 0 + + void %foo() { + %tmp.0 = load short* %X + %tmp.3 = add short %tmp.0, 329 + store short %tmp.3, short* %X + ret void + } From natebegeman at mac.com Fri Feb 3 00:47:08 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 3 Feb 2006 00:47:08 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602030647.AAA11263@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.93 -> 1.94 --- Log message: Add common code for reassociating ops in the dag combiner --- Diffs of the changes: (+55 -50) DAGCombiner.cpp | 105 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 55 insertions(+), 50 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.94 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 Thu Feb 2 01:17:31 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Feb 3 00:46:56 2006 @@ -33,7 +33,6 @@ // FIXME: divide by zero is currently left unfolded. do we want to turn this // into an undef? // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false -// FIXME: reassociate (X+C)+Y into (X+Y)+C if the inner expression has one use // //===----------------------------------------------------------------------===// @@ -179,6 +178,8 @@ SDOperand visitLOCATION(SDNode *N); SDOperand visitDEBUGLOC(SDNode *N); + SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS); + bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS); SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2); SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2, @@ -418,6 +419,37 @@ } } +SDOperand DAGCombiner::ReassociateOps(unsigned Opc, SDOperand N0, SDOperand N1){ + MVT::ValueType VT = N0.getValueType(); + // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use + // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2)) + if (N0.getOpcode() == Opc && isa(N0.getOperand(1))) { + if (isa(N1)) { + SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1); + WorkList.push_back(OpNode.Val); + return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0)); + } else if (N0.hasOneUse()) { + SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1); + WorkList.push_back(OpNode.Val); + return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1)); + } + } + // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use + // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2)) + if (N1.getOpcode() == Opc && isa(N1.getOperand(1))) { + if (isa(N0)) { + SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0); + WorkList.push_back(OpNode.Val); + return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0)); + } else if (N1.hasOneUse()) { + SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0); + WorkList.push_back(OpNode.Val); + return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1)); + } + } + return SDOperand(); +} + void DAGCombiner::Run(bool RunningAfterLegalize) { // set the instance variable, so that the various visit routines may use it. AfterLegalize = RunningAfterLegalize; @@ -587,25 +619,16 @@ // fold (add x, 0) -> x if (N1C && N1C->isNullValue()) return N0; - // fold (add (add x, c1), c2) -> (add x, c1+c2) - if (N1C && N0.getOpcode() == ISD::ADD) { - ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); - ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); - if (N00C) - return DAG.getNode(ISD::ADD, VT, N0.getOperand(1), - DAG.getConstant(N1C->getValue()+N00C->getValue(), VT)); - if (N01C) - return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), - DAG.getConstant(N1C->getValue()+N01C->getValue(), VT)); - } - // fold ((c1-A)+c2) -> (c1+c2)-A if (N1C && N0.getOpcode() == ISD::SUB) if (ConstantSDNode *N0C = dyn_cast(N0.getOperand(0))) return DAG.getNode(ISD::SUB, VT, DAG.getConstant(N1C->getValue()+N0C->getValue(), VT), N0.getOperand(1)); - + // reassociate add + SDOperand RADD = ReassociateOps(ISD::ADD, N0, N1); + if (RADD.Val != 0) + return RADD; // fold ((0-A) + B) -> B-A if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) && cast(N0.getOperand(0))->isNullValue()) @@ -678,19 +701,10 @@ DAG.getConstant(Log2_64(-N1C->getSignExtended()), TLI.getShiftAmountTy()))); } - - - // fold (mul (mul x, c1), c2) -> (mul x, c1*c2) - if (N1C && N0.getOpcode() == ISD::MUL) { - ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); - ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); - if (N00C) - return DAG.getNode(ISD::MUL, VT, N0.getOperand(1), - DAG.getConstant(N1C->getValue()*N00C->getValue(), VT)); - if (N01C) - return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), - DAG.getConstant(N1C->getValue()*N01C->getValue(), VT)); - } + // reassociate mul + SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1); + if (RMUL.Val != 0) + return RMUL; return SDOperand(); } @@ -866,17 +880,10 @@ if (N1C && TLI.MaskedValueIsZero(N0, ~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)))) return N0; - // fold (and (and x, c1), c2) -> (and x, c1^c2) - if (N1C && N0.getOpcode() == ISD::AND) { - ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); - ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); - if (N00C) - return DAG.getNode(ISD::AND, VT, N0.getOperand(1), - DAG.getConstant(N1C->getValue()&N00C->getValue(), VT)); - if (N01C) - return DAG.getNode(ISD::AND, VT, N0.getOperand(0), - DAG.getConstant(N1C->getValue()&N01C->getValue(), VT)); - } + // reassociate and + SDOperand RAND = ReassociateOps(ISD::AND, N0, N1); + if (RAND.Val != 0) + return RAND; // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { unsigned ExtendBits = @@ -1031,19 +1038,13 @@ if (N1C && TLI.MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits)))) return N1; - // fold (or (or x, c1), c2) -> (or x, c1|c2) - if (N1C && N0.getOpcode() == ISD::OR) { - ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); - ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); - if (N00C) - return DAG.getNode(ISD::OR, VT, N0.getOperand(1), - DAG.getConstant(N1C->getValue()|N00C->getValue(), VT)); - if (N01C) - return DAG.getNode(ISD::OR, VT, N0.getOperand(0), - DAG.getConstant(N1C->getValue()|N01C->getValue(), VT)); - } else if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() && + // reassociate or + SDOperand ROR = ReassociateOps(ISD::OR, N0, N1); + if (ROR.Val != 0) + return ROR; + // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2) + if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() && isa(N0.getOperand(1))) { - // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2) ConstantSDNode *C1 = cast(N0.getOperand(1)); return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0), N1), @@ -1160,6 +1161,10 @@ // fold (xor x, 0) -> x if (N1C && N1C->isNullValue()) return N0; + // reassociate xor + SDOperand RXOR = ReassociateOps(ISD::XOR, N0, N1); + if (RXOR.Val != 0) + return RXOR; // fold !(x cc y) -> (x !cc y) if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) { bool isInt = MVT::isInteger(LHS.getValueType()); From lattner at cs.uiuc.edu Fri Feb 3 00:51:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 00:51:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200602030651.AAA11344@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.252 -> 1.253 --- Log message: remove dead fn --- Diffs of the changes: (+0 -11) SelectionDAG.cpp | 11 ----------- 1 files changed, 11 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.252 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.253 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.252 Thu Feb 2 19:33:01 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Feb 3 00:51:34 2006 @@ -43,17 +43,6 @@ } } -static bool isAssociativeBinOp(unsigned Opcode) { - switch (Opcode) { - case ISD::ADD: - case ISD::MUL: - case ISD::AND: - case ISD::OR: - case ISD::XOR: return true; - default: return false; // FIXME: Need associative info for user ops! - } -} - // isInvertibleForFree - Return true if there is no cost to emitting the logical // inverse of this node. static bool isInvertibleForFree(SDOperand N) { From lattner at cs.uiuc.edu Fri Feb 3 01:06:36 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 01:06:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp SparcV8RegisterInfo.h Message-ID: <200602030706.BAA11475@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8RegisterInfo.cpp updated: 1.33 -> 1.34 SparcV8RegisterInfo.h updated: 1.6 -> 1.7 --- Log message: Teach sparc to fold loads/stores into copies. Remove the dead getRegClassForType method minor formating changes. --- Diffs of the changes: (+47 -37) SparcV8RegisterInfo.cpp | 79 ++++++++++++++++++++++++++---------------------- SparcV8RegisterInfo.h | 5 ++- 2 files changed, 47 insertions(+), 37 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.33 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.34 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.33 Mon Jan 9 12:28:21 2006 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Fri Feb 3 01:06:25 2006 @@ -27,34 +27,29 @@ void SparcV8RegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int FrameIdx, + unsigned SrcReg, int FI, const TargetRegisterClass *RC) const { // On the order of operands here: think "[FrameIdx + 0] = SrcReg". if (RC == V8::IntRegsRegisterClass) - BuildMI (MBB, I, V8::STri, 3).addFrameIndex (FrameIdx).addSImm (0) - .addReg (SrcReg); + BuildMI(MBB, I, V8::STri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); else if (RC == V8::FPRegsRegisterClass) - BuildMI (MBB, I, V8::STFri, 3).addFrameIndex (FrameIdx).addSImm (0) - .addReg (SrcReg); + BuildMI(MBB, I, V8::STFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); else if (RC == V8::DFPRegsRegisterClass) - BuildMI (MBB, I, V8::STDFri, 3).addFrameIndex (FrameIdx).addSImm (0) - .addReg (SrcReg); + BuildMI(MBB, I, V8::STDFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); else - assert (0 && "Can't store this register to stack slot"); + assert(0 && "Can't store this register to stack slot"); } void SparcV8RegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DestReg, int FrameIdx, + unsigned DestReg, int FI, const TargetRegisterClass *RC) const { if (RC == V8::IntRegsRegisterClass) - BuildMI (MBB, I, V8::LDri, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0); + BuildMI(MBB, I, V8::LDri, 2, DestReg).addFrameIndex(FI).addImm(0); else if (RC == V8::FPRegsRegisterClass) - BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx) - .addSImm (0); + BuildMI(MBB, I, V8::LDFri, 2, DestReg).addFrameIndex(FI).addImm (0); else if (RC == V8::DFPRegsRegisterClass) - BuildMI (MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex (FrameIdx) - .addSImm (0); + BuildMI(MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex(FI).addImm(0); else assert(0 && "Can't load this register from stack slot"); } @@ -64,15 +59,46 @@ unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const { if (RC == V8::IntRegsRegisterClass) - BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); + BuildMI(MBB, I, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(SrcReg); else if (RC == V8::FPRegsRegisterClass) - BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg); + BuildMI(MBB, I, V8::FMOVS, 1, DestReg).addReg(SrcReg); else if (RC == V8::DFPRegsRegisterClass) - BuildMI (MBB, I, V8::FpMOVD, 1, DestReg).addReg (SrcReg); + BuildMI(MBB, I, V8::FpMOVD, 1, DestReg).addReg(SrcReg); else assert (0 && "Can't copy this register"); } +MachineInstr *SparcV8RegisterInfo::foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + int FI) const { + bool isFloat = false; + switch (MI->getOpcode()) { + case V8::ORrr: + if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == V8::G0&& + MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) { + if (OpNum == 0) // COPY -> STORE + return BuildMI(V8::STri, 3).addFrameIndex(FI).addImm(0) + .addReg(MI->getOperand(2).getReg()); + else // COPY -> LOAD + return BuildMI(V8::LDri, 2, MI->getOperand(0).getReg()) + .addFrameIndex(FI).addImm(0); + } + break; + case V8::FMOVS: + isFloat = true; + // FALLTHROUGH + case V8::FMOVD: + if (OpNum == 0) // COPY -> STORE + return BuildMI(isFloat ? V8::STFri : V8::STDFri, 3) + .addFrameIndex(FI).addImm(0).addReg(MI->getOperand(1).getReg()); + else // COPY -> LOAD + return BuildMI(isFloat ? V8::LDFri : V8::LDDFri, 2, + MI->getOperand(0).getReg()).addFrameIndex(FI).addImm(0); + break; + } + return 0; +} + void SparcV8RegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { @@ -172,22 +198,3 @@ #include "SparcV8GenRegisterInfo.inc" -const TargetRegisterClass* -SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const { - switch (Ty->getTypeID()) { - case Type::FloatTyID: return V8::FPRegsRegisterClass; - case Type::DoubleTyID: return V8::DFPRegsRegisterClass; - case Type::LongTyID: - case Type::ULongTyID: assert(0 && "Long values do not fit in registers!"); - default: assert(0 && "Invalid type to getClass!"); - case Type::BoolTyID: - case Type::SByteTyID: - case Type::UByteTyID: - case Type::ShortTyID: - case Type::UShortTyID: - case Type::IntTyID: - case Type::UIntTyID: - case Type::PointerTyID: return V8::IntRegsRegisterClass; - } -} - Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.6 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.7 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.6 Thu Sep 29 20:29:42 2005 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h Fri Feb 3 01:06:25 2006 @@ -23,7 +23,6 @@ struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo { SparcV8RegisterInfo(); - const TargetRegisterClass* getRegClassForType(const Type* Ty) const; /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, @@ -39,6 +38,10 @@ void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, unsigned SrcReg, const TargetRegisterClass *RC) const; + + virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + int FrameIndex) const; void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, From lattner at cs.uiuc.edu Fri Feb 3 12:06:15 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 12:06:15 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602031806.MAA02407@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.160 -> 1.161 --- Log message: node predicates add to the complexity of a pattern. This ensures that the X86 backend attempts to match small-immediate versions of instructions before the full size immediate versions. --- Diffs of the changes: (+9 -2) DAGISelEmitter.cpp | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.160 llvm/utils/TableGen/DAGISelEmitter.cpp:1.161 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.160 Fri Feb 3 00:22:41 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Fri Feb 3 12:06:02 2006 @@ -1722,7 +1722,12 @@ const ComplexPattern *AM = NodeGetComplexPattern(P, ISE); if (AM) Size += AM->getNumOperands() * 2; - + + // If this node has some predicate function that must match, it adds to the + // complexity of this node. + if (!P->getPredicateFn().empty()) + ++Size; + // Count children in the count if they are also nodes. for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i) { TreePatternNode *Child = P->getChild(i); @@ -1730,9 +1735,11 @@ Size += getPatternSize(Child, ISE); else if (Child->isLeaf()) { if (dynamic_cast(Child->getLeafValue())) - Size += 3; // Matches a ConstantSDNode. + Size += 3; // Matches a ConstantSDNode (+2) and a specific value (+1). else if (NodeIsComplexPattern(Child)) Size += getPatternSize(Child, ISE); + else if (!Child->getPredicateFn().empty()) + ++Size; } } From lattner at cs.uiuc.edu Fri Feb 3 12:54:50 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 12:54:50 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86.h X86TargetMachine.cpp X86PeepholeOpt.cpp Message-ID: <200602031854.MAA01840@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86.h updated: 1.42 -> 1.43 X86TargetMachine.cpp updated: 1.100 -> 1.101 X86PeepholeOpt.cpp (r1.42) removed --- Log message: Remove the X86PeepholeOptimizerPass, a truly horrible old hack that is now obsolete. yaay :) --- Diffs of the changes: (+0 -9) X86.h | 5 ----- X86TargetMachine.cpp | 4 ---- 2 files changed, 9 deletions(-) Index: llvm/lib/Target/X86/X86.h diff -u llvm/lib/Target/X86/X86.h:1.42 llvm/lib/Target/X86/X86.h:1.43 --- llvm/lib/Target/X86/X86.h:1.42 Fri Jan 27 15:26:54 2006 +++ llvm/lib/Target/X86/X86.h Fri Feb 3 12:54:24 2006 @@ -38,11 +38,6 @@ /// FunctionPass *createX86ISelDag(TargetMachine &TM); -/// createX86PeepholeOptimizer - Create a pass to perform X86 specific peephole -/// optimizations. -/// -FunctionPass *createX86PeepholeOptimizerPass(); - /// createX86FloatingPointStackifierPass - This function returns a pass which /// converts floating point register references and pseudo instructions into /// floating point stack references and physical instructions. Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.100 llvm/lib/Target/X86/X86TargetMachine.cpp:1.101 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.100 Fri Jan 27 15:26:54 2006 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Fri Feb 3 12:54:24 2006 @@ -129,8 +129,6 @@ // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - PM.add(createX86PeepholeOptimizerPass()); - if (PrintMachineCode) // Print the register-allocated code PM.add(createX86CodePrinterPass(std::cerr, *this)); @@ -198,8 +196,6 @@ // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - PM.add(createX86PeepholeOptimizerPass()); - if (PrintMachineCode) // Print the register-allocated code PM.add(createX86CodePrinterPass(std::cerr, TM)); } From lattner at cs.uiuc.edu Fri Feb 3 12:59:51 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 12:59:51 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86TargetMachine.cpp Message-ID: <200602031859.MAA01964@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86TargetMachine.cpp updated: 1.101 -> 1.102 --- Log message: remove an old comment --- Diffs of the changes: (+2 -3) X86TargetMachine.cpp | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) Index: llvm/lib/Target/X86/X86TargetMachine.cpp diff -u llvm/lib/Target/X86/X86TargetMachine.cpp:1.101 llvm/lib/Target/X86/X86TargetMachine.cpp:1.102 --- llvm/lib/Target/X86/X86TargetMachine.cpp:1.101 Fri Feb 3 12:54:24 2006 +++ llvm/lib/Target/X86/X86TargetMachine.cpp Fri Feb 3 12:59:39 2006 @@ -82,7 +82,8 @@ Subtarget(M, FS), FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), -4), - JITInfo(*this) {} + JITInfo(*this) { +} // addPassesToEmitFile - We currently use all of the same passes as the JIT @@ -176,8 +177,6 @@ else PM.add(createX86ISelDag(TM)); - // FIXME: Add SSA based peephole optimizer here. - // Print the instruction selected machine code... if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); From lattner at cs.uiuc.edu Fri Feb 3 14:14:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 14:14:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602032014.OAA11911@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.146 -> 1.147 --- Log message: remove some #ifdef'd out code, which should properly be in the dag combiner anyway. --- Diffs of the changes: (+0 -30) SelectionDAGISel.cpp | 30 ------------------------------ 1 files changed, 30 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.146 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.147 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.146 Wed Feb 1 18:25:23 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Feb 3 14:13:59 2006 @@ -1504,36 +1504,6 @@ } void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { -#if 0 - // If the size of the cpy/move/set is constant (known) - if (ConstantUInt* op3 = dyn_cast(I.getOperand(3))) { - uint64_t size = op3->getValue(); - switch (Op) { - case ISD::MEMSET: - if (size <= TLI.getMaxStoresPerMemSet()) { - if (ConstantUInt* op4 = dyn_cast(I.getOperand(4))) { - uint64_t TySize = TLI.getTargetData().getTypeSize(Ty); - uint64_t align = op4.getValue(); - while (size > align) { - size -=align; - } - Value *SrcV = I.getOperand(0); - SDOperand Src = getValue(SrcV); - SDOperand Ptr = getValue(I.getOperand(1)); - DAG.setRoot(DAG.getNode(ISD::STORE, MVT::Other, getRoot(), Src, Ptr, - DAG.getSrcValue(I.getOperand(1)))); - } - break; - } - break; // don't do this optimization, use a normal memset - case ISD::MEMMOVE: - case ISD::MEMCPY: - break; // FIXME: not implemented yet - } - } -#endif - - // Non-optimized version std::vector Ops; Ops.push_back(getRoot()); Ops.push_back(getValue(I.getOperand(1))); From lattner at cs.uiuc.edu Fri Feb 3 15:25:35 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 15:25:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200602032125.PAA12595@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.1 -> 1.2 --- Log message: add a note --- Diffs of the changes: (+4 -0) README.txt | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.1 llvm/lib/Target/README.txt:1.2 --- llvm/lib/Target/README.txt:1.1 Fri Feb 3 00:21:43 2006 +++ llvm/lib/Target/README.txt Fri Feb 3 15:25:23 2006 @@ -64,4 +64,8 @@ //===---------------------------------------------------------------------===// +For dag combiner and instcombine: +Fold: "A / (B << N)" where B is a power of 2, to "A >> (N + log2(B))". +Fold: "A % (B << N)" where B is a power of 2, to "A & ((B << N) - 1)". +//===---------------------------------------------------------------------===// From lattner at cs.uiuc.edu Fri Feb 3 16:05:52 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 16:05:52 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200602032205.QAA13637@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.2 -> 1.3 --- Log message: another case Nate came up with --- Diffs of the changes: (+3 -0) README.txt | 3 +++ 1 files changed, 3 insertions(+) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.2 llvm/lib/Target/README.txt:1.3 --- llvm/lib/Target/README.txt:1.2 Fri Feb 3 15:25:23 2006 +++ llvm/lib/Target/README.txt Fri Feb 3 16:05:41 2006 @@ -68,4 +68,7 @@ Fold: "A / (B << N)" where B is a power of 2, to "A >> (N + log2(B))". Fold: "A % (B << N)" where B is a power of 2, to "A & ((B << N) - 1)". +int t(int X, int Y) { return 1 << (X+4); } --> 16 << X + + //===---------------------------------------------------------------------===// From lattner at cs.uiuc.edu Fri Feb 3 16:06:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 16:06:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602032206.QAA14007@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.59 -> 1.60 --- Log message: add a note --- Diffs of the changes: (+2 -0) README.txt | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.59 llvm/lib/Target/PowerPC/README.txt:1.60 --- llvm/lib/Target/PowerPC/README.txt:1.59 Fri Feb 3 00:22:11 2006 +++ llvm/lib/Target/PowerPC/README.txt Fri Feb 3 16:06:45 2006 @@ -39,6 +39,8 @@ b .LBBl42__2E_expand_function_8_42 ; NewDefault b .LBBl42__2E_expand_function_8_42 ; NewDefault +This occurs in SPASS. + ===-------------------------------------------------------------------------=== * Codegen this: From natebegeman at mac.com Fri Feb 3 16:24:18 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 3 Feb 2006 16:24:18 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200602032224.QAA15900@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.45 -> 1.46 --- Log message: Add a framework for eliminating instructions that produces undemanded bits. --- Diffs of the changes: (+9 -0) TargetLowering.h | 9 +++++++++ 1 files changed, 9 insertions(+) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.45 llvm/include/llvm/Target/TargetLowering.h:1.46 --- llvm/include/llvm/Target/TargetLowering.h:1.45 Mon Jan 30 00:09:03 2006 +++ llvm/include/llvm/Target/TargetLowering.h Fri Feb 3 16:24:05 2006 @@ -290,6 +290,15 @@ /// isMaskedValueZeroForTargetNode method, to allow target nodes to be /// understood. bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask) const; + + /// DemandedBitsAreZero - Return true if 'Op & Mask' demands no bits from a + /// bit set operation such as a sign extend or or/xor with constant whose only + /// use is Op. If it returns true, the old node that sets bits which are + /// not demanded is returned in Old, and its replacement node is returned in + /// New, such that callers of SetBitsAreZero may call CombineTo on them if + /// desired. + bool DemandedBitsAreZero(const SDOperand &Op, uint64_t Mask, SDOperand &Old, + SDOperand &New, SelectionDAG &DAG); //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by From natebegeman at mac.com Fri Feb 3 16:24:19 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 3 Feb 2006 16:24:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602032224.QAA15904@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.94 -> 1.95 --- Log message: Add a framework for eliminating instructions that produces undemanded bits. --- Diffs of the changes: (+30 -10) DAGCombiner.cpp | 40 ++++++++++++++++++++++++++++++---------- 1 files changed, 30 insertions(+), 10 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.94 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.95 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.94 Fri Feb 3 00:46:56 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Feb 3 16:24:05 2006 @@ -858,7 +858,7 @@ SDOperand DAGCombiner::visitAND(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); - SDOperand LL, LR, RL, RR, CC0, CC1; + SDOperand LL, LR, RL, RR, CC0, CC1, Old, New; ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N1.getValueType(); @@ -884,13 +884,6 @@ SDOperand RAND = ReassociateOps(ISD::AND, N0, N1); if (RAND.Val != 0) return RAND; - // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) - if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { - unsigned ExtendBits = - MVT::getSizeInBits(cast(N0.getOperand(1))->getVT()); - if (ExtendBits == 64 || ((N1C->getValue() & (~0ULL << ExtendBits)) == 0)) - return DAG.getNode(ISD::AND, VT, N0.getOperand(0), N1); - } // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF if (N1C && N0.getOpcode() == ISD::OR) if (ConstantSDNode *ORI = dyn_cast(N0.getOperand(1))) @@ -966,6 +959,26 @@ WorkList.push_back(ANDNode.Val); return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1)); } + // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1) + // fold (and (sra)) -> (and (srl)) when possible. + if (TLI.DemandedBitsAreZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits), Old, + New, DAG)) { + WorkList.push_back(N); + CombineTo(Old.Val, New); + return SDOperand(); + } + // FIXME: DemandedBitsAreZero cannot currently handle AND with non-constant + // RHS and propagate known cleared bits to LHS. For this reason, we must keep + // this fold, for now, for the following testcase: + // + //int %test2(uint %mode.0.i.0) { + // %tmp.79 = cast uint %mode.0.i.0 to int + // %tmp.80 = shr int %tmp.79, ubyte 15 + // %tmp.81 = shr uint %mode.0.i.0, ubyte 16 + // %tmp.82 = cast uint %tmp.81 to int + // %tmp.83 = and int %tmp.80, %tmp.82 + // ret int %tmp.83 + //} // fold (and (sra)) -> (and (srl)) when possible. if (N0.getOpcode() == ISD::SRA && N0.Val->hasOneUse()) { if (ConstantSDNode *N01C = dyn_cast(N0.getOperand(1))) { @@ -1240,6 +1253,8 @@ SDOperand DAGCombiner::visitSHL(SDNode *N) { SDOperand N0 = N->getOperand(0); SDOperand N1 = N->getOperand(1); + SDOperand Old = SDOperand(); + SDOperand New = SDOperand(); ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); MVT::ValueType VT = N0.getValueType(); @@ -1260,6 +1275,12 @@ // if (shl x, c) is known to be zero, return 0 if (N1C && TLI.MaskedValueIsZero(SDOperand(N, 0), ~0ULL >> (64-OpSizeInBits))) return DAG.getConstant(0, VT); + if (N1C && TLI.DemandedBitsAreZero(SDOperand(N,0), ~0ULL >> (64-OpSizeInBits), + Old, New, DAG)) { + WorkList.push_back(N); + CombineTo(Old.Val, New); + return SDOperand(); + } // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) if (N1C && N0.getOpcode() == ISD::SHL && N0.getOperand(1).getOpcode() == ISD::Constant) { @@ -1650,8 +1671,7 @@ return N0; // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1))) - return DAG.getNode(ISD::AND, N0.getValueType(), N0, - DAG.getConstant(~0ULL >> (64-EVTBits), VT)); + return DAG.getZeroExtendInReg(N0, EVT); // fold (sext_in_reg (srl x)) -> sra x if (N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant && From natebegeman at mac.com Fri Feb 3 16:24:19 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 3 Feb 2006 16:24:19 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602032224.QAA15908@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.26 -> 1.27 --- Log message: Add a framework for eliminating instructions that produces undemanded bits. --- Diffs of the changes: (+57 -1) TargetLowering.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 57 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.26 llvm/lib/Target/TargetLowering.cpp:1.27 --- llvm/lib/Target/TargetLowering.cpp:1.26 Thu Feb 2 00:43:15 2006 +++ llvm/lib/Target/TargetLowering.cpp Fri Feb 3 16:24:05 2006 @@ -131,7 +131,63 @@ return NULL; } - +/// DemandedBitsAreZero - Return true if 'Op & Mask' demands no bits from a bit +/// set operation such as a sign extend or or/xor with constant whose only +/// use is Op. If it returns true, the old node that sets bits which are +/// not demanded is returned in Old, and its replacement node is returned in +/// New, such that callers of SetBitsAreZero may call CombineTo on them if +/// desired. +bool TargetLowering::DemandedBitsAreZero(const SDOperand &Op, uint64_t Mask, + SDOperand &Old, SDOperand &New, + SelectionDAG &DAG) { + // If the operation has more than one use, we're not interested in it. + // Tracking down and checking all uses would be problematic and slow. + if (!Op.hasOneUse()) + return false; + + switch (Op.getOpcode()) { + case ISD::AND: + // (X & C1) & C2 == 0 iff C1 & C2 == 0. + if (ConstantSDNode *AndRHS = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask & AndRHS->getValue(); + return DemandedBitsAreZero(Op.getOperand(0), NewVal, Old, New, DAG); + } + break; + case ISD::SHL: + // (ushl X, C1) & C2 == 0 iff X & (C2 >> C1) == 0 + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + uint64_t NewVal = Mask >> ShAmt->getValue(); + return DemandedBitsAreZero(Op.getOperand(0), NewVal, Old, New, DAG); + } + break; + case ISD::SIGN_EXTEND_INREG: { + MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); + unsigned ExtendBits = MVT::getSizeInBits(EVT); + // If we're extending from something smaller than MVT::i64 and all of the + // sign extension bits are masked, return true and set New to be a zero + // extend inreg from the same type. + if (ExtendBits < 64 && ((Mask & (~0ULL << ExtendBits)) == 0)) { + Old = Op; + New = DAG.getZeroExtendInReg(Op.getOperand(0), EVT); + return true; + } + break; + } + case ISD::SRA: + if (ConstantSDNode *ShAmt = dyn_cast(Op.getOperand(1))) { + unsigned OpBits = MVT::getSizeInBits(Op.getValueType()); + unsigned SH = ShAmt->getValue(); + if (SH && ((Mask & (~0ULL << (OpBits-SH))) == 0)) { + Old = Op; + New = DAG.getNode(ISD::SRL, Op.getValueType(), Op.getOperand(0), + Op.getOperand(1)); + return true; + } + } + break; + } + return false; +} /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We use /// this predicate to simplify operations downstream. Op and Mask are known to From natebegeman at mac.com Fri Feb 3 16:38:18 2006 From: natebegeman at mac.com (Nate Begeman) Date: Fri, 3 Feb 2006 16:38:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602032238.QAA15942@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.27 -> 1.28 --- Log message: Implement some feedback from sabre --- Diffs of the changes: (+5 -5) TargetLowering.cpp | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.27 llvm/lib/Target/TargetLowering.cpp:1.28 --- llvm/lib/Target/TargetLowering.cpp:1.27 Fri Feb 3 16:24:05 2006 +++ llvm/lib/Target/TargetLowering.cpp Fri Feb 3 16:38:07 2006 @@ -135,14 +135,14 @@ /// set operation such as a sign extend or or/xor with constant whose only /// use is Op. If it returns true, the old node that sets bits which are /// not demanded is returned in Old, and its replacement node is returned in -/// New, such that callers of SetBitsAreZero may call CombineTo on them if +/// New, such that callers of DemandedBitsAreZero may call CombineTo on them if /// desired. bool TargetLowering::DemandedBitsAreZero(const SDOperand &Op, uint64_t Mask, SDOperand &Old, SDOperand &New, SelectionDAG &DAG) { // If the operation has more than one use, we're not interested in it. // Tracking down and checking all uses would be problematic and slow. - if (!Op.hasOneUse()) + if (!Op.Val->hasOneUse()) return false; switch (Op.getOpcode()) { @@ -164,11 +164,11 @@ MVT::ValueType EVT = cast(Op.getOperand(1))->getVT(); unsigned ExtendBits = MVT::getSizeInBits(EVT); // If we're extending from something smaller than MVT::i64 and all of the - // sign extension bits are masked, return true and set New to be a zero - // extend inreg from the same type. + // sign extension bits are masked, return true and set New to be the + // first operand, since we no longer care what the high bits are. if (ExtendBits < 64 && ((Mask & (~0ULL << ExtendBits)) == 0)) { Old = Op; - New = DAG.getZeroExtendInReg(Op.getOperand(0), EVT); + New = Op.getOperand(0); return true; } break; From lattner at cs.uiuc.edu Fri Feb 3 17:14:10 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 17:14:10 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602032314.RAA16200@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.51 -> 1.52 --- Log message: significantly simplify the VirtRegMap code by pulling the SpillSlotsAvailable and PhysRegsAvailable maps out into a new AvailableSpills struct. No functionality change. This paves the way for a bugfix, coming up next. --- Diffs of the changes: (+97 -69) VirtRegMap.cpp | 166 +++++++++++++++++++++++++++++++++------------------------ 1 files changed, 97 insertions(+), 69 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.51 llvm/lib/CodeGen/VirtRegMap.cpp:1.52 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.51 Thu Feb 2 21:48:54 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:13:58 2006 @@ -231,38 +231,92 @@ }; } -void LocalSpiller::ClobberPhysRegOnly(unsigned PhysReg, - std::map &SpillSlots, - std::multimap &PhysRegsAvailable) { - std::multimap::iterator I = PhysRegsAvailable.lower_bound(PhysReg); +/// AvailableSpills - As the local spiller is scanning and rewriting an MBB from +/// top down, keep track of which spills slots are available in each register. +class AvailableSpills { + const MRegisterInfo *MRI; + const TargetInstrInfo *TII; + + // SpillSlotsAvailable - This map keeps track of all of the spilled virtual + // register values that are still available, due to being loaded or stored to, + // but not invalidated yet. + std::map SpillSlotsAvailable; + + // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating + // which stack slot values are currently held by a physreg. This is used to + // invalidate entries in SpillSlotsAvailable when a physreg is modified. + std::multimap PhysRegsAvailable; + + void ClobberPhysRegOnly(unsigned PhysReg); +public: + AvailableSpills(const MRegisterInfo *mri, const TargetInstrInfo *tii) + : MRI(mri), TII(tii) { + } + + /// getSpillSlotPhysReg - If the specified stack slot is available in a + /// physical register, return that PhysReg, otherwise return 0. + unsigned getSpillSlotPhysReg(int Slot) const { + std::map::const_iterator I = SpillSlotsAvailable.find(Slot); + if (I != SpillSlotsAvailable.end()) + return I->second; + return 0; + } + + /// addAvailable - Mark that the specified stack slot is available in the + /// specified physreg. + void addAvailable(int Slot, unsigned Reg) { + PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); + SpillSlotsAvailable[Slot] = Reg; + + DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg " + << MRI->getName(Reg) << "\n"); + } + + + /// ClobberPhysReg - This is called when the specified physreg changes + /// value. We use this to invalidate any info about stuff we thing lives in + /// it and any of its aliases. + void ClobberPhysReg(unsigned PhysReg); + + /// ModifyStackSlot - This method is called when the value in a stack slot + /// changes. This removes information about which register the previous value + /// for this slot lives in (as the previous value is dead now). + void ModifyStackSlot(int Slot); +}; + +/// ClobberPhysRegOnly - This is called when the specified physreg changes +/// value. We use this to invalidate any info about stuff we thing lives in it. +void AvailableSpills::ClobberPhysRegOnly(unsigned PhysReg) { + std::multimap::iterator I = + PhysRegsAvailable.lower_bound(PhysReg); while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); - assert(SpillSlots[Slot] == PhysReg && "Bidirectional map mismatch!"); - SpillSlots.erase(Slot); + assert(SpillSlotsAvailable[Slot] == PhysReg && + "Bidirectional map mismatch!"); + SpillSlotsAvailable.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) << " clobbered, invalidating SS#" << Slot << "\n"); - } } -void LocalSpiller::ClobberPhysReg(unsigned PhysReg, - std::map &SpillSlots, - std::multimap &PhysRegsAvailable) { +/// ClobberPhysReg - This is called when the specified physreg changes +/// value. We use this to invalidate any info about stuff we thing lives in +/// it and any of its aliases. +void AvailableSpills::ClobberPhysReg(unsigned PhysReg) { for (const unsigned *AS = MRI->getAliasSet(PhysReg); *AS; ++AS) - ClobberPhysRegOnly(*AS, SpillSlots, PhysRegsAvailable); - ClobberPhysRegOnly(PhysReg, SpillSlots, PhysRegsAvailable); + ClobberPhysRegOnly(*AS); + ClobberPhysRegOnly(PhysReg); } /// ModifyStackSlot - This method is called when the value in a stack slot /// changes. This removes information about which register the previous value /// for this slot lives in (as the previous value is dead now). -void LocalSpiller::ModifyStackSlot(int Slot, std::map &SpillSlots, - std::multimap &PhysRegsAvailable) { - std::map::iterator It = SpillSlots.find(Slot); - if (It == SpillSlots.end()) return; +void AvailableSpills::ModifyStackSlot(int Slot) { + std::map::iterator It = SpillSlotsAvailable.find(Slot); + if (It == SpillSlotsAvailable.end()) return; unsigned Reg = It->second; - SpillSlots.erase(It); + SpillSlotsAvailable.erase(It); // This register may hold the value of multiple stack slots, only remove this // stack slot from the set of values the register contains. @@ -308,18 +362,12 @@ /// register allocator is done with them. If possible, avoid reloading vregs. void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, const VirtRegMap &VRM) { - // SpillSlotsAvailable - This map keeps track of all of the spilled virtual - // register values that are still available, due to being loaded or stored to, - // but not invalidated yet. - std::map SpillSlotsAvailable; - - // PhysRegsAvailable - This is the inverse of SpillSlotsAvailable, indicating - // which stack slot values are currently held by a physreg. This is used to - // invalidate entries in SpillSlotsAvailable when a physreg is modified. - std::multimap PhysRegsAvailable; - DEBUG(std::cerr << MBB.getBasicBlock()->getName() << ":\n"); + // Spills - Keep track of which spilled values are available in physregs so + // that we can choose to reuse the physregs instead of emitting reloads. + AvailableSpills Spills(MRI, TII); + std::vector ReusedOperands; // DefAndUseVReg - When we see a def&use operand that is spilled, keep track @@ -387,15 +435,12 @@ unsigned PhysReg; // Check to see if this stack slot is available. - std::map::iterator SSI = - SpillSlotsAvailable.find(StackSlot); - if (SSI != SpillSlotsAvailable.end()) { + if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) { + // If this stack slot value is already available, reuse it! DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " - << MRI->getName(SSI->second) << " for vreg" + << MRI->getName(PhysReg) << " for vreg" << VirtReg <<" instead of reloading into physreg " << MRI->getName(VRM.getPhys(VirtReg)) << "\n"); - // If this stack slot value is already available, reuse it! - PhysReg = SSI->second; MI.SetMachineOperandReg(i, PhysReg); // The only technical detail we have is that we don't know that @@ -446,20 +491,15 @@ MBB.getParent()->getSSARegMap()->getRegClass(Op.VirtReg); MRI->loadRegFromStackSlot(MBB, &MI, Op.AssignedPhysReg, Op.StackSlot, AliasRC); - ClobberPhysReg(Op.AssignedPhysReg, SpillSlotsAvailable, - PhysRegsAvailable); - + Spills.ClobberPhysReg(Op.AssignedPhysReg); + Spills.ClobberPhysReg(Op.PhysRegReused); + // Any stores to this stack slot are not dead anymore. MaybeDeadStores.erase(Op.StackSlot); MI.SetMachineOperandReg(Op.Operand, Op.AssignedPhysReg); - PhysRegsAvailable.insert(std::make_pair(Op.AssignedPhysReg, - Op.StackSlot)); - SpillSlotsAvailable[Op.StackSlot] = Op.AssignedPhysReg; - PhysRegsAvailable.erase(Op.PhysRegReused); - DEBUG(std::cerr << "Remembering SS#" << Op.StackSlot - << " in physreg " - << MRI->getName(Op.AssignedPhysReg) << "\n"); + + Spills.addAvailable(Op.StackSlot, Op.AssignedPhysReg); ++NumLoads; DEBUG(std::cerr << '\t' << *prior(MII)); @@ -473,17 +513,13 @@ PhysRegsUsed[PhysReg] = true; MRI->loadRegFromStackSlot(MBB, &MI, PhysReg, StackSlot, RC); // This invalidates PhysReg. - ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + Spills.ClobberPhysReg(PhysReg); // Any stores to this stack slot are not dead anymore. MaybeDeadStores.erase(StackSlot); - - MI.SetMachineOperandReg(i, PhysReg); - PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); - SpillSlotsAvailable[StackSlot] = PhysReg; - DEBUG(std::cerr << "Remembering SS#" << StackSlot <<" in physreg " - << MRI->getName(PhysReg) << "\n"); + Spills.addAvailable(StackSlot, PhysReg); ++NumLoads; + MI.SetMachineOperandReg(i, PhysReg); DEBUG(std::cerr << '\t' << *prior(MII)); } @@ -492,7 +528,7 @@ for (const unsigned *ImpDef = TII->getImplicitDefs(MI.getOpcode()); *ImpDef; ++ImpDef) { PhysRegsUsed[*ImpDef] = true; - ClobberPhysReg(*ImpDef, SpillSlotsAvailable, PhysRegsAvailable); + Spills.ClobberPhysReg(*ImpDef); } DEBUG(std::cerr << '\t' << MI); @@ -520,12 +556,12 @@ if (unsigned DestReg = TII->isLoadFromStackSlot(&MI, FrameIdx)) { // If this spill slot is available, turn it into a copy (or nothing) // instead of leaving it as a load! - std::map::iterator It = SpillSlotsAvailable.find(SS); - if (FrameIdx == SS && It != SpillSlotsAvailable.end()) { + unsigned InReg; + if (FrameIdx == SS && (InReg = Spills.getSpillSlotPhysReg(SS))) { DEBUG(std::cerr << "Promoted Load To Copy: " << MI); MachineFunction &MF = *MBB.getParent(); - if (DestReg != It->second) { - MRI->copyRegToReg(MBB, &MI, DestReg, It->second, + if (DestReg != InReg) { + MRI->copyRegToReg(MBB, &MI, DestReg, InReg, MF.getSSARegMap()->getRegClass(VirtReg)); // Revisit the copy so we make sure to notice the effects of the // operation on the destreg (either needing to RA it if it's @@ -558,7 +594,7 @@ // the value, the value is not available anymore. if (MR & VirtRegMap::isMod) { // Notice that the value in this stack slot has been modified. - ModifyStackSlot(SS, SpillSlotsAvailable, PhysRegsAvailable); + Spills.ModifyStackSlot(SS); // If this is *just* a mod of the value, check to see if this is just a // store to the spill slot (i.e. the spill got merged into the copy). If @@ -577,11 +613,7 @@ // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. - SpillSlotsAvailable[StackSlot] = SrcReg; - PhysRegsAvailable.insert(std::make_pair(SrcReg, StackSlot)); - DEBUG(std::cerr << "Updating SS#" << StackSlot << " in physreg " - << MRI->getName(SrcReg) << " for virtreg #" - << VirtReg << "\n" << MI); + Spills.addAvailable(StackSlot, SrcReg); } } } @@ -616,7 +648,7 @@ MBB.erase(&MI); goto ProcessNextInst; } - ClobberPhysReg(VirtReg, SpillSlotsAvailable, PhysRegsAvailable); + Spills.ClobberPhysReg(VirtReg); continue; } } @@ -664,14 +696,10 @@ // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. - ModifyStackSlot(StackSlot, SpillSlotsAvailable, PhysRegsAvailable); - ClobberPhysReg(PhysReg, SpillSlotsAvailable, PhysRegsAvailable); + Spills.ModifyStackSlot(StackSlot); + Spills.ClobberPhysReg(PhysReg); - PhysRegsAvailable.insert(std::make_pair(PhysReg, StackSlot)); - SpillSlotsAvailable[StackSlot] = PhysReg; - DEBUG(std::cerr << "Updating SS#" << StackSlot <<" in physreg " - << MRI->getName(PhysReg) << " for virtreg #" - << VirtReg << "\n"); + Spills.addAvailable(StackSlot, PhysReg); ++NumStores; } } From lattner at cs.uiuc.edu Fri Feb 3 17:28:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 17:28:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602032328.RAA16309@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.52 -> 1.53 --- Log message: Fix a nasty problem on two-address machines in the following situation: store EAX -> [ss#0] [ss#0] += 1 ... use(EAX) In this case, it is not valid to rewrite this as: store EAX -> [ss#0] EAX += 1 store EAX -> [ss#0] ;;; this would also delete the store above ... use(EAX) ... because EAX is not a dead at that point. Keep track of which registers we are allowed to clobber, and which ones we aren't, and don't clobber the ones we're not supposed to. :) This should resolve the issues on X86 last night. --- Diffs of the changes: (+27 -9) VirtRegMap.cpp | 36 +++++++++++++++++++++++++++--------- 1 files changed, 27 insertions(+), 9 deletions(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.52 llvm/lib/CodeGen/VirtRegMap.cpp:1.53 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.52 Fri Feb 3 17:13:58 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:28:46 2006 @@ -233,6 +233,14 @@ /// AvailableSpills - As the local spiller is scanning and rewriting an MBB from /// top down, keep track of which spills slots are available in each register. +/// +/// Note that not all physregs are created equal here. In particular, some +/// physregs are reloads that we are allowed to clobber or ignore at any time. +/// Other physregs are values that the register allocated program is using that +/// we cannot CHANGE, but we can read if we like. We keep track of this on a +/// per-stack-slot basis as the low bit in the value of the SpillSlotsAvailable +/// entries. The predicate 'canClobberPhysReg()' checks this bit and +/// addAvailable sets it if. class AvailableSpills { const MRegisterInfo *MRI; const TargetInstrInfo *TII; @@ -258,20 +266,28 @@ unsigned getSpillSlotPhysReg(int Slot) const { std::map::const_iterator I = SpillSlotsAvailable.find(Slot); if (I != SpillSlotsAvailable.end()) - return I->second; + return I->second >> 1; // Remove the CanClobber bit. return 0; } /// addAvailable - Mark that the specified stack slot is available in the - /// specified physreg. - void addAvailable(int Slot, unsigned Reg) { + /// specified physreg. If CanClobber is true, the physreg can be modified at + /// any time without changing the semantics of the program. + void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) { PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); - SpillSlotsAvailable[Slot] = Reg; + SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"); } + /// canClobberPhysReg - Return true if the spiller is allowed to change the + /// value of the specified stackslot register if it desires. The specified + /// stack slot must be available in a physreg for this query to make sense. + bool canClobberPhysReg(int Slot) const { + assert(SpillSlotsAvailable.count(Slot) && "Slot not available!"); + return SpillSlotsAvailable.find(Slot)->second & 1; + } /// ClobberPhysReg - This is called when the specified physreg changes /// value. We use this to invalidate any info about stuff we thing lives in @@ -292,7 +308,7 @@ while (I != PhysRegsAvailable.end() && I->first == PhysReg) { int Slot = I->second; PhysRegsAvailable.erase(I++); - assert(SpillSlotsAvailable[Slot] == PhysReg && + assert((SpillSlotsAvailable[Slot] >> 1) == PhysReg && "Bidirectional map mismatch!"); SpillSlotsAvailable.erase(Slot); DEBUG(std::cerr << "PhysReg " << MRI->getName(PhysReg) @@ -315,7 +331,7 @@ void AvailableSpills::ModifyStackSlot(int Slot) { std::map::iterator It = SpillSlotsAvailable.find(Slot); if (It == SpillSlotsAvailable.end()) return; - unsigned Reg = It->second; + unsigned Reg = It->second >> 1; SpillSlotsAvailable.erase(It); // This register may hold the value of multiple stack slots, only remove this @@ -435,7 +451,10 @@ unsigned PhysReg; // Check to see if this stack slot is available. - if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot))) { + if ((PhysReg = Spills.getSpillSlotPhysReg(StackSlot)) && + // Don't reuse it for a def&use operand if we aren't allowed to change + // the physreg! + (!MO.isDef() || Spills.canClobberPhysReg(StackSlot))) { // If this stack slot value is already available, reuse it! DEBUG(std::cerr << "Reusing SS#" << StackSlot << " from physreg " << MRI->getName(PhysReg) << " for vreg" @@ -613,7 +632,7 @@ // If the stack slot value was previously available in some other // register, change it now. Otherwise, make the register available, // in PhysReg. - Spills.addAvailable(StackSlot, SrcReg); + Spills.addAvailable(StackSlot, SrcReg, false /*don't clobber*/); } } } @@ -698,7 +717,6 @@ // in PhysReg. Spills.ModifyStackSlot(StackSlot); Spills.ClobberPhysReg(PhysReg); - Spills.addAvailable(StackSlot, PhysReg); ++NumStores; } From lattner at cs.uiuc.edu Fri Feb 3 17:50:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 17:50:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/VirtRegMap.cpp Message-ID: <200602032350.RAA23049@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.53 -> 1.54 --- Log message: Handle another case exposed on X86. --- Diffs of the changes: (+4 -0) VirtRegMap.cpp | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.53 llvm/lib/CodeGen/VirtRegMap.cpp:1.54 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.53 Fri Feb 3 17:28:46 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 17:50:46 2006 @@ -274,6 +274,10 @@ /// specified physreg. If CanClobber is true, the physreg can be modified at /// any time without changing the semantics of the program. void addAvailable(int Slot, unsigned Reg, bool CanClobber = true) { + // If this stack slot is thought to be available in some other physreg, + // remove its record. + ModifyStackSlot(Slot); + PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; From lattner at cs.uiuc.edu Fri Feb 3 20:12:21 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 20:12:21 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Target/TargetLowering.h Message-ID: <200602040212.UAA28714@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Target: TargetLowering.h updated: 1.46 -> 1.47 --- Log message: Add some methods for inline asm support. --- Diffs of the changes: (+16 -3) TargetLowering.h | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-) Index: llvm/include/llvm/Target/TargetLowering.h diff -u llvm/include/llvm/Target/TargetLowering.h:1.46 llvm/include/llvm/Target/TargetLowering.h:1.47 --- llvm/include/llvm/Target/TargetLowering.h:1.46 Fri Feb 3 16:24:05 2006 +++ llvm/include/llvm/Target/TargetLowering.h Fri Feb 3 20:12:09 2006 @@ -298,7 +298,7 @@ /// New, such that callers of SetBitsAreZero may call CombineTo on them if /// desired. bool DemandedBitsAreZero(const SDOperand &Op, uint64_t Mask, SDOperand &Old, - SDOperand &New, SelectionDAG &DAG); + SDOperand &New, SelectionDAG &DAG) const; //===--------------------------------------------------------------------===// // TargetLowering Configuration Methods - These methods should be invoked by @@ -442,13 +442,26 @@ // Inline Asm Support hooks // + enum ConstraintType { + C_RegisterClass, // Constraint represents one or more registers. + C_Other, // Something else. + C_Unknown // Unsupported constraint. + // INTEGER, ADDRESS, MEMORY? + }; + + /// getConstraintType - Given a constraint letter, return the type of + /// constraint it is for this target. + ConstraintType getConstraintType(char ConstraintLetter) const; + /// getRegForInlineAsmConstraint - Given a constraint letter or register /// name (e.g. "r" or "edx"), return a list of registers that can be used to - /// satisfy the constraint. If the constraint isn't supported, or isn't a - /// register constraint, return an empty list. + /// satisfy the constraint. This should only be used for physregs and + /// C_RegisterClass constraints. virtual std::vector getRegForInlineAsmConstraint(const std::string &Constraint) const; + virtual bool isOperandValidForConstraint(SDOperand Op, char ConstraintLetter); + //===--------------------------------------------------------------------===// // Scheduler hooks // From lattner at cs.uiuc.edu Fri Feb 3 20:13:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 20:13:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/TargetLowering.cpp Message-ID: <200602040213.UAA28802@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: TargetLowering.cpp updated: 1.28 -> 1.29 --- Log message: implementation of some methods for inlineasm --- Diffs of the changes: (+41 -1) TargetLowering.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 files changed, 41 insertions(+), 1 deletion(-) Index: llvm/lib/Target/TargetLowering.cpp diff -u llvm/lib/Target/TargetLowering.cpp:1.28 llvm/lib/Target/TargetLowering.cpp:1.29 --- llvm/lib/Target/TargetLowering.cpp:1.28 Fri Feb 3 16:38:07 2006 +++ llvm/lib/Target/TargetLowering.cpp Fri Feb 3 20:13:02 2006 @@ -131,6 +131,10 @@ return NULL; } +//===----------------------------------------------------------------------===// +// Optimization Methods +//===----------------------------------------------------------------------===// + /// DemandedBitsAreZero - Return true if 'Op & Mask' demands no bits from a bit /// set operation such as a sign extend or or/xor with constant whose only /// use is Op. If it returns true, the old node that sets bits which are @@ -139,7 +143,7 @@ /// desired. bool TargetLowering::DemandedBitsAreZero(const SDOperand &Op, uint64_t Mask, SDOperand &Old, SDOperand &New, - SelectionDAG &DAG) { + SelectionDAG &DAG) const { // If the operation has more than one use, we're not interested in it. // Tracking down and checking all uses would be problematic and slow. if (!Op.Val->hasOneUse()) @@ -302,6 +306,42 @@ return false; } +//===----------------------------------------------------------------------===// +// Inline Assembler Implementation Methods +//===----------------------------------------------------------------------===// + +TargetLowering::ConstraintType +TargetLowering::getConstraintType(char ConstraintLetter) const { + // FIXME: lots more standard ones to handle. + switch (ConstraintLetter) { + default: return C_Unknown; + case 'r': return C_RegisterClass; + case 'i': // Simple Integer or Relocatable Constant + case 'n': // Simple Integer + case 's': // Relocatable Constant + case 'I': // Target registers. + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': return C_Other; + } +} + +bool TargetLowering::isOperandValidForConstraint(SDOperand Op, + char ConstraintLetter) { + switch (ConstraintLetter) { + default: return false; + case 'i': // Simple Integer or Relocatable Constant + case 'n': // Simple Integer + case 's': // Relocatable Constant + return true; // FIXME: not right. + } +} + + std::vector TargetLowering:: getRegForInlineAsmConstraint(const std::string &Constraint) const { // Not a physreg, must not be a register reference or something. From lattner at cs.uiuc.edu Fri Feb 3 20:16:56 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 20:16:56 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200602040216.UAA28882@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAGISel.cpp updated: 1.147 -> 1.148 --- Log message: Initial early support for non-register operands, like immediates --- Diffs of the changes: (+42 -15) SelectionDAGISel.cpp | 57 +++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 42 insertions(+), 15 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.147 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.148 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.147 Fri Feb 3 14:13:59 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Feb 3 20:16:44 2006 @@ -1316,29 +1316,56 @@ OpNum++; // Consumes a call operand. unsigned SrcReg; + SDOperand ResOp; + unsigned ResOpType; + SDOperand InOperandVal = getValue(Operand); + if (isdigit(ConstraintCode[0])) { // Matching constraint? // If this is required to match an output register we have already set, // just use its register. unsigned OperandNo = atoi(ConstraintCode.c_str()); SrcReg = cast(AsmNodeOperands[OperandNo*2+2])->getReg(); + ResOp = DAG.getRegister(SrcReg, TLI.getValueType(OpTy)); + ResOpType = 1; + + Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); + Flag = Chain.getValue(1); } else { - // Copy the input into the appropriate register. - std::vector Regs = - TLI.getRegForInlineAsmConstraint(ConstraintCode); - if (Regs.size() == 1) - SrcReg = Regs[0]; - else - SrcReg = GetAvailableRegister(false, true, Regs, - OutputRegs, InputRegs); + TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass; + if (ConstraintCode.size() == 1) // not a physreg name. + CTy = TLI.getConstraintType(ConstraintCode[0]); + + switch (CTy) { + default: assert(0 && "Unknown constraint type! FAIL!"); + case TargetLowering::C_RegisterClass: { + // Copy the input into the appropriate register. + std::vector Regs = + TLI.getRegForInlineAsmConstraint(ConstraintCode); + if (Regs.size() == 1) + SrcReg = Regs[0]; + else + SrcReg = GetAvailableRegister(false, true, Regs, + OutputRegs, InputRegs); + // FIXME: should be match fail. + assert(SrcReg && "Wasn't able to allocate register!"); + Chain = DAG.getCopyToReg(Chain, SrcReg, InOperandVal, Flag); + Flag = Chain.getValue(1); + + ResOp = DAG.getRegister(SrcReg, TLI.getValueType(OpTy)); + ResOpType = 1; + break; + } + case TargetLowering::C_Other: + if (!TLI.isOperandValidForConstraint(InOperandVal, ConstraintCode[0])) + assert(0 && "MATCH FAIL!"); + ResOp = InOperandVal; + ResOpType = 3; + break; + } } - assert(SrcReg && "Couldn't allocate input reg!"); - - Chain = DAG.getCopyToReg(Chain, SrcReg, getValue(Operand), Flag); - Flag = Chain.getValue(1); - // Add information to the INLINEASM node to know that this register is - // read. - AsmNodeOperands.push_back(DAG.getRegister(SrcReg,TLI.getValueType(OpTy))); + // Add information to the INLINEASM node to know about this input. + AsmNodeOperands.push_back(ResOp); AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE break; } From evan.cheng at apple.com Fri Feb 3 20:20:43 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Feb 2006 20:20:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td Message-ID: <200602040220.UAA28921@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelLowering.cpp updated: 1.77 -> 1.78 X86ISelLowering.h updated: 1.24 -> 1.25 X86InstrInfo.td updated: 1.228 -> 1.229 --- Log message: Separate FILD and FILD_FLAG, the later is only used for SSE2. It produces a flag so it can be flagged to a FST. --- Diffs of the changes: (+15 -8) X86ISelLowering.cpp | 8 +++++--- X86ISelLowering.h | 10 ++++++---- X86InstrInfo.td | 5 ++++- 3 files changed, 15 insertions(+), 8 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.77 llvm/lib/Target/X86/X86ISelLowering.cpp:1.78 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.77 Wed Feb 1 18:28:23 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Feb 3 20:20:30 2006 @@ -1476,18 +1476,19 @@ std::vector Tys; Tys.push_back(MVT::f64); Tys.push_back(MVT::Other); - Tys.push_back(MVT::Flag); + if (X86ScalarSSE) Tys.push_back(MVT::Flag); std::vector Ops; Ops.push_back(Chain); Ops.push_back(StackSlot); Ops.push_back(DAG.getValueType(SrcVT)); - Result = DAG.getNode(X86ISD::FILD, Tys, Ops); + Result = DAG.getNode(X86ScalarSSE ? X86ISD::FILD_FLAG :X86ISD::FILD, + Tys, Ops); if (X86ScalarSSE) { Chain = Result.getValue(1); SDOperand InFlag = Result.getValue(2); - // FIXME: Currently the FST is flagged to the FILD. This + // FIXME: Currently the FST is flagged to the FILD_FLAG. This // shouldn't be necessary except that RFP cannot be live across // multiple blocks. When stackifier is fixed, they can be uncoupled. MachineFunction &MF = DAG.getMachineFunction(); @@ -1974,6 +1975,7 @@ case X86ISD::FAND: return "X86ISD::FAND"; case X86ISD::FXOR: return "X86ISD::FXOR"; case X86ISD::FILD: return "X86ISD::FILD"; + case X86ISD::FILD_FLAG: return "X86ISD::FILD_FLAG"; case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM"; case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM"; case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM"; Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.24 llvm/lib/Target/X86/X86ISelLowering.h:1.25 --- llvm/lib/Target/X86/X86ISelLowering.h:1.24 Tue Jan 31 16:28:30 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Fri Feb 3 20:20:30 2006 @@ -49,11 +49,13 @@ /// to X86::XORPS or X86::XORPD. FXOR, - /// FILD - This instruction implements SINT_TO_FP with the integer source - /// in memory and FP reg result. This corresponds to the X86::FILD*m - /// instructions. It has three inputs (token chain, address, and source - /// type) and three outputs (FP value, token chain, and a flag). + /// FILD, FILD_FLAG - This instruction implements SINT_TO_FP with the + /// integer source in memory and FP reg result. This corresponds to the + /// X86::FILD*m instructions. It has three inputs (token chain, address, + /// and source type) and two outputs (FP value and token chain). FILD_FLAG + /// also produces a flag). FILD, + FILD_FLAG, /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the /// integer destination in memory and a FP reg source. This corresponds Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.228 llvm/lib/Target/X86/X86InstrInfo.td:1.229 --- llvm/lib/Target/X86/X86InstrInfo.td:1.228 Wed Feb 1 17:01:57 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Feb 3 20:20:30 2006 @@ -108,6 +108,8 @@ def X86fst : SDNode<"X86ISD::FST", SDTX86Fst, [SDNPHasChain, SDNPInFlag]>; def X86fild : SDNode<"X86ISD::FILD", SDTX86Fild, + [SDNPHasChain]>; +def X86fildflag: SDNode<"X86ISD::FILD_FLAG",SDTX86Fild, [SDNPHasChain, SDNPOutFlag]>; def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem, [SDNPHasChain]>; @@ -3121,7 +3123,8 @@ def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; // Used to conv. i64 to f64 since there isn't a SSE version. -def : Pat<(X86fild addr:$src, i64), (FpILD64m addr:$src)>, Requires<[HasSSE2]>; +def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>, + Requires<[HasSSE2]>; //===----------------------------------------------------------------------===// // Some peepholes From evan.cheng at apple.com Fri Feb 3 20:23:13 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 3 Feb 2006 20:23:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86InstrInfo.td Message-ID: <200602040223.UAA28935@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86InstrInfo.td updated: 1.229 -> 1.230 --- Log message: Remove an unnecessary predicate. --- Diffs of the changes: (+1 -2) X86InstrInfo.td | 3 +-- 1 files changed, 1 insertion(+), 2 deletions(-) Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.229 llvm/lib/Target/X86/X86InstrInfo.td:1.230 --- llvm/lib/Target/X86/X86InstrInfo.td:1.229 Fri Feb 3 20:20:30 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Fri Feb 3 20:23:01 2006 @@ -3123,8 +3123,7 @@ def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>; // Used to conv. i64 to f64 since there isn't a SSE version. -def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>, - Requires<[HasSSE2]>; +def : Pat<(X86fildflag addr:$src, i64), (FpILD64m addr:$src)>; //===----------------------------------------------------------------------===// // Some peepholes From lattner at cs.uiuc.edu Fri Feb 3 20:26:25 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 20:26:25 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200602040226.UAA29008@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.62 -> 1.63 SelectionDAGISel.cpp updated: 1.148 -> 1.149 --- Log message: Add initial support for immediates. This allows us to compile this: int %rlwnm(int %A, int %B) { %C = call int asm "rlwnm $0, $1, $2, $3, $4", "=r,r,r,n,n"(int %A, int %B, int 4, int 17) ret int %C } into: _rlwnm: or r2, r3, r3 or r3, r4, r4 rlwnm r2, r2, r3, 4, 17 ;; note the immediates :) or r3, r2, r2 blr --- Diffs of the changes: (+16 -6) ScheduleDAG.cpp | 20 +++++++++++++++----- SelectionDAGISel.cpp | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.62 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.63 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.62 Tue Jan 31 16:23:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Fri Feb 3 20:26:14 2006 @@ -300,16 +300,26 @@ // Add all of the operand registers to the instruction. for (unsigned i = 2; i != NumOps; i += 2) { - unsigned Reg = cast(Node->getOperand(i))->getReg(); unsigned Flags =cast(Node->getOperand(i+1))->getValue(); MachineOperand::UseType UseTy; switch (Flags) { default: assert(0 && "Bad flags!"); - case 1: UseTy = MachineOperand::Use; break; - case 2: UseTy = MachineOperand::Def; break; - case 3: UseTy = MachineOperand::UseAndDef; break; + case 1: { // Use of register. + unsigned Reg = cast(Node->getOperand(i))->getReg(); + MI->addMachineRegOperand(Reg, MachineOperand::Use); + break; + } + case 2: { // Def of register. + unsigned Reg = cast(Node->getOperand(i))->getReg(); + MI->addMachineRegOperand(Reg, MachineOperand::Def); + break; + } + case 3: { // Immediate. + uint64_t Val = cast(Node->getOperand(i))->getValue(); + MI->addZeroExtImm64Operand(Val); + break; + } } - MI->addMachineRegOperand(Reg, UseTy); } break; } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.148 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.149 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.148 Fri Feb 3 20:16:44 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Feb 3 20:26:14 2006 @@ -1366,7 +1366,7 @@ // Add information to the INLINEASM node to know about this input. AsmNodeOperands.push_back(ResOp); - AsmNodeOperands.push_back(DAG.getConstant(1, MVT::i32)); // ISUSE + AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32)); break; } case InlineAsm::isClobber: From jeffc at jolt-lang.org Fri Feb 3 21:27:15 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Fri, 3 Feb 2006 21:27:15 -0600 Subject: [llvm-commits] CVS: llvm/win32/x86/x86.vcproj Message-ID: <200602040327.VAA29911@zion.cs.uiuc.edu> Changes in directory llvm/win32/x86: x86.vcproj updated: 1.19 -> 1.20 --- Log message: Keep Visual Studio informed. --- Diffs of the changes: (+4 -5) x86.vcproj | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) Index: llvm/win32/x86/x86.vcproj diff -u llvm/win32/x86/x86.vcproj:1.19 llvm/win32/x86/x86.vcproj:1.20 --- llvm/win32/x86/x86.vcproj:1.19 Sun Jan 29 22:07:08 2006 +++ llvm/win32/x86/x86.vcproj Fri Feb 3 21:27:04 2006 @@ -124,7 +124,8 @@ ..\$(IntDir)\TableGen.exe -gen-asm-writer -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -asmwriternum=1 -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter1.inc ..\$(IntDir)\TableGen.exe -gen-dag-isel -I ..\..\lib\Target\X86 $(InputPath) -o X86GenDAGISel.inc -..\$(IntDir)\TableGen.exe -gen-subtarget -I ..\..\lib\Target\X86 $(InputPath) -o X86GenSubtarget.inc" +..\$(IntDir)\TableGen.exe -gen-subtarget -I ..\..\lib\Target\X86 $(InputPath) -o X86GenSubtarget.inc +" AdditionalDependencies="$(InputDir)X86InstrInfo.td;$(InputDir)X86RegisterInfo.td;$(InputDir)..\Target.td;$(ProjectDir)..\$(IntDir)\TableGen.exe" Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc;X86GenDAGISel.inc;X86GenSubtarget.inc"/> @@ -141,7 +142,8 @@ ..\$(IntDir)\TableGen.exe -gen-asm-writer -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter.inc ..\$(IntDir)\TableGen.exe -gen-asm-writer -asmwriternum=1 -I ..\..\lib\Target\X86 $(InputPath) -o X86GenAsmWriter1.inc ..\$(IntDir)\TableGen.exe -gen-dag-isel -I ..\..\lib\Target\X86 $(InputPath) -o X86GenDAGISel.inc -..\$(IntDir)\TableGen.exe -gen-subtarget -I ..\..\lib\Target\X86 $(InputPath) -o X86GenSubtarget.inc" +..\$(IntDir)\TableGen.exe -gen-subtarget -I ..\..\lib\Target\X86 $(InputPath) -o X86GenSubtarget.inc +" AdditionalDependencies="$(InputDir)X86InstrInfo.td;$(InputDir)X86RegisterInfo.td;$(InputDir)..\Target.td;$(ProjectDir)..\$(IntDir)\TableGen.exe" Outputs="X86GenRegisterNames.inc;X86GenRegisterInfo.h.inc;X86GenRegisterInfo.inc;X86GenInstrNames.inc;X86GenInstrInfo.inc;X86GenAsmWriter.inc;X86GenAsmWriter1.inc;X86GenDAGISel.inc;X86GenSubtarget.inc"/> @@ -180,9 +182,6 @@ RelativePath="..\..\lib\Target\X86\X86JITInfo.cpp"> - - Changes in directory llvm/lib/CodeGen: VirtRegMap.cpp updated: 1.54 -> 1.55 --- Log message: Fix VC++ warning. --- Diffs of the changes: (+1 -1) VirtRegMap.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/CodeGen/VirtRegMap.cpp diff -u llvm/lib/CodeGen/VirtRegMap.cpp:1.54 llvm/lib/CodeGen/VirtRegMap.cpp:1.55 --- llvm/lib/CodeGen/VirtRegMap.cpp:1.54 Fri Feb 3 17:50:46 2006 +++ llvm/lib/CodeGen/VirtRegMap.cpp Fri Feb 3 21:27:39 2006 @@ -279,7 +279,7 @@ ModifyStackSlot(Slot); PhysRegsAvailable.insert(std::make_pair(Reg, Slot)); - SpillSlotsAvailable[Slot] = (Reg << 1) | CanClobber; + SpillSlotsAvailable[Slot] = (Reg << 1) | (unsigned)CanClobber; DEBUG(std::cerr << "Remembering SS#" << Slot << " in physreg " << MRI->getName(Reg) << "\n"); From lattner at cs.uiuc.edu Fri Feb 3 23:49:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri, 3 Feb 2006 23:49:14 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h Message-ID: <200602040549.XAA30618@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ScalarEvolutionExpander.h updated: 1.2 -> 1.3 --- Log message: add a method --- Diffs of the changes: (+2 -0) ScalarEvolutionExpander.h | 2 ++ 1 files changed, 2 insertions(+) Index: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h diff -u llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.2 llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.3 --- llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.2 Sat Jul 30 13:33:25 2005 +++ llvm/include/llvm/Analysis/ScalarEvolutionExpander.h Fri Feb 3 23:49:01 2006 @@ -41,6 +41,8 @@ public: SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {} + LoopInfo &getLoopInfo() const { return LI; } + /// clear - Erase the contents of the InsertedExpressions map so that users /// trying to expand the same expression into multiple BasicBlocks or /// different places within the same BasicBlock can do so. From evan.cheng at apple.com Sat Feb 4 00:49:11 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 00:49:11 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/ScheduleDAG.h Message-ID: <200602040649.AAA30836@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: ScheduleDAG.h updated: 1.7 -> 1.8 --- Log message: Get rid of some memory leaks identified by Valgrind --- Diffs of the changes: (+19 -4) ScheduleDAG.h | 23 +++++++++++++++++++---- 1 files changed, 19 insertions(+), 4 deletions(-) Index: llvm/include/llvm/CodeGen/ScheduleDAG.h diff -u llvm/include/llvm/CodeGen/ScheduleDAG.h:1.7 llvm/include/llvm/CodeGen/ScheduleDAG.h:1.8 --- llvm/include/llvm/CodeGen/ScheduleDAG.h:1.7 Wed Jan 25 18:28:35 2006 +++ llvm/include/llvm/CodeGen/ScheduleDAG.h Sat Feb 4 00:49:00 2006 @@ -50,6 +50,8 @@ /// Node group - This struct is used to manage flagged node groups. /// class NodeGroup { + public: + NodeGroup *Next; private: NIVector Members; // Group member nodes NodeInfo *Dominator; // Node with highest latency @@ -59,7 +61,7 @@ public: // Ctor. - NodeGroup() : Dominator(NULL), Pending(0) {} + NodeGroup() : Next(NULL), Dominator(NULL), Pending(0) {} // Accessors inline void setDominator(NodeInfo *D) { Dominator = D; } @@ -256,13 +258,24 @@ bool HasGroups; // True if there are any groups NodeInfo *Info; // Info for nodes being scheduled NIVector Ordering; // Emit ordering of nodes + NodeGroup *HeadNG, *TailNG; // Keep track of allocated NodeGroups ScheduleDAG(SchedHeuristics hstc, SelectionDAG &dag, MachineBasicBlock *bb, const TargetMachine &tm) - : Heuristic(hstc), DAG(dag), BB(bb), TM(tm), - NodeCount(0), HasGroups(false), Info(NULL) {} + : Heuristic(hstc), DAG(dag), BB(bb), TM(tm), NodeCount(0), + HasGroups(false), Info(NULL), HeadNG(NULL), TailNG(NULL) {} - virtual ~ScheduleDAG() {}; + virtual ~ScheduleDAG() { + if (Info) + delete[] Info; + + NodeGroup *NG = HeadNG; + while (NG) { + NodeGroup *NextSU = NG->Next; + delete NG; + NG = NextSU; + } + }; /// Run - perform scheduling. /// @@ -329,6 +342,8 @@ /// IdentifyGroups - Put flagged nodes into groups. /// void IdentifyGroups(); + + void AddToGroup(NodeInfo *D, NodeInfo *U); }; /// createSimpleDAGScheduler - This creates a simple two pass instruction From evan.cheng at apple.com Sat Feb 4 00:49:12 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 00:49:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp SelectionDAGISel.cpp Message-ID: <200602040649.AAA30842@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.63 -> 1.64 SelectionDAGISel.cpp updated: 1.149 -> 1.150 --- Log message: Get rid of some memory leaks identified by Valgrind --- Diffs of the changes: (+9 -2) ScheduleDAG.cpp | 10 ++++++++-- SelectionDAGISel.cpp | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.63 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.64 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.63 Fri Feb 3 20:26:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sat Feb 4 00:49:00 2006 @@ -85,7 +85,7 @@ // No more flags to walk if (Op.getValueType() != MVT::Flag) break; // Add to node group - NodeGroup::Add(getNI(Op.Val), NI); + AddToGroup(getNI(Op.Val), NI); // Let everyone else know HasGroups = true; } @@ -479,7 +479,7 @@ //===----------------------------------------------------------------------===// /// Add - Adds a definer and user pair to a node group. /// -void NodeGroup::Add(NodeInfo *D, NodeInfo *U) { +void ScheduleDAG::AddToGroup(NodeInfo *D, NodeInfo *U) { // Get current groups NodeGroup *DGroup = D->Group; NodeGroup *UGroup = U->Group; @@ -534,5 +534,11 @@ CountInternalUses(D, U)); DGroup->group_push_back(D); DGroup->group_push_back(U); + + if (HeadNG == NULL) + HeadNG = DGroup; + if (TailNG != NULL) + TailNG->Next = DGroup; + TailNG = DGroup; } } Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.149 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.150 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.149 Fri Feb 3 20:26:14 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Feb 4 00:49:00 2006 @@ -1998,4 +1998,5 @@ SL = createBURRListDAGScheduler(DAG, BB); } BB = SL->Run(); + delete SL; } From lattner at cs.uiuc.edu Sat Feb 4 00:58:58 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 00:58:58 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp SparcV8InstrInfo.h SparcV8RegisterInfo.cpp SparcV8RegisterInfo.h SparcV8TargetMachine.cpp Message-ID: <200602040658.AAA30956@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.cpp updated: 1.10 -> 1.11 SparcV8InstrInfo.h updated: 1.6 -> 1.7 SparcV8RegisterInfo.cpp updated: 1.34 -> 1.35 SparcV8RegisterInfo.h updated: 1.7 -> 1.8 SparcV8TargetMachine.cpp updated: 1.38 -> 1.39 --- Log message: Two changes: 1. Treat FMOVD as a copy instruction, to help with coallescing in V9 mode 2. When in V9 mode, insert FMOVD instead of FpMOVD instructions, as we don't ever rewrite FpMOVD instructions into FMOVS instructions, thus we just end up with commented out copies! This should fix a bunch of failures in V9 mode on sparc. --- Diffs of the changes: (+24 -17) SparcV8InstrInfo.cpp | 23 ++++++++++++----------- SparcV8InstrInfo.h | 2 +- SparcV8RegisterInfo.cpp | 9 ++++++--- SparcV8RegisterInfo.h | 5 ++++- SparcV8TargetMachine.cpp | 2 +- 5 files changed, 24 insertions(+), 17 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.10 llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.11 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.10 Fri Feb 3 00:44:54 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp Sat Feb 4 00:58:46 2006 @@ -17,12 +17,13 @@ #include "SparcV8GenInstrInfo.inc" using namespace llvm; -SparcV8InstrInfo::SparcV8InstrInfo() - : TargetInstrInfo(SparcV8Insts, sizeof(SparcV8Insts)/sizeof(SparcV8Insts[0])){ +SparcV8InstrInfo::SparcV8InstrInfo(SparcV8Subtarget &ST) + : TargetInstrInfo(SparcV8Insts, sizeof(SparcV8Insts)/sizeof(SparcV8Insts[0])), + RI(ST) { } -static bool isZeroImmed (const MachineOperand &op) { - return (op.isImmediate() && op.getImmedValue() == 0); +static bool isZeroImm(const MachineOperand &op) { + return op.isImmediate() && op.getImmedValue() == 0; } /// Return true if the instruction is a register to register move and @@ -44,13 +45,13 @@ SrcReg = MI.getOperand(1).getReg(); return true; } - } else if (MI.getOpcode() == V8::ORri || MI.getOpcode() == V8::ADDri) { - if (isZeroImmed(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { - DstReg = MI.getOperand(0).getReg(); - SrcReg = MI.getOperand(1).getReg(); - return true; - } - } else if (MI.getOpcode() == V8::FMOVS || MI.getOpcode() == V8::FpMOVD) { + } else if (MI.getOpcode() == V8::ORri || MI.getOpcode() == V8::ADDri && + isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { + DstReg = MI.getOperand(0).getReg(); + SrcReg = MI.getOperand(1).getReg(); + return true; + } else if (MI.getOpcode() == V8::FMOVS || MI.getOpcode() == V8::FpMOVD || + MI.getOpcode() == V8::FMOVD) { SrcReg = MI.getOperand(1).getReg(); DstReg = MI.getOperand(0).getReg(); return true; Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.h diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.6 llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.7 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.h:1.6 Fri Feb 3 00:44:54 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.h Sat Feb 4 00:58:46 2006 @@ -34,7 +34,7 @@ class SparcV8InstrInfo : public TargetInstrInfo { const SparcV8RegisterInfo RI; public: - SparcV8InstrInfo(); + SparcV8InstrInfo(SparcV8Subtarget &ST); /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.34 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.35 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.34 Fri Feb 3 01:06:25 2006 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Sat Feb 4 00:58:46 2006 @@ -13,6 +13,7 @@ #include "SparcV8.h" #include "SparcV8RegisterInfo.h" +#include "SparcV8Subtarget.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -21,9 +22,10 @@ #include using namespace llvm; -SparcV8RegisterInfo::SparcV8RegisterInfo() +SparcV8RegisterInfo::SparcV8RegisterInfo(SparcV8Subtarget &st) : SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN, - V8::ADJCALLSTACKUP) {} + V8::ADJCALLSTACKUP), Subtarget(st) { +} void SparcV8RegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, @@ -63,7 +65,8 @@ else if (RC == V8::FPRegsRegisterClass) BuildMI(MBB, I, V8::FMOVS, 1, DestReg).addReg(SrcReg); else if (RC == V8::DFPRegsRegisterClass) - BuildMI(MBB, I, V8::FpMOVD, 1, DestReg).addReg(SrcReg); + BuildMI(MBB, I, Subtarget.isV9() ? V8::FMOVD : V8::FpMOVD, + 1, DestReg).addReg(SrcReg); else assert (0 && "Can't copy this register"); } Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.7 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.8 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h:1.7 Fri Feb 3 01:06:25 2006 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.h Sat Feb 4 00:58:46 2006 @@ -19,10 +19,13 @@ namespace llvm { +class SparcV8Subtarget; class Type; struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo { - SparcV8RegisterInfo(); + SparcV8Subtarget &Subtarget; + + SparcV8RegisterInfo(SparcV8Subtarget &st); /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, Index: llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp diff -u llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.38 llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.39 --- llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp:1.38 Thu Jan 26 00:51:21 2006 +++ llvm/lib/Target/SparcV8/SparcV8TargetMachine.cpp Sat Feb 4 00:58:46 2006 @@ -35,7 +35,7 @@ IntrinsicLowering *IL, const std::string &FS) : TargetMachine("SparcV8", IL, false, 4, 4), - Subtarget(M, FS), + Subtarget(M, FS), InstrInfo(Subtarget), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { } From lattner at cs.uiuc.edu Sat Feb 4 01:07:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 01:07:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/README.txt Message-ID: <200602040707.BAA31039@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: README.txt updated: 1.48 -> 1.49 --- Log message: add a note --- Diffs of the changes: (+1 -0) README.txt | 1 + 1 files changed, 1 insertion(+) Index: llvm/lib/Target/SparcV8/README.txt diff -u llvm/lib/Target/SparcV8/README.txt:1.48 llvm/lib/Target/SparcV8/README.txt:1.49 --- llvm/lib/Target/SparcV8/README.txt:1.48 Tue Jan 31 01:45:45 2006 +++ llvm/lib/Target/SparcV8/README.txt Sat Feb 4 01:07:31 2006 @@ -2,6 +2,7 @@ To-do ----- +* Enable LSR for V8. * Keep the address of the constant pool in a register instead of forming its address all of the time. * We can fold small constant offsets into the %hi/%lo references to constant From natebegeman at mac.com Sat Feb 4 01:29:46 2006 From: natebegeman at mac.com (Nate Begeman) Date: Sat, 4 Feb 2006 01:29:46 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602040729.BAA31182@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.60 -> 1.61 --- Log message: Remove some stuff that now works --- Diffs of the changes: (+0 -53) README.txt | 53 ----------------------------------------------------- 1 files changed, 53 deletions(-) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.60 llvm/lib/Target/PowerPC/README.txt:1.61 --- llvm/lib/Target/PowerPC/README.txt:1.60 Fri Feb 3 16:06:45 2006 +++ llvm/lib/Target/PowerPC/README.txt Sat Feb 4 01:29:35 2006 @@ -198,59 +198,6 @@ ===-------------------------------------------------------------------------=== -176.gcc contains a bunch of code like this (this occurs dozens of times): - -int %test(uint %mode.0.i.0) { - %tmp.79 = cast uint %mode.0.i.0 to sbyte ; [#uses=1] - %tmp.80 = cast sbyte %tmp.79 to int ; [#uses=1] - %tmp.81 = shl int %tmp.80, ubyte 16 ; [#uses=1] - %tmp.82 = and int %tmp.81, 16711680 - ret int %tmp.82 -} - -which we compile to: - -_test: - extsb r2, r3 - rlwinm r3, r2, 16, 8, 15 - blr - -The extsb is obviously dead. This can be handled by a future thing like -MaskedValueIsZero that checks to see if bits are ever demanded (in this case, -the sign bits are never used, so we can fold the sext_inreg to nothing). - -I'm seeing code like this: - - srwi r3, r3, 16 - extsb r3, r3 - rlwimi r4, r3, 16, 8, 15 - -in which the extsb is preventing the srwi from being nuked. - -===-------------------------------------------------------------------------=== - -Another example that occurs is: - -uint %test(int %specbits.6.1) { - %tmp.2540 = shr int %specbits.6.1, ubyte 11 ; [#uses=1] - %tmp.2541 = cast int %tmp.2540 to uint ; [#uses=1] - %tmp.2542 = shl uint %tmp.2541, ubyte 13 ; [#uses=1] - %tmp.2543 = and uint %tmp.2542, 8192 ; [#uses=1] - ret uint %tmp.2543 -} - -which we codegen as: - -l1_test: - srawi r2, r3, 11 - rlwinm r3, r2, 13, 18, 18 - blr - -the srawi can be nuked by turning the SAR into a logical SHR (the sext bits are -dead), which I think can then be folded into the rlwinm. - -===-------------------------------------------------------------------------=== - Compile offsets from allocas: int *%test() { From lattner at cs.uiuc.edu Sat Feb 4 01:37:02 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 01:37:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200602040737.BAA31338@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.73 -> 1.74 --- Log message: Fix two significant bugs in LSR: 1. When rewriting code in outer loops, sometimes we would insert code into inner loops that is invariant in that loop. 2. Notice that 4*(2+x) is 8+4*x and use that to simplify expressions. This is a performance neutral change. --- Diffs of the changes: (+75 -14) LoopStrengthReduce.cpp | 89 +++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 75 insertions(+), 14 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.73 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.74 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.73 Sun Jan 22 17:32:06 2006 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sat Feb 4 01:36:50 2006 @@ -477,6 +477,10 @@ void RewriteInstructionToUseNewBase(const SCEVHandle &NewBase, SCEVExpander &Rewriter, Loop *L, Pass *P); + + Value *InsertCodeForBaseAtPosition(const SCEVHandle &NewBase, + SCEVExpander &Rewriter, + Instruction *IP, Loop *L); void dump() const; }; } @@ -490,6 +494,41 @@ std::cerr << " Inst: " << *Inst; } +Value *BasedUser::InsertCodeForBaseAtPosition(const SCEVHandle &NewBase, + SCEVExpander &Rewriter, + Instruction *IP, Loop *L) { + // Figure out where we *really* want to insert this code. In particular, if + // the user is inside of a loop that is nested inside of L, we really don't + // want to insert this expression before the user, we'd rather pull it out as + // many loops as possible. + LoopInfo &LI = Rewriter.getLoopInfo(); + Instruction *BaseInsertPt = IP; + + // Figure out the most-nested loop that IP is in. + Loop *InsertLoop = LI.getLoopFor(IP->getParent()); + + // If InsertLoop is not L, and InsertLoop is nested inside of L, figure out + // the preheader of the outer-most loop where NewBase is not loop invariant. + while (InsertLoop && NewBase->isLoopInvariant(InsertLoop)) { + BaseInsertPt = InsertLoop->getLoopPreheader()->getTerminator(); + InsertLoop = InsertLoop->getParentLoop(); + } + + // If there is no immediate value, skip the next part. + if (SCEVConstant *SC = dyn_cast(Imm)) + if (SC->getValue()->isNullValue()) + return Rewriter.expandCodeFor(NewBase, BaseInsertPt, + OperandValToReplace->getType()); + + Value *Base = Rewriter.expandCodeFor(NewBase, BaseInsertPt); + + // Always emit the immediate (if non-zero) into the same block as the user. + SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(Base), Imm); + return Rewriter.expandCodeFor(NewValSCEV, IP, + OperandValToReplace->getType()); +} + + // Once we rewrite the code to insert the new IVs we want, update the // operands of Inst to use the new expression 'NewBase', with 'Imm' added // to it. @@ -497,9 +536,7 @@ SCEVExpander &Rewriter, Loop *L, Pass *P) { if (!isa(Inst)) { - SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm); - Value *NewVal = Rewriter.expandCodeFor(NewValSCEV, Inst, - OperandValToReplace->getType()); + Value *NewVal = InsertCodeForBaseAtPosition(NewBase, Rewriter, Inst, L); // Replace the use of the operand Value with the new Phi we just created. Inst->replaceUsesOfWith(OperandValToReplace, NewVal); DEBUG(std::cerr << " CHANGED: IMM =" << *Imm << " Inst = " << *Inst); @@ -539,11 +576,8 @@ Value *&Code = InsertedCode[PN->getIncomingBlock(i)]; if (!Code) { // Insert the code into the end of the predecessor block. - BasicBlock::iterator InsertPt =PN->getIncomingBlock(i)->getTerminator(); - - SCEVHandle NewValSCEV = SCEVAddExpr::get(NewBase, Imm); - Code = Rewriter.expandCodeFor(NewValSCEV, InsertPt, - OperandValToReplace->getType()); + Instruction *InsertPt = PN->getIncomingBlock(i)->getTerminator(); + Code = InsertCodeForBaseAtPosition(NewBase, Rewriter, InsertPt, L); } // Replace the use of the operand Value with the new Phi we just created. @@ -627,16 +661,18 @@ std::vector NewOps; NewOps.reserve(SAE->getNumOperands()); - for (unsigned i = 0; i != SAE->getNumOperands(); ++i) - if (isAddress && isTargetConstant(SAE->getOperand(i))) { - Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i)); - } else if (!SAE->getOperand(i)->isLoopInvariant(L)) { + for (unsigned i = 0; i != SAE->getNumOperands(); ++i) { + SCEVHandle NewOp = SAE->getOperand(i); + MoveImmediateValues(NewOp, Imm, isAddress, L); + + if (!NewOp->isLoopInvariant(L)) { // If this is a loop-variant expression, it must stay in the immediate // field of the expression. - Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i)); + Imm = SCEVAddExpr::get(Imm, NewOp); } else { - NewOps.push_back(SAE->getOperand(i)); + NewOps.push_back(NewOp); } + } if (NewOps.empty()) Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); @@ -654,6 +690,31 @@ Val = SCEVAddRecExpr::get(Ops, SARE->getLoop()); } return; + } else if (SCEVMulExpr *SME = dyn_cast(Val)) { + // Transform "8 * (4 + v)" -> "32 + 8*V" if "32" fits in the immed field. + if (isAddress && isTargetConstant(SME->getOperand(0)) && + SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) { + + SCEVHandle SubImm = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + SCEVHandle NewOp = SME->getOperand(1); + MoveImmediateValues(NewOp, SubImm, isAddress, L); + + // If we extracted something out of the subexpressions, see if we can + // simplify this! + if (NewOp != SME->getOperand(1)) { + // Scale SubImm up by "8". If the result is a target constant, we are + // good. + SubImm = SCEVMulExpr::get(SubImm, SME->getOperand(0)); + if (isTargetConstant(SubImm)) { + // Accumulate the immediate. + Imm = SCEVAddExpr::get(Imm, SubImm); + + // Update what is left of 'Val'. + Val = SCEVMulExpr::get(SME->getOperand(0), NewOp); + return; + } + } + } } // Loop-variant expressions must stay in the immediate field of the From lattner at cs.uiuc.edu Sat Feb 4 01:48:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 01:48:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp Message-ID: <200602040748.BAA31402@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8InstrInfo.cpp updated: 1.11 -> 1.12 --- Log message: fix a bug in my last checkin --- Diffs of the changes: (+2 -2) SparcV8InstrInfo.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.11 llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.12 --- llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp:1.11 Sat Feb 4 00:58:46 2006 +++ llvm/lib/Target/SparcV8/SparcV8InstrInfo.cpp Sat Feb 4 01:48:46 2006 @@ -40,12 +40,12 @@ DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(2).getReg(); return true; - } else if (MI.getOperand (2).getReg() == V8::G0) { + } else if (MI.getOperand(2).getReg() == V8::G0) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(1).getReg(); return true; } - } else if (MI.getOpcode() == V8::ORri || MI.getOpcode() == V8::ADDri && + } else if ((MI.getOpcode() == V8::ORri || MI.getOpcode() == V8::ADDri) && isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(1).getReg(); From lattner at cs.uiuc.edu Sat Feb 4 02:04:33 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 02:04:33 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Message-ID: <200602040804.CAA31591@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8RegisterInfo.cpp updated: 1.35 -> 1.36 --- Log message: Fix a nasty typo that broke functions with big stack frames. --- Diffs of the changes: (+1 -1) SparcV8RegisterInfo.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.35 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.36 --- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.35 Sat Feb 4 00:58:46 2006 +++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp Sat Feb 4 02:04:21 2006 @@ -145,7 +145,7 @@ BuildMI(*MI.getParent(), II, V8::ADDrr, 2, V8::G1).addReg(V8::G1).addReg(V8::I6); // Insert: G1+%lo(offset) into the user. - MI.SetMachineOperandReg(i, V8::I1); + MI.SetMachineOperandReg(i, V8::G1); MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed, Offset & ((1 << 10)-1)); } From lattner at cs.uiuc.edu Sat Feb 4 02:31:43 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 02:31:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Message-ID: <200602040831.CAA07135@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: SparcV8ISelDAGToDAG.cpp updated: 1.75 -> 1.76 --- Log message: Custom lower VAARG for the case when we are doing vaarg(double). In this case, the double being loaded may not be 8-byte aligned, so we have to use our standard bit_convert game. --- Diffs of the changes: (+35 -3) SparcV8ISelDAGToDAG.cpp | 38 +++++++++++++++++++++++++++++++++++--- 1 files changed, 35 insertions(+), 3 deletions(-) Index: llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp diff -u llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.75 llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.76 --- llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp:1.75 Tue Jan 31 16:21:34 2006 +++ llvm/lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp Sat Feb 4 02:31:30 2006 @@ -203,11 +203,12 @@ // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); - // VASTART needs to be custom lowered to use the VarArgsFrameIndex + // VASTART needs to be custom lowered to use the VarArgsFrameIndex. setOperationAction(ISD::VASTART , MVT::Other, Custom); + // VAARG needs to be lowered to not do unaligned accesses for doubles. + setOperationAction(ISD::VAARG , MVT::Other, Custom); // Use the default implementation. - setOperationAction(ISD::VAARG , MVT::Other, Expand); setOperationAction(ISD::VACOPY , MVT::Other, Expand); setOperationAction(ISD::VAEND , MVT::Other, Expand); setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); @@ -778,10 +779,41 @@ // memory location argument. SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, DAG.getRegister(V8::I6, MVT::i32), - DAG.getConstant(VarArgsFrameOffset, MVT::i32)); + DAG.getConstant(VarArgsFrameOffset, MVT::i32)); return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, Op.getOperand(1), Op.getOperand(2)); } + case ISD::VAARG: { + SDNode *Node = Op.Val; + MVT::ValueType VT = Node->getValueType(0); + SDOperand InChain = Node->getOperand(0); + SDOperand VAListPtr = Node->getOperand(1); + SDOperand VAList = DAG.getLoad(getPointerTy(), InChain, VAListPtr, + Node->getOperand(2)); + // Increment the pointer, VAList, to the next vaarg + SDOperand NextPtr = DAG.getNode(ISD::ADD, getPointerTy(), VAList, + DAG.getConstant(MVT::getSizeInBits(VT)/8, + getPointerTy())); + // Store the incremented VAList to the legalized pointer + InChain = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), NextPtr, + VAListPtr, Node->getOperand(2)); + // Load the actual argument out of the pointer VAList, unless this is an + // f64 load. + if (VT != MVT::f64) { + return DAG.getLoad(VT, InChain, VAList, DAG.getSrcValue(0)); + } else { + // Otherwise, load it as i64, then do a bitconvert. + SDOperand V = DAG.getLoad(MVT::i64, InChain, VAList, DAG.getSrcValue(0)); + std::vector Tys; + Tys.push_back(MVT::f64); + Tys.push_back(MVT::Other); + std::vector Ops; + // Bit-Convert the value to f64. + Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, MVT::f64, V)); + Ops.push_back(V.getValue(1)); + return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops); + } + } case ISD::RET: { SDOperand Copy; From evan.cheng at apple.com Sat Feb 4 02:51:01 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 02:51:01 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602040851.CAA09606@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.161 -> 1.162 --- Log message: Complex pattern's custom matcher should not call Select() on any operands. Select them afterwards if it returns true. --- Diffs of the changes: (+5 -0) DAGISelEmitter.cpp | 5 +++++ 1 files changed, 5 insertions(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.161 llvm/utils/TableGen/DAGISelEmitter.cpp:1.162 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.161 Fri Feb 3 12:06:02 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Feb 4 02:50:49 2006 @@ -2136,6 +2136,11 @@ for (unsigned i = 0; i < NumRes; i++) Code += ", Tmp" + utostr(i + ResNo); emitCheck(Code + ")"); + + for (unsigned i = 0; i < NumRes; ++i) + emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" + + utostr(i+ResNo) + ");"); + TmpNo = ResNo + NumRes; } else { emitCode("SDOperand Tmp" + utostr(ResNo) + " = Select(" + Val + ");"); From evan.cheng at apple.com Sat Feb 4 02:51:02 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 02:51:02 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602040851.CAA09610@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.38 -> 1.39 --- Log message: Complex pattern's custom matcher should not call Select() on any operands. Select them afterwards if it returns true. --- Diffs of the changes: (+7 -13) X86ISelDAGToDAG.cpp | 20 +++++++------------- 1 files changed, 7 insertions(+), 13 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.38 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.39 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.38 Tue Jan 31 16:28:30 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Feb 4 02:50:49 2006 @@ -369,17 +369,11 @@ return false; if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (AM.Base.Reg.Val) { - if (AM.Base.Reg.getOpcode() != ISD::Register) - AM.Base.Reg = Select(AM.Base.Reg); - } else { + if (!AM.Base.Reg.Val) AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); - } } - if (AM.IndexReg.Val) - AM.IndexReg = Select(AM.IndexReg); - else + if (!AM.IndexReg.Val) AM.IndexReg = CurDAG->getRegister(0, MVT::i32); getAddressOperands(AM, Base, Scale, Index, Disp); @@ -441,11 +435,6 @@ return false; } - if (SelectBase) - AM.Base.Reg = Select(AM.Base.Reg); - if (SelectIndex) - AM.IndexReg = Select(AM.IndexReg); - getAddressOperands(AM, Base, Scale, Index, Disp); return true; } @@ -461,6 +450,11 @@ if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) return N; // Already selected. + // These are probably emitted by SelectAddr(). + if (Opcode == ISD::TargetConstant || Opcode == ISD::TargetConstantPool || + Opcode == ISD::TargetFrameIndex || Opcode == ISD::TargetGlobalAddress) + return N; + std::map::iterator CGMI = CodeGenMap.find(N); if (CGMI != CodeGenMap.end()) return CGMI->second; From lattner at cs.uiuc.edu Sat Feb 4 03:15:41 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:15:41 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ValueNumbering.cpp Message-ID: <200602040915.DAA09831@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ValueNumbering.cpp updated: 1.15 -> 1.16 --- Log message: Value# select instructions, allowing -gcse to remove duplicates --- Diffs of the changes: (+36 -1) ValueNumbering.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 files changed, 36 insertions(+), 1 deletion(-) Index: llvm/lib/Analysis/ValueNumbering.cpp diff -u llvm/lib/Analysis/ValueNumbering.cpp:1.15 llvm/lib/Analysis/ValueNumbering.cpp:1.16 --- llvm/lib/Analysis/ValueNumbering.cpp:1.15 Thu Apr 21 16:04:58 2005 +++ llvm/lib/Analysis/ValueNumbering.cpp Sat Feb 4 03:15:29 2006 @@ -80,8 +80,9 @@ void visitGetElementPtrInst(GetElementPtrInst &I); void visitCastInst(CastInst &I); void visitShiftInst(ShiftInst &I) { handleBinaryInst((Instruction&)I); } + void visitSelectInst(SelectInst &I); void visitInstruction(Instruction &) { - // Cannot value number calls or terminator instructions... + // Cannot value number calls or terminator instructions. } }; } @@ -198,4 +199,38 @@ } } +// isIdenticalSelectInst - Return true if the two select instructions are +// identical. +// +static inline bool isIdenticalSelectInst(const SelectInst &I1, + const SelectInst *I2) { + // Is it embedded in the same function? (This could be false if LHS + // is a constant or global!) + if (I1.getParent()->getParent() != I2->getParent()->getParent()) + return false; + + // They are identical if both operands are the same! + return I1.getOperand(0) == I2->getOperand(0) && + I1.getOperand(1) == I2->getOperand(1) && + I1.getOperand(2) == I2->getOperand(2); + return true; + + return false; +} + +void BVNImpl::visitSelectInst(SelectInst &I) { + Value *Cond = I.getOperand(0); + + for (Value::use_iterator UI = Cond->use_begin(), UE = Cond->use_end(); + UI != UE; ++UI) + if (SelectInst *Other = dyn_cast(*UI)) + // Check to see if this new select is not I, but has the same operands. + if (Other != &I && isIdenticalSelectInst(I, Other)) { + // These instructions are identical. Handle the situation. + RetVals.push_back(Other); + } + +} + + void llvm::BasicValueNumberingStub() { } From lattner at cs.uiuc.edu Sat Feb 4 03:23:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:23:18 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602040923.DAA10097@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.162 -> 1.163 --- Log message: Temporarily revert the last change, which breaks PPC and other targets that DO select things. --- Diffs of the changes: (+4 -3) DAGISelEmitter.cpp | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.162 llvm/utils/TableGen/DAGISelEmitter.cpp:1.163 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.162 Sat Feb 4 02:50:49 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Feb 4 03:23:06 2006 @@ -2137,9 +2137,10 @@ Code += ", Tmp" + utostr(i + ResNo); emitCheck(Code + ")"); - for (unsigned i = 0; i < NumRes; ++i) - emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" + - utostr(i+ResNo) + ");"); + // This breaks ppc + //for (unsigned i = 0; i < NumRes; ++i) + // emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" + + // utostr(i+ResNo) + ");"); TmpNo = ResNo + NumRes; } else { From lattner at cs.uiuc.edu Sat Feb 4 03:24:28 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:24:28 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602040924.DAA10185@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.39 -> 1.40 --- Log message: Temporarily revert this patch, which probably breaks with the tblgen patch reverted. --- Diffs of the changes: (+13 -7) X86ISelDAGToDAG.cpp | 20 +++++++++++++------- 1 files changed, 13 insertions(+), 7 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.39 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.40 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.39 Sat Feb 4 02:50:49 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Feb 4 03:24:16 2006 @@ -369,11 +369,17 @@ return false; if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (!AM.Base.Reg.Val) + if (AM.Base.Reg.Val) { + if (AM.Base.Reg.getOpcode() != ISD::Register) + AM.Base.Reg = Select(AM.Base.Reg); + } else { AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); + } } - if (!AM.IndexReg.Val) + if (AM.IndexReg.Val) + AM.IndexReg = Select(AM.IndexReg); + else AM.IndexReg = CurDAG->getRegister(0, MVT::i32); getAddressOperands(AM, Base, Scale, Index, Disp); @@ -435,6 +441,11 @@ return false; } + if (SelectBase) + AM.Base.Reg = Select(AM.Base.Reg); + if (SelectIndex) + AM.IndexReg = Select(AM.IndexReg); + getAddressOperands(AM, Base, Scale, Index, Disp); return true; } @@ -450,11 +461,6 @@ if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) return N; // Already selected. - // These are probably emitted by SelectAddr(). - if (Opcode == ISD::TargetConstant || Opcode == ISD::TargetConstantPool || - Opcode == ISD::TargetFrameIndex || Opcode == ISD::TargetGlobalAddress) - return N; - std::map::iterator CGMI = CodeGenMap.find(N); if (CGMI != CodeGenMap.end()) return CGMI->second; From lattner at cs.uiuc.edu Sat Feb 4 03:51:45 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:51:45 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h Message-ID: <200602040951.DAA10666@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: ScalarEvolutionExpander.h updated: 1.3 -> 1.4 --- Log message: Refactor a bunch of code into a non-inlined method --- Diffs of the changes: (+6 -33) ScalarEvolutionExpander.h | 39 ++++++--------------------------------- 1 files changed, 6 insertions(+), 33 deletions(-) Index: llvm/include/llvm/Analysis/ScalarEvolutionExpander.h diff -u llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.3 llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.4 --- llvm/include/llvm/Analysis/ScalarEvolutionExpander.h:1.3 Fri Feb 3 23:49:01 2006 +++ llvm/include/llvm/Analysis/ScalarEvolutionExpander.h Sat Feb 4 03:51:33 2006 @@ -86,6 +86,10 @@ return expandInTy(SH, Ty); } + /// InsertCastOfTo - Insert a cast of V to the specified type, doing what + /// we can to share the casts. + static Value *InsertCastOfTo(Value *V, const Type *Ty); + protected: Value *expand(SCEV *S) { // Check to see if we already expanded this. @@ -100,39 +104,8 @@ Value *expandInTy(SCEV *S, const Type *Ty) { Value *V = expand(S); - if (Ty && V->getType() != Ty) { - // FIXME: keep track of the cast instruction. - if (Constant *C = dyn_cast(V)) - return ConstantExpr::getCast(C, Ty); - else if (Instruction *I = dyn_cast(V)) { - // Check to see if there is already a cast. If there is, use it. - for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); - UI != E; ++UI) { - if ((*UI)->getType() == Ty) - if (CastInst *CI = dyn_cast(cast(*UI))) { - BasicBlock::iterator It = I; ++It; - if (isa(I)) - It = cast(I)->getNormalDest()->begin(); - while (isa(It)) ++It; - if (It != BasicBlock::iterator(CI)) { - // Splice the cast immediately after the operand in question. - BasicBlock::InstListType &InstList = - It->getParent()->getInstList(); - InstList.splice(It, CI->getParent()->getInstList(), CI); - } - return CI; - } - } - BasicBlock::iterator IP = I; ++IP; - if (InvokeInst *II = dyn_cast(I)) - IP = II->getNormalDest()->begin(); - while (isa(IP)) ++IP; - return new CastInst(V, Ty, V->getName(), IP); - } else { - // FIXME: check to see if there is already a cast! - return new CastInst(V, Ty, V->getName(), InsertPt); - } - } + if (Ty && V->getType() != Ty) + return InsertCastOfTo(V, Ty); return V; } From lattner at cs.uiuc.edu Sat Feb 4 03:52:04 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:52:04 -0600 Subject: [llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolutionExpander.cpp Message-ID: <200602040952.DAA10676@zion.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: ScalarEvolutionExpander.cpp updated: 1.2 -> 1.3 --- Log message: Pull the InsertCastOfTo out of the header, implement CSE'ing of arguments. --- Diffs of the changes: (+51 -0) ScalarEvolutionExpander.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+) Index: llvm/lib/Analysis/ScalarEvolutionExpander.cpp diff -u llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.2 llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.3 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp:1.2 Sun Oct 30 01:24:33 2005 +++ llvm/lib/Analysis/ScalarEvolutionExpander.cpp Sat Feb 4 03:51:53 2006 @@ -17,6 +17,57 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" using namespace llvm; +/// InsertCastOfTo - Insert a cast of V to the specified type, doing what +/// we can to share the casts. +Value *SCEVExpander::InsertCastOfTo(Value *V, const Type *Ty) { + // FIXME: keep track of the cast instruction. + if (Constant *C = dyn_cast(V)) + return ConstantExpr::getCast(C, Ty); + + if (Argument *A = dyn_cast(V)) { + // Check to see if there is already a cast! + for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); + UI != E; ++UI) { + if ((*UI)->getType() == Ty) + if (CastInst *CI = dyn_cast(cast(*UI))) { + // If the cast isn't in the first instruction of the function, + // move it. + if (BasicBlock::iterator(CI) != + A->getParent()->getEntryBlock().begin()) { + CI->moveBefore(A->getParent()->getEntryBlock().begin()); + } + return CI; + } + } + return new CastInst(V, Ty, V->getName(), + A->getParent()->getEntryBlock().begin()); + } + + Instruction *I = cast(V); + + // Check to see if there is already a cast. If there is, use it. + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); + UI != E; ++UI) { + if ((*UI)->getType() == Ty) + if (CastInst *CI = dyn_cast(cast(*UI))) { + BasicBlock::iterator It = I; ++It; + if (isa(I)) + It = cast(I)->getNormalDest()->begin(); + while (isa(It)) ++It; + if (It != BasicBlock::iterator(CI)) { + // Splice the cast immediately after the operand in question. + CI->moveBefore(It); + } + return CI; + } + } + BasicBlock::iterator IP = I; ++IP; + if (InvokeInst *II = dyn_cast(I)) + IP = II->getNormalDest()->begin(); + while (isa(IP)) ++IP; + return new CastInst(V, Ty, V->getName(), IP); +} + Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) { const Type *Ty = S->getType(); int FirstOp = 0; // Set if we should emit a subtract. From lattner at cs.uiuc.edu Sat Feb 4 03:52:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 03:52:55 -0600 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200602040952.DAA10793@zion.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Scalar: LoopStrengthReduce.cpp updated: 1.74 -> 1.75 --- Log message: Use SCEVExpander::InsertCastOfTo instead of our own code. This reduces #LLVM LOC, and auto-cse's cast instructions. --- Diffs of the changes: (+1 -18) LoopStrengthReduce.cpp | 19 +------------------ 1 files changed, 1 insertion(+), 18 deletions(-) Index: llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp diff -u llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.74 llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.75 --- llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp:1.74 Sat Feb 4 01:36:50 2006 +++ llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp Sat Feb 4 03:52:43 2006 @@ -176,24 +176,7 @@ Value *&New = CastedPointers[V]; if (New) return New; - BasicBlock::iterator InsertPt; - if (Argument *Arg = dyn_cast(V)) { - // Insert into the entry of the function, after any allocas. - InsertPt = Arg->getParent()->begin()->begin(); - while (isa(InsertPt)) ++InsertPt; - } else { - if (InvokeInst *II = dyn_cast(V)) { - InsertPt = II->getNormalDest()->begin(); - } else { - InsertPt = cast(V); - ++InsertPt; - } - - // Do not insert casts into the middle of PHI node blocks. - while (isa(InsertPt)) ++InsertPt; - } - - New = new CastInst(V, UIntPtrTy, V->getName(), InsertPt); + New = SCEVExpander::InsertCastOfTo(V, UIntPtrTy); DeadInsts.insert(cast(New)); return New; } From jeffc at jolt-lang.org Sat Feb 4 10:20:43 2006 From: jeffc at jolt-lang.org (Jeff Cohen) Date: Sat, 4 Feb 2006 10:20:43 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Message-ID: <200602041620.KAA12614@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: ScheduleDAG.cpp updated: 1.64 -> 1.65 --- Log message: Fix VC++ warning. --- Diffs of the changes: (+0 -1) ScheduleDAG.cpp | 1 - 1 files changed, 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.64 llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.65 --- llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp:1.64 Sat Feb 4 00:49:00 2006 +++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Sat Feb 4 10:20:31 2006 @@ -301,7 +301,6 @@ // Add all of the operand registers to the instruction. for (unsigned i = 2; i != NumOps; i += 2) { unsigned Flags =cast(Node->getOperand(i+1))->getValue(); - MachineOperand::UseType UseTy; switch (Flags) { default: assert(0 && "Bad flags!"); case 1: { // Use of register. From alenhar2 at cs.uiuc.edu Sat Feb 4 13:13:21 2006 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Sat, 4 Feb 2006 13:13:21 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Message-ID: <200602041913.NAA13134@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Alpha: AlphaAsmPrinter.cpp updated: 1.29 -> 1.30 --- Log message: linkage fix for weak functions --- Diffs of the changes: (+16 -3) AlphaAsmPrinter.cpp | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-) Index: llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp diff -u llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.29 llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.30 --- llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp:1.29 Sun Jan 22 17:37:17 2006 +++ llvm/lib/Target/Alpha/AlphaAsmPrinter.cpp Sat Feb 4 13:13:09 2006 @@ -173,9 +173,22 @@ EmitConstantPool(MF.getConstantPool()); // Print out labels for the function. - SwitchSection("\t.section .text", MF.getFunction()); - EmitAlignment(4); - O << "\t.globl " << CurrentFnName << "\n"; + const Function *F = MF.getFunction(); + SwitchSection(".text", F); + EmitAlignment(4, F); + switch (F->getLinkage()) { + default: assert(0 && "Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + break; + case Function::ExternalLinkage: + O << "\t.globl " << CurrentFnName << "\n"; + break; + case Function::WeakLinkage: + case Function::LinkOnceLinkage: + O << "\t.weak " << CurrentFnName << "\n"; + break; + } + O << "\t.ent " << CurrentFnName << "\n"; O << CurrentFnName << ":\n"; From lattner at cs.uiuc.edu Sat Feb 4 19:24:18 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 19:24:18 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/AsmPrinter.h Message-ID: <200602050124.TAA14309@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: AsmPrinter.h updated: 1.27 -> 1.28 --- Log message: add a new method, getPreferredAlignmentLog. --- Diffs of the changes: (+4 -0) AsmPrinter.h | 4 ++++ 1 files changed, 4 insertions(+) Index: llvm/include/llvm/CodeGen/AsmPrinter.h diff -u llvm/include/llvm/CodeGen/AsmPrinter.h:1.27 llvm/include/llvm/CodeGen/AsmPrinter.h:1.28 --- llvm/include/llvm/CodeGen/AsmPrinter.h:1.27 Wed Feb 1 16:39:30 2006 +++ llvm/include/llvm/CodeGen/AsmPrinter.h Sat Feb 4 19:24:06 2006 @@ -177,6 +177,10 @@ /// void SwitchSection(const char *NewSection, const GlobalValue *GV); + /// getPreferredAlignmentLog - Return the preferred alignment of the + /// specified global, returned in log form. This includes an explicitly + /// requested alignment (if the global has one). + unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const; protected: /// doInitialization - Set up the AsmPrinter when we are working on a new /// module. If your pass overrides this, it must make sure to explicitly From lattner at cs.uiuc.edu Sat Feb 4 19:29:30 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 19:29:30 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602050129.TAA14420@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.45 -> 1.46 --- Log message: Implement the AsmPrinter::getPreferredAlignmentLog method. --- Diffs of the changes: (+16 -0) AsmPrinter.cpp | 16 ++++++++++++++++ 1 files changed, 16 insertions(+) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.45 llvm/lib/CodeGen/AsmPrinter.cpp:1.46 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.45 Wed Feb 1 16:41:11 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Sat Feb 4 19:29:18 2006 @@ -171,6 +171,22 @@ } } +/// getPreferredAlignmentLog - Return the preferred alignment of the +/// specified global, returned in log form. This includes an explicitly +/// requested alignment (if the global has one). +unsigned AsmPrinter::getPreferredAlignmentLog(const GlobalVariable *GV) const { + unsigned Alignment = TM.getTargetData().getTypeAlignmentShift(GV->getType()); + if (GV->getAlignment() > (1U << Alignment)) + Alignment = Log2_32(GV->getAlignment()); + + if (GV->hasInitializer() && Alignment < 4) { + // If the global is not external, see if it is large. If so, give it a + // larger alignment. + if (TM.getTargetData().getTypeSize(GV->getType()->getElementType()) > 128) + Alignment = 4; // 16-byte alignment. + } + return Alignment; +} // EmitAlignment - Emit an alignment directive to the specified power of two. void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const { From lattner at cs.uiuc.edu Sat Feb 4 19:30:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 19:30:57 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Message-ID: <200602050130.TAA14490@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCAsmPrinter.cpp updated: 1.144 -> 1.145 --- Log message: Use the asmprinter to find out what the preferred alignment of a global is. This patch speeds up 172.mgrid from 31.81s to 11.39s on darwin/ppc. Many many thanks to Nate for tracking down the root cause of the issue. --- Diffs of the changes: (+1 -1) PPCAsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp diff -u llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.144 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.145 --- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1.144 Wed Feb 1 16:38:46 2006 +++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp Sat Feb 4 19:30:45 2006 @@ -527,7 +527,7 @@ std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignmentShift(C->getType()); + unsigned Align = getPreferredAlignmentLog(I); if (C->isNullValue() && /* FIXME: Verify correct */ (I->hasInternalLinkage() || I->hasWeakLinkage() || From lattner at cs.uiuc.edu Sat Feb 4 19:45:16 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 19:45:16 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86AsmPrinter.cpp Message-ID: <200602050145.TAA14708@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86AsmPrinter.cpp updated: 1.159 -> 1.160 --- Log message: Use getPreferredAlignmentLog. --- Diffs of the changes: (+1 -1) X86AsmPrinter.cpp | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/X86/X86AsmPrinter.cpp diff -u llvm/lib/Target/X86/X86AsmPrinter.cpp:1.159 llvm/lib/Target/X86/X86AsmPrinter.cpp:1.160 --- llvm/lib/Target/X86/X86AsmPrinter.cpp:1.159 Tue Dec 13 00:32:50 2005 +++ llvm/lib/Target/X86/X86AsmPrinter.cpp Sat Feb 4 19:45:04 2006 @@ -92,7 +92,7 @@ std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD.getTypeSize(C->getType()); - unsigned Align = TD.getTypeAlignmentShift(C->getType()); + unsigned Align = getPreferredAlignmentLog(I); switch (I->getLinkage()) { default: assert(0 && "Unknown linkage type!"); From lattner at cs.uiuc.edu Sat Feb 4 19:47:00 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 19:47:00 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/AsmPrinter.cpp Message-ID: <200602050147.TAA14761@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen: AsmPrinter.cpp updated: 1.46 -> 1.47 --- Log message: make sure that global doubles are aligned to 8 bytes --- Diffs of the changes: (+10 -5) AsmPrinter.cpp | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) Index: llvm/lib/CodeGen/AsmPrinter.cpp diff -u llvm/lib/CodeGen/AsmPrinter.cpp:1.46 llvm/lib/CodeGen/AsmPrinter.cpp:1.47 --- llvm/lib/CodeGen/AsmPrinter.cpp:1.46 Sat Feb 4 19:29:18 2006 +++ llvm/lib/CodeGen/AsmPrinter.cpp Sat Feb 4 19:46:49 2006 @@ -179,11 +179,16 @@ if (GV->getAlignment() > (1U << Alignment)) Alignment = Log2_32(GV->getAlignment()); - if (GV->hasInitializer() && Alignment < 4) { - // If the global is not external, see if it is large. If so, give it a - // larger alignment. - if (TM.getTargetData().getTypeSize(GV->getType()->getElementType()) > 128) - Alignment = 4; // 16-byte alignment. + if (GV->hasInitializer()) { + // Always round up alignment of global doubles to 8 bytes. + if (GV->getType()->getElementType() == Type::DoubleTy && Alignment < 3) + Alignment = 3; + if (Alignment < 4) { + // If the global is not external, see if it is large. If so, give it a + // larger alignment. + if (TM.getTargetData().getTypeSize(GV->getType()->getElementType()) > 128) + Alignment = 4; // 16-byte alignment. + } } return Alignment; } From evan.cheng at apple.com Sat Feb 4 23:22:30 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 23:22:30 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602050522.XAA15371@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.163 -> 1.164 --- Log message: Re-committing the last bit of change. It shouldn't break PPC this time. --- Diffs of the changes: (+7 -4) DAGISelEmitter.cpp | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.163 llvm/utils/TableGen/DAGISelEmitter.cpp:1.164 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.163 Sat Feb 4 03:23:06 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sat Feb 4 23:22:18 2006 @@ -2137,10 +2137,9 @@ Code += ", Tmp" + utostr(i + ResNo); emitCheck(Code + ")"); - // This breaks ppc - //for (unsigned i = 0; i < NumRes; ++i) - // emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" + - // utostr(i+ResNo) + ");"); + for (unsigned i = 0; i < NumRes; ++i) + emitCode("Tmp" + utostr(i+ResNo) + " = Select(Tmp" + + utostr(i+ResNo) + ");"); TmpNo = ResNo + NumRes; } else { @@ -2885,6 +2884,10 @@ << " case ISD::EntryToken: // These leaves remain the same.\n" << " case ISD::BasicBlock:\n" << " case ISD::Register:\n" + << " case ISD::TargetConstant:\n" + << " case ISD::TargetConstantPool:\n" + << " case ISD::TargetFrameIndex:\n" + << " case ISD::TargetGlobalAddress:\n" << " return N;\n" << " case ISD::AssertSext:\n" << " case ISD::AssertZext: {\n" From evan.cheng at apple.com Sat Feb 4 23:25:18 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sat, 4 Feb 2006 23:25:18 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Message-ID: <200602050525.XAA15429@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/X86: X86ISelDAGToDAG.cpp updated: 1.40 -> 1.41 --- Log message: Re-commit the last bit of change that was backed out. --- Diffs of the changes: (+2 -13) X86ISelDAGToDAG.cpp | 15 ++------------- 1 files changed, 2 insertions(+), 13 deletions(-) Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.40 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.41 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.40 Sat Feb 4 03:24:16 2006 +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Feb 4 23:25:07 2006 @@ -369,17 +369,11 @@ return false; if (AM.BaseType == X86ISelAddressMode::RegBase) { - if (AM.Base.Reg.Val) { - if (AM.Base.Reg.getOpcode() != ISD::Register) - AM.Base.Reg = Select(AM.Base.Reg); - } else { + if (!AM.Base.Reg.Val) AM.Base.Reg = CurDAG->getRegister(0, MVT::i32); - } } - if (AM.IndexReg.Val) - AM.IndexReg = Select(AM.IndexReg); - else + if (!AM.IndexReg.Val) AM.IndexReg = CurDAG->getRegister(0, MVT::i32); getAddressOperands(AM, Base, Scale, Index, Disp); @@ -441,11 +435,6 @@ return false; } - if (SelectBase) - AM.Base.Reg = Select(AM.Base.Reg); - if (SelectIndex) - AM.IndexReg = Select(AM.IndexReg); - getAddressOperands(AM, Base, Scale, Index, Disp); return true; } From lattner at cs.uiuc.edu Sat Feb 4 23:27:47 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:27:47 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/README.txt Message-ID: <200602050527.XAA15584@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: README.txt updated: 1.61 -> 1.62 --- Log message: add a note --- Diffs of the changes: (+11 -0) README.txt | 11 +++++++++++ 1 files changed, 11 insertions(+) Index: llvm/lib/Target/PowerPC/README.txt diff -u llvm/lib/Target/PowerPC/README.txt:1.61 llvm/lib/Target/PowerPC/README.txt:1.62 --- llvm/lib/Target/PowerPC/README.txt:1.61 Sat Feb 4 01:29:35 2006 +++ llvm/lib/Target/PowerPC/README.txt Sat Feb 4 23:27:35 2006 @@ -449,3 +449,14 @@ lbz r2, lo16(_a+3)(r2) stb r2, 0(r3) blr + +===-------------------------------------------------------------------------=== + +We generate really bad code for this: + +int f(signed char *a, _Bool b, _Bool c) { + signed char t = 0; + if (b) t = *a; + if (c) *a = t; +} + From lattner at cs.uiuc.edu Sat Feb 4 23:50:40 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:50:40 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/DelaySlotFiller.cpp FPMover.cpp Makefile Sparc.h Sparc.td SparcAsmPrinter.cpp SparcISelDAGToDAG.cpp SparcInstrFormats.td SparcInstrInfo.cpp SparcInstrInfo.h SparcInstrInfo.td SparcRegisterInfo.cpp SparcRegisterInfo.h SparcRegisterInfo.td SparcSubtarget.cpp SparcSubtarget.h SparcTargetMachine.cpp SparcTargetMachine.h Message-ID: <200602050550.XAA15808@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: DelaySlotFiller.cpp updated: 1.9 -> 1.10 FPMover.cpp updated: 1.11 -> 1.12 Makefile updated: 1.13 -> 1.14 Sparc.h updated: 1.10 -> 1.11 Sparc.td updated: 1.10 -> 1.11 SparcAsmPrinter.cpp updated: 1.52 -> 1.53 SparcISelDAGToDAG.cpp updated: 1.76 -> 1.77 SparcInstrFormats.td updated: 1.15 -> 1.16 SparcInstrInfo.cpp updated: 1.12 -> 1.13 SparcInstrInfo.h updated: 1.7 -> 1.8 SparcInstrInfo.td updated: 1.117 -> 1.118 SparcRegisterInfo.cpp updated: 1.36 -> 1.37 SparcRegisterInfo.h updated: 1.8 -> 1.9 SparcRegisterInfo.td updated: 1.27 -> 1.28 SparcSubtarget.cpp updated: 1.4 -> 1.5 SparcSubtarget.h updated: 1.2 -> 1.3 SparcTargetMachine.cpp updated: 1.39 -> 1.40 SparcTargetMachine.h updated: 1.10 -> 1.11 --- Log message: Rename SPARC V8 target to be the LLVM SPARC target. --- Diffs of the changes: (+532 -538) DelaySlotFiller.cpp | 37 ++--- FPMover.cpp | 46 +++--- Makefile | 14 - Sparc.h | 89 ++++++------ Sparc.td | 12 - SparcAsmPrinter.cpp | 48 +++--- SparcISelDAGToDAG.cpp | 350 ++++++++++++++++++++++++------------------------- SparcInstrFormats.td | 16 +- SparcInstrInfo.cpp | 50 +++---- SparcInstrInfo.h | 20 +- SparcInstrInfo.td | 148 ++++++++++---------- SparcRegisterInfo.cpp | 132 +++++++++--------- SparcRegisterInfo.h | 18 +- SparcRegisterInfo.td | 16 +- SparcSubtarget.cpp | 8 - SparcSubtarget.h | 6 SparcTargetMachine.cpp | 36 ++--- SparcTargetMachine.h | 24 +-- 18 files changed, 532 insertions(+), 538 deletions(-) Index: llvm/lib/Target/Sparc/DelaySlotFiller.cpp diff -u llvm/lib/Target/Sparc/DelaySlotFiller.cpp:1.9 llvm/lib/Target/Sparc/DelaySlotFiller.cpp:1.10 --- llvm/lib/Target/Sparc/DelaySlotFiller.cpp:1.9 Thu Apr 21 18:21:30 2005 +++ llvm/lib/Target/Sparc/DelaySlotFiller.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- DelaySlotFiller.cpp - SparcV8 delay slot filler -------------------===// +//===-- DelaySlotFiller.cpp - SPARC delay slot filler ---------------------===// // // The LLVM Compiler Infrastructure // @@ -11,17 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "SparcV8.h" +#include "Sparc.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/ADT/Statistic.h" - using namespace llvm; namespace { - Statistic<> FilledSlots ("delayslotfiller", "Num. of delay slots filled"); + Statistic<> FilledSlots("delayslotfiller", "Num. of delay slots filled"); struct Filler : public MachineFunctionPass { /// Target machine description which we query for reg. names, data @@ -30,42 +29,42 @@ TargetMachine &TM; const TargetInstrInfo *TII; - Filler (TargetMachine &tm) : TM (tm), TII (tm.getInstrInfo ()) { } + Filler(TargetMachine &tm) : TM(tm), TII(tm.getInstrInfo()) { } - virtual const char *getPassName () const { - return "SparcV8 Delay Slot Filler"; + virtual const char *getPassName() const { + return "SPARC Delay Slot Filler"; } - bool runOnMachineBasicBlock (MachineBasicBlock &MBB); - bool runOnMachineFunction (MachineFunction &F) { + bool runOnMachineBasicBlock(MachineBasicBlock &MBB); + bool runOnMachineFunction(MachineFunction &F) { bool Changed = false; - for (MachineFunction::iterator FI = F.begin (), FE = F.end (); + for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) - Changed |= runOnMachineBasicBlock (*FI); + Changed |= runOnMachineBasicBlock(*FI); return Changed; } }; } // end of anonymous namespace -/// createSparcV8DelaySlotFillerPass - Returns a pass that fills in delay -/// slots in SparcV8 MachineFunctions +/// createSparcDelaySlotFillerPass - Returns a pass that fills in delay +/// slots in Sparc MachineFunctions /// -FunctionPass *llvm::createSparcV8DelaySlotFillerPass (TargetMachine &tm) { - return new Filler (tm); +FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) { + return new Filler(tm); } /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// Currently, we fill delay slots with NOPs. We assume there is only one /// delay slot per delayed instruction. /// -bool Filler::runOnMachineBasicBlock (MachineBasicBlock &MBB) { +bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; - for (MachineBasicBlock::iterator I = MBB.begin (); I != MBB.end (); ++I) - if (TII->hasDelaySlot (I->getOpcode ())) { + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) + if (TII->hasDelaySlot(I->getOpcode())) { MachineBasicBlock::iterator J = I; ++J; - BuildMI (MBB, J, V8::NOP, 0); + BuildMI(MBB, J, SP::NOP, 0); ++FilledSlots; Changed = true; } Index: llvm/lib/Target/Sparc/FPMover.cpp diff -u llvm/lib/Target/Sparc/FPMover.cpp:1.11 llvm/lib/Target/Sparc/FPMover.cpp:1.12 --- llvm/lib/Target/Sparc/FPMover.cpp:1.11 Sun Jan 29 23:51:14 2006 +++ llvm/lib/Target/Sparc/FPMover.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- FPMover.cpp - SparcV8 double-precision floating point move fixer --===// +//===-- FPMover.cpp - Sparc double-precision floating point move fixer ----===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "SparcV8.h" -#include "SparcV8Subtarget.h" +#include "Sparc.h" +#include "SparcSubtarget.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetMachine.h" @@ -34,7 +34,7 @@ FPMover(TargetMachine &tm) : TM(tm) { } virtual const char *getPassName() const { - return "SparcV8 Double-FP Move Fixer"; + return "Sparc Double-FP Move Fixer"; } bool runOnMachineBasicBlock(MachineBasicBlock &MBB); @@ -42,10 +42,10 @@ }; } // end of anonymous namespace -/// createSparcV8FPMoverPass - Returns a pass that turns FpMOVD +/// createSparcFPMoverPass - Returns a pass that turns FpMOVD /// instructions into FMOVS instructions /// -FunctionPass *llvm::createSparcV8FPMoverPass(TargetMachine &tm) { +FunctionPass *llvm::createSparcFPMoverPass(TargetMachine &tm) { return new FPMover(tm); } @@ -54,16 +54,16 @@ static void getDoubleRegPair(unsigned DoubleReg, unsigned &EvenReg, unsigned &OddReg) { static const unsigned EvenHalvesOfPairs[] = { - V8::F0, V8::F2, V8::F4, V8::F6, V8::F8, V8::F10, V8::F12, V8::F14, - V8::F16, V8::F18, V8::F20, V8::F22, V8::F24, V8::F26, V8::F28, V8::F30 + SP::F0, SP::F2, SP::F4, SP::F6, SP::F8, SP::F10, SP::F12, SP::F14, + SP::F16, SP::F18, SP::F20, SP::F22, SP::F24, SP::F26, SP::F28, SP::F30 }; static const unsigned OddHalvesOfPairs[] = { - V8::F1, V8::F3, V8::F5, V8::F7, V8::F9, V8::F11, V8::F13, V8::F15, - V8::F17, V8::F19, V8::F21, V8::F23, V8::F25, V8::F27, V8::F29, V8::F31 + SP::F1, SP::F3, SP::F5, SP::F7, SP::F9, SP::F11, SP::F13, SP::F15, + SP::F17, SP::F19, SP::F21, SP::F23, SP::F25, SP::F27, SP::F29, SP::F31 }; static const unsigned DoubleRegsInOrder[] = { - V8::D0, V8::D1, V8::D2, V8::D3, V8::D4, V8::D5, V8::D6, V8::D7, V8::D8, - V8::D9, V8::D10, V8::D11, V8::D12, V8::D13, V8::D14, V8::D15 + SP::D0, SP::D1, SP::D2, SP::D3, SP::D4, SP::D5, SP::D6, SP::D7, SP::D8, + SP::D9, SP::D10, SP::D11, SP::D12, SP::D13, SP::D14, SP::D15 }; for (unsigned i = 0; i < sizeof(DoubleRegsInOrder)/sizeof(unsigned); ++i) if (DoubleRegsInOrder[i] == DoubleReg) { @@ -80,12 +80,12 @@ bool Changed = false; for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { MachineInstr *MI = I++; - if (MI->getOpcode() == V8::FpMOVD || MI->getOpcode() == V8::FpABSD || - MI->getOpcode() == V8::FpNEGD) { + if (MI->getOpcode() == SP::FpMOVD || MI->getOpcode() == SP::FpABSD || + MI->getOpcode() == SP::FpNEGD) { Changed = true; unsigned DestDReg = MI->getOperand(0).getReg(); unsigned SrcDReg = MI->getOperand(1).getReg(); - if (DestDReg == SrcDReg && MI->getOpcode() == V8::FpMOVD) { + if (DestDReg == SrcDReg && MI->getOpcode() == SP::FpMOVD) { MBB.erase(MI); // Eliminate the noop copy. ++NoopFpDs; continue; @@ -95,12 +95,12 @@ getDoubleRegPair(DestDReg, EvenDestReg, OddDestReg); getDoubleRegPair(SrcDReg, EvenSrcReg, OddSrcReg); - if (MI->getOpcode() == V8::FpMOVD) - MI->setOpcode(V8::FMOVS); - else if (MI->getOpcode() == V8::FpNEGD) - MI->setOpcode(V8::FNEGS); - else if (MI->getOpcode() == V8::FpABSD) - MI->setOpcode(V8::FABSS); + if (MI->getOpcode() == SP::FpMOVD) + MI->setOpcode(SP::FMOVS); + else if (MI->getOpcode() == SP::FpNEGD) + MI->setOpcode(SP::FNEGS); + else if (MI->getOpcode() == SP::FpABSD) + MI->setOpcode(SP::FABSS); else assert(0 && "Unknown opcode!"); @@ -109,7 +109,7 @@ DEBUG(std::cerr << "FPMover: the modified instr is: " << *MI); // Insert copy for the other half of the double. if (DestDReg != SrcDReg) { - MI = BuildMI(MBB, I, V8::FMOVS, 1, OddDestReg).addReg(OddSrcReg); + MI = BuildMI(MBB, I, SP::FMOVS, 1, OddDestReg).addReg(OddSrcReg); DEBUG(std::cerr << "FPMover: the inserted instr is: " << *MI); } ++NumFpDs; @@ -121,7 +121,7 @@ bool FPMover::runOnMachineFunction(MachineFunction &F) { // If the target has V9 instructions, the fp-mover pseudos will never be // emitted. Avoid a scan of the instructions to improve compile time. - if (TM.getSubtarget().isV9()) + if (TM.getSubtarget().isV9()) return false; bool Changed = false; Index: llvm/lib/Target/Sparc/Makefile diff -u llvm/lib/Target/Sparc/Makefile:1.13 llvm/lib/Target/Sparc/Makefile:1.14 --- llvm/lib/Target/Sparc/Makefile:1.13 Thu Jan 26 00:51:21 2006 +++ llvm/lib/Target/Sparc/Makefile Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -##===- lib/Target/SparcV8/Makefile -------------------------*- Makefile -*-===## +##===- lib/Target/Sparc/Makefile ---------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -7,14 +7,14 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../../.. -LIBRARYNAME = LLVMSparcV8 -TARGET = SparcV8 +LIBRARYNAME = LLVMSparc +TARGET = Sparc # Make sure that tblgen is run, first thing. -BUILT_SOURCES = SparcV8GenRegisterInfo.h.inc SparcV8GenRegisterNames.inc \ - SparcV8GenRegisterInfo.inc SparcV8GenInstrNames.inc \ - SparcV8GenInstrInfo.inc SparcV8GenAsmWriter.inc \ - SparcV8GenDAGISel.inc SparcV8GenSubtarget.inc +BUILT_SOURCES = SparcGenRegisterInfo.h.inc SparcGenRegisterNames.inc \ + SparcGenRegisterInfo.inc SparcGenInstrNames.inc \ + SparcGenInstrInfo.inc SparcGenAsmWriter.inc \ + SparcGenDAGISel.inc SparcGenSubtarget.inc include $(LEVEL)/Makefile.common Index: llvm/lib/Target/Sparc/Sparc.h diff -u llvm/lib/Target/Sparc/Sparc.h:1.10 llvm/lib/Target/Sparc/Sparc.h:1.11 --- llvm/lib/Target/Sparc/Sparc.h:1.10 Tue Jan 31 00:56:30 2006 +++ llvm/lib/Target/Sparc/Sparc.h Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- SparcV8.h - Top-level interface for SparcV8 representation -*- C++ -*-// +//===-- Sparc.h - Top-level interface for Sparc representation --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,43 +8,40 @@ //===----------------------------------------------------------------------===// // // This file contains the entry points for global functions defined in the LLVM -// SparcV8 back-end. +// Sparc back-end. // //===----------------------------------------------------------------------===// -#ifndef TARGET_SPARCV8_H -#define TARGET_SPARCV8_H +#ifndef TARGET_SPARC_H +#define TARGET_SPARC_H #include #include namespace llvm { - class FunctionPass; class TargetMachine; - FunctionPass *createSparcV8ISelDag(TargetMachine &TM); - - FunctionPass *createSparcV8CodePrinterPass(std::ostream &OS, - TargetMachine &TM); - FunctionPass *createSparcV8DelaySlotFillerPass(TargetMachine &TM); - FunctionPass *createSparcV8FPMoverPass(TargetMachine &TM); + FunctionPass *createSparcISelDag(TargetMachine &TM); + FunctionPass *createSparcCodePrinterPass(std::ostream &OS, TargetMachine &TM); + FunctionPass *createSparcDelaySlotFillerPass(TargetMachine &TM); + FunctionPass *createSparcFPMoverPass(TargetMachine &TM); } // end namespace llvm; -// Defines symbolic names for SparcV8 registers. This defines a mapping from +// Defines symbolic names for Sparc registers. This defines a mapping from // register name to register number. // -#include "SparcV8GenRegisterNames.inc" +#include "SparcGenRegisterNames.inc" -// Defines symbolic names for the SparcV8 instructions. +// Defines symbolic names for the Sparc instructions. // -#include "SparcV8GenInstrNames.inc" +#include "SparcGenInstrNames.inc" namespace llvm { - // Enums corresponding to SparcV8 condition codes, both icc's and fcc's. These + // Enums corresponding to Sparc condition codes, both icc's and fcc's. These // values must be kept in sync with the ones in the .td file. - namespace V8CC { + namespace SPCC { enum CondCodes { //ICC_A = 8 , // Always //ICC_N = 0 , // Never @@ -82,37 +79,37 @@ }; } - static const char *SPARCCondCodeToString(V8CC::CondCodes CC) { + static const char *SPARCCondCodeToString(SPCC::CondCodes CC) { switch (CC) { default: assert(0 && "Unknown condition code"); - case V8CC::ICC_NE: return "ne"; - case V8CC::ICC_E: return "e"; - case V8CC::ICC_G: return "g"; - case V8CC::ICC_LE: return "le"; - case V8CC::ICC_GE: return "ge"; - case V8CC::ICC_L: return "l"; - case V8CC::ICC_GU: return "gu"; - case V8CC::ICC_LEU: return "leu"; - case V8CC::ICC_CC: return "cc"; - case V8CC::ICC_CS: return "cs"; - case V8CC::ICC_POS: return "pos"; - case V8CC::ICC_NEG: return "neg"; - case V8CC::ICC_VC: return "vc"; - case V8CC::ICC_VS: return "vs"; - case V8CC::FCC_U: return "u"; - case V8CC::FCC_G: return "g"; - case V8CC::FCC_UG: return "ug"; - case V8CC::FCC_L: return "l"; - case V8CC::FCC_UL: return "ul"; - case V8CC::FCC_LG: return "lg"; - case V8CC::FCC_NE: return "ne"; - case V8CC::FCC_E: return "e"; - case V8CC::FCC_UE: return "ue"; - case V8CC::FCC_GE: return "ge"; - case V8CC::FCC_UGE: return "uge"; - case V8CC::FCC_LE: return "le"; - case V8CC::FCC_ULE: return "ule"; - case V8CC::FCC_O: return "o"; + case SPCC::ICC_NE: return "ne"; + case SPCC::ICC_E: return "e"; + case SPCC::ICC_G: return "g"; + case SPCC::ICC_LE: return "le"; + case SPCC::ICC_GE: return "ge"; + case SPCC::ICC_L: return "l"; + case SPCC::ICC_GU: return "gu"; + case SPCC::ICC_LEU: return "leu"; + case SPCC::ICC_CC: return "cc"; + case SPCC::ICC_CS: return "cs"; + case SPCC::ICC_POS: return "pos"; + case SPCC::ICC_NEG: return "neg"; + case SPCC::ICC_VC: return "vc"; + case SPCC::ICC_VS: return "vs"; + case SPCC::FCC_U: return "u"; + case SPCC::FCC_G: return "g"; + case SPCC::FCC_UG: return "ug"; + case SPCC::FCC_L: return "l"; + case SPCC::FCC_UL: return "ul"; + case SPCC::FCC_LG: return "lg"; + case SPCC::FCC_NE: return "ne"; + case SPCC::FCC_E: return "e"; + case SPCC::FCC_UE: return "ue"; + case SPCC::FCC_GE: return "ge"; + case SPCC::FCC_UGE: return "uge"; + case SPCC::FCC_LE: return "le"; + case SPCC::FCC_ULE: return "ule"; + case SPCC::FCC_O: return "o"; } } } // end namespace llvm Index: llvm/lib/Target/Sparc/Sparc.td diff -u llvm/lib/Target/Sparc/Sparc.td:1.10 llvm/lib/Target/Sparc/Sparc.td:1.11 --- llvm/lib/Target/Sparc/Sparc.td:1.10 Fri Jan 27 02:09:42 2006 +++ llvm/lib/Target/Sparc/Sparc.td Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8.td - Describe the SparcV8 Target Machine ---------*- C++ -*-===// +//===- Sparc.td - Describe the Sparc Target Machine -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -34,15 +34,15 @@ // Register File Description //===----------------------------------------------------------------------===// -include "SparcV8RegisterInfo.td" +include "SparcRegisterInfo.td" //===----------------------------------------------------------------------===// // Instruction Descriptions //===----------------------------------------------------------------------===// -include "SparcV8InstrInfo.td" +include "SparcInstrInfo.td" -def SparcV8InstrInfo : InstrInfo { +def SparcInstrInfo : InstrInfo { // Define how we want to layout our target-specific information field. let TSFlagsFields = []; let TSFlagsShifts = []; @@ -74,7 +74,7 @@ // Declare the target which we are implementing //===----------------------------------------------------------------------===// -def SparcV8 : Target { +def Sparc : Target { // Pointers are 32-bits in size. let PointerType = i32; @@ -82,5 +82,5 @@ let CalleeSavedRegisters = []; // Pull in Instruction Info: - let InstructionSet = SparcV8InstrInfo; + let InstructionSet = SparcInstrInfo; } Index: llvm/lib/Target/Sparc/SparcAsmPrinter.cpp diff -u llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.52 llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.53 --- llvm/lib/Target/Sparc/SparcAsmPrinter.cpp:1.52 Tue Jan 31 00:49:09 2006 +++ llvm/lib/Target/Sparc/SparcAsmPrinter.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===// +//===-- SparcAsmPrinter.cpp - Sparc LLVM assembly writer ------------------===// // // The LLVM Compiler Infrastructure // @@ -8,12 +8,12 @@ //===----------------------------------------------------------------------===// // // This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to GAS-format Sparc V8 assembly language. +// of machine-dependent LLVM code to GAS-format SPARC assembly language. // //===----------------------------------------------------------------------===// -#include "SparcV8.h" -#include "SparcV8InstrInfo.h" +#include "Sparc.h" +#include "SparcInstrInfo.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" @@ -35,8 +35,8 @@ namespace { Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); - struct SparcV8AsmPrinter : public AsmPrinter { - SparcV8AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { + struct SparcAsmPrinter : public AsmPrinter { + SparcAsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) { Data16bitsDirective = "\t.half\t"; Data32bitsDirective = "\t.word\t"; Data64bitsDirective = 0; // .xword is only supported by V9. @@ -53,12 +53,12 @@ ValueMapTy NumberForBB; virtual const char *getPassName() const { - return "SparcV8 Assembly Printer"; + return "Sparc Assembly Printer"; } void printOperand(const MachineInstr *MI, int opNum); void printMemOperand(const MachineInstr *MI, int opNum); - void printV8CCOperand(const MachineInstr *MI, int opNum); + void printCCOperand(const MachineInstr *MI, int opNum); bool printInstruction(const MachineInstr *MI); // autogenerated. bool runOnMachineFunction(MachineFunction &F); @@ -67,22 +67,22 @@ }; } // end of anonymous namespace -#include "SparcV8GenAsmWriter.inc" +#include "SparcGenAsmWriter.inc" -/// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8 +/// createSparcCodePrinterPass - Returns a pass that prints the SPARC /// assembly code for a MachineFunction to the given output stream, /// using the given target machine description. This should work /// regardless of whether the function is in SSA form. /// -FunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o, - TargetMachine &tm) { - return new SparcV8AsmPrinter(o, tm); +FunctionPass *llvm::createSparcCodePrinterPass(std::ostream &o, + TargetMachine &tm) { + return new SparcAsmPrinter(o, tm); } /// runOnMachineFunction - This uses the printMachineInstruction() /// method to print assembly for each instruction. /// -bool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) { +bool SparcAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SetupMachineFunction(MF); // Print out constants referenced by the function @@ -132,14 +132,14 @@ return false; } -void SparcV8AsmPrinter::printOperand(const MachineInstr *MI, int opNum) { +void SparcAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { const MachineOperand &MO = MI->getOperand (opNum); const MRegisterInfo &RI = *TM.getRegisterInfo(); bool CloseParen = false; - if (MI->getOpcode() == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) { + if (MI->getOpcode() == SP::SETHIi && !MO.isRegister() && !MO.isImmediate()) { O << "%hi("; CloseParen = true; - } else if ((MI->getOpcode() == V8::ORri || MI->getOpcode() == V8::ADDri) + } else if ((MI->getOpcode() == SP::ORri || MI->getOpcode() == SP::ADDri) && !MO.isRegister() && !MO.isImmediate()) { O << "%lo("; CloseParen = true; @@ -170,7 +170,7 @@ return; } case MachineOperand::MO_PCRelativeDisp: - std::cerr << "Shouldn't use addPCDisp() when building SparcV8 MachineInstrs"; + std::cerr << "Shouldn't use addPCDisp() when building Sparc MachineInstrs"; abort (); return; case MachineOperand::MO_GlobalAddress: @@ -189,13 +189,13 @@ if (CloseParen) O << ")"; } -void SparcV8AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) { +void SparcAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) { printOperand(MI, opNum); MachineOperand::MachineOperandType OpTy = MI->getOperand(opNum+1).getType(); if ((OpTy == MachineOperand::MO_VirtualRegister || OpTy == MachineOperand::MO_MachineRegister) && - MI->getOperand(opNum+1).getReg() == V8::G0) + MI->getOperand(opNum+1).getReg() == SP::G0) return; // don't print "+%g0" if ((OpTy == MachineOperand::MO_SignExtendedImmed || OpTy == MachineOperand::MO_UnextendedImmed) && @@ -213,19 +213,19 @@ } } -void SparcV8AsmPrinter::printV8CCOperand(const MachineInstr *MI, int opNum) { +void SparcAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) { int CC = (int)MI->getOperand(opNum).getImmedValue(); - O << SPARCCondCodeToString((V8CC::CondCodes)CC); + O << SPARCCondCodeToString((SPCC::CondCodes)CC); } -bool SparcV8AsmPrinter::doInitialization(Module &M) { +bool SparcAsmPrinter::doInitialization(Module &M) { Mang = new Mangler(M); return false; // success } -bool SparcV8AsmPrinter::doFinalization(Module &M) { +bool SparcAsmPrinter::doFinalization(Module &M) { const TargetData &TD = TM.getTargetData(); // Print out module-level global variables here. Index: llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp diff -u llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.76 llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.77 --- llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp:1.76 Sat Feb 4 02:31:30 2006 +++ llvm/lib/Target/Sparc/SparcISelDAGToDAG.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===// +//===-- SparcISelDAGToDAG.cpp - A dag to dag inst selector for Sparc ------===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file defines an instruction selector for the V8 target +// This file defines an instruction selector for the SPARC target. // //===----------------------------------------------------------------------===// -#include "SparcV8.h" -#include "SparcV8TargetMachine.h" +#include "Sparc.h" +#include "SparcTargetMachine.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -30,9 +30,9 @@ // TargetLowering Implementation //===----------------------------------------------------------------------===// -namespace V8ISD { +namespace SPISD { enum { - FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END, + FIRST_NUMBER = ISD::BUILTIN_OP_END+SP::INSTRUCTION_LIST_END, CMPICC, // Compare two GPR operands, set icc. CMPFCC, // Compare two FP operands, set fcc. BRICC, // Branch to dest on icc condition @@ -45,56 +45,56 @@ FTOI, // FP to Int within a FP register. ITOF, // Int to FP within a FP register. - CALL, // A V8 call instruction. + CALL, // A call instruction. RET_FLAG, // Return with a flag operand. }; } /// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC /// condition. -static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { +static SPCC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { switch (CC) { default: assert(0 && "Unknown integer condition code!"); - case ISD::SETEQ: return V8CC::ICC_E; - case ISD::SETNE: return V8CC::ICC_NE; - case ISD::SETLT: return V8CC::ICC_L; - case ISD::SETGT: return V8CC::ICC_G; - case ISD::SETLE: return V8CC::ICC_LE; - case ISD::SETGE: return V8CC::ICC_GE; - case ISD::SETULT: return V8CC::ICC_CS; - case ISD::SETULE: return V8CC::ICC_LEU; - case ISD::SETUGT: return V8CC::ICC_GU; - case ISD::SETUGE: return V8CC::ICC_CC; + case ISD::SETEQ: return SPCC::ICC_E; + case ISD::SETNE: return SPCC::ICC_NE; + case ISD::SETLT: return SPCC::ICC_L; + case ISD::SETGT: return SPCC::ICC_G; + case ISD::SETLE: return SPCC::ICC_LE; + case ISD::SETGE: return SPCC::ICC_GE; + case ISD::SETULT: return SPCC::ICC_CS; + case ISD::SETULE: return SPCC::ICC_LEU; + case ISD::SETUGT: return SPCC::ICC_GU; + case ISD::SETUGE: return SPCC::ICC_CC; } } /// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC /// FCC condition. -static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { +static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { switch (CC) { default: assert(0 && "Unknown fp condition code!"); - case ISD::SETEQ: return V8CC::FCC_E; - case ISD::SETNE: return V8CC::FCC_NE; - case ISD::SETLT: return V8CC::FCC_L; - case ISD::SETGT: return V8CC::FCC_G; - case ISD::SETLE: return V8CC::FCC_LE; - case ISD::SETGE: return V8CC::FCC_GE; - case ISD::SETULT: return V8CC::FCC_UL; - case ISD::SETULE: return V8CC::FCC_ULE; - case ISD::SETUGT: return V8CC::FCC_UG; - case ISD::SETUGE: return V8CC::FCC_UGE; - case ISD::SETUO: return V8CC::FCC_U; - case ISD::SETO: return V8CC::FCC_O; - case ISD::SETONE: return V8CC::FCC_LG; - case ISD::SETUEQ: return V8CC::FCC_UE; + case ISD::SETEQ: return SPCC::FCC_E; + case ISD::SETNE: return SPCC::FCC_NE; + case ISD::SETLT: return SPCC::FCC_L; + case ISD::SETGT: return SPCC::FCC_G; + case ISD::SETLE: return SPCC::FCC_LE; + case ISD::SETGE: return SPCC::FCC_GE; + case ISD::SETULT: return SPCC::FCC_UL; + case ISD::SETULE: return SPCC::FCC_ULE; + case ISD::SETUGT: return SPCC::FCC_UG; + case ISD::SETUGE: return SPCC::FCC_UGE; + case ISD::SETUO: return SPCC::FCC_U; + case ISD::SETO: return SPCC::FCC_O; + case ISD::SETONE: return SPCC::FCC_LG; + case ISD::SETUEQ: return SPCC::FCC_UE; } } namespace { - class SparcV8TargetLowering : public TargetLowering { + class SparcTargetLowering : public TargetLowering { int VarArgsFrameOffset; // Frame offset to start of varargs area. public: - SparcV8TargetLowering(TargetMachine &TM); + SparcTargetLowering(TargetMachine &TM); virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to @@ -120,13 +120,13 @@ }; } -SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) +SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) : TargetLowering(TM) { // Set up the register classes. - addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); - addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); - addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); + addRegisterClass(MVT::i32, SP::IntRegsRegisterClass); + addRegisterClass(MVT::f32, SP::FPRegsRegisterClass); + addRegisterClass(MVT::f64, SP::DFPRegsRegisterClass); // Custom legalize GlobalAddress nodes into LO/HI parts. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); @@ -175,7 +175,7 @@ setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); - // V8 has no intrinsics for these particular operations. + // SPARC has no intrinsics for these particular operations. setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); setOperationAction(ISD::MEMSET, MVT::Other, Expand); setOperationAction(ISD::MEMCPY, MVT::Other, Expand); @@ -218,42 +218,42 @@ setOperationAction(ISD::ConstantFP, MVT::f64, Expand); setOperationAction(ISD::ConstantFP, MVT::f32, Expand); - setStackPointerRegisterToSaveRestore(V8::O6); + setStackPointerRegisterToSaveRestore(SP::O6); - if (TM.getSubtarget().isV9()) { + if (TM.getSubtarget().isV9()) { setOperationAction(ISD::CTPOP, MVT::i32, Legal); } computeRegisterProperties(); } -const char *SparcV8TargetLowering::getTargetNodeName(unsigned Opcode) const { +const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { default: return 0; - case V8ISD::CMPICC: return "V8ISD::CMPICC"; - case V8ISD::CMPFCC: return "V8ISD::CMPFCC"; - case V8ISD::BRICC: return "V8ISD::BRICC"; - case V8ISD::BRFCC: return "V8ISD::BRFCC"; - case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; - case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; - case V8ISD::Hi: return "V8ISD::Hi"; - case V8ISD::Lo: return "V8ISD::Lo"; - case V8ISD::FTOI: return "V8ISD::FTOI"; - case V8ISD::ITOF: return "V8ISD::ITOF"; - case V8ISD::CALL: return "V8ISD::CALL"; - case V8ISD::RET_FLAG: return "V8ISD::RET_FLAG"; + case SPISD::CMPICC: return "SPISD::CMPICC"; + case SPISD::CMPFCC: return "SPISD::CMPFCC"; + case SPISD::BRICC: return "SPISD::BRICC"; + case SPISD::BRFCC: return "SPISD::BRFCC"; + case SPISD::SELECT_ICC: return "SPISD::SELECT_ICC"; + case SPISD::SELECT_FCC: return "SPISD::SELECT_FCC"; + case SPISD::Hi: return "SPISD::Hi"; + case SPISD::Lo: return "SPISD::Lo"; + case SPISD::FTOI: return "SPISD::FTOI"; + case SPISD::ITOF: return "SPISD::ITOF"; + case SPISD::CALL: return "SPISD::CALL"; + case SPISD::RET_FLAG: return "SPISD::RET_FLAG"; } } /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to /// be zero. Op is expected to be a target specific node. Used by DAG /// combiner. -bool SparcV8TargetLowering:: +bool SparcTargetLowering:: isMaskedValueZeroForTargetNode(const SDOperand &Op, uint64_t Mask) const { switch (Op.getOpcode()) { default: return false; - case V8ISD::SELECT_ICC: - case V8ISD::SELECT_FCC: + case SPISD::SELECT_ICC: + case SPISD::SELECT_FCC: assert(MVT::isInteger(Op.getValueType()) && "Not an integer select!"); // These operations are masked zero if both the left and the right are zero. return MaskedValueIsZero(Op.getOperand(0), Mask) && @@ -266,13 +266,13 @@ /// either one or two GPRs, including FP values. TODO: we should pass FP values /// in FP registers for fastcc functions. std::vector -SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { +SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); SSARegMap *RegMap = MF.getSSARegMap(); std::vector ArgValues; static const unsigned ArgRegs[] = { - V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 + SP::I0, SP::I1, SP::I2, SP::I3, SP::I4, SP::I5 }; const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6; @@ -294,7 +294,7 @@ if (CurArgReg < ArgRegEnd) ++CurArgReg; ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR - unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); + unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass); MF.addLiveIn(*CurArgReg++, VReg); SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); if (ObjectVT != MVT::i32) { @@ -334,7 +334,7 @@ ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR // FP value is passed in an integer register. - unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); + unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass); MF.addLiveIn(*CurArgReg++, VReg); SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); @@ -369,7 +369,7 @@ } else { SDOperand HiVal; if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR - unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass); + unsigned VRegHi = RegMap->createVirtualRegister(&SP::IntRegsRegClass); MF.addLiveIn(*CurArgReg++, VRegHi); HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32); } else { @@ -380,7 +380,7 @@ SDOperand LoVal; if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR - unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass); + unsigned VRegLo = RegMap->createVirtualRegister(&SP::IntRegsRegClass); MF.addLiveIn(*CurArgReg++, VRegLo); LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32); } else { @@ -410,7 +410,7 @@ VarArgsFrameOffset = ArgOffset; for (; CurArgReg != ArgRegEnd; ++CurArgReg) { - unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); + unsigned VReg = RegMap->createVirtualRegister(&SP::IntRegsRegClass); MF.addLiveIn(*CurArgReg, VReg); SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); @@ -434,17 +434,17 @@ case MVT::i8: case MVT::i16: case MVT::i32: - MF.addLiveOut(V8::I0); + MF.addLiveOut(SP::I0); break; case MVT::i64: - MF.addLiveOut(V8::I0); - MF.addLiveOut(V8::I1); + MF.addLiveOut(SP::I0); + MF.addLiveOut(SP::I1); break; case MVT::f32: - MF.addLiveOut(V8::F0); + MF.addLiveOut(SP::F0); break; case MVT::f64: - MF.addLiveOut(V8::D0); + MF.addLiveOut(SP::D0); break; } @@ -452,10 +452,10 @@ } std::pair -SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, - bool isVarArg, unsigned CC, - bool isTailCall, SDOperand Callee, - ArgListTy &Args, SelectionDAG &DAG) { +SparcTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, + bool isVarArg, unsigned CC, + bool isTailCall, SDOperand Callee, + ArgListTy &Args, SelectionDAG &DAG) { MachineFunction &MF = DAG.getMachineFunction(); // Count the size of the outgoing arguments. unsigned ArgsSize = 0; @@ -565,7 +565,7 @@ if (ValToStore.Val) { if (!StackPtr.Val) { - StackPtr = DAG.getRegister(V8::O6, MVT::i32); + StackPtr = DAG.getRegister(SP::O6, MVT::i32); NullSV = DAG.getSrcValue(NULL); } SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); @@ -581,7 +581,7 @@ Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); static const unsigned ArgRegs[] = { - V8::O0, V8::O1, V8::O2, V8::O3, V8::O4, V8::O5 + SP::O0, SP::O1, SP::O2, SP::O3, SP::O4, SP::O5 }; // Build a sequence of copy-to-reg nodes chained together with token chain @@ -605,7 +605,7 @@ Ops.push_back(Callee); if (InFlag.Val) Ops.push_back(InFlag); - Chain = DAG.getNode(V8ISD::CALL, NodeTys, Ops); + Chain = DAG.getNode(SPISD::CALL, NodeTys, Ops); InFlag = Chain.getValue(1); MVT::ValueType RetTyVT = getValueType(RetTy); @@ -616,7 +616,7 @@ case MVT::i1: case MVT::i8: case MVT::i16: - RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag); + RetVal = DAG.getCopyFromReg(Chain, SP::O0, MVT::i32, InFlag); Chain = RetVal.getValue(1); // Add a note to keep track of whether it is sign or zero extended. @@ -625,20 +625,20 @@ RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); break; case MVT::i32: - RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag); + RetVal = DAG.getCopyFromReg(Chain, SP::O0, MVT::i32, InFlag); Chain = RetVal.getValue(1); break; case MVT::f32: - RetVal = DAG.getCopyFromReg(Chain, V8::F0, MVT::f32, InFlag); + RetVal = DAG.getCopyFromReg(Chain, SP::F0, MVT::f32, InFlag); Chain = RetVal.getValue(1); break; case MVT::f64: - RetVal = DAG.getCopyFromReg(Chain, V8::D0, MVT::f64, InFlag); + RetVal = DAG.getCopyFromReg(Chain, SP::D0, MVT::f64, InFlag); Chain = RetVal.getValue(1); break; case MVT::i64: - SDOperand Lo = DAG.getCopyFromReg(Chain, V8::O1, MVT::i32, InFlag); - SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), V8::O0, MVT::i32, + SDOperand Lo = DAG.getCopyFromReg(Chain, SP::O1, MVT::i32, InFlag); + SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), SP::O0, MVT::i32, Lo.getValue(2)); RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); Chain = Hi.getValue(1); @@ -652,64 +652,64 @@ return std::make_pair(RetVal, Chain); } -std::pair SparcV8TargetLowering:: +std::pair SparcTargetLowering:: LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG) { assert(0 && "Unimp"); abort(); } -// Look at LHS/RHS/CC and see if they are a lowered V8 setcc instruction. If so -// set LHS/RHS and V8CC to the LHS/RHS of the setcc and V8CC to the condition. +// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so +// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition. static void LookThroughSetCC(SDOperand &LHS, SDOperand &RHS, - ISD::CondCode CC, unsigned &V8CC) { + ISD::CondCode CC, unsigned &SPCC) { if (isa(RHS) && cast(RHS)->getValue() == 0 && CC == ISD::SETNE && - ((LHS.getOpcode() == V8ISD::SELECT_ICC && - LHS.getOperand(3).getOpcode() == V8ISD::CMPICC) || - (LHS.getOpcode() == V8ISD::SELECT_FCC && - LHS.getOperand(3).getOpcode() == V8ISD::CMPFCC)) && + ((LHS.getOpcode() == SPISD::SELECT_ICC && + LHS.getOperand(3).getOpcode() == SPISD::CMPICC) || + (LHS.getOpcode() == SPISD::SELECT_FCC && + LHS.getOperand(3).getOpcode() == SPISD::CMPFCC)) && isa(LHS.getOperand(0)) && isa(LHS.getOperand(1)) && cast(LHS.getOperand(0))->getValue() == 1 && cast(LHS.getOperand(1))->getValue() == 0) { SDOperand CMPCC = LHS.getOperand(3); - V8CC = cast(LHS.getOperand(2))->getValue(); + SPCC = cast(LHS.getOperand(2))->getValue(); LHS = CMPCC.getOperand(0); RHS = CMPCC.getOperand(1); } } -SDOperand SparcV8TargetLowering:: +SDOperand SparcTargetLowering:: LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Should not custom lower this!"); case ISD::GlobalAddress: { GlobalValue *GV = cast(Op)->getGlobal(); SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); - SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA); - SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA); + SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, GA); + SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, GA); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); } case ISD::ConstantPool: { Constant *C = cast(Op)->get(); SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, cast(Op)->getAlignment()); - SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP); - SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP); + SDOperand Hi = DAG.getNode(SPISD::Hi, MVT::i32, CP); + SDOperand Lo = DAG.getNode(SPISD::Lo, MVT::i32, CP); return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); } case ISD::FP_TO_SINT: // Convert the fp value to integer in an FP register. assert(Op.getValueType() == MVT::i32); - Op = DAG.getNode(V8ISD::FTOI, MVT::f32, Op.getOperand(0)); + Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0)); return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op); case ISD::SINT_TO_FP: { assert(Op.getOperand(0).getValueType() == MVT::i32); SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Op.getOperand(0)); // Convert the int value to FP in an FP register. - return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Tmp); + return DAG.getNode(SPISD::ITOF, Op.getValueType(), Tmp); } case ISD::BR_CC: { SDOperand Chain = Op.getOperand(0); @@ -717,11 +717,11 @@ SDOperand LHS = Op.getOperand(2); SDOperand RHS = Op.getOperand(3); SDOperand Dest = Op.getOperand(4); - unsigned Opc, V8CC = ~0U; + unsigned Opc, SPCC = ~0U; // If this is a br_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. - LookThroughSetCC(LHS, RHS, CC, V8CC); + LookThroughSetCC(LHS, RHS, CC, SPCC); // Get the condition flag. SDOperand CompareFlag; @@ -732,16 +732,16 @@ std::vector Ops; Ops.push_back(LHS); Ops.push_back(RHS); - CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); - if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); - Opc = V8ISD::BRICC; + CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1); + if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); + Opc = SPISD::BRICC; } else { - CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); - if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); - Opc = V8ISD::BRFCC; + CompareFlag = DAG.getNode(SPISD::CMPFCC, MVT::Flag, LHS, RHS); + if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); + Opc = SPISD::BRFCC; } return DAG.getNode(Opc, MVT::Other, Chain, Dest, - DAG.getConstant(V8CC, MVT::i32), CompareFlag); + DAG.getConstant(SPCC, MVT::i32), CompareFlag); } case ISD::SELECT_CC: { SDOperand LHS = Op.getOperand(0); @@ -749,11 +749,11 @@ ISD::CondCode CC = cast(Op.getOperand(4))->get(); SDOperand TrueVal = Op.getOperand(2); SDOperand FalseVal = Op.getOperand(3); - unsigned Opc, V8CC = ~0U; + unsigned Opc, SPCC = ~0U; // If this is a select_cc of a "setcc", and if the setcc got lowered into // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. - LookThroughSetCC(LHS, RHS, CC, V8CC); + LookThroughSetCC(LHS, RHS, CC, SPCC); SDOperand CompareFlag; if (LHS.getValueType() == MVT::i32) { @@ -763,22 +763,22 @@ std::vector Ops; Ops.push_back(LHS); Ops.push_back(RHS); - CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); - Opc = V8ISD::SELECT_ICC; - if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); + CompareFlag = DAG.getNode(SPISD::CMPICC, VTs, Ops).getValue(1); + Opc = SPISD::SELECT_ICC; + if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); } else { - CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); - Opc = V8ISD::SELECT_FCC; - if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); + CompareFlag = DAG.getNode(SPISD::CMPFCC, MVT::Flag, LHS, RHS); + Opc = SPISD::SELECT_FCC; + if (SPCC == ~0U) SPCC = FPCondCCodeToFCC(CC); } return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, - DAG.getConstant(V8CC, MVT::i32), CompareFlag); + DAG.getConstant(SPCC, MVT::i32), CompareFlag); } case ISD::VASTART: { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, - DAG.getRegister(V8::I6, MVT::i32), + DAG.getRegister(SP::I6, MVT::i32), DAG.getConstant(VarArgsFrameOffset, MVT::i32)); return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, Op.getOperand(1), Op.getOperand(2)); @@ -827,46 +827,46 @@ unsigned ArgReg; switch(Op.getOperand(1).getValueType()) { default: assert(0 && "Unknown type to return!"); - case MVT::i32: ArgReg = V8::I0; break; - case MVT::f32: ArgReg = V8::F0; break; - case MVT::f64: ArgReg = V8::D0; break; + case MVT::i32: ArgReg = SP::I0; break; + case MVT::f32: ArgReg = SP::F0; break; + case MVT::f64: ArgReg = SP::D0; break; } Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1), SDOperand()); break; } case 3: - Copy = DAG.getCopyToReg(Op.getOperand(0), V8::I0, Op.getOperand(2), + Copy = DAG.getCopyToReg(Op.getOperand(0), SP::I0, Op.getOperand(2), SDOperand()); - Copy = DAG.getCopyToReg(Copy, V8::I1, Op.getOperand(1), Copy.getValue(1)); + Copy = DAG.getCopyToReg(Copy, SP::I1, Op.getOperand(1), Copy.getValue(1)); break; } - return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); + return DAG.getNode(SPISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); } } } MachineBasicBlock * -SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, - MachineBasicBlock *BB) { +SparcTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) { unsigned BROpcode; unsigned CC; // Figure out the conditional branch opcode to use for this select_cc. switch (MI->getOpcode()) { default: assert(0 && "Unknown SELECT_CC!"); - case V8::SELECT_CC_Int_ICC: - case V8::SELECT_CC_FP_ICC: - case V8::SELECT_CC_DFP_ICC: - BROpcode = V8::BCOND; + case SP::SELECT_CC_Int_ICC: + case SP::SELECT_CC_FP_ICC: + case SP::SELECT_CC_DFP_ICC: + BROpcode = SP::BCOND; break; - case V8::SELECT_CC_Int_FCC: - case V8::SELECT_CC_FP_FCC: - case V8::SELECT_CC_DFP_FCC: - BROpcode = V8::FBCOND; + case SP::SELECT_CC_Int_FCC: + case SP::SELECT_CC_FP_FCC: + case SP::SELECT_CC_DFP_FCC: + BROpcode = SP::FBCOND; break; } - CC = (V8CC::CondCodes)MI->getOperand(3).getImmedValue(); + CC = (SPCC::CondCodes)MI->getOperand(3).getImmedValue(); // To "insert" a SELECT_CC instruction, we actually have to insert the diamond // control-flow pattern. The incoming instruction knows the destination vreg @@ -904,7 +904,7 @@ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] // ... BB = sinkMBB; - BuildMI(BB, V8::PHI, 4, MI->getOperand(0).getReg()) + BuildMI(BB, SP::PHI, 4, MI->getOperand(0).getReg()) .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); @@ -917,20 +917,20 @@ //===----------------------------------------------------------------------===// //===--------------------------------------------------------------------===// -/// SparcV8DAGToDAGISel - SPARC specific code to select Sparc V8 machine +/// SparcDAGToDAGISel - SPARC specific code to select SPARC machine /// instructions for SelectionDAG operations. /// namespace { -class SparcV8DAGToDAGISel : public SelectionDAGISel { - SparcV8TargetLowering V8Lowering; +class SparcDAGToDAGISel : public SelectionDAGISel { + SparcTargetLowering Lowering; /// Subtarget - Keep a pointer to the Sparc Subtarget around so that we can /// make the right decision when generating code for different targets. - const SparcV8Subtarget &Subtarget; + const SparcSubtarget &Subtarget; public: - SparcV8DAGToDAGISel(TargetMachine &TM) - : SelectionDAGISel(V8Lowering), V8Lowering(TM), - Subtarget(TM.getSubtarget()) { + SparcDAGToDAGISel(TargetMachine &TM) + : SelectionDAGISel(Lowering), Lowering(TM), + Subtarget(TM.getSubtarget()) { } SDOperand Select(SDOperand Op); @@ -944,17 +944,17 @@ virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); virtual const char *getPassName() const { - return "SparcV8 DAG->DAG Pattern Instruction Selection"; + return "SPARC DAG->DAG Pattern Instruction Selection"; } // Include the pieces autogenerated from the target description. -#include "SparcV8GenDAGISel.inc" +#include "SparcGenDAGISel.inc" }; } // end anonymous namespace /// InstructionSelectBasicBlock - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { +void SparcDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { DEBUG(BB->dump()); // Select target instructions for the DAG. @@ -966,7 +966,7 @@ ScheduleAndEmitDAG(DAG); } -bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, +bool SparcDAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, SDOperand &Offset) { if (FrameIndexSDNode *FIN = dyn_cast(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); @@ -988,12 +988,12 @@ return true; } } - if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) { + if (Addr.getOperand(0).getOpcode() == SPISD::Lo) { Base = Select(Addr.getOperand(1)); Offset = Addr.getOperand(0).getOperand(0); return true; } - if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) { + if (Addr.getOperand(1).getOpcode() == SPISD::Lo) { Base = Select(Addr.getOperand(0)); Offset = Addr.getOperand(1).getOperand(0); return true; @@ -1004,15 +1004,15 @@ return true; } -bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, - SDOperand &R2) { +bool SparcDAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, + SDOperand &R2) { if (Addr.getOpcode() == ISD::FrameIndex) return false; if (Addr.getOpcode() == ISD::ADD) { if (isa(Addr.getOperand(1)) && Predicate_simm13(Addr.getOperand(1).Val)) return false; // Let the reg+imm pattern catch this! - if (Addr.getOperand(0).getOpcode() == V8ISD::Lo || - Addr.getOperand(1).getOpcode() == V8ISD::Lo) + if (Addr.getOperand(0).getOpcode() == SPISD::Lo || + Addr.getOperand(1).getOpcode() == SPISD::Lo) return false; // Let the reg+imm pattern catch this! R1 = Select(Addr.getOperand(0)); R2 = Select(Addr.getOperand(1)); @@ -1020,14 +1020,14 @@ } R1 = Select(Addr); - R2 = CurDAG->getRegister(V8::G0, MVT::i32); + R2 = CurDAG->getRegister(SP::G0, MVT::i32); return true; } -SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { +SDOperand SparcDAGToDAGISel::Select(SDOperand Op) { SDNode *N = Op.Val; if (N->getOpcode() >= ISD::BUILTIN_OP_END && - N->getOpcode() < V8ISD::FIRST_NUMBER) + N->getOpcode() < SPISD::FIRST_NUMBER) return Op; // Already selected. // If this has already been converted, use it. std::map::iterator CGMI = CodeGenMap.find(Op); @@ -1038,11 +1038,11 @@ case ISD::FrameIndex: { int FI = cast(N)->getIndex(); if (N->hasOneUse()) - return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32, + return CurDAG->SelectNodeTo(N, SP::ADDri, MVT::i32, CurDAG->getTargetFrameIndex(FI, MVT::i32), CurDAG->getTargetConstant(0, MVT::i32)); return CodeGenMap[Op] = - CurDAG->getTargetNode(V8::ADDri, MVT::i32, + CurDAG->getTargetNode(SP::ADDri, MVT::i32, CurDAG->getTargetFrameIndex(FI, MVT::i32), CurDAG->getTargetConstant(0, MVT::i32)); } @@ -1052,9 +1052,9 @@ SDOperand RHSL = Select(N->getOperand(2)); SDOperand RHSH = Select(N->getOperand(3)); // FIXME, handle immediate RHS. - SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag, + SDOperand Low = CurDAG->getTargetNode(SP::ADDCCrr, MVT::i32, MVT::Flag, LHSL, RHSL); - SDOperand Hi = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, + SDOperand Hi = CurDAG->getTargetNode(SP::ADDXrr, MVT::i32, LHSH, RHSH, Low.getValue(1)); CodeGenMap[SDOperand(N, 0)] = Low; CodeGenMap[SDOperand(N, 1)] = Hi; @@ -1066,9 +1066,9 @@ SDOperand RHSL = Select(N->getOperand(2)); SDOperand RHSH = Select(N->getOperand(3)); // FIXME, handle immediate RHS. - SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag, + SDOperand Low = CurDAG->getTargetNode(SP::SUBCCrr, MVT::i32, MVT::Flag, LHSL, RHSL); - SDOperand Hi = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, + SDOperand Hi = CurDAG->getTargetNode(SP::SUBXrr, MVT::i32, LHSH, RHSH, Low.getValue(1)); CodeGenMap[SDOperand(N, 0)] = Low; CodeGenMap[SDOperand(N, 1)] = Hi; @@ -1083,16 +1083,16 @@ // Set the Y register to the high-part. SDOperand TopPart; if (N->getOpcode() == ISD::SDIV) { - TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS, + TopPart = CurDAG->getTargetNode(SP::SRAri, MVT::i32, DivLHS, CurDAG->getTargetConstant(31, MVT::i32)); } else { - TopPart = CurDAG->getRegister(V8::G0, MVT::i32); + TopPart = CurDAG->getRegister(SP::G0, MVT::i32); } - TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart, - CurDAG->getRegister(V8::G0, MVT::i32)); + TopPart = CurDAG->getTargetNode(SP::WRYrr, MVT::Flag, TopPart, + CurDAG->getRegister(SP::G0, MVT::i32)); // FIXME: Handle div by immediate. - unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr; + unsigned Opcode = N->getOpcode() == ISD::SDIV ? SP::SDIVrr : SP::UDIVrr; return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); } case ISD::MULHU: @@ -1100,13 +1100,13 @@ // FIXME: Handle mul by immediate. SDOperand MulLHS = Select(N->getOperand(0)); SDOperand MulRHS = Select(N->getOperand(1)); - unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr; + unsigned Opcode = N->getOpcode() == ISD::MULHU ? SP::UMULrr : SP::SMULrr; SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag, MulLHS, MulRHS); // The high part is in the Y register. - return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1)); + return CurDAG->SelectNodeTo(N, SP::RDY, MVT::i32, Mul.getValue(1)); } - case V8ISD::CALL: + case SPISD::CALL: // FIXME: This is a workaround for a bug in tblgen. { // Pattern #47: (call:Flag (tglobaladdr:i32):$dst, ICC:Flag) // Emits: (CALL:void (tglobaladdr:i32):$dst) @@ -1121,10 +1121,10 @@ SDOperand Result; if (N->getNumOperands() == 3) { InFlag = Select(N->getOperand(2)); - Result = CurDAG->getTargetNode(V8::CALL, MVT::Other, MVT::Flag, Tmp0, + Result = CurDAG->getTargetNode(SP::CALL, MVT::Other, MVT::Flag, Tmp0, Chain, InFlag); } else { - Result = CurDAG->getTargetNode(V8::CALL, MVT::Other, MVT::Flag, Tmp0, + Result = CurDAG->getTargetNode(SP::CALL, MVT::Other, MVT::Flag, Tmp0, Chain); } Chain = CodeGenMap[SDOperand(N, 0)] = Result.getValue(0); @@ -1139,9 +1139,9 @@ } -/// createSparcV8ISelDag - This pass converts a legalized DAG into a +/// createSparcISelDag - This pass converts a legalized DAG into a /// SPARC-specific DAG, ready for instruction scheduling. /// -FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { - return new SparcV8DAGToDAGISel(TM); +FunctionPass *llvm::createSparcISelDag(TargetMachine &TM) { + return new SparcDAGToDAGISel(TM); } Index: llvm/lib/Target/Sparc/SparcInstrFormats.td diff -u llvm/lib/Target/Sparc/SparcInstrFormats.td:1.15 llvm/lib/Target/Sparc/SparcInstrFormats.td:1.16 --- llvm/lib/Target/Sparc/SparcInstrFormats.td:1.15 Sun Dec 18 02:21:00 2005 +++ llvm/lib/Target/Sparc/SparcInstrFormats.td Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8InstrFormats.td - SparcV8 Instr Formats ------*- tablegen -*-===// +//===- SparcInstrFormats.td - Sparc Instruction Formats ----*- tablegen -*-===// // // The LLVM Compiler Infrastructure // @@ -7,10 +7,10 @@ // //===----------------------------------------------------------------------===// -class InstV8 pattern> : Instruction { +class InstSP pattern> : Instruction { field bits<32> Inst; - let Namespace = "V8"; + let Namespace = "SP"; bits<2> op; let Inst{31-30} = op; // Top two bits are the 'op' field @@ -21,12 +21,12 @@ } //===----------------------------------------------------------------------===// -// Format #2 instruction classes in the SparcV8 +// Format #2 instruction classes in the Sparc //===----------------------------------------------------------------------===// // Format 2 instructions class F2 pattern> - : InstV8 { + : InstSP { bits<3> op2; bits<22> imm22; let op = 0; // op = 0 @@ -58,11 +58,11 @@ } //===----------------------------------------------------------------------===// -// Format #3 instruction classes in the SparcV8 +// Format #3 instruction classes in the Sparc //===----------------------------------------------------------------------===// class F3 pattern> - : InstV8 { + : InstSP { bits<5> rd; bits<6> op3; bits<5> rs1; @@ -76,7 +76,7 @@ // class F3_1 opVal, bits<6> op3val, dag ops, string asmstr, list pattern> : F3 { - bits<8> asi = 0; // asi not currently used in SparcV8 + bits<8> asi = 0; // asi not currently used bits<5> rs2; let op = opVal; Index: llvm/lib/Target/Sparc/SparcInstrInfo.cpp diff -u llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.12 llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.13 --- llvm/lib/Target/Sparc/SparcInstrInfo.cpp:1.12 Sat Feb 4 01:48:46 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8InstrInfo.cpp - SparcV8 Instruction Information ---*- C++ -*-===// +//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,18 @@ // //===----------------------------------------------------------------------===// // -// This file contains the SparcV8 implementation of the TargetInstrInfo class. +// This file contains the Sparc implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// -#include "SparcV8InstrInfo.h" -#include "SparcV8.h" +#include "SparcInstrInfo.h" +#include "Sparc.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "SparcV8GenInstrInfo.inc" +#include "SparcGenInstrInfo.inc" using namespace llvm; -SparcV8InstrInfo::SparcV8InstrInfo(SparcV8Subtarget &ST) - : TargetInstrInfo(SparcV8Insts, sizeof(SparcV8Insts)/sizeof(SparcV8Insts[0])), +SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) + : TargetInstrInfo(SparcInsts, sizeof(SparcInsts)/sizeof(SparcInsts[0])), RI(ST) { } @@ -29,29 +29,29 @@ /// Return true if the instruction is a register to register move and /// leave the source and dest operands in the passed parameters. /// -bool SparcV8InstrInfo::isMoveInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DstReg) const { +bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, + unsigned &SrcReg, unsigned &DstReg) const { // We look for 3 kinds of patterns here: // or with G0 or 0 // add with G0 or 0 // fmovs or FpMOVD (pseudo double move). - if (MI.getOpcode() == V8::ORrr || MI.getOpcode() == V8::ADDrr) { - if (MI.getOperand(1).getReg() == V8::G0) { + if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { + if (MI.getOperand(1).getReg() == SP::G0) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(2).getReg(); return true; - } else if (MI.getOperand(2).getReg() == V8::G0) { + } else if (MI.getOperand(2).getReg() == SP::G0) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(1).getReg(); return true; } - } else if ((MI.getOpcode() == V8::ORri || MI.getOpcode() == V8::ADDri) && + } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(1).getReg(); return true; - } else if (MI.getOpcode() == V8::FMOVS || MI.getOpcode() == V8::FpMOVD || - MI.getOpcode() == V8::FMOVD) { + } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || + MI.getOpcode() == SP::FMOVD) { SrcReg = MI.getOperand(1).getReg(); DstReg = MI.getOperand(0).getReg(); return true; @@ -64,11 +64,11 @@ /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. -unsigned SparcV8InstrInfo::isLoadFromStackSlot(MachineInstr *MI, - int &FrameIndex) const { - if (MI->getOpcode() == V8::LDri || - MI->getOpcode() == V8::LDFri || - MI->getOpcode() == V8::LDDFri) { +unsigned SparcInstrInfo::isLoadFromStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == SP::LDri || + MI->getOpcode() == SP::LDFri || + MI->getOpcode() == SP::LDDFri) { if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && MI->getOperand(2).getImmedValue() == 0) { FrameIndex = MI->getOperand(1).getFrameIndex(); @@ -83,11 +83,11 @@ /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned SparcV8InstrInfo::isStoreToStackSlot(MachineInstr *MI, - int &FrameIndex) const { - if (MI->getOpcode() == V8::STri || - MI->getOpcode() == V8::STFri || - MI->getOpcode() == V8::STDFri) { +unsigned SparcInstrInfo::isStoreToStackSlot(MachineInstr *MI, + int &FrameIndex) const { + if (MI->getOpcode() == SP::STri || + MI->getOpcode() == SP::STFri || + MI->getOpcode() == SP::STDFri) { if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && MI->getOperand(1).getImmedValue() == 0) { FrameIndex = MI->getOperand(0).getFrameIndex(); Index: llvm/lib/Target/Sparc/SparcInstrInfo.h diff -u llvm/lib/Target/Sparc/SparcInstrInfo.h:1.7 llvm/lib/Target/Sparc/SparcInstrInfo.h:1.8 --- llvm/lib/Target/Sparc/SparcInstrInfo.h:1.7 Sat Feb 4 00:58:46 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.h Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8InstrInfo.h - SparcV8 Instruction Information -----*- C++ -*-===// +//===- SparcInstrInfo.h - Sparc Instruction Information ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,22 @@ // //===----------------------------------------------------------------------===// // -// This file contains the SparcV8 implementation of the TargetInstrInfo class. +// This file contains the Sparc implementation of the TargetInstrInfo class. // //===----------------------------------------------------------------------===// -#ifndef SPARCV8INSTRUCTIONINFO_H -#define SPARCV8INSTRUCTIONINFO_H +#ifndef SPARCINSTRUCTIONINFO_H +#define SPARCINSTRUCTIONINFO_H #include "llvm/Target/TargetInstrInfo.h" -#include "SparcV8RegisterInfo.h" +#include "SparcRegisterInfo.h" namespace llvm { -/// V8II - This namespace holds all of the target specific flags that +/// SPII - This namespace holds all of the target specific flags that /// instruction info tracks. /// -namespace V8II { +namespace SPII { enum { Pseudo = (1<<0), Load = (1<<1), @@ -31,10 +31,10 @@ }; }; -class SparcV8InstrInfo : public TargetInstrInfo { - const SparcV8RegisterInfo RI; +class SparcInstrInfo : public TargetInstrInfo { + const SparcRegisterInfo RI; public: - SparcV8InstrInfo(SparcV8Subtarget &ST); + SparcInstrInfo(SparcSubtarget &ST); /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As /// such, whenever a client has an instance of instruction info, it should Index: llvm/lib/Target/Sparc/SparcInstrInfo.td diff -u llvm/lib/Target/Sparc/SparcInstrInfo.td:1.117 llvm/lib/Target/Sparc/SparcInstrInfo.td:1.118 --- llvm/lib/Target/Sparc/SparcInstrInfo.td:1.117 Thu Feb 2 02:02:20 2006 +++ llvm/lib/Target/Sparc/SparcInstrInfo.td Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8Instrs.td - Target Description for SparcV8 Target -----------===// +//===- SparcInstrInfo.td - Target Description for Sparc Target ------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file describes the SparcV8 instructions in TableGen format. +// This file describes the Sparc instructions in TableGen format. // //===----------------------------------------------------------------------===// @@ -15,7 +15,7 @@ // Instruction format superclass //===----------------------------------------------------------------------===// -include "SparcV8InstrFormats.td" +include "SparcInstrFormats.td" //===----------------------------------------------------------------------===// // Feature predicates. @@ -87,54 +87,54 @@ def calltarget : Operand; // Operand for printing out a condition code. -let PrintMethod = "printV8CCOperand" in - def V8CC : Operand; +let PrintMethod = "printCCOperand" in + def CCOp : Operand; -def SDTV8cmpfcc : +def SDTSPcmpfcc : SDTypeProfile<1, 2, [SDTCisVT<0, FlagVT>, SDTCisFP<1>, SDTCisSameAs<1, 2>]>; -def SDTV8brcc : +def SDTSPbrcc : SDTypeProfile<0, 3, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>, SDTCisVT<2, FlagVT>]>; -def SDTV8selectcc : +def SDTSPselectcc : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>, SDTCisVT<4, FlagVT>]>; -def SDTV8FTOI : +def SDTSPFTOI : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; -def SDTV8ITOF : +def SDTSPITOF : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; -def V8cmpicc : SDNode<"V8ISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>; -def V8cmpfcc : SDNode<"V8ISD::CMPFCC", SDTV8cmpfcc, [SDNPOutFlag]>; -def V8bricc : SDNode<"V8ISD::BRICC", SDTV8brcc, [SDNPHasChain]>; -def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>; +def SPcmpicc : SDNode<"SPISD::CMPICC", SDTIntBinOp, [SDNPOutFlag]>; +def SPcmpfcc : SDNode<"SPISD::CMPFCC", SDTSPcmpfcc, [SDNPOutFlag]>; +def SPbricc : SDNode<"SPISD::BRICC", SDTSPbrcc, [SDNPHasChain]>; +def SPbrfcc : SDNode<"SPISD::BRFCC", SDTSPbrcc, [SDNPHasChain]>; -def V8hi : SDNode<"V8ISD::Hi", SDTIntUnaryOp>; -def V8lo : SDNode<"V8ISD::Lo", SDTIntUnaryOp>; +def SPhi : SDNode<"SPISD::Hi", SDTIntUnaryOp>; +def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>; -def V8ftoi : SDNode<"V8ISD::FTOI", SDTV8FTOI>; -def V8itof : SDNode<"V8ISD::ITOF", SDTV8ITOF>; +def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>; +def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>; -def V8selecticc : SDNode<"V8ISD::SELECT_ICC", SDTV8selectcc>; -def V8selectfcc : SDNode<"V8ISD::SELECT_FCC", SDTV8selectcc>; +def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc>; +def SPselectfcc : SDNode<"SPISD::SELECT_FCC", SDTSPselectcc>; // These are target-independent nodes, but have target-specific formats. -def SDT_V8CallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; -def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_V8CallSeq, [SDNPHasChain]>; -def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_V8CallSeq, [SDNPHasChain]>; +def SDT_SPCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeq, [SDNPHasChain]>; +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeq, [SDNPHasChain]>; -def SDT_V8Call : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; -def call : SDNode<"V8ISD::CALL", SDT_V8Call, +def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def call : SDNode<"SPISD::CALL", SDT_SPCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -def SDT_V8RetFlag : SDTypeProfile<0, 0, []>; -def retflag : SDNode<"V8ISD::RET_FLAG", SDT_V8RetFlag, +def SDT_SPRetFlag : SDTypeProfile<0, 0, []>; +def retflag : SDNode<"SPISD::RET_FLAG", SDT_SPRetFlag, [SDNPHasChain, SDNPOptInFlag]>; //===----------------------------------------------------------------------===// // SPARC Flag Conditions //===----------------------------------------------------------------------===// -// Note that these values must be kept in sync with the V8CC::CondCode enum +// Note that these values must be kept in sync with the CCOp::CondCode enum // values. class ICC_VAL : PatLeaf<(i32 N)>; def ICC_NE : ICC_VAL< 9>; // Not Equal @@ -175,7 +175,7 @@ // Pseudo instructions. class Pseudo pattern> - : InstV8; + : InstSP; def ADJCALLSTACKDOWN : Pseudo<(ops i32imm:$amt), "!ADJCALLSTACKDOWN $amt", @@ -193,7 +193,7 @@ // FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the // fpmover pass. -let Predicates = [HasNoV9] in { // Only emit these in V8 mode. +let Predicates = [HasNoV9] in { // Only emit these in SP mode. def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), "!FpMOVD $src, $dst", []>; def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), @@ -212,32 +212,32 @@ def SELECT_CC_Int_ICC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", - [(set IntRegs:$dst, (V8selecticc IntRegs:$T, IntRegs:$F, + [(set IntRegs:$dst, (SPselecticc IntRegs:$T, IntRegs:$F, imm:$Cond, ICC))]>; def SELECT_CC_Int_FCC : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, i32imm:$Cond), "; SELECT_CC_Int_FCC PSEUDO!", - [(set IntRegs:$dst, (V8selectfcc IntRegs:$T, IntRegs:$F, + [(set IntRegs:$dst, (SPselectfcc IntRegs:$T, IntRegs:$F, imm:$Cond, FCC))]>; def SELECT_CC_FP_ICC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_ICC PSEUDO!", - [(set FPRegs:$dst, (V8selecticc FPRegs:$T, FPRegs:$F, + [(set FPRegs:$dst, (SPselecticc FPRegs:$T, FPRegs:$F, imm:$Cond, ICC))]>; def SELECT_CC_FP_FCC : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, i32imm:$Cond), "; SELECT_CC_FP_FCC PSEUDO!", - [(set FPRegs:$dst, (V8selectfcc FPRegs:$T, FPRegs:$F, + [(set FPRegs:$dst, (SPselectfcc FPRegs:$T, FPRegs:$F, imm:$Cond, FCC))]>; def SELECT_CC_DFP_ICC : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), "; SELECT_CC_DFP_ICC PSEUDO!", - [(set DFPRegs:$dst, (V8selecticc DFPRegs:$T, DFPRegs:$F, + [(set DFPRegs:$dst, (SPselecticc DFPRegs:$T, DFPRegs:$F, imm:$Cond, ICC))]>; def SELECT_CC_DFP_FCC : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, i32imm:$Cond), "; SELECT_CC_DFP_FCC PSEUDO!", - [(set DFPRegs:$dst, (V8selectfcc DFPRegs:$T, DFPRegs:$F, + [(set DFPRegs:$dst, (SPselectfcc DFPRegs:$T, DFPRegs:$F, imm:$Cond, FCC))]>; } @@ -477,11 +477,11 @@ def SUBCCrr : F3_1<2, 0b010100, (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c), "subcc $b, $c, $dst", - [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, IntRegs:$c))]>; + [(set IntRegs:$dst, (SPcmpicc IntRegs:$b, IntRegs:$c))]>; def SUBCCri : F3_2<2, 0b010100, (ops IntRegs:$dst, IntRegs:$b, i32imm:$c), "subcc $b, $c, $dst", - [(set IntRegs:$dst, (V8cmpicc IntRegs:$b, simm13:$c))]>; + [(set IntRegs:$dst, (SPcmpicc IntRegs:$b, simm13:$c))]>; def SUBXCCrr: F3_1<2, 0b011100, (ops IntRegs:$dst, IntRegs:$b, IntRegs:$c), "subxcc $b, $c, $dst", []>; @@ -533,7 +533,7 @@ // Section B.21 - Branch on Integer Condition Codes Instructions, p. 119 // conditional branch class: -class BranchV8 cc, dag ops, string asmstr, list pattern> +class BranchSP cc, dag ops, string asmstr, list pattern> : F2_2 { let isBranch = 1; let isTerminator = 1; @@ -542,20 +542,20 @@ } let isBarrier = 1 in - def BA : BranchV8<0b1000, (ops brtarget:$dst), + def BA : BranchSP<0b1000, (ops brtarget:$dst), "ba $dst", [(br bb:$dst)]>; // FIXME: the encoding for the JIT should look at the condition field. -def BCOND : BranchV8<0, (ops brtarget:$dst, V8CC:$cc), +def BCOND : BranchSP<0, (ops brtarget:$dst, CCOp:$cc), "b$cc $dst", - [(V8bricc bb:$dst, imm:$cc, ICC)]>; + [(SPbricc bb:$dst, imm:$cc, ICC)]>; // Section B.22 - Branch on Floating-point Condition Codes Instructions, p. 121 // floating-point conditional branch class: -class FPBranchV8 cc, dag ops, string asmstr, list pattern> +class FPBranchSP cc, dag ops, string asmstr, list pattern> : F2_2 { let isBranch = 1; let isTerminator = 1; @@ -564,9 +564,9 @@ } // FIXME: the encoding for the JIT should look at the condition field. -def FBCOND : FPBranchV8<0, (ops brtarget:$dst, V8CC:$cc), +def FBCOND : FPBranchSP<0, (ops brtarget:$dst, CCOp:$cc), "fb$cc $dst", - [(V8brfcc bb:$dst, imm:$cc, FCC)]>; + [(SPbrfcc bb:$dst, imm:$cc, FCC)]>; // Section B.24 - Call and Link Instruction, p. 125 @@ -575,7 +575,7 @@ hasDelaySlot = 1, isCall = 1, noResults = 1, Defs = [O0, O1, O2, O3, O4, O5, O7, G1, G2, G3, G4, G5, G6, G7, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15] in { - def CALL : InstV8<(ops calltarget:$dst), + def CALL : InstSP<(ops calltarget:$dst), "call $dst", []> { bits<30> disp; let op = 1; @@ -610,21 +610,21 @@ def FITOS : F3_3<2, 0b110100, 0b011000100, (ops FPRegs:$dst, FPRegs:$src), "fitos $src, $dst", - [(set FPRegs:$dst, (V8itof FPRegs:$src))]>; + [(set FPRegs:$dst, (SPitof FPRegs:$src))]>; def FITOD : F3_3<2, 0b110100, 0b011001000, (ops DFPRegs:$dst, FPRegs:$src), "fitod $src, $dst", - [(set DFPRegs:$dst, (V8itof FPRegs:$src))]>; + [(set DFPRegs:$dst, (SPitof FPRegs:$src))]>; // Convert Floating-point to Integer Instructions, p. 142 def FSTOI : F3_3<2, 0b110100, 0b011010001, (ops FPRegs:$dst, FPRegs:$src), "fstoi $src, $dst", - [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>; + [(set FPRegs:$dst, (SPftoi FPRegs:$src))]>; def FDTOI : F3_3<2, 0b110100, 0b011010010, (ops FPRegs:$dst, DFPRegs:$src), "fdtoi $src, $dst", - [(set FPRegs:$dst, (V8ftoi DFPRegs:$src))]>; + [(set FPRegs:$dst, (SPftoi DFPRegs:$src))]>; // Convert between Floating-point Formats Instructions, p. 143 def FSTOD : F3_3<2, 0b110100, 0b011001001, @@ -711,11 +711,11 @@ def FCMPS : F3_3<2, 0b110101, 0b001010001, (ops FPRegs:$src1, FPRegs:$src2), "fcmps $src1, $src2\n\tnop", - [(set FCC, (V8cmpfcc FPRegs:$src1, FPRegs:$src2))]>; + [(set FCC, (SPcmpfcc FPRegs:$src1, FPRegs:$src2))]>; def FCMPD : F3_3<2, 0b110101, 0b001010010, (ops DFPRegs:$src1, DFPRegs:$src2), "fcmpd $src1, $src2\n\tnop", - [(set FCC, (V8cmpfcc DFPRegs:$src1, DFPRegs:$src2))]>; + [(set FCC, (SPcmpfcc DFPRegs:$src1, DFPRegs:$src2))]>; //===----------------------------------------------------------------------===// @@ -727,47 +727,47 @@ // Move Integer Register on Condition (MOVcc) p. 194 of the V9 manual. // FIXME: Add instruction encodings for the JIT some day. def MOVICCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, CCOp:$cc), "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>; + (SPselecticc IntRegs:$F, IntRegs:$T, imm:$cc, ICC))]>; def MOVICCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, CCOp:$cc), "mov$cc %icc, $F, $dst", [(set IntRegs:$dst, - (V8selecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>; + (SPselecticc simm11:$F, IntRegs:$T, imm:$cc, ICC))]>; def MOVFCCrr - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, V8CC:$cc), + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, IntRegs:$F, CCOp:$cc), "mov$cc %fcc0, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; + (SPselectfcc IntRegs:$F, IntRegs:$T, imm:$cc, FCC))]>; def MOVFCCri - : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, V8CC:$cc), + : Pseudo<(ops IntRegs:$dst, IntRegs:$T, i32imm:$F, CCOp:$cc), "mov$cc %fcc0, $F, $dst", [(set IntRegs:$dst, - (V8selectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; + (SPselectfcc simm11:$F, IntRegs:$T, imm:$cc, FCC))]>; def FMOVS_ICC - : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, V8CC:$cc), + : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, CCOp:$cc), "fmovs$cc %icc, $F, $dst", [(set FPRegs:$dst, - (V8selecticc FPRegs:$F, FPRegs:$T, imm:$cc, ICC))]>; + (SPselecticc FPRegs:$F, FPRegs:$T, imm:$cc, ICC))]>; def FMOVD_ICC - : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, V8CC:$cc), + : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, CCOp:$cc), "fmovd$cc %icc, $F, $dst", [(set DFPRegs:$dst, - (V8selecticc DFPRegs:$F, DFPRegs:$T, imm:$cc, ICC))]>; + (SPselecticc DFPRegs:$F, DFPRegs:$T, imm:$cc, ICC))]>; def FMOVS_FCC - : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, V8CC:$cc), + : Pseudo<(ops FPRegs:$dst, FPRegs:$T, FPRegs:$F, CCOp:$cc), "fmovs$cc %fcc0, $F, $dst", [(set FPRegs:$dst, - (V8selectfcc FPRegs:$F, FPRegs:$T, imm:$cc, FCC))]>; + (SPselectfcc FPRegs:$F, FPRegs:$T, imm:$cc, FCC))]>; def FMOVD_FCC - : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, V8CC:$cc), + : Pseudo<(ops DFPRegs:$dst, DFPRegs:$T, DFPRegs:$F, CCOp:$cc), "fmovd$cc %fcc0, $F, $dst", [(set DFPRegs:$dst, - (V8selectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc, FCC))]>; + (SPselectfcc DFPRegs:$F, DFPRegs:$T, imm:$cc, FCC))]>; } @@ -806,15 +806,15 @@ (ORri (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>; // Global addresses, constant pool entries -def : Pat<(V8hi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; -def : Pat<(V8lo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>; -def : Pat<(V8hi tconstpool:$in), (SETHIi tconstpool:$in)>; -def : Pat<(V8lo tconstpool:$in), (ORri G0, tconstpool:$in)>; +def : Pat<(SPhi tglobaladdr:$in), (SETHIi tglobaladdr:$in)>; +def : Pat<(SPlo tglobaladdr:$in), (ORri G0, tglobaladdr:$in)>; +def : Pat<(SPhi tconstpool:$in), (SETHIi tconstpool:$in)>; +def : Pat<(SPlo tconstpool:$in), (ORri G0, tconstpool:$in)>; // Add reg, lo. This is used when taking the addr of a global/constpool entry. -def : Pat<(add IntRegs:$r, (V8lo tglobaladdr:$in)), +def : Pat<(add IntRegs:$r, (SPlo tglobaladdr:$in)), (ADDri IntRegs:$r, tglobaladdr:$in)>; -def : Pat<(add IntRegs:$r, (V8lo tconstpool:$in)), +def : Pat<(add IntRegs:$r, (SPlo tconstpool:$in)), (ADDri IntRegs:$r, tconstpool:$in)>; Index: llvm/lib/Target/Sparc/SparcRegisterInfo.cpp diff -u llvm/lib/Target/Sparc/SparcRegisterInfo.cpp:1.36 llvm/lib/Target/Sparc/SparcRegisterInfo.cpp:1.37 --- llvm/lib/Target/Sparc/SparcRegisterInfo.cpp:1.36 Sat Feb 4 02:04:21 2006 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===// +//===- SparcRegisterInfo.cpp - SPARC Register Information -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// // -// This file contains the SparcV8 implementation of the MRegisterInfo class. +// This file contains the SPARC implementation of the MRegisterInfo class. // //===----------------------------------------------------------------------===// -#include "SparcV8.h" -#include "SparcV8RegisterInfo.h" -#include "SparcV8Subtarget.h" +#include "Sparc.h" +#include "SparcRegisterInfo.h" +#include "SparcSubtarget.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -22,100 +22,100 @@ #include using namespace llvm; -SparcV8RegisterInfo::SparcV8RegisterInfo(SparcV8Subtarget &st) - : SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN, - V8::ADJCALLSTACKUP), Subtarget(st) { +SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st) + : SparcGenRegisterInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP), + Subtarget(st) { } -void SparcV8RegisterInfo:: +void SparcRegisterInfo:: storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned SrcReg, int FI, const TargetRegisterClass *RC) const { // On the order of operands here: think "[FrameIdx + 0] = SrcReg". - if (RC == V8::IntRegsRegisterClass) - BuildMI(MBB, I, V8::STri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); - else if (RC == V8::FPRegsRegisterClass) - BuildMI(MBB, I, V8::STFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); - else if (RC == V8::DFPRegsRegisterClass) - BuildMI(MBB, I, V8::STDFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); + if (RC == SP::IntRegsRegisterClass) + BuildMI(MBB, I, SP::STri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); + else if (RC == SP::FPRegsRegisterClass) + BuildMI(MBB, I, SP::STFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); + else if (RC == SP::DFPRegsRegisterClass) + BuildMI(MBB, I, SP::STDFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg); else assert(0 && "Can't store this register to stack slot"); } -void SparcV8RegisterInfo:: +void SparcRegisterInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, const TargetRegisterClass *RC) const { - if (RC == V8::IntRegsRegisterClass) - BuildMI(MBB, I, V8::LDri, 2, DestReg).addFrameIndex(FI).addImm(0); - else if (RC == V8::FPRegsRegisterClass) - BuildMI(MBB, I, V8::LDFri, 2, DestReg).addFrameIndex(FI).addImm (0); - else if (RC == V8::DFPRegsRegisterClass) - BuildMI(MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex(FI).addImm(0); + if (RC == SP::IntRegsRegisterClass) + BuildMI(MBB, I, SP::LDri, 2, DestReg).addFrameIndex(FI).addImm(0); + else if (RC == SP::FPRegsRegisterClass) + BuildMI(MBB, I, SP::LDFri, 2, DestReg).addFrameIndex(FI).addImm (0); + else if (RC == SP::DFPRegsRegisterClass) + BuildMI(MBB, I, SP::LDDFri, 2, DestReg).addFrameIndex(FI).addImm(0); else assert(0 && "Can't load this register from stack slot"); } -void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *RC) const { - if (RC == V8::IntRegsRegisterClass) - BuildMI(MBB, I, V8::ORrr, 2, DestReg).addReg(V8::G0).addReg(SrcReg); - else if (RC == V8::FPRegsRegisterClass) - BuildMI(MBB, I, V8::FMOVS, 1, DestReg).addReg(SrcReg); - else if (RC == V8::DFPRegsRegisterClass) - BuildMI(MBB, I, Subtarget.isV9() ? V8::FMOVD : V8::FpMOVD, +void SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DestReg, unsigned SrcReg, + const TargetRegisterClass *RC) const { + if (RC == SP::IntRegsRegisterClass) + BuildMI(MBB, I, SP::ORrr, 2, DestReg).addReg(SP::G0).addReg(SrcReg); + else if (RC == SP::FPRegsRegisterClass) + BuildMI(MBB, I, SP::FMOVS, 1, DestReg).addReg(SrcReg); + else if (RC == SP::DFPRegsRegisterClass) + BuildMI(MBB, I, Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD, 1, DestReg).addReg(SrcReg); else assert (0 && "Can't copy this register"); } -MachineInstr *SparcV8RegisterInfo::foldMemoryOperand(MachineInstr* MI, - unsigned OpNum, - int FI) const { +MachineInstr *SparcRegisterInfo::foldMemoryOperand(MachineInstr* MI, + unsigned OpNum, + int FI) const { bool isFloat = false; switch (MI->getOpcode()) { - case V8::ORrr: - if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == V8::G0&& + case SP::ORrr: + if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == SP::G0&& MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) { if (OpNum == 0) // COPY -> STORE - return BuildMI(V8::STri, 3).addFrameIndex(FI).addImm(0) + return BuildMI(SP::STri, 3).addFrameIndex(FI).addImm(0) .addReg(MI->getOperand(2).getReg()); else // COPY -> LOAD - return BuildMI(V8::LDri, 2, MI->getOperand(0).getReg()) + return BuildMI(SP::LDri, 2, MI->getOperand(0).getReg()) .addFrameIndex(FI).addImm(0); } break; - case V8::FMOVS: + case SP::FMOVS: isFloat = true; // FALLTHROUGH - case V8::FMOVD: + case SP::FMOVD: if (OpNum == 0) // COPY -> STORE - return BuildMI(isFloat ? V8::STFri : V8::STDFri, 3) + return BuildMI(isFloat ? SP::STFri : SP::STDFri, 3) .addFrameIndex(FI).addImm(0).addReg(MI->getOperand(1).getReg()); else // COPY -> LOAD - return BuildMI(isFloat ? V8::LDFri : V8::LDDFri, 2, + return BuildMI(isFloat ? SP::LDFri : SP::LDDFri, 2, MI->getOperand(0).getReg()).addFrameIndex(FI).addImm(0); break; } return 0; } -void SparcV8RegisterInfo:: +void SparcRegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { MachineInstr &MI = *I; int Size = MI.getOperand(0).getImmedValue(); - if (MI.getOpcode() == V8::ADJCALLSTACKDOWN) + if (MI.getOpcode() == SP::ADJCALLSTACKDOWN) Size = -Size; if (Size) - BuildMI(MBB, I, V8::ADDri, 2, V8::O6).addReg(V8::O6).addSImm(Size); + BuildMI(MBB, I, SP::ADDri, 2, SP::O6).addReg(SP::O6).addSImm(Size); MBB.erase(I); } void -SparcV8RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { +SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { unsigned i = 0; MachineInstr &MI = *II; while (!MI.getOperand(i).isFrameIndex()) { @@ -134,27 +134,27 @@ if (Offset >= -4096 && Offset <= 4095) { // If the offset is small enough to fit in the immediate field, directly // encode it. - MI.SetMachineOperandReg(i, V8::I6); + MI.SetMachineOperandReg(i, SP::I6); MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,Offset); } else { // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to // scavenge a register here instead of reserving G1 all of the time. unsigned OffHi = (unsigned)Offset >> 10U; - BuildMI(*MI.getParent(), II, V8::SETHIi, 1, V8::G1).addImm(OffHi); + BuildMI(*MI.getParent(), II, SP::SETHIi, 1, SP::G1).addImm(OffHi); // Emit G1 = G1 + I6 - BuildMI(*MI.getParent(), II, V8::ADDrr, 2, - V8::G1).addReg(V8::G1).addReg(V8::I6); + BuildMI(*MI.getParent(), II, SP::ADDrr, 2, + SP::G1).addReg(SP::G1).addReg(SP::I6); // Insert: G1+%lo(offset) into the user. - MI.SetMachineOperandReg(i, V8::G1); + MI.SetMachineOperandReg(i, SP::G1); MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed, Offset & ((1 << 10)-1)); } } -void SparcV8RegisterInfo:: +void SparcRegisterInfo:: processFunctionBeforeFrameFinalized(MachineFunction &MF) const {} -void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const { +void SparcRegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -175,29 +175,29 @@ NumBytes = -NumBytes; if (NumBytes >= -4096) { - BuildMI(MBB, MBB.begin(), V8::SAVEri, 2, - V8::O6).addImm(NumBytes).addReg(V8::O6); + BuildMI(MBB, MBB.begin(), SP::SAVEri, 2, + SP::O6).addImm(NumBytes).addReg(SP::O6); } else { MachineBasicBlock::iterator InsertPt = MBB.begin(); // Emit this the hard way. This clobbers G1 which we always know is // available here. unsigned OffHi = (unsigned)NumBytes >> 10U; - BuildMI(MBB, InsertPt, V8::SETHIi, 1, V8::G1).addImm(OffHi); + BuildMI(MBB, InsertPt, SP::SETHIi, 1, SP::G1).addImm(OffHi); // Emit G1 = G1 + I6 - BuildMI(MBB, InsertPt, V8::ORri, 2, V8::G1) - .addReg(V8::G1).addImm(NumBytes & ((1 << 10)-1)); - BuildMI(MBB, InsertPt, V8::SAVErr, 2, - V8::O6).addReg(V8::O6).addReg(V8::G1); + BuildMI(MBB, InsertPt, SP::ORri, 2, SP::G1) + .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1)); + BuildMI(MBB, InsertPt, SP::SAVErr, 2, + SP::O6).addReg(SP::O6).addReg(SP::G1); } } -void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { +void SparcRegisterInfo::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = prior(MBB.end()); - assert(MBBI->getOpcode() == V8::RETL && + assert(MBBI->getOpcode() == SP::RETL && "Can only put epilog before 'retl' instruction!"); - BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0); + BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0); } -#include "SparcV8GenRegisterInfo.inc" +#include "SparcGenRegisterInfo.inc" Index: llvm/lib/Target/Sparc/SparcRegisterInfo.h diff -u llvm/lib/Target/Sparc/SparcRegisterInfo.h:1.8 llvm/lib/Target/Sparc/SparcRegisterInfo.h:1.9 --- llvm/lib/Target/Sparc/SparcRegisterInfo.h:1.8 Sat Feb 4 00:58:46 2006 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.h Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8RegisterInfo.h - SparcV8 Register Information Impl -*- C++ -*-==// +//===- SparcRegisterInfo.h - Sparc Register Information Impl ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,25 +7,25 @@ // //===----------------------------------------------------------------------===// // -// This file contains the SparcV8 implementation of the MRegisterInfo class. +// This file contains the Sparc implementation of the MRegisterInfo class. // //===----------------------------------------------------------------------===// -#ifndef SPARCV8REGISTERINFO_H -#define SPARCV8REGISTERINFO_H +#ifndef SPARCREGISTERINFO_H +#define SPARCREGISTERINFO_H #include "llvm/Target/MRegisterInfo.h" -#include "SparcV8GenRegisterInfo.h.inc" +#include "SparcGenRegisterInfo.h.inc" namespace llvm { -class SparcV8Subtarget; +class SparcSubtarget; class Type; -struct SparcV8RegisterInfo : public SparcV8GenRegisterInfo { - SparcV8Subtarget &Subtarget; +struct SparcRegisterInfo : public SparcGenRegisterInfo { + SparcSubtarget &Subtarget; - SparcV8RegisterInfo(SparcV8Subtarget &st); + SparcRegisterInfo(SparcSubtarget &st); /// Code Generation virtual methods... void storeRegToStackSlot(MachineBasicBlock &MBB, Index: llvm/lib/Target/Sparc/SparcRegisterInfo.td diff -u llvm/lib/Target/Sparc/SparcRegisterInfo.td:1.27 llvm/lib/Target/Sparc/SparcRegisterInfo.td:1.28 --- llvm/lib/Target/Sparc/SparcRegisterInfo.td:1.27 Tue Dec 20 01:56:31 2005 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.td Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8RegisterInfo.td - SparcV8 Register defs ------*- tablegen -*-===// +//===- SparcRegisterInfo.td - Sparc Register defs ----------*- tablegen -*-===// // // The LLVM Compiler Infrastructure // @@ -8,12 +8,12 @@ //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// Declarations that describe the SparcV8 register file +// Declarations that describe the Sparc register file //===----------------------------------------------------------------------===// class SparcReg : Register { field bits<5> Num; - let Namespace = "V8"; + let Namespace = "SP"; } // Registers are identified with 5-bit ID numbers. @@ -69,11 +69,11 @@ def D14 : Rd<28, "F28", [F28, F29]>; def D15 : Rd<30, "F30", [F30, F31]>; /// Integer and FP Condition codes. -let Namespace = "V8" in { +let Namespace = "SP" in { def ICC : Register<"ICC">; def FCC : Register<"FCC">; } -def FLAGS_REGS : RegisterClass<"V8", [FlagVT], 32, [ICC, FCC]> { +def FLAGS_REGS : RegisterClass<"SP", [FlagVT], 32, [ICC, FCC]> { let Size = 32; } @@ -82,7 +82,7 @@ // FIXME: the register order should be defined in terms of the preferred // allocation order... // -def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7, +def IntRegs : RegisterClass<"SP", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7, I0, I1, I2, I3, I4, I5, O0, O1, O2, O3, O4, O5, O7, @@ -110,9 +110,9 @@ }]; } -def FPRegs : RegisterClass<"V8", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8, +def FPRegs : RegisterClass<"SP", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>; -def DFPRegs : RegisterClass<"V8", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7, +def DFPRegs : RegisterClass<"SP", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15]>; Index: llvm/lib/Target/Sparc/SparcSubtarget.cpp diff -u llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.4 llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.5 --- llvm/lib/Target/Sparc/SparcSubtarget.cpp:1.4 Sun Jan 29 22:57:43 2006 +++ llvm/lib/Target/Sparc/SparcSubtarget.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===- SparcV8Subtarget.cpp - SPARC Subtarget Information -----------------===// +//===- SparcSubtarget.cpp - SPARC Subtarget Information -------------------===// // // The LLVM Compiler Infrastructure // @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "SparcV8Subtarget.h" -#include "SparcV8GenSubtarget.inc" +#include "SparcSubtarget.h" +#include "SparcGenSubtarget.inc" using namespace llvm; // FIXME: temporary. @@ -22,7 +22,7 @@ cl::desc("Enable V9 instructions in the V8 target")); } -SparcV8Subtarget::SparcV8Subtarget(const Module &M, const std::string &FS) { +SparcSubtarget::SparcSubtarget(const Module &M, const std::string &FS) { // Set the default features. IsV9 = false; V8DeprecatedInsts = false; Index: llvm/lib/Target/Sparc/SparcSubtarget.h diff -u llvm/lib/Target/Sparc/SparcSubtarget.h:1.2 llvm/lib/Target/Sparc/SparcSubtarget.h:1.3 --- llvm/lib/Target/Sparc/SparcSubtarget.h:1.2 Thu Jan 26 01:22:22 2006 +++ llvm/lib/Target/Sparc/SparcSubtarget.h Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//=====-- SparcV8Subtarget.h - Define Subtarget for the SPARC -*- C++ -*--====// +//=====-- SparcSubtarget.h - Define Subtarget for the SPARC ----*- C++ -*-====// // // The LLVM Compiler Infrastructure // @@ -20,12 +20,12 @@ namespace llvm { class Module; -class SparcV8Subtarget : public TargetSubtarget { +class SparcSubtarget : public TargetSubtarget { bool IsV9; bool V8DeprecatedInsts; bool IsVIS; public: - SparcV8Subtarget(const Module &M, const std::string &FS); + SparcSubtarget(const Module &M, const std::string &FS); bool isV9() const { return IsV9; } bool isVIS() const { return IsVIS; } Index: llvm/lib/Target/Sparc/SparcTargetMachine.cpp diff -u llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.39 llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.40 --- llvm/lib/Target/Sparc/SparcTargetMachine.cpp:1.39 Sat Feb 4 00:58:46 2006 +++ llvm/lib/Target/Sparc/SparcTargetMachine.cpp Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- SparcV8TargetMachine.cpp - Define TargetMachine for SparcV8 -------===// +//===-- SparcTargetMachine.cpp - Define TargetMachine for Sparc -----------===// // // The LLVM Compiler Infrastructure // @@ -10,8 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "SparcV8TargetMachine.h" -#include "SparcV8.h" +#include "SparcTargetMachine.h" +#include "Sparc.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Module.h" #include "llvm/PassManager.h" @@ -26,20 +26,19 @@ namespace { // Register the target. - RegisterTarget X("sparcv8"," SPARC V8 (experimental)"); + RegisterTarget X("sparc", " SPARC"); } -/// SparcV8TargetMachine ctor - Create an ILP32 architecture model +/// SparcTargetMachine ctor - Create an ILP32 architecture model /// -SparcV8TargetMachine::SparcV8TargetMachine(const Module &M, - IntrinsicLowering *IL, - const std::string &FS) - : TargetMachine("SparcV8", IL, false, 4, 4), +SparcTargetMachine::SparcTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS) + : TargetMachine("Sparc", IL, false, 4, 4), Subtarget(M, FS), InstrInfo(Subtarget), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { } -unsigned SparcV8TargetMachine::getModuleMatchQuality(const Module &M) { +unsigned SparcTargetMachine::getModuleMatchQuality(const Module &M) { std::string TT = M.getTargetTriple(); if (TT.size() >= 6 && std::string(TT.begin(), TT.begin()+6) == "sparc-") return 20; @@ -47,7 +46,7 @@ if (M.getEndianness() == Module::BigEndian && M.getPointerSize() == Module::Pointer32) #ifdef __sparc__ - return 20; // BE/32 ==> Prefer sparcv8 on sparc + return 20; // BE/32 ==> Prefer sparc on sparc #else return 5; // BE/32 ==> Prefer ppc elsewhere #endif @@ -61,10 +60,9 @@ /// addPassesToEmitFile - Add passes to the specified pass manager /// to implement a static compiler for this target. /// -bool SparcV8TargetMachine::addPassesToEmitFile(PassManager &PM, - std::ostream &Out, - CodeGenFileType FileType, - bool Fast) { +bool SparcTargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, + CodeGenFileType FileType, + bool Fast) { if (FileType != TargetMachine::AssemblyFile) return true; // FIXME: Implement efficient support for garbage collection intrinsics. @@ -83,7 +81,7 @@ // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - PM.add(createSparcV8ISelDag(*this)); + PM.add(createSparcISelDag(*this)); // Print machine instructions as they were initially generated. if (PrintMachineCode) @@ -97,16 +95,16 @@ if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); - PM.add(createSparcV8FPMoverPass(*this)); + PM.add(createSparcFPMoverPass(*this)); - PM.add(createSparcV8DelaySlotFillerPass(*this)); + PM.add(createSparcDelaySlotFillerPass(*this)); // Print machine instructions after filling delay slots. if (PrintMachineCode) PM.add(createMachineFunctionPrinterPass(&std::cerr)); // Output assembly language. - PM.add(createSparcV8CodePrinterPass(Out, *this)); + PM.add(createSparcCodePrinterPass(Out, *this)); // Delete the MachineInstrs we generated, since they're no longer needed. PM.add(createMachineCodeDeleter()); Index: llvm/lib/Target/Sparc/SparcTargetMachine.h diff -u llvm/lib/Target/Sparc/SparcTargetMachine.h:1.10 llvm/lib/Target/Sparc/SparcTargetMachine.h:1.11 --- llvm/lib/Target/Sparc/SparcTargetMachine.h:1.10 Thu Jan 26 00:51:21 2006 +++ llvm/lib/Target/Sparc/SparcTargetMachine.h Sat Feb 4 23:50:24 2006 @@ -1,4 +1,4 @@ -//===-- SparcV8TargetMachine.h - Define TargetMachine for SparcV8 -*- C++ -*-=// +//===-- SparcTargetMachine.h - Define TargetMachine for Sparc ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,33 +7,33 @@ // //===----------------------------------------------------------------------===// // -// This file declares the SparcV8 specific subclass of TargetMachine. +// This file declares the Sparc specific subclass of TargetMachine. // //===----------------------------------------------------------------------===// -#ifndef SPARCV8TARGETMACHINE_H -#define SPARCV8TARGETMACHINE_H +#ifndef SPARCTARGETMACHINE_H +#define SPARCTARGETMACHINE_H #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/PassManager.h" -#include "SparcV8InstrInfo.h" -#include "SparcV8Subtarget.h" +#include "SparcInstrInfo.h" +#include "SparcSubtarget.h" namespace llvm { class IntrinsicLowering; class Module; -class SparcV8TargetMachine : public TargetMachine { - SparcV8Subtarget Subtarget; - SparcV8InstrInfo InstrInfo; +class SparcTargetMachine : public TargetMachine { + SparcSubtarget Subtarget; + SparcInstrInfo InstrInfo; TargetFrameInfo FrameInfo; public: - SparcV8TargetMachine(const Module &M, IntrinsicLowering *IL, - const std::string &FS); + SparcTargetMachine(const Module &M, IntrinsicLowering *IL, + const std::string &FS); - virtual const SparcV8InstrInfo *getInstrInfo() const { return &InstrInfo; } + virtual const SparcInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; } virtual const MRegisterInfo *getRegisterInfo() const { From lattner at cs.uiuc.edu Sat Feb 4 23:51:34 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:51:34 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SPARC/ Message-ID: <200602050551.XAA15845@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SPARC: --- Log message: Directory /home/vadve/shared/PublicCVS/llvm/test/Regression/CodeGen/SPARC added to the repository --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sat Feb 4 23:53:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:53:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SPARC/2006-01-22-BitConvertLegalize.ll basictest.ll ctpop.ll dg.exp xnor.ll Message-ID: <200602050553.XAA15923@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SPARC: 2006-01-22-BitConvertLegalize.ll added (r1.1) basictest.ll added (r1.1) ctpop.ll added (r1.1) dg.exp added (r1.1) xnor.ll added (r1.1) --- Log message: move V8 testcases here --- Diffs of the changes: (+46 -0) 2006-01-22-BitConvertLegalize.ll | 12 ++++++++++++ basictest.ll | 6 ++++++ ctpop.ll | 11 +++++++++++ dg.exp | 3 +++ xnor.ll | 14 ++++++++++++++ 5 files changed, 46 insertions(+) Index: llvm/test/Regression/CodeGen/SPARC/2006-01-22-BitConvertLegalize.ll diff -c /dev/null llvm/test/Regression/CodeGen/SPARC/2006-01-22-BitConvertLegalize.ll:1.1 *** /dev/null Sat Feb 4 23:53:06 2006 --- llvm/test/Regression/CodeGen/SPARC/2006-01-22-BitConvertLegalize.ll Sat Feb 4 23:52:55 2006 *************** *** 0 **** --- 1,12 ---- + ; RUN: llvm-as < %s | llc -march=sparc + + void %execute_list() { + %tmp.33.i = div float 0.000000e+00, 0.000000e+00 ; [#uses=1] + %tmp.37.i = mul float 0.000000e+00, %tmp.33.i ; [#uses=1] + %tmp.42.i = add float %tmp.37.i, 0.000000e+00 ; [#uses=1] + call void %gl_EvalCoord1f( float %tmp.42.i ) + ret void + } + + declare void %gl_EvalCoord1f( float) + Index: llvm/test/Regression/CodeGen/SPARC/basictest.ll diff -c /dev/null llvm/test/Regression/CodeGen/SPARC/basictest.ll:1.1 *** /dev/null Sat Feb 4 23:53:08 2006 --- llvm/test/Regression/CodeGen/SPARC/basictest.ll Sat Feb 4 23:52:55 2006 *************** *** 0 **** --- 1,6 ---- + ; RUN: llvm-as < %s | llc -march=sparc + + int %test(int %X) { + %tmp.1 = add int %X, 1 ; [#uses=1] + ret int %tmp.1 + } Index: llvm/test/Regression/CodeGen/SPARC/ctpop.ll diff -c /dev/null llvm/test/Regression/CodeGen/SPARC/ctpop.ll:1.1 *** /dev/null Sat Feb 4 23:53:08 2006 --- llvm/test/Regression/CodeGen/SPARC/ctpop.ll Sat Feb 4 23:52:55 2006 *************** *** 0 **** --- 1,11 ---- + ; RUN: llvm-as < %s | llc -march=sparc -mattr=-v9 && + ; RUN: llvm-as < %s | llc -march=sparc -mattr=v9 -enable-sparc-v9-insts && + ; RUN: llvm-as < %s | llc -march=sparc -mattr=-v9 | not grep popc && + ; RUN: llvm-as < %s | llc -march=sparc -mattr=v9 -enable-sparc-v9-insts | grep popc + + declare uint %llvm.ctpop.i32(uint) + uint %test(uint %X) { + %Y = call uint %llvm.ctpop.i32(uint %X) + ret uint %Y + } + Index: llvm/test/Regression/CodeGen/SPARC/dg.exp diff -c /dev/null llvm/test/Regression/CodeGen/SPARC/dg.exp:1.1 *** /dev/null Sat Feb 4 23:53:08 2006 --- llvm/test/Regression/CodeGen/SPARC/dg.exp Sat Feb 4 23:52:55 2006 *************** *** 0 **** --- 1,3 ---- + load_lib llvm-dg.exp + + llvm-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]] $objdir $srcdir $subdir $target_triplet $llvmgcc $llvmgxx $prcontext Index: llvm/test/Regression/CodeGen/SPARC/xnor.ll diff -c /dev/null llvm/test/Regression/CodeGen/SPARC/xnor.ll:1.1 *** /dev/null Sat Feb 4 23:53:08 2006 --- llvm/test/Regression/CodeGen/SPARC/xnor.ll Sat Feb 4 23:52:55 2006 *************** *** 0 **** --- 1,14 ---- + ; RUN: llvm-as < %s | llc -march=sparc && + ; RUN: llvm-as < %s | llc -march=sparc | grep xnor | wc -l | grep 2 + + int %test1(int %X, int %Y) { + %A = xor int %X, %Y + %B = xor int %A, -1 + ret int %B + } + + int %test2(int %X, int %Y) { + %A = xor int %X, -1 + %B = xor int %A, %Y + ret int %B + } From lattner at cs.uiuc.edu Sat Feb 4 23:54:08 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:54:08 -0600 Subject: [llvm-commits] CVS: llvm/test/Regression/CodeGen/SparcV8/2006-01-22-BitConvertLegalize.ll basictest.ll ctpop.ll dg.exp xnor.ll Message-ID: <200602050554.XAA15985@zion.cs.uiuc.edu> Changes in directory llvm/test/Regression/CodeGen/SparcV8: 2006-01-22-BitConvertLegalize.ll (r1.1) removed basictest.ll (r1.1) removed ctpop.ll (r1.1) removed dg.exp (r1.1) removed xnor.ll (r1.3) removed --- Log message: These were moved to ../SPARC --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sat Feb 4 23:57:03 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat, 4 Feb 2006 23:57:03 -0600 Subject: [llvm-commits] CVS: llvm/autoconf/configure.ac Message-ID: <200602050557.XAA16029@zion.cs.uiuc.edu> Changes in directory llvm/autoconf: configure.ac updated: 1.206 -> 1.207 --- Log message: SparcV8 -> Sparc --- Diffs of the changes: (+3 -3) configure.ac | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/autoconf/configure.ac diff -u llvm/autoconf/configure.ac:1.206 llvm/autoconf/configure.ac:1.207 --- llvm/autoconf/configure.ac:1.206 Mon Jan 23 00:47:56 2006 +++ llvm/autoconf/configure.ac Sat Feb 4 23:56:51 2006 @@ -258,12 +258,12 @@ [Build specific host targets: all,host-only,{target-name} (default=all)]),, enableval=all) case "$enableval" in - all) TARGETS_TO_BUILD="X86 SparcV8 SparcV9 PowerPC Alpha IA64 Skeleton" ;; + all) TARGETS_TO_BUILD="X86 Sparc SparcV9 PowerPC Alpha IA64 Skeleton" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; x86_64) TARGETS_TO_BUILD="X86" ;; - Sparc) TARGETS_TO_BUILD="SparcV8 SparcV9" ;; + Sparc) TARGETS_TO_BUILD="Sparc SparcV9" ;; PowerPC) TARGETS_TO_BUILD="PowerPC" ;; Alpha) TARGETS_TO_BUILD="Alpha" ;; IA64) TARGETS_TO_BUILD="IA64" ;; @@ -274,7 +274,7 @@ case "$a_target" in x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; - sparc) TARGETS_TO_BUILD="SparcV8 SparcV9 $TARGETS_TO_BUILD" ;; + sparc) TARGETS_TO_BUILD="Sparc SparcV9 $TARGETS_TO_BUILD" ;; powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;; alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;; ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;; From lattner at cs.uiuc.edu Sun Feb 5 00:26:55 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 00:26:55 -0600 Subject: [llvm-commits] CVS: llvm/configure Message-ID: <200602050626.AAA16151@zion.cs.uiuc.edu> Changes in directory llvm: configure updated: 1.208 -> 1.209 --- Log message: SparcV8 -> Sparc --- Diffs of the changes: (+3 -3) configure | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Index: llvm/configure diff -u llvm/configure:1.208 llvm/configure:1.209 --- llvm/configure:1.208 Mon Jan 23 02:15:53 2006 +++ llvm/configure Sun Feb 5 00:26:43 2006 @@ -3078,12 +3078,12 @@ enableval=all fi; case "$enableval" in - all) TARGETS_TO_BUILD="X86 SparcV8 SparcV9 PowerPC Alpha IA64 Skeleton" ;; + all) TARGETS_TO_BUILD="X86 Sparc SparcV9 PowerPC Alpha IA64 Skeleton" ;; host-only) case "$llvm_cv_target_arch" in x86) TARGETS_TO_BUILD="X86" ;; x86_64) TARGETS_TO_BUILD="X86" ;; - Sparc) TARGETS_TO_BUILD="SparcV8 SparcV9" ;; + Sparc) TARGETS_TO_BUILD="Sparc SparcV9" ;; PowerPC) TARGETS_TO_BUILD="PowerPC" ;; Alpha) TARGETS_TO_BUILD="Alpha" ;; IA64) TARGETS_TO_BUILD="IA64" ;; @@ -3096,7 +3096,7 @@ case "$a_target" in x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;; - sparc) TARGETS_TO_BUILD="SparcV8 SparcV9 $TARGETS_TO_BUILD" ;; + sparc) TARGETS_TO_BUILD="Sparc SparcV9 $TARGETS_TO_BUILD" ;; powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;; alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;; ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;; From evan.cheng at apple.com Sun Feb 5 00:29:35 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 5 Feb 2006 00:29:35 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Message-ID: <200602050629.AAA16180@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: SelectionDAG.cpp updated: 1.253 -> 1.254 --- Log message: * Added SDNode::isOnlyUse(). * Fix hasNUsesOfValue(), it should be const. --- Diffs of the changes: (+18 -3) SelectionDAG.cpp | 21 ++++++++++++++++++--- 1 files changed, 18 insertions(+), 3 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.253 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.254 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.253 Fri Feb 3 00:51:34 2006 +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Feb 5 00:29:23 2006 @@ -2177,7 +2177,7 @@ /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. -bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) { +bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const { assert(Value < getNumValues() && "Bad value!"); // If there is only one value, this is easy. @@ -2185,11 +2185,11 @@ return use_size() == NUses; if (Uses.size() < NUses) return false; - SDOperand TheValue(this, Value); + SDOperand TheValue(const_cast(this), Value); std::set UsersHandled; - for (std::vector::iterator UI = Uses.begin(), E = Uses.end(); + for (std::vector::const_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) { SDNode *User = *UI; if (User->getNumOperands() == 1 || @@ -2207,6 +2207,21 @@ } +// isOnlyUse - Return true if this node is the only use of N. +bool SDNode::isOnlyUse(SDNode *N) const { + bool Seen = false; + for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { + SDNode *User = *I; + if (User == this) + Seen = true; + else + return false; + } + + return Seen; +} + + const char *SDNode::getOperationName(const SelectionDAG *G) const { switch (getOpcode()) { default: From evan.cheng at apple.com Sun Feb 5 00:29:36 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 5 Feb 2006 00:29:36 -0600 Subject: [llvm-commits] CVS: llvm/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200602050629.AAA16184@zion.cs.uiuc.edu> Changes in directory llvm/include/llvm/CodeGen: SelectionDAGNodes.h updated: 1.99 -> 1.100 --- Log message: * Added SDNode::isOnlyUse(). * Fix hasNUsesOfValue(), it should be const. --- Diffs of the changes: (+4 -1) SelectionDAGNodes.h | 5 ++++- 1 files changed, 4 insertions(+), 1 deletion(-) Index: llvm/include/llvm/CodeGen/SelectionDAGNodes.h diff -u llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.99 llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.100 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h:1.99 Tue Jan 31 16:21:33 2006 +++ llvm/include/llvm/CodeGen/SelectionDAGNodes.h Sun Feb 5 00:29:23 2006 @@ -619,7 +619,10 @@ /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the /// indicated value. This method ignores uses of other values defined by this /// operation. - bool hasNUsesOfValue(unsigned NUses, unsigned Value); + bool hasNUsesOfValue(unsigned NUses, unsigned Value) const; + + // isOnlyUse - Return true if this node is the only use of N. + bool isOnlyUse(SDNode *N) const; /// getNumOperands - Return the number of values used by this operation. /// From lattner at cs.uiuc.edu Sun Feb 5 00:33:11 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 00:33:11 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/Sparc/README.txt Message-ID: <200602050633.AAA16283@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/Sparc: README.txt updated: 1.49 -> 1.50 --- Log message: remove V8 reference --- Diffs of the changes: (+1 -1) README.txt | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: llvm/lib/Target/Sparc/README.txt diff -u llvm/lib/Target/Sparc/README.txt:1.49 llvm/lib/Target/Sparc/README.txt:1.50 --- llvm/lib/Target/Sparc/README.txt:1.49 Sat Feb 4 01:07:31 2006 +++ llvm/lib/Target/Sparc/README.txt Sun Feb 5 00:32:59 2006 @@ -2,7 +2,7 @@ To-do ----- -* Enable LSR for V8. +* Enable LSR for SPARC. * Keep the address of the constant pool in a register instead of forming its address all of the time. * We can fold small constant offsets into the %hi/%lo references to constant From lattner at cs.uiuc.edu Sun Feb 5 00:34:14 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 00:34:14 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/SparcV8/DelaySlotFiller.cpp FPMover.cpp Makefile README.txt SparcV8.h SparcV8.td SparcV8AsmPrinter.cpp SparcV8ISelDAGToDAG.cpp SparcV8InstrFormats.td SparcV8InstrInfo.cpp SparcV8InstrInfo.h SparcV8InstrInfo.td SparcV8RegisterInfo.cpp SparcV8RegisterInfo.h SparcV8RegisterInfo.td SparcV8Subtarget.cpp SparcV8Subtarget.h SparcV8TargetMachine.cpp SparcV8TargetMachine.h Message-ID: <200602050634.AAA16332@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/SparcV8: DelaySlotFiller.cpp (r1.9) removed FPMover.cpp (r1.11) removed Makefile (r1.13) removed README.txt (r1.49) removed SparcV8.h (r1.10) removed SparcV8.td (r1.10) removed SparcV8AsmPrinter.cpp (r1.52) removed SparcV8ISelDAGToDAG.cpp (r1.76) removed SparcV8InstrFormats.td (r1.15) removed SparcV8InstrInfo.cpp (r1.12) removed SparcV8InstrInfo.h (r1.7) removed SparcV8InstrInfo.td (r1.117) removed SparcV8RegisterInfo.cpp (r1.36) removed SparcV8RegisterInfo.h (r1.8) removed SparcV8RegisterInfo.td (r1.27) removed SparcV8Subtarget.cpp (r1.4) removed SparcV8Subtarget.h (r1.2) removed SparcV8TargetMachine.cpp (r1.39) removed SparcV8TargetMachine.h (r1.10) removed --- Log message: Remove the SparcV8 backend. It has been renamed to be the Sparc backend. --- Diffs of the changes: (+0 -0) 0 files changed From lattner at cs.uiuc.edu Sun Feb 5 00:39:48 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 00:39:48 -0600 Subject: [llvm-commits] CVS: llvm/docs/ReleaseNotes.html Message-ID: <200602050639.AAA16397@zion.cs.uiuc.edu> Changes in directory llvm/docs: ReleaseNotes.html updated: 1.345 -> 1.346 --- Log message: V8 -> Sparc --- Diffs of the changes: (+9 -5) ReleaseNotes.html | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) Index: llvm/docs/ReleaseNotes.html diff -u llvm/docs/ReleaseNotes.html:1.345 llvm/docs/ReleaseNotes.html:1.346 --- llvm/docs/ReleaseNotes.html:1.345 Sun Jan 15 19:05:00 2006 +++ llvm/docs/ReleaseNotes.html Sun Feb 5 00:39:36 2006 @@ -74,6 +74,11 @@ New Features in LLVM 1.7cvs +
+
    +
  • New SPARC backend.
  • +
+
@@ -138,7 +143,7 @@ releases: -cee
  • The llvm-db tool is in a very early stage of development, but can be used to step through programs and inspect the stack.
  • -
  • The SparcV8 and IA64 code generators are experimental.
  • +
  • The IA64 code generator is experimental.
  • The Alpha JIT is experimental.
  • @@ -512,14 +517,13 @@
      -
    • Many features are still missing (e.g. support for 64-bit integer -arithmetic). This back-end is in pre-beta state.
    • +
    • This backend lacks a JIT compiler.
    @@ -556,7 +560,7 @@ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2006/01/16 01:05:00 $ + Last modified: $Date: 2006/02/05 06:39:36 $ From lattner at cs.uiuc.edu Sun Feb 5 00:40:24 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 00:40:24 -0600 Subject: [llvm-commits] CVS: llvm/docs/UsingLibraries.html Message-ID: <200602050640.AAA16465@zion.cs.uiuc.edu> Changes in directory llvm/docs: UsingLibraries.html updated: 1.17 -> 1.18 --- Log message: This document is out of date. :( --- Diffs of the changes: (+4 -4) UsingLibraries.html | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) Index: llvm/docs/UsingLibraries.html diff -u llvm/docs/UsingLibraries.html:1.17 llvm/docs/UsingLibraries.html:1.18 --- llvm/docs/UsingLibraries.html:1.17 Sun Jan 2 23:46:46 2005 +++ llvm/docs/UsingLibraries.html Sun Feb 5 00:40:12 2006 @@ -126,8 +126,8 @@ Aggressive instruction selector for directed acyclic graphs. LLVMSkeleton.a .o Skeleton for a code generation backend. - LLVMSparcV8.o - Code generation for SparcV8. + LLVMSparc.o + Code generation for Sparc. LLVMSparcV9.o Code generation for SparcV9. LLVMSparcV9RegAlloc.a .o @@ -369,7 +369,7 @@
  • LLVMCodeGen.o
  • LLVMCore.o
  • -
    LLVMSparcV8.o
    +
    Last modified: $Date: 2006/02/05 06:40:12 $ 16 << X - //===---------------------------------------------------------------------===// From natebegeman at mac.com Sun Feb 5 02:07:36 2006 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 5 Feb 2006 02:07:36 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602050807.CAA17861@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.97 -> 1.98 --- Log message: fold c1 << (x + c2) into (c1 << c2) << x. fix a warning. --- Diffs of the changes: (+7 -1) DAGCombiner.cpp | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletion(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.97 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.98 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.97 Sun Feb 5 01:36:48 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Feb 5 02:07:24 2006 @@ -838,7 +838,7 @@ if (N1.getOpcode() == ISD::SHL) { if (ConstantSDNode *SHC = dyn_cast(N1.getOperand(0))) { if (isPowerOf2_64(SHC->getValue())) { - SDOperand Add = DAG.getNode(ISD::ADD, VT, N1, DAG.getConstant(-1, VT)); + SDOperand Add = DAG.getNode(ISD::ADD, VT, N1,DAG.getConstant(~0ULL,VT)); WorkList.push_back(Add.Val); return DAG.getNode(ISD::AND, VT, N0, Add); } @@ -1288,6 +1288,12 @@ // fold (shl 0, x) -> 0 if (N0C && N0C->isNullValue()) return N0; + // fold (shl c1, (add x, c2)) -> (shl c1 << c2, x) + if (N0C && N1.getOpcode() == ISD::ADD && + N1.getOperand(1).getOpcode() == ISD::Constant) { + SDOperand LHS = DAG.getNode(ISD::SHL, VT, N0, N1.getOperand(1)); + return DAG.getNode(ISD::SHL, VT, LHS, N1.getOperand(0)); + } // fold (shl x, c >= size(x)) -> undef if (N1C && N1C->getValue() >= OpSizeInBits) return DAG.getNode(ISD::UNDEF, VT); From natebegeman at mac.com Sun Feb 5 02:23:12 2006 From: natebegeman at mac.com (Nate Begeman) Date: Sun, 5 Feb 2006 02:23:12 -0600 Subject: [llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Message-ID: <200602050823.CAA22293@zion.cs.uiuc.edu> Changes in directory llvm/lib/CodeGen/SelectionDAG: DAGCombiner.cpp updated: 1.98 -> 1.99 --- Log message: Back out previous commit, it isn't safe. --- Diffs of the changes: (+0 -6) DAGCombiner.cpp | 6 ------ 1 files changed, 6 deletions(-) Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.98 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.99 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.98 Sun Feb 5 02:07:24 2006 +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Feb 5 02:23:00 2006 @@ -1288,12 +1288,6 @@ // fold (shl 0, x) -> 0 if (N0C && N0C->isNullValue()) return N0; - // fold (shl c1, (add x, c2)) -> (shl c1 << c2, x) - if (N0C && N1.getOpcode() == ISD::ADD && - N1.getOperand(1).getOpcode() == ISD::Constant) { - SDOperand LHS = DAG.getNode(ISD::SHL, VT, N0, N1.getOperand(1)); - return DAG.getNode(ISD::SHL, VT, LHS, N1.getOperand(0)); - } // fold (shl x, c >= size(x)) -> undef if (N1C && N1C->getValue() >= OpSizeInBits) return DAG.getNode(ISD::UNDEF, VT); From lattner at cs.uiuc.edu Sun Feb 5 02:26:29 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 02:26:29 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/README.txt Message-ID: <200602050826.CAA23070@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target: README.txt updated: 1.4 -> 1.5 --- Log message: This xform isn't safe --- Diffs of the changes: (+0 -4) README.txt | 4 ---- 1 files changed, 4 deletions(-) Index: llvm/lib/Target/README.txt diff -u llvm/lib/Target/README.txt:1.4 llvm/lib/Target/README.txt:1.5 --- llvm/lib/Target/README.txt:1.4 Sun Feb 5 01:54:37 2006 +++ llvm/lib/Target/README.txt Sun Feb 5 02:26:16 2006 @@ -64,7 +64,3 @@ //===---------------------------------------------------------------------===// -For dag combiner and instcombine: -int t(int X, int Y) { return 1 << (X+4); } --> 16 << X - -//===---------------------------------------------------------------------===// From lattner at cs.uiuc.edu Sun Feb 5 02:30:57 2006 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun, 5 Feb 2006 02:30:57 -0600 Subject: [llvm-commits] CVS: llvm/tools/llc/Makefile Message-ID: <200602050830.CAA24076@zion.cs.uiuc.edu> Changes in directory llvm/tools/llc: Makefile updated: 1.77 -> 1.78 --- Log message: SparcV8 -> Sparc --- Diffs of the changes: (+2 -2) Makefile | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: llvm/tools/llc/Makefile diff -u llvm/tools/llc/Makefile:1.77 llvm/tools/llc/Makefile:1.78 --- llvm/tools/llc/Makefile:1.77 Thu Oct 27 10:54:34 2005 +++ llvm/tools/llc/Makefile Sun Feb 5 02:30:45 2006 @@ -38,8 +38,8 @@ LLVMSparcV9LiveVar endif -ifneq ($(strip $(filter SparcV8,$(TARGETS_TO_BUILD))),) -USEDLIBS += LLVMSparcV8 +ifneq ($(strip $(filter Sparc,$(TARGETS_TO_BUILD))),) +USEDLIBS += LLVMSparc endif From evan.cheng at apple.com Sun Feb 5 02:45:13 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 5 Feb 2006 02:45:13 -0600 Subject: [llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Message-ID: <200602050845.CAA26491@zion.cs.uiuc.edu> Changes in directory llvm/lib/Target/PowerPC: PPCISelDAGToDAG.cpp updated: 1.154 -> 1.155 --- Log message: Complex pattern isel code shouldn't select nodes. --- Diffs of the changes: (+9 -9) PPCISelDAGToDAG.cpp | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.154 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.155 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.154 Sun Feb 5 00:46:41 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Sun Feb 5 02:45:01 2006 @@ -392,7 +392,7 @@ if (FrameIndexSDNode *FI = dyn_cast(N.getOperand(0))) { Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); } else { - Base = Select(N.getOperand(0)); + Base = N.getOperand(0); } return true; // [r+i] } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) { @@ -402,7 +402,7 @@ Disp = N.getOperand(1).getOperand(0); // The global address. assert(Disp.getOpcode() == ISD::TargetGlobalAddress || Disp.getOpcode() == ISD::TargetConstantPool); - Base = Select(N.getOperand(0)); + Base = N.getOperand(0); return true; // [&g+r] } return false; // [r+r] @@ -411,7 +411,7 @@ if (FrameIndexSDNode *FI = dyn_cast(N)) Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); else - Base = Select(N); + Base = N; return true; // [r+0] } @@ -427,13 +427,13 @@ return false; if (N.getOpcode() == ISD::ADD) { - Base = Select(N.getOperand(0)); - Index = Select(N.getOperand(1)); + Base = N.getOperand(0); + Index = N.getOperand(1); return true; } Base = CurDAG->getRegister(PPC::R0, MVT::i32); - Index = Select(N); + Index = N; return true; } @@ -442,13 +442,13 @@ bool PPCDAGToDAGISel::SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index) { if (N.getOpcode() == ISD::ADD) { - Base = Select(N.getOperand(0)); - Index = Select(N.getOperand(1)); + Base = N.getOperand(0); + Index = N.getOperand(1); return true; } Base = CurDAG->getRegister(PPC::R0, MVT::i32); - Index = Select(N); + Index = N; return true; } From evan.cheng at apple.com Sun Feb 5 02:46:26 2006 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 5 Feb 2006 02:46:26 -0600 Subject: [llvm-commits] CVS: llvm/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200602050846.CAA26791@zion.cs.uiuc.edu> Changes in directory llvm/utils/TableGen: DAGISelEmitter.cpp updated: 1.165 -> 1.166 --- Log message: Handle HANDLENODE: just return itself. --- Diffs of the changes: (+1 -0) DAGISelEmitter.cpp | 1 + 1 files changed, 1 insertion(+) Index: llvm/utils/TableGen/DAGISelEmitter.cpp diff -u llvm/utils/TableGen/DAGISelEmitter.cpp:1.165 llvm/utils/TableGen/DAGISelEmitter.cpp:1.166 --- llvm/utils/TableGen/DAGISelEmitter.cpp:1.165 Sun Feb 5 00:43:12 2006 +++ llvm/utils/TableGen/DAGISelEmitter.cpp Sun Feb 5 02:46:14 2006 @@ -2958,6 +2958,7 @@ << " case ISD::EntryToken: // These leaves remain the same.\n" << " case ISD::BasicBlock:\n" << " case ISD::Register:\n" + << " case ISD::HANDLENODE:\n" << " case ISD::TargetConstant:\n" << " case ISD::TargetConstantPool:\n" << " case ISD::TargetFrameIndex:\n"