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/Error.h" 21 #include "llvm/TargetParser/Triple.h" 22 #include <llvm/Support/MemoryBuffer.h> 23 #include <string> 24 #include <vector> 25 26 namespace clang { 27 28 class OffloadBundlerConfig { 29 public: 30 OffloadBundlerConfig(); 31 32 bool AllowNoHost = false; 33 bool AllowMissingBundles = false; 34 bool CheckInputArchive = false; 35 bool PrintExternalCommands = false; 36 bool HipOpenmpCompatible = false; 37 bool Compress = false; 38 bool Verbose = false; 39 40 unsigned BundleAlignment = 1; 41 unsigned HostInputIndex = ~0u; 42 43 std::string FilesType; 44 std::string ObjcopyPath; 45 46 // TODO: Convert these to llvm::SmallVector 47 std::vector<std::string> TargetNames; 48 std::vector<std::string> InputFileNames; 49 std::vector<std::string> OutputFileNames; 50 }; 51 52 class OffloadBundler { 53 public: 54 const OffloadBundlerConfig &BundlerConfig; 55 56 // TODO: Add error checking from ClangOffloadBundler.cpp 57 OffloadBundler(const OffloadBundlerConfig &BC) : BundlerConfig(BC) {} 58 59 // List bundle IDs. Return true if an error was found. 60 static llvm::Error 61 ListBundleIDsInFile(llvm::StringRef InputFileName, 62 const OffloadBundlerConfig &BundlerConfig); 63 64 llvm::Error BundleFiles(); 65 llvm::Error UnbundleFiles(); 66 llvm::Error UnbundleArchive(); 67 }; 68 69 /// Obtain the offload kind, real machine triple, and an optional TargetID 70 /// out of the target information specified by the user. 71 /// Bundle Entry ID (or, Offload Target String) has following components: 72 /// * Offload Kind - Host, OpenMP, or HIP 73 /// * Triple - Standard LLVM Triple 74 /// * TargetID (Optional) - target ID, like gfx906:xnack+ or sm_30 75 struct OffloadTargetInfo { 76 llvm::StringRef OffloadKind; 77 llvm::Triple Triple; 78 llvm::StringRef TargetID; 79 80 const OffloadBundlerConfig &BundlerConfig; 81 82 OffloadTargetInfo(const llvm::StringRef Target, 83 const OffloadBundlerConfig &BC); 84 bool hasHostKind() const; 85 bool isOffloadKindValid() const; 86 bool isOffloadKindCompatible(const llvm::StringRef TargetOffloadKind) const; 87 bool isTripleValid() const; 88 bool operator==(const OffloadTargetInfo &Target) const; 89 std::string str() const; 90 }; 91 92 // CompressedOffloadBundle represents the format for the compressed offload 93 // bundles. 94 // 95 // The format is as follows: 96 // - Magic Number (4 bytes) - A constant "CCOB". 97 // - Version (2 bytes) 98 // - Compression Method (2 bytes) - Uses the values from 99 // llvm::compression::Format. 100 // - Uncompressed Size (4 bytes). 101 // - Truncated MD5 Hash (8 bytes). 102 // - Compressed Data (variable length). 103 104 class CompressedOffloadBundle { 105 private: 106 static inline const size_t MagicSize = 4; 107 static inline const size_t VersionFieldSize = sizeof(uint16_t); 108 static inline const size_t MethodFieldSize = sizeof(uint16_t); 109 static inline const size_t SizeFieldSize = sizeof(uint32_t); 110 static inline const size_t HashFieldSize = 8; 111 static inline const size_t HeaderSize = MagicSize + VersionFieldSize + 112 MethodFieldSize + SizeFieldSize + 113 HashFieldSize; 114 static inline const llvm::StringRef MagicNumber = "CCOB"; 115 static inline const uint16_t Version = 1; 116 117 public: 118 static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 119 compress(const llvm::MemoryBuffer &Input, bool Verbose = false); 120 static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> 121 decompress(const llvm::MemoryBuffer &Input, bool Verbose = false); 122 }; 123 124 } // namespace clang 125 126 #endif // LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H 127