[PATCH] add support for LayoutAfter/LayoutBefore references

Michael Spencer bigcheesegs at gmail.com
Wed Feb 6 15:16:40 PST 2013



================
Comment at: include/lld/Core/Pass.h:140-141
@@ +139,4 @@
+
+  typedef std::map<const Atom *, const Atom *> AtomToAtomT;
+  typedef std::map<const Atom *, uint64_t> AtomToOrdinalT;
+  AtomToAtomT _followOnNexts;
----------------
These would be better as llvm::DenseMap.

================
Comment at: include/lld/Core/Pass.h:117-146
@@ -113,11 +116,32 @@
 
-/// Pass for sorting atoms.
-class OrderPass : public Pass {
+/// Pass for atoms layout.
+class LayoutPass : public Pass {
 public:
-  OrderPass() : Pass() {}
-  
+  class CompareAtoms {
+  public:
+    CompareAtoms(const LayoutPass &pass) : _layout(pass) {}
+    bool operator()(const DefinedAtom *left, const DefinedAtom *right);
+  private:
+    const LayoutPass &_layout;
+  };
+
+  LayoutPass() : Pass(), _compareAtoms(*this) {}
+
   /// Sorts atoms in mergedFile by content type then by command line order.
   virtual void perform(MutableFile &mergedFile);
-};
 
+  virtual ~LayoutPass() {}
+
+private:
+  void buildFollowOnTable(MutableFile::DefinedAtomRange &range);
+  void buildPrecededByTable(MutableFile::DefinedAtomRange &range);
+  void buildOrdinalOverrideMap(MutableFile::DefinedAtomRange &range);
+
+  typedef std::map<const Atom *, const Atom *> AtomToAtomT;
+  typedef std::map<const Atom *, uint64_t> AtomToOrdinalT;
+  AtomToAtomT _followOnNexts;
+  AtomToAtomT _followOnRoots;
+  AtomToOrdinalT _ordinalOverrideMap;
+  CompareAtoms _compareAtoms;
+};
 
----------------
This should really be in the Passes library.

================
Comment at: include/lld/Core/Reference.h:52-73
@@ -45,2 +51,24 @@
 
+  virtual StringRef kindToString() const {
+    switch (kind()) {
+    case -1:
+      return "layoutbefore";
+      break;
+    case -2:
+      return "layoutafter";
+      break;
+    default:
+      return "unknown";
+    }
+  }
+
+  virtual int32_t stringToKind(StringRef kindString) const {
+    if (kindString == "layoutbefore")
+      return LayoutBefore;
+    else if (kindString == "layoutafter")
+      return LayoutAfter;
+    assert(0 && "unknown relocation kind");
+    return -1;
+  }
+
   /// If the reference is a fixup in the Atom, then this returns the
----------------
This is adding another way to transform string <-> kind. We should have one place be responsible for this, and have it know that kinds < 0 are reserved for the core.

================
Comment at: lib/Passes/LayoutPass.cpp:9-15
@@ +8,9 @@
+//===----------------------------------------------------------------------===//
+//
+// This linker pass does the layout of the atoms. The pass is done after the 
+// order their .o files were found on the command line, then by order of the
+// atoms (address) in the .o file.  But some atoms have a prefered location
+// in their section (such as pinned to the start or end of the section), so
+// the sort must take that into account too.
+//
+//===----------------------------------------------------------------------===//
----------------
Doxygen comment.

================
Comment at: lib/Passes/LayoutPass.cpp:107-110
@@ +106,6 @@
+        // the root of the targetAtom to the root of the current chain
+        if (_followOnRoots.count(targetAtom) == 0) {
+          _followOnRoots[targetAtom] = _followOnRoots[ai];
+        } else {
+          AtomToAtomT::iterator iter = _followOnRoots.find(targetAtom);
+          // The followon is part of another chain
----------------
This is doing the lookup two times. Just do:

  auto iter = _followOnRoots.find(targetAtom);
  if (iter == _followOnRoots.end())
    _followOnRoots[targetAtom] = _followOnRoots[ai];
  else

This is still two lookups in the not-found case. You could actually reduce this to one lookup with lower_bound, but that doesn't work if you switch to DenseMap.

================
Comment at: lib/Passes/LayoutPass.cpp:93
@@ +92,3 @@
+}
+
+void LayoutPass::buildFollowOnTable(MutableFile::DefinedAtomRange &range) {
----------------
Can we get an overview of this algorithm?

================
Comment at: lib/Passes/LayoutPass.cpp:111-112
@@ +110,4 @@
+          AtomToAtomT::iterator iter = _followOnRoots.find(targetAtom);
+          // The followon is part of another chain
+          if (iter->second == targetAtom) {
+            const Atom *a = targetAtom;
----------------
The comment doesn't seem to match the condition. Do you mean the target is the start of another chain?

================
Comment at: lib/Passes/LayoutPass.cpp:115
@@ +114,3 @@
+            while (true) {
+              _followOnRoots[a] = _followOnRoots[ai];
+              // Set all the follow on's for the targetAtom to be
----------------
_followOnRoots[ai] was already looked up on line 102. That lookup should be reused here.

================
Comment at: lib/Passes/LayoutPass.cpp:128
@@ +127,3 @@
+                   // Get to the root of the chain
+                   // TODO : fix it 
+            const Atom *a = _followOnRoots[targetAtom];
----------------
Fix what?

================
Comment at: lib/Passes/LayoutPass.cpp:145
@@ +144,3 @@
+
+              if (((DefinedAtom *)a)->size() != 0) {
+                foundNonZeroSizeAtom = true;
----------------
You should just be using DefinedAtom everywhere. Is MutableFile::DefinedAtomRange not a const DefinedAtom *?

================
Comment at: lib/Passes/LayoutPass.cpp:179-180
@@ +178,4 @@
+}
+
+void LayoutPass::buildPrecededByTable(MutableFile::DefinedAtomRange &range) {
+  // This table would convert precededby references to follow on 
----------------
Describe algorithm.

================
Comment at: lib/Passes/LayoutPass.cpp:183-185
@@ +182,5 @@
+  // references so that we have only one table 
+  for (auto ai : range) {
+    for (const Reference *r : *ai) {
+      if (r->kind() == lld::Reference::LayoutBefore) {
+        const Atom *targetAtom = r->target();
----------------
Instead of looping over everything multiple times, it would be better to loop once and dispatch on r->kind(). That is if the algorithm can be made to handle both LayoutAfter and LayoutBefore at the same time.

================
Comment at: lib/Passes/LayoutPass.cpp:200
@@ +199,3 @@
+          }
+        } else if ((_followOnRoots.find(targetAtom))->second == targetAtom) {
+          // Is the targetAtom in chain with the targetAtom as the root ?
----------------
The extra () are unnecessary.


http://llvm-reviews.chandlerc.com/D373



More information about the llvm-commits mailing list