xref: /freebsd-src/contrib/llvm-project/clang/include/clang/Driver/OffloadBundler.h (revision aca928a50a42f00f344df934005b09dbcb4e2f77)
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