From 97aae40880d76765e9fe2c14ccc8734c1f207414 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 26 Oct 2015 18:23:16 +0000 Subject: [PATCH] ARM/ELF: Better codegen for global variable addresses. In PIC mode we were previously computing global variable addresses (or GOT entry addresses) by adding the PC, the PC-relative GOT displacement and the GOT-relative symbol/GOT entry displacement. Because the latter two displacements are fixed, we ended up performing one more addition than necessary. This change causes us to compute addresses using a single PC-relative displacement, resulting in a shorter code sequence. This reduces code size by about 4% in a recent build of Chromium for Android. As a result of this change we no longer need to compute the GOT base address in the ARM backend, which allows us to remove the Global Base Reg pass and SDAG lowering for the GOT. We also now no longer use the GOT when addressing a symbol which is known to be defined in the same linkage unit. Specifically, the symbol must have either hidden visibility or a strong definition in the current module in order to not use the the GOT. This is a change from the previous behaviour where we would use the GOT to address externally visible symbols defined in the same module. I think the only cases where this could matter are cases involving symbol interposition, but we don't really support that well anyway. Differential Revision: http://reviews.llvm.org/D13650 llvm-svn: 251322 --- llvm/include/llvm/MC/MCExpr.h | 1 + llvm/lib/MC/MCExpr.cpp | 3 +- llvm/lib/Target/ARM/ARM.h | 1 - llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 3 +- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 6 +- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp | 3 +- llvm/lib/Target/ARM/ARMConstantPoolValue.h | 3 +- llvm/lib/Target/ARM/ARMFastISel.cpp | 77 ++++++++++--------- llvm/lib/Target/ARM/ARMISelLowering.cpp | 48 ++++-------- llvm/lib/Target/ARM/ARMISelLowering.h | 1 - llvm/lib/Target/ARM/ARMInstrInfo.cpp | 70 ----------------- .../lib/Target/ARM/ARMMachineFunctionInfo.cpp | 3 +- llvm/lib/Target/ARM/ARMMachineFunctionInfo.h | 10 +-- llvm/lib/Target/ARM/ARMTargetMachine.cpp | 3 - .../ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 4 +- llvm/test/CodeGen/ARM/emutls.ll | 60 ++++----------- llvm/test/CodeGen/ARM/fast-isel-pic.ll | 20 +++-- llvm/test/CodeGen/ARM/globals.ll | 9 +-- llvm/test/CodeGen/ARM/load-global.ll | 12 ++- 19 files changed, 104 insertions(+), 233 deletions(-) diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h index 76da86cd7d63..1d6bdef0af27 100644 --- a/llvm/include/llvm/MC/MCExpr.h +++ b/llvm/include/llvm/MC/MCExpr.h @@ -188,6 +188,7 @@ public: VK_WEAKREF, // The link between the symbols in .weakref foo, bar VK_ARM_NONE, + VK_ARM_GOT_PREL, VK_ARM_TARGET1, VK_ARM_TARGET2, VK_ARM_PREL31, diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index 9d01e13e0a26..caa502086a03 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -202,6 +202,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_SIZE: return "SIZE"; case VK_WEAKREF: return "WEAKREF"; case VK_ARM_NONE: return "none"; + case VK_ARM_GOT_PREL: return "GOT_PREL"; case VK_ARM_TARGET1: return "target1"; case VK_ARM_TARGET2: return "target2"; case VK_ARM_PREL31: return "prel31"; @@ -311,7 +312,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("got", VK_GOT) .Case("gotoff", VK_GOTOFF) .Case("gotpcrel", VK_GOTPCREL) - .Case("got_prel", VK_GOTPCREL) .Case("gottpoff", VK_GOTTPOFF) .Case("indntpoff", VK_INDNTPOFF) .Case("ntpoff", VK_NTPOFF) @@ -383,6 +383,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI) .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA) .Case("none", VK_ARM_NONE) + .Case("got_prel", VK_ARM_GOT_PREL) .Case("target1", VK_ARM_TARGET1) .Case("target2", VK_ARM_TARGET2) .Case("prel31", VK_ARM_PREL31) diff --git a/llvm/lib/Target/ARM/ARM.h b/llvm/lib/Target/ARM/ARM.h index 9550a3a3cad1..cd7540e52410 100644 --- a/llvm/lib/Target/ARM/ARM.h +++ b/llvm/lib/Target/ARM/ARM.h @@ -35,7 +35,6 @@ FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM, FunctionPass *createA15SDOptimizerPass(); FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); FunctionPass *createARMExpandPseudoPass(); -FunctionPass *createARMGlobalBaseRegPass(); FunctionPass *createARMConstantIslandPass(); FunctionPass *createMLxExpansionPass(); FunctionPass *createThumb2ITBlockPass(); diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 9e2dc4578e2c..ef56a0114f5c 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -819,8 +819,7 @@ getModifierVariantKind(ARMCP::ARMCPModifier Modifier) { case ARMCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD; case ARMCP::TPOFF: return MCSymbolRefExpr::VK_TPOFF; case ARMCP::GOTTPOFF: return MCSymbolRefExpr::VK_GOTTPOFF; - case ARMCP::GOT: return MCSymbolRefExpr::VK_GOT; - case ARMCP::GOTOFF: return MCSymbolRefExpr::VK_GOTOFF; + case ARMCP::GOT_PREL: return MCSymbolRefExpr::VK_ARM_GOT_PREL; } llvm_unreachable("Invalid ARMCPModifier!"); } diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index a32af35ed5d8..62f1dae78393 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -1379,9 +1379,9 @@ static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) { // instructions, so that's probably OK, but is PIC always correct when // we get here? if (ACPV->isGlobalValue()) - NewCPV = ARMConstantPoolConstant:: - Create(cast(ACPV)->getGV(), PCLabelId, - ARMCP::CPValue, 4); + NewCPV = ARMConstantPoolConstant::Create( + cast(ACPV)->getGV(), PCLabelId, ARMCP::CPValue, + 4, ACPV->getModifier(), ACPV->mustAddCurrentAddress()); else if (ACPV->isExtSymbol()) NewCPV = ARMConstantPoolSymbol:: Create(MF.getFunction()->getContext(), diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp index 7d41c69f08b8..c9849b2605ea 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -52,8 +52,7 @@ const char *ARMConstantPoolValue::getModifierText() const { // strings if that's legal. case ARMCP::no_modifier: return "none"; case ARMCP::TLSGD: return "tlsgd"; - case ARMCP::GOT: return "GOT"; - case ARMCP::GOTOFF: return "GOTOFF"; + case ARMCP::GOT_PREL: return "GOT_PREL"; case ARMCP::GOTTPOFF: return "gottpoff"; case ARMCP::TPOFF: return "tpoff"; } diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h index 36f63e239a9e..21ad07d394c9 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.h +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h @@ -39,8 +39,7 @@ namespace ARMCP { enum ARMCPModifier { no_modifier, TLSGD, - GOT, - GOTOFF, + GOT_PREL, GOTTPOFF, TPOFF }; diff --git a/llvm/lib/Target/ARM/ARMFastISel.cpp b/llvm/lib/Target/ARM/ARMFastISel.cpp index 113f1f12f8c6..a2093ebb85db 100644 --- a/llvm/lib/Target/ARM/ARMFastISel.cpp +++ b/llvm/lib/Target/ARM/ARMFastISel.cpp @@ -2939,48 +2939,51 @@ bool ARMFastISel::tryToFoldLoadIntoMI(MachineInstr *MI, unsigned OpNo, unsigned ARMFastISel::ARMLowerPICELF(const GlobalValue *GV, unsigned Align, MVT VT) { - bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); - ARMConstantPoolConstant *CPV = - ARMConstantPoolConstant::Create(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); - unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); + bool UseGOT_PREL = + !(GV->hasHiddenVisibility() || GV->isStrongDefinitionForLinker()); - unsigned Opc; - unsigned DestReg1 = createResultReg(TLI.getRegClassFor(VT)); - // Load value. - if (isThumb2) { - DestReg1 = constrainOperandRegClass(TII.get(ARM::t2LDRpci), DestReg1, 0); - AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(ARM::t2LDRpci), DestReg1) - .addConstantPoolIndex(Idx)); - Opc = UseGOTOFF ? ARM::t2ADDrr : ARM::t2LDRs; - } else { - // The extra immediate is for addrmode2. - DestReg1 = constrainOperandRegClass(TII.get(ARM::LDRcp), DestReg1, 0); - AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, - DbgLoc, TII.get(ARM::LDRcp), DestReg1) - .addConstantPoolIndex(Idx).addImm(0)); - Opc = UseGOTOFF ? ARM::ADDrr : ARM::LDRrs; - } + LLVMContext *Context = &MF->getFunction()->getContext(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create( + GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, + UseGOT_PREL ? ARMCP::GOT_PREL : ARMCP::no_modifier, + /*AddCurrentAddress=*/UseGOT_PREL); - unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); - if (GlobalBaseReg == 0) { - GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT)); - AFI->setGlobalBaseReg(GlobalBaseReg); - } + unsigned ConstAlign = + MF->getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); + unsigned Idx = MF->getConstantPool()->getConstantPoolIndex(CPV, ConstAlign); - unsigned DestReg2 = createResultReg(TLI.getRegClassFor(VT)); - DestReg2 = constrainOperandRegClass(TII.get(Opc), DestReg2, 0); - DestReg1 = constrainOperandRegClass(TII.get(Opc), DestReg1, 1); - GlobalBaseReg = constrainOperandRegClass(TII.get(Opc), GlobalBaseReg, 2); - MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, - DbgLoc, TII.get(Opc), DestReg2) - .addReg(DestReg1) - .addReg(GlobalBaseReg); - if (!UseGOTOFF) + unsigned TempReg = MF->getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); + unsigned Opc = isThumb2 ? ARM::t2LDRpci : ARM::LDRcp; + MachineInstrBuilder MIB = + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), TempReg) + .addConstantPoolIndex(Idx); + if (Opc == ARM::LDRcp) MIB.addImm(0); - AddOptionalDefs(MIB); + AddDefaultPred(MIB); - return DestReg2; + // Fix the address by adding pc. + unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); + Opc = Subtarget->isThumb() ? ARM::tPICADD : UseGOT_PREL ? ARM::PICLDR + : ARM::PICADD; + DestReg = constrainOperandRegClass(TII.get(Opc), DestReg, 0); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DestReg) + .addReg(TempReg) + .addImm(ARMPCLabelIndex); + if (!Subtarget->isThumb()) + AddDefaultPred(MIB); + + if (UseGOT_PREL && Subtarget->isThumb()) { + unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(ARM::t2LDRi12), NewDestReg) + .addReg(DestReg) + .addImm(0); + DestReg = NewDestReg; + AddOptionalDefs(MIB); + } + return DestReg; } bool ARMFastISel::fastLowerArguments() { diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 857c85cab070..36f8886ea0ed 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -788,7 +788,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); - setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); setOperationAction(ISD::BlockAddress, MVT::i32, Custom); @@ -2637,10 +2636,19 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op, SDLoc dl(Op); const GlobalValue *GV = cast(Op)->getGlobal(); if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { - bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); - ARMConstantPoolValue *CPV = - ARMConstantPoolConstant::Create(GV, - UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); + bool UseGOT_PREL = + !(GV->hasHiddenVisibility() || GV->isStrongDefinitionForLinker()); + + MachineFunction &MF = DAG.getMachineFunction(); + ARMFunctionInfo *AFI = MF.getInfo(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + EVT PtrVT = getPointerTy(DAG.getDataLayout()); + SDLoc dl(Op); + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create( + GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, + UseGOT_PREL ? ARMCP::GOT_PREL : ARMCP::no_modifier, + /*AddCurrentAddress=*/UseGOT_PREL); SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); SDValue Result = DAG.getLoad( @@ -2648,9 +2656,9 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op, MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), false, false, false, 0); SDValue Chain = Result.getValue(1); - SDValue GOT = DAG.getGLOBAL_OFFSET_TABLE(PtrVT); - Result = DAG.getNode(ISD::ADD, dl, PtrVT, Result, GOT); - if (!UseGOTOFF) + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32); + Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + if (UseGOT_PREL) Result = DAG.getLoad(PtrVT, dl, Chain, Result, MachinePointerInfo::getGOT(DAG.getMachineFunction()), false, false, false, 0); @@ -2727,29 +2735,6 @@ SDValue ARMTargetLowering::LowerGlobalAddressWindows(SDValue Op, return Result; } -SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, - SelectionDAG &DAG) const { - assert(Subtarget->isTargetELF() && - "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); - MachineFunction &MF = DAG.getMachineFunction(); - ARMFunctionInfo *AFI = MF.getInfo(); - unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - EVT PtrVT = getPointerTy(DAG.getDataLayout()); - SDLoc dl(Op); - unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = - ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", - ARMPCLabelIndex, PCAdj); - SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); - CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); - SDValue Result = - DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, - MachinePointerInfo::getConstantPool(DAG.getMachineFunction()), - false, false, false, 0); - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, dl, MVT::i32); - return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); -} - SDValue ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { SDLoc dl(Op); @@ -6783,7 +6768,6 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); - case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); case ISD::EH_SJLJ_SETUP_DISPATCH: return LowerEH_SJLJ_SETUP_DISPATCH(Op, DAG); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index e4b8891728b9..99a18f0d3324 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -514,7 +514,6 @@ namespace llvm { SDValue LowerToTLSExecModels(GlobalAddressSDNode *GA, SelectionDAG &DAG, TLSModel::Model model) const; - SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp index 39715aa9ad74..cf973d68085f 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp @@ -132,73 +132,3 @@ void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI, MIB.setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); AddDefaultPred(MIB); } - -namespace { -/// ARMCGBR - Create Global Base Reg pass. This initializes the PIC -/// global base register for ARM ELF. -struct ARMCGBR : public MachineFunctionPass { - static char ID; - ARMCGBR() : MachineFunctionPass(ID) {} - - bool runOnMachineFunction(MachineFunction &MF) override { - ARMFunctionInfo *AFI = MF.getInfo(); - if (AFI->getGlobalBaseReg() == 0) - return false; - const ARMSubtarget &STI = - static_cast(MF.getSubtarget()); - // Don't do this for Thumb1. - if (STI.isThumb1Only()) - return false; - - const TargetMachine &TM = MF.getTarget(); - if (TM.getRelocationModel() != Reloc::PIC_) - return false; - - LLVMContext *Context = &MF.getFunction()->getContext(); - unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - unsigned PCAdj = STI.isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create( - *Context, "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); - - unsigned Align = - MF.getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context)); - unsigned Idx = MF.getConstantPool()->getConstantPoolIndex(CPV, Align); - - MachineBasicBlock &FirstMBB = MF.front(); - MachineBasicBlock::iterator MBBI = FirstMBB.begin(); - DebugLoc DL = FirstMBB.findDebugLoc(MBBI); - unsigned TempReg = - MF.getRegInfo().createVirtualRegister(&ARM::rGPRRegClass); - unsigned Opc = STI.isThumb2() ? ARM::t2LDRpci : ARM::LDRcp; - const TargetInstrInfo &TII = *STI.getInstrInfo(); - MachineInstrBuilder MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), TempReg) - .addConstantPoolIndex(Idx); - if (Opc == ARM::LDRcp) - MIB.addImm(0); - AddDefaultPred(MIB); - - // Fix the GOT address by adding pc. - unsigned GlobalBaseReg = AFI->getGlobalBaseReg(); - Opc = STI.isThumb2() ? ARM::tPICADD : ARM::PICADD; - MIB = BuildMI(FirstMBB, MBBI, DL, TII.get(Opc), GlobalBaseReg) - .addReg(TempReg) - .addImm(ARMPCLabelIndex); - if (Opc == ARM::PICADD) - AddDefaultPred(MIB); - - return true; - } - - const char *getPassName() const override { - return "ARM PIC Global Base Reg Initialization"; - } - - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); - MachineFunctionPass::getAnalysisUsage(AU); - } -}; -} - -char ARMCGBR::ID = 0; -FunctionPass *llvm::createARMGlobalBaseRegPass() { return new ARMCGBR(); } diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp index 8ca4be725acd..ac0330fbcb34 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.cpp @@ -20,5 +20,4 @@ ARMFunctionInfo::ARMFunctionInfo(MachineFunction &MF) RestoreSPFromFP(false), LRSpilledForFarJump(false), FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0), - PICLabelUId(0), VarArgsFrameIndex(0), HasITBlocks(false), - GlobalBaseReg(0) {} + PICLabelUId(0), VarArgsFrameIndex(0), HasITBlocks(false) {} diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h index 40ace69e94ca..d6447978ef2c 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -110,11 +110,6 @@ class ARMFunctionInfo : public MachineFunctionInfo { /// pass. DenseMap CPEClones; - /// GlobalBaseReg - keeps track of the virtual register initialized for - /// use as the global base register. This is used for PIC in some PIC - /// relocation models. - unsigned GlobalBaseReg; - /// ArgumentStackSize - amount of bytes on stack consumed by the arguments /// being passed on the stack unsigned ArgumentStackSize; @@ -133,7 +128,7 @@ public: FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0), GPRCS1Size(0), GPRCS2Size(0), DPRCSAlignGapSize(0), DPRCSSize(0), NumAlignedDPRCS2Regs(0), PICLabelUId(0), - VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {} + VarArgsFrameIndex(0), HasITBlocks(false) {} explicit ARMFunctionInfo(MachineFunction &MF); @@ -204,9 +199,6 @@ public: bool hasITBlocks() const { return HasITBlocks; } void setHasITBlocks(bool h) { HasITBlocks = h; } - unsigned getGlobalBaseReg() const { return GlobalBaseReg; } - void setGlobalBaseReg(unsigned Reg) { GlobalBaseReg = Reg; } - void recordCPEClone(unsigned CPIdx, unsigned CPCloneIdx) { if (!CPEClones.insert(std::make_pair(CPCloneIdx, CPIdx)).second) llvm_unreachable("Duplicate entries!"); diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index b5815090ab21..3e3c8646a819 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -362,9 +362,6 @@ bool ARMPassConfig::addPreISel() { bool ARMPassConfig::addInstSelector() { addPass(createARMISelDag(getARMTargetMachine(), getOptLevel())); - - if (TM->getTargetTriple().isOSBinFormatELF() && TM->Options.EnableFastISel) - addPass(createARMGlobalBaseRegPass()); return false; } diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 804d3534096a..52eba8be288f 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -95,7 +95,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_GOTTPOFF: Type = ELF::R_ARM_TLS_IE32; break; - case MCSymbolRefExpr::VK_GOTPCREL: + case MCSymbolRefExpr::VK_ARM_GOT_PREL: Type = ELF::R_ARM_GOT_PREL; break; } @@ -192,7 +192,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, case MCSymbolRefExpr::VK_GOTOFF: Type = ELF::R_ARM_GOTOFF32; break; - case MCSymbolRefExpr::VK_GOTPCREL: + case MCSymbolRefExpr::VK_ARM_GOT_PREL: Type = ELF::R_ARM_GOT_PREL; break; case MCSymbolRefExpr::VK_ARM_TARGET1: diff --git a/llvm/test/CodeGen/ARM/emutls.ll b/llvm/test/CodeGen/ARM/emutls.ll index a313b8c68dd1..7ba50dd249bb 100644 --- a/llvm/test/CodeGen/ARM/emutls.ll +++ b/llvm/test/CodeGen/ARM/emutls.ll @@ -10,9 +10,7 @@ declare i8* @my_emutls_get_address(i8*) define i32 @my_get_xyz() { ; ARM32-LABEL: my_get_xyz: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl my_emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -34,9 +32,7 @@ entry: define i32 @f1() { ; ARM32-LABEL: f1: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -48,9 +44,7 @@ entry: define i32* @f2() { ; ARM32-LABEL: f2: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -61,9 +55,7 @@ entry: define i32 @f3() nounwind { ; ARM32-LABEL: f3: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -75,9 +67,7 @@ entry: define i32* @f4() { ; ARM32-LABEL: f4: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -88,9 +78,7 @@ entry: define i32 @f5() nounwind { ; ARM32-LABEL: f5: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -102,9 +90,7 @@ entry: define i32* @f6() { ; ARM32-LABEL: f6: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -115,9 +101,7 @@ entry: define i32 @f7() { ; ARM32-LABEL: f7: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -129,9 +113,7 @@ entry: define i32* @f8() { ; ARM32-LABEL: f8: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -142,9 +124,7 @@ entry: define i32 @f9() { ; ARM32-LABEL: f9: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldr r0, [r0] @@ -156,9 +136,7 @@ entry: define i32* @f10() { ; ARM32-LABEL: f10: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: pop @@ -169,9 +147,7 @@ entry: define i16 @f11() { ; ARM32-LABEL: f11: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrh r0, [r0] @@ -183,9 +159,7 @@ entry: define i32 @f12() { ; ARM32-LABEL: f12: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrsh r0, [r0] @@ -198,9 +172,7 @@ entry: define i8 @f13() { ; ARM32-LABEL: f13: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrb r0, [r0] ; ARM32-NEXT: pop @@ -213,9 +185,7 @@ entry: define i32 @f14() { ; ARM32-LABEL: f14: ; ARM32: ldr r0, -; ARM32-NEXT: ldr r1, -; ARM32: add r0, pc, r0 -; ARM32-NEXT: ldr r0, [r1, r0] +; ARM32: ldr r0, [pc, r0] ; ARM32-NEXT: bl __emutls_get_address(PLT) ; ARM32-NEXT: ldrsb r0, [r0] ; ARM32-NEXT: pop diff --git a/llvm/test/CodeGen/ARM/fast-isel-pic.ll b/llvm/test/CodeGen/ARM/fast-isel-pic.ll index 75b82e8b0d64..a4494eedcf6c 100644 --- a/llvm/test/CodeGen/ARM/fast-isel-pic.ll +++ b/llvm/test/CodeGen/ARM/fast-isel-pic.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB ; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARMv7 -; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s --check-prefix=THUMB-ELF -; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -relocation-model=pic -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefix=ARMv7-ELF +; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -arm-force-fast-isel -relocation-model=pic -mtriple=thumbv7-none-linux-gnueabi | FileCheck %s --check-prefix=THUMB-ELF +; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort=1 -arm-force-fast-isel -relocation-model=pic -mtriple=armv7-none-linux-gnueabi | FileCheck %s --check-prefix=ARMv7-ELF @g = global i32 0, align 4 @@ -13,8 +13,8 @@ entry: ; THUMB: add [[reg0]], pc ; THUMB-ELF: LoadGV ; THUMB-ELF: ldr r[[reg0:[0-9]+]], -; THUMB-ELF: ldr r[[reg1:[0-9]+]], -; THUMB-ELF: ldr r[[reg0]], [r[[reg0]], r[[reg1]]] +; THUMB-ELF: add r[[reg0]], pc +; THUMB-ELF: ldr r[[reg0]], [r[[reg0]]] ; ARM: LoadGV ; ARM: ldr [[reg1:r[0-9]+]], ; ARM: add [[reg1]], pc, [[reg1]] @@ -26,8 +26,7 @@ entry: ; ARMv7-ELF: ldr r[[reg2:[0-9]+]], ; ARMv7-ELF: .LPC ; ARMv7-ELF-NEXT: add r[[reg2]], pc -; ARMv7-ELF: ldr r[[reg3:[0-9]+]], -; ARMv7-ELF: ldr r[[reg2]], [r[[reg3]], r[[reg2]]] +; ARMv7-ELF: ldr r[[reg2]], [r[[reg2]]] %tmp = load i32, i32* @g ret i32 %tmp } @@ -43,8 +42,8 @@ entry: ; THUMB: ldr r[[reg3]], [r[[reg3]]] ; THUMB-ELF: LoadIndirectSymbol ; THUMB-ELF: ldr r[[reg3:[0-9]+]], -; THUMB-ELF: ldr r[[reg4:[0-9]+]], -; THUMB-ELF: ldr r[[reg3]], [r[[reg3]], r[[reg4]]] +; THUMB-ELF: ldr r[[reg4:[0-9]+]], [r[[reg3]]] +; THUMB-ELF: ldr r0, [r[[reg4]]] ; ARM: LoadIndirectSymbol ; ARM: ldr [[reg4:r[0-9]+]], ; ARM: ldr [[reg4]], [pc, [[reg4]]] @@ -56,9 +55,8 @@ entry: ; ARMv7-ELF: LoadIndirectSymbol ; ARMv7-ELF: ldr r[[reg5:[0-9]+]], ; ARMv7-ELF: .LPC -; ARMv7-ELF-NEXT: add r[[reg5]], pc -; ARMv7-ELF: ldr r[[reg6:[0-9]+]], -; ARMv7-ELF: ldr r[[reg5]], [r[[reg6]], r[[reg5]]] +; ARMv7-ELF: ldr r[[reg6:[0-9]+]], [pc, r[[reg5]]] +; ARMv7-ELF: ldr r0, [r[[reg5]]] %tmp = load i32, i32* @i ret i32 %tmp } diff --git a/llvm/test/CodeGen/ARM/globals.ll b/llvm/test/CodeGen/ARM/globals.ll index bab96dadce55..e6aa2db744d5 100644 --- a/llvm/test/CodeGen/ARM/globals.ll +++ b/llvm/test/CodeGen/ARM/globals.ll @@ -60,16 +60,13 @@ define i32 @test1() { ; LinuxPIC-LABEL: test1: ; LinuxPIC: ldr r0, .LCPI0_0 -; LinuxPIC: ldr r1, .LCPI0_1 ; LinuxPIC: .LPC0_0: -; LinuxPIC: add r0, pc, r0 -; LinuxPIC: ldr r0, [r1, r0] +; LinuxPIC: ldr r0, [pc, r0] ; LinuxPIC: ldr r0, [r0] ; LinuxPIC: bx lr ; LinuxPIC: .align 2 ; LinuxPIC: .LCPI0_0: -; LinuxPIC: .long _GLOBAL_OFFSET_TABLE_-(.LPC0_0+8) -; LinuxPIC: .LCPI0_1: -; LinuxPIC: .long G(GOT) +; LinuxPIC: .Ltmp0: +; LinuxPIC: .long G(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) diff --git a/llvm/test/CodeGen/ARM/load-global.ll b/llvm/test/CodeGen/ARM/load-global.ll index 34748bc848bd..eade2fda3705 100644 --- a/llvm/test/CodeGen/ARM/load-global.ll +++ b/llvm/test/CodeGen/ARM/load-global.ll @@ -4,6 +4,7 @@ ; RUN: llc < %s -mtriple=thumbv6-apple-darwin -relocation-model=pic | FileCheck %s -check-prefix=PIC_T ; RUN: llc < %s -mtriple=armv7-apple-darwin -relocation-model=pic | FileCheck %s -check-prefix=PIC_V7 ; RUN: llc < %s -mtriple=armv6-linux-gnueabi -relocation-model=pic | FileCheck %s -check-prefix=LINUX +; RUN: llc < %s -mtriple=thumbv6-linux-gnueabi -relocation-model=pic | FileCheck %s -check-prefix=LINUX_T @G = external global i32 @@ -40,11 +41,14 @@ define i32 @test1() { ; LINUX: test1 ; LINUX: ldr r0, .LCPI0_0 -; LINUX: ldr r1, .LCPI0_1 -; LINUX: add r0, pc, r0 -; LINUX: ldr r0, [r1, r0] +; LINUX: ldr r0, [pc, r0] ; LINUX: ldr r0, [r0] -; LINUX: .long G(GOT) +; LINUX: .long G(GOT_PREL)-((.LPC0_0+8)-.Ltmp0) + +; LINUX_T: ldr r0, .LCPI0_0 +; LINUX_T: add r0, pc +; LINUX_T: ldr r0, [r0] +; LINUX_T: ldr r0, [r0] %tmp = load i32, i32* @G ret i32 %tmp }