From 4e6295128239c671181a64dea38b079a70cfc733 Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Sat, 24 Dec 2005 05:36:33 +0000 Subject: [PATCH] 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 --- lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 7 +- lib/Target/Alpha/AlphaISelLowering.cpp | 27 ++++++++ lib/Target/Alpha/AlphaISelLowering.h | 12 ++++ lib/Target/Alpha/AlphaISelPattern.cpp | 96 ++++++++++++++++---------- lib/Target/Alpha/AlphaInstrInfo.td | 81 ++++++++++++++++++---- 5 files changed, 172 insertions(+), 51 deletions(-) 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 +//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 -//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 - //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)>;