Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-compress.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* LTO IL compression streams. | 1 /* LTO IL compression streams. |
2 | 2 |
3 Copyright (C) 2009-2018 Free Software Foundation, Inc. | 3 Copyright (C) 2009-2020 Free Software Foundation, Inc. |
4 Contributed by Simon Baldwin <simonb@google.com> | 4 Contributed by Simon Baldwin <simonb@google.com> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
8 GCC is free software; you can redistribute it and/or modify it | 8 GCC is free software; you can redistribute it and/or modify it |
33 system.h. */ | 33 system.h. */ |
34 #include <zlib.h> | 34 #include <zlib.h> |
35 #include "lto-compress.h" | 35 #include "lto-compress.h" |
36 #include "timevar.h" | 36 #include "timevar.h" |
37 | 37 |
38 #ifdef HAVE_ZSTD_H | |
39 #include <zstd.h> | |
40 #endif | |
41 | |
38 /* Compression stream structure, holds the flush callback and opaque token, | 42 /* Compression stream structure, holds the flush callback and opaque token, |
39 the buffered data, and a note of whether compressing or uncompressing. */ | 43 the buffered data, and a note of whether compressing or uncompressing. */ |
40 | 44 |
41 struct lto_compression_stream | 45 struct lto_compression_stream |
42 { | 46 { |
90 } | 94 } |
91 | 95 |
92 return level; | 96 return level; |
93 } | 97 } |
94 | 98 |
99 /* Free the buffer and memory associated with STREAM. */ | |
100 | |
101 static void | |
102 lto_destroy_compression_stream (struct lto_compression_stream *stream) | |
103 { | |
104 free (stream->buffer); | |
105 free (stream); | |
106 } | |
107 | |
108 #ifdef HAVE_ZSTD_H | |
109 /* Return a zstd compression level that zstd will not reject. Normalizes | |
110 the compression level from the command line flag, clamping non-default | |
111 values to the appropriate end of their valid range. */ | |
112 | |
113 static int | |
114 lto_normalized_zstd_level (void) | |
115 { | |
116 int level = flag_lto_compression_level; | |
117 | |
118 if (level < 0) | |
119 level = 0; | |
120 else if (level > ZSTD_maxCLevel ()) | |
121 level = ZSTD_maxCLevel (); | |
122 | |
123 return level; | |
124 } | |
125 | |
126 /* Compress STREAM using ZSTD algorithm. */ | |
127 | |
128 static void | |
129 lto_compression_zstd (struct lto_compression_stream *stream) | |
130 { | |
131 unsigned char *cursor = (unsigned char *) stream->buffer; | |
132 size_t size = stream->bytes; | |
133 | |
134 timevar_push (TV_IPA_LTO_COMPRESS); | |
135 size_t const outbuf_length = ZSTD_compressBound (size); | |
136 char *outbuf = (char *) xmalloc (outbuf_length); | |
137 | |
138 size_t const csize = ZSTD_compress (outbuf, outbuf_length, cursor, size, | |
139 lto_normalized_zstd_level ()); | |
140 | |
141 if (ZSTD_isError (csize)) | |
142 internal_error ("compressed stream: %s", ZSTD_getErrorName (csize)); | |
143 | |
144 stream->callback (outbuf, csize, NULL); | |
145 | |
146 lto_destroy_compression_stream (stream); | |
147 free (outbuf); | |
148 timevar_pop (TV_IPA_LTO_COMPRESS); | |
149 } | |
150 | |
151 /* Uncompress STREAM using ZSTD algorithm. */ | |
152 | |
153 static void | |
154 lto_uncompression_zstd (struct lto_compression_stream *stream) | |
155 { | |
156 unsigned char *cursor = (unsigned char *) stream->buffer; | |
157 size_t size = stream->bytes; | |
158 | |
159 timevar_push (TV_IPA_LTO_DECOMPRESS); | |
160 unsigned long long const rsize = ZSTD_getFrameContentSize (cursor, size); | |
161 if (rsize == ZSTD_CONTENTSIZE_ERROR) | |
162 internal_error ("original not compressed with zstd"); | |
163 else if (rsize == ZSTD_CONTENTSIZE_UNKNOWN) | |
164 internal_error ("original size unknown"); | |
165 | |
166 char *outbuf = (char *) xmalloc (rsize); | |
167 size_t const dsize = ZSTD_decompress (outbuf, rsize, cursor, size); | |
168 | |
169 if (ZSTD_isError (dsize)) | |
170 internal_error ("decompressed stream: %s", ZSTD_getErrorName (dsize)); | |
171 | |
172 stream->callback (outbuf, dsize, stream->opaque); | |
173 | |
174 lto_destroy_compression_stream (stream); | |
175 free (outbuf); | |
176 timevar_pop (TV_IPA_LTO_DECOMPRESS); | |
177 } | |
178 | |
179 #endif | |
180 | |
95 /* Create a new compression stream, with CALLBACK flush function passed | 181 /* Create a new compression stream, with CALLBACK flush function passed |
96 OPAQUE token, IS_COMPRESSION indicates if compressing or uncompressing. */ | 182 OPAQUE token, IS_COMPRESSION indicates if compressing or uncompressing. */ |
97 | 183 |
98 static struct lto_compression_stream * | 184 static struct lto_compression_stream * |
99 lto_new_compression_stream (void (*callback) (const char *, unsigned, void *), | 185 lto_new_compression_stream (void (*callback) (const char *, unsigned, void *), |
130 | 216 |
131 memcpy (stream->buffer + stream->bytes, base, num_chars); | 217 memcpy (stream->buffer + stream->bytes, base, num_chars); |
132 stream->bytes += num_chars; | 218 stream->bytes += num_chars; |
133 } | 219 } |
134 | 220 |
135 /* Free the buffer and memory associated with STREAM. */ | |
136 | |
137 static void | |
138 lto_destroy_compression_stream (struct lto_compression_stream *stream) | |
139 { | |
140 free (stream->buffer); | |
141 free (stream); | |
142 } | |
143 | |
144 /* Return a new compression stream, with CALLBACK flush function passed | 221 /* Return a new compression stream, with CALLBACK flush function passed |
145 OPAQUE token. */ | 222 OPAQUE token. */ |
146 | 223 |
147 struct lto_compression_stream * | 224 struct lto_compression_stream * |
148 lto_start_compression (void (*callback) (const char *, unsigned, void *), | 225 lto_start_compression (void (*callback) (const char *, unsigned, void *), |
161 | 238 |
162 lto_append_to_compression_stream (stream, base, num_chars); | 239 lto_append_to_compression_stream (stream, base, num_chars); |
163 lto_stats.num_output_il_bytes += num_chars; | 240 lto_stats.num_output_il_bytes += num_chars; |
164 } | 241 } |
165 | 242 |
166 /* Finalize STREAM compression, and free stream allocations. */ | 243 static void ATTRIBUTE_UNUSED |
167 | 244 lto_compression_zlib (struct lto_compression_stream *stream) |
168 void | |
169 lto_end_compression (struct lto_compression_stream *stream) | |
170 { | 245 { |
171 unsigned char *cursor = (unsigned char *) stream->buffer; | 246 unsigned char *cursor = (unsigned char *) stream->buffer; |
172 size_t remaining = stream->bytes; | 247 size_t remaining = stream->bytes; |
173 const size_t outbuf_length = Z_BUFFER_LENGTH; | 248 const size_t outbuf_length = Z_BUFFER_LENGTH; |
174 unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length); | 249 unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length); |
224 lto_destroy_compression_stream (stream); | 299 lto_destroy_compression_stream (stream); |
225 free (outbuf); | 300 free (outbuf); |
226 timevar_pop (TV_IPA_LTO_COMPRESS); | 301 timevar_pop (TV_IPA_LTO_COMPRESS); |
227 } | 302 } |
228 | 303 |
304 void | |
305 lto_end_compression (struct lto_compression_stream *stream) | |
306 { | |
307 #ifdef HAVE_ZSTD_H | |
308 lto_compression_zstd (stream); | |
309 #else | |
310 lto_compression_zlib (stream); | |
311 #endif | |
312 } | |
313 | |
229 /* Return a new uncompression stream, with CALLBACK flush function passed | 314 /* Return a new uncompression stream, with CALLBACK flush function passed |
230 OPAQUE token. */ | 315 OPAQUE token. */ |
231 | 316 |
232 struct lto_compression_stream * | 317 struct lto_compression_stream * |
233 lto_start_uncompression (void (*callback) (const char *, unsigned, void *), | 318 lto_start_uncompression (void (*callback) (const char *, unsigned, void *), |
246 | 331 |
247 lto_append_to_compression_stream (stream, base, num_chars); | 332 lto_append_to_compression_stream (stream, base, num_chars); |
248 lto_stats.num_input_il_bytes += num_chars; | 333 lto_stats.num_input_il_bytes += num_chars; |
249 } | 334 } |
250 | 335 |
251 /* Finalize STREAM uncompression, and free stream allocations. | 336 static void |
252 | 337 lto_uncompression_zlib (struct lto_compression_stream *stream) |
253 Because of the way LTO IL streams are compressed, there may be several | |
254 concatenated compressed segments in the accumulated data, so for this | |
255 function we iterate decompressions until no data remains. */ | |
256 | |
257 void | |
258 lto_end_uncompression (struct lto_compression_stream *stream) | |
259 { | 338 { |
260 unsigned char *cursor = (unsigned char *) stream->buffer; | 339 unsigned char *cursor = (unsigned char *) stream->buffer; |
261 size_t remaining = stream->bytes; | 340 size_t remaining = stream->bytes; |
262 const size_t outbuf_length = Z_BUFFER_LENGTH; | 341 const size_t outbuf_length = Z_BUFFER_LENGTH; |
263 unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length); | 342 unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length); |
316 | 395 |
317 lto_destroy_compression_stream (stream); | 396 lto_destroy_compression_stream (stream); |
318 free (outbuf); | 397 free (outbuf); |
319 timevar_pop (TV_IPA_LTO_DECOMPRESS); | 398 timevar_pop (TV_IPA_LTO_DECOMPRESS); |
320 } | 399 } |
400 | |
401 void | |
402 lto_end_uncompression (struct lto_compression_stream *stream, | |
403 lto_compression compression) | |
404 { | |
405 #ifdef HAVE_ZSTD_H | |
406 if (compression == ZSTD) | |
407 { | |
408 lto_uncompression_zstd (stream); | |
409 return; | |
410 } | |
411 #endif | |
412 if (compression == ZSTD) | |
413 internal_error ("compiler does not support ZSTD LTO compression"); | |
414 | |
415 lto_uncompression_zlib (stream); | |
416 } |