1bdd1243dSDimitry Andric //===- OffloadBundler.h - File Bundling and Unbundling ----------*- C++ -*-===// 2bdd1243dSDimitry Andric // 3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bdd1243dSDimitry Andric // 7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8bdd1243dSDimitry Andric /// 9bdd1243dSDimitry Andric /// \file 10bdd1243dSDimitry Andric /// This file defines an offload bundling API that bundles different files 11bdd1243dSDimitry Andric /// that relate with the same source code but different targets into a single 12bdd1243dSDimitry Andric /// one. Also the implements the opposite functionality, i.e. unbundle files 13bdd1243dSDimitry Andric /// previous created by this API. 14bdd1243dSDimitry Andric /// 15bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 16bdd1243dSDimitry Andric 17bdd1243dSDimitry Andric #ifndef LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 18bdd1243dSDimitry Andric #define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 19bdd1243dSDimitry Andric 20*0fca6ea1SDimitry Andric #include "llvm/Support/Compression.h" 21bdd1243dSDimitry Andric #include "llvm/Support/Error.h" 2206c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 235f757f3fSDimitry Andric #include <llvm/Support/MemoryBuffer.h> 24bdd1243dSDimitry Andric #include <string> 25bdd1243dSDimitry Andric #include <vector> 26bdd1243dSDimitry Andric 27bdd1243dSDimitry Andric namespace clang { 28bdd1243dSDimitry Andric 29bdd1243dSDimitry Andric class OffloadBundlerConfig { 30bdd1243dSDimitry Andric public: 315f757f3fSDimitry Andric OffloadBundlerConfig(); 325f757f3fSDimitry Andric 33bdd1243dSDimitry Andric bool AllowNoHost = false; 34bdd1243dSDimitry Andric bool AllowMissingBundles = false; 35bdd1243dSDimitry Andric bool CheckInputArchive = false; 36bdd1243dSDimitry Andric bool PrintExternalCommands = false; 37bdd1243dSDimitry Andric bool HipOpenmpCompatible = false; 385f757f3fSDimitry Andric bool Compress = false; 395f757f3fSDimitry Andric bool Verbose = false; 40*0fca6ea1SDimitry Andric llvm::compression::Format CompressionFormat; 41*0fca6ea1SDimitry Andric int CompressionLevel; 42bdd1243dSDimitry Andric 43bdd1243dSDimitry Andric unsigned BundleAlignment = 1; 44bdd1243dSDimitry Andric unsigned HostInputIndex = ~0u; 45bdd1243dSDimitry Andric 46bdd1243dSDimitry Andric std::string FilesType; 47bdd1243dSDimitry Andric std::string ObjcopyPath; 48bdd1243dSDimitry Andric 49bdd1243dSDimitry Andric // TODO: Convert these to llvm::SmallVector 50bdd1243dSDimitry Andric std::vector<std::string> TargetNames; 51bdd1243dSDimitry Andric std::vector<std::string> InputFileNames; 52bdd1243dSDimitry Andric std::vector<std::string> OutputFileNames; 53bdd1243dSDimitry Andric }; 54bdd1243dSDimitry Andric 55bdd1243dSDimitry Andric class OffloadBundler { 56bdd1243dSDimitry Andric public: 57bdd1243dSDimitry Andric const OffloadBundlerConfig &BundlerConfig; 58bdd1243dSDimitry Andric 59bdd1243dSDimitry Andric // TODO: Add error checking from ClangOffloadBundler.cpp 60bdd1243dSDimitry Andric OffloadBundler(const OffloadBundlerConfig &BC) : BundlerConfig(BC) {} 61bdd1243dSDimitry Andric 62bdd1243dSDimitry Andric // List bundle IDs. Return true if an error was found. 63bdd1243dSDimitry Andric static llvm::Error 64bdd1243dSDimitry Andric ListBundleIDsInFile(llvm::StringRef InputFileName, 65bdd1243dSDimitry Andric const OffloadBundlerConfig &BundlerConfig); 66bdd1243dSDimitry Andric 67bdd1243dSDimitry Andric llvm::Error BundleFiles(); 68bdd1243dSDimitry Andric llvm::Error UnbundleFiles(); 69bdd1243dSDimitry Andric llvm::Error UnbundleArchive(); 70bdd1243dSDimitry Andric }; 71bdd1243dSDimitry Andric 725f757f3fSDimitry Andric /// Obtain the offload kind, real machine triple, and an optional TargetID 73bdd1243dSDimitry Andric /// out of the target information specified by the user. 74bdd1243dSDimitry Andric /// Bundle Entry ID (or, Offload Target String) has following components: 75bdd1243dSDimitry Andric /// * Offload Kind - Host, OpenMP, or HIP 76bdd1243dSDimitry Andric /// * Triple - Standard LLVM Triple 77bdd1243dSDimitry Andric /// * TargetID (Optional) - target ID, like gfx906:xnack+ or sm_30 78bdd1243dSDimitry Andric struct OffloadTargetInfo { 79bdd1243dSDimitry Andric llvm::StringRef OffloadKind; 80bdd1243dSDimitry Andric llvm::Triple Triple; 81bdd1243dSDimitry Andric llvm::StringRef TargetID; 82bdd1243dSDimitry Andric 83bdd1243dSDimitry Andric const OffloadBundlerConfig &BundlerConfig; 84bdd1243dSDimitry Andric 85bdd1243dSDimitry Andric OffloadTargetInfo(const llvm::StringRef Target, 86bdd1243dSDimitry Andric const OffloadBundlerConfig &BC); 87bdd1243dSDimitry Andric bool hasHostKind() const; 88bdd1243dSDimitry Andric bool isOffloadKindValid() const; 89bdd1243dSDimitry Andric bool isOffloadKindCompatible(const llvm::StringRef TargetOffloadKind) const; 90bdd1243dSDimitry Andric bool isTripleValid() const; 91bdd1243dSDimitry Andric bool operator==(const OffloadTargetInfo &Target) const; 92bdd1243dSDimitry Andric std::string str() const; 93bdd1243dSDimitry Andric }; 94bdd1243dSDimitry Andric 955f757f3fSDimitry Andric // CompressedOffloadBundle represents the format for the compressed offload 965f757f3fSDimitry Andric // bundles. 975f757f3fSDimitry Andric // 985f757f3fSDimitry Andric // The format is as follows: 995f757f3fSDimitry Andric // - Magic Number (4 bytes) - A constant "CCOB". 1005f757f3fSDimitry Andric // - Version (2 bytes) 1015f757f3fSDimitry Andric // - Compression Method (2 bytes) - Uses the values from 1025f757f3fSDimitry Andric // llvm::compression::Format. 103*0fca6ea1SDimitry Andric // - Total file size (4 bytes). Available in version 2 and above. 1045f757f3fSDimitry Andric // - Uncompressed Size (4 bytes). 1055f757f3fSDimitry Andric // - Truncated MD5 Hash (8 bytes). 1065f757f3fSDimitry Andric // - Compressed Data (variable length). 1075f757f3fSDimitry Andric 1085f757f3fSDimitry Andric class CompressedOffloadBundle { 1095f757f3fSDimitry Andric private: 1105f757f3fSDimitry Andric static inline const size_t MagicSize = 4; 1115f757f3fSDimitry Andric static inline const size_t VersionFieldSize = sizeof(uint16_t); 1125f757f3fSDimitry Andric static inline const size_t MethodFieldSize = sizeof(uint16_t); 113*0fca6ea1SDimitry Andric static inline const size_t FileSizeFieldSize = sizeof(uint32_t); 114*0fca6ea1SDimitry Andric static inline const size_t UncompressedSizeFieldSize = sizeof(uint32_t); 115*0fca6ea1SDimitry Andric static inline const size_t HashFieldSize = sizeof(uint64_t); 116*0fca6ea1SDimitry Andric static inline const size_t V1HeaderSize = 117*0fca6ea1SDimitry Andric MagicSize + VersionFieldSize + MethodFieldSize + 118*0fca6ea1SDimitry Andric UncompressedSizeFieldSize + HashFieldSize; 119*0fca6ea1SDimitry Andric static inline const size_t V2HeaderSize = 120*0fca6ea1SDimitry Andric MagicSize + VersionFieldSize + FileSizeFieldSize + MethodFieldSize + 121*0fca6ea1SDimitry Andric UncompressedSizeFieldSize + HashFieldSize; 1225f757f3fSDimitry Andric static inline const llvm::StringRef MagicNumber = "CCOB"; 123*0fca6ea1SDimitry Andric static inline const uint16_t Version = 2; 1245f757f3fSDimitry Andric 1255f757f3fSDimitry Andric public: 1265f757f3fSDimitry Andric static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 127*0fca6ea1SDimitry Andric compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input, 128*0fca6ea1SDimitry Andric bool Verbose = false); 1295f757f3fSDimitry Andric static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 1305f757f3fSDimitry Andric decompress(const llvm::MemoryBuffer &Input, bool Verbose = false); 1315f757f3fSDimitry Andric }; 1325f757f3fSDimitry Andric 133bdd1243dSDimitry Andric } // namespace clang 134bdd1243dSDimitry Andric 135bdd1243dSDimitry Andric #endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 136