A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/OffloadBundler_8cpp_source.html below:

clang: lib/Driver/OffloadBundler.cpp Source File

20#include "llvm/ADT/ArrayRef.h" 21#include "llvm/ADT/SmallString.h" 22#include "llvm/ADT/SmallVector.h" 23#include "llvm/ADT/StringExtras.h" 24#include "llvm/ADT/StringMap.h" 25#include "llvm/ADT/StringRef.h" 26#include "llvm/BinaryFormat/Magic.h" 27#include "llvm/Object/Archive.h" 28#include "llvm/Object/ArchiveWriter.h" 29#include "llvm/Object/Binary.h" 30#include "llvm/Object/ObjectFile.h" 31#include "llvm/Support/Casting.h" 32#include "llvm/Support/Compression.h" 33#include "llvm/Support/Debug.h" 34#include "llvm/Support/EndianStream.h" 35#include "llvm/Support/Errc.h" 36#include "llvm/Support/Error.h" 37#include "llvm/Support/ErrorOr.h" 38#include "llvm/Support/FileSystem.h" 39#include "llvm/Support/MD5.h" 40#include "llvm/Support/ManagedStatic.h" 41#include "llvm/Support/MemoryBuffer.h" 42#include "llvm/Support/Path.h" 43#include "llvm/Support/Program.h" 44#include "llvm/Support/Signals.h" 45#include "llvm/Support/StringSaver.h" 46#include "llvm/Support/Timer.h" 47#include "llvm/Support/WithColor.h" 48#include "llvm/Support/raw_ostream.h" 49#include "llvm/TargetParser/Host.h" 50#include "llvm/TargetParser/Triple.h" 55#include <forward_list> 56#include <llvm/Support/Process.h> 60#include <system_error> 64using namespace

llvm::object;

65using namespace clang

;

68struct

CreateClangOffloadBundlerTimerGroup {

70 return new

TimerGroup(

"Clang Offload Bundler Timer Group"

,

71 "Timer group for clang offload bundler"

);

75static

llvm::ManagedStatic<llvm::TimerGroup,

76

CreateClangOffloadBundlerTimerGroup>

80#define OFFLOAD_BUNDLER_MAGIC_STR "__CLANG_OFFLOAD_BUNDLE__" 87 auto

TargetFeatures =

Target

.split(

':'

);

88 auto

TripleOrGPU = TargetFeatures.first.rsplit(

'-'

);

92 auto

KindTriple = TripleOrGPU.first.split(

'-'

);

96

llvm::Triple t = llvm::Triple(KindTriple.second);

97

this->

Triple

= llvm::Triple(t.getArchName(), t.getVendorName(),

98

t.getOSName(), t.getEnvironmentName());

100

this->

TargetID

= Target.substr(

Target

.find(TripleOrGPU.second));

102 auto

KindTriple = TargetFeatures.first.split(

'-'

);

106

llvm::Triple t = llvm::Triple(KindTriple.second);

107

this->

Triple

= llvm::Triple(t.getArchName(), t.getVendorName(),

108

t.getOSName(), t.getEnvironmentName());

124 const

StringRef TargetOffloadKind)

const

{

126

(

OffloadKind

==

"hip"

&& TargetOffloadKind ==

"hipv4"

) ||

127

(

OffloadKind

==

"hipv4"

&& TargetOffloadKind ==

"hip"

))

131 bool

HIPCompatibleWithOpenMP =

OffloadKind

.starts_with_insensitive(

"hip"

) &&

132

TargetOffloadKind ==

"openmp"

;

133 bool

OpenMPCompatibleWithHIP =

135

TargetOffloadKind.starts_with_insensitive(

"hip"

);

136 return

HIPCompatibleWithOpenMP || OpenMPCompatibleWithHIP;

142 return

!

Triple

.str().empty() &&

Triple

.getArch() != Triple::UnknownArch;

155

StringRef BundleFileName) {

156 if

(

Device

.contains(

"gfx"

))

158 if

(

Device

.contains(

"sm_"

))

160 return

sys::path::extension(BundleFileName);

165

StringRef LibName = sys::path::stem(BundleFileName);

184 virtual

~FileHandler() {}

188 virtual Error

ReadHeader(MemoryBuffer &Input) = 0;

194

ReadBundleStart(MemoryBuffer &Input) = 0;

197 virtual Error

ReadBundleEnd(MemoryBuffer &Input) = 0;

200 virtual Error

ReadBundle(raw_ostream &OS, MemoryBuffer &Input) = 0;

204 virtual Error

WriteHeader(raw_ostream &OS,

205 ArrayRef

<std::unique_ptr<MemoryBuffer>> Inputs) = 0;

209 virtual Error

WriteBundleStart(raw_ostream &OS, StringRef TargetTriple) = 0;

213 virtual Error

WriteBundleEnd(raw_ostream &OS, StringRef TargetTriple) = 0;

216 virtual Error

WriteBundle(raw_ostream &OS, MemoryBuffer &Input) = 0;

219 virtual Error

finalizeOutputFile() {

return

Error::success(); }

222 virtual Error

listBundleIDs(MemoryBuffer &Input) {

223 if

(Error Err = ReadHeader(Input))

225 return

forEachBundle(Input, [&](

const

BundleInfo &Info) -> Error {

226

llvm::outs() << Info.BundleID <<

'\n'

;

227 Error

Err = listBundleIDsCallback(Input, Info);

230 return

Error::success();

235 virtual Error

getBundleIDs(MemoryBuffer &Input,

236

std::set<StringRef> &BundleIds) {

237 if

(Error Err = ReadHeader(Input))

239 return

forEachBundle(Input, [&](

const

BundleInfo &Info) -> Error {

240

BundleIds.insert(Info.BundleID);

241

Error Err = listBundleIDsCallback(Input, Info);

244 return

Error::success();

249 Error

forEachBundle(MemoryBuffer &Input,

250

std::function<

Error

(

const

BundleInfo &)>

Func

) {

253

ReadBundleStart(Input);

255 return

CurTripleOrErr.takeError();

258 if

(!*CurTripleOrErr)

261

StringRef CurTriple = **CurTripleOrErr;

262

assert(!CurTriple.empty());

264

BundleInfo Info{CurTriple};

265 if

(Error Err =

Func

(Info))

268 return

Error::success();

272 virtual Error

listBundleIDsCallback(MemoryBuffer &Input,

273 const

BundleInfo &Info) {

274 return

Error::success();

302static uint64_t

Read8byteIntegerFromBuffer(StringRef Buffer,

size_t

pos) {

303 return

llvm::support::endian::read64le(Buffer.data() + pos);

307static void

Write8byteIntegerToBuffer(raw_ostream &OS, uint64_t Val) {

308

llvm::support::endian::write(OS, Val, llvm::endianness::little);

311class

BinaryFileHandler final :

public

FileHandler {

313 struct

BinaryBundleInfo final :

public

BundleInfo {

319

BinaryBundleInfo() {}

320

BinaryBundleInfo(uint64_t Size, uint64_t Offset)

325

StringMap<BinaryBundleInfo> BundlesInfo;

328

StringMap<BinaryBundleInfo>::iterator CurBundleInfo;

329

StringMap<BinaryBundleInfo>::iterator NextBundleInfo;

332

std::string CurWriteBundleTarget;

341

~BinaryFileHandler() final {}

343 Error

ReadHeader(MemoryBuffer &Input)

final

{

344

StringRef FC = Input.getBuffer();

347

CurBundleInfo = BundlesInfo.end();

351 if

(ReadChars > FC.size())

352 return

Error::success();

355 if

(llvm::identify_magic(FC) != llvm::file_magic::offload_bundle)

356 return

Error::success();

359 if

(ReadChars + 8 > FC.size())

360 return

Error::success();

362 uint64_t

NumberOfBundles = Read8byteIntegerFromBuffer(FC, ReadChars);

366 for

(uint64_t i = 0; i < NumberOfBundles; ++i) {

369 if

(ReadChars + 8 > FC.size())

370 return

Error::success();

372 uint64_t

Offset = Read8byteIntegerFromBuffer(FC, ReadChars);

376 if

(ReadChars + 8 > FC.size())

377 return

Error::success();

379 uint64_t Size

= Read8byteIntegerFromBuffer(FC, ReadChars);

383 if

(ReadChars + 8 > FC.size())

384 return

Error::success();

386 uint64_t

TripleSize = Read8byteIntegerFromBuffer(FC, ReadChars);

390 if

(ReadChars + TripleSize > FC.size())

391 return

Error::success();

393

StringRef Triple(&FC.data()[ReadChars], TripleSize);

394

ReadChars += TripleSize;

397 if

(!Offset || Offset + Size > FC.size())

398 return

Error::success();

400

assert(!BundlesInfo.contains(Triple) &&

"Triple is duplicated??"

);

401

BundlesInfo[Triple] = BinaryBundleInfo(Size, Offset);

404

CurBundleInfo = BundlesInfo.end();

405

NextBundleInfo = BundlesInfo.begin();

406 return

Error::success();

410

ReadBundleStart(MemoryBuffer &Input)

final

{

411 if

(NextBundleInfo == BundlesInfo.end())

413

CurBundleInfo = NextBundleInfo++;

414 return

CurBundleInfo->first();

417 Error

ReadBundleEnd(MemoryBuffer &Input)

final

{

418

assert(CurBundleInfo != BundlesInfo.end() &&

"Invalid reader info!"

);

419 return

Error::success();

422 Error

ReadBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

423

assert(CurBundleInfo != BundlesInfo.end() &&

"Invalid reader info!"

);

424

StringRef FC = Input.getBuffer();

425

OS.write(FC.data() + CurBundleInfo->second.Offset,

426

CurBundleInfo->second.Size);

427 return

Error::success();

430 Error

WriteHeader(raw_ostream &OS,

431 ArrayRef

<std::unique_ptr<MemoryBuffer>> Inputs)

final

{

441

HeaderSize +=

T

.size();

447

Write8byteIntegerToBuffer(OS, BundlerConfig.

TargetNames

.size());

451

MemoryBuffer &MB = *Inputs[Idx++];

454

Write8byteIntegerToBuffer(OS, HeaderSize);

456

Write8byteIntegerToBuffer(OS, MB.getBufferSize());

457

BundlesInfo[

T

] = BinaryBundleInfo(MB.getBufferSize(), HeaderSize);

458

HeaderSize += MB.getBufferSize();

460

Write8byteIntegerToBuffer(OS,

T

.size());

464 return

Error::success();

467 Error

WriteBundleStart(raw_ostream &OS, StringRef TargetTriple)

final

{

468

CurWriteBundleTarget = TargetTriple.str();

469 return

Error::success();

472 Error

WriteBundleEnd(raw_ostream &OS, StringRef TargetTriple)

final

{

473 return

Error::success();

476 Error

WriteBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

477 auto

BI = BundlesInfo[CurWriteBundleTarget];

480 size_t

CurrentPos = OS.tell();

481 size_t

PaddingSize = BI.Offset > CurrentPos ? BI.Offset - CurrentPos : 0;

482 for

(

size_t

I = 0; I < PaddingSize; ++I)

484

assert(OS.tell() == BI.Offset);

486

OS.write(Input.getBufferStart(), Input.getBufferSize());

488 return

Error::success();

494class

TempFileHandlerRAII {

496

~TempFileHandlerRAII() {

497 for

(

const auto

&

File

: Files)

498

sys::fs::remove(

File

);

504 if

(std::error_code EC =

505

sys::fs::createTemporaryFile(

"clang-offload-bundler"

,

"tmp"

,

File

))

506 return

createFileError(

File

, EC);

507

Files.push_front(

File

);

511

raw_fd_ostream OS(

File

, EC);

513 return

createFileError(

File

, EC);

514

OS.write(Contents->data(), Contents->size());

516 return

Files.front().str();

520

std::forward_list<SmallString<128u>> Files;

527class

ObjectFileHandler final :

public

FileHandler {

530

std::unique_ptr<ObjectFile> Obj;

533

StringRef getInputFileContents()

const

{

return

Obj->getData(); }

538

IsOffloadSection(SectionRef CurSection) {

541 return

NameOrErr.takeError();

544 if

(llvm::identify_magic(*NameOrErr) != llvm::file_magic::offload_bundle)

552 unsigned

NumberOfInputs = 0;

556 unsigned

NumberOfProcessedInputs = 0;

559

section_iterator CurrentSection;

560

section_iterator NextSection;

567

ObjectFileHandler(std::unique_ptr<ObjectFile> ObjIn,

569

: Obj(

std

::move(ObjIn)), CurrentSection(Obj->section_begin()),

570

NextSection(Obj->section_begin()), BundlerConfig(BC) {}

572

~ObjectFileHandler() final {}

574 Error

ReadHeader(MemoryBuffer &Input)

final

{

return

Error::success(); }

577

ReadBundleStart(MemoryBuffer &Input)

final

{

578 while

(NextSection != Obj->section_end()) {

579

CurrentSection = NextSection;

585

IsOffloadSection(*CurrentSection);

587 return

TripleOrErr.takeError();

589 return

**TripleOrErr;

594 Error

ReadBundleEnd(MemoryBuffer &Input)

final

{

return

Error::success(); }

596 Error

ReadBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

599 return

ContentOrErr.takeError();

600

StringRef Content = *ContentOrErr;

603

std::string ModifiedContent;

604 if

(Content.size() == 1u && Content.front() == 0) {

605 auto

HostBundleOrErr = getHostBundle(

606

StringRef(Input.getBufferStart(), Input.getBufferSize()));

607 if

(!HostBundleOrErr)

608 return

HostBundleOrErr.takeError();

610

ModifiedContent = std::move(*HostBundleOrErr);

611

Content = ModifiedContent;

614

OS.write(Content.data(), Content.size());

615 return

Error::success();

618 Error

WriteHeader(raw_ostream &OS,

619 ArrayRef

<std::unique_ptr<MemoryBuffer>> Inputs)

final

{

621 "Host input index not defined."

);

624

NumberOfInputs = Inputs.size();

625 return

Error::success();

628 Error

WriteBundleStart(raw_ostream &OS, StringRef TargetTriple)

final

{

629

++NumberOfProcessedInputs;

630 return

Error::success();

633 Error

WriteBundleEnd(raw_ostream &OS, StringRef TargetTriple)

final

{

634 return

Error::success();

637 Error

finalizeOutputFile() final {

638

assert(NumberOfProcessedInputs <= NumberOfInputs &&

639 "Processing more inputs that actually exist!"

);

641 "Host input index not defined."

);

644 if

(NumberOfProcessedInputs != NumberOfInputs)

645 return

Error::success();

653 "llvm-objcopy path not specified"

);

656

TempFileHandlerRAII TempFiles;

660

BumpPtrAllocator

Alloc

;

661

StringSaver SS{

Alloc

};

664 for

(

unsigned

I = 0; I < NumberOfInputs; ++I) {

673 return

TempFileOrErr.takeError();

674

InputFile = *TempFileOrErr;

677

ObjcopyArgs.push_back(

679

BundlerConfig.

TargetNames

[I] +

"="

+ InputFile));

680

ObjcopyArgs.push_back(

682

BundlerConfig.

TargetNames

[I] +

"=readonly,exclude"

));

684

ObjcopyArgs.push_back(

"--"

);

685

ObjcopyArgs.push_back(

689 if

(Error Err = executeObjcopy(BundlerConfig.

ObjcopyPath

, ObjcopyArgs))

692 return

Error::success();

695 Error

WriteBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

696 return

Error::success();

704

errs() <<

"\""

<< Objcopy <<

"\""

;

705 for

(StringRef Arg : drop_begin(Args, 1))

706

errs() <<

" \""

<< Arg <<

"\""

;

709 if

(sys::ExecuteAndWait(Objcopy, Args))

710 return

createStringError(inconvertibleErrorCode(),

711 "'llvm-objcopy' tool failed"

);

713 return

Error::success();

717

TempFileHandlerRAII TempFiles;

719 auto

ModifiedObjPathOrErr = TempFiles.Create(std::nullopt);

720 if

(!ModifiedObjPathOrErr)

721 return

ModifiedObjPathOrErr.takeError();

722

StringRef ModifiedObjPath = *ModifiedObjPathOrErr;

724

BumpPtrAllocator

Alloc

;

725

StringSaver SS{

Alloc

};

728

ObjcopyArgs.push_back(

"--regex"

);

729

ObjcopyArgs.push_back(

"--remove-section=__CLANG_OFFLOAD_BUNDLE__.*"

);

730

ObjcopyArgs.push_back(

"--"

);

732

StringRef ObjcopyInputFileName;

739 if

(StringRef(BundlerConfig.

FilesType

).starts_with(

"a"

)) {

740 auto

InputFileOrErr =

743 return

InputFileOrErr.takeError();

744

ObjcopyInputFileName = *InputFileOrErr;

748

ObjcopyArgs.push_back(ObjcopyInputFileName);

749

ObjcopyArgs.push_back(ModifiedObjPath);

751 if

(Error Err = executeObjcopy(BundlerConfig.

ObjcopyPath

, ObjcopyArgs))

752 return

std::move(Err);

754 auto

BufOrErr = MemoryBuffer::getFile(ModifiedObjPath);

756 return

createStringError(BufOrErr.getError(),

757 "Failed to read back the modified object file"

);

759 return

BufOrErr->get()->getBuffer().str();

772class

TextFileHandler final :

public

FileHandler {

777

std::string BundleStartString;

780

std::string BundleEndString;

783 size_t

ReadChars = 0u;

786 Error

ReadHeader(MemoryBuffer &Input)

final

{

return

Error::success(); }

789

ReadBundleStart(MemoryBuffer &Input)

final

{

790

StringRef FC = Input.getBuffer();

793

ReadChars = FC.find(BundleStartString, ReadChars);

794 if

(ReadChars == FC.npos)

798 size_t

TripleStart = ReadChars = ReadChars + BundleStartString.size();

801 size_t

TripleEnd = ReadChars = FC.find(

"\n"

, ReadChars);

802 if

(TripleEnd == FC.npos)

808 return

StringRef(&FC.data()[TripleStart], TripleEnd - TripleStart);

811 Error

ReadBundleEnd(MemoryBuffer &Input)

final

{

812

StringRef FC = Input.getBuffer();

815

assert(FC[ReadChars] ==

'\n'

&&

"The bundle should end with a new line."

);

817 size_t

TripleEnd = ReadChars = FC.find(

"\n"

, ReadChars + 1);

818 if

(TripleEnd != FC.npos)

822 return

Error::success();

825 Error

ReadBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

826

StringRef FC = Input.getBuffer();

827 size_t

BundleStart = ReadChars;

830 size_t

BundleEnd = ReadChars = FC.find(BundleEndString, ReadChars);

832

StringRef Bundle(&FC.data()[BundleStart], BundleEnd - BundleStart);

835 return

Error::success();

838 Error

WriteHeader(raw_ostream &OS,

839 ArrayRef

<std::unique_ptr<MemoryBuffer>> Inputs)

final

{

840 return

Error::success();

843 Error

WriteBundleStart(raw_ostream &OS, StringRef TargetTriple)

final

{

844

OS << BundleStartString << TargetTriple <<

"\n"

;

845 return

Error::success();

848 Error

WriteBundleEnd(raw_ostream &OS, StringRef TargetTriple)

final

{

849

OS << BundleEndString << TargetTriple <<

"\n"

;

850 return

Error::success();

853 Error

WriteBundle(raw_ostream &OS, MemoryBuffer &Input)

final

{

854

OS << Input.getBuffer();

855 return

Error::success();

859

TextFileHandler(StringRef Comment) : Comment(Comment), ReadChars(0) {

866 Error

listBundleIDsCallback(MemoryBuffer &Input,

867 const

BundleInfo &Info)

final

{

872

ReadChars = Input.getBuffer().find(BundleEndString, ReadChars);

873 if

(Error Err = ReadBundleEnd(Input))

875 return

Error::success();

883static

std::unique_ptr<FileHandler>

891 if

(errorToBool(BinaryOrErr.takeError()) || !isa<ObjectFile>(*BinaryOrErr))

892 return

std::make_unique<BinaryFileHandler>(BundlerConfig);

896 return

std::make_unique<ObjectFileHandler>(

897

std::unique_ptr<ObjectFile>(cast<ObjectFile>(BinaryOrErr->release())),

905

std::string FilesType = BundlerConfig.

FilesType

;

907 if

(FilesType ==

"i"

)

908 return

std::make_unique<TextFileHandler>(

"//"

);

909 if

(FilesType ==

"ii"

)

910 return

std::make_unique<TextFileHandler>(

"//"

);

911 if

(FilesType ==

"cui"

)

912 return

std::make_unique<TextFileHandler>(

"//"

);

913 if

(FilesType ==

"hipi"

)

914 return

std::make_unique<TextFileHandler>(

"//"

);

917 if

(FilesType ==

"d"

)

918 return

std::make_unique<TextFileHandler>(

"#"

);

919 if

(FilesType ==

"ll"

)

920 return

std::make_unique<TextFileHandler>(

";"

);

921 if

(FilesType ==

"bc"

)

922 return

std::make_unique<BinaryFileHandler>(BundlerConfig);

923 if

(FilesType ==

"s"

)

924 return

std::make_unique<TextFileHandler>(

"#"

);

925 if

(FilesType ==

"o"

)

927 if

(FilesType ==

"a"

)

929 if

(FilesType ==

"gch"

)

930 return

std::make_unique<BinaryFileHandler>(BundlerConfig);

931 if

(FilesType ==

"ast"

)

932 return

std::make_unique<BinaryFileHandler>(BundlerConfig);

934 return

createStringError(errc::invalid_argument,

935 "'"

+ FilesType +

"': invalid file type specified"

);

940 if

(llvm::compression::zstd::isAvailable()) {

945

}

else if

(llvm::compression::zlib::isAvailable()) {

951 auto

IgnoreEnvVarOpt =

952

llvm::sys::Process::GetEnv(

"OFFLOAD_BUNDLER_IGNORE_ENV_VAR"

);

953 if

(IgnoreEnvVarOpt.has_value() && IgnoreEnvVarOpt.value() ==

"1"

)

955 auto

VerboseEnvVarOpt = llvm::sys::Process::GetEnv(

"OFFLOAD_BUNDLER_VERBOSE"

);

956 if

(VerboseEnvVarOpt.has_value())

957 Verbose

= VerboseEnvVarOpt.value() ==

"1"

;

958 auto

CompressEnvVarOpt =

959

llvm::sys::Process::GetEnv(

"OFFLOAD_BUNDLER_COMPRESS"

);

960 if

(CompressEnvVarOpt.has_value())

961 Compress

= CompressEnvVarOpt.value() ==

"1"

;

962 auto

CompressionLevelEnvVarOpt =

963

llvm::sys::Process::GetEnv(

"OFFLOAD_BUNDLER_COMPRESSION_LEVEL"

);

964 if

(CompressionLevelEnvVarOpt.has_value()) {

965

llvm::StringRef CompressionLevelStr = CompressionLevelEnvVarOpt.value();

967 if

(!CompressionLevelStr.getAsInteger(10, Level))

971

<<

"Warning: Invalid value for OFFLOAD_BUNDLER_COMPRESSION_LEVEL: " 972

<< CompressionLevelStr.str() <<

". Ignoring it.\n"

;

974 auto

CompressedBundleFormatVersionOpt =

975

llvm::sys::Process::GetEnv(

"COMPRESSED_BUNDLE_FORMAT_VERSION"

);

976 if

(CompressedBundleFormatVersionOpt.has_value()) {

977

llvm::StringRef VersionStr = CompressedBundleFormatVersionOpt.value();

979 if

(!VersionStr.getAsInteger(10, Version)) {

980 if

(Version >= 2 && Version <= 3)

984

<<

"Warning: Invalid value for COMPRESSED_BUNDLE_FORMAT_VERSION: " 986

<<

". Valid values are 2 or 3. Using default version " 990

<<

"Warning: Invalid value for COMPRESSED_BUNDLE_FORMAT_VERSION: " 991

<< VersionStr.str() <<

". Using default version " 998

std::string

Num

= std::to_string(

Value

);

999 int

InsertPosition =

Num

.length() - 3;

1000 while

(InsertPosition > 0) {

1001 Num

.insert(InsertPosition,

","

);

1002

InsertPosition -= 3;

1009 const

llvm::MemoryBuffer &Input,

1010

uint16_t Version,

bool

Verbose) {

1011 if

(!llvm::compression::zstd::isAvailable() &&

1012

!llvm::compression::zlib::isAvailable())

1013 return

createStringError(llvm::inconvertibleErrorCode(),

1014 "Compression not supported"

);

1015

llvm::Timer HashTimer(

"Hash Calculation Timer"

,

"Hash calculation time"

,

1018

HashTimer.startTimer();

1020

llvm::MD5::MD5Result

Result

;

1021

Hash.update(Input.getBuffer());

1023

uint64_t TruncatedHash =

Result

.low();

1025

HashTimer.stopTimer();

1029 reinterpret_cast<const

uint8_t *

>

(Input.getBuffer().data()),

1030

Input.getBuffer().size());

1031

llvm::Timer CompressTimer(

"Compression Timer"

,

"Compression time"

,

1034

CompressTimer.startTimer();

1035

llvm::compression::compress(

P

, BufferUint8, CompressedBuffer);

1037

CompressTimer.stopTimer();

1039

uint16_t CompressionMethod =

static_cast<

uint16_t

>

(

P

.format);

1042

uint64_t UncompressedSize64 = Input.getBuffer().size();

1043

uint64_t TotalFileSize64;

1048 if

(UncompressedSize64 > std::numeric_limits<uint32_t>::max())

1049 return

createStringError(llvm::inconvertibleErrorCode(),

1050 "Uncompressed size exceeds version 2 limit"

);

1051 if

((MagicNumber.size() +

sizeof

(uint32_t) +

sizeof

(Version) +

1052 sizeof

(CompressionMethod) +

sizeof

(uint32_t) +

sizeof

(TruncatedHash) +

1053

CompressedBuffer.size()) > std::numeric_limits<uint32_t>::max())

1054 return

createStringError(llvm::inconvertibleErrorCode(),

1055 "Total file size exceeds version 2 limit"

);

1057

TotalFileSize64 = MagicNumber.size() +

sizeof

(uint32_t) +

sizeof

(Version) +

1058 sizeof

(CompressionMethod) +

sizeof

(uint32_t) +

1059 sizeof

(TruncatedHash) + CompressedBuffer.size();

1061

TotalFileSize64 = MagicNumber.size() +

sizeof

(uint64_t) +

sizeof

(Version) +

1062 sizeof

(CompressionMethod) +

sizeof

(uint64_t) +

1063 sizeof

(TruncatedHash) + CompressedBuffer.size();

1067

llvm::raw_svector_ostream OS(FinalBuffer);

1069

OS.write(

reinterpret_cast<const char

*

>

(&Version),

sizeof

(Version));

1070

OS.write(

reinterpret_cast<const char

*

>

(&CompressionMethod),

1071 sizeof

(CompressionMethod));

1075

uint32_t TotalFileSize32 =

static_cast<

uint32_t

>

(TotalFileSize64);

1076

uint32_t UncompressedSize32 =

static_cast<

uint32_t

>

(UncompressedSize64);

1077

OS.write(

reinterpret_cast<const char

*

>

(&TotalFileSize32),

1078 sizeof

(TotalFileSize32));

1079

OS.write(

reinterpret_cast<const char

*

>

(&UncompressedSize32),

1080 sizeof

(UncompressedSize32));

1082

OS.write(

reinterpret_cast<const char

*

>

(&TotalFileSize64),

1083 sizeof

(TotalFileSize64));

1084

OS.write(

reinterpret_cast<const char

*

>

(&UncompressedSize64),

1085 sizeof

(UncompressedSize64));

1088

OS.write(

reinterpret_cast<const char

*

>

(&TruncatedHash),

1089 sizeof

(TruncatedHash));

1090

OS.write(

reinterpret_cast<const char

*

>

(CompressedBuffer.data()),

1091

CompressedBuffer.size());

1095 P

.format == llvm::compression::Format::Zstd ?

"zstd"

:

"zlib"

;

1096 double

CompressionRate =

1097 static_cast<double>

(UncompressedSize64) / CompressedBuffer.size();

1098 double

CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime();

1099 double

CompressionSpeedMBs =

1100

(UncompressedSize64 / (1024.0 * 1024.0)) / CompressionTimeSeconds;

1101

llvm::errs() <<

"Compressed bundle format version: "

<< Version <<

"\n" 1102

<<

"Total file size (including headers): " 1104

<<

"Compression method used: "

<< MethodUsed <<

"\n" 1105

<<

"Compression level: "

<<

P

.level <<

"\n" 1106

<<

"Binary size before compression: " 1108

<<

"Binary size after compression: " 1110

<<

"Compression rate: " 1111

<< llvm::format(

"%.2lf"

, CompressionRate) <<

"\n" 1112

<<

"Compression ratio: " 1113

<< llvm::format(

"%.2lf%%"

, 100.0 / CompressionRate) <<

"\n" 1114

<<

"Compression speed: " 1115

<< llvm::format(

"%.2lf MB/s"

, CompressionSpeedMBs) <<

"\n" 1116

<<

"Truncated MD5 hash: " 1117

<< llvm::format_hex(TruncatedHash, 16) <<

"\n"

;

1120 return

llvm::MemoryBuffer::getMemBufferCopy(

1121

llvm::StringRef(FinalBuffer.data(), FinalBuffer.size()));

1127

StringRef Blob = Input.getBuffer();

1130 if

(Blob.size() < V1HeaderSize)

1131 return

llvm::MemoryBuffer::getMemBufferCopy(Blob);

1133 if

(llvm::identify_magic(Blob) !=

1134

llvm::file_magic::offload_bundle_compressed) {

1136

llvm::errs() <<

"Uncompressed bundle.\n"

;

1137 return

llvm::MemoryBuffer::getMemBufferCopy(Blob);

1140 size_t

CurrentOffset = MagicSize;

1143

uint16_t ThisVersion;

1144 memcpy

(&ThisVersion, Blob.data() + CurrentOffset,

sizeof

(uint16_t));

1145

CurrentOffset += VersionFieldSize;

1148 if

(ThisVersion >= 2 && ThisVersion <= 3) {

1149 size_t

RequiredSize = (ThisVersion == 2) ? V2HeaderSize : V3HeaderSize;

1150 if

(Blob.size() < RequiredSize)

1151 return

createStringError(inconvertibleErrorCode(),

1152 "Compressed bundle header size too small"

);

1156

uint16_t CompressionMethod;

1157 memcpy

(&CompressionMethod, Blob.data() + CurrentOffset,

sizeof

(uint16_t));

1158

CurrentOffset += MethodFieldSize;

1161

uint64_t TotalFileSize = 0;

1162 if

(ThisVersion >= 2) {

1163 if

(ThisVersion == 2) {

1164

uint32_t TotalFileSize32;

1165 memcpy

(&TotalFileSize32, Blob.data() + CurrentOffset,

sizeof

(uint32_t));

1166

TotalFileSize = TotalFileSize32;

1167

CurrentOffset += FileSizeFieldSizeV2;

1169 memcpy

(&TotalFileSize, Blob.data() + CurrentOffset,

sizeof

(uint64_t));

1170

CurrentOffset += FileSizeFieldSizeV3;

1175

uint64_t UncompressedSize = 0;

1176 if

(ThisVersion <= 2) {

1177

uint32_t UncompressedSize32;

1178 memcpy

(&UncompressedSize32, Blob.data() + CurrentOffset,

sizeof

(uint32_t));

1179

UncompressedSize = UncompressedSize32;

1180

CurrentOffset += UncompressedSizeFieldSizeV2;

1182 memcpy

(&UncompressedSize, Blob.data() + CurrentOffset,

sizeof

(uint64_t));

1183

CurrentOffset += UncompressedSizeFieldSizeV3;

1187

uint64_t StoredHash;

1188 memcpy

(&StoredHash, Blob.data() + CurrentOffset,

sizeof

(uint64_t));

1189

CurrentOffset += HashFieldSize;

1192

llvm::compression::Format CompressionFormat;

1193 if

(CompressionMethod ==

1194 static_cast<

uint16_t

>

(llvm::compression::Format::Zlib))

1195

CompressionFormat = llvm::compression::Format::Zlib;

1196 else if

(CompressionMethod ==

1197 static_cast<

uint16_t

>

(llvm::compression::Format::Zstd))

1198

CompressionFormat = llvm::compression::Format::Zstd;

1200 return

createStringError(inconvertibleErrorCode(),

1201 "Unknown compressing method"

);

1203

llvm::Timer DecompressTimer(

"Decompression Timer"

,

"Decompression time"

,

1206

DecompressTimer.startTimer();

1209

StringRef CompressedData = Blob.substr(CurrentOffset);

1210 if

(llvm::Error DecompressionError = llvm::compression::decompress(

1211

CompressionFormat, llvm::arrayRefFromStringRef(CompressedData),

1212

DecompressedData, UncompressedSize))

1213 return

createStringError(inconvertibleErrorCode(),

1214 "Could not decompress embedded file contents: "

+

1215

llvm::toString(std::move(DecompressionError)));

1218

DecompressTimer.stopTimer();

1220 double

DecompressionTimeSeconds =

1221

DecompressTimer.getTotalTime().getWallTime();

1224

llvm::Timer HashRecalcTimer(

"Hash Recalculation Timer"

,

1225 "Hash recalculation time"

,

1227

HashRecalcTimer.startTimer();

1229

llvm::MD5::MD5Result

Result

;

1231

DecompressedData.size()));

1233

uint64_t RecalculatedHash =

Result

.low();

1234

HashRecalcTimer.stopTimer();

1235 bool

HashMatch = (StoredHash == RecalculatedHash);

1237 double

CompressionRate =

1238 static_cast<double>

(UncompressedSize) / CompressedData.size();

1239 double

DecompressionSpeedMBs =

1240

(UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds;

1242

llvm::errs() <<

"Compressed bundle format version: "

<< ThisVersion <<

"\n"

;

1243 if

(ThisVersion >= 2)

1244

llvm::errs() <<

"Total file size (from header): " 1246

llvm::errs() <<

"Decompression method: " 1247

<< (CompressionFormat == llvm::compression::Format::Zlib

1251

<<

"Size before decompression: " 1253

<<

"Size after decompression: " 1255

<<

"Compression rate: " 1256

<< llvm::format(

"%.2lf"

, CompressionRate) <<

"\n" 1257

<<

"Compression ratio: " 1258

<< llvm::format(

"%.2lf%%"

, 100.0 / CompressionRate) <<

"\n" 1259

<<

"Decompression speed: " 1260

<< llvm::format(

"%.2lf MB/s"

, DecompressionSpeedMBs) <<

"\n" 1261

<<

"Stored hash: "

<< llvm::format_hex(StoredHash, 16) <<

"\n" 1262

<<

"Recalculated hash: " 1263

<< llvm::format_hex(RecalculatedHash, 16) <<

"\n" 1264

<<

"Hashes match: "

<< (HashMatch ?

"Yes"

:

"No"

) <<

"\n"

;

1267 return

llvm::MemoryBuffer::getMemBufferCopy(

1268

llvm::toStringRef(DecompressedData));

1275

ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =

1276

MemoryBuffer::getFileOrSTDIN(InputFileName,

true

);

1277 if

(std::error_code EC = CodeOrErr.getError())

1278 return

createFileError(InputFileName, EC);

1283 if

(!DecompressedBufferOrErr)

1284 return

createStringError(

1285

inconvertibleErrorCode(),

1286 "Failed to decompress input: "

+

1287

llvm::toString(DecompressedBufferOrErr.takeError()));

1289

MemoryBuffer &DecompressedInput = **DecompressedBufferOrErr;

1294 if

(!FileHandlerOrErr)

1295 return

FileHandlerOrErr.takeError();

1297

std::unique_ptr<FileHandler> &FH = *FileHandlerOrErr;

1299 return

FH->listBundleIDs(DecompressedInput);

1310

DEBUG_WITH_TYPE(

"CodeObjectCompatibility"

,

1311

dbgs() <<

"Compatible: Exact match: \t[CodeObject: " 1312

<< CodeObjectInfo.

str

()

1313

<<

"]\t:\t[Target: "

<<

TargetInfo

.str() <<

"]\n"

);

1321 "CodeObjectCompatibility"

,

1322

dbgs() <<

"Incompatible: Kind/Triple mismatch \t[CodeObject: " 1323

<< CodeObjectInfo.

str

() <<

"]\t:\t[Target: "

<<

TargetInfo

.str()

1329

llvm::StringMap<bool> CodeObjectFeatureMap, TargetFeatureMap;

1331

CodeObjectInfo.

Triple

, CodeObjectInfo.

TargetID

, &CodeObjectFeatureMap);

1336 if

(!TargetProc || !CodeObjectProc ||

1337

CodeObjectProc.value() != TargetProc.value()) {

1338

DEBUG_WITH_TYPE(

"CodeObjectCompatibility"

,

1339

dbgs() <<

"Incompatible: Processor mismatch \t[CodeObject: " 1340

<< CodeObjectInfo.

str

()

1341

<<

"]\t:\t[Target: "

<<

TargetInfo

.str() <<

"]\n"

);

1347 if

(CodeObjectFeatureMap.getNumItems() > TargetFeatureMap.getNumItems()) {

1348

DEBUG_WITH_TYPE(

"CodeObjectCompatibility"

,

1349

dbgs() <<

"Incompatible: CodeObject has more features " 1350 "than target \t[CodeObject: " 1351

<< CodeObjectInfo.

str

()

1352

<<

"]\t:\t[Target: "

<<

TargetInfo

.str() <<

"]\n"

);

1360 for

(

const auto

&CodeObjectFeature : CodeObjectFeatureMap) {

1361 auto

TargetFeature = TargetFeatureMap.find(CodeObjectFeature.getKey());

1362 if

(TargetFeature == TargetFeatureMap.end()) {

1364 "CodeObjectCompatibility"

,

1366

<<

"Incompatible: Value of CodeObject's non-ANY feature is " 1367 "not matching with Target feature's ANY value \t[CodeObject: " 1368

<< CodeObjectInfo.

str

() <<

"]\t:\t[Target: "

<<

TargetInfo

.str()

1371

}

else if

(TargetFeature->getValue() != CodeObjectFeature.getValue()) {

1373 "CodeObjectCompatibility"

,

1374

dbgs() <<

"Incompatible: Value of CodeObject's non-ANY feature is " 1375 "not matching with Target feature's non-ANY value " 1377

<< CodeObjectInfo.

str

()

1378

<<

"]\t:\t[Target: "

<<

TargetInfo

.str() <<

"]\n"

);

1388 "CodeObjectCompatibility"

,

1389

dbgs() <<

"Compatible: Target IDs are compatible \t[CodeObject: " 1390

<< CodeObjectInfo.

str

() <<

"]\t:\t[Target: "

<<

TargetInfo

.str()

1401

llvm::raw_svector_ostream BufferStream(Buffer);

1407

ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =

1408

MemoryBuffer::getFileOrSTDIN(I,

true

);

1409 if

(std::error_code EC = CodeOrErr.getError())

1410 return

createFileError(I, EC);

1411

InputBuffers.emplace_back(std::move(*CodeOrErr));

1416 "Host input index undefined??"

);

1421 if

(!FileHandlerOrErr)

1422 return

FileHandlerOrErr.takeError();

1424

std::unique_ptr<FileHandler> &FH = *FileHandlerOrErr;

1428 if

(Error Err = FH->WriteHeader(BufferStream, InputBuffers))

1433 auto

Input = InputBuffers.begin();

1435 if

(Error Err = FH->WriteBundleStart(BufferStream, Triple))

1437 if

(Error Err = FH->WriteBundle(BufferStream, **Input))

1439 if

(Error Err = FH->WriteBundleEnd(BufferStream, Triple))

1451

std::unique_ptr<llvm::MemoryBuffer> BufferMemory =

1452

llvm::MemoryBuffer::getMemBufferCopy(

1453

llvm::StringRef(Buffer.data(), Buffer.size()));

1459 if

(

auto

Error = CompressionResult.takeError())

1462 auto

CompressedMemBuffer = std::move(CompressionResult.get());

1463

CompressedBuffer.assign(CompressedMemBuffer->getBufferStart(),

1464

CompressedMemBuffer->getBufferEnd());

1466

CompressedBuffer = Buffer;

1468

OutputFile.write(CompressedBuffer.data(), CompressedBuffer.size());

1470 return

FH->finalizeOutputFile();

1476

ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =

1479 if

(std::error_code EC = CodeOrErr.getError())

1485 if

(!DecompressedBufferOrErr)

1486 return

createStringError(

1487

inconvertibleErrorCode(),

1488 "Failed to decompress input: "

+

1489

llvm::toString(DecompressedBufferOrErr.takeError()));

1491

MemoryBuffer &Input = **DecompressedBufferOrErr;

1496 if

(!FileHandlerOrErr)

1497 return

FileHandlerOrErr.takeError();

1499

std::unique_ptr<FileHandler> &FH = *FileHandlerOrErr;

1503 if

(Error Err = FH->ReadHeader(Input))

1507

StringMap<StringRef> Worklist;

1510

Worklist[Triple] = *Output;

1516 bool

FoundHostBundle =

false

;

1517 while

(!Worklist.empty()) {

1519

FH->ReadBundleStart(Input);

1520 if

(!CurTripleOrErr)

1521 return

CurTripleOrErr.takeError();

1524 if

(!*CurTripleOrErr)

1527

StringRef CurTriple = **CurTripleOrErr;

1528

assert(!CurTriple.empty());

1530 auto

Output = Worklist.begin();

1531 for

(

auto E

= Worklist.end(); Output !=

E

; Output++) {

1539 if

(Output == Worklist.end())

1543

raw_fd_ostream OutputFile((*Output).second, EC, sys::fs::OF_None);

1545 return

createFileError((*Output).second, EC);

1546 if

(Error Err = FH->ReadBundle(OutputFile, Input))

1548 if

(Error Err = FH->ReadBundleEnd(Input))

1550

Worklist.erase(Output);

1554 if

(OffloadInfo.hasHostKind())

1555

FoundHostBundle =

true

;

1559

std::string ErrMsg =

"Can't find bundles for"

;

1560

std::set<StringRef> Sorted;

1561 for

(

auto

&

E

: Worklist)

1562

Sorted.insert(

E

.first());

1564 unsigned Last

= Sorted.size() - 1;

1565 for

(

auto

&

E

: Sorted) {

1566 if

(I != 0 &&

Last

> 1)

1569 if

(I ==

Last

&& I != 0)

1574 return

createStringError(inconvertibleErrorCode(), ErrMsg);

1580 for

(

auto

&

E

: Worklist) {

1582

raw_fd_ostream OutputFile(

E

.second, EC, sys::fs::OF_None);

1584 return

createFileError(

E

.second, EC);

1588 if

(OffloadInfo.hasHostKind())

1589

OutputFile.write(Input.getBufferStart(), Input.getBufferSize());

1591 return

Error::success();

1598 return

createStringError(inconvertibleErrorCode(),

1599 "Can't find bundle for the host target"

);

1602 for

(

auto

&

E

: Worklist) {

1604

raw_fd_ostream OutputFile(

E

.second, EC, sys::fs::OF_None);

1606 return

createFileError(

E

.second, EC);

1609 return

Error::success();

1613 return

Triple(sys::getDefaultTargetTriple()).isOSDarwin() ? Archive::K_DARWIN

1627 if

(!CompatibleTargets.empty()) {

1628

DEBUG_WITH_TYPE(

"CodeObjectCompatibility"

,

1629

dbgs() <<

"CompatibleTargets list should be empty\n"

);

1635

CompatibleTargets.push_back(

Target

);

1637 return

!CompatibleTargets.empty();

1647

std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;

1648

ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =

1649

MemoryBuffer::getFileOrSTDIN(ArchiveName,

true

,

false

);

1650 if

(std::error_code EC = BufOrErr.getError())

1651 return

createFileError(ArchiveName, EC);

1653

ArchiveBuffers.push_back(std::move(*BufOrErr));

1655

Archive::create(ArchiveBuffers.back()->getMemBufferRef());

1657 return

LibOrErr.takeError();

1659 auto

Archive = std::move(*LibOrErr);

1661

Error ArchiveErr = Error::success();

1662 auto

ChildEnd = Archive->child_end();

1665 for

(

auto

ArchiveIter = Archive->child_begin(ArchiveErr);

1666

ArchiveIter != ChildEnd; ++ArchiveIter) {

1669 auto

ArchiveChildNameOrErr = (*ArchiveIter).getName();

1670 if

(!ArchiveChildNameOrErr)

1671 return

ArchiveChildNameOrErr.takeError();

1673 auto

CodeObjectBufferRefOrErr = (*ArchiveIter).getMemoryBufferRef();

1674 if

(!CodeObjectBufferRefOrErr)

1675 return

CodeObjectBufferRefOrErr.takeError();

1677 auto

CodeObjectBuffer =

1678

MemoryBuffer::getMemBuffer(*CodeObjectBufferRefOrErr,

false

);

1682 if

(!FileHandlerOrErr)

1683 return

FileHandlerOrErr.takeError();

1685

std::unique_ptr<FileHandler> &FileHandler = *FileHandlerOrErr;

1686

assert(FileHandler);

1688

std::set<StringRef> BundleIds;

1689 auto

CodeObjectFileError =

1690

FileHandler->getBundleIDs(*CodeObjectBuffer, BundleIds);

1691 if

(CodeObjectFileError)

1692 return

CodeObjectFileError;

1695 if

(ConflictingArchs) {

1696

std::string ErrMsg =

1697

Twine(

"conflicting TargetIDs ["

+ ConflictingArchs.value().first +

1698 ", "

+ ConflictingArchs.value().second +

"] found in "

+

1699

ArchiveChildNameOrErr.get() +

" of "

+ ArchiveName)

1701 return

createStringError(inconvertibleErrorCode(), ErrMsg);

1716

std::vector<std::unique_ptr<MemoryBuffer>> ArchiveBuffers;

1720

StringMap<std::vector<NewArchiveMember>> OutputArchivesMap;

1723

StringMap<StringRef> TargetOutputFileNameMap;

1727

TargetOutputFileNameMap[

Target

] = *Output;

1739 return

ArchiveError;

1743

ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =

1744

MemoryBuffer::getFileOrSTDIN(IFName,

true

,

false

);

1745 if

(std::error_code EC = BufOrErr.getError())

1748

ArchiveBuffers.push_back(std::move(*BufOrErr));

1750

Archive::create(ArchiveBuffers.back()->getMemBufferRef());

1752 return

LibOrErr.takeError();

1754 auto

Archive = std::move(*LibOrErr);

1756

Error ArchiveErr = Error::success();

1757 auto

ChildEnd = Archive->child_end();

1760 for

(

auto

ArchiveIter = Archive->child_begin(ArchiveErr);

1761

ArchiveIter != ChildEnd; ++ArchiveIter) {

1764 auto

ArchiveChildNameOrErr = (*ArchiveIter).getName();

1765 if

(!ArchiveChildNameOrErr)

1766 return

ArchiveChildNameOrErr.takeError();

1768

StringRef BundledObjectFile = sys::path::filename(*ArchiveChildNameOrErr);

1770 auto

CodeObjectBufferRefOrErr = (*ArchiveIter).getMemoryBufferRef();

1771 if

(!CodeObjectBufferRefOrErr)

1772 return

CodeObjectBufferRefOrErr.takeError();

1774 auto

TempCodeObjectBuffer =

1775

MemoryBuffer::getMemBuffer(*CodeObjectBufferRefOrErr,

false

);

1781 if

(!DecompressedBufferOrErr)

1782 return

createStringError(

1783

inconvertibleErrorCode(),

1784 "Failed to decompress code object: "

+

1785

llvm::toString(DecompressedBufferOrErr.takeError()));

1787

MemoryBuffer &CodeObjectBuffer = **DecompressedBufferOrErr;

1791 if

(!FileHandlerOrErr)

1792 return

FileHandlerOrErr.takeError();

1794

std::unique_ptr<FileHandler> &FileHandler = *FileHandlerOrErr;

1795

assert(FileHandler &&

1796 "FileHandle creation failed for file in the archive!"

);

1798 if

(Error ReadErr = FileHandler->ReadHeader(CodeObjectBuffer))

1802

FileHandler->ReadBundleStart(CodeObjectBuffer);

1803 if

(!CurBundleIDOrErr)

1804 return

CurBundleIDOrErr.takeError();

1806

std::optional<StringRef> OptionalCurBundleID = *CurBundleIDOrErr;

1808 if

(!OptionalCurBundleID)

1810

StringRef CodeObject = *OptionalCurBundleID;

1814 while

(!CodeObject.empty()) {

1819

std::string BundleData;

1820

raw_string_ostream DataStream(BundleData);

1821 if

(Error Err = FileHandler->ReadBundle(DataStream, CodeObjectBuffer))

1824 for

(

auto

&CompatibleTarget : CompatibleTargets) {

1826

BundledObjectFileName.assign(BundledObjectFile);

1827 auto

OutputBundleName =

1828

Twine(llvm::sys::path::stem(BundledObjectFileName) +

"-"

+

1831

CodeObjectInfo.TargetID))

1835

std::replace(OutputBundleName.begin(), OutputBundleName.end(),

':'

,

1838

std::unique_ptr<MemoryBuffer> MemBuf = MemoryBuffer::getMemBufferCopy(

1839

DataStream.str(), OutputBundleName);

1840

ArchiveBuffers.push_back(std::move(MemBuf));

1841

llvm::MemoryBufferRef MemBufRef =

1842

MemoryBufferRef(*(ArchiveBuffers.back()));

1846

OutputArchivesMap[CompatibleTarget].push_back(

1847

NewArchiveMember(MemBufRef));

1851 if

(Error Err = FileHandler->ReadBundleEnd(CodeObjectBuffer))

1855

FileHandler->ReadBundleStart(CodeObjectBuffer);

1856 if

(!NextTripleOrErr)

1857 return

NextTripleOrErr.takeError();

1859

CodeObject = ((*NextTripleOrErr).has_value()) ? **NextTripleOrErr :

""

;

1863

assert(!ArchiveErr &&

"Error occurred while reading archive!"

);

1868

StringMapIterator<std::vector<llvm::NewArchiveMember>> CurArchiveMembers =

1869

OutputArchivesMap.find(

Target

);

1870 if

(CurArchiveMembers != OutputArchivesMap.end()) {

1871 if

(Error WriteErr = writeArchive(

FileName

, CurArchiveMembers->getValue(),

1872

SymtabWritingMode::NormalSymtab,

1877

std::string ErrMsg =

1878

Twine(

"no compatible code object found for the target '"

+

Target

+

1879 "' in heterogeneous archive library: "

+ IFName)

1881 return

createStringError(inconvertibleErrorCode(), ErrMsg);

1886

std::vector<llvm::NewArchiveMember> EmptyArchive;

1887

EmptyArchive.clear();

1888 if

(Error WriteErr = writeArchive(

1889 FileName

, EmptyArchive, SymtabWritingMode::NormalSymtab,

1895 return

Error::success();

llvm::MachO::Target Target

static std::string getDeviceLibraryFileName(StringRef BundleFileName, StringRef Device)

static llvm::ManagedStatic< llvm::TimerGroup, CreateClangOffloadBundlerTimerGroup > ClangOffloadBundlerTimerGroup

static StringRef getDeviceFileExtension(StringRef Device, StringRef BundleFileName)

static Expected< std::unique_ptr< FileHandler > > CreateFileHandler(MemoryBuffer &FirstInput, const OffloadBundlerConfig &BundlerConfig)

Return an appropriate handler given the input files and options.

#define OFFLOAD_BUNDLER_MAGIC_STR

Magic string that marks the existence of offloading data.

bool isCodeObjectCompatible(const OffloadTargetInfo &CodeObjectInfo, const OffloadTargetInfo &TargetInfo)

Checks if a code object CodeObjectInfo is compatible with a given target TargetInfo.

static Error CheckHeterogeneousArchive(StringRef ArchiveName, const OffloadBundlerConfig &BundlerConfig)

static std::unique_ptr< FileHandler > CreateObjectFileHandler(MemoryBuffer &FirstInput, const OffloadBundlerConfig &BundlerConfig)

Return an appropriate object file handler.

static Archive::Kind getDefaultArchiveKindForHost()

static std::string formatWithCommas(unsigned long long Value)

static bool getCompatibleOffloadTargets(OffloadTargetInfo &CodeObjectInfo, SmallVectorImpl< StringRef > &CompatibleTargets, const OffloadBundlerConfig &BundlerConfig)

Computes a list of targets among all given targets which are compatible with this code object.

This file defines an offload bundling API that bundles different files that relate with the same sour...

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

static llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > decompress(const llvm::MemoryBuffer &Input, bool Verbose=false)

static llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input, uint16_t Version, bool Verbose=false)

llvm::compression::Format CompressionFormat

std::vector< std::string > OutputFileNames

std::vector< std::string > TargetNames

uint16_t CompressedBundleVersion

std::vector< std::string > InputFileNames

bool PrintExternalCommands

llvm::Error BundleFiles()

Bundle the files. Return true if an error was found.

llvm::Error UnbundleFiles()

llvm::Error UnbundleArchive()

UnbundleArchive takes an archive file (".a") as input containing bundled code object files,...

static llvm::Error ListBundleIDsInFile(llvm::StringRef InputFileName, const OffloadBundlerConfig &BundlerConfig)

const OffloadBundlerConfig & BundlerConfig

Exposes information about the current target.

bool Alloc(InterpState &S, CodePtr OpPC, const Descriptor *Desc)

The JSON file list parser is used to communicate input to InstallAPI.

std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)

Parse a target ID to get processor and feature map.

@ Create

'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...

std::optional< std::pair< llvm::StringRef, llvm::StringRef > > getConflictTargetIDCombination(const std::set< llvm::StringRef > &TargetIDs)

Get the conflicted pair of target IDs for a compilation or a bundled code object, assuming TargetIDs ...

@ Result

The result type of a method or function.

OffloadArch StringToOffloadArch(llvm::StringRef S)

const FunctionProtoType * T

Diagnostic wrappers for TextAPI types for error reporting.

Obtain the offload kind, real machine triple, and an optional TargetID out of the target information ...

bool operator==(const OffloadTargetInfo &Target) const

bool isOffloadKindCompatible(const llvm::StringRef TargetOffloadKind) const

bool isTripleValid() const

OffloadTargetInfo(const llvm::StringRef Target, const OffloadBundlerConfig &BC)

llvm::StringRef OffloadKind

bool isOffloadKindValid() const

const OffloadBundlerConfig & BundlerConfig


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4