Skip to content

Commit c5708f9

Browse files
sndmitrievbader
authored andcommitted
[Clang][Bundler] Do not require host triple for extracting device bundles (#571)
* [Clang][Bundler] Do not require host triple for extracting device bundles Bundler currently requires host triple to be provided no matter if you are performing bundling or unbundling, but for unbundling operation such requirement is too restrictive. You may for example want to examine device part of the object for a particular offload target, but you have to extract host part as well even though you do not need it. Host triple isn't really needed for unbundling, so this patch removes that requirement. This is a cherry-pick of two llvm.org patches https://reviews.llvm.org/D66598 (prerequisite for the second patch) https://reviews.llvm.org/D66601 I addition to that this patch includes a fix for a bundler assertion on debug build Signed-off-by: Sergey Dmitriev <[email protected]>
1 parent 32f0cd5 commit c5708f9

File tree

2 files changed

+46
-15
lines changed

2 files changed

+46
-15
lines changed

clang/test/Driver/clang-offload-bundler.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,20 @@
170170
// RUN: diff %t.i %t.res.i
171171
// RUN: diff %t.tgt1 %t.res.tgt1
172172
// RUN: diff %t.tgt2 %t.res.tgt2
173+
// RUN: clang-offload-bundler -type=i -targets=openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.tgt1 -inputs=%t.bundle3.i -unbundle
174+
// RUN: diff %t.tgt1 %t.res.tgt1
173175
// RUN: clang-offload-bundler -type=ii -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.ii,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.ii -unbundle
174176
// RUN: diff %t.ii %t.res.ii
175177
// RUN: diff %t.tgt1 %t.res.tgt1
176178
// RUN: diff %t.tgt2 %t.res.tgt2
179+
// RUN: clang-offload-bundler -type=ii -targets=openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt2 -inputs=%t.bundle3.ii -unbundle
180+
// RUN: diff %t.tgt2 %t.res.tgt2
177181
// RUN: clang-offload-bundler -type=ll -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.ll,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.ll -unbundle
178182
// RUN: diff %t.ll %t.res.ll
179183
// RUN: diff %t.tgt1 %t.res.tgt1
180184
// RUN: diff %t.tgt2 %t.res.tgt2
185+
// RUN: clang-offload-bundler -type=ll -targets=openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.tgt1 -inputs=%t.bundle3.ll -unbundle
186+
// RUN: diff %t.tgt1 %t.res.tgt1
181187
// RUN: clang-offload-bundler -type=s -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.s,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.s -unbundle
182188
// RUN: diff %t.s %t.res.s
183189
// RUN: diff %t.tgt1 %t.res.tgt1
@@ -186,6 +192,8 @@
186192
// RUN: diff %t.s %t.res.s
187193
// RUN: diff %t.tgt1 %t.res.tgt1
188194
// RUN: diff %t.tgt2 %t.res.tgt2
195+
// RUN: clang-offload-bundler -type=s -targets=openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt2 -inputs=%t.bundle3.s -unbundle
196+
// RUN: diff %t.tgt2 %t.res.tgt2
189197

190198
// Check if we can unbundle a file with no magic strings.
191199
// RUN: clang-offload-bundler -type=s -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.s,%t.res.tgt1,%t.res.tgt2 -inputs=%t.s -unbundle
@@ -197,6 +205,10 @@
197205
// RUN: diff %t.empty %t.res.tgt1
198206
// RUN: diff %t.empty %t.res.tgt2
199207

208+
// Check that bindler prints an error if given host bundle does not exist in the fat binary.
209+
// RUN: not clang-offload-bundler -type=s -targets=host-x86_64-xxx-linux-gnu,openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.s,%t.res.tgt1 -inputs=%t.bundle3.s -unbundle 2>&1 | FileCheck %s --check-prefix CK-NO-HOST-BUNDLE
210+
// CK-NO-HOST-BUNDLE: error: Can't find bundle for the host target
211+
200212
//
201213
// Check binary bundle/unbundle. The content that we have before bundling must be the same we have after unbundling.
202214
//
@@ -208,10 +220,14 @@
208220
// RUN: diff %t.bc %t.res.bc
209221
// RUN: diff %t.tgt1 %t.res.tgt1
210222
// RUN: diff %t.tgt2 %t.res.tgt2
223+
// RUN: clang-offload-bundler -type=bc -targets=openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.tgt1 -inputs=%t.bundle3.bc -unbundle
224+
// RUN: diff %t.tgt1 %t.res.tgt1
211225
// RUN: clang-offload-bundler -type=gch -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.gch,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.gch -unbundle
212226
// RUN: diff %t.ast %t.res.gch
213227
// RUN: diff %t.tgt1 %t.res.tgt1
214228
// RUN: diff %t.tgt2 %t.res.tgt2
229+
// RUN: clang-offload-bundler -type=gch -targets=openmp-x86_64-pc-linux-gnu -outputs=%t.res.tgt2 -inputs=%t.bundle3.gch -unbundle
230+
// RUN: diff %t.tgt2 %t.res.tgt2
215231
// RUN: clang-offload-bundler -type=ast -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.ast,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bundle3.ast -unbundle
216232
// RUN: diff %t.ast %t.res.ast
217233
// RUN: diff %t.tgt1 %t.res.tgt1
@@ -224,6 +240,8 @@
224240
// RUN: diff %t.ast %t.res.ast
225241
// RUN: diff %t.tgt1 %t.res.tgt1
226242
// RUN: diff %t.tgt2 %t.res.tgt2
243+
// RUN: clang-offload-bundler -type=ast -targets=openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.tgt1 -inputs=%t.bundle3.ast -unbundle
244+
// RUN: diff %t.tgt1 %t.res.tgt1
227245

228246
// Check if we can unbundle a file with no magic strings.
229247
// RUN: clang-offload-bundler -type=bc -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.bc,%t.res.tgt1,%t.res.tgt2 -inputs=%t.bc -unbundle
@@ -235,6 +253,11 @@
235253
// RUN: diff %t.empty %t.res.tgt1
236254
// RUN: diff %t.empty %t.res.tgt2
237255

256+
// Check that we do not have to unbundle all available bundles from the fat binary.
257+
// RUN: clang-offload-bundler -type=ast -targets=host-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.ast,%t.res.tgt2 -inputs=%t.bundle3.unordered.ast -unbundle
258+
// RUN: diff %t.ast %t.res.ast
259+
// RUN: diff %t.tgt2 %t.res.tgt2
260+
238261
//
239262
// Check object bundle/unbundle. The content should be bundled into an ELF
240263
// section (we are using a PowerPC little-endian host which uses ELF). We
@@ -255,6 +278,8 @@
255278
// RUN: diff %t.2.o %t.res.o
256279
// RUN: diff %t.tgt1 %t.res.tgt1
257280
// RUN: diff %t.tgt2 %t.res.tgt2
281+
// RUN: clang-offload-bundler -type=o -targets=openmp-powerpc64le-ibm-linux-gnu -outputs=%t.res.tgt1 -inputs=%t.2.o -unbundle
282+
// RUN: diff %t.tgt1 %t.res.tgt1
258283

259284
// Check if we can unbundle a file with no magic strings.
260285
// RUN: clang-offload-bundler -type=o -targets=host-powerpc64le-ibm-linux-gnu,openmp-powerpc64le-ibm-linux-gnu,openmp-x86_64-pc-linux-gnu -outputs=%t.res.o,%t.res.tgt1,%t.res.tgt2 -inputs=%t.o -unbundle

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

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class BinaryFileHandler final : public FileHandler {
257257

258258
/// Iterator for the bundle information that is being read.
259259
StringMap<BundleInfo>::iterator CurBundleInfo;
260+
StringMap<BundleInfo>::iterator NextBundleInfo;
260261

261262
public:
262263
BinaryFileHandler() : FileHandler() {}
@@ -326,19 +327,19 @@ class BinaryFileHandler final : public FileHandler {
326327
BundlesInfo[Triple] = BundleInfo(Size, Offset);
327328
}
328329
// Set the iterator to where we will start to read.
329-
CurBundleInfo = BundlesInfo.begin();
330+
CurBundleInfo = BundlesInfo.end();
331+
NextBundleInfo = BundlesInfo.begin();
330332
}
331333

332334
StringRef ReadBundleStart(MemoryBuffer &Input) final {
333-
if (CurBundleInfo == BundlesInfo.end())
335+
if (NextBundleInfo == BundlesInfo.end())
334336
return StringRef();
335-
337+
CurBundleInfo = NextBundleInfo++;
336338
return CurBundleInfo->first();
337339
}
338340

339341
void ReadBundleEnd(MemoryBuffer &Input) final {
340342
assert(CurBundleInfo != BundlesInfo.end() && "Invalid reader info!");
341-
++CurBundleInfo;
342343
}
343344

344345
using FileHandler::ReadBundle; // to avoid hiding via the overload below
@@ -1247,15 +1248,16 @@ static bool UnbundleFiles() {
12471248
break;
12481249

12491250
auto Output = Worklist.find(CurTriple);
1250-
1251-
// Read the bundle if triple is included in targets
1252-
if (Output != Worklist.end()) {
1253-
// Check if the output file can be opened and copy the bundle to it.
1254-
FH->ReadBundle(Output->second, Input);
1255-
Worklist.erase(Output);
1251+
// The file may have more bundles for other targets, that we don't care
1252+
// about. Therefore, move on to the next triple
1253+
if (Output == Worklist.end()) {
1254+
continue;
12561255
}
1257-
1256+
1257+
// Check if the output file can be opened and copy the bundle to it.
1258+
FH->ReadBundle(Output->second, Input);
12581259
FH->ReadBundleEnd(Input);
1260+
Worklist.erase(Output);
12591261

12601262
// Record if we found the host bundle.
12611263
if (hasHostKind(CurTriple))
@@ -1282,8 +1284,9 @@ static bool UnbundleFiles() {
12821284
return false;
12831285
}
12841286

1285-
// If we found elements, we emit an error if none of those were for the host.
1286-
if (!FoundHostBundle) {
1287+
// If we found elements, we emit an error if none of those were for the host
1288+
// in case host bundle name was provided in command line.
1289+
if (!FoundHostBundle && HostInputIndex != ~0u) {
12871290
errs() << "error: Can't find bundle for the host target\n";
12881291
return true;
12891292
}
@@ -1340,8 +1343,8 @@ static bool CheckBundledSection() {
13401343

13411344
if(CurTriple == triple) {
13421345
found = true;
1346+
break;
13431347
}
1344-
FH->ReadBundleEnd(Input);
13451348
}
13461349
return found;
13471350
}
@@ -1457,7 +1460,10 @@ int main(int argc, const char **argv) {
14571460
++Index;
14581461
}
14591462

1460-
if (!CheckSection && HostTargetNum != 1) {
1463+
// Host triple is not really needed for unbundling operation, so do not
1464+
// treat missing host triple as error if we do unbundling.
1465+
if (!CheckSection &&
1466+
((Unbundle && HostTargetNum > 1) || (!Unbundle && HostTargetNum != 1))) {
14611467
Error = true;
14621468
errs() << "error: expecting exactly one host target but got "
14631469
<< HostTargetNum << ".\n";

0 commit comments

Comments
 (0)