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