1 | //===-- llvm/Support/Compression.h ---Compression----------------*- 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 | // This file contains basic functions for compression/decompression. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #ifndef LLVM_SUPPORT_COMPRESSION_H |
14 | #define LLVM_SUPPORT_COMPRESSION_H |
15 | |
16 | #include "llvm/ADT/ArrayRef.h" |
17 | #include "llvm/Support/DataTypes.h" |
18 | |
19 | namespace llvm { |
20 | template <typename T> class SmallVectorImpl; |
21 | class Error; |
22 | |
23 | // None indicates no compression. The other members are a subset of |
24 | // compression::Format, which is used for compressed debug sections in some |
25 | // object file formats (e.g. ELF). This is a separate class as we may add new |
26 | // compression::Format members for non-debugging purposes. |
27 | enum class DebugCompressionType { |
28 | None, ///< No compression |
29 | Zlib, ///< zlib |
30 | Zstd, ///< Zstandard |
31 | }; |
32 | |
33 | namespace compression { |
34 | namespace zlib { |
35 | |
36 | constexpr int NoCompression = 0; |
37 | constexpr int BestSpeedCompression = 1; |
38 | constexpr int DefaultCompression = 6; |
39 | constexpr int BestSizeCompression = 9; |
40 | |
41 | bool isAvailable(); |
42 | |
43 | void compress(ArrayRef<uint8_t> Input, |
44 | SmallVectorImpl<uint8_t> &CompressedBuffer, |
45 | int Level = DefaultCompression); |
46 | |
47 | Error decompress(ArrayRef<uint8_t> Input, uint8_t *Output, |
48 | size_t &UncompressedSize); |
49 | |
50 | Error decompress(ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &Output, |
51 | size_t UncompressedSize); |
52 | |
53 | } // End of namespace zlib |
54 | |
55 | namespace zstd { |
56 | |
57 | constexpr int NoCompression = -5; |
58 | constexpr int BestSpeedCompression = 1; |
59 | constexpr int DefaultCompression = 5; |
60 | constexpr int BestSizeCompression = 12; |
61 | |
62 | bool isAvailable(); |
63 | |
64 | void compress(ArrayRef<uint8_t> Input, |
65 | SmallVectorImpl<uint8_t> &CompressedBuffer, |
66 | int Level = DefaultCompression, bool EnableLdm = false); |
67 | |
68 | Error decompress(ArrayRef<uint8_t> Input, uint8_t *Output, |
69 | size_t &UncompressedSize); |
70 | |
71 | Error decompress(ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &Output, |
72 | size_t UncompressedSize); |
73 | |
74 | } // End of namespace zstd |
75 | |
76 | enum class Format { |
77 | Zlib, |
78 | Zstd, |
79 | }; |
80 | |
81 | inline Format formatFor(DebugCompressionType Type) { |
82 | switch (Type) { |
83 | case DebugCompressionType::None: |
84 | llvm_unreachable("not a compression type" ); |
85 | case DebugCompressionType::Zlib: |
86 | return Format::Zlib; |
87 | case DebugCompressionType::Zstd: |
88 | return Format::Zstd; |
89 | } |
90 | llvm_unreachable("" ); |
91 | } |
92 | |
93 | struct Params { |
94 | constexpr Params(Format F) |
95 | : format(F), level(F == Format::Zlib ? zlib::DefaultCompression |
96 | : zstd::DefaultCompression) {} |
97 | constexpr Params(Format F, int L, bool Ldm = false) |
98 | : format(F), level(L), zstdEnableLdm(Ldm) {} |
99 | Params(DebugCompressionType Type) : Params(formatFor(Type)) {} |
100 | |
101 | Format format; |
102 | int level; |
103 | bool zstdEnableLdm = false; // Enable zstd long distance matching |
104 | // This may support multi-threading for zstd in the future. Note that |
105 | // different threads may produce different output, so be careful if certain |
106 | // output determinism is desired. |
107 | }; |
108 | |
109 | // Return nullptr if LLVM was built with support (LLVM_ENABLE_ZLIB, |
110 | // LLVM_ENABLE_ZSTD) for the specified compression format; otherwise |
111 | // return a string literal describing the reason. |
112 | const char *getReasonIfUnsupported(Format F); |
113 | |
114 | // Compress Input with the specified format P.Format. If Level is -1, use |
115 | // *::DefaultCompression for the format. |
116 | void compress(Params P, ArrayRef<uint8_t> Input, |
117 | SmallVectorImpl<uint8_t> &Output); |
118 | |
119 | // Decompress Input. The uncompressed size must be available. |
120 | Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input, |
121 | uint8_t *Output, size_t UncompressedSize); |
122 | Error decompress(Format F, ArrayRef<uint8_t> Input, |
123 | SmallVectorImpl<uint8_t> &Output, size_t UncompressedSize); |
124 | Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input, |
125 | SmallVectorImpl<uint8_t> &Output, size_t UncompressedSize); |
126 | |
127 | } // End of namespace compression |
128 | |
129 | } // End of namespace llvm |
130 | |
131 | #endif |
132 | |