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
19namespace llvm {
20template <typename T> class SmallVectorImpl;
21class 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.
27enum class DebugCompressionType {
28  None, ///< No compression
29  Zlib, ///< zlib
30  Zstd, ///< Zstandard
31};
32
33namespace compression {
34namespace zlib {
35
36constexpr int NoCompression = 0;
37constexpr int BestSpeedCompression = 1;
38constexpr int DefaultCompression = 6;
39constexpr int BestSizeCompression = 9;
40
41bool isAvailable();
42
43void compress(ArrayRef<uint8_t> Input,
44              SmallVectorImpl<uint8_t> &CompressedBuffer,
45              int Level = DefaultCompression);
46
47Error decompress(ArrayRef<uint8_t> Input, uint8_t *Output,
48                 size_t &UncompressedSize);
49
50Error decompress(ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &Output,
51                 size_t UncompressedSize);
52
53} // End of namespace zlib
54
55namespace zstd {
56
57constexpr int NoCompression = -5;
58constexpr int BestSpeedCompression = 1;
59constexpr int DefaultCompression = 5;
60constexpr int BestSizeCompression = 12;
61
62bool isAvailable();
63
64void compress(ArrayRef<uint8_t> Input,
65              SmallVectorImpl<uint8_t> &CompressedBuffer,
66              int Level = DefaultCompression);
67
68Error decompress(ArrayRef<uint8_t> Input, uint8_t *Output,
69                 size_t &UncompressedSize);
70
71Error decompress(ArrayRef<uint8_t> Input, SmallVectorImpl<uint8_t> &Output,
72                 size_t UncompressedSize);
73
74} // End of namespace zstd
75
76enum class Format {
77  Zlib,
78  Zstd,
79};
80
81inline 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
93struct Params {
94  constexpr Params(Format F)
95      : format(F), level(F == Format::Zlib ? zlib::DefaultCompression
96                                           : zstd::DefaultCompression) {}
97  Params(DebugCompressionType Type) : Params(formatFor(Type)) {}
98
99  Format format;
100  int level;
101  // This may support multi-threading for zstd in the future. Note that
102  // different threads may produce different output, so be careful if certain
103  // output determinism is desired.
104};
105
106// Return nullptr if LLVM was built with support (LLVM_ENABLE_ZLIB,
107// LLVM_ENABLE_ZSTD) for the specified compression format; otherwise
108// return a string literal describing the reason.
109const char *getReasonIfUnsupported(Format F);
110
111// Compress Input with the specified format P.Format. If Level is -1, use
112// *::DefaultCompression for the format.
113void compress(Params P, ArrayRef<uint8_t> Input,
114              SmallVectorImpl<uint8_t> &Output);
115
116// Decompress Input. The uncompressed size must be available.
117Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
118                 uint8_t *Output, size_t UncompressedSize);
119Error decompress(Format F, ArrayRef<uint8_t> Input,
120                 SmallVectorImpl<uint8_t> &Output, size_t UncompressedSize);
121Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
122                 SmallVectorImpl<uint8_t> &Output, size_t UncompressedSize);
123
124} // End of namespace compression
125
126} // End of namespace llvm
127
128#endif
129