This is an archive of the discontinued LLVM Phabricator instance.

Expose IRMover flag
Needs RevisionPublic

Authored by eschew on Jun 3 2017, 3:20 PM.

Details

Summary

In the 4.0 cycle, the NamedOnly flag in IRMover.cpp was changed from true to false. This wound up breaking my out-of-tree compiler frontend.

The attached patch threads through the NamedOnly flag from IRMover to Linker and adds a new flag enum value. Thus, the behavior of existing code remains the same, but linker clients can override the NamedOnly behavior as needed.

I'm looking into adding a test for the new flag but wanted to throw the current diff up for review first.

Diff Detail

Repository
rL LLVM

Event Timeline

eschew created this revision.Jun 3 2017, 3:20 PM
tejohnson edited edge metadata.Jun 4 2017, 10:04 PM

You could add an llvm-link based test, adding an option for controlling this behavior to that tool.

include/llvm/Linker/IRMover.h
64

How about just add the parameter to the existing constructor, but with a default of false (here and elsewhere).

pcc added a reviewer: pcc.Jun 4 2017, 10:38 PM
eschew updated this revision to Diff 101593.Jun 6 2017, 12:08 PM
eschew edited the summary of this revision. (Show Details)

This adds a defaulted parameter instead of multiple constructors. I also added a hidden flag to llvm-link.

So far I haven't managed to construct inputs which get llvm-link'ed differently when the flag is toggled (I verified that the OnlyNamed flag in TypeFinder.cpp does indeed change). I tried using the testcase from the bug which changed the flag, https://reviews.llvm.org/D26840 , but the linking behavior is essentially unchanged between ThinLTO mode, plain llvm-link, and llvm-link -no-unnamed-types. I also tried reducing a testcase from my frontend, but haven't managed to reproduce the difference in behavior via llvm-link.

FWIW I changed my frontend, so I'm not blocked by this patch, but I am curious whether there is any LLVM IR that links different via llvm-link under the NamedOnly flag.

eschew marked an inline comment as done.Jun 6 2017, 12:09 PM
pcc requested changes to this revision.Jun 6 2017, 12:22 PM

I'm not yet convinced that we should take this. If changing the flag from true to false broke your frontend, it may mean that there is a bug in the IRMover that was exposed by your frontend. So we may be introducing a flag that means "do you want this set of bugs or that other set of bugs", which doesn't seem like a good idea to me.

Can you go into more detail as to how changing the flag broke your frontend?

This revision now requires changes to proceed.Jun 6 2017, 12:22 PM

I'm almost certain the bug was in my frontend's misuse of LLVM's linking infrastructure, not a bug in linking itself (per se).

My frontend first constructs a shell Module with declarations for the language's runtime functions, then codegens into the shell, then links the shell with the runtime. It was constructing the shell from a precompiled bitcode by iterating over the runtime's Module and calling shell->getOrInsertFunction(...) providing *a type from the runtime Module*. I'm guessing mixing types like that between modules isn't kosher. The workaround/fix is to round-trip the constructed shell through bitcode.

What I'm confused about is: what does the OnlyNamed flag (in TypeFinder.cpp) actually do, from the perspective of LLVM IR?

I'm almost certain the bug was in my frontend's misuse of LLVM's linking infrastructure, not a bug in linking itself (per se).

My frontend first constructs a shell Module with declarations for the language's runtime functions, then codegens into the shell, then links the shell with the runtime. It was constructing the shell from a precompiled bitcode by iterating over the runtime's Module and calling shell->getOrInsertFunction(...) providing *a type from the runtime Module*. I'm guessing mixing types like that between modules isn't kosher. The workaround/fix is to round-trip the constructed shell through bitcode.

What I'm confused about is: what does the OnlyNamed flag (in TypeFinder.cpp) actually do, from the perspective of LLVM IR?

I'm not familiar with the TypeFinder, but I did a little bit of digging. As you noted earlier, the change of this flag from true to false recently was a fix by Mehdi for ThinLTO IR linking (r287453 - [ThinLTO] Fix crash when importing an opaque type). Looks like we need to eagerly map all types because of complications due to the fact that we are only linking some of the symbols. But it sounds like you couldn't reproduce the original problem with the test case in that change?

There are 2 other callers with OnlyNamed=false:

  1. the AsmPrinter calls this with OnlyNamed=false because it is printing all the types.
  2. StripTypeNames in IPO/StripSymbols.cpp, and that code is actually looking for named types, and skips those without names! So I am not sure why it needs to call TypeFinder with OnlyNamed=false to start with.