[PATCH] [LayoutPass] Add a method to check the followon graph structure.

Shankar Kalpathi Easwaran shankarke at gmail.com
Wed Jun 5 15:28:46 PDT 2013


  You should try adding a test too, by mixing Debug outputs too. Wait for BigCheese to review this too.


================
Comment at: include/lld/Core/Atom.h:68-73
@@ -67,2 +67,8 @@
 
+  // Returns a human-readable string representation of this atom. Used
+  // only for debugging.
+  virtual std::string toDebugString() const {
+    return name().empty() ? "<anonymous>" : name();
+  }
+
 protected:
----------------
This should be moved the code thats using it.

================
Comment at: lib/Passes/LayoutPass.cpp:412-415
@@ +411,6 @@
+      std::string refstr = ref->target()->toDebugString();
+      if (ref->kind() == lld::Reference::kindLayoutBefore) {
+        llvm::dbgs () << "    layout-before: " << refstr << "\n";
+      } else if (ref->kind() == lld::Reference::kindLayoutAfter) {
+        llvm::dbgs () << "    layout-after: " << refstr << "\n";
+      }
----------------
not handling In-Group references.

================
Comment at: lib/Passes/LayoutPass.cpp:423-425
@@ +422,5 @@
+
+// Exit if there's a cycle in a followon chain reachable from the
+// given root atom. Uses the tortoise and hare algorithm to detect a
+// cycle.
+void checkNoCycleInFollowonChain(AtomToAtomT &followOnNexts,
----------------
doxygen ?

================
Comment at: lib/Passes/LayoutPass.cpp:426-438
@@ +425,15 @@
+// cycle.
+void checkNoCycleInFollowonChain(AtomToAtomT &followOnNexts,
+                                 const DefinedAtom *root) {
+  const DefinedAtom *tortoise = root;
+  const DefinedAtom *hare = followOnNexts[root];
+  while (true) {
+    if (!tortoise || !hare)
+      return;
+    if (tortoise == hare)
+      showCycleDetectedError(followOnNexts, tortoise);
+    tortoise = followOnNexts[tortoise];
+    hare = followOnNexts[followOnNexts[hare]];
+  }
+}
+
----------------
can all these functions be const ?

================
Comment at: lib/Passes/LayoutPass.cpp:440-461
@@ +439,24 @@
+
+void checkReachabilityFromRoot(AtomToAtomT &followOnRoots,
+                               const DefinedAtom *atom) {
+  if (!atom) return;
+  auto i = followOnRoots.find(atom);
+  if (i == followOnRoots.end()) {
+    std::string msg = "Atom <" + atom->toDebugString()
+        + "> has no follow-on root!";
+    llvm_unreachable(msg.c_str());
+  }
+  const DefinedAtom *ap = i->second;
+  while (true) {
+    const DefinedAtom *next = followOnRoots[ap];
+    if (!next) {
+      std::string msg = "Atom <" + atom->toDebugString()
+          + "> is not reachable from its root!";
+      llvm_unreachable(msg.c_str());
+    }
+    if (next == ap)
+      return;
+    ap = next;
+  }
+}
+
----------------
const function ?

================
Comment at: lib/Passes/LayoutPass.cpp:463-472
@@ +462,12 @@
+
+void printDefinedAtoms(const MutableFile::DefinedAtomRange &atomRange) {
+  for (const DefinedAtom *atom : atomRange) {
+    llvm::dbgs() << "  file=" << atom->file().path()
+                 << ", name=" << atom->name()
+                 << ", size=" << atom->size()
+                 << ", type=" << atom->contentType()
+                 << ", ordinal=" << atom->ordinal()
+                 << "\n";
+  }
+}
+} // end anonymous namespace
----------------
const function ?

================
Comment at: lib/Passes/LayoutPass.cpp:475-493
@@ +474,21 @@
+
+/// Verify that the followon chain is sane. Should not be called in
+/// release binary.
+void LayoutPass::checkFollowonChain(MutableFile::DefinedAtomRange &range) {
+  ScopedTask task(getDefaultDomain(), "LayoutPass::checkFollowonChain");
+
+  // Verify that there's no cycle in follow-on chain.
+  std::set<const DefinedAtom *> roots;
+  for (const auto &ai : _followOnRoots)
+    roots.insert(ai.second);
+  for (const DefinedAtom *root : roots)
+    checkNoCycleInFollowonChain(_followOnNexts, root);
+
+  // Verify that all the atoms in followOnNexts have references to
+  // their roots.
+  for (const auto &ai : _followOnNexts) {
+    checkReachabilityFromRoot(_followOnRoots, ai.first);
+    checkReachabilityFromRoot(_followOnRoots, ai.second);
+  }
+}
+
----------------
all of the code that shouldnt be in release build should be in 

ifndef NDEBUG

================
Comment at: lib/ReaderWriter/ELF/Atoms.h:484-488
@@ -483,2 +483,7 @@
 
+  std::string toDebugString() const {
+    std::string name = DefinedAtom::toDebugString();
+    return name + " in " + _sectionName.str();
+  }
+
 private:
----------------
should be moved to LayoutPass, you can call toDebugString(Atom) and have this function in the LayoutPass.



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



More information about the llvm-commits mailing list