Avoid relocations in a common case.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 17 Sep 2010 22:34:41 +0000 (22:34 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 17 Sep 2010 22:34:41 +0000 (22:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114229 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/ELFObjectWriter.cpp

index 8295dacd1568393bbc33da5c383965daffd25e06..d0fc9cac4793187a311ecc779e62a64f57153a20 100644 (file)
@@ -470,12 +470,22 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
   unsigned Index = 0;
   int64_t Value = Target.getConstant();
 
+  bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
   if (!Target.isAbsolute()) {
     const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
     MCSymbolData &SD = Asm.getSymbolData(*Symbol);
     const MCSymbolData *Base = Asm.getAtom(Layout, &SD);
     MCFragment *F = SD.getFragment();
 
+    // Avoid relocations for cases like jumps and calls in the same file.
+    if (Symbol->isDefined() && !SD.isExternal() &&
+        IsPCRel &&
+        &Fragment->getParent()->getSection() == &Symbol->getSection()) {
+      uint64_t FixupAddr = Layout.getFragmentAddress(Fragment) + Fixup.getOffset();
+      FixedValue = Layout.getSymbolAddress(&SD) + Target.getConstant() - FixupAddr;
+      return;
+    }
+
     if (Base) {
       if (F && (!Symbol->isInSection() || SD.isCommon()) && !SD.isExternal()) {
         Index = F->getParent()->getOrdinal() + LocalSymbolData.size() + 1;
@@ -507,7 +517,6 @@ void ELFObjectWriterImpl::RecordRelocation(const MCAssembler &Asm,
   FixedValue = Value;
 
   // determine the type of the relocation
-  bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
   unsigned Type;
   if (Is64Bit) {
     if (IsPCRel) {