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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [postreload.c] - Blame information for rev 307

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

Line No. Rev Author Line
1 38 julius
/* Perform simple optimizations to clean up the result of reload.
2
   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3
   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
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
 
26
#include "machmode.h"
27
#include "hard-reg-set.h"
28
#include "rtl.h"
29
#include "tm_p.h"
30
#include "obstack.h"
31
#include "insn-config.h"
32
#include "flags.h"
33
#include "function.h"
34
#include "expr.h"
35
#include "optabs.h"
36
#include "regs.h"
37
#include "basic-block.h"
38
#include "reload.h"
39
#include "recog.h"
40
#include "output.h"
41
#include "cselib.h"
42
#include "real.h"
43
#include "toplev.h"
44
#include "except.h"
45
#include "tree.h"
46
#include "timevar.h"
47
#include "tree-pass.h"
48
 
49
static int reload_cse_noop_set_p (rtx);
50
static void reload_cse_simplify (rtx, rtx);
51
static void reload_cse_regs_1 (rtx);
52
static int reload_cse_simplify_set (rtx, rtx);
53
static int reload_cse_simplify_operands (rtx, rtx);
54
 
55
static void reload_combine (void);
56
static void reload_combine_note_use (rtx *, rtx);
57
static void reload_combine_note_store (rtx, rtx, void *);
58
 
59
static void reload_cse_move2add (rtx);
60
static void move2add_note_store (rtx, rtx, void *);
61
 
62
/* Call cse / combine like post-reload optimization phases.
63
   FIRST is the first instruction.  */
64
void
65
reload_cse_regs (rtx first ATTRIBUTE_UNUSED)
66
{
67
  reload_cse_regs_1 (first);
68
  reload_combine ();
69
  reload_cse_move2add (first);
70
  if (flag_expensive_optimizations)
71
    reload_cse_regs_1 (first);
72
}
73
 
74
/* See whether a single set SET is a noop.  */
75
static int
76
reload_cse_noop_set_p (rtx set)
77
{
78
  if (cselib_reg_set_mode (SET_DEST (set)) != GET_MODE (SET_DEST (set)))
79
    return 0;
80
 
81
  return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set));
82
}
83
 
84
/* Try to simplify INSN.  */
85
static void
86
reload_cse_simplify (rtx insn, rtx testreg)
87
{
88
  rtx body = PATTERN (insn);
89
 
90
  if (GET_CODE (body) == SET)
91
    {
92
      int count = 0;
93
 
94
      /* Simplify even if we may think it is a no-op.
95
         We may think a memory load of a value smaller than WORD_SIZE
96
         is redundant because we haven't taken into account possible
97
         implicit extension.  reload_cse_simplify_set() will bring
98
         this out, so it's safer to simplify before we delete.  */
99
      count += reload_cse_simplify_set (body, insn);
100
 
101
      if (!count && reload_cse_noop_set_p (body))
102
        {
103
          rtx value = SET_DEST (body);
104
          if (REG_P (value)
105
              && ! REG_FUNCTION_VALUE_P (value))
106
            value = 0;
107
          delete_insn_and_edges (insn);
108
          return;
109
        }
110
 
111
      if (count > 0)
112
        apply_change_group ();
113
      else
114
        reload_cse_simplify_operands (insn, testreg);
115
    }
116
  else if (GET_CODE (body) == PARALLEL)
117
    {
118
      int i;
119
      int count = 0;
120
      rtx value = NULL_RTX;
121
 
122
      /* Registers mentioned in the clobber list for an asm cannot be reused
123
         within the body of the asm.  Invalidate those registers now so that
124
         we don't try to substitute values for them.  */
125
      if (asm_noperands (body) >= 0)
126
        {
127
          for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
128
            {
129
              rtx part = XVECEXP (body, 0, i);
130
              if (GET_CODE (part) == CLOBBER && REG_P (XEXP (part, 0)))
131
                cselib_invalidate_rtx (XEXP (part, 0));
132
            }
133
        }
134
 
135
      /* If every action in a PARALLEL is a noop, we can delete
136
         the entire PARALLEL.  */
137
      for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
138
        {
139
          rtx part = XVECEXP (body, 0, i);
140
          if (GET_CODE (part) == SET)
141
            {
142
              if (! reload_cse_noop_set_p (part))
143
                break;
144
              if (REG_P (SET_DEST (part))
145
                  && REG_FUNCTION_VALUE_P (SET_DEST (part)))
146
                {
147
                  if (value)
148
                    break;
149
                  value = SET_DEST (part);
150
                }
151
            }
152
          else if (GET_CODE (part) != CLOBBER)
153
            break;
154
        }
155
 
156
      if (i < 0)
157
        {
158
          delete_insn_and_edges (insn);
159
          /* We're done with this insn.  */
160
          return;
161
        }
162
 
163
      /* It's not a no-op, but we can try to simplify it.  */
164
      for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
165
        if (GET_CODE (XVECEXP (body, 0, i)) == SET)
166
          count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
167
 
168
      if (count > 0)
169
        apply_change_group ();
170
      else
171
        reload_cse_simplify_operands (insn, testreg);
172
    }
173
}
174
 
175
/* Do a very simple CSE pass over the hard registers.
176
 
177
   This function detects no-op moves where we happened to assign two
178
   different pseudo-registers to the same hard register, and then
179
   copied one to the other.  Reload will generate a useless
180
   instruction copying a register to itself.
181
 
182
   This function also detects cases where we load a value from memory
183
   into two different registers, and (if memory is more expensive than
184
   registers) changes it to simply copy the first register into the
185
   second register.
186
 
187
   Another optimization is performed that scans the operands of each
188
   instruction to see whether the value is already available in a
189
   hard register.  It then replaces the operand with the hard register
190
   if possible, much like an optional reload would.  */
191
 
192
static void
193
reload_cse_regs_1 (rtx first)
194
{
195
  rtx insn;
196
  rtx testreg = gen_rtx_REG (VOIDmode, -1);
197
 
198
  cselib_init (true);
199
  init_alias_analysis ();
200
 
201
  for (insn = first; insn; insn = NEXT_INSN (insn))
202
    {
203
      if (INSN_P (insn))
204
        reload_cse_simplify (insn, testreg);
205
 
206
      cselib_process_insn (insn);
207
    }
208
 
209
  /* Clean up.  */
210
  end_alias_analysis ();
211
  cselib_finish ();
212
}
213
 
214
/* Try to simplify a single SET instruction.  SET is the set pattern.
215
   INSN is the instruction it came from.
216
   This function only handles one case: if we set a register to a value
217
   which is not a register, we try to find that value in some other register
218
   and change the set into a register copy.  */
219
 
220
static int
221
reload_cse_simplify_set (rtx set, rtx insn)
222
{
223
  int did_change = 0;
224
  int dreg;
225
  rtx src;
226
  enum reg_class dclass;
227
  int old_cost;
228
  cselib_val *val;
229
  struct elt_loc_list *l;
230
#ifdef LOAD_EXTEND_OP
231
  enum rtx_code extend_op = UNKNOWN;
232
#endif
233
 
234
  dreg = true_regnum (SET_DEST (set));
235
  if (dreg < 0)
236
    return 0;
237
 
238
  src = SET_SRC (set);
239
  if (side_effects_p (src) || true_regnum (src) >= 0)
240
    return 0;
241
 
242
  dclass = REGNO_REG_CLASS (dreg);
243
 
244
#ifdef LOAD_EXTEND_OP
245
  /* When replacing a memory with a register, we need to honor assumptions
246
     that combine made wrt the contents of sign bits.  We'll do this by
247
     generating an extend instruction instead of a reg->reg copy.  Thus
248
     the destination must be a register that we can widen.  */
249
  if (MEM_P (src)
250
      && GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD
251
      && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != UNKNOWN
252
      && !REG_P (SET_DEST (set)))
253
    return 0;
254
#endif
255
 
256
  val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0);
257
  if (! val)
258
    return 0;
259
 
260
  /* If memory loads are cheaper than register copies, don't change them.  */
261
  if (MEM_P (src))
262
    old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
263
  else if (REG_P (src))
264
    old_cost = REGISTER_MOVE_COST (GET_MODE (src),
265
                                   REGNO_REG_CLASS (REGNO (src)), dclass);
266
  else
267
    old_cost = rtx_cost (src, SET);
268
 
269
  for (l = val->locs; l; l = l->next)
270
    {
271
      rtx this_rtx = l->loc;
272
      int this_cost;
273
 
274
      if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
275
        {
276
#ifdef LOAD_EXTEND_OP
277
          if (extend_op != UNKNOWN)
278
            {
279
              HOST_WIDE_INT this_val;
280
 
281
              /* ??? I'm lazy and don't wish to handle CONST_DOUBLE.  Other
282
                 constants, such as SYMBOL_REF, cannot be extended.  */
283
              if (GET_CODE (this_rtx) != CONST_INT)
284
                continue;
285
 
286
              this_val = INTVAL (this_rtx);
287
              switch (extend_op)
288
                {
289
                case ZERO_EXTEND:
290
                  this_val &= GET_MODE_MASK (GET_MODE (src));
291
                  break;
292
                case SIGN_EXTEND:
293
                  /* ??? In theory we're already extended.  */
294
                  if (this_val == trunc_int_for_mode (this_val, GET_MODE (src)))
295
                    break;
296
                default:
297
                  gcc_unreachable ();
298
                }
299
              this_rtx = GEN_INT (this_val);
300
            }
301
#endif
302
          this_cost = rtx_cost (this_rtx, SET);
303
        }
304
      else if (REG_P (this_rtx))
305
        {
306
#ifdef LOAD_EXTEND_OP
307
          if (extend_op != UNKNOWN)
308
            {
309
              this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
310
              this_cost = rtx_cost (this_rtx, SET);
311
            }
312
          else
313
#endif
314
            this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
315
                                            REGNO_REG_CLASS (REGNO (this_rtx)),
316
                                            dclass);
317
        }
318
      else
319
        continue;
320
 
321
      /* If equal costs, prefer registers over anything else.  That
322
         tends to lead to smaller instructions on some machines.  */
323
      if (this_cost < old_cost
324
          || (this_cost == old_cost
325
              && REG_P (this_rtx)
326
              && !REG_P (SET_SRC (set))))
327
        {
328
#ifdef LOAD_EXTEND_OP
329
          if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD
330
              && extend_op != UNKNOWN
331
#ifdef CANNOT_CHANGE_MODE_CLASS
332
              && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
333
                                            word_mode,
334
                                            REGNO_REG_CLASS (REGNO (SET_DEST (set))))
335
#endif
336
              )
337
            {
338
              rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
339
              ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
340
              validate_change (insn, &SET_DEST (set), wide_dest, 1);
341
            }
342
#endif
343
 
344
          validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1);
345
          old_cost = this_cost, did_change = 1;
346
        }
347
    }
348
 
349
  return did_change;
350
}
351
 
352
/* Try to replace operands in INSN with equivalent values that are already
353
   in registers.  This can be viewed as optional reloading.
354
 
355
   For each non-register operand in the insn, see if any hard regs are
356
   known to be equivalent to that operand.  Record the alternatives which
357
   can accept these hard registers.  Among all alternatives, select the
358
   ones which are better or equal to the one currently matching, where
359
   "better" is in terms of '?' and '!' constraints.  Among the remaining
360
   alternatives, select the one which replaces most operands with
361
   hard registers.  */
362
 
363
static int
364
reload_cse_simplify_operands (rtx insn, rtx testreg)
365
{
366
  int i, j;
367
 
368
  /* For each operand, all registers that are equivalent to it.  */
369
  HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
370
 
371
  const char *constraints[MAX_RECOG_OPERANDS];
372
 
373
  /* Vector recording how bad an alternative is.  */
374
  int *alternative_reject;
375
  /* Vector recording how many registers can be introduced by choosing
376
     this alternative.  */
377
  int *alternative_nregs;
378
  /* Array of vectors recording, for each operand and each alternative,
379
     which hard register to substitute, or -1 if the operand should be
380
     left as it is.  */
381
  int *op_alt_regno[MAX_RECOG_OPERANDS];
382
  /* Array of alternatives, sorted in order of decreasing desirability.  */
383
  int *alternative_order;
384
 
385
  extract_insn (insn);
386
 
387
  if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
388
    return 0;
389
 
390
  /* Figure out which alternative currently matches.  */
391
  if (! constrain_operands (1))
392
    fatal_insn_not_found (insn);
393
 
394
  alternative_reject = alloca (recog_data.n_alternatives * sizeof (int));
395
  alternative_nregs = alloca (recog_data.n_alternatives * sizeof (int));
396
  alternative_order = alloca (recog_data.n_alternatives * sizeof (int));
397
  memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
398
  memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
399
 
400
  /* For each operand, find out which regs are equivalent.  */
401
  for (i = 0; i < recog_data.n_operands; i++)
402
    {
403
      cselib_val *v;
404
      struct elt_loc_list *l;
405
      rtx op;
406
      enum machine_mode mode;
407
 
408
      CLEAR_HARD_REG_SET (equiv_regs[i]);
409
 
410
      /* cselib blows up on CODE_LABELs.  Trying to fix that doesn't seem
411
         right, so avoid the problem here.  Likewise if we have a constant
412
         and the insn pattern doesn't tell us the mode we need.  */
413
      if (LABEL_P (recog_data.operand[i])
414
          || (CONSTANT_P (recog_data.operand[i])
415
              && recog_data.operand_mode[i] == VOIDmode))
416
        continue;
417
 
418
      op = recog_data.operand[i];
419
      mode = GET_MODE (op);
420
#ifdef LOAD_EXTEND_OP
421
      if (MEM_P (op)
422
          && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
423
          && LOAD_EXTEND_OP (mode) != UNKNOWN)
424
        {
425
          rtx set = single_set (insn);
426
 
427
          /* We might have multiple sets, some of which do implicit
428
             extension.  Punt on this for now.  */
429
          if (! set)
430
            continue;
431
          /* If the destination is also a MEM or a STRICT_LOW_PART, no
432
             extension applies.
433
             Also, if there is an explicit extension, we don't have to
434
             worry about an implicit one.  */
435
          else if (MEM_P (SET_DEST (set))
436
                   || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART
437
                   || GET_CODE (SET_SRC (set)) == ZERO_EXTEND
438
                   || GET_CODE (SET_SRC (set)) == SIGN_EXTEND)
439
            ; /* Continue ordinary processing.  */
440
#ifdef CANNOT_CHANGE_MODE_CLASS
441
          /* If the register cannot change mode to word_mode, it follows that
442
             it cannot have been used in word_mode.  */
443
          else if (REG_P (SET_DEST (set))
444
                   && CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
445
                                                word_mode,
446
                                                REGNO_REG_CLASS (REGNO (SET_DEST (set)))))
447
            ; /* Continue ordinary processing.  */
448
#endif
449
          /* If this is a straight load, make the extension explicit.  */
450
          else if (REG_P (SET_DEST (set))
451
                   && recog_data.n_operands == 2
452
                   && SET_SRC (set) == op
453
                   && SET_DEST (set) == recog_data.operand[1-i])
454
            {
455
              validate_change (insn, recog_data.operand_loc[i],
456
                               gen_rtx_fmt_e (LOAD_EXTEND_OP (mode),
457
                                              word_mode, op),
458
                               1);
459
              validate_change (insn, recog_data.operand_loc[1-i],
460
                               gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
461
                               1);
462
              if (! apply_change_group ())
463
                return 0;
464
              return reload_cse_simplify_operands (insn, testreg);
465
            }
466
          else
467
            /* ??? There might be arithmetic operations with memory that are
468
               safe to optimize, but is it worth the trouble?  */
469
            continue;
470
        }
471
#endif /* LOAD_EXTEND_OP */
472
      v = cselib_lookup (op, recog_data.operand_mode[i], 0);
473
      if (! v)
474
        continue;
475
 
476
      for (l = v->locs; l; l = l->next)
477
        if (REG_P (l->loc))
478
          SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
479
    }
480
 
481
  for (i = 0; i < recog_data.n_operands; i++)
482
    {
483
      enum machine_mode mode;
484
      int regno;
485
      const char *p;
486
 
487
      op_alt_regno[i] = alloca (recog_data.n_alternatives * sizeof (int));
488
      for (j = 0; j < recog_data.n_alternatives; j++)
489
        op_alt_regno[i][j] = -1;
490
 
491
      p = constraints[i] = recog_data.constraints[i];
492
      mode = recog_data.operand_mode[i];
493
 
494
      /* Add the reject values for each alternative given by the constraints
495
         for this operand.  */
496
      j = 0;
497
      while (*p != '\0')
498
        {
499
          char c = *p++;
500
          if (c == ',')
501
            j++;
502
          else if (c == '?')
503
            alternative_reject[j] += 3;
504
          else if (c == '!')
505
            alternative_reject[j] += 300;
506
        }
507
 
508
      /* We won't change operands which are already registers.  We
509
         also don't want to modify output operands.  */
510
      regno = true_regnum (recog_data.operand[i]);
511
      if (regno >= 0
512
          || constraints[i][0] == '='
513
          || constraints[i][0] == '+')
514
        continue;
515
 
516
      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
517
        {
518
          int class = (int) NO_REGS;
519
 
520
          if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
521
            continue;
522
 
523
          REGNO (testreg) = regno;
524
          PUT_MODE (testreg, mode);
525
 
526
          /* We found a register equal to this operand.  Now look for all
527
             alternatives that can accept this register and have not been
528
             assigned a register they can use yet.  */
529
          j = 0;
530
          p = constraints[i];
531
          for (;;)
532
            {
533
              char c = *p;
534
 
535
              switch (c)
536
                {
537
                case '=':  case '+':  case '?':
538
                case '#':  case '&':  case '!':
539
                case '*':  case '%':
540
                case '0':  case '1':  case '2':  case '3':  case '4':
541
                case '5':  case '6':  case '7':  case '8':  case '9':
542
                case 'm':  case '<':  case '>':  case 'V':  case 'o':
543
                case 'E':  case 'F':  case 'G':  case 'H':
544
                case 's':  case 'i':  case 'n':
545
                case 'I':  case 'J':  case 'K':  case 'L':
546
                case 'M':  case 'N':  case 'O':  case 'P':
547
                case 'p': case 'X':
548
                  /* These don't say anything we care about.  */
549
                  break;
550
 
551
                case 'g': case 'r':
552
                  class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
553
                  break;
554
 
555
                default:
556
                  class
557
                    = (reg_class_subunion
558
                       [(int) class]
559
                       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
560
                  break;
561
 
562
                case ',': case '\0':
563
                  /* See if REGNO fits this alternative, and set it up as the
564
                     replacement register if we don't have one for this
565
                     alternative yet and the operand being replaced is not
566
                     a cheap CONST_INT.  */
567
                  if (op_alt_regno[i][j] == -1
568
                      && reg_fits_class_p (testreg, class, 0, mode)
569
                      && (GET_CODE (recog_data.operand[i]) != CONST_INT
570
                          || (rtx_cost (recog_data.operand[i], SET)
571
                              > rtx_cost (testreg, SET))))
572
                    {
573
                      alternative_nregs[j]++;
574
                      op_alt_regno[i][j] = regno;
575
                    }
576
                  j++;
577
                  class = (int) NO_REGS;
578
                  break;
579
                }
580
              p += CONSTRAINT_LEN (c, p);
581
 
582
              if (c == '\0')
583
                break;
584
            }
585
        }
586
    }
587
 
588
  /* Record all alternatives which are better or equal to the currently
589
     matching one in the alternative_order array.  */
590
  for (i = j = 0; i < recog_data.n_alternatives; i++)
591
    if (alternative_reject[i] <= alternative_reject[which_alternative])
592
      alternative_order[j++] = i;
593
  recog_data.n_alternatives = j;
594
 
595
  /* Sort it.  Given a small number of alternatives, a dumb algorithm
596
     won't hurt too much.  */
597
  for (i = 0; i < recog_data.n_alternatives - 1; i++)
598
    {
599
      int best = i;
600
      int best_reject = alternative_reject[alternative_order[i]];
601
      int best_nregs = alternative_nregs[alternative_order[i]];
602
      int tmp;
603
 
604
      for (j = i + 1; j < recog_data.n_alternatives; j++)
605
        {
606
          int this_reject = alternative_reject[alternative_order[j]];
607
          int this_nregs = alternative_nregs[alternative_order[j]];
608
 
609
          if (this_reject < best_reject
610
              || (this_reject == best_reject && this_nregs > best_nregs))
611
            {
612
              best = j;
613
              best_reject = this_reject;
614
              best_nregs = this_nregs;
615
            }
616
        }
617
 
618
      tmp = alternative_order[best];
619
      alternative_order[best] = alternative_order[i];
620
      alternative_order[i] = tmp;
621
    }
622
 
623
  /* Substitute the operands as determined by op_alt_regno for the best
624
     alternative.  */
625
  j = alternative_order[0];
626
 
627
  for (i = 0; i < recog_data.n_operands; i++)
628
    {
629
      enum machine_mode mode = recog_data.operand_mode[i];
630
      if (op_alt_regno[i][j] == -1)
631
        continue;
632
 
633
      validate_change (insn, recog_data.operand_loc[i],
634
                       gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
635
    }
636
 
637
  for (i = recog_data.n_dups - 1; i >= 0; i--)
638
    {
639
      int op = recog_data.dup_num[i];
640
      enum machine_mode mode = recog_data.operand_mode[op];
641
 
642
      if (op_alt_regno[op][j] == -1)
643
        continue;
644
 
645
      validate_change (insn, recog_data.dup_loc[i],
646
                       gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
647
    }
648
 
649
  return apply_change_group ();
650
}
651
 
652
/* If reload couldn't use reg+reg+offset addressing, try to use reg+reg
653
   addressing now.
654
   This code might also be useful when reload gave up on reg+reg addressing
655
   because of clashes between the return register and INDEX_REG_CLASS.  */
656
 
657
/* The maximum number of uses of a register we can keep track of to
658
   replace them with reg+reg addressing.  */
659
#define RELOAD_COMBINE_MAX_USES 6
660
 
661
/* INSN is the insn where a register has ben used, and USEP points to the
662
   location of the register within the rtl.  */
663
struct reg_use { rtx insn, *usep; };
664
 
665
/* If the register is used in some unknown fashion, USE_INDEX is negative.
666
   If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID
667
   indicates where it becomes live again.
668
   Otherwise, USE_INDEX is the index of the last encountered use of the
669
   register (which is first among these we have seen since we scan backwards),
670
   OFFSET contains the constant offset that is added to the register in
671
   all encountered uses, and USE_RUID indicates the first encountered, i.e.
672
   last, of these uses.
673
   STORE_RUID is always meaningful if we only want to use a value in a
674
   register in a different place: it denotes the next insn in the insn
675
   stream (i.e. the last encountered) that sets or clobbers the register.  */
676
static struct
677
  {
678
    struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
679
    int use_index;
680
    rtx offset;
681
    int store_ruid;
682
    int use_ruid;
683
  } reg_state[FIRST_PSEUDO_REGISTER];
684
 
685
/* Reverse linear uid.  This is increased in reload_combine while scanning
686
   the instructions from last to first.  It is used to set last_label_ruid
687
   and the store_ruid / use_ruid fields in reg_state.  */
688
static int reload_combine_ruid;
689
 
690
#define LABEL_LIVE(LABEL) \
691
  (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
692
 
693
static void
694
reload_combine (void)
695
{
696
  rtx insn, set;
697
  int first_index_reg = -1;
698
  int last_index_reg = 0;
699
  int i;
700
  basic_block bb;
701
  unsigned int r;
702
  int last_label_ruid;
703
  int min_labelno, n_labels;
704
  HARD_REG_SET ever_live_at_start, *label_live;
705
 
706
  /* If reg+reg can be used in offsetable memory addresses, the main chunk of
707
     reload has already used it where appropriate, so there is no use in
708
     trying to generate it now.  */
709
  if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
710
    return;
711
 
712
  /* To avoid wasting too much time later searching for an index register,
713
     determine the minimum and maximum index register numbers.  */
714
  for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
715
    if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
716
      {
717
        if (first_index_reg == -1)
718
          first_index_reg = r;
719
 
720
        last_index_reg = r;
721
      }
722
 
723
  /* If no index register is available, we can quit now.  */
724
  if (first_index_reg == -1)
725
    return;
726
 
727
  /* Set up LABEL_LIVE and EVER_LIVE_AT_START.  The register lifetime
728
     information is a bit fuzzy immediately after reload, but it's
729
     still good enough to determine which registers are live at a jump
730
     destination.  */
731
  min_labelno = get_first_label_num ();
732
  n_labels = max_label_num () - min_labelno;
733
  label_live = XNEWVEC (HARD_REG_SET, n_labels);
734
  CLEAR_HARD_REG_SET (ever_live_at_start);
735
 
736
  FOR_EACH_BB_REVERSE (bb)
737
    {
738
      insn = BB_HEAD (bb);
739
      if (LABEL_P (insn))
740
        {
741
          HARD_REG_SET live;
742
 
743
          REG_SET_TO_HARD_REG_SET (live,
744
                                   bb->il.rtl->global_live_at_start);
745
          compute_use_by_pseudos (&live,
746
                                  bb->il.rtl->global_live_at_start);
747
          COPY_HARD_REG_SET (LABEL_LIVE (insn), live);
748
          IOR_HARD_REG_SET (ever_live_at_start, live);
749
        }
750
    }
751
 
752
  /* Initialize last_label_ruid, reload_combine_ruid and reg_state.  */
753
  last_label_ruid = reload_combine_ruid = 0;
754
  for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
755
    {
756
      reg_state[r].store_ruid = reload_combine_ruid;
757
      if (fixed_regs[r])
758
        reg_state[r].use_index = -1;
759
      else
760
        reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
761
    }
762
 
763
  for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
764
    {
765
      rtx note;
766
 
767
      /* We cannot do our optimization across labels.  Invalidating all the use
768
         information we have would be costly, so we just note where the label
769
         is and then later disable any optimization that would cross it.  */
770
      if (LABEL_P (insn))
771
        last_label_ruid = reload_combine_ruid;
772
      else if (BARRIER_P (insn))
773
        for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
774
          if (! fixed_regs[r])
775
              reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
776
 
777
      if (! INSN_P (insn))
778
        continue;
779
 
780
      reload_combine_ruid++;
781
 
782
      /* Look for (set (REGX) (CONST_INT))
783
         (set (REGX) (PLUS (REGX) (REGY)))
784
         ...
785
         ... (MEM (REGX)) ...
786
         and convert it to
787
         (set (REGZ) (CONST_INT))
788
         ...
789
         ... (MEM (PLUS (REGZ) (REGY)))... .
790
 
791
         First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
792
         and that we know all uses of REGX before it dies.
793
         Also, explicitly check that REGX != REGY; our life information
794
         does not yet show whether REGY changes in this insn.  */
795
      set = single_set (insn);
796
      if (set != NULL_RTX
797
          && REG_P (SET_DEST (set))
798
          && (hard_regno_nregs[REGNO (SET_DEST (set))]
799
                              [GET_MODE (SET_DEST (set))]
800
              == 1)
801
          && GET_CODE (SET_SRC (set)) == PLUS
802
          && REG_P (XEXP (SET_SRC (set), 1))
803
          && rtx_equal_p (XEXP (SET_SRC (set), 0), SET_DEST (set))
804
          && !rtx_equal_p (XEXP (SET_SRC (set), 1), SET_DEST (set))
805
          && last_label_ruid < reg_state[REGNO (SET_DEST (set))].use_ruid)
806
        {
807
          rtx reg = SET_DEST (set);
808
          rtx plus = SET_SRC (set);
809
          rtx base = XEXP (plus, 1);
810
          rtx prev = prev_nonnote_insn (insn);
811
          rtx prev_set = prev ? single_set (prev) : NULL_RTX;
812
          unsigned int regno = REGNO (reg);
813
          rtx const_reg = NULL_RTX;
814
          rtx reg_sum = NULL_RTX;
815
 
816
          /* Now, we need an index register.
817
             We'll set index_reg to this index register, const_reg to the
818
             register that is to be loaded with the constant
819
             (denoted as REGZ in the substitution illustration above),
820
             and reg_sum to the register-register that we want to use to
821
             substitute uses of REG (typically in MEMs) with.
822
             First check REG and BASE for being index registers;
823
             we can use them even if they are not dead.  */
824
          if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
825
              || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
826
                                    REGNO (base)))
827
            {
828
              const_reg = reg;
829
              reg_sum = plus;
830
            }
831
          else
832
            {
833
              /* Otherwise, look for a free index register.  Since we have
834
                 checked above that neither REG nor BASE are index registers,
835
                 if we find anything at all, it will be different from these
836
                 two registers.  */
837
              for (i = first_index_reg; i <= last_index_reg; i++)
838
                {
839
                  if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
840
                                         i)
841
                      && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
842
                      && reg_state[i].store_ruid <= reg_state[regno].use_ruid
843
                      && hard_regno_nregs[i][GET_MODE (reg)] == 1)
844
                    {
845
                      rtx index_reg = gen_rtx_REG (GET_MODE (reg), i);
846
 
847
                      const_reg = index_reg;
848
                      reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
849
                      break;
850
                    }
851
                }
852
            }
853
 
854
          /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
855
             (REGY), i.e. BASE, is not clobbered before the last use we'll
856
             create.  */
857
          if (prev_set != 0
858
              && GET_CODE (SET_SRC (prev_set)) == CONST_INT
859
              && rtx_equal_p (SET_DEST (prev_set), reg)
860
              && reg_state[regno].use_index >= 0
861
              && (reg_state[REGNO (base)].store_ruid
862
                  <= reg_state[regno].use_ruid)
863
              && reg_sum != 0)
864
            {
865
              int i;
866
 
867
              /* Change destination register and, if necessary, the
868
                 constant value in PREV, the constant loading instruction.  */
869
              validate_change (prev, &SET_DEST (prev_set), const_reg, 1);
870
              if (reg_state[regno].offset != const0_rtx)
871
                validate_change (prev,
872
                                 &SET_SRC (prev_set),
873
                                 GEN_INT (INTVAL (SET_SRC (prev_set))
874
                                          + INTVAL (reg_state[regno].offset)),
875
                                 1);
876
 
877
              /* Now for every use of REG that we have recorded, replace REG
878
                 with REG_SUM.  */
879
              for (i = reg_state[regno].use_index;
880
                   i < RELOAD_COMBINE_MAX_USES; i++)
881
                validate_change (reg_state[regno].reg_use[i].insn,
882
                                 reg_state[regno].reg_use[i].usep,
883
                                 /* Each change must have its own
884
                                    replacement.  */
885
                                 copy_rtx (reg_sum), 1);
886
 
887
              if (apply_change_group ())
888
                {
889
                  rtx *np;
890
 
891
                  /* Delete the reg-reg addition.  */
892
                  delete_insn (insn);
893
 
894
                  if (reg_state[regno].offset != const0_rtx)
895
                    /* Previous REG_EQUIV / REG_EQUAL notes for PREV
896
                       are now invalid.  */
897
                    for (np = &REG_NOTES (prev); *np;)
898
                      {
899
                        if (REG_NOTE_KIND (*np) == REG_EQUAL
900
                            || REG_NOTE_KIND (*np) == REG_EQUIV)
901
                          *np = XEXP (*np, 1);
902
                        else
903
                          np = &XEXP (*np, 1);
904
                      }
905
 
906
                  reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
907
                  reg_state[REGNO (const_reg)].store_ruid
908
                    = reload_combine_ruid;
909
                  continue;
910
                }
911
            }
912
        }
913
 
914
      note_stores (PATTERN (insn), reload_combine_note_store, NULL);
915
 
916
      if (CALL_P (insn))
917
        {
918
          rtx link;
919
 
920
          for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
921
            if (call_used_regs[r])
922
              {
923
                reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
924
                reg_state[r].store_ruid = reload_combine_ruid;
925
              }
926
 
927
          for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
928
               link = XEXP (link, 1))
929
            {
930
              rtx usage_rtx = XEXP (XEXP (link, 0), 0);
931
              if (REG_P (usage_rtx))
932
                {
933
                  unsigned int i;
934
                  unsigned int start_reg = REGNO (usage_rtx);
935
                  unsigned int num_regs =
936
                        hard_regno_nregs[start_reg][GET_MODE (usage_rtx)];
937
                  unsigned int end_reg  = start_reg + num_regs - 1;
938
                  for (i = start_reg; i <= end_reg; i++)
939
                    if (GET_CODE (XEXP (link, 0)) == CLOBBER)
940
                      {
941
                        reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
942
                        reg_state[i].store_ruid = reload_combine_ruid;
943
                      }
944
                    else
945
                      reg_state[i].use_index = -1;
946
                 }
947
             }
948
 
949
        }
950
      else if (JUMP_P (insn)
951
               && GET_CODE (PATTERN (insn)) != RETURN)
952
        {
953
          /* Non-spill registers might be used at the call destination in
954
             some unknown fashion, so we have to mark the unknown use.  */
955
          HARD_REG_SET *live;
956
 
957
          if ((condjump_p (insn) || condjump_in_parallel_p (insn))
958
              && JUMP_LABEL (insn))
959
            live = &LABEL_LIVE (JUMP_LABEL (insn));
960
          else
961
            live = &ever_live_at_start;
962
 
963
          for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
964
            if (TEST_HARD_REG_BIT (*live, i))
965
              reg_state[i].use_index = -1;
966
        }
967
 
968
      reload_combine_note_use (&PATTERN (insn), insn);
969
      for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
970
        {
971
          if (REG_NOTE_KIND (note) == REG_INC
972
              && REG_P (XEXP (note, 0)))
973
            {
974
              int regno = REGNO (XEXP (note, 0));
975
 
976
              reg_state[regno].store_ruid = reload_combine_ruid;
977
              reg_state[regno].use_index = -1;
978
            }
979
        }
980
    }
981
 
982
  free (label_live);
983
}
984
 
985
/* Check if DST is a register or a subreg of a register; if it is,
986
   update reg_state[regno].store_ruid and reg_state[regno].use_index
987
   accordingly.  Called via note_stores from reload_combine.  */
988
 
989
static void
990
reload_combine_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
991
{
992
  int regno = 0;
993
  int i;
994
  enum machine_mode mode = GET_MODE (dst);
995
 
996
  if (GET_CODE (dst) == SUBREG)
997
    {
998
      regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
999
                                   GET_MODE (SUBREG_REG (dst)),
1000
                                   SUBREG_BYTE (dst),
1001
                                   GET_MODE (dst));
1002
      dst = SUBREG_REG (dst);
1003
    }
1004
  if (!REG_P (dst))
1005
    return;
1006
  regno += REGNO (dst);
1007
 
1008
  /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
1009
     careful with registers / register parts that are not full words.
1010
     Similarly for ZERO_EXTRACT.  */
1011
  if (GET_CODE (set) != SET
1012
      || GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
1013
      || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
1014
    {
1015
      for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--)
1016
        {
1017
          reg_state[i].use_index = -1;
1018
          reg_state[i].store_ruid = reload_combine_ruid;
1019
        }
1020
    }
1021
  else
1022
    {
1023
      for (i = hard_regno_nregs[regno][mode] - 1 + regno; i >= regno; i--)
1024
        {
1025
          reg_state[i].store_ruid = reload_combine_ruid;
1026
          reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
1027
        }
1028
    }
1029
}
1030
 
1031
/* XP points to a piece of rtl that has to be checked for any uses of
1032
   registers.
1033
   *XP is the pattern of INSN, or a part of it.
1034
   Called from reload_combine, and recursively by itself.  */
1035
static void
1036
reload_combine_note_use (rtx *xp, rtx insn)
1037
{
1038
  rtx x = *xp;
1039
  enum rtx_code code = x->code;
1040
  const char *fmt;
1041
  int i, j;
1042
  rtx offset = const0_rtx; /* For the REG case below.  */
1043
 
1044
  switch (code)
1045
    {
1046
    case SET:
1047
      if (REG_P (SET_DEST (x)))
1048
        {
1049
          reload_combine_note_use (&SET_SRC (x), insn);
1050
          return;
1051
        }
1052
      break;
1053
 
1054
    case USE:
1055
      /* If this is the USE of a return value, we can't change it.  */
1056
      if (REG_P (XEXP (x, 0)) && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
1057
        {
1058
        /* Mark the return register as used in an unknown fashion.  */
1059
          rtx reg = XEXP (x, 0);
1060
          int regno = REGNO (reg);
1061
          int nregs = hard_regno_nregs[regno][GET_MODE (reg)];
1062
 
1063
          while (--nregs >= 0)
1064
            reg_state[regno + nregs].use_index = -1;
1065
          return;
1066
        }
1067
      break;
1068
 
1069
    case CLOBBER:
1070
      if (REG_P (SET_DEST (x)))
1071
        {
1072
          /* No spurious CLOBBERs of pseudo registers may remain.  */
1073
          gcc_assert (REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER);
1074
          return;
1075
        }
1076
      break;
1077
 
1078
    case PLUS:
1079
      /* We are interested in (plus (reg) (const_int)) .  */
1080
      if (!REG_P (XEXP (x, 0))
1081
          || GET_CODE (XEXP (x, 1)) != CONST_INT)
1082
        break;
1083
      offset = XEXP (x, 1);
1084
      x = XEXP (x, 0);
1085
      /* Fall through.  */
1086
    case REG:
1087
      {
1088
        int regno = REGNO (x);
1089
        int use_index;
1090
        int nregs;
1091
 
1092
        /* No spurious USEs of pseudo registers may remain.  */
1093
        gcc_assert (regno < FIRST_PSEUDO_REGISTER);
1094
 
1095
        nregs = hard_regno_nregs[regno][GET_MODE (x)];
1096
 
1097
        /* We can't substitute into multi-hard-reg uses.  */
1098
        if (nregs > 1)
1099
          {
1100
            while (--nregs >= 0)
1101
              reg_state[regno + nregs].use_index = -1;
1102
            return;
1103
          }
1104
 
1105
        /* If this register is already used in some unknown fashion, we
1106
           can't do anything.
1107
           If we decrement the index from zero to -1, we can't store more
1108
           uses, so this register becomes used in an unknown fashion.  */
1109
        use_index = --reg_state[regno].use_index;
1110
        if (use_index < 0)
1111
          return;
1112
 
1113
        if (use_index != RELOAD_COMBINE_MAX_USES - 1)
1114
          {
1115
            /* We have found another use for a register that is already
1116
               used later.  Check if the offsets match; if not, mark the
1117
               register as used in an unknown fashion.  */
1118
            if (! rtx_equal_p (offset, reg_state[regno].offset))
1119
              {
1120
                reg_state[regno].use_index = -1;
1121
                return;
1122
              }
1123
          }
1124
        else
1125
          {
1126
            /* This is the first use of this register we have seen since we
1127
               marked it as dead.  */
1128
            reg_state[regno].offset = offset;
1129
            reg_state[regno].use_ruid = reload_combine_ruid;
1130
          }
1131
        reg_state[regno].reg_use[use_index].insn = insn;
1132
        reg_state[regno].reg_use[use_index].usep = xp;
1133
        return;
1134
      }
1135
 
1136
    default:
1137
      break;
1138
    }
1139
 
1140
  /* Recursively process the components of X.  */
1141
  fmt = GET_RTX_FORMAT (code);
1142
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1143
    {
1144
      if (fmt[i] == 'e')
1145
        reload_combine_note_use (&XEXP (x, i), insn);
1146
      else if (fmt[i] == 'E')
1147
        {
1148
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1149
            reload_combine_note_use (&XVECEXP (x, i, j), insn);
1150
        }
1151
    }
1152
}
1153
 
1154
/* See if we can reduce the cost of a constant by replacing a move
1155
   with an add.  We track situations in which a register is set to a
1156
   constant or to a register plus a constant.  */
1157
/* We cannot do our optimization across labels.  Invalidating all the
1158
   information about register contents we have would be costly, so we
1159
   use move2add_last_label_luid to note where the label is and then
1160
   later disable any optimization that would cross it.
1161
   reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if
1162
   reg_set_luid[n] is greater than move2add_last_label_luid.  */
1163
static int reg_set_luid[FIRST_PSEUDO_REGISTER];
1164
 
1165
/* If reg_base_reg[n] is negative, register n has been set to
1166
   reg_offset[n] in mode reg_mode[n] .
1167
   If reg_base_reg[n] is non-negative, register n has been set to the
1168
   sum of reg_offset[n] and the value of register reg_base_reg[n]
1169
   before reg_set_luid[n], calculated in mode reg_mode[n] .  */
1170
static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
1171
static int reg_base_reg[FIRST_PSEUDO_REGISTER];
1172
static enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
1173
 
1174
/* move2add_luid is linearly increased while scanning the instructions
1175
   from first to last.  It is used to set reg_set_luid in
1176
   reload_cse_move2add and move2add_note_store.  */
1177
static int move2add_luid;
1178
 
1179
/* move2add_last_label_luid is set whenever a label is found.  Labels
1180
   invalidate all previously collected reg_offset data.  */
1181
static int move2add_last_label_luid;
1182
 
1183
/* ??? We don't know how zero / sign extension is handled, hence we
1184
   can't go from a narrower to a wider mode.  */
1185
#define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
1186
  (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
1187
   || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
1188
       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \
1189
                                 GET_MODE_BITSIZE (INMODE))))
1190
 
1191
static void
1192
reload_cse_move2add (rtx first)
1193
{
1194
  int i;
1195
  rtx insn;
1196
 
1197
  for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
1198
    reg_set_luid[i] = 0;
1199
 
1200
  move2add_last_label_luid = 0;
1201
  move2add_luid = 2;
1202
  for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
1203
    {
1204
      rtx pat, note;
1205
 
1206
      if (LABEL_P (insn))
1207
        {
1208
          move2add_last_label_luid = move2add_luid;
1209
          /* We're going to increment move2add_luid twice after a
1210
             label, so that we can use move2add_last_label_luid + 1 as
1211
             the luid for constants.  */
1212
          move2add_luid++;
1213
          continue;
1214
        }
1215
      if (! INSN_P (insn))
1216
        continue;
1217
      pat = PATTERN (insn);
1218
      /* For simplicity, we only perform this optimization on
1219
         straightforward SETs.  */
1220
      if (GET_CODE (pat) == SET
1221
          && REG_P (SET_DEST (pat)))
1222
        {
1223
          rtx reg = SET_DEST (pat);
1224
          int regno = REGNO (reg);
1225
          rtx src = SET_SRC (pat);
1226
 
1227
          /* Check if we have valid information on the contents of this
1228
             register in the mode of REG.  */
1229
          if (reg_set_luid[regno] > move2add_last_label_luid
1230
              && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno]))
1231
            {
1232
              /* Try to transform (set (REGX) (CONST_INT A))
1233
                                  ...
1234
                                  (set (REGX) (CONST_INT B))
1235
                 to
1236
                                  (set (REGX) (CONST_INT A))
1237
                                  ...
1238
                                  (set (REGX) (plus (REGX) (CONST_INT B-A)))
1239
                 or
1240
                                  (set (REGX) (CONST_INT A))
1241
                                  ...
1242
                                  (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
1243
              */
1244
 
1245
              if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
1246
                {
1247
                  rtx new_src = gen_int_mode (INTVAL (src) - reg_offset[regno],
1248
                                              GET_MODE (reg));
1249
                  /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
1250
                     use (set (reg) (reg)) instead.
1251
                     We don't delete this insn, nor do we convert it into a
1252
                     note, to avoid losing register notes or the return
1253
                     value flag.  jump2 already knows how to get rid of
1254
                     no-op moves.  */
1255
                  if (new_src == const0_rtx)
1256
                    {
1257
                      /* If the constants are different, this is a
1258
                         truncation, that, if turned into (set (reg)
1259
                         (reg)), would be discarded.  Maybe we should
1260
                         try a truncMN pattern?  */
1261
                      if (INTVAL (src) == reg_offset [regno])
1262
                        validate_change (insn, &SET_SRC (pat), reg, 0);
1263
                    }
1264
                  else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
1265
                           && have_add2_insn (reg, new_src))
1266
                    {
1267
                      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
1268
                      validate_change (insn, &SET_SRC (pat), tem, 0);
1269
                    }
1270
                  else if (GET_MODE (reg) != BImode)
1271
                    {
1272
                      enum machine_mode narrow_mode;
1273
                      for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1274
                           narrow_mode != VOIDmode
1275
                           && narrow_mode != GET_MODE (reg);
1276
                           narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
1277
                        {
1278
                          if (have_insn_for (STRICT_LOW_PART, narrow_mode)
1279
                              && ((reg_offset[regno]
1280
                                   & ~GET_MODE_MASK (narrow_mode))
1281
                                  == (INTVAL (src)
1282
                                      & ~GET_MODE_MASK (narrow_mode))))
1283
                            {
1284
                              rtx narrow_reg = gen_rtx_REG (narrow_mode,
1285
                                                            REGNO (reg));
1286
                              rtx narrow_src = gen_int_mode (INTVAL (src),
1287
                                                             narrow_mode);
1288
                              rtx new_set =
1289
                                gen_rtx_SET (VOIDmode,
1290
                                             gen_rtx_STRICT_LOW_PART (VOIDmode,
1291
                                                                      narrow_reg),
1292
                                             narrow_src);
1293
                              if (validate_change (insn, &PATTERN (insn),
1294
                                                   new_set, 0))
1295
                                break;
1296
                            }
1297
                        }
1298
                    }
1299
                  reg_set_luid[regno] = move2add_luid;
1300
                  reg_mode[regno] = GET_MODE (reg);
1301
                  reg_offset[regno] = INTVAL (src);
1302
                  continue;
1303
                }
1304
 
1305
              /* Try to transform (set (REGX) (REGY))
1306
                                  (set (REGX) (PLUS (REGX) (CONST_INT A)))
1307
                                  ...
1308
                                  (set (REGX) (REGY))
1309
                                  (set (REGX) (PLUS (REGX) (CONST_INT B)))
1310
                 to
1311
                                  (set (REGX) (REGY))
1312
                                  (set (REGX) (PLUS (REGX) (CONST_INT A)))
1313
                                  ...
1314
                                  (set (REGX) (plus (REGX) (CONST_INT B-A)))  */
1315
              else if (REG_P (src)
1316
                       && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
1317
                       && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
1318
                       && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
1319
                                                 reg_mode[REGNO (src)]))
1320
                {
1321
                  rtx next = next_nonnote_insn (insn);
1322
                  rtx set = NULL_RTX;
1323
                  if (next)
1324
                    set = single_set (next);
1325
                  if (set
1326
                      && SET_DEST (set) == reg
1327
                      && GET_CODE (SET_SRC (set)) == PLUS
1328
                      && XEXP (SET_SRC (set), 0) == reg
1329
                      && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
1330
                    {
1331
                      rtx src3 = XEXP (SET_SRC (set), 1);
1332
                      HOST_WIDE_INT added_offset = INTVAL (src3);
1333
                      HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
1334
                      HOST_WIDE_INT regno_offset = reg_offset[regno];
1335
                      rtx new_src =
1336
                        gen_int_mode (added_offset
1337
                                      + base_offset
1338
                                      - regno_offset,
1339
                                      GET_MODE (reg));
1340
                      int success = 0;
1341
 
1342
                      if (new_src == const0_rtx)
1343
                        /* See above why we create (set (reg) (reg)) here.  */
1344
                        success
1345
                          = validate_change (next, &SET_SRC (set), reg, 0);
1346
                      else if ((rtx_cost (new_src, PLUS)
1347
                                < COSTS_N_INSNS (1) + rtx_cost (src3, SET))
1348
                               && have_add2_insn (reg, new_src))
1349
                        {
1350
                          rtx newpat = gen_rtx_SET (VOIDmode,
1351
                                                    reg,
1352
                                                    gen_rtx_PLUS (GET_MODE (reg),
1353
                                                                  reg,
1354
                                                                  new_src));
1355
                          success
1356
                            = validate_change (next, &PATTERN (next),
1357
                                               newpat, 0);
1358
                        }
1359
                      if (success)
1360
                        delete_insn (insn);
1361
                      insn = next;
1362
                      reg_mode[regno] = GET_MODE (reg);
1363
                      reg_offset[regno] =
1364
                        trunc_int_for_mode (added_offset + base_offset,
1365
                                            GET_MODE (reg));
1366
                      continue;
1367
                    }
1368
                }
1369
            }
1370
        }
1371
 
1372
      for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
1373
        {
1374
          if (REG_NOTE_KIND (note) == REG_INC
1375
              && REG_P (XEXP (note, 0)))
1376
            {
1377
              /* Reset the information about this register.  */
1378
              int regno = REGNO (XEXP (note, 0));
1379
              if (regno < FIRST_PSEUDO_REGISTER)
1380
                reg_set_luid[regno] = 0;
1381
            }
1382
        }
1383
      note_stores (PATTERN (insn), move2add_note_store, NULL);
1384
 
1385
      /* If INSN is a conditional branch, we try to extract an
1386
         implicit set out of it.  */
1387
      if (any_condjump_p (insn))
1388
        {
1389
          rtx cnd = fis_get_condition (insn);
1390
 
1391
          if (cnd != NULL_RTX
1392
              && GET_CODE (cnd) == NE
1393
              && REG_P (XEXP (cnd, 0))
1394
              && !reg_set_p (XEXP (cnd, 0), insn)
1395
              /* The following two checks, which are also in
1396
                 move2add_note_store, are intended to reduce the
1397
                 number of calls to gen_rtx_SET to avoid memory
1398
                 allocation if possible.  */
1399
              && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
1400
              && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1
1401
              && GET_CODE (XEXP (cnd, 1)) == CONST_INT)
1402
            {
1403
              rtx implicit_set =
1404
                gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1));
1405
              move2add_note_store (SET_DEST (implicit_set), implicit_set, 0);
1406
            }
1407
        }
1408
 
1409
      /* If this is a CALL_INSN, all call used registers are stored with
1410
         unknown values.  */
1411
      if (CALL_P (insn))
1412
        {
1413
          for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
1414
            {
1415
              if (call_used_regs[i])
1416
                /* Reset the information about this register.  */
1417
                reg_set_luid[i] = 0;
1418
            }
1419
        }
1420
    }
1421
}
1422
 
1423
/* SET is a SET or CLOBBER that sets DST.
1424
   Update reg_set_luid, reg_offset and reg_base_reg accordingly.
1425
   Called from reload_cse_move2add via note_stores.  */
1426
 
1427
static void
1428
move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
1429
{
1430
  unsigned int regno = 0;
1431
  unsigned int i;
1432
  enum machine_mode mode = GET_MODE (dst);
1433
 
1434
  if (GET_CODE (dst) == SUBREG)
1435
    {
1436
      regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
1437
                                   GET_MODE (SUBREG_REG (dst)),
1438
                                   SUBREG_BYTE (dst),
1439
                                   GET_MODE (dst));
1440
      dst = SUBREG_REG (dst);
1441
    }
1442
 
1443
  /* Some targets do argument pushes without adding REG_INC notes.  */
1444
 
1445
  if (MEM_P (dst))
1446
    {
1447
      dst = XEXP (dst, 0);
1448
      if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
1449
          || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
1450
        reg_set_luid[REGNO (XEXP (dst, 0))] = 0;
1451
      return;
1452
    }
1453
  if (!REG_P (dst))
1454
    return;
1455
 
1456
  regno += REGNO (dst);
1457
 
1458
  if (SCALAR_INT_MODE_P (GET_MODE (dst))
1459
      && hard_regno_nregs[regno][mode] == 1 && GET_CODE (set) == SET
1460
      && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
1461
      && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
1462
    {
1463
      rtx src = SET_SRC (set);
1464
      rtx base_reg;
1465
      HOST_WIDE_INT offset;
1466
      int base_regno;
1467
      /* This may be different from mode, if SET_DEST (set) is a
1468
         SUBREG.  */
1469
      enum machine_mode dst_mode = GET_MODE (dst);
1470
 
1471
      switch (GET_CODE (src))
1472
        {
1473
        case PLUS:
1474
          if (REG_P (XEXP (src, 0)))
1475
            {
1476
              base_reg = XEXP (src, 0);
1477
 
1478
              if (GET_CODE (XEXP (src, 1)) == CONST_INT)
1479
                offset = INTVAL (XEXP (src, 1));
1480
              else if (REG_P (XEXP (src, 1))
1481
                       && (reg_set_luid[REGNO (XEXP (src, 1))]
1482
                           > move2add_last_label_luid)
1483
                       && (MODES_OK_FOR_MOVE2ADD
1484
                           (dst_mode, reg_mode[REGNO (XEXP (src, 1))])))
1485
                {
1486
                  if (reg_base_reg[REGNO (XEXP (src, 1))] < 0)
1487
                    offset = reg_offset[REGNO (XEXP (src, 1))];
1488
                  /* Maybe the first register is known to be a
1489
                     constant.  */
1490
                  else if (reg_set_luid[REGNO (base_reg)]
1491
                           > move2add_last_label_luid
1492
                           && (MODES_OK_FOR_MOVE2ADD
1493
                               (dst_mode, reg_mode[REGNO (XEXP (src, 1))]))
1494
                           && reg_base_reg[REGNO (base_reg)] < 0)
1495
                    {
1496
                      offset = reg_offset[REGNO (base_reg)];
1497
                      base_reg = XEXP (src, 1);
1498
                    }
1499
                  else
1500
                    goto invalidate;
1501
                }
1502
              else
1503
                goto invalidate;
1504
 
1505
              break;
1506
            }
1507
 
1508
          goto invalidate;
1509
 
1510
        case REG:
1511
          base_reg = src;
1512
          offset = 0;
1513
          break;
1514
 
1515
        case CONST_INT:
1516
          /* Start tracking the register as a constant.  */
1517
          reg_base_reg[regno] = -1;
1518
          reg_offset[regno] = INTVAL (SET_SRC (set));
1519
          /* We assign the same luid to all registers set to constants.  */
1520
          reg_set_luid[regno] = move2add_last_label_luid + 1;
1521
          reg_mode[regno] = mode;
1522
          return;
1523
 
1524
        default:
1525
        invalidate:
1526
          /* Invalidate the contents of the register.  */
1527
          reg_set_luid[regno] = 0;
1528
          return;
1529
        }
1530
 
1531
      base_regno = REGNO (base_reg);
1532
      /* If information about the base register is not valid, set it
1533
         up as a new base register, pretending its value is known
1534
         starting from the current insn.  */
1535
      if (reg_set_luid[base_regno] <= move2add_last_label_luid)
1536
        {
1537
          reg_base_reg[base_regno] = base_regno;
1538
          reg_offset[base_regno] = 0;
1539
          reg_set_luid[base_regno] = move2add_luid;
1540
          reg_mode[base_regno] = mode;
1541
        }
1542
      else if (! MODES_OK_FOR_MOVE2ADD (dst_mode,
1543
                                        reg_mode[base_regno]))
1544
        goto invalidate;
1545
 
1546
      reg_mode[regno] = mode;
1547
 
1548
      /* Copy base information from our base register.  */
1549
      reg_set_luid[regno] = reg_set_luid[base_regno];
1550
      reg_base_reg[regno] = reg_base_reg[base_regno];
1551
 
1552
      /* Compute the sum of the offsets or constants.  */
1553
      reg_offset[regno] = trunc_int_for_mode (offset
1554
                                              + reg_offset[base_regno],
1555
                                              dst_mode);
1556
    }
1557
  else
1558
    {
1559
      unsigned int endregno = regno + hard_regno_nregs[regno][mode];
1560
 
1561
      for (i = regno; i < endregno; i++)
1562
        /* Reset the information about this register.  */
1563
        reg_set_luid[i] = 0;
1564
    }
1565
}
1566
 
1567
static bool
1568
gate_handle_postreload (void)
1569
{
1570
  return (optimize > 0);
1571
}
1572
 
1573
 
1574
static unsigned int
1575
rest_of_handle_postreload (void)
1576
{
1577
  /* Do a very simple CSE pass over just the hard registers.  */
1578
  reload_cse_regs (get_insns ());
1579
  /* reload_cse_regs can eliminate potentially-trapping MEMs.
1580
     Remove any EH edges associated with them.  */
1581
  if (flag_non_call_exceptions)
1582
    purge_all_dead_edges ();
1583
  return 0;
1584
}
1585
 
1586
struct tree_opt_pass pass_postreload_cse =
1587
{
1588
  "postreload",                         /* name */
1589
  gate_handle_postreload,               /* gate */
1590
  rest_of_handle_postreload,            /* execute */
1591
  NULL,                                 /* sub */
1592
  NULL,                                 /* next */
1593
  0,                                    /* static_pass_number */
1594
  TV_RELOAD_CSE_REGS,                   /* tv_id */
1595
  0,                                    /* properties_required */
1596
  0,                                    /* properties_provided */
1597
  0,                                    /* properties_destroyed */
1598
  0,                                    /* todo_flags_start */
1599
  TODO_dump_func,                       /* todo_flags_finish */
1600
  'o'                                   /* letter */
1601
};
1602
 

powered by: WebSVN 2.1.0

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