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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [lto-compress.c] - Blame information for rev 856

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

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

powered by: WebSVN 2.1.0

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