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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [df-byte-scan.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Scanning of rtl byte level scanning for dataflow analysis.
2
   Copyright (C) 2008  Free Software Foundation, Inc.
3
   Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "rtl.h"
26
#include "tm_p.h"
27
#include "df.h"
28
#include "output.h"
29
#include "dbgcnt.h"
30
 
31
/* The following suite of functions provides bytewise modeling of REFs
32
   which are struct df_ref.  START_BYTE and LAST_BYTE are returned.
33
   These can be used as indexes into bitmaps.  The indexes are
34
   normalized so that 0 is the lowest numbered byte, of the inner
35
   register according to the natural ordering of the machine.
36
 
37
   This code is designed to be used in backwards scans (which is, of
38
   course, the way all dataflow scanning should really be done).  It
39
   would require a lot of reworking of the api to make it work in a
40
   forwards scanning world.  */
41
 
42
 
43
/* Helper for df_compute_accessed_bytes.  Ref is some sort of extract.
44
   Return true if this effects the entire reg in REF.  Return false if
45
   otherwise and set START_BYTE and LAST_BYTE.  See the description of
46
   df_compute_accessed_bytes for a description of MM.  */
47
 
48
static bool
49
df_compute_accessed_bytes_extract (df_ref ref,
50
                                   enum df_mm mm ,
51
                                   unsigned int *start_byte,
52
                                   unsigned int *last_byte)
53
{
54
  int start;
55
  int last;
56
  rtx reg = DF_REF_REG (ref);
57
  enum machine_mode m1;
58
  int m1_size;
59
  enum machine_mode m2;
60
  int m2_size;
61
 
62
  /* (*_extract:M1 (reg:M2 X) WIDTH POS)
63
     (*_extract:M1 (subreg:M1 (reg:M2 X N) WIDTH POS)
64
 
65
     This is a bitfield extraction.  The assignment clobbers/extracts
66
     exactly the bits named by WIDTH and POS and does not affect the
67
     other bits in register X.  It is also technically possible that
68
     the bits asked for are longer than units per word.  */
69
 
70
  int offset = DF_REF_EXTRACT_OFFSET (ref);
71
  int width = DF_REF_EXTRACT_WIDTH (ref);
72
 
73
  if (width == -1 || offset == -1)
74
    return true;
75
 
76
  m1 = DF_REF_EXTRACT_MODE (ref);
77
  m1_size = GET_MODE_SIZE (m1);
78
 
79
  gcc_assert (m1_size <= UNITS_PER_WORD);
80
 
81
  /* There is nothing to do if this is a pure big or small endian
82
     machine, but if the machine is a pastiche, we have to convert the
83
     bit offsets into byte offsets.  This is only possible because we
84
     do not care about individual bits because this conversion may
85
     make the bits non-contiguous.  */
86
  if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN)
87
    offset = GET_MODE_BITSIZE (m1_size) - (offset + width);
88
 
89
  /* The offset is now in the same order as the subreg_byte.  */
90
  if (GET_CODE (reg) == SUBREG)
91
    {
92
      m2 = GET_MODE (SUBREG_REG (reg));
93
      m2_size = GET_MODE_SIZE (m2);
94
      if (m1_size > m2_size)
95
        /* If it is paradoxical, subreg_byte will be zero.  */
96
        offset -= subreg_lowpart_offset (m2, m1) * BITS_PER_UNIT;
97
      else
98
        offset += SUBREG_BYTE (reg) * BITS_PER_UNIT;
99
    }
100
  else
101
    {
102
      m2 = GET_MODE (reg);
103
      m2_size = GET_MODE_SIZE (m2);
104
    }
105
 
106
  if (mm == DF_MM_MUST)
107
    {
108
      /* For defs (generally), count the byte only if the whole byte
109
         is touched.  */
110
      start = (offset + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
111
      last = (width + offset) / BITS_PER_UNIT;
112
 
113
      /* In the case where there is nothing, start may be one larger
114
         than last, we canonize this to return zeros.  This keeps
115
         computations of length from being negative.  */
116
      if (start >= last)
117
        {
118
          start = 0;
119
          last = 0;
120
        }
121
    }
122
  else
123
    {
124
      /* For uses (generally), count the byte if any part of the byte
125
         is touched.  */
126
      start = offset / BITS_PER_UNIT;
127
      last = (width + offset + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
128
    }
129
 
130
  /* Paradoxical truncation.  */
131
  if (start < 0)
132
    start = 0;
133
  if (last > m2_size)
134
    last = m2_size;
135
 
136
  if (dump_file)
137
    fprintf (dump_file, "    cpb extract regno=%d start=%d last=%d\n",
138
             DF_REF_REGNO (ref), start, last);
139
 
140
  *start_byte = start;
141
  *last_byte = last;
142
  return false;
143
}
144
 
145
 
146
/* Helper for df_compute_accessed_bytes.  Ref is a strict_low_part.
147
   Return true if this effects the entire reg in REF. Return false if
148
   otherwise and set START_BYTE and LAST_BYTE.  */
149
 
150
static bool
151
df_compute_accessed_bytes_strict_low_part (df_ref ref,
152
                                           unsigned int *start_byte,
153
                                           unsigned int *last_byte)
154
{
155
  int start;
156
  int last;
157
  rtx reg = DF_REF_REG (ref);
158
  enum machine_mode m1;
159
  int m1_size;
160
  enum machine_mode m2;
161
  int m2_size;
162
  int offset;
163
 
164
  /* In order to accommodate multiword subregs of a hardreg, df_scan
165
     eats the subreg and it can only be found from the loc.  */
166
  if (REG_P (reg))
167
    reg = *(DF_REF_LOC (ref));
168
 
169
  m1 = GET_MODE (reg);
170
  m1_size = GET_MODE_SIZE (m1);
171
  m2 = GET_MODE (SUBREG_REG (reg));
172
  m2_size = GET_MODE_SIZE (m2);
173
  offset = SUBREG_BYTE (reg);
174
 
175
  /* It does not seem to be meaningful to apply a strict_low_part of a
176
     paradoxical register.  */
177
  gcc_assert (m1_size <= m2_size);
178
 
179
  /* (set (strict_low_part (subreg:M1 (reg:M2 X) N)) ...)
180
 
181
  This is a bitfield insertion.  The assignment clobbers exactly the
182
  bits named by the subreg--the M1 bits at position N.  It is also
183
  technically possible that the bits asked for are longer than units
184
  per word.  */
185
 
186
  start = offset;
187
  last = offset + m1_size;
188
 
189
  if (dump_file)
190
    fprintf (dump_file, "    cpb strict low part regno=%d start=%d last=%d\n",
191
             DF_REF_REGNO (ref), start, last);
192
 
193
  *start_byte = start;
194
  *last_byte = last;
195
  return false;
196
}
197
 
198
/* Helper for df_compute_accessed_bytes.  Ref is a naked subreg.
199
   Return true if this effects the entire reg in REF. Return false if
200
   otherwise and set START_BYTE and LAST_BYTE.  */
201
 
202
static bool
203
df_compute_accessed_bytes_subreg (df_ref ref, unsigned int *start_byte,
204
                                  unsigned int *last_byte)
205
 
206
{
207
  /* (subreg:M1 (reg:M2 X) N) */
208
  int start;
209
  int last;
210
  rtx reg = DF_REF_REG (ref);
211
 
212
  enum machine_mode m1;
213
  int m1_size;
214
  enum machine_mode m2;
215
  int m2_size;
216
 
217
  /* In order to accommodate multiword subregs of a hardreg, df_scan
218
     eats the subreg and it can only be found from the loc.  */
219
  if (REG_P (reg))
220
    reg = *(DF_REF_LOC (ref));
221
 
222
  m1 = GET_MODE (reg);
223
  m1_size = GET_MODE_SIZE (m1);
224
  m2 = GET_MODE (SUBREG_REG (reg));
225
  m2_size = GET_MODE_SIZE (m2);
226
 
227
  /* A simple paradoxical subreg just accesses the entire inner reg.  */
228
  if (m1_size >= m2_size)
229
    return true;
230
 
231
  /* Defs and uses are different in the amount of the reg that touch.  */
232
  if (DF_REF_REG_DEF_P (ref))
233
    {
234
      /* This is an lvalue.  */
235
 
236
      if (m2_size > UNITS_PER_WORD)
237
        {
238
          /* The assignment clobbers UNITS_PER_WORD segments of X.
239
             Look at the bytes named by the subreg, and expand it to
240
             cover a UNITS_PER_WORD part of register X.  That part of
241
             register X is clobbered, the rest is not.
242
 
243
             E.g., (subreg:SI (reg:DI X) 0), where UNITS_PER_WORD is the
244
             size of SImode, clobbers the first SImode part of X, and does
245
             not affect the second SImode part.
246
 
247
             E.g., (subreg:QI (reg:DI X) 0), where UNITS_PER_WORD is the
248
             size of SImode, clobbers the first SImode part of X, and does
249
             not affect the second SImode part.  Here the QImode byte is
250
             expanded to a UNITS_PER_WORD portion of the register for
251
             purposes of determining what is clobbered.
252
 
253
             If this is an rvalue, then it touches just the bytes that it
254
             talks about.  */
255
          int offset = SUBREG_BYTE (reg);
256
 
257
          start = offset & ~(UNITS_PER_WORD - 1);
258
          last = (offset + m1_size + UNITS_PER_WORD - 1)
259
            & ~(UNITS_PER_WORD - 1);
260
        }
261
      else
262
        /* Whole register size M2 equal to or smaller than
263
           UNITS_PER_WORD The assignment clobbers the entire register
264
           X.  */
265
        return true;
266
    }
267
  else
268
    {
269
      /* This is an rvalue. It touches just the bytes they explicitly
270
         mentioned.  */
271
      int offset = SUBREG_BYTE (reg);
272
      start = offset;
273
      last = start + m1_size;
274
    }
275
 
276
  if (dump_file)
277
    fprintf (dump_file, "    cpb subreg regno=%d start=%d last=%d\n",
278
             DF_REF_REGNO (ref), start, last);
279
 
280
  *start_byte = start;
281
  *last_byte = last;
282
  return false;
283
}
284
 
285
 
286
/* Compute the set of affected bytes by a store to a pseudo to REF.
287
   MM is either DF_MM_MAY or DF_MM_MUST.  This is only relevant for
288
   the extracts which are not aligned to byte boundaries.  The
289
   DF_MM_MAY returns all of the bytes that any bit is set in and the
290
   DF_MM_MUST returns only the bytes that are completely covered.  In
291
   general DF_MM_MAY is used for uses and DF_MM_MUST is used for defs,
292
   but there are exceptions such as the inner loop of the byte level
293
   dead code eliminator which needs DF_MM_MAY for the defs to see if
294
   it any possible bit could be used.
295
 
296
   If the store is to the whole register, just return TRUE, if it is
297
   to part of the register, return FALSE and set START_BYTE and
298
   LAST_BYTE properly.  In the case where fabricated uses are passed
299
   in, START_BYTE and LAST_BYTE are set to 0 and false is returned.
300
   This means that this use can be ignored.  */
301
 
302
bool
303
df_compute_accessed_bytes (df_ref ref, enum df_mm mm,
304
                           unsigned int *start_byte,
305
                           unsigned int *last_byte)
306
{
307
  if (!dbg_cnt (df_byte_scan))
308
    return true;
309
 
310
  if (!DF_REF_REG_DEF_P (ref)
311
      && DF_REF_FLAGS_IS_SET (ref, DF_REF_READ_WRITE))
312
    {
313
      if (DF_REF_FLAGS_IS_SET (ref, DF_REF_PRE_POST_MODIFY))
314
        /* Pre/post modify/inc/dec always read and write the entire
315
           reg.  */
316
        return true;
317
      else
318
        {
319
          /* DF_REF_READ_WRITE on a use (except for the
320
             DF_REF_PRE_POST_MODIFY) means that this use is fabricated
321
             from a def that is a partial set to a multiword reg.
322
             Here, we only model those cases precisely so the only one
323
             to consider is the use put on a auto inc and dec
324
             insns.  */
325
          *start_byte = 0;
326
          *last_byte = 0;
327
          return false;
328
        }
329
    }
330
 
331
  if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
332
    return df_compute_accessed_bytes_extract (ref, mm, start_byte, last_byte);
333
  else if (DF_REF_FLAGS_IS_SET (ref, DF_REF_STRICT_LOW_PART))
334
    return df_compute_accessed_bytes_strict_low_part (ref,
335
                                                      start_byte, last_byte);
336
  else if (GET_CODE (DF_REF_REG (ref)) == SUBREG)
337
    return df_compute_accessed_bytes_subreg (ref, start_byte, last_byte);
338
  return true;
339
}
340
 

powered by: WebSVN 2.1.0

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