Skip to content

Commit 2bc9193

Browse files
authored
[clang-offload-bundler] Initialize assembly parsers (#2886)
This is needed for reading bitcode objects with inline assembly. Signed-off-by: Sergey Dmitriev <serguei.n.dmitriev@intel.com>
1 parent a08eeb4 commit 2bc9193

File tree

3 files changed

+79
-8
lines changed

3 files changed

+79
-8
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// REQUIRES: x86-registered-target
2+
// UNSUPPORTED: system-windows
3+
4+
// This test check that clang-offload-bundler correctly handles embedded
5+
// bitcode objects with module-level inline assembly when generating
6+
// .tgtsym section with defined symbols.
7+
8+
// RUN: %clang -target %itanium_abi_triple -c %s -o %t.o
9+
// RUN: %clang -target x86_64-pc-linux-gnu -emit-llvm -c %s -o %t.tgt1
10+
// RUN: %clang -target spir64 -emit-llvm -c %s -o %t.tgt2
11+
12+
// RUN: clang-offload-bundler -type=o -targets=host-%itanium_abi_triple,openmp-x86_64-pc-linux-gnu,sycl-spir64 -inputs=%t.o,%t.tgt1,%t.tgt2 -outputs=%t.fat.o
13+
// RUN: llvm-readobj --string-dump=.tgtsym %t.fat.o | FileCheck %s
14+
15+
// CHECK: String dump of section '.tgtsym':
16+
// CHECK-DAG: openmp-x86_64-pc-linux-gnu.foo
17+
// CHECK-DAG: sycl-spir64.foo
18+
19+
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
20+
void foo(void) {}

clang/tools/clang-offload-bundler/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
set(LLVM_LINK_COMPONENTS Core Object Support)
1+
set(LLVM_LINK_COMPONENTS
2+
AllTargetsAsmParsers
3+
AllTargetsDescs
4+
AllTargetsInfos
5+
BitWriter
6+
Core
7+
IRReader
8+
Object
9+
Support
10+
)
211

312
add_clang_tool(clang-offload-bundler
413
ClangOffloadBundler.cpp

clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
#include "llvm/ADT/StringSet.h"
2424
#include "llvm/ADT/StringSwitch.h"
2525
#include "llvm/ADT/Triple.h"
26+
#include "llvm/Bitcode/BitcodeReader.h"
27+
#include "llvm/Bitcode/BitcodeWriter.h"
2628
#include "llvm/IR/LLVMContext.h"
29+
#include "llvm/IRReader/IRReader.h"
2730
#include "llvm/Object/Archive.h"
2831
#include "llvm/Object/ArchiveWriter.h"
2932
#include "llvm/Object/Binary.h"
@@ -40,6 +43,7 @@
4043
#include "llvm/Support/Program.h"
4144
#include "llvm/Support/Signals.h"
4245
#include "llvm/Support/StringSaver.h"
46+
#include "llvm/Support/TargetSelect.h"
4347
#include "llvm/Support/WithColor.h"
4448
#include "llvm/Support/raw_ostream.h"
4549
#include <algorithm>
@@ -146,6 +150,13 @@ static bool hasHostKind(StringRef Target) {
146150
return OffloadKind == "host";
147151
}
148152

153+
static Triple getTargetTriple(StringRef Target) {
154+
StringRef OffloadKind;
155+
StringRef TargetTriple;
156+
getOffloadKindAndTriple(Target, OffloadKind, TargetTriple);
157+
return Triple(TargetTriple);
158+
}
159+
149160
/// Generic file handler interface.
150161
class FileHandler {
151162
public:
@@ -557,6 +568,7 @@ class ObjectFileHandler final : public FileHandler {
557568
Expected<SmallVector<char, 0>> makeTargetSymbolTable() {
558569
SmallVector<char, 0> SymbolsBuf;
559570
raw_svector_ostream SymbolsOS(SymbolsBuf);
571+
LLVMContext Context;
560572

561573
for (unsigned I = 0; I < NumberOfInputs; ++I) {
562574
if (I == HostInputIndex)
@@ -569,9 +581,36 @@ class ObjectFileHandler final : public FileHandler {
569581
if (!BufOrErr)
570582
return createFileError(InputFileNames[I], BufOrErr.getError());
571583

572-
LLVMContext Context;
584+
std::unique_ptr<MemoryBuffer> Buf = std::move(*BufOrErr);
585+
586+
// Workaround for the absence of assembly parser for spir target. If this
587+
// input is a bitcode for spir target we need to remove module-level
588+
// inline asm from it, if there is one, and recreate the buffer with new
589+
// contents.
590+
// TODO: remove this workaround once spir target gets asm parser.
591+
if (isBitcode((const unsigned char *)Buf->getBufferStart(),
592+
(const unsigned char *)Buf->getBufferEnd()))
593+
if (getTargetTriple(TargetNames[I]).isSPIR()) {
594+
SMDiagnostic Err;
595+
std::unique_ptr<Module> Mod = parseIR(*Buf, Err, Context);
596+
if (!Mod)
597+
return createStringError(inconvertibleErrorCode(),
598+
Err.getMessage());
599+
600+
if (!Mod->getModuleInlineAsm().empty()) {
601+
Mod->setModuleInlineAsm("");
602+
603+
SmallVector<char, 0> ModuleBuf;
604+
raw_svector_ostream ModuleOS(ModuleBuf);
605+
WriteBitcodeToFile(*Mod, ModuleOS);
606+
607+
Buf = MemoryBuffer::getMemBufferCopy(ModuleOS.str(),
608+
Buf->getBufferIdentifier());
609+
}
610+
}
611+
573612
Expected<std::unique_ptr<Binary>> BinOrErr =
574-
createBinary(BufOrErr.get()->getMemBufferRef(), &Context);
613+
createBinary(Buf->getMemBufferRef(), &Context);
575614

576615
// If it is not a symbolic file just ignore it since we cannot do anything
577616
// with it.
@@ -1213,11 +1252,9 @@ class ArchiveFileHandler final : public FileHandler {
12131252

12141253
if (Mode == OutputType::Archive) {
12151254
// Determine archive kind for the offload target.
1216-
StringRef TargetKind;
1217-
StringRef TargetTriple;
1218-
getOffloadKindAndTriple(CurrBundle->first(), TargetKind, TargetTriple);
1219-
auto ArKind = Triple(TargetTriple).isOSDarwin() ? Archive::K_DARWIN
1220-
: Archive::K_GNU;
1255+
auto ArKind = getTargetTriple(CurrBundle->first()).isOSDarwin()
1256+
? Archive::K_DARWIN
1257+
: Archive::K_GNU;
12211258

12221259
// And write archive to the output.
12231260
Expected<std::unique_ptr<MemoryBuffer>> NewAr =
@@ -1527,6 +1564,11 @@ int main(int argc, const char **argv) {
15271564
return 0;
15281565
}
15291566

1567+
// These calls are needed so that we can read bitcode correctly.
1568+
InitializeAllTargetInfos();
1569+
InitializeAllTargetMCs();
1570+
InitializeAllAsmParsers();
1571+
15301572
auto reportError = [argv](Error E) {
15311573
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
15321574
};

0 commit comments

Comments
 (0)