[lld] r184091 - [Passes][GOT] Split perform() into small predicate functions for readability sake.

Rui Ueyama ruiu at google.com
Mon Jun 17 10:29:47 PDT 2013


Author: ruiu
Date: Mon Jun 17 12:29:46 2013
New Revision: 184091

URL: http://llvm.org/viewvc/llvm-project?rev=184091&view=rev
Log:
[Passes][GOT] Split perform() into small predicate functions for readability sake.

Reviewers: shankarke

CC: llvm-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D988

Modified:
    lld/trunk/lib/Passes/GOTPass.cpp

Modified: lld/trunk/lib/Passes/GOTPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Passes/GOTPass.cpp?rev=184091&r1=184090&r2=184091&view=diff
==============================================================================
--- lld/trunk/lib/Passes/GOTPass.cpp (original)
+++ lld/trunk/lib/Passes/GOTPass.cpp Mon Jun 17 12:29:46 2013
@@ -40,6 +40,33 @@
 #include "llvm/ADT/DenseMap.h"
 
 namespace lld {
+
+namespace {
+bool shouldReplaceTargetWithGOTAtom(const Atom *target, bool canBypassGOT) {
+  // Accesses to shared library symbols must go through GOT.
+  if (target->definition() == Atom::definitionSharedLibrary)
+    return true;
+  // Accesses to interposable symbols in same linkage unit must also go
+  // through GOT.
+  const DefinedAtom *defTarget = dyn_cast<DefinedAtom>(target);
+  if (defTarget != nullptr &&
+      defTarget->interposable() != DefinedAtom::interposeNo) {
+    assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
+    return true;
+  }
+  // Target does not require indirection.  So, if instruction allows GOT to be
+  // by-passed, do that optimization and don't create GOT entry.
+  return !canBypassGOT;
+}
+
+const DefinedAtom *
+findGOTAtom(const Atom *target,
+            llvm::DenseMap<const Atom *, const DefinedAtom *> &targetToGOT) {
+  auto pos = targetToGOT.find(target);
+  return (pos == targetToGOT.end()) ? nullptr : pos->second;
+}
+} // end anonymous namespace
+
 void GOTPass::perform(MutableFile &mergedFile) {
   // Use map so all pointers to same symbol use same GOT entry.
   llvm::DenseMap<const Atom*, const DefinedAtom*> targetToGOT;
@@ -49,48 +76,27 @@ void GOTPass::perform(MutableFile &merge
     for (const Reference *ref : *atom) {
       // Look at instructions accessing the GOT.
       bool canBypassGOT;
-      if (isGOTAccess(ref->kind(), canBypassGOT)) {
-        const Atom* target = ref->target();
-        assert(target != nullptr);
-        const DefinedAtom* defTarget = dyn_cast<DefinedAtom>(target);
-        bool replaceTargetWithGOTAtom = false;
-        if (target->definition() == Atom::definitionSharedLibrary) {
-          // Accesses to shared library symbols must go through GOT.
-          replaceTargetWithGOTAtom = true;
-        } else if ((defTarget != nullptr) &&
-                   (defTarget->interposable() != DefinedAtom::interposeNo)) {
-          // Accesses to interposable symbols in same linkage unit
-          // must also go through GOT.
-          assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
-          replaceTargetWithGOTAtom = true;
-        } else {
-          // Target does not require indirection.  So, if instruction allows
-          // GOT to be by-passed, do that optimization and don't create
-          // GOT entry.
-          replaceTargetWithGOTAtom = !canBypassGOT;
-        }
-        if (replaceTargetWithGOTAtom) {
-          // Replace the target with a reference to a GOT entry.
-          const DefinedAtom* gotEntry = nullptr;
-          auto pos = targetToGOT.find(target);
-          if (pos == targetToGOT.end()) {
-            // This is no existing GOT entry.  Create a new one.
-            gotEntry = makeGOTEntry(*target);
-            assert(gotEntry != nullptr);
-            assert(gotEntry->contentType() == DefinedAtom::typeGOT);
-            targetToGOT[target] = gotEntry;
-          } else {
-            // Reuse an existing GOT entry.
-            gotEntry = pos->second;
-            assert(gotEntry != nullptr);
-          }
-          // Switch reference to GOT atom.
-          const_cast<Reference*>(ref)->setTarget(gotEntry);
-        }
-        // Update reference kind to reflect
-        // that target is now a GOT entry or a direct accesss.
-        updateReferenceToGOT(ref, replaceTargetWithGOTAtom);
+      if (!isGOTAccess(ref->kind(), canBypassGOT))
+        continue;
+      const Atom *target = ref->target();
+      assert(target != nullptr);
+
+      if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
+        // Update reference kind to reflect that target is a direct accesss.
+        updateReferenceToGOT(ref, false);
+        continue;
+      }
+      // Replace the target with a reference to a GOT entry.
+      const DefinedAtom *gotEntry = findGOTAtom(target, targetToGOT);
+      if (!gotEntry) {
+        gotEntry = makeGOTEntry(*target);
+        assert(gotEntry != nullptr);
+        assert(gotEntry->contentType() == DefinedAtom::typeGOT);
+        targetToGOT[target] = gotEntry;
       }
+      const_cast<Reference *>(ref)->setTarget(gotEntry);
+      // Update reference kind to reflect that target is now a GOT entry.
+      updateReferenceToGOT(ref, true);
     }
   }
 





More information about the llvm-commits mailing list