From: Andrew Lenharth Date: Sat, 24 Dec 2005 05:36:33 +0000 (+0000) Subject: Let's see if we can break things. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4e6295128239c671181a64dea38b079a70cfc733;p=oota-llvm.git Let's see if we can break things. Lower GOT relative addresses to Lo and HI. Update both ISels to select them when they can. Saves instructions here and there. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25001 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index f570fa6a39a..838841d1f80 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -203,13 +203,16 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) { CurDAG->getTargetFrameIndex(FI, MVT::i32), getI64Imm(0)); } - case ISD::ConstantPool: { + case AlphaISD::GlobalBaseReg: + return getGlobalBaseReg(); + + case ISD::TargetConstantPool: { Constant *C = cast(N)->get(); SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64); Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg()); return CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp); } - case ISD::GlobalAddress: { + case ISD::TargetGlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64); return CurDAG->SelectNodeTo(N, Alpha::LDQl, MVT::i64, GA, diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp index 9b2fce2c1a9..8d2ffa7177e 100644 --- a/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/lib/Target/Alpha/AlphaISelLowering.cpp @@ -104,6 +104,11 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) setOperationAction(ISD::LOCATION, MVT::Other, Expand); setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); + // We want to legalize GlobalAddress and ConstantPool nodes into the + // appropriate instructions to materialize the address. + setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); + setOperationAction(ISD::ConstantPool, MVT::i64, Custom); + addLegalFPImmediate(+0.0); //F31 addLegalFPImmediate(-0.0); //-F31 @@ -434,6 +439,28 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0)); } } + case ISD::ConstantPool: { + Constant *C = cast(Op)->get(); + SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i64); + + SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, CPI, + DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); + SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, CPI, Hi); + return Lo; + } + case ISD::GlobalAddress: { + GlobalAddressSDNode *GSDN = cast(Op); + GlobalValue *GV = GSDN->getGlobal(); + SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i64, GSDN->getOffset()); + + if (!GV->hasWeakLinkage() && !GV->isExternal()) { + SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, GA, + DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); + SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, GA, Hi); + return Lo; + } else + return GA; + } } diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h index c42dbcef4ba..16ff79d5ca3 100644 --- a/lib/Target/Alpha/AlphaISelLowering.h +++ b/lib/Target/Alpha/AlphaISelLowering.h @@ -27,6 +27,18 @@ namespace llvm { FIRST_NUMBER = ISD::BUILTIN_OP_END+Alpha::INSTRUCTION_LIST_END, //These corrospond to the identical Instruction ITOFT_, FTOIT_, CVTQT_, CVTQS_, CVTTQ_, + + /// GPRelHi/GPRelLo - These represent the high and low 16-bit + /// parts of a global address respectively. These nodes have + /// two operands, the first of which must be a + /// TargetGlobalAddress, and the second of which must be a + /// Constant. Selected naively, these turn into 'ldah R(G)' and + /// 'lda R(C)', though these are usually folded into other nodes. + GPRelHi, GPRelLo, + + /// GlobalBaseReg, used to restore the GOT ptr + GlobalBaseReg, + }; } diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp index 2ce18e1ae31..80e18e7325b 100644 --- a/lib/Target/Alpha/AlphaISelPattern.cpp +++ b/lib/Target/Alpha/AlphaISelPattern.cpp @@ -676,31 +676,26 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { getValueInfo(dyn_cast(N.getOperand(2))->getValue(), i, j, k); - GlobalAddressSDNode *GASD = dyn_cast(Address); - if (GASD && !GASD->getGlobal()->isExternal()) { - Tmp1 = MakeReg(MVT::i64); - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::LDAHr, 2, Tmp1) - .addGlobalAddress(GASD->getGlobal()).addReg(Alpha::R29); - if (EnableAlphaLSMark) - BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) - .addImm(getUID()); - BuildMI(BB, GetRelVersion(Opc), 2, Result) - .addGlobalAddress(GASD->getGlobal()).addReg(Tmp1); - } else if (ConstantPoolSDNode *CP = - dyn_cast(Address)) { - unsigned CPIdx = BB->getParent()->getConstantPool()-> - getConstantPoolIndex(CP->get()); - AlphaLowering.restoreGP(BB); - has_sym = true; - Tmp1 = MakeReg(MVT::i64); - BuildMI(BB, Alpha::LDAHr, 2, Tmp1).addConstantPoolIndex(CPIdx) - .addReg(Alpha::R29); - if (EnableAlphaLSMark) - BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) - .addImm(getUID()); - BuildMI(BB, GetRelVersion(Opc), 2, Result) - .addConstantPoolIndex(CPIdx).addReg(Tmp1); + if (Address.getOpcode() == AlphaISD::GPRelLo) { + unsigned Hi = SelectExpr(Address.getOperand(1)); + Address = Address.getOperand(0); + if (GlobalAddressSDNode *GASD = dyn_cast(Address)) { + if (EnableAlphaLSMark) + BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) + .addImm(getUID()); + BuildMI(BB, GetRelVersion(Opc), 2, Result) + .addGlobalAddress(GASD->getGlobal()).addReg(Hi); + } else if (ConstantPoolSDNode *CP = + dyn_cast(Address)) { + unsigned CPIdx = BB->getParent()->getConstantPool()-> + getConstantPoolIndex(CP->get()); + has_sym = true; + if (EnableAlphaLSMark) + BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) + .addImm(getUID()); + BuildMI(BB, GetRelVersion(Opc), 2, Result) + .addConstantPoolIndex(CPIdx).addReg(Tmp1); + } else assert(0 && "Unknown Lo part"); } else if(Address.getOpcode() == ISD::FrameIndex) { if (EnableAlphaLSMark) BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) @@ -718,6 +713,36 @@ unsigned AlphaISel::SelectExpr(SDOperand N) { } return Result; } + case AlphaISD::GlobalBaseReg: + AlphaLowering.restoreGP(BB); + BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R29).addReg(Alpha::R29); + return Result; + case AlphaISD::GPRelHi: + if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(0))) + BuildMI(BB, Alpha::LDAHr, 2, Result) + .addConstantPoolIndex(BB->getParent()->getConstantPool()-> + getConstantPoolIndex(CP->get())) + .addReg(SelectExpr(N.getOperand(1))); + else if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(0))) + BuildMI(BB, Alpha::LDAHr, 2, Result) + .addGlobalAddress(GASD->getGlobal()) + .addReg(SelectExpr(N.getOperand(1))); + else assert(0 && "unknown Hi part"); + return Result; + case AlphaISD::GPRelLo: + if (ConstantPoolSDNode *CP = dyn_cast(N.getOperand(0))) + BuildMI(BB, Alpha::LDAr, 2, Result) + .addConstantPoolIndex(BB->getParent()->getConstantPool()-> + getConstantPoolIndex(CP->get())) + .addReg(SelectExpr(N.getOperand(1))); + else if (GlobalAddressSDNode *GASD = + dyn_cast(N.getOperand(0))) + BuildMI(BB, Alpha::LDAr, 2, Result) + .addGlobalAddress(GASD->getGlobal()) + .addReg(SelectExpr(N.getOperand(1))); + else assert(0 && "unknown Lo part"); + return Result; case ISD::GlobalAddress: AlphaLowering.restoreGP(BB); @@ -1699,17 +1724,16 @@ void AlphaISel::Select(SDOperand N) { getValueInfo(cast(N.getOperand(3))->getValue(), i, j, k); - GlobalAddressSDNode *GASD = dyn_cast(Address); - if (GASD && !GASD->getGlobal()->isExternal()) { - Tmp2 = MakeReg(MVT::i64); - AlphaLowering.restoreGP(BB); - BuildMI(BB, Alpha::LDAHr, 2, Tmp2) - .addGlobalAddress(GASD->getGlobal()).addReg(Alpha::R29); - if (EnableAlphaLSMark) - BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) - .addImm(getUID()); - BuildMI(BB, GetRelVersion(Opc), 3).addReg(Tmp1) - .addGlobalAddress(GASD->getGlobal()).addReg(Tmp2); + if (Address.getOpcode() == AlphaISD::GPRelLo) { + unsigned Hi = SelectExpr(Address.getOperand(1)); + Address = Address.getOperand(0); + if (GlobalAddressSDNode *GASD = dyn_cast(Address)) { + if (EnableAlphaLSMark) + BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) + .addImm(getUID()); + BuildMI(BB, GetRelVersion(Opc), 3).addReg(Tmp1) + .addGlobalAddress(GASD->getGlobal()).addReg(Hi); + } else assert(0 && "Unknown Lo part"); } else if(Address.getOpcode() == ISD::FrameIndex) { if (EnableAlphaLSMark) BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k) diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td index 75fa67c408a..9508c101e85 100644 --- a/lib/Target/Alpha/AlphaInstrInfo.td +++ b/lib/Target/Alpha/AlphaInstrInfo.td @@ -25,6 +25,8 @@ def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>; def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>; def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>; def Alpha_cvttq : SDNode<"AlphaISD::CVTTQ_", SDTFPUnaryOp, []>; +def Alpha_gprello : SDNode<"AlphaISD::GPRelLo", SDTIntBinOp, []>; +def Alpha_gprelhi : SDNode<"AlphaISD::GPRelHi", SDTIntBinOp, []>; // These are target-independent nodes, but have target-specific formats. def SDT_AlphaCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i64> ]>; @@ -437,7 +439,8 @@ def BR : BForm<0x30, "br $RA,$DISP">; //Branch def BR_DAG : BFormD<0x30, "br $$31,$DISP">; //Branch -let isLoad = 1, OperandList = (ops GPRC:$RA, GPRC:$RB), disp = 0 in { +let OperandList = (ops GPRC:$RA, GPRC:$RB), disp = 0 in { +let isLoad = 1 in { def LDQdag : MFormD<0x29, "ldq $RA,0($RB)", [(set GPRC:$RA, (load GPRC:$RB))]>; def LDLdag : MFormD<0x29, "ldl $RA,0($RB)", @@ -446,7 +449,8 @@ def LDBUdag : MFormD<0x0A, "ldbu $RA,0($RB)", [(set GPRC:$RA, (zextload GPRC:$RB, i8))]>; def LDWUdag : MFormD<0x0C, "ldwu $RA,0($RB)", [(set GPRC:$RA, (zextload GPRC:$RB, i16))]>; - +} +let isStore = 1 in { def STBdag : MFormD<0x0E, "stb $RA,0($RB)", [(truncstore GPRC:$RA, GPRC:$RB, i8)]>; def STWdag : MFormD<0x0D, "stw $RA,0($RB)", @@ -456,6 +460,7 @@ def STLdag : MFormD<0x2C, "stl $RA,0($RB)", def STQdag : MFormD<0x2D, "stq $RA,0($RB)", [(store GPRC:$RA, GPRC:$RB)]>; } +} def : Pat<(i64 (extload GPRC:$src, i8)), (LDBUdag GPRC:$src)>; @@ -464,48 +469,56 @@ def : Pat<(i64 (extload GPRC:$src, i16)), def : Pat<(i64 (extload GPRC:$src, i32)), (LDLdag GPRC:$src)>; -let isLoad = 1, OperandList = (ops F4RC:$RA, GPRC:$RB), disp = 0 in { +let OperandList = (ops F4RC:$RA, GPRC:$RB), disp = 0 in { +let isStore = 1 in def STSdag : MFormD<0x26, "sts $RA,0($RB)", [(store F4RC:$RA, GPRC:$RB)]>; +let isLoad = 1 in def LDSdag : MFormD<0x22, "lds $RA,0($RB)", [(set F4RC:$RA, (load GPRC:$RB))]>; } -let isLoad = 1, OperandList = (ops F8RC:$RA, GPRC:$RB), disp = 0 in { +let OperandList = (ops F8RC:$RA, GPRC:$RB), disp = 0 in { +let isStore = 1 in def STTdag : MFormD<0x27, "stt $RA,0($RB)", [(store F8RC:$RA, GPRC:$RB)]>; +let isLoad = 1 in def LDTdag : MFormD<0x23, "ldt $RA,0($RB)", [(set F8RC:$RA, (load GPRC:$RB))]>; } +let isStore = 1 in { //Stores, int def STB : MForm<0x0E, "stb $RA,$DISP($RB)">; // Store byte def STW : MForm<0x0D, "stw $RA,$DISP($RB)">; // Store word def STL : MForm<0x2C, "stl $RA,$DISP($RB)">; // Store longword def STQ : MForm<0x2D, "stq $RA,$DISP($RB)">; //Store quadword -//Loads, int -def LDL : MForm<0x28, "ldl $RA,$DISP($RB)">; // Load sign-extended longword -def LDQ : MForm<0x29, "ldq $RA,$DISP($RB)">; //Load quadword -def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte -def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word - //Stores, float let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in def STS : MFormAlt<0x26, "sts $RA,$DISP($RB)">; //Store S_floating let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in def STT : MFormAlt<0x27, "stt $RA,$DISP($RB)">; //Store T_floating +} + +let isLoad = 1 in { +//Loads, int +def LDL : MForm<0x28, "ldl $RA,$DISP($RB)">; // Load sign-extended longword +def LDQ : MForm<0x29, "ldq $RA,$DISP($RB)">; //Load quadword +def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte +def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word //Loads, float let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in def LDS : MFormAlt<0x22, "lds $RA,$DISP($RB)">; //Load S_floating let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in def LDT : MFormAlt<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating +} //Load address def LDA : MForm<0x08, "lda $RA,$DISP($RB)">; //Load address def LDAH : MForm<0x09, "ldah $RA,$DISP($RB)">; //Load address high - +let isLoad = 1 in { //Loads, int, Rellocated Low form def LDLr : MForm<0x28, "ldl $RA,$DISP($RB)\t\t!gprellow">; // Load sign-extended longword def LDQr : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!gprellow">; //Load quadword @@ -517,19 +530,22 @@ let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in def LDSr : MFormAlt<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in def LDTr : MFormAlt<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating +} //Load address, rellocated low and high form def LDAr : MForm<0x08, "lda $RA,$DISP($RB)\t\t!gprellow">; //Load address def LDAHr : MForm<0x09, "ldah $RA,$DISP($RB)\t\t!gprelhigh">; //Load address high + //load address, rellocated gpdist form def LDAg : MgForm<0x08, "lda $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address def LDAHg : MgForm<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">; //Load address - //Load quad, rellocated literal form +let isLoad = 1 in def LDQl : MForm<0x29, "ldq $RA,$DISP($RB)\t\t!literal">; //Load quadword +let isStore = 1 in { //Stores, int def STBr : MForm<0x0E, "stb $RA,$DISP($RB)\t\t!gprellow">; // Store byte def STWr : MForm<0x0D, "stw $RA,$DISP($RB)\t\t!gprellow">; // Store word @@ -541,7 +557,7 @@ let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in def STSr : MFormAlt<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in def STTr : MFormAlt<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating - +} //Branches, int def BEQ : BForm<0x39, "beq $RA,$DISP">; //Branch if = zero @@ -803,3 +819,42 @@ def : Pat<(fneg F4RC:$RB), def : Pat<(mulhs GPRC:$RA, GPRC:$RB), (SUBQ (UMULH GPRC:$RA, GPRC:$RB), (ADDQ (CMOVGE GPRC:$RB, R31, GPRC:$RA), (CMOVGE GPRC:$RA, R31, GPRC:$RB)))>; + +def : Pat<(Alpha_gprello tglobaladdr:$in, GPRC:$reg), + (LDAr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(Alpha_gprelhi tglobaladdr:$in, GPRC:$reg), + (LDAHr tglobaladdr:$in, GPRC:$reg)>; + +//GOT Relative loads +def : Pat<(i64 (load (Alpha_gprello tglobaladdr:$in, GPRC:$reg))), + (LDQr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(f64 (load (Alpha_gprello tglobaladdr:$in, GPRC:$reg))), + (LDTr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(f32 (load (Alpha_gprello tglobaladdr:$in, GPRC:$reg))), + (LDSr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (sextload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i32)), + (LDLr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (extload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i32)), + (LDLr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (zextload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i16)), + (LDWUr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (extload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i16)), + (LDWUr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (zextload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i8)), + (LDBUr tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(i64 (extload (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i8)), + (LDBUr tglobaladdr:$in, GPRC:$reg)>; + +//GOT Relative Stores +def : Pat<(store GPRC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg)), + (STQr GPRC:$val, tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(store F8RC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg)), + (STTr F8RC:$val, tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(store F4RC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg)), + (STSr F4RC:$val, tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(truncstore GPRC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i32), + (STLr GPRC:$val, tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(truncstore GPRC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i16), + (STWr GPRC:$val, tglobaladdr:$in, GPRC:$reg)>; +def : Pat<(truncstore GPRC:$val, (Alpha_gprello tglobaladdr:$in, GPRC:$reg), i8), + (STBr GPRC:$val, tglobaladdr:$in, GPRC:$reg)>;