ARM/ELF: Better codegen for global variable addresses.
authorPeter Collingbourne <peter@pcc.me.uk>
Mon, 26 Oct 2015 18:23:16 +0000 (18:23 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Mon, 26 Oct 2015 18:23:16 +0000 (18:23 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251322 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/llvm/MC/MCExpr.h
lib/MC/MCExpr.cpp
lib/Target/ARM/ARM.h
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMBaseInstrInfo.cpp
lib/Target/ARM/ARMConstantPoolValue.cpp
lib/Target/ARM/ARMConstantPoolValue.h
lib/Target/ARM/ARMFastISel.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h
lib/Target/ARM/ARMInstrInfo.cpp
lib/Target/ARM/ARMMachineFunctionInfo.cpp
lib/Target/ARM/ARMMachineFunctionInfo.h
lib/Target/ARM/ARMTargetMachine.cpp
lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
test/CodeGen/ARM/emutls.ll
test/CodeGen/ARM/fast-isel-pic.ll
test/CodeGen/ARM/globals.ll
test/CodeGen/ARM/load-global.ll

index 76da86cd7d6376f6529f5d7a819ee2e41d0f25d2..1d6bdef0af279a7a71593658c00842bb22ae9189 100644 (file)
@@ -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,
index 9d01e13e0a2699121c1094c26580c8e0161a9f93..caa502086a0324111fc135cf53162b535a8bdaeb 100644 (file)
@@ -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)
index 9550a3a3cad1243f04666ac79d9ccd103c52d1ab..cd7540e5241085c5904d58cbcd1fcca5ada8e151 100644 (file)
@@ -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();
index 9e2dc4578e2c21a367761e892a10b678081b0054..ef56a0114f5c24a5d018c96ab7d6c8097846ddf0 100644 (file)
@@ -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!");
 }
index a32af35ed5d8e6462fc5d184b736e3a16a718ca1..62f1dae7839309088a9324087be693d463f2f804 100644 (file)
@@ -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<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId,
-             ARMCP::CPValue, 4);
+    NewCPV = ARMConstantPoolConstant::Create(
+        cast<ARMConstantPoolConstant>(ACPV)->getGV(), PCLabelId, ARMCP::CPValue,
+        4, ACPV->getModifier(), ACPV->mustAddCurrentAddress());
   else if (ACPV->isExtSymbol())
     NewCPV = ARMConstantPoolSymbol::
       Create(MF.getFunction()->getContext(),
index 7d41c69f08b87c95d18b12a357a3df0b11e9b762..c9849b2605ea2c1228fe41d7173d6a033ce2a89e 100644 (file)
@@ -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";
   }
index 36f63e239a9e1a11136a17e55c67e62471b633d7..21ad07d394c96c9eb4c6f69ff94036af03e0ddbb 100644 (file)
@@ -39,8 +39,7 @@ namespace ARMCP {
   enum ARMCPModifier {
     no_modifier,
     TLSGD,
-    GOT,
-    GOTOFF,
+    GOT_PREL,
     GOTTPOFF,
     TPOFF
   };
index 113f1f12f8c6f2abc0e4ac8a366e2260967eb113..a2093ebb85dba7e500cbcd5e15a41deac3f6a1fd 100644 (file)
@@ -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());
+
+  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 ConstAlign =
+      MF->getDataLayout().getPrefTypeAlignment(Type::getInt32PtrTy(*Context));
+  unsigned Idx = MF->getConstantPool()->getConstantPoolIndex(CPV, ConstAlign);
+
+  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);
+  AddDefaultPred(MIB);
 
-  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;
-  }
+  // 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);
 
-  unsigned GlobalBaseReg = AFI->getGlobalBaseReg();
-  if (GlobalBaseReg == 0) {
-    GlobalBaseReg = MRI.createVirtualRegister(TLI.getRegClassFor(VT));
-    AFI->setGlobalBaseReg(GlobalBaseReg);
+  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);
   }
-
-  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)
-    MIB.addImm(0);
-  AddOptionalDefs(MIB);
-
-  return DestReg2;
+  return DestReg;
 }
 
 bool ARMFastISel::fastLowerArguments() {
index 857c85cab0702bcb76cbeadfbfc118300adf3278..36f8886ea0ed9a8ecc1fac6807f54288a4f20dad 100644 (file)
@@ -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<GlobalAddressSDNode>(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<ARMFunctionInfo>();
+    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<ARMFunctionInfo>();
-  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);
index e4b8891728b94950c3b47f7e65d68c6265cf4dbd..99a18f0d33241643c250a798cfdaf7fbc153d59e 100644 (file)
@@ -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;
index 39715aa9ad74708efdaf16fd3291262f49efa1bd..cf973d68085f281e6e8cac205ccfeaa2a964d9ac 100644 (file)
@@ -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<ARMFunctionInfo>();
-    if (AFI->getGlobalBaseReg() == 0)
-      return false;
-    const ARMSubtarget &STI =
-        static_cast<const ARMSubtarget &>(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(); }
index 8ca4be725acd713637fd94b3e0bb264a2d2e53a9..ac0330fbcb34884f812e0099aa75732a54203b94 100644 (file)
@@ -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) {}
index 40ace69e94cae338e2d950c2994b3f772df5a63e..d6447978ef2c30dfbe491541cdfcd4c26f220f34 100644 (file)
@@ -110,11 +110,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
   /// pass.
   DenseMap<unsigned, unsigned> 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!");
index b5815090ab2174b58f0b567772ba1740c8c4151a..3e3c8646a8192e40a77ab7d0bfc61d436bbfa1a4 100644 (file)
@@ -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;
 }
 
index 804d3534096abf5fb753ab933ddec3c170c136dc..52eba8be288fdfba6dc23e9ed11f956c140e9e00 100644 (file)
@@ -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:
index a313b8c68dd1cb2d15203d012aac81663109bae2..7ba50dd249bbc79fb9200947456d1ee2b374dc31 100644 (file)
@@ -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
index 75b82e8b0d64d140aac19bdcdf5326c610c4e3be..a4494eedcf6cd6d3352efd4c768e1abbcdf4cdb7 100644 (file)
@@ -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
 }
index bab96dadce55ee00ea47713c6cef137f406ea4e3..e6aa2db744d5854c249c2f2b394fd28d2c218e27 100644 (file)
@@ -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)
index 34748bc848bdb3d2c7297f29b53e77afc1239aad..eade2fda37054160f75f0ab1ba93a5f80b846bc8 100644 (file)
@@ -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
 }