This is an archive of the discontinued LLVM Phabricator instance.

[Offloading] Embed the target features in the OffloadBinary
ClosedPublic

Authored by jhuber6 on Jun 13 2022, 12:53 PM.

Details

Summary

The target features are necessary for correctly compiling most programs
in LTO mode. Currently, these are derived in clang at link time and
passed as an arguemnt to the linker wrapper. This is problematic because
it requires knowing the required toolchain at link time, which should
not be necessry. Instead, these features should be embedded into the
offloading binary so we can unify them in the linker wrapper for LTO.
This also required changing the offload packager to interpret multiple
arguments as concatenation with a comma. This is so we can still use the
, separator for the argument list.

Depends on D127246

Diff Detail

Event Timeline

jhuber6 created this revision.Jun 13 2022, 12:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2022, 12:53 PM
jhuber6 requested review of this revision.Jun 13 2022, 12:53 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2022, 12:53 PM
tra added inline comments.Jun 13 2022, 3:39 PM
clang/lib/Driver/ToolChains/Clang.cpp
8321–8327

I think this would look cleaner if expressed along these lines:

SmallVector<StringRef> Parts = {
  "--image=file=" + File,
  "triple=" + TC->getTripleString() ,
  "arch=" + Arch,
  "kind=" + Action::GetOffloadKindName(OffloadAction->getOffloadingDeviceKind()),
};

// Add "-feature=foo" arguments to `Parts` here.

llvm::join(",", Parts)
8330

This makes a couple of implicit assumptions that we should probably make more explicit.

  • assert(!FeatureArgs.empty()), otherwise we may end up passing an empty feature=.
  • that it will be appended to the comma-separated list, which is not obvious until we actually do it later.
clang/test/Driver/openmp-offload-gpu-new.c
122

This should probably be a bit more specific/verbose. E.g. I'd want to make sure that feature= is part of the --image argument and that ptx belongs to it and is not part of some other argument (or even a file name extension).

clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
81–85

This looks like a homegrown version of getLastArg(). I wonder if there's a way to use the standard LLVM option parser for that.

Thanks for the comments, I'll try to address them.

clang/lib/Driver/ToolChains/Clang.cpp
8321–8327

Yeah, it would probably be best to organize something like this. Though we would either need to make them strings, use a string saver, or store a Twine (which probably isn't recommended). I'll try to clean it up like this.

8330

I think I should add some appropriate logic to not add this string and empty comma if the features are empty. I'll try to include that in a cleanup here.

clang/test/Driver/openmp-offload-gpu-new.c
122

Sure, I was just hesitant to make it super specific since the specific feature will change depending on the CUDA installation (or lack thereof).

clang/tools/clang-offload-packager/ClangOffloadPackager.cpp
81–85

It's copy-pasted from unifyTargetFeatures in Clang, which does the same thing. I may be able to simplify this, but for now I just wanted to copy something that ostensibly worked. Using LLVM option parsing stuff is another thing on my list. I want to pass arguments to the linker wrapper via some --offload-opt similar to --plugin-opt for LTO. Since my ultimate goal is to incorporate this into a linker completely.

tra added inline comments.Jun 13 2022, 4:13 PM
clang/test/Driver/openmp-offload-gpu-new.c
122

I'm all for concise tests as long as they:

  • express what you want to verify in a way that the reader would be able to understand w/o having to look at the source code.
  • are reasonably robust and do not produce false positives. .* wildcards make it very easy to match things unintentionally. Their use should be carefully restricted.

I wish FileCheck would have some sort of nested match check. E.g.

; CHECK : [[CANDIDATE:--option.*?\s+]]
; CHECK:  [[SUBMATCH1: match something within [[CANDIDATE]]]]
; CHECK:  [[SUBMATCH2: match something within [[SUBMATCH1]]]]
jhuber6 updated this revision to Diff 436607.Jun 13 2022, 4:55 PM

Adjust how we generate arguments.

tra added inline comments.Jun 13 2022, 5:30 PM
clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
735

// Record the index of the last occurence of the feature.

741

// Populate UnifiedFeatures only with last mentions of specific feature.

743–748
auto FeatureName = Name.drop_front(1); 
if (!LastOpt.count(FeatureName)) // could be just assert(LastOpt.count(FeatureName))
  continue
if (LastOpt[FeatureName] != I) // could be merged with the `if` above
  continue;
jhuber6 updated this revision to Diff 436611.Jun 13 2022, 5:50 PM

Does this approach work? I'm just using the reverse iterator and only adding the argument if it hasn't been seen yet.

tra accepted this revision.Jun 22 2022, 2:44 PM

LGTM with a nit.

clang/test/Driver/openmp-offload-gpu-new.c
122

Nit: ^^^ looks like this one slipped through the cracks and wasn't addressed.

This revision is now accepted and ready to land.Jun 22 2022, 2:44 PM
This revision was landed with ongoing or failed builds.Jun 23 2022, 10:15 AM
This revision was automatically updated to reflect the committed changes.