This is an archive of the discontinued LLVM Phabricator instance.

[MinGW] [AArch64] Add stubs for potential automatic dllimported variables
ClosedPublic

Authored by mstorsjo on Aug 29 2018, 12:37 PM.

Details

Summary

The runtime pseudo relocations can't handle the AArch64 format PC relative addressing in adrp+add/ldr pairs. By using stubs, the potentially dllimported addresses can be touched up by the runtime pseudo relocation framework.

The MachineOperand TargetFlags range (8 bits) is just about exhausted; this allocates the last bit to MO_COFFSTUB. (In the X86 target, the TargetFlags are just direct values, while most of it is used as a bitfield on ARM and AArch64.) An alternative, to conserve bits, would be to use MO_GOT (which doesn't have much meaning in a COFF context right now).

Currently in the AArch64 target, the MO_GOT flag is set for any indirect access (so we have MO_GOT | MO_DLLIMPORT or MO_GOT | MO_COFFSTUB).

Diff Detail

Repository
rL LLVM

Event Timeline

mstorsjo created this revision.Aug 29 2018, 12:37 PM
efriedma added inline comments.Aug 29 2018, 12:47 PM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

I don't see why it matters whether the value is a GlobalVariable, specifically, as opposed to an alias or function.

I don't see why this applies specifically to MinGW, as opposed to all Windows targets.

I'm not sure what the point of the isDeclarationForLinker check is... it seems redundant with the isDSOLocal check.

mstorsjo added inline comments.Aug 29 2018, 1:03 PM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

Sorry, there's probably not nearly enough context here - this is the AArch64 followup to D51382 and D51288; it should do the same as the latter but for the AArch64 target.

This relates to MinGW and automatically importing data variables from another DLL, even though the code referencing the variable didn't use a dllimport attribute.

For functions, in case they turn out to need to be imported from a DLL even though the access didn't know that, the linker will just insert a thunk and use that instead (and even MSVC supports this).

To handle the same for data, though, the linker must create a list of deferred relocations that the MinGW runtime will process on load, to fix things up for cases when a variable turned out to be automatically imported from a DLL. All of this is a MinGW specific concept; MSVC's runtime and linker don't support it.

This patch reroutes accesses to variables that potentially might need to be imported from a DLL via a stub pointer, to avoid having the runtime fixup touch the code section.

As for aliases, I'm not familiar enough with them on the IR level to know whether they should get the same treatment or not.

efriedma added inline comments.Aug 29 2018, 1:43 PM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

Okay, that makes sense.

For the alias thing, I guess the right way to deal with it is to check something like !isa<FunctionType>(GV->getValueType()).

Still not sure why you need the isDeclarationForLinker check, given you already check isDSOLocal(). Does the isDSOLocal() check not work correctly in some cases?

efriedma added inline comments.Aug 29 2018, 1:47 PM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

Oh, just read the discussion on D51288; refactoring the DSOLocal stuff incrementally should be fine.

mstorsjo added inline comments.Aug 29 2018, 1:55 PM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

Ok, checking for functions like that might be good. We have a bunch of similar checks added in both of the earlier commits, and since I think that's a fringe case (and I'm planning to refactor parts of this to reduce the duplication, once all of X86, ARM and AArch64 supports this) perhaps it makes sense to postpone that change until then?

As for isDeclarationForLinker(), originally I had hasExternalLinkage() && isDeclaration() (with the intent to only do this for variables where we don't see any definition within the current scope). In D51382 (in clang, to skip setting the dso_local for potentially imported variables), @rnk suggested to use isDeclarationForLinker(). Even though the distinction between the two might not make sense at this spot (while it does when generating IR in clang), I think it makes sense to try to keep the (currently quite scattered) conditions as similar as possible.

@rnk - FWIW, this one should be pretty much similar to the ARM one that already was approved and merged. I'll update the second value to StubValueTy just like in the other one as well before committing; I'll do the generic refactoring and deduplication between X86/ARM/AArch64 when this one is done, and then we can consider tweaking the condition as suggested by @efriedma.

mstorsjo updated this revision to Diff 163692.Sep 3 2018, 5:06 AM

Updated the patch after SVN r341310 where I cleaned up and simplified some related code.

mstorsjo added inline comments.Sep 3 2018, 5:42 AM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

For the alias thing, I guess the right way to deal with it is to check something like !isa<FunctionType>(GV->getValueType()).

I started looking at this part now (for a separate later commit), but is it at all possible to declare an external alias? I don't find anything relevant under test/CodeGen at least.

As soon as we see a definition of the variable, we know that the variable really will be available in the local DSO, and we bypass the stub altogether. So this is only invoked for variables that are declared but not defined.

efriedma added inline comments.Sep 4 2018, 11:27 AM
lib/Target/AArch64/AArch64Subtarget.cpp
204 ↗(On Diff #163159)

You're right, an alias always points to a variable or function definition, so that isn't relevant.

Is anyone up for approving this one (@efriedma @rnk) now then? The ARM one was already approved and committed last week.

rnk accepted this revision.Sep 4 2018, 1:43 PM

lgtm

Now I see the relation to D51590.

This revision is now accepted and ready to land.Sep 4 2018, 1:43 PM
This revision was automatically updated to reflect the committed changes.