[PATCH] Alternative way of representing comdats

Rafael Ávila de Espíndola rafael.espindola at gmail.com
Thu Jun 19 20:30:10 PDT 2014


This also needs tests for the errors. In particular

* comdat that is only a forward ref
* redefinition of a comdat.
* linker errors

And one more thing, when dropping a comdat we should drop it from the comdat symbol table.

================
Comment at: docs/LangRef.rst:732
@@ +731,3 @@
+specify this key will only end up in the final object file if the linker chooses
+that key over some other key.
+
----------------
Other set of objects/sections with that key.

"the linker" in here is a bit ambiguous. Are we talking about the system linker or lib/Linker. Since we produce relocatable objects, it is probably better to state this in terms of what we do: put the global objects in a section with that comdat.


================
Comment at: docs/LangRef.rst:734
@@ +733,3 @@
+
+Note that the Mach-O platform doesn't support COMDATs and ELF only supports
+``any`` as a selection kind.
----------------
Move this after the part the defines what the selection kind is maybe?

================
Comment at: docs/LangRef.rst:761
@@ +760,3 @@
+
+Note that not all targets support COMDATs and some may only support ``any`` as a
+selection kind.
----------------
This paragraph is now redundant.

================
Comment at: docs/LangRef.rst:763
@@ +762,3 @@
+selection kind.
+
+Here is an example of a COMDAT group where a function will only be selected if
----------------
There are still some things should probably be mentioned:

* We split "IR level sections" into multiple sections in the final .o since in object files you can't have a section that is part in one comdat and part in another.
* Explain how we map mulitple sections with the same comdat to using associative comdts on COFF. Otherwise someone is sure to look at the list and think associative is missing :-)
* Alias are placed in the same comdat the aliasee computes to, if any.

================
Comment at: include/llvm/ADT/UniqueVector.h:24
@@ -23,2 +23,3 @@
 /// Entries can be fetched using operator[] with the entry ID.
 template<class T> class UniqueVector {
+public:
----------------
Cool, I had no idea we had this :-)

================
Comment at: include/llvm/IR/GlobalValue.h:115
@@ +114,3 @@
+  bool hasComdat() const { return getComdat() != nullptr; }
+  Comdat *getComdat() {
+    return const_cast<Comdat *>(
----------------
This looks odd. You probably want the const version to forward to the non-const:

return const_cast<GlobalValue*>(this)->getComdat();


================
Comment at: include/llvm/Support/GCOV.h:369
@@ +368,3 @@
+          BranchesExec(0), BranchesTaken(0) {}
+    GCOVCoverage(StringRef Name)
+        : Name(Name), LogicalLines(0), LinesExec(0), Branches(0),
----------------
unrelated change?

================
Comment at: lib/CodeGen/TargetLoweringObjectFileImpl.cpp:252
@@ -242,4 +251,3 @@
       !Kind.isCommon()) {
-    const char *Prefix;
-    Prefix = getSectionPrefixForGlobal(Kind);
+    StringRef Prefix = getSectionPrefixForGlobal(Kind);
 
----------------
Nice cleanup. You can commit this now if you want.

================
Comment at: lib/CodeGen/TargetLoweringObjectFileImpl.cpp:844
@@ -781,1 +843,3 @@
+  if ((GV->isWeakForLinker() || EmitUniquedSection || GV->hasComdat()) &&
+      !Kind.isCommon()) {
     const char *Name = getCOFFSectionNameForUniqueGlobal(Kind);
----------------
Reminds me: we should probably reject GlobalObject with common linkage and an explicit comdat in the verifier.

================
Comment at: lib/Linker/LinkModules.cpp:542
@@ -536,1 +541,3 @@
 
+static GlobalValue *getComdatLeader(Module *M, StringRef ComdatName) {
+  GlobalValue *GV = M->getNamedValue(ComdatName);
----------------
Not sure I follow. Is this assuming that the comdat name is related to the name of a global? That may be a common use but is not in any way required by the semantics.


================
Comment at: lib/Linker/LinkModules.cpp:558
@@ +557,3 @@
+  if (DstC && SrcC) {
+    Comdat::SelectionKind DSK = DstC->getSelectionKind();
+    Comdat::SelectionKind SSK = SrcC->getSelectionKind();
----------------
I assume this logic matches what the COFF linker does? Can you extract it to a helper like

bool computeResultingSeelectionKind(Comdat::SelectionKind &Result, Comdat::SelectionKind &Src, Comdat::SelectionKind &Dst) ...

and put a comment saying where the merging logic comes from.

================
Comment at: lib/Linker/LinkModules.cpp:583
@@ +582,3 @@
+    case Comdat::SelectionKind::Newest:
+      // Go with src
+      LinkFromSrc = true;
----------------
This is fairly arbitrary for Newest. We should probably error or actually check the bitcode timestamp, no?

================
Comment at: lib/Linker/LinkModules.cpp:595
@@ +594,3 @@
+
+      const auto SrcGV = dyn_cast<GlobalVariable>(SrcGVLeader);
+      const auto DstGV = dyn_cast<GlobalVariable>(DstGVLeader);
----------------
"auto *" instead of "auto" is probably better since it makes it obvious it is a pointer.

================
Comment at: lib/Linker/LinkModules.cpp:626
@@ +625,3 @@
+        return emitError("Linking COMDATs named '" + ComdatName +
+                         "': ExactMatch requries GlobalVariable");
+      }
----------------
Not just ExactMatch.

================
Comment at: lib/Linker/LinkModules.cpp:865
@@ +864,3 @@
+  bool LinkFromSrc = false;
+  Comdat *DC = nullptr;
+  if (const Comdat *SC = SGV->getComdat()) {
----------------
BTW, do we produce as error if we have

module1:

@a = ... comdat $c1, largest

module2

@b = ... comdat $c1, newest

that is, we have conflicting comdat selection kinds, but the comdats never show up in the corresponding global objects.

http://reviews.llvm.org/D4178






More information about the llvm-commits mailing list