OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [lto-compress.c] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* LTO IL compression streams.
2
 
3
   Copyright 2009, 2010 Free Software Foundation, Inc.
4
   Contributed by Simon Baldwin <simonb@google.com>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it
9
under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3, or (at your option)
11
any later version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT
14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
/* zlib.h includes other system headers.  Those headers may test feature
25
   test macros.  config.h may define feature test macros.  For this reason,
26
   zlib.h needs to be included after, rather than before, config.h and
27
   system.h.  */
28
#include <zlib.h>
29
#include "coretypes.h"
30
#include "tree.h"
31
#include "diagnostic-core.h"
32
#include "langhooks.h"
33
#include "lto-streamer.h"
34
#include "lto-compress.h"
35
 
36
/* Compression stream structure, holds the flush callback and opaque token,
37
   the buffered data, and a note of whether compressing or uncompressing.  */
38
 
39
struct lto_compression_stream
40
{
41
  void (*callback) (const char *, unsigned, void *);
42
  void *opaque;
43
  char *buffer;
44
  size_t bytes;
45
  size_t allocation;
46
  bool is_compression;
47
};
48
 
49
/* Overall compression constants for zlib.  */
50
 
51
static const size_t Z_BUFFER_LENGTH = 4096;
52
static const size_t MIN_STREAM_ALLOCATION = 1024;
53
 
54
/* For zlib, allocate SIZE count of ITEMS and return the address, OPAQUE
55
   is unused.  */
56
 
57
static void *
58
lto_zalloc (void *opaque, unsigned items, unsigned size)
59
{
60
  gcc_assert (opaque == Z_NULL);
61
  return xmalloc (items * size);
62
}
63
 
64
/* For zlib, free memory at ADDRESS, OPAQUE is unused.  */
65
 
66
static void
67
lto_zfree (void *opaque, void *address)
68
{
69
  gcc_assert (opaque == Z_NULL);
70
  free (address);
71
}
72
 
73
/* Return a zlib compression level that zlib will not reject.  Normalizes
74
   the compression level from the command line flag, clamping non-default
75
   values to the appropriate end of their valid range.  */
76
 
77
static int
78
lto_normalized_zlib_level (void)
79
{
80
  int level = flag_lto_compression_level;
81
 
82
  if (level != Z_DEFAULT_COMPRESSION)
83
    {
84
      if (level < Z_NO_COMPRESSION)
85
        level = Z_NO_COMPRESSION;
86
      else if (level > Z_BEST_COMPRESSION)
87
        level = Z_BEST_COMPRESSION;
88
    }
89
 
90
  return level;
91
}
92
 
93
/* Create a new compression stream, with CALLBACK flush function passed
94
   OPAQUE token, IS_COMPRESSION indicates if compressing or uncompressing.  */
95
 
96
static struct lto_compression_stream *
97
lto_new_compression_stream (void (*callback) (const char *, unsigned, void *),
98
                            void *opaque, bool is_compression)
99
{
100
  struct lto_compression_stream *stream
101
    = (struct lto_compression_stream *) xmalloc (sizeof (*stream));
102
 
103
  memset (stream, 0, sizeof (*stream));
104
  stream->callback = callback;
105
  stream->opaque = opaque;
106
  stream->is_compression = is_compression;
107
 
108
  return stream;
109
}
110
 
111
/* Append NUM_CHARS from address BASE to STREAM.  */
112
 
113
static void
114
lto_append_to_compression_stream (struct lto_compression_stream *stream,
115
                                  const char *base, size_t num_chars)
116
{
117
  size_t required = stream->bytes + num_chars;
118
 
119
  if (stream->allocation < required)
120
    {
121
      if (stream->allocation == 0)
122
        stream->allocation = MIN_STREAM_ALLOCATION;
123
      while (stream->allocation < required)
124
        stream->allocation *= 2;
125
 
126
      stream->buffer = (char *) xrealloc (stream->buffer, stream->allocation);
127
    }
128
 
129
  memcpy (stream->buffer + stream->bytes, base, num_chars);
130
  stream->bytes += num_chars;
131
}
132
 
133
/* Free the buffer and memory associated with STREAM.  */
134
 
135
static void
136
lto_destroy_compression_stream (struct lto_compression_stream *stream)
137
{
138
  free (stream->buffer);
139
  free (stream);
140
}
141
 
142
/* Return a new compression stream, with CALLBACK flush function passed
143
   OPAQUE token.  */
144
 
145
struct lto_compression_stream *
146
lto_start_compression (void (*callback) (const char *, unsigned, void *),
147
                       void *opaque)
148
{
149
  return lto_new_compression_stream (callback, opaque, true);
150
}
151
 
152
/* Append NUM_CHARS from address BASE to STREAM.  */
153
 
154
void
155
lto_compress_block (struct lto_compression_stream *stream,
156
                    const char *base, size_t num_chars)
157
{
158
  gcc_assert (stream->is_compression);
159
 
160
  lto_append_to_compression_stream (stream, base, num_chars);
161
  lto_stats.num_output_il_bytes += num_chars;
162
}
163
 
164
/* Finalize STREAM compression, and free stream allocations.  */
165
 
166
void
167
lto_end_compression (struct lto_compression_stream *stream)
168
{
169
  unsigned char *cursor = (unsigned char *) stream->buffer;
170
  size_t remaining = stream->bytes;
171
  const size_t outbuf_length = Z_BUFFER_LENGTH;
172
  unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length);
173
  z_stream out_stream;
174
  size_t compressed_bytes = 0;
175
  int status;
176
 
177
  gcc_assert (stream->is_compression);
178
 
179
  out_stream.next_out = outbuf;
180
  out_stream.avail_out = outbuf_length;
181
  out_stream.next_in = cursor;
182
  out_stream.avail_in = remaining;
183
  out_stream.zalloc = lto_zalloc;
184
  out_stream.zfree = lto_zfree;
185
  out_stream.opaque = Z_NULL;
186
 
187
  status = deflateInit (&out_stream, lto_normalized_zlib_level ());
188
  if (status != Z_OK)
189
    internal_error ("compressed stream: %s", zError (status));
190
 
191
  do
192
    {
193
      size_t in_bytes, out_bytes;
194
 
195
      status = deflate (&out_stream, Z_FINISH);
196
      if (status != Z_OK && status != Z_STREAM_END)
197
        internal_error ("compressed stream: %s", zError (status));
198
 
199
      in_bytes = remaining - out_stream.avail_in;
200
      out_bytes = outbuf_length - out_stream.avail_out;
201
 
202
      stream->callback ((const char *) outbuf, out_bytes, stream->opaque);
203
      lto_stats.num_compressed_il_bytes += out_bytes;
204
      compressed_bytes += out_bytes;
205
 
206
      cursor += in_bytes;
207
      remaining -= in_bytes;
208
 
209
      out_stream.next_out = outbuf;
210
      out_stream.avail_out = outbuf_length;
211
      out_stream.next_in = cursor;
212
      out_stream.avail_in = remaining;
213
    }
214
  while (status != Z_STREAM_END);
215
 
216
  status = deflateEnd (&out_stream);
217
  if (status != Z_OK)
218
    internal_error ("compressed stream: %s", zError (status));
219
 
220
  lto_destroy_compression_stream (stream);
221
  free (outbuf);
222
}
223
 
224
/* Return a new uncompression stream, with CALLBACK flush function passed
225
   OPAQUE token.  */
226
 
227
struct lto_compression_stream *
228
lto_start_uncompression (void (*callback) (const char *, unsigned, void *),
229
                         void *opaque)
230
{
231
  return lto_new_compression_stream (callback, opaque, false);
232
}
233
 
234
/* Append NUM_CHARS from address BASE to STREAM.  */
235
 
236
void
237
lto_uncompress_block (struct lto_compression_stream *stream,
238
                      const char *base, size_t num_chars)
239
{
240
  gcc_assert (!stream->is_compression);
241
 
242
  lto_append_to_compression_stream (stream, base, num_chars);
243
  lto_stats.num_input_il_bytes += num_chars;
244
}
245
 
246
/* Finalize STREAM uncompression, and free stream allocations.
247
 
248
   Because of the way LTO IL streams are compressed, there may be several
249
   concatenated compressed segments in the accumulated data, so for this
250
   function we iterate decompressions until no data remains.  */
251
 
252
void
253
lto_end_uncompression (struct lto_compression_stream *stream)
254
{
255
  unsigned char *cursor = (unsigned char *) stream->buffer;
256
  size_t remaining = stream->bytes;
257
  const size_t outbuf_length = Z_BUFFER_LENGTH;
258
  unsigned char *outbuf = (unsigned char *) xmalloc (outbuf_length);
259
  size_t uncompressed_bytes = 0;
260
 
261
  gcc_assert (!stream->is_compression);
262
 
263
  while (remaining > 0)
264
    {
265
      z_stream in_stream;
266
      size_t out_bytes;
267
      int status;
268
 
269
      in_stream.next_out = outbuf;
270
      in_stream.avail_out = outbuf_length;
271
      in_stream.next_in = cursor;
272
      in_stream.avail_in = remaining;
273
      in_stream.zalloc = lto_zalloc;
274
      in_stream.zfree = lto_zfree;
275
      in_stream.opaque = Z_NULL;
276
 
277
      status = inflateInit (&in_stream);
278
      if (status != Z_OK)
279
        internal_error ("compressed stream: %s", zError (status));
280
 
281
      do
282
        {
283
          size_t in_bytes;
284
 
285
          status = inflate (&in_stream, Z_SYNC_FLUSH);
286
          if (status != Z_OK && status != Z_STREAM_END)
287
            internal_error ("compressed stream: %s", zError (status));
288
 
289
          in_bytes = remaining - in_stream.avail_in;
290
          out_bytes = outbuf_length - in_stream.avail_out;
291
 
292
          stream->callback ((const char *) outbuf, out_bytes, stream->opaque);
293
          lto_stats.num_uncompressed_il_bytes += out_bytes;
294
          uncompressed_bytes += out_bytes;
295
 
296
          cursor += in_bytes;
297
          remaining -= in_bytes;
298
 
299
          in_stream.next_out = outbuf;
300
          in_stream.avail_out = outbuf_length;
301
          in_stream.next_in = cursor;
302
          in_stream.avail_in = remaining;
303
        }
304
      while (!(status == Z_STREAM_END && out_bytes == 0));
305
 
306
      status = inflateEnd (&in_stream);
307
      if (status != Z_OK)
308
        internal_error ("compressed stream: %s", zError (status));
309
    }
310
 
311
  lto_destroy_compression_stream (stream);
312
  free (outbuf);
313
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.