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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [var-tracking.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Variable tracking routines for the GNU compiler.
2
   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
3
   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
8
   under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GCC is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License 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
/* This file contains the variable tracking pass.  It computes where
22
   variables are located (which registers or where in memory) at each position
23
   in instruction stream and emits notes describing the locations.
24
   Debug information (DWARF2 location lists) is finally generated from
25
   these notes.
26
   With this debug information, it is possible to show variables
27
   even when debugging optimized code.
28
 
29
   How does the variable tracking pass work?
30
 
31
   First, it scans RTL code for uses, stores and clobbers (register/memory
32
   references in instructions), for call insns and for stack adjustments
33
   separately for each basic block and saves them to an array of micro
34
   operations.
35
   The micro operations of one instruction are ordered so that
36
   pre-modifying stack adjustment < use < use with no var < call insn <
37
     < clobber < set < post-modifying stack adjustment
38
 
39
   Then, a forward dataflow analysis is performed to find out how locations
40
   of variables change through code and to propagate the variable locations
41
   along control flow graph.
42
   The IN set for basic block BB is computed as a union of OUT sets of BB's
43
   predecessors, the OUT set for BB is copied from the IN set for BB and
44
   is changed according to micro operations in BB.
45
 
46
   The IN and OUT sets for basic blocks consist of a current stack adjustment
47
   (used for adjusting offset of variables addressed using stack pointer),
48
   the table of structures describing the locations of parts of a variable
49
   and for each physical register a linked list for each physical register.
50
   The linked list is a list of variable parts stored in the register,
51
   i.e. it is a list of triplets (reg, decl, offset) where decl is
52
   REG_EXPR (reg) and offset is REG_OFFSET (reg).  The linked list is used for
53
   effective deleting appropriate variable parts when we set or clobber the
54
   register.
55
 
56
   There may be more than one variable part in a register.  The linked lists
57
   should be pretty short so it is a good data structure here.
58
   For example in the following code, register allocator may assign same
59
   register to variables A and B, and both of them are stored in the same
60
   register in CODE:
61
 
62
     if (cond)
63
       set A;
64
     else
65
       set B;
66
     CODE;
67
     if (cond)
68
       use A;
69
     else
70
       use B;
71
 
72
   Finally, the NOTE_INSN_VAR_LOCATION notes describing the variable locations
73
   are emitted to appropriate positions in RTL code.  Each such a note describes
74
   the location of one variable at the point in instruction stream where the
75
   note is.  There is no need to emit a note for each variable before each
76
   instruction, we only emit these notes where the location of variable changes
77
   (this means that we also emit notes for changes between the OUT set of the
78
   previous block and the IN set of the current block).
79
 
80
   The notes consist of two parts:
81
   1. the declaration (from REG_EXPR or MEM_EXPR)
82
   2. the location of a variable - it is either a simple register/memory
83
      reference (for simple variables, for example int),
84
      or a parallel of register/memory references (for a large variables
85
      which consist of several parts, for example long long).
86
 
87
*/
88
 
89
#include "config.h"
90
#include "system.h"
91
#include "coretypes.h"
92
#include "tm.h"
93
#include "rtl.h"
94
#include "tree.h"
95
#include "tm_p.h"
96
#include "hard-reg-set.h"
97
#include "basic-block.h"
98
#include "flags.h"
99
#include "output.h"
100
#include "insn-config.h"
101
#include "reload.h"
102
#include "sbitmap.h"
103
#include "alloc-pool.h"
104
#include "fibheap.h"
105
#include "hashtab.h"
106
#include "regs.h"
107
#include "expr.h"
108
#include "timevar.h"
109
#include "tree-pass.h"
110
#include "tree-flow.h"
111
#include "cselib.h"
112
#include "target.h"
113
#include "params.h"
114
#include "diagnostic.h"
115
#include "tree-pretty-print.h"
116
#include "pointer-set.h"
117
#include "recog.h"
118
#include "tm_p.h"
119
 
120
/* var-tracking.c assumes that tree code with the same value as VALUE rtx code
121
   has no chance to appear in REG_EXPR/MEM_EXPRs and isn't a decl.
122
   Currently the value is the same as IDENTIFIER_NODE, which has such
123
   a property.  If this compile time assertion ever fails, make sure that
124
   the new tree code that equals (int) VALUE has the same property.  */
125
extern char check_value_val[(int) VALUE == (int) IDENTIFIER_NODE ? 1 : -1];
126
 
127
/* Type of micro operation.  */
128
enum micro_operation_type
129
{
130
  MO_USE,       /* Use location (REG or MEM).  */
131
  MO_USE_NO_VAR,/* Use location which is not associated with a variable
132
                   or the variable is not trackable.  */
133
  MO_VAL_USE,   /* Use location which is associated with a value.  */
134
  MO_VAL_LOC,   /* Use location which appears in a debug insn.  */
135
  MO_VAL_SET,   /* Set location associated with a value.  */
136
  MO_SET,       /* Set location.  */
137
  MO_COPY,      /* Copy the same portion of a variable from one
138
                   location to another.  */
139
  MO_CLOBBER,   /* Clobber location.  */
140
  MO_CALL,      /* Call insn.  */
141
  MO_ADJUST     /* Adjust stack pointer.  */
142
 
143
};
144
 
145
static const char * const ATTRIBUTE_UNUSED
146
micro_operation_type_name[] = {
147
  "MO_USE",
148
  "MO_USE_NO_VAR",
149
  "MO_VAL_USE",
150
  "MO_VAL_LOC",
151
  "MO_VAL_SET",
152
  "MO_SET",
153
  "MO_COPY",
154
  "MO_CLOBBER",
155
  "MO_CALL",
156
  "MO_ADJUST"
157
};
158
 
159
/* Where shall the note be emitted?  BEFORE or AFTER the instruction.
160
   Notes emitted as AFTER_CALL are to take effect during the call,
161
   rather than after the call.  */
162
enum emit_note_where
163
{
164
  EMIT_NOTE_BEFORE_INSN,
165
  EMIT_NOTE_AFTER_INSN,
166
  EMIT_NOTE_AFTER_CALL_INSN
167
};
168
 
169
/* Structure holding information about micro operation.  */
170
typedef struct micro_operation_def
171
{
172
  /* Type of micro operation.  */
173
  enum micro_operation_type type;
174
 
175
  /* The instruction which the micro operation is in, for MO_USE,
176
     MO_USE_NO_VAR, MO_CALL and MO_ADJUST, or the subsequent
177
     instruction or note in the original flow (before any var-tracking
178
     notes are inserted, to simplify emission of notes), for MO_SET
179
     and MO_CLOBBER.  */
180
  rtx insn;
181
 
182
  union {
183
    /* Location.  For MO_SET and MO_COPY, this is the SET that
184
       performs the assignment, if known, otherwise it is the target
185
       of the assignment.  For MO_VAL_USE and MO_VAL_SET, it is a
186
       CONCAT of the VALUE and the LOC associated with it.  For
187
       MO_VAL_LOC, it is a CONCAT of the VALUE and the VAR_LOCATION
188
       associated with it.  */
189
    rtx loc;
190
 
191
    /* Stack adjustment.  */
192
    HOST_WIDE_INT adjust;
193
  } u;
194
} micro_operation;
195
 
196
DEF_VEC_O(micro_operation);
197
DEF_VEC_ALLOC_O(micro_operation,heap);
198
 
199
/* A declaration of a variable, or an RTL value being handled like a
200
   declaration.  */
201
typedef void *decl_or_value;
202
 
203
/* Structure for passing some other parameters to function
204
   emit_note_insn_var_location.  */
205
typedef struct emit_note_data_def
206
{
207
  /* The instruction which the note will be emitted before/after.  */
208
  rtx insn;
209
 
210
  /* Where the note will be emitted (before/after insn)?  */
211
  enum emit_note_where where;
212
 
213
  /* The variables and values active at this point.  */
214
  htab_t vars;
215
} emit_note_data;
216
 
217
/* Description of location of a part of a variable.  The content of a physical
218
   register is described by a chain of these structures.
219
   The chains are pretty short (usually 1 or 2 elements) and thus
220
   chain is the best data structure.  */
221
typedef struct attrs_def
222
{
223
  /* Pointer to next member of the list.  */
224
  struct attrs_def *next;
225
 
226
  /* The rtx of register.  */
227
  rtx loc;
228
 
229
  /* The declaration corresponding to LOC.  */
230
  decl_or_value dv;
231
 
232
  /* Offset from start of DECL.  */
233
  HOST_WIDE_INT offset;
234
} *attrs;
235
 
236
/* Structure holding a refcounted hash table.  If refcount > 1,
237
   it must be first unshared before modified.  */
238
typedef struct shared_hash_def
239
{
240
  /* Reference count.  */
241
  int refcount;
242
 
243
  /* Actual hash table.  */
244
  htab_t htab;
245
} *shared_hash;
246
 
247
/* Structure holding the IN or OUT set for a basic block.  */
248
typedef struct dataflow_set_def
249
{
250
  /* Adjustment of stack offset.  */
251
  HOST_WIDE_INT stack_adjust;
252
 
253
  /* Attributes for registers (lists of attrs).  */
254
  attrs regs[FIRST_PSEUDO_REGISTER];
255
 
256
  /* Variable locations.  */
257
  shared_hash vars;
258
 
259
  /* Vars that is being traversed.  */
260
  shared_hash traversed_vars;
261
} dataflow_set;
262
 
263
/* The structure (one for each basic block) containing the information
264
   needed for variable tracking.  */
265
typedef struct variable_tracking_info_def
266
{
267
  /* The vector of micro operations.  */
268
  VEC(micro_operation, heap) *mos;
269
 
270
  /* The IN and OUT set for dataflow analysis.  */
271
  dataflow_set in;
272
  dataflow_set out;
273
 
274
  /* The permanent-in dataflow set for this block.  This is used to
275
     hold values for which we had to compute entry values.  ??? This
276
     should probably be dynamically allocated, to avoid using more
277
     memory in non-debug builds.  */
278
  dataflow_set *permp;
279
 
280
  /* Has the block been visited in DFS?  */
281
  bool visited;
282
 
283
  /* Has the block been flooded in VTA?  */
284
  bool flooded;
285
 
286
} *variable_tracking_info;
287
 
288
/* Structure for chaining the locations.  */
289
typedef struct location_chain_def
290
{
291
  /* Next element in the chain.  */
292
  struct location_chain_def *next;
293
 
294
  /* The location (REG, MEM or VALUE).  */
295
  rtx loc;
296
 
297
  /* The "value" stored in this location.  */
298
  rtx set_src;
299
 
300
  /* Initialized? */
301
  enum var_init_status init;
302
} *location_chain;
303
 
304
/* A vector of loc_exp_dep holds the active dependencies of a one-part
305
   DV on VALUEs, i.e., the VALUEs expanded so as to form the current
306
   location of DV.  Each entry is also part of VALUE' s linked-list of
307
   backlinks back to DV.  */
308
typedef struct loc_exp_dep_s
309
{
310
  /* The dependent DV.  */
311
  decl_or_value dv;
312
  /* The dependency VALUE or DECL_DEBUG.  */
313
  rtx value;
314
  /* The next entry in VALUE's backlinks list.  */
315
  struct loc_exp_dep_s *next;
316
  /* A pointer to the pointer to this entry (head or prev's next) in
317
     the doubly-linked list.  */
318
  struct loc_exp_dep_s **pprev;
319
} loc_exp_dep;
320
 
321
DEF_VEC_O (loc_exp_dep);
322
 
323
/* This data structure is allocated for one-part variables at the time
324
   of emitting notes.  */
325
struct onepart_aux
326
{
327
  /* Doubly-linked list of dependent DVs.  These are DVs whose cur_loc
328
     computation used the expansion of this variable, and that ought
329
     to be notified should this variable change.  If the DV's cur_loc
330
     expanded to NULL, all components of the loc list are regarded as
331
     active, so that any changes in them give us a chance to get a
332
     location.  Otherwise, only components of the loc that expanded to
333
     non-NULL are regarded as active dependencies.  */
334
  loc_exp_dep *backlinks;
335
  /* This holds the LOC that was expanded into cur_loc.  We need only
336
     mark a one-part variable as changed if the FROM loc is removed,
337
     or if it has no known location and a loc is added, or if it gets
338
     a change notification from any of its active dependencies.  */
339
  rtx from;
340
  /* The depth of the cur_loc expression.  */
341
  int depth;
342
  /* Dependencies actively used when expand FROM into cur_loc.  */
343
  VEC (loc_exp_dep, none) deps;
344
};
345
 
346
/* Structure describing one part of variable.  */
347
typedef struct variable_part_def
348
{
349
  /* Chain of locations of the part.  */
350
  location_chain loc_chain;
351
 
352
  /* Location which was last emitted to location list.  */
353
  rtx cur_loc;
354
 
355
  union variable_aux
356
  {
357
    /* The offset in the variable, if !var->onepart.  */
358
    HOST_WIDE_INT offset;
359
 
360
    /* Pointer to auxiliary data, if var->onepart and emit_notes.  */
361
    struct onepart_aux *onepaux;
362
  } aux;
363
} variable_part;
364
 
365
/* Maximum number of location parts.  */
366
#define MAX_VAR_PARTS 16
367
 
368
/* Enumeration type used to discriminate various types of one-part
369
   variables.  */
370
typedef enum onepart_enum
371
{
372
  /* Not a one-part variable.  */
373
  NOT_ONEPART = 0,
374
  /* A one-part DECL that is not a DEBUG_EXPR_DECL.  */
375
  ONEPART_VDECL = 1,
376
  /* A DEBUG_EXPR_DECL.  */
377
  ONEPART_DEXPR = 2,
378
  /* A VALUE.  */
379
  ONEPART_VALUE = 3
380
} onepart_enum_t;
381
 
382
/* Structure describing where the variable is located.  */
383
typedef struct variable_def
384
{
385
  /* The declaration of the variable, or an RTL value being handled
386
     like a declaration.  */
387
  decl_or_value dv;
388
 
389
  /* Reference count.  */
390
  int refcount;
391
 
392
  /* Number of variable parts.  */
393
  char n_var_parts;
394
 
395
  /* What type of DV this is, according to enum onepart_enum.  */
396
  ENUM_BITFIELD (onepart_enum) onepart : CHAR_BIT;
397
 
398
  /* True if this variable_def struct is currently in the
399
     changed_variables hash table.  */
400
  bool in_changed_variables;
401
 
402
  /* The variable parts.  */
403
  variable_part var_part[1];
404
} *variable;
405
typedef const struct variable_def *const_variable;
406
 
407
/* Pointer to the BB's information specific to variable tracking pass.  */
408
#define VTI(BB) ((variable_tracking_info) (BB)->aux)
409
 
410
/* Macro to access MEM_OFFSET as an HOST_WIDE_INT.  Evaluates MEM twice.  */
411
#define INT_MEM_OFFSET(mem) (MEM_OFFSET_KNOWN_P (mem) ? MEM_OFFSET (mem) : 0)
412
 
413
#if ENABLE_CHECKING && (GCC_VERSION >= 2007)
414
 
415
/* Access VAR's Ith part's offset, checking that it's not a one-part
416
   variable.  */
417
#define VAR_PART_OFFSET(var, i) __extension__                   \
418
(*({  variable const __v = (var);                               \
419
      gcc_checking_assert (!__v->onepart);                      \
420
      &__v->var_part[(i)].aux.offset; }))
421
 
422
/* Access VAR's one-part auxiliary data, checking that it is a
423
   one-part variable.  */
424
#define VAR_LOC_1PAUX(var) __extension__                        \
425
(*({  variable const __v = (var);                               \
426
      gcc_checking_assert (__v->onepart);                       \
427
      &__v->var_part[0].aux.onepaux; }))
428
 
429
#else
430
#define VAR_PART_OFFSET(var, i) ((var)->var_part[(i)].aux.offset)
431
#define VAR_LOC_1PAUX(var) ((var)->var_part[0].aux.onepaux)
432
#endif
433
 
434
/* These are accessor macros for the one-part auxiliary data.  When
435
   convenient for users, they're guarded by tests that the data was
436
   allocated.  */
437
#define VAR_LOC_DEP_LST(var) (VAR_LOC_1PAUX (var)                 \
438
                              ? VAR_LOC_1PAUX (var)->backlinks    \
439
                              : NULL)
440
#define VAR_LOC_DEP_LSTP(var) (VAR_LOC_1PAUX (var)                \
441
                               ? &VAR_LOC_1PAUX (var)->backlinks  \
442
                               : NULL)
443
#define VAR_LOC_FROM(var) (VAR_LOC_1PAUX (var)->from)
444
#define VAR_LOC_DEPTH(var) (VAR_LOC_1PAUX (var)->depth)
445
#define VAR_LOC_DEP_VEC(var) (VAR_LOC_1PAUX (var)                 \
446
                              ? &VAR_LOC_1PAUX (var)->deps        \
447
                              : NULL)
448
 
449
/* Alloc pool for struct attrs_def.  */
450
static alloc_pool attrs_pool;
451
 
452
/* Alloc pool for struct variable_def with MAX_VAR_PARTS entries.  */
453
static alloc_pool var_pool;
454
 
455
/* Alloc pool for struct variable_def with a single var_part entry.  */
456
static alloc_pool valvar_pool;
457
 
458
/* Alloc pool for struct location_chain_def.  */
459
static alloc_pool loc_chain_pool;
460
 
461
/* Alloc pool for struct shared_hash_def.  */
462
static alloc_pool shared_hash_pool;
463
 
464
/* Changed variables, notes will be emitted for them.  */
465
static htab_t changed_variables;
466
 
467
/* Shall notes be emitted?  */
468
static bool emit_notes;
469
 
470
/* Values whose dynamic location lists have gone empty, but whose
471
   cselib location lists are still usable.  Use this to hold the
472
   current location, the backlinks, etc, during emit_notes.  */
473
static htab_t dropped_values;
474
 
475
/* Empty shared hashtable.  */
476
static shared_hash empty_shared_hash;
477
 
478
/* Scratch register bitmap used by cselib_expand_value_rtx.  */
479
static bitmap scratch_regs = NULL;
480
 
481
#ifdef HAVE_window_save
482
typedef struct GTY(()) parm_reg {
483
  rtx outgoing;
484
  rtx incoming;
485
} parm_reg_t;
486
 
487
DEF_VEC_O(parm_reg_t);
488
DEF_VEC_ALLOC_O(parm_reg_t, gc);
489
 
490
/* Vector of windowed parameter registers, if any.  */
491
static VEC(parm_reg_t, gc) *windowed_parm_regs = NULL;
492
#endif
493
 
494
/* Variable used to tell whether cselib_process_insn called our hook.  */
495
static bool cselib_hook_called;
496
 
497
/* Local function prototypes.  */
498
static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
499
                                          HOST_WIDE_INT *);
500
static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
501
                                               HOST_WIDE_INT *);
502
static bool vt_stack_adjustments (void);
503
static hashval_t variable_htab_hash (const void *);
504
static int variable_htab_eq (const void *, const void *);
505
static void variable_htab_free (void *);
506
 
507
static void init_attrs_list_set (attrs *);
508
static void attrs_list_clear (attrs *);
509
static attrs attrs_list_member (attrs, decl_or_value, HOST_WIDE_INT);
510
static void attrs_list_insert (attrs *, decl_or_value, HOST_WIDE_INT, rtx);
511
static void attrs_list_copy (attrs *, attrs);
512
static void attrs_list_union (attrs *, attrs);
513
 
514
static void **unshare_variable (dataflow_set *set, void **slot, variable var,
515
                                enum var_init_status);
516
static void vars_copy (htab_t, htab_t);
517
static tree var_debug_decl (tree);
518
static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
519
static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
520
                                    enum var_init_status, rtx);
521
static void var_reg_delete (dataflow_set *, rtx, bool);
522
static void var_regno_delete (dataflow_set *, int);
523
static void var_mem_set (dataflow_set *, rtx, enum var_init_status, rtx);
524
static void var_mem_delete_and_set (dataflow_set *, rtx, bool,
525
                                    enum var_init_status, rtx);
526
static void var_mem_delete (dataflow_set *, rtx, bool);
527
 
528
static void dataflow_set_init (dataflow_set *);
529
static void dataflow_set_clear (dataflow_set *);
530
static void dataflow_set_copy (dataflow_set *, dataflow_set *);
531
static int variable_union_info_cmp_pos (const void *, const void *);
532
static void dataflow_set_union (dataflow_set *, dataflow_set *);
533
static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
534
static bool canon_value_cmp (rtx, rtx);
535
static int loc_cmp (rtx, rtx);
536
static bool variable_part_different_p (variable_part *, variable_part *);
537
static bool onepart_variable_different_p (variable, variable);
538
static bool variable_different_p (variable, variable);
539
static bool dataflow_set_different (dataflow_set *, dataflow_set *);
540
static void dataflow_set_destroy (dataflow_set *);
541
 
542
static bool contains_symbol_ref (rtx);
543
static bool track_expr_p (tree, bool);
544
static bool same_variable_part_p (rtx, tree, HOST_WIDE_INT);
545
static int add_uses (rtx *, void *);
546
static void add_uses_1 (rtx *, void *);
547
static void add_stores (rtx, const_rtx, void *);
548
static bool compute_bb_dataflow (basic_block);
549
static bool vt_find_locations (void);
550
 
551
static void dump_attrs_list (attrs);
552
static int dump_var_slot (void **, void *);
553
static void dump_var (variable);
554
static void dump_vars (htab_t);
555
static void dump_dataflow_set (dataflow_set *);
556
static void dump_dataflow_sets (void);
557
 
558
static void set_dv_changed (decl_or_value, bool);
559
static void variable_was_changed (variable, dataflow_set *);
560
static void **set_slot_part (dataflow_set *, rtx, void **,
561
                             decl_or_value, HOST_WIDE_INT,
562
                             enum var_init_status, rtx);
563
static void set_variable_part (dataflow_set *, rtx,
564
                               decl_or_value, HOST_WIDE_INT,
565
                               enum var_init_status, rtx, enum insert_option);
566
static void **clobber_slot_part (dataflow_set *, rtx,
567
                                 void **, HOST_WIDE_INT, rtx);
568
static void clobber_variable_part (dataflow_set *, rtx,
569
                                   decl_or_value, HOST_WIDE_INT, rtx);
570
static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
571
static void delete_variable_part (dataflow_set *, rtx,
572
                                  decl_or_value, HOST_WIDE_INT);
573
static int emit_note_insn_var_location (void **, void *);
574
static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
575
static int emit_notes_for_differences_1 (void **, void *);
576
static int emit_notes_for_differences_2 (void **, void *);
577
static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
578
static void emit_notes_in_bb (basic_block, dataflow_set *);
579
static void vt_emit_notes (void);
580
 
581
static bool vt_get_decl_and_offset (rtx, tree *, HOST_WIDE_INT *);
582
static void vt_add_function_parameters (void);
583
static bool vt_initialize (void);
584
static void vt_finalize (void);
585
 
586
/* Given a SET, calculate the amount of stack adjustment it contains
587
   PRE- and POST-modifying stack pointer.
588
   This function is similar to stack_adjust_offset.  */
589
 
590
static void
591
stack_adjust_offset_pre_post (rtx pattern, HOST_WIDE_INT *pre,
592
                              HOST_WIDE_INT *post)
593
{
594
  rtx src = SET_SRC (pattern);
595
  rtx dest = SET_DEST (pattern);
596
  enum rtx_code code;
597
 
598
  if (dest == stack_pointer_rtx)
599
    {
600
      /* (set (reg sp) (plus (reg sp) (const_int))) */
601
      code = GET_CODE (src);
602
      if (! (code == PLUS || code == MINUS)
603
          || XEXP (src, 0) != stack_pointer_rtx
604
          || !CONST_INT_P (XEXP (src, 1)))
605
        return;
606
 
607
      if (code == MINUS)
608
        *post += INTVAL (XEXP (src, 1));
609
      else
610
        *post -= INTVAL (XEXP (src, 1));
611
    }
612
  else if (MEM_P (dest))
613
    {
614
      /* (set (mem (pre_dec (reg sp))) (foo)) */
615
      src = XEXP (dest, 0);
616
      code = GET_CODE (src);
617
 
618
      switch (code)
619
        {
620
        case PRE_MODIFY:
621
        case POST_MODIFY:
622
          if (XEXP (src, 0) == stack_pointer_rtx)
623
            {
624
              rtx val = XEXP (XEXP (src, 1), 1);
625
              /* We handle only adjustments by constant amount.  */
626
              gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS &&
627
                          CONST_INT_P (val));
628
 
629
              if (code == PRE_MODIFY)
630
                *pre -= INTVAL (val);
631
              else
632
                *post -= INTVAL (val);
633
              break;
634
            }
635
          return;
636
 
637
        case PRE_DEC:
638
          if (XEXP (src, 0) == stack_pointer_rtx)
639
            {
640
              *pre += GET_MODE_SIZE (GET_MODE (dest));
641
              break;
642
            }
643
          return;
644
 
645
        case POST_DEC:
646
          if (XEXP (src, 0) == stack_pointer_rtx)
647
            {
648
              *post += GET_MODE_SIZE (GET_MODE (dest));
649
              break;
650
            }
651
          return;
652
 
653
        case PRE_INC:
654
          if (XEXP (src, 0) == stack_pointer_rtx)
655
            {
656
              *pre -= GET_MODE_SIZE (GET_MODE (dest));
657
              break;
658
            }
659
          return;
660
 
661
        case POST_INC:
662
          if (XEXP (src, 0) == stack_pointer_rtx)
663
            {
664
              *post -= GET_MODE_SIZE (GET_MODE (dest));
665
              break;
666
            }
667
          return;
668
 
669
        default:
670
          return;
671
        }
672
    }
673
}
674
 
675
/* Given an INSN, calculate the amount of stack adjustment it contains
676
   PRE- and POST-modifying stack pointer.  */
677
 
678
static void
679
insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
680
                                   HOST_WIDE_INT *post)
681
{
682
  rtx pattern;
683
 
684
  *pre = 0;
685
  *post = 0;
686
 
687
  pattern = PATTERN (insn);
688
  if (RTX_FRAME_RELATED_P (insn))
689
    {
690
      rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
691
      if (expr)
692
        pattern = XEXP (expr, 0);
693
    }
694
 
695
  if (GET_CODE (pattern) == SET)
696
    stack_adjust_offset_pre_post (pattern, pre, post);
697
  else if (GET_CODE (pattern) == PARALLEL
698
           || GET_CODE (pattern) == SEQUENCE)
699
    {
700
      int i;
701
 
702
      /* There may be stack adjustments inside compound insns.  Search
703
         for them.  */
704
      for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
705
        if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
706
          stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
707
    }
708
}
709
 
710
/* Compute stack adjustments for all blocks by traversing DFS tree.
711
   Return true when the adjustments on all incoming edges are consistent.
712
   Heavily borrowed from pre_and_rev_post_order_compute.  */
713
 
714
static bool
715
vt_stack_adjustments (void)
716
{
717
  edge_iterator *stack;
718
  int sp;
719
 
720
  /* Initialize entry block.  */
721
  VTI (ENTRY_BLOCK_PTR)->visited = true;
722
  VTI (ENTRY_BLOCK_PTR)->in.stack_adjust = INCOMING_FRAME_SP_OFFSET;
723
  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
724
 
725
  /* Allocate stack for back-tracking up CFG.  */
726
  stack = XNEWVEC (edge_iterator, n_basic_blocks + 1);
727
  sp = 0;
728
 
729
  /* Push the first edge on to the stack.  */
730
  stack[sp++] = ei_start (ENTRY_BLOCK_PTR->succs);
731
 
732
  while (sp)
733
    {
734
      edge_iterator ei;
735
      basic_block src;
736
      basic_block dest;
737
 
738
      /* Look at the edge on the top of the stack.  */
739
      ei = stack[sp - 1];
740
      src = ei_edge (ei)->src;
741
      dest = ei_edge (ei)->dest;
742
 
743
      /* Check if the edge destination has been visited yet.  */
744
      if (!VTI (dest)->visited)
745
        {
746
          rtx insn;
747
          HOST_WIDE_INT pre, post, offset;
748
          VTI (dest)->visited = true;
749
          VTI (dest)->in.stack_adjust = offset = VTI (src)->out.stack_adjust;
750
 
751
          if (dest != EXIT_BLOCK_PTR)
752
            for (insn = BB_HEAD (dest);
753
                 insn != NEXT_INSN (BB_END (dest));
754
                 insn = NEXT_INSN (insn))
755
              if (INSN_P (insn))
756
                {
757
                  insn_stack_adjust_offset_pre_post (insn, &pre, &post);
758
                  offset += pre + post;
759
                }
760
 
761
          VTI (dest)->out.stack_adjust = offset;
762
 
763
          if (EDGE_COUNT (dest->succs) > 0)
764
            /* Since the DEST node has been visited for the first
765
               time, check its successors.  */
766
            stack[sp++] = ei_start (dest->succs);
767
        }
768
      else
769
        {
770
          /* Check whether the adjustments on the edges are the same.  */
771
          if (VTI (dest)->in.stack_adjust != VTI (src)->out.stack_adjust)
772
            {
773
              free (stack);
774
              return false;
775
            }
776
 
777
          if (! ei_one_before_end_p (ei))
778
            /* Go to the next edge.  */
779
            ei_next (&stack[sp - 1]);
780
          else
781
            /* Return to previous level if there are no more edges.  */
782
            sp--;
783
        }
784
    }
785
 
786
  free (stack);
787
  return true;
788
}
789
 
790
/* arg_pointer_rtx resp. frame_pointer_rtx if stack_pointer_rtx or
791
   hard_frame_pointer_rtx is being mapped to it and offset for it.  */
792
static rtx cfa_base_rtx;
793
static HOST_WIDE_INT cfa_base_offset;
794
 
795
/* Compute a CFA-based value for an ADJUSTMENT made to stack_pointer_rtx
796
   or hard_frame_pointer_rtx.  */
797
 
798
static inline rtx
799
compute_cfa_pointer (HOST_WIDE_INT adjustment)
800
{
801
  return plus_constant (cfa_base_rtx, adjustment + cfa_base_offset);
802
}
803
 
804
/* Adjustment for hard_frame_pointer_rtx to cfa base reg,
805
   or -1 if the replacement shouldn't be done.  */
806
static HOST_WIDE_INT hard_frame_pointer_adjustment = -1;
807
 
808
/* Data for adjust_mems callback.  */
809
 
810
struct adjust_mem_data
811
{
812
  bool store;
813
  enum machine_mode mem_mode;
814
  HOST_WIDE_INT stack_adjust;
815
  rtx side_effects;
816
};
817
 
818
/* Helper for adjust_mems.  Return 1 if *loc is unsuitable for
819
   transformation of wider mode arithmetics to narrower mode,
820
   -1 if it is suitable and subexpressions shouldn't be
821
   traversed and 0 if it is suitable and subexpressions should
822
   be traversed.  Called through for_each_rtx.  */
823
 
824
static int
825
use_narrower_mode_test (rtx *loc, void *data)
826
{
827
  rtx subreg = (rtx) data;
828
 
829
  if (CONSTANT_P (*loc))
830
    return -1;
831
  switch (GET_CODE (*loc))
832
    {
833
    case REG:
834
      if (cselib_lookup (*loc, GET_MODE (SUBREG_REG (subreg)), 0, VOIDmode))
835
        return 1;
836
      if (!validate_subreg (GET_MODE (subreg), GET_MODE (*loc),
837
                            *loc, subreg_lowpart_offset (GET_MODE (subreg),
838
                                                         GET_MODE (*loc))))
839
        return 1;
840
      return -1;
841
    case PLUS:
842
    case MINUS:
843
    case MULT:
844
      return 0;
845
    case ASHIFT:
846
      if (for_each_rtx (&XEXP (*loc, 0), use_narrower_mode_test, data))
847
        return 1;
848
      else
849
        return -1;
850
    default:
851
      return 1;
852
    }
853
}
854
 
855
/* Transform X into narrower mode MODE from wider mode WMODE.  */
856
 
857
static rtx
858
use_narrower_mode (rtx x, enum machine_mode mode, enum machine_mode wmode)
859
{
860
  rtx op0, op1;
861
  if (CONSTANT_P (x))
862
    return lowpart_subreg (mode, x, wmode);
863
  switch (GET_CODE (x))
864
    {
865
    case REG:
866
      return lowpart_subreg (mode, x, wmode);
867
    case PLUS:
868
    case MINUS:
869
    case MULT:
870
      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
871
      op1 = use_narrower_mode (XEXP (x, 1), mode, wmode);
872
      return simplify_gen_binary (GET_CODE (x), mode, op0, op1);
873
    case ASHIFT:
874
      op0 = use_narrower_mode (XEXP (x, 0), mode, wmode);
875
      return simplify_gen_binary (ASHIFT, mode, op0, XEXP (x, 1));
876
    default:
877
      gcc_unreachable ();
878
    }
879
}
880
 
881
/* Helper function for adjusting used MEMs.  */
882
 
883
static rtx
884
adjust_mems (rtx loc, const_rtx old_rtx, void *data)
885
{
886
  struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
887
  rtx mem, addr = loc, tem;
888
  enum machine_mode mem_mode_save;
889
  bool store_save;
890
  switch (GET_CODE (loc))
891
    {
892
    case REG:
893
      /* Don't do any sp or fp replacements outside of MEM addresses
894
         on the LHS.  */
895
      if (amd->mem_mode == VOIDmode && amd->store)
896
        return loc;
897
      if (loc == stack_pointer_rtx
898
          && !frame_pointer_needed
899
          && cfa_base_rtx)
900
        return compute_cfa_pointer (amd->stack_adjust);
901
      else if (loc == hard_frame_pointer_rtx
902
               && frame_pointer_needed
903
               && hard_frame_pointer_adjustment != -1
904
               && cfa_base_rtx)
905
        return compute_cfa_pointer (hard_frame_pointer_adjustment);
906
      gcc_checking_assert (loc != virtual_incoming_args_rtx);
907
      return loc;
908
    case MEM:
909
      mem = loc;
910
      if (!amd->store)
911
        {
912
          mem = targetm.delegitimize_address (mem);
913
          if (mem != loc && !MEM_P (mem))
914
            return simplify_replace_fn_rtx (mem, old_rtx, adjust_mems, data);
915
        }
916
 
917
      addr = XEXP (mem, 0);
918
      mem_mode_save = amd->mem_mode;
919
      amd->mem_mode = GET_MODE (mem);
920
      store_save = amd->store;
921
      amd->store = false;
922
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
923
      amd->store = store_save;
924
      amd->mem_mode = mem_mode_save;
925
      if (mem == loc)
926
        addr = targetm.delegitimize_address (addr);
927
      if (addr != XEXP (mem, 0))
928
        mem = replace_equiv_address_nv (mem, addr);
929
      if (!amd->store)
930
        mem = avoid_constant_pool_reference (mem);
931
      return mem;
932
    case PRE_INC:
933
    case PRE_DEC:
934
      addr = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
935
                           GEN_INT (GET_CODE (loc) == PRE_INC
936
                                    ? GET_MODE_SIZE (amd->mem_mode)
937
                                    : -GET_MODE_SIZE (amd->mem_mode)));
938
    case POST_INC:
939
    case POST_DEC:
940
      if (addr == loc)
941
        addr = XEXP (loc, 0);
942
      gcc_assert (amd->mem_mode != VOIDmode && amd->mem_mode != BLKmode);
943
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
944
      tem = gen_rtx_PLUS (GET_MODE (loc), XEXP (loc, 0),
945
                           GEN_INT ((GET_CODE (loc) == PRE_INC
946
                                     || GET_CODE (loc) == POST_INC)
947
                                    ? GET_MODE_SIZE (amd->mem_mode)
948
                                    : -GET_MODE_SIZE (amd->mem_mode)));
949
      amd->side_effects = alloc_EXPR_LIST (0,
950
                                           gen_rtx_SET (VOIDmode,
951
                                                        XEXP (loc, 0),
952
                                                        tem),
953
                                           amd->side_effects);
954
      return addr;
955
    case PRE_MODIFY:
956
      addr = XEXP (loc, 1);
957
    case POST_MODIFY:
958
      if (addr == loc)
959
        addr = XEXP (loc, 0);
960
      gcc_assert (amd->mem_mode != VOIDmode);
961
      addr = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
962
      amd->side_effects = alloc_EXPR_LIST (0,
963
                                           gen_rtx_SET (VOIDmode,
964
                                                        XEXP (loc, 0),
965
                                                        XEXP (loc, 1)),
966
                                           amd->side_effects);
967
      return addr;
968
    case SUBREG:
969
      /* First try without delegitimization of whole MEMs and
970
         avoid_constant_pool_reference, which is more likely to succeed.  */
971
      store_save = amd->store;
972
      amd->store = true;
973
      addr = simplify_replace_fn_rtx (SUBREG_REG (loc), old_rtx, adjust_mems,
974
                                      data);
975
      amd->store = store_save;
976
      mem = simplify_replace_fn_rtx (addr, old_rtx, adjust_mems, data);
977
      if (mem == SUBREG_REG (loc))
978
        {
979
          tem = loc;
980
          goto finish_subreg;
981
        }
982
      tem = simplify_gen_subreg (GET_MODE (loc), mem,
983
                                 GET_MODE (SUBREG_REG (loc)),
984
                                 SUBREG_BYTE (loc));
985
      if (tem)
986
        goto finish_subreg;
987
      tem = simplify_gen_subreg (GET_MODE (loc), addr,
988
                                 GET_MODE (SUBREG_REG (loc)),
989
                                 SUBREG_BYTE (loc));
990
      if (tem == NULL_RTX)
991
        tem = gen_rtx_raw_SUBREG (GET_MODE (loc), addr, SUBREG_BYTE (loc));
992
    finish_subreg:
993
      if (MAY_HAVE_DEBUG_INSNS
994
          && GET_CODE (tem) == SUBREG
995
          && (GET_CODE (SUBREG_REG (tem)) == PLUS
996
              || GET_CODE (SUBREG_REG (tem)) == MINUS
997
              || GET_CODE (SUBREG_REG (tem)) == MULT
998
              || GET_CODE (SUBREG_REG (tem)) == ASHIFT)
999
          && GET_MODE_CLASS (GET_MODE (tem)) == MODE_INT
1000
          && GET_MODE_CLASS (GET_MODE (SUBREG_REG (tem))) == MODE_INT
1001
          && GET_MODE_SIZE (GET_MODE (tem))
1002
             < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tem)))
1003
          && subreg_lowpart_p (tem)
1004
          && !for_each_rtx (&SUBREG_REG (tem), use_narrower_mode_test, tem))
1005
        return use_narrower_mode (SUBREG_REG (tem), GET_MODE (tem),
1006
                                  GET_MODE (SUBREG_REG (tem)));
1007
      return tem;
1008
    case ASM_OPERANDS:
1009
      /* Don't do any replacements in second and following
1010
         ASM_OPERANDS of inline-asm with multiple sets.
1011
         ASM_OPERANDS_INPUT_VEC, ASM_OPERANDS_INPUT_CONSTRAINT_VEC
1012
         and ASM_OPERANDS_LABEL_VEC need to be equal between
1013
         all the ASM_OPERANDs in the insn and adjust_insn will
1014
         fix this up.  */
1015
      if (ASM_OPERANDS_OUTPUT_IDX (loc) != 0)
1016
        return loc;
1017
      break;
1018
    default:
1019
      break;
1020
    }
1021
  return NULL_RTX;
1022
}
1023
 
1024
/* Helper function for replacement of uses.  */
1025
 
1026
static void
1027
adjust_mem_uses (rtx *x, void *data)
1028
{
1029
  rtx new_x = simplify_replace_fn_rtx (*x, NULL_RTX, adjust_mems, data);
1030
  if (new_x != *x)
1031
    validate_change (NULL_RTX, x, new_x, true);
1032
}
1033
 
1034
/* Helper function for replacement of stores.  */
1035
 
1036
static void
1037
adjust_mem_stores (rtx loc, const_rtx expr, void *data)
1038
{
1039
  if (MEM_P (loc))
1040
    {
1041
      rtx new_dest = simplify_replace_fn_rtx (SET_DEST (expr), NULL_RTX,
1042
                                              adjust_mems, data);
1043
      if (new_dest != SET_DEST (expr))
1044
        {
1045
          rtx xexpr = CONST_CAST_RTX (expr);
1046
          validate_change (NULL_RTX, &SET_DEST (xexpr), new_dest, true);
1047
        }
1048
    }
1049
}
1050
 
1051
/* Simplify INSN.  Remove all {PRE,POST}_{INC,DEC,MODIFY} rtxes,
1052
   replace them with their value in the insn and add the side-effects
1053
   as other sets to the insn.  */
1054
 
1055
static void
1056
adjust_insn (basic_block bb, rtx insn)
1057
{
1058
  struct adjust_mem_data amd;
1059
  rtx set;
1060
 
1061
#ifdef HAVE_window_save
1062
  /* If the target machine has an explicit window save instruction, the
1063
     transformation OUTGOING_REGNO -> INCOMING_REGNO is done there.  */
1064
  if (RTX_FRAME_RELATED_P (insn)
1065
      && find_reg_note (insn, REG_CFA_WINDOW_SAVE, NULL_RTX))
1066
    {
1067
      unsigned int i, nregs = VEC_length(parm_reg_t, windowed_parm_regs);
1068
      rtx rtl = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs * 2));
1069
      parm_reg_t *p;
1070
 
1071
      FOR_EACH_VEC_ELT (parm_reg_t, windowed_parm_regs, i, p)
1072
        {
1073
          XVECEXP (rtl, 0, i * 2)
1074
            = gen_rtx_SET (VOIDmode, p->incoming, p->outgoing);
1075
          /* Do not clobber the attached DECL, but only the REG.  */
1076
          XVECEXP (rtl, 0, i * 2 + 1)
1077
            = gen_rtx_CLOBBER (GET_MODE (p->outgoing),
1078
                               gen_raw_REG (GET_MODE (p->outgoing),
1079
                                            REGNO (p->outgoing)));
1080
        }
1081
 
1082
      validate_change (NULL_RTX, &PATTERN (insn), rtl, true);
1083
      return;
1084
    }
1085
#endif
1086
 
1087
  amd.mem_mode = VOIDmode;
1088
  amd.stack_adjust = -VTI (bb)->out.stack_adjust;
1089
  amd.side_effects = NULL_RTX;
1090
 
1091
  amd.store = true;
1092
  note_stores (PATTERN (insn), adjust_mem_stores, &amd);
1093
 
1094
  amd.store = false;
1095
  if (GET_CODE (PATTERN (insn)) == PARALLEL
1096
      && asm_noperands (PATTERN (insn)) > 0
1097
      && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
1098
    {
1099
      rtx body, set0;
1100
      int i;
1101
 
1102
      /* inline-asm with multiple sets is tiny bit more complicated,
1103
         because the 3 vectors in ASM_OPERANDS need to be shared between
1104
         all ASM_OPERANDS in the instruction.  adjust_mems will
1105
         not touch ASM_OPERANDS other than the first one, asm_noperands
1106
         test above needs to be called before that (otherwise it would fail)
1107
         and afterwards this code fixes it up.  */
1108
      note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
1109
      body = PATTERN (insn);
1110
      set0 = XVECEXP (body, 0, 0);
1111
      gcc_checking_assert (GET_CODE (set0) == SET
1112
                           && GET_CODE (SET_SRC (set0)) == ASM_OPERANDS
1113
                           && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set0)) == 0);
1114
      for (i = 1; i < XVECLEN (body, 0); i++)
1115
        if (GET_CODE (XVECEXP (body, 0, i)) != SET)
1116
          break;
1117
        else
1118
          {
1119
            set = XVECEXP (body, 0, i);
1120
            gcc_checking_assert (GET_CODE (SET_SRC (set)) == ASM_OPERANDS
1121
                                 && ASM_OPERANDS_OUTPUT_IDX (SET_SRC (set))
1122
                                    == i);
1123
            if (ASM_OPERANDS_INPUT_VEC (SET_SRC (set))
1124
                != ASM_OPERANDS_INPUT_VEC (SET_SRC (set0))
1125
                || ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set))
1126
                   != ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0))
1127
                || ASM_OPERANDS_LABEL_VEC (SET_SRC (set))
1128
                   != ASM_OPERANDS_LABEL_VEC (SET_SRC (set0)))
1129
              {
1130
                rtx newsrc = shallow_copy_rtx (SET_SRC (set));
1131
                ASM_OPERANDS_INPUT_VEC (newsrc)
1132
                  = ASM_OPERANDS_INPUT_VEC (SET_SRC (set0));
1133
                ASM_OPERANDS_INPUT_CONSTRAINT_VEC (newsrc)
1134
                  = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (SET_SRC (set0));
1135
                ASM_OPERANDS_LABEL_VEC (newsrc)
1136
                  = ASM_OPERANDS_LABEL_VEC (SET_SRC (set0));
1137
                validate_change (NULL_RTX, &SET_SRC (set), newsrc, true);
1138
              }
1139
          }
1140
    }
1141
  else
1142
    note_uses (&PATTERN (insn), adjust_mem_uses, &amd);
1143
 
1144
  /* For read-only MEMs containing some constant, prefer those
1145
     constants.  */
1146
  set = single_set (insn);
1147
  if (set && MEM_P (SET_SRC (set)) && MEM_READONLY_P (SET_SRC (set)))
1148
    {
1149
      rtx note = find_reg_equal_equiv_note (insn);
1150
 
1151
      if (note && CONSTANT_P (XEXP (note, 0)))
1152
        validate_change (NULL_RTX, &SET_SRC (set), XEXP (note, 0), true);
1153
    }
1154
 
1155
  if (amd.side_effects)
1156
    {
1157
      rtx *pat, new_pat, s;
1158
      int i, oldn, newn;
1159
 
1160
      pat = &PATTERN (insn);
1161
      if (GET_CODE (*pat) == COND_EXEC)
1162
        pat = &COND_EXEC_CODE (*pat);
1163
      if (GET_CODE (*pat) == PARALLEL)
1164
        oldn = XVECLEN (*pat, 0);
1165
      else
1166
        oldn = 1;
1167
      for (s = amd.side_effects, newn = 0; s; newn++)
1168
        s = XEXP (s, 1);
1169
      new_pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (oldn + newn));
1170
      if (GET_CODE (*pat) == PARALLEL)
1171
        for (i = 0; i < oldn; i++)
1172
          XVECEXP (new_pat, 0, i) = XVECEXP (*pat, 0, i);
1173
      else
1174
        XVECEXP (new_pat, 0, 0) = *pat;
1175
      for (s = amd.side_effects, i = oldn; i < oldn + newn; i++, s = XEXP (s, 1))
1176
        XVECEXP (new_pat, 0, i) = XEXP (s, 0);
1177
      free_EXPR_LIST_list (&amd.side_effects);
1178
      validate_change (NULL_RTX, pat, new_pat, true);
1179
    }
1180
}
1181
 
1182
/* Return true if a decl_or_value DV is a DECL or NULL.  */
1183
static inline bool
1184
dv_is_decl_p (decl_or_value dv)
1185
{
1186
  return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
1187
}
1188
 
1189
/* Return true if a decl_or_value is a VALUE rtl.  */
1190
static inline bool
1191
dv_is_value_p (decl_or_value dv)
1192
{
1193
  return dv && !dv_is_decl_p (dv);
1194
}
1195
 
1196
/* Return the decl in the decl_or_value.  */
1197
static inline tree
1198
dv_as_decl (decl_or_value dv)
1199
{
1200
  gcc_checking_assert (dv_is_decl_p (dv));
1201
  return (tree) dv;
1202
}
1203
 
1204
/* Return the value in the decl_or_value.  */
1205
static inline rtx
1206
dv_as_value (decl_or_value dv)
1207
{
1208
  gcc_checking_assert (dv_is_value_p (dv));
1209
  return (rtx)dv;
1210
}
1211
 
1212
/* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV.  */
1213
static inline rtx
1214
dv_as_rtx (decl_or_value dv)
1215
{
1216
  tree decl;
1217
 
1218
  if (dv_is_value_p (dv))
1219
    return dv_as_value (dv);
1220
 
1221
  decl = dv_as_decl (dv);
1222
 
1223
  gcc_checking_assert (TREE_CODE (decl) == DEBUG_EXPR_DECL);
1224
  return DECL_RTL_KNOWN_SET (decl);
1225
}
1226
 
1227
/* Return the opaque pointer in the decl_or_value.  */
1228
static inline void *
1229
dv_as_opaque (decl_or_value dv)
1230
{
1231
  return dv;
1232
}
1233
 
1234
/* Return nonzero if a decl_or_value must not have more than one
1235
   variable part.  The returned value discriminates among various
1236
   kinds of one-part DVs ccording to enum onepart_enum.  */
1237
static inline onepart_enum_t
1238
dv_onepart_p (decl_or_value dv)
1239
{
1240
  tree decl;
1241
 
1242
  if (!MAY_HAVE_DEBUG_INSNS)
1243
    return NOT_ONEPART;
1244
 
1245
  if (dv_is_value_p (dv))
1246
    return ONEPART_VALUE;
1247
 
1248
  decl = dv_as_decl (dv);
1249
 
1250
  if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
1251
    return ONEPART_DEXPR;
1252
 
1253
  if (target_for_debug_bind (decl) != NULL_TREE)
1254
    return ONEPART_VDECL;
1255
 
1256
  return NOT_ONEPART;
1257
}
1258
 
1259
/* Return the variable pool to be used for a dv of type ONEPART.  */
1260
static inline alloc_pool
1261
onepart_pool (onepart_enum_t onepart)
1262
{
1263
  return onepart ? valvar_pool : var_pool;
1264
}
1265
 
1266
/* Build a decl_or_value out of a decl.  */
1267
static inline decl_or_value
1268
dv_from_decl (tree decl)
1269
{
1270
  decl_or_value dv;
1271
  dv = decl;
1272
  gcc_checking_assert (dv_is_decl_p (dv));
1273
  return dv;
1274
}
1275
 
1276
/* Build a decl_or_value out of a value.  */
1277
static inline decl_or_value
1278
dv_from_value (rtx value)
1279
{
1280
  decl_or_value dv;
1281
  dv = value;
1282
  gcc_checking_assert (dv_is_value_p (dv));
1283
  return dv;
1284
}
1285
 
1286
/* Return a value or the decl of a debug_expr as a decl_or_value.  */
1287
static inline decl_or_value
1288
dv_from_rtx (rtx x)
1289
{
1290
  decl_or_value dv;
1291
 
1292
  switch (GET_CODE (x))
1293
    {
1294
    case DEBUG_EXPR:
1295
      dv = dv_from_decl (DEBUG_EXPR_TREE_DECL (x));
1296
      gcc_checking_assert (DECL_RTL_KNOWN_SET (DEBUG_EXPR_TREE_DECL (x)) == x);
1297
      break;
1298
 
1299
    case VALUE:
1300
      dv = dv_from_value (x);
1301
      break;
1302
 
1303
    default:
1304
      gcc_unreachable ();
1305
    }
1306
 
1307
  return dv;
1308
}
1309
 
1310
extern void debug_dv (decl_or_value dv);
1311
 
1312
DEBUG_FUNCTION void
1313
debug_dv (decl_or_value dv)
1314
{
1315
  if (dv_is_value_p (dv))
1316
    debug_rtx (dv_as_value (dv));
1317
  else
1318
    debug_generic_stmt (dv_as_decl (dv));
1319
}
1320
 
1321
typedef unsigned int dvuid;
1322
 
1323
/* Return the uid of DV.  */
1324
 
1325
static inline dvuid
1326
dv_uid (decl_or_value dv)
1327
{
1328
  if (dv_is_value_p (dv))
1329
    return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
1330
  else
1331
    return DECL_UID (dv_as_decl (dv));
1332
}
1333
 
1334
/* Compute the hash from the uid.  */
1335
 
1336
static inline hashval_t
1337
dv_uid2hash (dvuid uid)
1338
{
1339
  return uid;
1340
}
1341
 
1342
/* The hash function for a mask table in a shared_htab chain.  */
1343
 
1344
static inline hashval_t
1345
dv_htab_hash (decl_or_value dv)
1346
{
1347
  return dv_uid2hash (dv_uid (dv));
1348
}
1349
 
1350
/* The hash function for variable_htab, computes the hash value
1351
   from the declaration of variable X.  */
1352
 
1353
static hashval_t
1354
variable_htab_hash (const void *x)
1355
{
1356
  const_variable const v = (const_variable) x;
1357
 
1358
  return dv_htab_hash (v->dv);
1359
}
1360
 
1361
/* Compare the declaration of variable X with declaration Y.  */
1362
 
1363
static int
1364
variable_htab_eq (const void *x, const void *y)
1365
{
1366
  const_variable const v = (const_variable) x;
1367
  decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
1368
 
1369
  return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
1370
}
1371
 
1372
static void loc_exp_dep_clear (variable var);
1373
 
1374
/* Free the element of VARIABLE_HTAB (its type is struct variable_def).  */
1375
 
1376
static void
1377
variable_htab_free (void *elem)
1378
{
1379
  int i;
1380
  variable var = (variable) elem;
1381
  location_chain node, next;
1382
 
1383
  gcc_checking_assert (var->refcount > 0);
1384
 
1385
  var->refcount--;
1386
  if (var->refcount > 0)
1387
    return;
1388
 
1389
  for (i = 0; i < var->n_var_parts; i++)
1390
    {
1391
      for (node = var->var_part[i].loc_chain; node; node = next)
1392
        {
1393
          next = node->next;
1394
          pool_free (loc_chain_pool, node);
1395
        }
1396
      var->var_part[i].loc_chain = NULL;
1397
    }
1398
  if (var->onepart && VAR_LOC_1PAUX (var))
1399
    {
1400
      loc_exp_dep_clear (var);
1401
      if (VAR_LOC_DEP_LST (var))
1402
        VAR_LOC_DEP_LST (var)->pprev = NULL;
1403
      XDELETE (VAR_LOC_1PAUX (var));
1404
      /* These may be reused across functions, so reset
1405
         e.g. NO_LOC_P.  */
1406
      if (var->onepart == ONEPART_DEXPR)
1407
        set_dv_changed (var->dv, true);
1408
    }
1409
  pool_free (onepart_pool (var->onepart), var);
1410
}
1411
 
1412
/* Initialize the set (array) SET of attrs to empty lists.  */
1413
 
1414
static void
1415
init_attrs_list_set (attrs *set)
1416
{
1417
  int i;
1418
 
1419
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1420
    set[i] = NULL;
1421
}
1422
 
1423
/* Make the list *LISTP empty.  */
1424
 
1425
static void
1426
attrs_list_clear (attrs *listp)
1427
{
1428
  attrs list, next;
1429
 
1430
  for (list = *listp; list; list = next)
1431
    {
1432
      next = list->next;
1433
      pool_free (attrs_pool, list);
1434
    }
1435
  *listp = NULL;
1436
}
1437
 
1438
/* Return true if the pair of DECL and OFFSET is the member of the LIST.  */
1439
 
1440
static attrs
1441
attrs_list_member (attrs list, decl_or_value dv, HOST_WIDE_INT offset)
1442
{
1443
  for (; list; list = list->next)
1444
    if (dv_as_opaque (list->dv) == dv_as_opaque (dv) && list->offset == offset)
1445
      return list;
1446
  return NULL;
1447
}
1448
 
1449
/* Insert the triplet DECL, OFFSET, LOC to the list *LISTP.  */
1450
 
1451
static void
1452
attrs_list_insert (attrs *listp, decl_or_value dv,
1453
                   HOST_WIDE_INT offset, rtx loc)
1454
{
1455
  attrs list;
1456
 
1457
  list = (attrs) pool_alloc (attrs_pool);
1458
  list->loc = loc;
1459
  list->dv = dv;
1460
  list->offset = offset;
1461
  list->next = *listp;
1462
  *listp = list;
1463
}
1464
 
1465
/* Copy all nodes from SRC and create a list *DSTP of the copies.  */
1466
 
1467
static void
1468
attrs_list_copy (attrs *dstp, attrs src)
1469
{
1470
  attrs n;
1471
 
1472
  attrs_list_clear (dstp);
1473
  for (; src; src = src->next)
1474
    {
1475
      n = (attrs) pool_alloc (attrs_pool);
1476
      n->loc = src->loc;
1477
      n->dv = src->dv;
1478
      n->offset = src->offset;
1479
      n->next = *dstp;
1480
      *dstp = n;
1481
    }
1482
}
1483
 
1484
/* Add all nodes from SRC which are not in *DSTP to *DSTP.  */
1485
 
1486
static void
1487
attrs_list_union (attrs *dstp, attrs src)
1488
{
1489
  for (; src; src = src->next)
1490
    {
1491
      if (!attrs_list_member (*dstp, src->dv, src->offset))
1492
        attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1493
    }
1494
}
1495
 
1496
/* Combine nodes that are not onepart nodes from SRC and SRC2 into
1497
   *DSTP.  */
1498
 
1499
static void
1500
attrs_list_mpdv_union (attrs *dstp, attrs src, attrs src2)
1501
{
1502
  gcc_assert (!*dstp);
1503
  for (; src; src = src->next)
1504
    {
1505
      if (!dv_onepart_p (src->dv))
1506
        attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1507
    }
1508
  for (src = src2; src; src = src->next)
1509
    {
1510
      if (!dv_onepart_p (src->dv)
1511
          && !attrs_list_member (*dstp, src->dv, src->offset))
1512
        attrs_list_insert (dstp, src->dv, src->offset, src->loc);
1513
    }
1514
}
1515
 
1516
/* Shared hashtable support.  */
1517
 
1518
/* Return true if VARS is shared.  */
1519
 
1520
static inline bool
1521
shared_hash_shared (shared_hash vars)
1522
{
1523
  return vars->refcount > 1;
1524
}
1525
 
1526
/* Return the hash table for VARS.  */
1527
 
1528
static inline htab_t
1529
shared_hash_htab (shared_hash vars)
1530
{
1531
  return vars->htab;
1532
}
1533
 
1534
/* Return true if VAR is shared, or maybe because VARS is shared.  */
1535
 
1536
static inline bool
1537
shared_var_p (variable var, shared_hash vars)
1538
{
1539
  /* Don't count an entry in the changed_variables table as a duplicate.  */
1540
  return ((var->refcount > 1 + (int) var->in_changed_variables)
1541
          || shared_hash_shared (vars));
1542
}
1543
 
1544
/* Copy variables into a new hash table.  */
1545
 
1546
static shared_hash
1547
shared_hash_unshare (shared_hash vars)
1548
{
1549
  shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
1550
  gcc_assert (vars->refcount > 1);
1551
  new_vars->refcount = 1;
1552
  new_vars->htab
1553
    = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
1554
                   variable_htab_eq, variable_htab_free);
1555
  vars_copy (new_vars->htab, vars->htab);
1556
  vars->refcount--;
1557
  return new_vars;
1558
}
1559
 
1560
/* Increment reference counter on VARS and return it.  */
1561
 
1562
static inline shared_hash
1563
shared_hash_copy (shared_hash vars)
1564
{
1565
  vars->refcount++;
1566
  return vars;
1567
}
1568
 
1569
/* Decrement reference counter and destroy hash table if not shared
1570
   anymore.  */
1571
 
1572
static void
1573
shared_hash_destroy (shared_hash vars)
1574
{
1575
  gcc_checking_assert (vars->refcount > 0);
1576
  if (--vars->refcount == 0)
1577
    {
1578
      htab_delete (vars->htab);
1579
      pool_free (shared_hash_pool, vars);
1580
    }
1581
}
1582
 
1583
/* Unshare *PVARS if shared and return slot for DV.  If INS is
1584
   INSERT, insert it if not already present.  */
1585
 
1586
static inline void **
1587
shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv,
1588
                                 hashval_t dvhash, enum insert_option ins)
1589
{
1590
  if (shared_hash_shared (*pvars))
1591
    *pvars = shared_hash_unshare (*pvars);
1592
  return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins);
1593
}
1594
 
1595
static inline void **
1596
shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
1597
                               enum insert_option ins)
1598
{
1599
  return shared_hash_find_slot_unshare_1 (pvars, dv, dv_htab_hash (dv), ins);
1600
}
1601
 
1602
/* Return slot for DV, if it is already present in the hash table.
1603
   If it is not present, insert it only VARS is not shared, otherwise
1604
   return NULL.  */
1605
 
1606
static inline void **
1607
shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1608
{
1609
  return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1610
                                   shared_hash_shared (vars)
1611
                                   ? NO_INSERT : INSERT);
1612
}
1613
 
1614
static inline void **
1615
shared_hash_find_slot (shared_hash vars, decl_or_value dv)
1616
{
1617
  return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
1618
}
1619
 
1620
/* Return slot for DV only if it is already present in the hash table.  */
1621
 
1622
static inline void **
1623
shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv,
1624
                                  hashval_t dvhash)
1625
{
1626
  return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
1627
                                   NO_INSERT);
1628
}
1629
 
1630
static inline void **
1631
shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
1632
{
1633
  return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
1634
}
1635
 
1636
/* Return variable for DV or NULL if not already present in the hash
1637
   table.  */
1638
 
1639
static inline variable
1640
shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
1641
{
1642
  return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash);
1643
}
1644
 
1645
static inline variable
1646
shared_hash_find (shared_hash vars, decl_or_value dv)
1647
{
1648
  return shared_hash_find_1 (vars, dv, dv_htab_hash (dv));
1649
}
1650
 
1651
/* Return true if TVAL is better than CVAL as a canonival value.  We
1652
   choose lowest-numbered VALUEs, using the RTX address as a
1653
   tie-breaker.  The idea is to arrange them into a star topology,
1654
   such that all of them are at most one step away from the canonical
1655
   value, and the canonical value has backlinks to all of them, in
1656
   addition to all the actual locations.  We don't enforce this
1657
   topology throughout the entire dataflow analysis, though.
1658
 */
1659
 
1660
static inline bool
1661
canon_value_cmp (rtx tval, rtx cval)
1662
{
1663
  return !cval
1664
    || CSELIB_VAL_PTR (tval)->uid < CSELIB_VAL_PTR (cval)->uid;
1665
}
1666
 
1667
static bool dst_can_be_shared;
1668
 
1669
/* Return a copy of a variable VAR and insert it to dataflow set SET.  */
1670
 
1671
static void **
1672
unshare_variable (dataflow_set *set, void **slot, variable var,
1673
                  enum var_init_status initialized)
1674
{
1675
  variable new_var;
1676
  int i;
1677
 
1678
  new_var = (variable) pool_alloc (onepart_pool (var->onepart));
1679
  new_var->dv = var->dv;
1680
  new_var->refcount = 1;
1681
  var->refcount--;
1682
  new_var->n_var_parts = var->n_var_parts;
1683
  new_var->onepart = var->onepart;
1684
  new_var->in_changed_variables = false;
1685
 
1686
  if (! flag_var_tracking_uninit)
1687
    initialized = VAR_INIT_STATUS_INITIALIZED;
1688
 
1689
  for (i = 0; i < var->n_var_parts; i++)
1690
    {
1691
      location_chain node;
1692
      location_chain *nextp;
1693
 
1694
      if (i == 0 && var->onepart)
1695
        {
1696
          /* One-part auxiliary data is only used while emitting
1697
             notes, so propagate it to the new variable in the active
1698
             dataflow set.  If we're not emitting notes, this will be
1699
             a no-op.  */
1700
          gcc_checking_assert (!VAR_LOC_1PAUX (var) || emit_notes);
1701
          VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (var);
1702
          VAR_LOC_1PAUX (var) = NULL;
1703
        }
1704
      else
1705
        VAR_PART_OFFSET (new_var, i) = VAR_PART_OFFSET (var, i);
1706
      nextp = &new_var->var_part[i].loc_chain;
1707
      for (node = var->var_part[i].loc_chain; node; node = node->next)
1708
        {
1709
          location_chain new_lc;
1710
 
1711
          new_lc = (location_chain) pool_alloc (loc_chain_pool);
1712
          new_lc->next = NULL;
1713
          if (node->init > initialized)
1714
            new_lc->init = node->init;
1715
          else
1716
            new_lc->init = initialized;
1717
          if (node->set_src && !(MEM_P (node->set_src)))
1718
            new_lc->set_src = node->set_src;
1719
          else
1720
            new_lc->set_src = NULL;
1721
          new_lc->loc = node->loc;
1722
 
1723
          *nextp = new_lc;
1724
          nextp = &new_lc->next;
1725
        }
1726
 
1727
      new_var->var_part[i].cur_loc = var->var_part[i].cur_loc;
1728
    }
1729
 
1730
  dst_can_be_shared = false;
1731
  if (shared_hash_shared (set->vars))
1732
    slot = shared_hash_find_slot_unshare (&set->vars, var->dv, NO_INSERT);
1733
  else if (set->traversed_vars && set->vars != set->traversed_vars)
1734
    slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
1735
  *slot = new_var;
1736
  if (var->in_changed_variables)
1737
    {
1738
      void **cslot
1739
        = htab_find_slot_with_hash (changed_variables, var->dv,
1740
                                    dv_htab_hash (var->dv), NO_INSERT);
1741
      gcc_assert (*cslot == (void *) var);
1742
      var->in_changed_variables = false;
1743
      variable_htab_free (var);
1744
      *cslot = new_var;
1745
      new_var->in_changed_variables = true;
1746
    }
1747
  return slot;
1748
}
1749
 
1750
/* Copy all variables from hash table SRC to hash table DST.  */
1751
 
1752
static void
1753
vars_copy (htab_t dst, htab_t src)
1754
{
1755
  htab_iterator hi;
1756
  variable var;
1757
 
1758
  FOR_EACH_HTAB_ELEMENT (src, var, variable, hi)
1759
    {
1760
      void **dstp;
1761
      var->refcount++;
1762
      dstp = htab_find_slot_with_hash (dst, var->dv,
1763
                                       dv_htab_hash (var->dv),
1764
                                       INSERT);
1765
      *dstp = var;
1766
    }
1767
}
1768
 
1769
/* Map a decl to its main debug decl.  */
1770
 
1771
static inline tree
1772
var_debug_decl (tree decl)
1773
{
1774
  if (decl && DECL_P (decl)
1775
      && DECL_DEBUG_EXPR_IS_FROM (decl))
1776
    {
1777
      tree debugdecl = DECL_DEBUG_EXPR (decl);
1778
      if (debugdecl && DECL_P (debugdecl))
1779
        decl = debugdecl;
1780
    }
1781
 
1782
  return decl;
1783
}
1784
 
1785
/* Set the register LOC to contain DV, OFFSET.  */
1786
 
1787
static void
1788
var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1789
                  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1790
                  enum insert_option iopt)
1791
{
1792
  attrs node;
1793
  bool decl_p = dv_is_decl_p (dv);
1794
 
1795
  if (decl_p)
1796
    dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1797
 
1798
  for (node = set->regs[REGNO (loc)]; node; node = node->next)
1799
    if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
1800
        && node->offset == offset)
1801
      break;
1802
  if (!node)
1803
    attrs_list_insert (&set->regs[REGNO (loc)], dv, offset, loc);
1804
  set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1805
}
1806
 
1807
/* Set the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  */
1808
 
1809
static void
1810
var_reg_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1811
             rtx set_src)
1812
{
1813
  tree decl = REG_EXPR (loc);
1814
  HOST_WIDE_INT offset = REG_OFFSET (loc);
1815
 
1816
  var_reg_decl_set (set, loc, initialized,
1817
                    dv_from_decl (decl), offset, set_src, INSERT);
1818
}
1819
 
1820
static enum var_init_status
1821
get_init_value (dataflow_set *set, rtx loc, decl_or_value dv)
1822
{
1823
  variable var;
1824
  int i;
1825
  enum var_init_status ret_val = VAR_INIT_STATUS_UNKNOWN;
1826
 
1827
  if (! flag_var_tracking_uninit)
1828
    return VAR_INIT_STATUS_INITIALIZED;
1829
 
1830
  var = shared_hash_find (set->vars, dv);
1831
  if (var)
1832
    {
1833
      for (i = 0; i < var->n_var_parts && ret_val == VAR_INIT_STATUS_UNKNOWN; i++)
1834
        {
1835
          location_chain nextp;
1836
          for (nextp = var->var_part[i].loc_chain; nextp; nextp = nextp->next)
1837
            if (rtx_equal_p (nextp->loc, loc))
1838
              {
1839
                ret_val = nextp->init;
1840
                break;
1841
              }
1842
        }
1843
    }
1844
 
1845
  return ret_val;
1846
}
1847
 
1848
/* Delete current content of register LOC in dataflow set SET and set
1849
   the register to contain REG_EXPR (LOC), REG_OFFSET (LOC).  If
1850
   MODIFY is true, any other live copies of the same variable part are
1851
   also deleted from the dataflow set, otherwise the variable part is
1852
   assumed to be copied from another location holding the same
1853
   part.  */
1854
 
1855
static void
1856
var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1857
                        enum var_init_status initialized, rtx set_src)
1858
{
1859
  tree decl = REG_EXPR (loc);
1860
  HOST_WIDE_INT offset = REG_OFFSET (loc);
1861
  attrs node, next;
1862
  attrs *nextp;
1863
 
1864
  decl = var_debug_decl (decl);
1865
 
1866
  if (initialized == VAR_INIT_STATUS_UNKNOWN)
1867
    initialized = get_init_value (set, loc, dv_from_decl (decl));
1868
 
1869
  nextp = &set->regs[REGNO (loc)];
1870
  for (node = *nextp; node; node = next)
1871
    {
1872
      next = node->next;
1873
      if (dv_as_opaque (node->dv) != decl || node->offset != offset)
1874
        {
1875
          delete_variable_part (set, node->loc, node->dv, node->offset);
1876
          pool_free (attrs_pool, node);
1877
          *nextp = next;
1878
        }
1879
      else
1880
        {
1881
          node->loc = loc;
1882
          nextp = &node->next;
1883
        }
1884
    }
1885
  if (modify)
1886
    clobber_variable_part (set, loc, dv_from_decl (decl), offset, set_src);
1887
  var_reg_set (set, loc, initialized, set_src);
1888
}
1889
 
1890
/* Delete the association of register LOC in dataflow set SET with any
1891
   variables that aren't onepart.  If CLOBBER is true, also delete any
1892
   other live copies of the same variable part, and delete the
1893
   association with onepart dvs too.  */
1894
 
1895
static void
1896
var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
1897
{
1898
  attrs *nextp = &set->regs[REGNO (loc)];
1899
  attrs node, next;
1900
 
1901
  if (clobber)
1902
    {
1903
      tree decl = REG_EXPR (loc);
1904
      HOST_WIDE_INT offset = REG_OFFSET (loc);
1905
 
1906
      decl = var_debug_decl (decl);
1907
 
1908
      clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
1909
    }
1910
 
1911
  for (node = *nextp; node; node = next)
1912
    {
1913
      next = node->next;
1914
      if (clobber || !dv_onepart_p (node->dv))
1915
        {
1916
          delete_variable_part (set, node->loc, node->dv, node->offset);
1917
          pool_free (attrs_pool, node);
1918
          *nextp = next;
1919
        }
1920
      else
1921
        nextp = &node->next;
1922
    }
1923
}
1924
 
1925
/* Delete content of register with number REGNO in dataflow set SET.  */
1926
 
1927
static void
1928
var_regno_delete (dataflow_set *set, int regno)
1929
{
1930
  attrs *reg = &set->regs[regno];
1931
  attrs node, next;
1932
 
1933
  for (node = *reg; node; node = next)
1934
    {
1935
      next = node->next;
1936
      delete_variable_part (set, node->loc, node->dv, node->offset);
1937
      pool_free (attrs_pool, node);
1938
    }
1939
  *reg = NULL;
1940
}
1941
 
1942
/* Set the location of DV, OFFSET as the MEM LOC.  */
1943
 
1944
static void
1945
var_mem_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1946
                  decl_or_value dv, HOST_WIDE_INT offset, rtx set_src,
1947
                  enum insert_option iopt)
1948
{
1949
  if (dv_is_decl_p (dv))
1950
    dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
1951
 
1952
  set_variable_part (set, loc, dv, offset, initialized, set_src, iopt);
1953
}
1954
 
1955
/* Set the location part of variable MEM_EXPR (LOC) in dataflow set
1956
   SET to LOC.
1957
   Adjust the address first if it is stack pointer based.  */
1958
 
1959
static void
1960
var_mem_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
1961
             rtx set_src)
1962
{
1963
  tree decl = MEM_EXPR (loc);
1964
  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1965
 
1966
  var_mem_decl_set (set, loc, initialized,
1967
                    dv_from_decl (decl), offset, set_src, INSERT);
1968
}
1969
 
1970
/* Delete and set the location part of variable MEM_EXPR (LOC) in
1971
   dataflow set SET to LOC.  If MODIFY is true, any other live copies
1972
   of the same variable part are also deleted from the dataflow set,
1973
   otherwise the variable part is assumed to be copied from another
1974
   location holding the same part.
1975
   Adjust the address first if it is stack pointer based.  */
1976
 
1977
static void
1978
var_mem_delete_and_set (dataflow_set *set, rtx loc, bool modify,
1979
                        enum var_init_status initialized, rtx set_src)
1980
{
1981
  tree decl = MEM_EXPR (loc);
1982
  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
1983
 
1984
  decl = var_debug_decl (decl);
1985
 
1986
  if (initialized == VAR_INIT_STATUS_UNKNOWN)
1987
    initialized = get_init_value (set, loc, dv_from_decl (decl));
1988
 
1989
  if (modify)
1990
    clobber_variable_part (set, NULL, dv_from_decl (decl), offset, set_src);
1991
  var_mem_set (set, loc, initialized, set_src);
1992
}
1993
 
1994
/* Delete the location part LOC from dataflow set SET.  If CLOBBER is
1995
   true, also delete any other live copies of the same variable part.
1996
   Adjust the address first if it is stack pointer based.  */
1997
 
1998
static void
1999
var_mem_delete (dataflow_set *set, rtx loc, bool clobber)
2000
{
2001
  tree decl = MEM_EXPR (loc);
2002
  HOST_WIDE_INT offset = INT_MEM_OFFSET (loc);
2003
 
2004
  decl = var_debug_decl (decl);
2005
  if (clobber)
2006
    clobber_variable_part (set, NULL, dv_from_decl (decl), offset, NULL);
2007
  delete_variable_part (set, loc, dv_from_decl (decl), offset);
2008
}
2009
 
2010
/* Return true if LOC should not be expanded for location expressions,
2011
   or used in them.  */
2012
 
2013
static inline bool
2014
unsuitable_loc (rtx loc)
2015
{
2016
  switch (GET_CODE (loc))
2017
    {
2018
    case PC:
2019
    case SCRATCH:
2020
    case CC0:
2021
    case ASM_INPUT:
2022
    case ASM_OPERANDS:
2023
      return true;
2024
 
2025
    default:
2026
      return false;
2027
    }
2028
}
2029
 
2030
/* Bind VAL to LOC in SET.  If MODIFIED, detach LOC from any values
2031
   bound to it.  */
2032
 
2033
static inline void
2034
val_bind (dataflow_set *set, rtx val, rtx loc, bool modified)
2035
{
2036
  if (REG_P (loc))
2037
    {
2038
      if (modified)
2039
        var_regno_delete (set, REGNO (loc));
2040
      var_reg_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
2041
                        dv_from_value (val), 0, NULL_RTX, INSERT);
2042
    }
2043
  else if (MEM_P (loc))
2044
    {
2045
      struct elt_loc_list *l = CSELIB_VAL_PTR (val)->locs;
2046
 
2047
      if (l && GET_CODE (l->loc) == VALUE)
2048
        l = canonical_cselib_val (CSELIB_VAL_PTR (l->loc))->locs;
2049
 
2050
      /* If this MEM is a global constant, we don't need it in the
2051
         dynamic tables.  ??? We should test this before emitting the
2052
         micro-op in the first place.  */
2053
      while (l)
2054
        if (GET_CODE (l->loc) == MEM && XEXP (l->loc, 0) == XEXP (loc, 0))
2055
          break;
2056
        else
2057
          l = l->next;
2058
 
2059
      if (!l)
2060
        var_mem_decl_set (set, loc, VAR_INIT_STATUS_INITIALIZED,
2061
                          dv_from_value (val), 0, NULL_RTX, INSERT);
2062
    }
2063
  else
2064
    {
2065
      /* Other kinds of equivalences are necessarily static, at least
2066
         so long as we do not perform substitutions while merging
2067
         expressions.  */
2068
      gcc_unreachable ();
2069
      set_variable_part (set, loc, dv_from_value (val), 0,
2070
                         VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2071
    }
2072
}
2073
 
2074
/* Bind a value to a location it was just stored in.  If MODIFIED
2075
   holds, assume the location was modified, detaching it from any
2076
   values bound to it.  */
2077
 
2078
static void
2079
val_store (dataflow_set *set, rtx val, rtx loc, rtx insn, bool modified)
2080
{
2081
  cselib_val *v = CSELIB_VAL_PTR (val);
2082
 
2083
  gcc_assert (cselib_preserved_value_p (v));
2084
 
2085
  if (dump_file)
2086
    {
2087
      fprintf (dump_file, "%i: ", insn ? INSN_UID (insn) : 0);
2088
      print_inline_rtx (dump_file, loc, 0);
2089
      fprintf (dump_file, " evaluates to ");
2090
      print_inline_rtx (dump_file, val, 0);
2091
      if (v->locs)
2092
        {
2093
          struct elt_loc_list *l;
2094
          for (l = v->locs; l; l = l->next)
2095
            {
2096
              fprintf (dump_file, "\n%i: ", INSN_UID (l->setting_insn));
2097
              print_inline_rtx (dump_file, l->loc, 0);
2098
            }
2099
        }
2100
      fprintf (dump_file, "\n");
2101
    }
2102
 
2103
  gcc_checking_assert (!unsuitable_loc (loc));
2104
 
2105
  val_bind (set, val, loc, modified);
2106
}
2107
 
2108
/* Reset this node, detaching all its equivalences.  Return the slot
2109
   in the variable hash table that holds dv, if there is one.  */
2110
 
2111
static void
2112
val_reset (dataflow_set *set, decl_or_value dv)
2113
{
2114
  variable var = shared_hash_find (set->vars, dv) ;
2115
  location_chain node;
2116
  rtx cval;
2117
 
2118
  if (!var || !var->n_var_parts)
2119
    return;
2120
 
2121
  gcc_assert (var->n_var_parts == 1);
2122
 
2123
  cval = NULL;
2124
  for (node = var->var_part[0].loc_chain; node; node = node->next)
2125
    if (GET_CODE (node->loc) == VALUE
2126
        && canon_value_cmp (node->loc, cval))
2127
      cval = node->loc;
2128
 
2129
  for (node = var->var_part[0].loc_chain; node; node = node->next)
2130
    if (GET_CODE (node->loc) == VALUE && cval != node->loc)
2131
      {
2132
        /* Redirect the equivalence link to the new canonical
2133
           value, or simply remove it if it would point at
2134
           itself.  */
2135
        if (cval)
2136
          set_variable_part (set, cval, dv_from_value (node->loc),
2137
                             0, node->init, node->set_src, NO_INSERT);
2138
        delete_variable_part (set, dv_as_value (dv),
2139
                              dv_from_value (node->loc), 0);
2140
      }
2141
 
2142
  if (cval)
2143
    {
2144
      decl_or_value cdv = dv_from_value (cval);
2145
 
2146
      /* Keep the remaining values connected, accummulating links
2147
         in the canonical value.  */
2148
      for (node = var->var_part[0].loc_chain; node; node = node->next)
2149
        {
2150
          if (node->loc == cval)
2151
            continue;
2152
          else if (GET_CODE (node->loc) == REG)
2153
            var_reg_decl_set (set, node->loc, node->init, cdv, 0,
2154
                              node->set_src, NO_INSERT);
2155
          else if (GET_CODE (node->loc) == MEM)
2156
            var_mem_decl_set (set, node->loc, node->init, cdv, 0,
2157
                              node->set_src, NO_INSERT);
2158
          else
2159
            set_variable_part (set, node->loc, cdv, 0,
2160
                               node->init, node->set_src, NO_INSERT);
2161
        }
2162
    }
2163
 
2164
  /* We remove this last, to make sure that the canonical value is not
2165
     removed to the point of requiring reinsertion.  */
2166
  if (cval)
2167
    delete_variable_part (set, dv_as_value (dv), dv_from_value (cval), 0);
2168
 
2169
  clobber_variable_part (set, NULL, dv, 0, NULL);
2170
}
2171
 
2172
/* Find the values in a given location and map the val to another
2173
   value, if it is unique, or add the location as one holding the
2174
   value.  */
2175
 
2176
static void
2177
val_resolve (dataflow_set *set, rtx val, rtx loc, rtx insn)
2178
{
2179
  decl_or_value dv = dv_from_value (val);
2180
 
2181
  if (dump_file && (dump_flags & TDF_DETAILS))
2182
    {
2183
      if (insn)
2184
        fprintf (dump_file, "%i: ", INSN_UID (insn));
2185
      else
2186
        fprintf (dump_file, "head: ");
2187
      print_inline_rtx (dump_file, val, 0);
2188
      fputs (" is at ", dump_file);
2189
      print_inline_rtx (dump_file, loc, 0);
2190
      fputc ('\n', dump_file);
2191
    }
2192
 
2193
  val_reset (set, dv);
2194
 
2195
  gcc_checking_assert (!unsuitable_loc (loc));
2196
 
2197
  if (REG_P (loc))
2198
    {
2199
      attrs node, found = NULL;
2200
 
2201
      for (node = set->regs[REGNO (loc)]; node; node = node->next)
2202
        if (dv_is_value_p (node->dv)
2203
            && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
2204
          {
2205
            found = node;
2206
 
2207
            /* Map incoming equivalences.  ??? Wouldn't it be nice if
2208
             we just started sharing the location lists?  Maybe a
2209
             circular list ending at the value itself or some
2210
             such.  */
2211
            set_variable_part (set, dv_as_value (node->dv),
2212
                               dv_from_value (val), node->offset,
2213
                               VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2214
            set_variable_part (set, val, node->dv, node->offset,
2215
                               VAR_INIT_STATUS_INITIALIZED, NULL_RTX, INSERT);
2216
          }
2217
 
2218
      /* If we didn't find any equivalence, we need to remember that
2219
         this value is held in the named register.  */
2220
      if (found)
2221
        return;
2222
    }
2223
  /* ??? Attempt to find and merge equivalent MEMs or other
2224
     expressions too.  */
2225
 
2226
  val_bind (set, val, loc, false);
2227
}
2228
 
2229
/* Initialize dataflow set SET to be empty.
2230
   VARS_SIZE is the initial size of hash table VARS.  */
2231
 
2232
static void
2233
dataflow_set_init (dataflow_set *set)
2234
{
2235
  init_attrs_list_set (set->regs);
2236
  set->vars = shared_hash_copy (empty_shared_hash);
2237
  set->stack_adjust = 0;
2238
  set->traversed_vars = NULL;
2239
}
2240
 
2241
/* Delete the contents of dataflow set SET.  */
2242
 
2243
static void
2244
dataflow_set_clear (dataflow_set *set)
2245
{
2246
  int i;
2247
 
2248
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2249
    attrs_list_clear (&set->regs[i]);
2250
 
2251
  shared_hash_destroy (set->vars);
2252
  set->vars = shared_hash_copy (empty_shared_hash);
2253
}
2254
 
2255
/* Copy the contents of dataflow set SRC to DST.  */
2256
 
2257
static void
2258
dataflow_set_copy (dataflow_set *dst, dataflow_set *src)
2259
{
2260
  int i;
2261
 
2262
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2263
    attrs_list_copy (&dst->regs[i], src->regs[i]);
2264
 
2265
  shared_hash_destroy (dst->vars);
2266
  dst->vars = shared_hash_copy (src->vars);
2267
  dst->stack_adjust = src->stack_adjust;
2268
}
2269
 
2270
/* Information for merging lists of locations for a given offset of variable.
2271
 */
2272
struct variable_union_info
2273
{
2274
  /* Node of the location chain.  */
2275
  location_chain lc;
2276
 
2277
  /* The sum of positions in the input chains.  */
2278
  int pos;
2279
 
2280
  /* The position in the chain of DST dataflow set.  */
2281
  int pos_dst;
2282
};
2283
 
2284
/* Buffer for location list sorting and its allocated size.  */
2285
static struct variable_union_info *vui_vec;
2286
static int vui_allocated;
2287
 
2288
/* Compare function for qsort, order the structures by POS element.  */
2289
 
2290
static int
2291
variable_union_info_cmp_pos (const void *n1, const void *n2)
2292
{
2293
  const struct variable_union_info *const i1 =
2294
    (const struct variable_union_info *) n1;
2295
  const struct variable_union_info *const i2 =
2296
    ( const struct variable_union_info *) n2;
2297
 
2298
  if (i1->pos != i2->pos)
2299
    return i1->pos - i2->pos;
2300
 
2301
  return (i1->pos_dst - i2->pos_dst);
2302
}
2303
 
2304
/* Compute union of location parts of variable *SLOT and the same variable
2305
   from hash table DATA.  Compute "sorted" union of the location chains
2306
   for common offsets, i.e. the locations of a variable part are sorted by
2307
   a priority where the priority is the sum of the positions in the 2 chains
2308
   (if a location is only in one list the position in the second list is
2309
   defined to be larger than the length of the chains).
2310
   When we are updating the location parts the newest location is in the
2311
   beginning of the chain, so when we do the described "sorted" union
2312
   we keep the newest locations in the beginning.  */
2313
 
2314
static int
2315
variable_union (variable src, dataflow_set *set)
2316
{
2317
  variable dst;
2318
  void **dstp;
2319
  int i, j, k;
2320
 
2321
  dstp = shared_hash_find_slot (set->vars, src->dv);
2322
  if (!dstp || !*dstp)
2323
    {
2324
      src->refcount++;
2325
 
2326
      dst_can_be_shared = false;
2327
      if (!dstp)
2328
        dstp = shared_hash_find_slot_unshare (&set->vars, src->dv, INSERT);
2329
 
2330
      *dstp = src;
2331
 
2332
      /* Continue traversing the hash table.  */
2333
      return 1;
2334
    }
2335
  else
2336
    dst = (variable) *dstp;
2337
 
2338
  gcc_assert (src->n_var_parts);
2339
  gcc_checking_assert (src->onepart == dst->onepart);
2340
 
2341
  /* We can combine one-part variables very efficiently, because their
2342
     entries are in canonical order.  */
2343
  if (src->onepart)
2344
    {
2345
      location_chain *nodep, dnode, snode;
2346
 
2347
      gcc_assert (src->n_var_parts == 1
2348
                  && dst->n_var_parts == 1);
2349
 
2350
      snode = src->var_part[0].loc_chain;
2351
      gcc_assert (snode);
2352
 
2353
    restart_onepart_unshared:
2354
      nodep = &dst->var_part[0].loc_chain;
2355
      dnode = *nodep;
2356
      gcc_assert (dnode);
2357
 
2358
      while (snode)
2359
        {
2360
          int r = dnode ? loc_cmp (dnode->loc, snode->loc) : 1;
2361
 
2362
          if (r > 0)
2363
            {
2364
              location_chain nnode;
2365
 
2366
              if (shared_var_p (dst, set->vars))
2367
                {
2368
                  dstp = unshare_variable (set, dstp, dst,
2369
                                           VAR_INIT_STATUS_INITIALIZED);
2370
                  dst = (variable)*dstp;
2371
                  goto restart_onepart_unshared;
2372
                }
2373
 
2374
              *nodep = nnode = (location_chain) pool_alloc (loc_chain_pool);
2375
              nnode->loc = snode->loc;
2376
              nnode->init = snode->init;
2377
              if (!snode->set_src || MEM_P (snode->set_src))
2378
                nnode->set_src = NULL;
2379
              else
2380
                nnode->set_src = snode->set_src;
2381
              nnode->next = dnode;
2382
              dnode = nnode;
2383
            }
2384
          else if (r == 0)
2385
            gcc_checking_assert (rtx_equal_p (dnode->loc, snode->loc));
2386
 
2387
          if (r >= 0)
2388
            snode = snode->next;
2389
 
2390
          nodep = &dnode->next;
2391
          dnode = *nodep;
2392
        }
2393
 
2394
      return 1;
2395
    }
2396
 
2397
  gcc_checking_assert (!src->onepart);
2398
 
2399
  /* Count the number of location parts, result is K.  */
2400
  for (i = 0, j = 0, k = 0;
2401
       i < src->n_var_parts && j < dst->n_var_parts; k++)
2402
    {
2403
      if (VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2404
        {
2405
          i++;
2406
          j++;
2407
        }
2408
      else if (VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
2409
        i++;
2410
      else
2411
        j++;
2412
    }
2413
  k += src->n_var_parts - i;
2414
  k += dst->n_var_parts - j;
2415
 
2416
  /* We track only variables whose size is <= MAX_VAR_PARTS bytes
2417
     thus there are at most MAX_VAR_PARTS different offsets.  */
2418
  gcc_checking_assert (dst->onepart ? k == 1 : k <= MAX_VAR_PARTS);
2419
 
2420
  if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
2421
    {
2422
      dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
2423
      dst = (variable)*dstp;
2424
    }
2425
 
2426
  i = src->n_var_parts - 1;
2427
  j = dst->n_var_parts - 1;
2428
  dst->n_var_parts = k;
2429
 
2430
  for (k--; k >= 0; k--)
2431
    {
2432
      location_chain node, node2;
2433
 
2434
      if (i >= 0 && j >= 0
2435
          && VAR_PART_OFFSET (src, i) == VAR_PART_OFFSET (dst, j))
2436
        {
2437
          /* Compute the "sorted" union of the chains, i.e. the locations which
2438
             are in both chains go first, they are sorted by the sum of
2439
             positions in the chains.  */
2440
          int dst_l, src_l;
2441
          int ii, jj, n;
2442
          struct variable_union_info *vui;
2443
 
2444
          /* If DST is shared compare the location chains.
2445
             If they are different we will modify the chain in DST with
2446
             high probability so make a copy of DST.  */
2447
          if (shared_var_p (dst, set->vars))
2448
            {
2449
              for (node = src->var_part[i].loc_chain,
2450
                   node2 = dst->var_part[j].loc_chain; node && node2;
2451
                   node = node->next, node2 = node2->next)
2452
                {
2453
                  if (!((REG_P (node2->loc)
2454
                         && REG_P (node->loc)
2455
                         && REGNO (node2->loc) == REGNO (node->loc))
2456
                        || rtx_equal_p (node2->loc, node->loc)))
2457
                    {
2458
                      if (node2->init < node->init)
2459
                        node2->init = node->init;
2460
                      break;
2461
                    }
2462
                }
2463
              if (node || node2)
2464
                {
2465
                  dstp = unshare_variable (set, dstp, dst,
2466
                                           VAR_INIT_STATUS_UNKNOWN);
2467
                  dst = (variable)*dstp;
2468
                }
2469
            }
2470
 
2471
          src_l = 0;
2472
          for (node = src->var_part[i].loc_chain; node; node = node->next)
2473
            src_l++;
2474
          dst_l = 0;
2475
          for (node = dst->var_part[j].loc_chain; node; node = node->next)
2476
            dst_l++;
2477
 
2478
          if (dst_l == 1)
2479
            {
2480
              /* The most common case, much simpler, no qsort is needed.  */
2481
              location_chain dstnode = dst->var_part[j].loc_chain;
2482
              dst->var_part[k].loc_chain = dstnode;
2483
              VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET(dst, j);
2484
              node2 = dstnode;
2485
              for (node = src->var_part[i].loc_chain; node; node = node->next)
2486
                if (!((REG_P (dstnode->loc)
2487
                       && REG_P (node->loc)
2488
                       && REGNO (dstnode->loc) == REGNO (node->loc))
2489
                      || rtx_equal_p (dstnode->loc, node->loc)))
2490
                  {
2491
                    location_chain new_node;
2492
 
2493
                    /* Copy the location from SRC.  */
2494
                    new_node = (location_chain) pool_alloc (loc_chain_pool);
2495
                    new_node->loc = node->loc;
2496
                    new_node->init = node->init;
2497
                    if (!node->set_src || MEM_P (node->set_src))
2498
                      new_node->set_src = NULL;
2499
                    else
2500
                      new_node->set_src = node->set_src;
2501
                    node2->next = new_node;
2502
                    node2 = new_node;
2503
                  }
2504
              node2->next = NULL;
2505
            }
2506
          else
2507
            {
2508
              if (src_l + dst_l > vui_allocated)
2509
                {
2510
                  vui_allocated = MAX (vui_allocated * 2, src_l + dst_l);
2511
                  vui_vec = XRESIZEVEC (struct variable_union_info, vui_vec,
2512
                                        vui_allocated);
2513
                }
2514
              vui = vui_vec;
2515
 
2516
              /* Fill in the locations from DST.  */
2517
              for (node = dst->var_part[j].loc_chain, jj = 0; node;
2518
                   node = node->next, jj++)
2519
                {
2520
                  vui[jj].lc = node;
2521
                  vui[jj].pos_dst = jj;
2522
 
2523
                  /* Pos plus value larger than a sum of 2 valid positions.  */
2524
                  vui[jj].pos = jj + src_l + dst_l;
2525
                }
2526
 
2527
              /* Fill in the locations from SRC.  */
2528
              n = dst_l;
2529
              for (node = src->var_part[i].loc_chain, ii = 0; node;
2530
                   node = node->next, ii++)
2531
                {
2532
                  /* Find location from NODE.  */
2533
                  for (jj = 0; jj < dst_l; jj++)
2534
                    {
2535
                      if ((REG_P (vui[jj].lc->loc)
2536
                           && REG_P (node->loc)
2537
                           && REGNO (vui[jj].lc->loc) == REGNO (node->loc))
2538
                          || rtx_equal_p (vui[jj].lc->loc, node->loc))
2539
                        {
2540
                          vui[jj].pos = jj + ii;
2541
                          break;
2542
                        }
2543
                    }
2544
                  if (jj >= dst_l)      /* The location has not been found.  */
2545
                    {
2546
                      location_chain new_node;
2547
 
2548
                      /* Copy the location from SRC.  */
2549
                      new_node = (location_chain) pool_alloc (loc_chain_pool);
2550
                      new_node->loc = node->loc;
2551
                      new_node->init = node->init;
2552
                      if (!node->set_src || MEM_P (node->set_src))
2553
                        new_node->set_src = NULL;
2554
                      else
2555
                        new_node->set_src = node->set_src;
2556
                      vui[n].lc = new_node;
2557
                      vui[n].pos_dst = src_l + dst_l;
2558
                      vui[n].pos = ii + src_l + dst_l;
2559
                      n++;
2560
                    }
2561
                }
2562
 
2563
              if (dst_l == 2)
2564
                {
2565
                  /* Special case still very common case.  For dst_l == 2
2566
                     all entries dst_l ... n-1 are sorted, with for i >= dst_l
2567
                     vui[i].pos == i + src_l + dst_l.  */
2568
                  if (vui[0].pos > vui[1].pos)
2569
                    {
2570
                      /* Order should be 1, 0, 2... */
2571
                      dst->var_part[k].loc_chain = vui[1].lc;
2572
                      vui[1].lc->next = vui[0].lc;
2573
                      if (n >= 3)
2574
                        {
2575
                          vui[0].lc->next = vui[2].lc;
2576
                          vui[n - 1].lc->next = NULL;
2577
                        }
2578
                      else
2579
                        vui[0].lc->next = NULL;
2580
                      ii = 3;
2581
                    }
2582
                  else
2583
                    {
2584
                      dst->var_part[k].loc_chain = vui[0].lc;
2585
                      if (n >= 3 && vui[2].pos < vui[1].pos)
2586
                        {
2587
                          /* Order should be 0, 2, 1, 3... */
2588
                          vui[0].lc->next = vui[2].lc;
2589
                          vui[2].lc->next = vui[1].lc;
2590
                          if (n >= 4)
2591
                            {
2592
                              vui[1].lc->next = vui[3].lc;
2593
                              vui[n - 1].lc->next = NULL;
2594
                            }
2595
                          else
2596
                            vui[1].lc->next = NULL;
2597
                          ii = 4;
2598
                        }
2599
                      else
2600
                        {
2601
                          /* Order should be 0, 1, 2... */
2602
                          ii = 1;
2603
                          vui[n - 1].lc->next = NULL;
2604
                        }
2605
                    }
2606
                  for (; ii < n; ii++)
2607
                    vui[ii - 1].lc->next = vui[ii].lc;
2608
                }
2609
              else
2610
                {
2611
                  qsort (vui, n, sizeof (struct variable_union_info),
2612
                         variable_union_info_cmp_pos);
2613
 
2614
                  /* Reconnect the nodes in sorted order.  */
2615
                  for (ii = 1; ii < n; ii++)
2616
                    vui[ii - 1].lc->next = vui[ii].lc;
2617
                  vui[n - 1].lc->next = NULL;
2618
                  dst->var_part[k].loc_chain = vui[0].lc;
2619
                }
2620
 
2621
              VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (dst, j);
2622
            }
2623
          i--;
2624
          j--;
2625
        }
2626
      else if ((i >= 0 && j >= 0
2627
                && VAR_PART_OFFSET (src, i) < VAR_PART_OFFSET (dst, j))
2628
               || i < 0)
2629
        {
2630
          dst->var_part[k] = dst->var_part[j];
2631
          j--;
2632
        }
2633
      else if ((i >= 0 && j >= 0
2634
                && VAR_PART_OFFSET (src, i) > VAR_PART_OFFSET (dst, j))
2635
               || j < 0)
2636
        {
2637
          location_chain *nextp;
2638
 
2639
          /* Copy the chain from SRC.  */
2640
          nextp = &dst->var_part[k].loc_chain;
2641
          for (node = src->var_part[i].loc_chain; node; node = node->next)
2642
            {
2643
              location_chain new_lc;
2644
 
2645
              new_lc = (location_chain) pool_alloc (loc_chain_pool);
2646
              new_lc->next = NULL;
2647
              new_lc->init = node->init;
2648
              if (!node->set_src || MEM_P (node->set_src))
2649
                new_lc->set_src = NULL;
2650
              else
2651
                new_lc->set_src = node->set_src;
2652
              new_lc->loc = node->loc;
2653
 
2654
              *nextp = new_lc;
2655
              nextp = &new_lc->next;
2656
            }
2657
 
2658
          VAR_PART_OFFSET (dst, k) = VAR_PART_OFFSET (src, i);
2659
          i--;
2660
        }
2661
      dst->var_part[k].cur_loc = NULL;
2662
    }
2663
 
2664
  if (flag_var_tracking_uninit)
2665
    for (i = 0; i < src->n_var_parts && i < dst->n_var_parts; i++)
2666
      {
2667
        location_chain node, node2;
2668
        for (node = src->var_part[i].loc_chain; node; node = node->next)
2669
          for (node2 = dst->var_part[i].loc_chain; node2; node2 = node2->next)
2670
            if (rtx_equal_p (node->loc, node2->loc))
2671
              {
2672
                if (node->init > node2->init)
2673
                  node2->init = node->init;
2674
              }
2675
      }
2676
 
2677
  /* Continue traversing the hash table.  */
2678
  return 1;
2679
}
2680
 
2681
/* Compute union of dataflow sets SRC and DST and store it to DST.  */
2682
 
2683
static void
2684
dataflow_set_union (dataflow_set *dst, dataflow_set *src)
2685
{
2686
  int i;
2687
 
2688
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2689
    attrs_list_union (&dst->regs[i], src->regs[i]);
2690
 
2691
  if (dst->vars == empty_shared_hash)
2692
    {
2693
      shared_hash_destroy (dst->vars);
2694
      dst->vars = shared_hash_copy (src->vars);
2695
    }
2696
  else
2697
    {
2698
      htab_iterator hi;
2699
      variable var;
2700
 
2701
      FOR_EACH_HTAB_ELEMENT (shared_hash_htab (src->vars), var, variable, hi)
2702
        variable_union (var, dst);
2703
    }
2704
}
2705
 
2706
/* Whether the value is currently being expanded.  */
2707
#define VALUE_RECURSED_INTO(x) \
2708
  (RTL_FLAG_CHECK2 ("VALUE_RECURSED_INTO", (x), VALUE, DEBUG_EXPR)->used)
2709
 
2710
/* Whether no expansion was found, saving useless lookups.
2711
   It must only be set when VALUE_CHANGED is clear.  */
2712
#define NO_LOC_P(x) \
2713
  (RTL_FLAG_CHECK2 ("NO_LOC_P", (x), VALUE, DEBUG_EXPR)->return_val)
2714
 
2715
/* Whether cur_loc in the value needs to be (re)computed.  */
2716
#define VALUE_CHANGED(x) \
2717
  (RTL_FLAG_CHECK1 ("VALUE_CHANGED", (x), VALUE)->frame_related)
2718
/* Whether cur_loc in the decl needs to be (re)computed.  */
2719
#define DECL_CHANGED(x) TREE_VISITED (x)
2720
 
2721
/* Record (if NEWV) that DV needs to have its cur_loc recomputed.  For
2722
   user DECLs, this means they're in changed_variables.  Values and
2723
   debug exprs may be left with this flag set if no user variable
2724
   requires them to be evaluated.  */
2725
 
2726
static inline void
2727
set_dv_changed (decl_or_value dv, bool newv)
2728
{
2729
  switch (dv_onepart_p (dv))
2730
    {
2731
    case ONEPART_VALUE:
2732
      if (newv)
2733
        NO_LOC_P (dv_as_value (dv)) = false;
2734
      VALUE_CHANGED (dv_as_value (dv)) = newv;
2735
      break;
2736
 
2737
    case ONEPART_DEXPR:
2738
      if (newv)
2739
        NO_LOC_P (DECL_RTL_KNOWN_SET (dv_as_decl (dv))) = false;
2740
      /* Fall through...  */
2741
 
2742
    default:
2743
      DECL_CHANGED (dv_as_decl (dv)) = newv;
2744
      break;
2745
    }
2746
}
2747
 
2748
/* Return true if DV needs to have its cur_loc recomputed.  */
2749
 
2750
static inline bool
2751
dv_changed_p (decl_or_value dv)
2752
{
2753
  return (dv_is_value_p (dv)
2754
          ? VALUE_CHANGED (dv_as_value (dv))
2755
          : DECL_CHANGED (dv_as_decl (dv)));
2756
}
2757
 
2758
/* Return a location list node whose loc is rtx_equal to LOC, in the
2759
   location list of a one-part variable or value VAR, or in that of
2760
   any values recursively mentioned in the location lists.  VARS must
2761
   be in star-canonical form.  */
2762
 
2763
static location_chain
2764
find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
2765
{
2766
  location_chain node;
2767
  enum rtx_code loc_code;
2768
 
2769
  if (!var)
2770
    return NULL;
2771
 
2772
  gcc_checking_assert (var->onepart);
2773
 
2774
  if (!var->n_var_parts)
2775
    return NULL;
2776
 
2777
  gcc_checking_assert (loc != dv_as_opaque (var->dv));
2778
 
2779
  loc_code = GET_CODE (loc);
2780
  for (node = var->var_part[0].loc_chain; node; node = node->next)
2781
    {
2782
      decl_or_value dv;
2783
      variable rvar;
2784
 
2785
      if (GET_CODE (node->loc) != loc_code)
2786
        {
2787
          if (GET_CODE (node->loc) != VALUE)
2788
            continue;
2789
        }
2790
      else if (loc == node->loc)
2791
        return node;
2792
      else if (loc_code != VALUE)
2793
        {
2794
          if (rtx_equal_p (loc, node->loc))
2795
            return node;
2796
          continue;
2797
        }
2798
 
2799
      /* Since we're in star-canonical form, we don't need to visit
2800
         non-canonical nodes: one-part variables and non-canonical
2801
         values would only point back to the canonical node.  */
2802
      if (dv_is_value_p (var->dv)
2803
          && !canon_value_cmp (node->loc, dv_as_value (var->dv)))
2804
        {
2805
          /* Skip all subsequent VALUEs.  */
2806
          while (node->next && GET_CODE (node->next->loc) == VALUE)
2807
            {
2808
              node = node->next;
2809
              gcc_checking_assert (!canon_value_cmp (node->loc,
2810
                                                     dv_as_value (var->dv)));
2811
              if (loc == node->loc)
2812
                return node;
2813
            }
2814
          continue;
2815
        }
2816
 
2817
      gcc_checking_assert (node == var->var_part[0].loc_chain);
2818
      gcc_checking_assert (!node->next);
2819
 
2820
      dv = dv_from_value (node->loc);
2821
      rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
2822
      return find_loc_in_1pdv (loc, rvar, vars);
2823
    }
2824
 
2825
  /* ??? Gotta look in cselib_val locations too.  */
2826
 
2827
  return NULL;
2828
}
2829
 
2830
/* Hash table iteration argument passed to variable_merge.  */
2831
struct dfset_merge
2832
{
2833
  /* The set in which the merge is to be inserted.  */
2834
  dataflow_set *dst;
2835
  /* The set that we're iterating in.  */
2836
  dataflow_set *cur;
2837
  /* The set that may contain the other dv we are to merge with.  */
2838
  dataflow_set *src;
2839
  /* Number of onepart dvs in src.  */
2840
  int src_onepart_cnt;
2841
};
2842
 
2843
/* Insert LOC in *DNODE, if it's not there yet.  The list must be in
2844
   loc_cmp order, and it is maintained as such.  */
2845
 
2846
static void
2847
insert_into_intersection (location_chain *nodep, rtx loc,
2848
                          enum var_init_status status)
2849
{
2850
  location_chain node;
2851
  int r;
2852
 
2853
  for (node = *nodep; node; nodep = &node->next, node = *nodep)
2854
    if ((r = loc_cmp (node->loc, loc)) == 0)
2855
      {
2856
        node->init = MIN (node->init, status);
2857
        return;
2858
      }
2859
    else if (r > 0)
2860
      break;
2861
 
2862
  node = (location_chain) pool_alloc (loc_chain_pool);
2863
 
2864
  node->loc = loc;
2865
  node->set_src = NULL;
2866
  node->init = status;
2867
  node->next = *nodep;
2868
  *nodep = node;
2869
}
2870
 
2871
/* Insert in DEST the intersection of the locations present in both
2872
   S1NODE and S2VAR, directly or indirectly.  S1NODE is from a
2873
   variable in DSM->cur, whereas S2VAR is from DSM->src.  dvar is in
2874
   DSM->dst.  */
2875
 
2876
static void
2877
intersect_loc_chains (rtx val, location_chain *dest, struct dfset_merge *dsm,
2878
                      location_chain s1node, variable s2var)
2879
{
2880
  dataflow_set *s1set = dsm->cur;
2881
  dataflow_set *s2set = dsm->src;
2882
  location_chain found;
2883
 
2884
  if (s2var)
2885
    {
2886
      location_chain s2node;
2887
 
2888
      gcc_checking_assert (s2var->onepart);
2889
 
2890
      if (s2var->n_var_parts)
2891
        {
2892
          s2node = s2var->var_part[0].loc_chain;
2893
 
2894
          for (; s1node && s2node;
2895
               s1node = s1node->next, s2node = s2node->next)
2896
            if (s1node->loc != s2node->loc)
2897
              break;
2898
            else if (s1node->loc == val)
2899
              continue;
2900
            else
2901
              insert_into_intersection (dest, s1node->loc,
2902
                                        MIN (s1node->init, s2node->init));
2903
        }
2904
    }
2905
 
2906
  for (; s1node; s1node = s1node->next)
2907
    {
2908
      if (s1node->loc == val)
2909
        continue;
2910
 
2911
      if ((found = find_loc_in_1pdv (s1node->loc, s2var,
2912
                                     shared_hash_htab (s2set->vars))))
2913
        {
2914
          insert_into_intersection (dest, s1node->loc,
2915
                                    MIN (s1node->init, found->init));
2916
          continue;
2917
        }
2918
 
2919
      if (GET_CODE (s1node->loc) == VALUE
2920
          && !VALUE_RECURSED_INTO (s1node->loc))
2921
        {
2922
          decl_or_value dv = dv_from_value (s1node->loc);
2923
          variable svar = shared_hash_find (s1set->vars, dv);
2924
          if (svar)
2925
            {
2926
              if (svar->n_var_parts == 1)
2927
                {
2928
                  VALUE_RECURSED_INTO (s1node->loc) = true;
2929
                  intersect_loc_chains (val, dest, dsm,
2930
                                        svar->var_part[0].loc_chain,
2931
                                        s2var);
2932
                  VALUE_RECURSED_INTO (s1node->loc) = false;
2933
                }
2934
            }
2935
        }
2936
 
2937
      /* ??? gotta look in cselib_val locations too.  */
2938
 
2939
      /* ??? if the location is equivalent to any location in src,
2940
         searched recursively
2941
 
2942
           add to dst the values needed to represent the equivalence
2943
 
2944
     telling whether locations S is equivalent to another dv's
2945
     location list:
2946
 
2947
       for each location D in the list
2948
 
2949
         if S and D satisfy rtx_equal_p, then it is present
2950
 
2951
         else if D is a value, recurse without cycles
2952
 
2953
         else if S and D have the same CODE and MODE
2954
 
2955
           for each operand oS and the corresponding oD
2956
 
2957
             if oS and oD are not equivalent, then S an D are not equivalent
2958
 
2959
             else if they are RTX vectors
2960
 
2961
               if any vector oS element is not equivalent to its respective oD,
2962
               then S and D are not equivalent
2963
 
2964
   */
2965
 
2966
 
2967
    }
2968
}
2969
 
2970
/* Return -1 if X should be before Y in a location list for a 1-part
2971
   variable, 1 if Y should be before X, and 0 if they're equivalent
2972
   and should not appear in the list.  */
2973
 
2974
static int
2975
loc_cmp (rtx x, rtx y)
2976
{
2977
  int i, j, r;
2978
  RTX_CODE code = GET_CODE (x);
2979
  const char *fmt;
2980
 
2981
  if (x == y)
2982
    return 0;
2983
 
2984
  if (REG_P (x))
2985
    {
2986
      if (!REG_P (y))
2987
        return -1;
2988
      gcc_assert (GET_MODE (x) == GET_MODE (y));
2989
      if (REGNO (x) == REGNO (y))
2990
        return 0;
2991
      else if (REGNO (x) < REGNO (y))
2992
        return -1;
2993
      else
2994
        return 1;
2995
    }
2996
 
2997
  if (REG_P (y))
2998
    return 1;
2999
 
3000
  if (MEM_P (x))
3001
    {
3002
      if (!MEM_P (y))
3003
        return -1;
3004
      gcc_assert (GET_MODE (x) == GET_MODE (y));
3005
      return loc_cmp (XEXP (x, 0), XEXP (y, 0));
3006
    }
3007
 
3008
  if (MEM_P (y))
3009
    return 1;
3010
 
3011
  if (GET_CODE (x) == VALUE)
3012
    {
3013
      if (GET_CODE (y) != VALUE)
3014
        return -1;
3015
      /* Don't assert the modes are the same, that is true only
3016
         when not recursing.  (subreg:QI (value:SI 1:1) 0)
3017
         and (subreg:QI (value:DI 2:2) 0) can be compared,
3018
         even when the modes are different.  */
3019
      if (canon_value_cmp (x, y))
3020
        return -1;
3021
      else
3022
        return 1;
3023
    }
3024
 
3025
  if (GET_CODE (y) == VALUE)
3026
    return 1;
3027
 
3028
  /* Entry value is the least preferable kind of expression.  */
3029
  if (GET_CODE (x) == ENTRY_VALUE)
3030
    {
3031
      if (GET_CODE (y) != ENTRY_VALUE)
3032
        return 1;
3033
      gcc_assert (GET_MODE (x) == GET_MODE (y));
3034
      return loc_cmp (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
3035
    }
3036
 
3037
  if (GET_CODE (y) == ENTRY_VALUE)
3038
    return -1;
3039
 
3040
  if (GET_CODE (x) == GET_CODE (y))
3041
    /* Compare operands below.  */;
3042
  else if (GET_CODE (x) < GET_CODE (y))
3043
    return -1;
3044
  else
3045
    return 1;
3046
 
3047
  gcc_assert (GET_MODE (x) == GET_MODE (y));
3048
 
3049
  if (GET_CODE (x) == DEBUG_EXPR)
3050
    {
3051
      if (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3052
          < DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)))
3053
        return -1;
3054
      gcc_checking_assert (DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x))
3055
                           > DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (y)));
3056
      return 1;
3057
    }
3058
 
3059
  fmt = GET_RTX_FORMAT (code);
3060
  for (i = 0; i < GET_RTX_LENGTH (code); i++)
3061
    switch (fmt[i])
3062
      {
3063
      case 'w':
3064
        if (XWINT (x, i) == XWINT (y, i))
3065
          break;
3066
        else if (XWINT (x, i) < XWINT (y, i))
3067
          return -1;
3068
        else
3069
          return 1;
3070
 
3071
      case 'n':
3072
      case 'i':
3073
        if (XINT (x, i) == XINT (y, i))
3074
          break;
3075
        else if (XINT (x, i) < XINT (y, i))
3076
          return -1;
3077
        else
3078
          return 1;
3079
 
3080
      case 'V':
3081
      case 'E':
3082
        /* Compare the vector length first.  */
3083
        if (XVECLEN (x, i) == XVECLEN (y, i))
3084
          /* Compare the vectors elements.  */;
3085
        else if (XVECLEN (x, i) < XVECLEN (y, i))
3086
          return -1;
3087
        else
3088
          return 1;
3089
 
3090
        for (j = 0; j < XVECLEN (x, i); j++)
3091
          if ((r = loc_cmp (XVECEXP (x, i, j),
3092
                            XVECEXP (y, i, j))))
3093
            return r;
3094
        break;
3095
 
3096
      case 'e':
3097
        if ((r = loc_cmp (XEXP (x, i), XEXP (y, i))))
3098
          return r;
3099
        break;
3100
 
3101
      case 'S':
3102
      case 's':
3103
        if (XSTR (x, i) == XSTR (y, i))
3104
          break;
3105
        if (!XSTR (x, i))
3106
          return -1;
3107
        if (!XSTR (y, i))
3108
          return 1;
3109
        if ((r = strcmp (XSTR (x, i), XSTR (y, i))) == 0)
3110
          break;
3111
        else if (r < 0)
3112
          return -1;
3113
        else
3114
          return 1;
3115
 
3116
      case 'u':
3117
        /* These are just backpointers, so they don't matter.  */
3118
        break;
3119
 
3120
      case '0':
3121
      case 't':
3122
        break;
3123
 
3124
        /* It is believed that rtx's at this level will never
3125
           contain anything but integers and other rtx's,
3126
           except for within LABEL_REFs and SYMBOL_REFs.  */
3127
      default:
3128
        gcc_unreachable ();
3129
      }
3130
 
3131
  return 0;
3132
}
3133
 
3134
#if ENABLE_CHECKING
3135
/* Check the order of entries in one-part variables.   */
3136
 
3137
static int
3138
canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
3139
{
3140
  variable var = (variable) *slot;
3141
  location_chain node, next;
3142
 
3143
#ifdef ENABLE_RTL_CHECKING
3144
  int i;
3145
  for (i = 0; i < var->n_var_parts; i++)
3146
    gcc_assert (var->var_part[0].cur_loc == NULL);
3147
  gcc_assert (!var->in_changed_variables);
3148
#endif
3149
 
3150
  if (!var->onepart)
3151
    return 1;
3152
 
3153
  gcc_assert (var->n_var_parts == 1);
3154
  node = var->var_part[0].loc_chain;
3155
  gcc_assert (node);
3156
 
3157
  while ((next = node->next))
3158
    {
3159
      gcc_assert (loc_cmp (node->loc, next->loc) < 0);
3160
      node = next;
3161
    }
3162
 
3163
  return 1;
3164
}
3165
#endif
3166
 
3167
/* Mark with VALUE_RECURSED_INTO values that have neighbors that are
3168
   more likely to be chosen as canonical for an equivalence set.
3169
   Ensure less likely values can reach more likely neighbors, making
3170
   the connections bidirectional.  */
3171
 
3172
static int
3173
canonicalize_values_mark (void **slot, void *data)
3174
{
3175
  dataflow_set *set = (dataflow_set *)data;
3176
  variable var = (variable) *slot;
3177
  decl_or_value dv = var->dv;
3178
  rtx val;
3179
  location_chain node;
3180
 
3181
  if (!dv_is_value_p (dv))
3182
    return 1;
3183
 
3184
  gcc_checking_assert (var->n_var_parts == 1);
3185
 
3186
  val = dv_as_value (dv);
3187
 
3188
  for (node = var->var_part[0].loc_chain; node; node = node->next)
3189
    if (GET_CODE (node->loc) == VALUE)
3190
      {
3191
        if (canon_value_cmp (node->loc, val))
3192
          VALUE_RECURSED_INTO (val) = true;
3193
        else
3194
          {
3195
            decl_or_value odv = dv_from_value (node->loc);
3196
            void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
3197
 
3198
            set_slot_part (set, val, oslot, odv, 0,
3199
                           node->init, NULL_RTX);
3200
 
3201
            VALUE_RECURSED_INTO (node->loc) = true;
3202
          }
3203
      }
3204
 
3205
  return 1;
3206
}
3207
 
3208
/* Remove redundant entries from equivalence lists in onepart
3209
   variables, canonicalizing equivalence sets into star shapes.  */
3210
 
3211
static int
3212
canonicalize_values_star (void **slot, void *data)
3213
{
3214
  dataflow_set *set = (dataflow_set *)data;
3215
  variable var = (variable) *slot;
3216
  decl_or_value dv = var->dv;
3217
  location_chain node;
3218
  decl_or_value cdv;
3219
  rtx val, cval;
3220
  void **cslot;
3221
  bool has_value;
3222
  bool has_marks;
3223
 
3224
  if (!var->onepart)
3225
    return 1;
3226
 
3227
  gcc_checking_assert (var->n_var_parts == 1);
3228
 
3229
  if (dv_is_value_p (dv))
3230
    {
3231
      cval = dv_as_value (dv);
3232
      if (!VALUE_RECURSED_INTO (cval))
3233
        return 1;
3234
      VALUE_RECURSED_INTO (cval) = false;
3235
    }
3236
  else
3237
    cval = NULL_RTX;
3238
 
3239
 restart:
3240
  val = cval;
3241
  has_value = false;
3242
  has_marks = false;
3243
 
3244
  gcc_assert (var->n_var_parts == 1);
3245
 
3246
  for (node = var->var_part[0].loc_chain; node; node = node->next)
3247
    if (GET_CODE (node->loc) == VALUE)
3248
      {
3249
        has_value = true;
3250
        if (VALUE_RECURSED_INTO (node->loc))
3251
          has_marks = true;
3252
        if (canon_value_cmp (node->loc, cval))
3253
          cval = node->loc;
3254
      }
3255
 
3256
  if (!has_value)
3257
    return 1;
3258
 
3259
  if (cval == val)
3260
    {
3261
      if (!has_marks || dv_is_decl_p (dv))
3262
        return 1;
3263
 
3264
      /* Keep it marked so that we revisit it, either after visiting a
3265
         child node, or after visiting a new parent that might be
3266
         found out.  */
3267
      VALUE_RECURSED_INTO (val) = true;
3268
 
3269
      for (node = var->var_part[0].loc_chain; node; node = node->next)
3270
        if (GET_CODE (node->loc) == VALUE
3271
            && VALUE_RECURSED_INTO (node->loc))
3272
          {
3273
            cval = node->loc;
3274
          restart_with_cval:
3275
            VALUE_RECURSED_INTO (cval) = false;
3276
            dv = dv_from_value (cval);
3277
            slot = shared_hash_find_slot_noinsert (set->vars, dv);
3278
            if (!slot)
3279
              {
3280
                gcc_assert (dv_is_decl_p (var->dv));
3281
                /* The canonical value was reset and dropped.
3282
                   Remove it.  */
3283
                clobber_variable_part (set, NULL, var->dv, 0, NULL);
3284
                return 1;
3285
              }
3286
            var = (variable)*slot;
3287
            gcc_assert (dv_is_value_p (var->dv));
3288
            if (var->n_var_parts == 0)
3289
              return 1;
3290
            gcc_assert (var->n_var_parts == 1);
3291
            goto restart;
3292
          }
3293
 
3294
      VALUE_RECURSED_INTO (val) = false;
3295
 
3296
      return 1;
3297
    }
3298
 
3299
  /* Push values to the canonical one.  */
3300
  cdv = dv_from_value (cval);
3301
  cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3302
 
3303
  for (node = var->var_part[0].loc_chain; node; node = node->next)
3304
    if (node->loc != cval)
3305
      {
3306
        cslot = set_slot_part (set, node->loc, cslot, cdv, 0,
3307
                               node->init, NULL_RTX);
3308
        if (GET_CODE (node->loc) == VALUE)
3309
          {
3310
            decl_or_value ndv = dv_from_value (node->loc);
3311
 
3312
            set_variable_part (set, cval, ndv, 0, node->init, NULL_RTX,
3313
                               NO_INSERT);
3314
 
3315
            if (canon_value_cmp (node->loc, val))
3316
              {
3317
                /* If it could have been a local minimum, it's not any more,
3318
                   since it's now neighbor to cval, so it may have to push
3319
                   to it.  Conversely, if it wouldn't have prevailed over
3320
                   val, then whatever mark it has is fine: if it was to
3321
                   push, it will now push to a more canonical node, but if
3322
                   it wasn't, then it has already pushed any values it might
3323
                   have to.  */
3324
                VALUE_RECURSED_INTO (node->loc) = true;
3325
                /* Make sure we visit node->loc by ensuring we cval is
3326
                   visited too.  */
3327
                VALUE_RECURSED_INTO (cval) = true;
3328
              }
3329
            else if (!VALUE_RECURSED_INTO (node->loc))
3330
              /* If we have no need to "recurse" into this node, it's
3331
                 already "canonicalized", so drop the link to the old
3332
                 parent.  */
3333
              clobber_variable_part (set, cval, ndv, 0, NULL);
3334
          }
3335
        else if (GET_CODE (node->loc) == REG)
3336
          {
3337
            attrs list = set->regs[REGNO (node->loc)], *listp;
3338
 
3339
            /* Change an existing attribute referring to dv so that it
3340
               refers to cdv, removing any duplicate this might
3341
               introduce, and checking that no previous duplicates
3342
               existed, all in a single pass.  */
3343
 
3344
            while (list)
3345
              {
3346
                if (list->offset == 0
3347
                    && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3348
                        || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3349
                  break;
3350
 
3351
                list = list->next;
3352
              }
3353
 
3354
            gcc_assert (list);
3355
            if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3356
              {
3357
                list->dv = cdv;
3358
                for (listp = &list->next; (list = *listp); listp = &list->next)
3359
                  {
3360
                    if (list->offset)
3361
                      continue;
3362
 
3363
                    if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3364
                      {
3365
                        *listp = list->next;
3366
                        pool_free (attrs_pool, list);
3367
                        list = *listp;
3368
                        break;
3369
                      }
3370
 
3371
                    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (dv));
3372
                  }
3373
              }
3374
            else if (dv_as_opaque (list->dv) == dv_as_opaque (cdv))
3375
              {
3376
                for (listp = &list->next; (list = *listp); listp = &list->next)
3377
                  {
3378
                    if (list->offset)
3379
                      continue;
3380
 
3381
                    if (dv_as_opaque (list->dv) == dv_as_opaque (dv))
3382
                      {
3383
                        *listp = list->next;
3384
                        pool_free (attrs_pool, list);
3385
                        list = *listp;
3386
                        break;
3387
                      }
3388
 
3389
                    gcc_assert (dv_as_opaque (list->dv) != dv_as_opaque (cdv));
3390
                  }
3391
              }
3392
            else
3393
              gcc_unreachable ();
3394
 
3395
#if ENABLE_CHECKING
3396
            while (list)
3397
              {
3398
                if (list->offset == 0
3399
                    && (dv_as_opaque (list->dv) == dv_as_opaque (dv)
3400
                        || dv_as_opaque (list->dv) == dv_as_opaque (cdv)))
3401
                  gcc_unreachable ();
3402
 
3403
                list = list->next;
3404
              }
3405
#endif
3406
          }
3407
      }
3408
 
3409
  if (val)
3410
    set_slot_part (set, val, cslot, cdv, 0,
3411
                   VAR_INIT_STATUS_INITIALIZED, NULL_RTX);
3412
 
3413
  slot = clobber_slot_part (set, cval, slot, 0, NULL);
3414
 
3415
  /* Variable may have been unshared.  */
3416
  var = (variable)*slot;
3417
  gcc_checking_assert (var->n_var_parts && var->var_part[0].loc_chain->loc == cval
3418
                       && var->var_part[0].loc_chain->next == NULL);
3419
 
3420
  if (VALUE_RECURSED_INTO (cval))
3421
    goto restart_with_cval;
3422
 
3423
  return 1;
3424
}
3425
 
3426
/* Bind one-part variables to the canonical value in an equivalence
3427
   set.  Not doing this causes dataflow convergence failure in rare
3428
   circumstances, see PR42873.  Unfortunately we can't do this
3429
   efficiently as part of canonicalize_values_star, since we may not
3430
   have determined or even seen the canonical value of a set when we
3431
   get to a variable that references another member of the set.  */
3432
 
3433
static int
3434
canonicalize_vars_star (void **slot, void *data)
3435
{
3436
  dataflow_set *set = (dataflow_set *)data;
3437
  variable var = (variable) *slot;
3438
  decl_or_value dv = var->dv;
3439
  location_chain node;
3440
  rtx cval;
3441
  decl_or_value cdv;
3442
  void **cslot;
3443
  variable cvar;
3444
  location_chain cnode;
3445
 
3446
  if (!var->onepart || var->onepart == ONEPART_VALUE)
3447
    return 1;
3448
 
3449
  gcc_assert (var->n_var_parts == 1);
3450
 
3451
  node = var->var_part[0].loc_chain;
3452
 
3453
  if (GET_CODE (node->loc) != VALUE)
3454
    return 1;
3455
 
3456
  gcc_assert (!node->next);
3457
  cval = node->loc;
3458
 
3459
  /* Push values to the canonical one.  */
3460
  cdv = dv_from_value (cval);
3461
  cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
3462
  if (!cslot)
3463
    return 1;
3464
  cvar = (variable)*cslot;
3465
  gcc_assert (cvar->n_var_parts == 1);
3466
 
3467
  cnode = cvar->var_part[0].loc_chain;
3468
 
3469
  /* CVAL is canonical if its value list contains non-VALUEs or VALUEs
3470
     that are not “more canonical” than it.  */
3471
  if (GET_CODE (cnode->loc) != VALUE
3472
      || !canon_value_cmp (cnode->loc, cval))
3473
    return 1;
3474
 
3475
  /* CVAL was found to be non-canonical.  Change the variable to point
3476
     to the canonical VALUE.  */
3477
  gcc_assert (!cnode->next);
3478
  cval = cnode->loc;
3479
 
3480
  slot = set_slot_part (set, cval, slot, dv, 0,
3481
                        node->init, node->set_src);
3482
  clobber_slot_part (set, cval, slot, 0, node->set_src);
3483
 
3484
  return 1;
3485
}
3486
 
3487
/* Combine variable or value in *S1SLOT (in DSM->cur) with the
3488
   corresponding entry in DSM->src.  Multi-part variables are combined
3489
   with variable_union, whereas onepart dvs are combined with
3490
   intersection.  */
3491
 
3492
static int
3493
variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
3494
{
3495
  dataflow_set *dst = dsm->dst;
3496
  void **dstslot;
3497
  variable s2var, dvar = NULL;
3498
  decl_or_value dv = s1var->dv;
3499
  onepart_enum_t onepart = s1var->onepart;
3500
  rtx val;
3501
  hashval_t dvhash;
3502
  location_chain node, *nodep;
3503
 
3504
  /* If the incoming onepart variable has an empty location list, then
3505
     the intersection will be just as empty.  For other variables,
3506
     it's always union.  */
3507
  gcc_checking_assert (s1var->n_var_parts
3508
                       && s1var->var_part[0].loc_chain);
3509
 
3510
  if (!onepart)
3511
    return variable_union (s1var, dst);
3512
 
3513
  gcc_checking_assert (s1var->n_var_parts == 1);
3514
 
3515
  dvhash = dv_htab_hash (dv);
3516
  if (dv_is_value_p (dv))
3517
    val = dv_as_value (dv);
3518
  else
3519
    val = NULL;
3520
 
3521
  s2var = shared_hash_find_1 (dsm->src->vars, dv, dvhash);
3522
  if (!s2var)
3523
    {
3524
      dst_can_be_shared = false;
3525
      return 1;
3526
    }
3527
 
3528
  dsm->src_onepart_cnt--;
3529
  gcc_assert (s2var->var_part[0].loc_chain
3530
              && s2var->onepart == onepart
3531
              && s2var->n_var_parts == 1);
3532
 
3533
  dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3534
  if (dstslot)
3535
    {
3536
      dvar = (variable)*dstslot;
3537
      gcc_assert (dvar->refcount == 1
3538
                  && dvar->onepart == onepart
3539
                  && dvar->n_var_parts == 1);
3540
      nodep = &dvar->var_part[0].loc_chain;
3541
    }
3542
  else
3543
    {
3544
      nodep = &node;
3545
      node = NULL;
3546
    }
3547
 
3548
  if (!dstslot && !onepart_variable_different_p (s1var, s2var))
3549
    {
3550
      dstslot = shared_hash_find_slot_unshare_1 (&dst->vars, dv,
3551
                                                 dvhash, INSERT);
3552
      *dstslot = dvar = s2var;
3553
      dvar->refcount++;
3554
    }
3555
  else
3556
    {
3557
      dst_can_be_shared = false;
3558
 
3559
      intersect_loc_chains (val, nodep, dsm,
3560
                            s1var->var_part[0].loc_chain, s2var);
3561
 
3562
      if (!dstslot)
3563
        {
3564
          if (node)
3565
            {
3566
              dvar = (variable) pool_alloc (onepart_pool (onepart));
3567
              dvar->dv = dv;
3568
              dvar->refcount = 1;
3569
              dvar->n_var_parts = 1;
3570
              dvar->onepart = onepart;
3571
              dvar->in_changed_variables = false;
3572
              dvar->var_part[0].loc_chain = node;
3573
              dvar->var_part[0].cur_loc = NULL;
3574
              if (onepart)
3575
                VAR_LOC_1PAUX (dvar) = NULL;
3576
              else
3577
                VAR_PART_OFFSET (dvar, 0) = 0;
3578
 
3579
              dstslot
3580
                = shared_hash_find_slot_unshare_1 (&dst->vars, dv, dvhash,
3581
                                                   INSERT);
3582
              gcc_assert (!*dstslot);
3583
              *dstslot = dvar;
3584
            }
3585
          else
3586
            return 1;
3587
        }
3588
    }
3589
 
3590
  nodep = &dvar->var_part[0].loc_chain;
3591
  while ((node = *nodep))
3592
    {
3593
      location_chain *nextp = &node->next;
3594
 
3595
      if (GET_CODE (node->loc) == REG)
3596
        {
3597
          attrs list;
3598
 
3599
          for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
3600
            if (GET_MODE (node->loc) == GET_MODE (list->loc)
3601
                && dv_is_value_p (list->dv))
3602
              break;
3603
 
3604
          if (!list)
3605
            attrs_list_insert (&dst->regs[REGNO (node->loc)],
3606
                               dv, 0, node->loc);
3607
          /* If this value became canonical for another value that had
3608
             this register, we want to leave it alone.  */
3609
          else if (dv_as_value (list->dv) != val)
3610
            {
3611
              dstslot = set_slot_part (dst, dv_as_value (list->dv),
3612
                                       dstslot, dv, 0,
3613
                                       node->init, NULL_RTX);
3614
              dstslot = delete_slot_part (dst, node->loc, dstslot, 0);
3615
 
3616
              /* Since nextp points into the removed node, we can't
3617
                 use it.  The pointer to the next node moved to nodep.
3618
                 However, if the variable we're walking is unshared
3619
                 during our walk, we'll keep walking the location list
3620
                 of the previously-shared variable, in which case the
3621
                 node won't have been removed, and we'll want to skip
3622
                 it.  That's why we test *nodep here.  */
3623
              if (*nodep != node)
3624
                nextp = nodep;
3625
            }
3626
        }
3627
      else
3628
        /* Canonicalization puts registers first, so we don't have to
3629
           walk it all.  */
3630
        break;
3631
      nodep = nextp;
3632
    }
3633
 
3634
  if (dvar != (variable)*dstslot)
3635
    dvar = (variable)*dstslot;
3636
  nodep = &dvar->var_part[0].loc_chain;
3637
 
3638
  if (val)
3639
    {
3640
      /* Mark all referenced nodes for canonicalization, and make sure
3641
         we have mutual equivalence links.  */
3642
      VALUE_RECURSED_INTO (val) = true;
3643
      for (node = *nodep; node; node = node->next)
3644
        if (GET_CODE (node->loc) == VALUE)
3645
          {
3646
            VALUE_RECURSED_INTO (node->loc) = true;
3647
            set_variable_part (dst, val, dv_from_value (node->loc), 0,
3648
                               node->init, NULL, INSERT);
3649
          }
3650
 
3651
      dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3652
      gcc_assert (*dstslot == dvar);
3653
      canonicalize_values_star (dstslot, dst);
3654
      gcc_checking_assert (dstslot
3655
                           == shared_hash_find_slot_noinsert_1 (dst->vars,
3656
                                                                dv, dvhash));
3657
      dvar = (variable)*dstslot;
3658
    }
3659
  else
3660
    {
3661
      bool has_value = false, has_other = false;
3662
 
3663
      /* If we have one value and anything else, we're going to
3664
         canonicalize this, so make sure all values have an entry in
3665
         the table and are marked for canonicalization.  */
3666
      for (node = *nodep; node; node = node->next)
3667
        {
3668
          if (GET_CODE (node->loc) == VALUE)
3669
            {
3670
              /* If this was marked during register canonicalization,
3671
                 we know we have to canonicalize values.  */
3672
              if (has_value)
3673
                has_other = true;
3674
              has_value = true;
3675
              if (has_other)
3676
                break;
3677
            }
3678
          else
3679
            {
3680
              has_other = true;
3681
              if (has_value)
3682
                break;
3683
            }
3684
        }
3685
 
3686
      if (has_value && has_other)
3687
        {
3688
          for (node = *nodep; node; node = node->next)
3689
            {
3690
              if (GET_CODE (node->loc) == VALUE)
3691
                {
3692
                  decl_or_value dv = dv_from_value (node->loc);
3693
                  void **slot = NULL;
3694
 
3695
                  if (shared_hash_shared (dst->vars))
3696
                    slot = shared_hash_find_slot_noinsert (dst->vars, dv);
3697
                  if (!slot)
3698
                    slot = shared_hash_find_slot_unshare (&dst->vars, dv,
3699
                                                          INSERT);
3700
                  if (!*slot)
3701
                    {
3702
                      variable var = (variable) pool_alloc (onepart_pool
3703
                                                            (ONEPART_VALUE));
3704
                      var->dv = dv;
3705
                      var->refcount = 1;
3706
                      var->n_var_parts = 1;
3707
                      var->onepart = ONEPART_VALUE;
3708
                      var->in_changed_variables = false;
3709
                      var->var_part[0].loc_chain = NULL;
3710
                      var->var_part[0].cur_loc = NULL;
3711
                      VAR_LOC_1PAUX (var) = NULL;
3712
                      *slot = var;
3713
                    }
3714
 
3715
                  VALUE_RECURSED_INTO (node->loc) = true;
3716
                }
3717
            }
3718
 
3719
          dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
3720
          gcc_assert (*dstslot == dvar);
3721
          canonicalize_values_star (dstslot, dst);
3722
          gcc_checking_assert (dstslot
3723
                               == shared_hash_find_slot_noinsert_1 (dst->vars,
3724
                                                                    dv, dvhash));
3725
          dvar = (variable)*dstslot;
3726
        }
3727
    }
3728
 
3729
  if (!onepart_variable_different_p (dvar, s2var))
3730
    {
3731
      variable_htab_free (dvar);
3732
      *dstslot = dvar = s2var;
3733
      dvar->refcount++;
3734
    }
3735
  else if (s2var != s1var && !onepart_variable_different_p (dvar, s1var))
3736
    {
3737
      variable_htab_free (dvar);
3738
      *dstslot = dvar = s1var;
3739
      dvar->refcount++;
3740
      dst_can_be_shared = false;
3741
    }
3742
  else
3743
    dst_can_be_shared = false;
3744
 
3745
  return 1;
3746
}
3747
 
3748
/* Copy s2slot (in DSM->src) to DSM->dst if the variable is a
3749
   multi-part variable.  Unions of multi-part variables and
3750
   intersections of one-part ones will be handled in
3751
   variable_merge_over_cur().  */
3752
 
3753
static int
3754
variable_merge_over_src (variable s2var, struct dfset_merge *dsm)
3755
{
3756
  dataflow_set *dst = dsm->dst;
3757
  decl_or_value dv = s2var->dv;
3758
 
3759
  if (!s2var->onepart)
3760
    {
3761
      void **dstp = shared_hash_find_slot (dst->vars, dv);
3762
      *dstp = s2var;
3763
      s2var->refcount++;
3764
      return 1;
3765
    }
3766
 
3767
  dsm->src_onepart_cnt++;
3768
  return 1;
3769
}
3770
 
3771
/* Combine dataflow set information from SRC2 into DST, using PDST
3772
   to carry over information across passes.  */
3773
 
3774
static void
3775
dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
3776
{
3777
  dataflow_set cur = *dst;
3778
  dataflow_set *src1 = &cur;
3779
  struct dfset_merge dsm;
3780
  int i;
3781
  size_t src1_elems, src2_elems;
3782
  htab_iterator hi;
3783
  variable var;
3784
 
3785
  src1_elems = htab_elements (shared_hash_htab (src1->vars));
3786
  src2_elems = htab_elements (shared_hash_htab (src2->vars));
3787
  dataflow_set_init (dst);
3788
  dst->stack_adjust = cur.stack_adjust;
3789
  shared_hash_destroy (dst->vars);
3790
  dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
3791
  dst->vars->refcount = 1;
3792
  dst->vars->htab
3793
    = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
3794
                   variable_htab_eq, variable_htab_free);
3795
 
3796
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3797
    attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
3798
 
3799
  dsm.dst = dst;
3800
  dsm.src = src2;
3801
  dsm.cur = src1;
3802
  dsm.src_onepart_cnt = 0;
3803
 
3804
  FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.src->vars), var, variable, hi)
3805
    variable_merge_over_src (var, &dsm);
3806
  FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.cur->vars), var, variable, hi)
3807
    variable_merge_over_cur (var, &dsm);
3808
 
3809
  if (dsm.src_onepart_cnt)
3810
    dst_can_be_shared = false;
3811
 
3812
  dataflow_set_destroy (src1);
3813
}
3814
 
3815
/* Mark register equivalences.  */
3816
 
3817
static void
3818
dataflow_set_equiv_regs (dataflow_set *set)
3819
{
3820
  int i;
3821
  attrs list, *listp;
3822
 
3823
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3824
    {
3825
      rtx canon[NUM_MACHINE_MODES];
3826
 
3827
      /* If the list is empty or one entry, no need to canonicalize
3828
         anything.  */
3829
      if (set->regs[i] == NULL || set->regs[i]->next == NULL)
3830
        continue;
3831
 
3832
      memset (canon, 0, sizeof (canon));
3833
 
3834
      for (list = set->regs[i]; list; list = list->next)
3835
        if (list->offset == 0 && dv_is_value_p (list->dv))
3836
          {
3837
            rtx val = dv_as_value (list->dv);
3838
            rtx *cvalp = &canon[(int)GET_MODE (val)];
3839
            rtx cval = *cvalp;
3840
 
3841
            if (canon_value_cmp (val, cval))
3842
              *cvalp = val;
3843
          }
3844
 
3845
      for (list = set->regs[i]; list; list = list->next)
3846
        if (list->offset == 0 && dv_onepart_p (list->dv))
3847
          {
3848
            rtx cval = canon[(int)GET_MODE (list->loc)];
3849
 
3850
            if (!cval)
3851
              continue;
3852
 
3853
            if (dv_is_value_p (list->dv))
3854
              {
3855
                rtx val = dv_as_value (list->dv);
3856
 
3857
                if (val == cval)
3858
                  continue;
3859
 
3860
                VALUE_RECURSED_INTO (val) = true;
3861
                set_variable_part (set, val, dv_from_value (cval), 0,
3862
                                   VAR_INIT_STATUS_INITIALIZED,
3863
                                   NULL, NO_INSERT);
3864
              }
3865
 
3866
            VALUE_RECURSED_INTO (cval) = true;
3867
            set_variable_part (set, cval, list->dv, 0,
3868
                               VAR_INIT_STATUS_INITIALIZED, NULL, NO_INSERT);
3869
          }
3870
 
3871
      for (listp = &set->regs[i]; (list = *listp);
3872
           listp = list ? &list->next : listp)
3873
        if (list->offset == 0 && dv_onepart_p (list->dv))
3874
          {
3875
            rtx cval = canon[(int)GET_MODE (list->loc)];
3876
            void **slot;
3877
 
3878
            if (!cval)
3879
              continue;
3880
 
3881
            if (dv_is_value_p (list->dv))
3882
              {
3883
                rtx val = dv_as_value (list->dv);
3884
                if (!VALUE_RECURSED_INTO (val))
3885
                  continue;
3886
              }
3887
 
3888
            slot = shared_hash_find_slot_noinsert (set->vars, list->dv);
3889
            canonicalize_values_star (slot, set);
3890
            if (*listp != list)
3891
              list = NULL;
3892
          }
3893
    }
3894
}
3895
 
3896
/* Remove any redundant values in the location list of VAR, which must
3897
   be unshared and 1-part.  */
3898
 
3899
static void
3900
remove_duplicate_values (variable var)
3901
{
3902
  location_chain node, *nodep;
3903
 
3904
  gcc_assert (var->onepart);
3905
  gcc_assert (var->n_var_parts == 1);
3906
  gcc_assert (var->refcount == 1);
3907
 
3908
  for (nodep = &var->var_part[0].loc_chain; (node = *nodep); )
3909
    {
3910
      if (GET_CODE (node->loc) == VALUE)
3911
        {
3912
          if (VALUE_RECURSED_INTO (node->loc))
3913
            {
3914
              /* Remove duplicate value node.  */
3915
              *nodep = node->next;
3916
              pool_free (loc_chain_pool, node);
3917
              continue;
3918
            }
3919
          else
3920
            VALUE_RECURSED_INTO (node->loc) = true;
3921
        }
3922
      nodep = &node->next;
3923
    }
3924
 
3925
  for (node = var->var_part[0].loc_chain; node; node = node->next)
3926
    if (GET_CODE (node->loc) == VALUE)
3927
      {
3928
        gcc_assert (VALUE_RECURSED_INTO (node->loc));
3929
        VALUE_RECURSED_INTO (node->loc) = false;
3930
      }
3931
}
3932
 
3933
 
3934
/* Hash table iteration argument passed to variable_post_merge.  */
3935
struct dfset_post_merge
3936
{
3937
  /* The new input set for the current block.  */
3938
  dataflow_set *set;
3939
  /* Pointer to the permanent input set for the current block, or
3940
     NULL.  */
3941
  dataflow_set **permp;
3942
};
3943
 
3944
/* Create values for incoming expressions associated with one-part
3945
   variables that don't have value numbers for them.  */
3946
 
3947
static int
3948
variable_post_merge_new_vals (void **slot, void *info)
3949
{
3950
  struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
3951
  dataflow_set *set = dfpm->set;
3952
  variable var = (variable)*slot;
3953
  location_chain node;
3954
 
3955
  if (!var->onepart || !var->n_var_parts)
3956
    return 1;
3957
 
3958
  gcc_assert (var->n_var_parts == 1);
3959
 
3960
  if (dv_is_decl_p (var->dv))
3961
    {
3962
      bool check_dupes = false;
3963
 
3964
    restart:
3965
      for (node = var->var_part[0].loc_chain; node; node = node->next)
3966
        {
3967
          if (GET_CODE (node->loc) == VALUE)
3968
            gcc_assert (!VALUE_RECURSED_INTO (node->loc));
3969
          else if (GET_CODE (node->loc) == REG)
3970
            {
3971
              attrs att, *attp, *curp = NULL;
3972
 
3973
              if (var->refcount != 1)
3974
                {
3975
                  slot = unshare_variable (set, slot, var,
3976
                                           VAR_INIT_STATUS_INITIALIZED);
3977
                  var = (variable)*slot;
3978
                  goto restart;
3979
                }
3980
 
3981
              for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
3982
                   attp = &att->next)
3983
                if (att->offset == 0
3984
                    && GET_MODE (att->loc) == GET_MODE (node->loc))
3985
                  {
3986
                    if (dv_is_value_p (att->dv))
3987
                      {
3988
                        rtx cval = dv_as_value (att->dv);
3989
                        node->loc = cval;
3990
                        check_dupes = true;
3991
                        break;
3992
                      }
3993
                    else if (dv_as_opaque (att->dv) == dv_as_opaque (var->dv))
3994
                      curp = attp;
3995
                  }
3996
 
3997
              if (!curp)
3998
                {
3999
                  curp = attp;
4000
                  while (*curp)
4001
                    if ((*curp)->offset == 0
4002
                        && GET_MODE ((*curp)->loc) == GET_MODE (node->loc)
4003
                        && dv_as_opaque ((*curp)->dv) == dv_as_opaque (var->dv))
4004
                      break;
4005
                    else
4006
                      curp = &(*curp)->next;
4007
                  gcc_assert (*curp);
4008
                }
4009
 
4010
              if (!att)
4011
                {
4012
                  decl_or_value cdv;
4013
                  rtx cval;
4014
 
4015
                  if (!*dfpm->permp)
4016
                    {
4017
                      *dfpm->permp = XNEW (dataflow_set);
4018
                      dataflow_set_init (*dfpm->permp);
4019
                    }
4020
 
4021
                  for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
4022
                       att; att = att->next)
4023
                    if (GET_MODE (att->loc) == GET_MODE (node->loc))
4024
                      {
4025
                        gcc_assert (att->offset == 0
4026
                                    && dv_is_value_p (att->dv));
4027
                        val_reset (set, att->dv);
4028
                        break;
4029
                      }
4030
 
4031
                  if (att)
4032
                    {
4033
                      cdv = att->dv;
4034
                      cval = dv_as_value (cdv);
4035
                    }
4036
                  else
4037
                    {
4038
                      /* Create a unique value to hold this register,
4039
                         that ought to be found and reused in
4040
                         subsequent rounds.  */
4041
                      cselib_val *v;
4042
                      gcc_assert (!cselib_lookup (node->loc,
4043
                                                  GET_MODE (node->loc), 0,
4044
                                                  VOIDmode));
4045
                      v = cselib_lookup (node->loc, GET_MODE (node->loc), 1,
4046
                                         VOIDmode);
4047
                      cselib_preserve_value (v);
4048
                      cselib_invalidate_rtx (node->loc);
4049
                      cval = v->val_rtx;
4050
                      cdv = dv_from_value (cval);
4051
                      if (dump_file)
4052
                        fprintf (dump_file,
4053
                                 "Created new value %u:%u for reg %i\n",
4054
                                 v->uid, v->hash, REGNO (node->loc));
4055
                    }
4056
 
4057
                  var_reg_decl_set (*dfpm->permp, node->loc,
4058
                                    VAR_INIT_STATUS_INITIALIZED,
4059
                                    cdv, 0, NULL, INSERT);
4060
 
4061
                  node->loc = cval;
4062
                  check_dupes = true;
4063
                }
4064
 
4065
              /* Remove attribute referring to the decl, which now
4066
                 uses the value for the register, already existing or
4067
                 to be added when we bring perm in.  */
4068
              att = *curp;
4069
              *curp = att->next;
4070
              pool_free (attrs_pool, att);
4071
            }
4072
        }
4073
 
4074
      if (check_dupes)
4075
        remove_duplicate_values (var);
4076
    }
4077
 
4078
  return 1;
4079
}
4080
 
4081
/* Reset values in the permanent set that are not associated with the
4082
   chosen expression.  */
4083
 
4084
static int
4085
variable_post_merge_perm_vals (void **pslot, void *info)
4086
{
4087
  struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
4088
  dataflow_set *set = dfpm->set;
4089
  variable pvar = (variable)*pslot, var;
4090
  location_chain pnode;
4091
  decl_or_value dv;
4092
  attrs att;
4093
 
4094
  gcc_assert (dv_is_value_p (pvar->dv)
4095
              && pvar->n_var_parts == 1);
4096
  pnode = pvar->var_part[0].loc_chain;
4097
  gcc_assert (pnode
4098
              && !pnode->next
4099
              && REG_P (pnode->loc));
4100
 
4101
  dv = pvar->dv;
4102
 
4103
  var = shared_hash_find (set->vars, dv);
4104
  if (var)
4105
    {
4106
      /* Although variable_post_merge_new_vals may have made decls
4107
         non-star-canonical, values that pre-existed in canonical form
4108
         remain canonical, and newly-created values reference a single
4109
         REG, so they are canonical as well.  Since VAR has the
4110
         location list for a VALUE, using find_loc_in_1pdv for it is
4111
         fine, since VALUEs don't map back to DECLs.  */
4112
      if (find_loc_in_1pdv (pnode->loc, var, shared_hash_htab (set->vars)))
4113
        return 1;
4114
      val_reset (set, dv);
4115
    }
4116
 
4117
  for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
4118
    if (att->offset == 0
4119
        && GET_MODE (att->loc) == GET_MODE (pnode->loc)
4120
        && dv_is_value_p (att->dv))
4121
      break;
4122
 
4123
  /* If there is a value associated with this register already, create
4124
     an equivalence.  */
4125
  if (att && dv_as_value (att->dv) != dv_as_value (dv))
4126
    {
4127
      rtx cval = dv_as_value (att->dv);
4128
      set_variable_part (set, cval, dv, 0, pnode->init, NULL, INSERT);
4129
      set_variable_part (set, dv_as_value (dv), att->dv, 0, pnode->init,
4130
                         NULL, INSERT);
4131
    }
4132
  else if (!att)
4133
    {
4134
      attrs_list_insert (&set->regs[REGNO (pnode->loc)],
4135
                         dv, 0, pnode->loc);
4136
      variable_union (pvar, set);
4137
    }
4138
 
4139
  return 1;
4140
}
4141
 
4142
/* Just checking stuff and registering register attributes for
4143
   now.  */
4144
 
4145
static void
4146
dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
4147
{
4148
  struct dfset_post_merge dfpm;
4149
 
4150
  dfpm.set = set;
4151
  dfpm.permp = permp;
4152
 
4153
  htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
4154
                 &dfpm);
4155
  if (*permp)
4156
    htab_traverse (shared_hash_htab ((*permp)->vars),
4157
                   variable_post_merge_perm_vals, &dfpm);
4158
  htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
4159
  htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set);
4160
}
4161
 
4162
/* Return a node whose loc is a MEM that refers to EXPR in the
4163
   location list of a one-part variable or value VAR, or in that of
4164
   any values recursively mentioned in the location lists.  */
4165
 
4166
static location_chain
4167
find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
4168
{
4169
  location_chain node;
4170
  decl_or_value dv;
4171
  variable var;
4172
  location_chain where = NULL;
4173
 
4174
  if (!val)
4175
    return NULL;
4176
 
4177
  gcc_assert (GET_CODE (val) == VALUE
4178
              && !VALUE_RECURSED_INTO (val));
4179
 
4180
  dv = dv_from_value (val);
4181
  var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
4182
 
4183
  if (!var)
4184
    return NULL;
4185
 
4186
  gcc_assert (var->onepart);
4187
 
4188
  if (!var->n_var_parts)
4189
    return NULL;
4190
 
4191
  VALUE_RECURSED_INTO (val) = true;
4192
 
4193
  for (node = var->var_part[0].loc_chain; node; node = node->next)
4194
    if (MEM_P (node->loc)
4195
        && MEM_EXPR (node->loc) == expr
4196
        && INT_MEM_OFFSET (node->loc) == 0)
4197
      {
4198
        where = node;
4199
        break;
4200
      }
4201
    else if (GET_CODE (node->loc) == VALUE
4202
             && !VALUE_RECURSED_INTO (node->loc)
4203
             && (where = find_mem_expr_in_1pdv (expr, node->loc, vars)))
4204
      break;
4205
 
4206
  VALUE_RECURSED_INTO (val) = false;
4207
 
4208
  return where;
4209
}
4210
 
4211
/* Return TRUE if the value of MEM may vary across a call.  */
4212
 
4213
static bool
4214
mem_dies_at_call (rtx mem)
4215
{
4216
  tree expr = MEM_EXPR (mem);
4217
  tree decl;
4218
 
4219
  if (!expr)
4220
    return true;
4221
 
4222
  decl = get_base_address (expr);
4223
 
4224
  if (!decl)
4225
    return true;
4226
 
4227
  if (!DECL_P (decl))
4228
    return true;
4229
 
4230
  return (may_be_aliased (decl)
4231
          || (!TREE_READONLY (decl) && is_global_var (decl)));
4232
}
4233
 
4234
/* Remove all MEMs from the location list of a hash table entry for a
4235
   one-part variable, except those whose MEM attributes map back to
4236
   the variable itself, directly or within a VALUE.  */
4237
 
4238
static int
4239
dataflow_set_preserve_mem_locs (void **slot, void *data)
4240
{
4241
  dataflow_set *set = (dataflow_set *) data;
4242
  variable var = (variable) *slot;
4243
 
4244
  if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
4245
    {
4246
      tree decl = dv_as_decl (var->dv);
4247
      location_chain loc, *locp;
4248
      bool changed = false;
4249
 
4250
      if (!var->n_var_parts)
4251
        return 1;
4252
 
4253
      gcc_assert (var->n_var_parts == 1);
4254
 
4255
      if (shared_var_p (var, set->vars))
4256
        {
4257
          for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4258
            {
4259
              /* We want to remove dying MEMs that doesn't refer to DECL.  */
4260
              if (GET_CODE (loc->loc) == MEM
4261
                  && (MEM_EXPR (loc->loc) != decl
4262
                      || INT_MEM_OFFSET (loc->loc) != 0)
4263
                  && !mem_dies_at_call (loc->loc))
4264
                break;
4265
              /* We want to move here MEMs that do refer to DECL.  */
4266
              else if (GET_CODE (loc->loc) == VALUE
4267
                       && find_mem_expr_in_1pdv (decl, loc->loc,
4268
                                                 shared_hash_htab (set->vars)))
4269
                break;
4270
            }
4271
 
4272
          if (!loc)
4273
            return 1;
4274
 
4275
          slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4276
          var = (variable)*slot;
4277
          gcc_assert (var->n_var_parts == 1);
4278
        }
4279
 
4280
      for (locp = &var->var_part[0].loc_chain, loc = *locp;
4281
           loc; loc = *locp)
4282
        {
4283
          rtx old_loc = loc->loc;
4284
          if (GET_CODE (old_loc) == VALUE)
4285
            {
4286
              location_chain mem_node
4287
                = find_mem_expr_in_1pdv (decl, loc->loc,
4288
                                         shared_hash_htab (set->vars));
4289
 
4290
              /* ??? This picks up only one out of multiple MEMs that
4291
                 refer to the same variable.  Do we ever need to be
4292
                 concerned about dealing with more than one, or, given
4293
                 that they should all map to the same variable
4294
                 location, their addresses will have been merged and
4295
                 they will be regarded as equivalent?  */
4296
              if (mem_node)
4297
                {
4298
                  loc->loc = mem_node->loc;
4299
                  loc->set_src = mem_node->set_src;
4300
                  loc->init = MIN (loc->init, mem_node->init);
4301
                }
4302
            }
4303
 
4304
          if (GET_CODE (loc->loc) != MEM
4305
              || (MEM_EXPR (loc->loc) == decl
4306
                  && INT_MEM_OFFSET (loc->loc) == 0)
4307
              || !mem_dies_at_call (loc->loc))
4308
            {
4309
              if (old_loc != loc->loc && emit_notes)
4310
                {
4311
                  if (old_loc == var->var_part[0].cur_loc)
4312
                    {
4313
                      changed = true;
4314
                      var->var_part[0].cur_loc = NULL;
4315
                    }
4316
                }
4317
              locp = &loc->next;
4318
              continue;
4319
            }
4320
 
4321
          if (emit_notes)
4322
            {
4323
              if (old_loc == var->var_part[0].cur_loc)
4324
                {
4325
                  changed = true;
4326
                  var->var_part[0].cur_loc = NULL;
4327
                }
4328
            }
4329
          *locp = loc->next;
4330
          pool_free (loc_chain_pool, loc);
4331
        }
4332
 
4333
      if (!var->var_part[0].loc_chain)
4334
        {
4335
          var->n_var_parts--;
4336
          changed = true;
4337
        }
4338
      if (changed)
4339
        variable_was_changed (var, set);
4340
    }
4341
 
4342
  return 1;
4343
}
4344
 
4345
/* Remove all MEMs from the location list of a hash table entry for a
4346
   value.  */
4347
 
4348
static int
4349
dataflow_set_remove_mem_locs (void **slot, void *data)
4350
{
4351
  dataflow_set *set = (dataflow_set *) data;
4352
  variable var = (variable) *slot;
4353
 
4354
  if (var->onepart == ONEPART_VALUE)
4355
    {
4356
      location_chain loc, *locp;
4357
      bool changed = false;
4358
      rtx cur_loc;
4359
 
4360
      gcc_assert (var->n_var_parts == 1);
4361
 
4362
      if (shared_var_p (var, set->vars))
4363
        {
4364
          for (loc = var->var_part[0].loc_chain; loc; loc = loc->next)
4365
            if (GET_CODE (loc->loc) == MEM
4366
                && mem_dies_at_call (loc->loc))
4367
              break;
4368
 
4369
          if (!loc)
4370
            return 1;
4371
 
4372
          slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
4373
          var = (variable)*slot;
4374
          gcc_assert (var->n_var_parts == 1);
4375
        }
4376
 
4377
      if (VAR_LOC_1PAUX (var))
4378
        cur_loc = VAR_LOC_FROM (var);
4379
      else
4380
        cur_loc = var->var_part[0].cur_loc;
4381
 
4382
      for (locp = &var->var_part[0].loc_chain, loc = *locp;
4383
           loc; loc = *locp)
4384
        {
4385
          if (GET_CODE (loc->loc) != MEM
4386
              || !mem_dies_at_call (loc->loc))
4387
            {
4388
              locp = &loc->next;
4389
              continue;
4390
            }
4391
 
4392
          *locp = loc->next;
4393
          /* If we have deleted the location which was last emitted
4394
             we have to emit new location so add the variable to set
4395
             of changed variables.  */
4396
          if (cur_loc == loc->loc)
4397
            {
4398
              changed = true;
4399
              var->var_part[0].cur_loc = NULL;
4400
              if (VAR_LOC_1PAUX (var))
4401
                VAR_LOC_FROM (var) = NULL;
4402
            }
4403
          pool_free (loc_chain_pool, loc);
4404
        }
4405
 
4406
      if (!var->var_part[0].loc_chain)
4407
        {
4408
          var->n_var_parts--;
4409
          changed = true;
4410
        }
4411
      if (changed)
4412
        variable_was_changed (var, set);
4413
    }
4414
 
4415
  return 1;
4416
}
4417
 
4418
/* Remove all variable-location information about call-clobbered
4419
   registers, as well as associations between MEMs and VALUEs.  */
4420
 
4421
static void
4422
dataflow_set_clear_at_call (dataflow_set *set)
4423
{
4424
  int r;
4425
 
4426
  for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
4427
    if (TEST_HARD_REG_BIT (regs_invalidated_by_call, r))
4428
      var_regno_delete (set, r);
4429
 
4430
  if (MAY_HAVE_DEBUG_INSNS)
4431
    {
4432
      set->traversed_vars = set->vars;
4433
      htab_traverse (shared_hash_htab (set->vars),
4434
                     dataflow_set_preserve_mem_locs, set);
4435
      set->traversed_vars = set->vars;
4436
      htab_traverse (shared_hash_htab (set->vars), dataflow_set_remove_mem_locs,
4437
                     set);
4438
      set->traversed_vars = NULL;
4439
    }
4440
}
4441
 
4442
static bool
4443
variable_part_different_p (variable_part *vp1, variable_part *vp2)
4444
{
4445
  location_chain lc1, lc2;
4446
 
4447
  for (lc1 = vp1->loc_chain; lc1; lc1 = lc1->next)
4448
    {
4449
      for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
4450
        {
4451
          if (REG_P (lc1->loc) && REG_P (lc2->loc))
4452
            {
4453
              if (REGNO (lc1->loc) == REGNO (lc2->loc))
4454
                break;
4455
            }
4456
          if (rtx_equal_p (lc1->loc, lc2->loc))
4457
            break;
4458
        }
4459
      if (!lc2)
4460
        return true;
4461
    }
4462
  return false;
4463
}
4464
 
4465
/* Return true if one-part variables VAR1 and VAR2 are different.
4466
   They must be in canonical order.  */
4467
 
4468
static bool
4469
onepart_variable_different_p (variable var1, variable var2)
4470
{
4471
  location_chain lc1, lc2;
4472
 
4473
  if (var1 == var2)
4474
    return false;
4475
 
4476
  gcc_assert (var1->n_var_parts == 1
4477
              && var2->n_var_parts == 1);
4478
 
4479
  lc1 = var1->var_part[0].loc_chain;
4480
  lc2 = var2->var_part[0].loc_chain;
4481
 
4482
  gcc_assert (lc1 && lc2);
4483
 
4484
  while (lc1 && lc2)
4485
    {
4486
      if (loc_cmp (lc1->loc, lc2->loc))
4487
        return true;
4488
      lc1 = lc1->next;
4489
      lc2 = lc2->next;
4490
    }
4491
 
4492
  return lc1 != lc2;
4493
}
4494
 
4495
/* Return true if variables VAR1 and VAR2 are different.  */
4496
 
4497
static bool
4498
variable_different_p (variable var1, variable var2)
4499
{
4500
  int i;
4501
 
4502
  if (var1 == var2)
4503
    return false;
4504
 
4505
  if (var1->onepart != var2->onepart)
4506
    return true;
4507
 
4508
  if (var1->n_var_parts != var2->n_var_parts)
4509
    return true;
4510
 
4511
  if (var1->onepart && var1->n_var_parts)
4512
    {
4513
      gcc_checking_assert (dv_as_opaque (var1->dv) == dv_as_opaque (var2->dv)
4514
                           && var1->n_var_parts == 1);
4515
      /* One-part values have locations in a canonical order.  */
4516
      return onepart_variable_different_p (var1, var2);
4517
    }
4518
 
4519
  for (i = 0; i < var1->n_var_parts; i++)
4520
    {
4521
      if (VAR_PART_OFFSET (var1, i) != VAR_PART_OFFSET (var2, i))
4522
        return true;
4523
      if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
4524
        return true;
4525
      if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
4526
        return true;
4527
    }
4528
  return false;
4529
}
4530
 
4531
/* Return true if dataflow sets OLD_SET and NEW_SET differ.  */
4532
 
4533
static bool
4534
dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
4535
{
4536
  htab_iterator hi;
4537
  variable var1;
4538
 
4539
  if (old_set->vars == new_set->vars)
4540
    return false;
4541
 
4542
  if (htab_elements (shared_hash_htab (old_set->vars))
4543
      != htab_elements (shared_hash_htab (new_set->vars)))
4544
    return true;
4545
 
4546
  FOR_EACH_HTAB_ELEMENT (shared_hash_htab (old_set->vars), var1, variable, hi)
4547
    {
4548
      htab_t htab = shared_hash_htab (new_set->vars);
4549
      variable var2 = (variable) htab_find_with_hash (htab, var1->dv,
4550
                                                      dv_htab_hash (var1->dv));
4551
      if (!var2)
4552
        {
4553
          if (dump_file && (dump_flags & TDF_DETAILS))
4554
            {
4555
              fprintf (dump_file, "dataflow difference found: removal of:\n");
4556
              dump_var (var1);
4557
            }
4558
          return true;
4559
        }
4560
 
4561
      if (variable_different_p (var1, var2))
4562
        {
4563
          if (dump_file && (dump_flags & TDF_DETAILS))
4564
            {
4565
              fprintf (dump_file, "dataflow difference found: "
4566
                       "old and new follow:\n");
4567
              dump_var (var1);
4568
              dump_var (var2);
4569
            }
4570
          return true;
4571
        }
4572
    }
4573
 
4574
  /* No need to traverse the second hashtab, if both have the same number
4575
     of elements and the second one had all entries found in the first one,
4576
     then it can't have any extra entries.  */
4577
  return false;
4578
}
4579
 
4580
/* Free the contents of dataflow set SET.  */
4581
 
4582
static void
4583
dataflow_set_destroy (dataflow_set *set)
4584
{
4585
  int i;
4586
 
4587
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4588
    attrs_list_clear (&set->regs[i]);
4589
 
4590
  shared_hash_destroy (set->vars);
4591
  set->vars = NULL;
4592
}
4593
 
4594
/* Return true if RTL X contains a SYMBOL_REF.  */
4595
 
4596
static bool
4597
contains_symbol_ref (rtx x)
4598
{
4599
  const char *fmt;
4600
  RTX_CODE code;
4601
  int i;
4602
 
4603
  if (!x)
4604
    return false;
4605
 
4606
  code = GET_CODE (x);
4607
  if (code == SYMBOL_REF)
4608
    return true;
4609
 
4610
  fmt = GET_RTX_FORMAT (code);
4611
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4612
    {
4613
      if (fmt[i] == 'e')
4614
        {
4615
          if (contains_symbol_ref (XEXP (x, i)))
4616
            return true;
4617
        }
4618
      else if (fmt[i] == 'E')
4619
        {
4620
          int j;
4621
          for (j = 0; j < XVECLEN (x, i); j++)
4622
            if (contains_symbol_ref (XVECEXP (x, i, j)))
4623
              return true;
4624
        }
4625
    }
4626
 
4627
  return false;
4628
}
4629
 
4630
/* Shall EXPR be tracked?  */
4631
 
4632
static bool
4633
track_expr_p (tree expr, bool need_rtl)
4634
{
4635
  rtx decl_rtl;
4636
  tree realdecl;
4637
 
4638
  if (TREE_CODE (expr) == DEBUG_EXPR_DECL)
4639
    return DECL_RTL_SET_P (expr);
4640
 
4641
  /* If EXPR is not a parameter or a variable do not track it.  */
4642
  if (TREE_CODE (expr) != VAR_DECL && TREE_CODE (expr) != PARM_DECL)
4643
    return 0;
4644
 
4645
  /* It also must have a name...  */
4646
  if (!DECL_NAME (expr) && need_rtl)
4647
    return 0;
4648
 
4649
  /* ... and a RTL assigned to it.  */
4650
  decl_rtl = DECL_RTL_IF_SET (expr);
4651
  if (!decl_rtl && need_rtl)
4652
    return 0;
4653
 
4654
  /* If this expression is really a debug alias of some other declaration, we
4655
     don't need to track this expression if the ultimate declaration is
4656
     ignored.  */
4657
  realdecl = expr;
4658
  if (DECL_DEBUG_EXPR_IS_FROM (realdecl))
4659
    {
4660
      realdecl = DECL_DEBUG_EXPR (realdecl);
4661
      if (realdecl == NULL_TREE)
4662
        realdecl = expr;
4663
      else if (!DECL_P (realdecl))
4664
        {
4665
          if (handled_component_p (realdecl))
4666
            {
4667
              HOST_WIDE_INT bitsize, bitpos, maxsize;
4668
              tree innerdecl
4669
                = get_ref_base_and_extent (realdecl, &bitpos, &bitsize,
4670
                                           &maxsize);
4671
              if (!DECL_P (innerdecl)
4672
                  || DECL_IGNORED_P (innerdecl)
4673
                  || TREE_STATIC (innerdecl)
4674
                  || bitsize <= 0
4675
                  || bitpos + bitsize > 256
4676
                  || bitsize != maxsize)
4677
                return 0;
4678
              else
4679
                realdecl = expr;
4680
            }
4681
          else
4682
            return 0;
4683
        }
4684
    }
4685
 
4686
  /* Do not track EXPR if REALDECL it should be ignored for debugging
4687
     purposes.  */
4688
  if (DECL_IGNORED_P (realdecl))
4689
    return 0;
4690
 
4691
  /* Do not track global variables until we are able to emit correct location
4692
     list for them.  */
4693
  if (TREE_STATIC (realdecl))
4694
    return 0;
4695
 
4696
  /* When the EXPR is a DECL for alias of some variable (see example)
4697
     the TREE_STATIC flag is not used.  Disable tracking all DECLs whose
4698
     DECL_RTL contains SYMBOL_REF.
4699
 
4700
     Example:
4701
     extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
4702
     char **_dl_argv;
4703
  */
4704
  if (decl_rtl && MEM_P (decl_rtl)
4705
      && contains_symbol_ref (XEXP (decl_rtl, 0)))
4706
    return 0;
4707
 
4708
  /* If RTX is a memory it should not be very large (because it would be
4709
     an array or struct).  */
4710
  if (decl_rtl && MEM_P (decl_rtl))
4711
    {
4712
      /* Do not track structures and arrays.  */
4713
      if (GET_MODE (decl_rtl) == BLKmode
4714
          || AGGREGATE_TYPE_P (TREE_TYPE (realdecl)))
4715
        return 0;
4716
      if (MEM_SIZE_KNOWN_P (decl_rtl)
4717
          && MEM_SIZE (decl_rtl) > MAX_VAR_PARTS)
4718
        return 0;
4719
    }
4720
 
4721
  DECL_CHANGED (expr) = 0;
4722
  DECL_CHANGED (realdecl) = 0;
4723
  return 1;
4724
}
4725
 
4726
/* Determine whether a given LOC refers to the same variable part as
4727
   EXPR+OFFSET.  */
4728
 
4729
static bool
4730
same_variable_part_p (rtx loc, tree expr, HOST_WIDE_INT offset)
4731
{
4732
  tree expr2;
4733
  HOST_WIDE_INT offset2;
4734
 
4735
  if (! DECL_P (expr))
4736
    return false;
4737
 
4738
  if (REG_P (loc))
4739
    {
4740
      expr2 = REG_EXPR (loc);
4741
      offset2 = REG_OFFSET (loc);
4742
    }
4743
  else if (MEM_P (loc))
4744
    {
4745
      expr2 = MEM_EXPR (loc);
4746
      offset2 = INT_MEM_OFFSET (loc);
4747
    }
4748
  else
4749
    return false;
4750
 
4751
  if (! expr2 || ! DECL_P (expr2))
4752
    return false;
4753
 
4754
  expr = var_debug_decl (expr);
4755
  expr2 = var_debug_decl (expr2);
4756
 
4757
  return (expr == expr2 && offset == offset2);
4758
}
4759
 
4760
/* LOC is a REG or MEM that we would like to track if possible.
4761
   If EXPR is null, we don't know what expression LOC refers to,
4762
   otherwise it refers to EXPR + OFFSET.  STORE_REG_P is true if
4763
   LOC is an lvalue register.
4764
 
4765
   Return true if EXPR is nonnull and if LOC, or some lowpart of it,
4766
   is something we can track.  When returning true, store the mode of
4767
   the lowpart we can track in *MODE_OUT (if nonnull) and its offset
4768
   from EXPR in *OFFSET_OUT (if nonnull).  */
4769
 
4770
static bool
4771
track_loc_p (rtx loc, tree expr, HOST_WIDE_INT offset, bool store_reg_p,
4772
             enum machine_mode *mode_out, HOST_WIDE_INT *offset_out)
4773
{
4774
  enum machine_mode mode;
4775
 
4776
  if (expr == NULL || !track_expr_p (expr, true))
4777
    return false;
4778
 
4779
  /* If REG was a paradoxical subreg, its REG_ATTRS will describe the
4780
     whole subreg, but only the old inner part is really relevant.  */
4781
  mode = GET_MODE (loc);
4782
  if (REG_P (loc) && !HARD_REGISTER_NUM_P (ORIGINAL_REGNO (loc)))
4783
    {
4784
      enum machine_mode pseudo_mode;
4785
 
4786
      pseudo_mode = PSEUDO_REGNO_MODE (ORIGINAL_REGNO (loc));
4787
      if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (pseudo_mode))
4788
        {
4789
          offset += byte_lowpart_offset (pseudo_mode, mode);
4790
          mode = pseudo_mode;
4791
        }
4792
    }
4793
 
4794
  /* If LOC is a paradoxical lowpart of EXPR, refer to EXPR itself.
4795
     Do the same if we are storing to a register and EXPR occupies
4796
     the whole of register LOC; in that case, the whole of EXPR is
4797
     being changed.  We exclude complex modes from the second case
4798
     because the real and imaginary parts are represented as separate
4799
     pseudo registers, even if the whole complex value fits into one
4800
     hard register.  */
4801
  if ((GET_MODE_SIZE (mode) > GET_MODE_SIZE (DECL_MODE (expr))
4802
       || (store_reg_p
4803
           && !COMPLEX_MODE_P (DECL_MODE (expr))
4804
           && hard_regno_nregs[REGNO (loc)][DECL_MODE (expr)] == 1))
4805
      && offset + byte_lowpart_offset (DECL_MODE (expr), mode) == 0)
4806
    {
4807
      mode = DECL_MODE (expr);
4808
      offset = 0;
4809
    }
4810
 
4811
  if (offset < 0 || offset >= MAX_VAR_PARTS)
4812
    return false;
4813
 
4814
  if (mode_out)
4815
    *mode_out = mode;
4816
  if (offset_out)
4817
    *offset_out = offset;
4818
  return true;
4819
}
4820
 
4821
/* Return the MODE lowpart of LOC, or null if LOC is not something we
4822
   want to track.  When returning nonnull, make sure that the attributes
4823
   on the returned value are updated.  */
4824
 
4825
static rtx
4826
var_lowpart (enum machine_mode mode, rtx loc)
4827
{
4828
  unsigned int offset, reg_offset, regno;
4829
 
4830
  if (!REG_P (loc) && !MEM_P (loc))
4831
    return NULL;
4832
 
4833
  if (GET_MODE (loc) == mode)
4834
    return loc;
4835
 
4836
  offset = byte_lowpart_offset (mode, GET_MODE (loc));
4837
 
4838
  if (MEM_P (loc))
4839
    return adjust_address_nv (loc, mode, offset);
4840
 
4841
  reg_offset = subreg_lowpart_offset (mode, GET_MODE (loc));
4842
  regno = REGNO (loc) + subreg_regno_offset (REGNO (loc), GET_MODE (loc),
4843
                                             reg_offset, mode);
4844
  return gen_rtx_REG_offset (loc, mode, regno, offset);
4845
}
4846
 
4847
/* Carry information about uses and stores while walking rtx.  */
4848
 
4849
struct count_use_info
4850
{
4851
  /* The insn where the RTX is.  */
4852
  rtx insn;
4853
 
4854
  /* The basic block where insn is.  */
4855
  basic_block bb;
4856
 
4857
  /* The array of n_sets sets in the insn, as determined by cselib.  */
4858
  struct cselib_set *sets;
4859
  int n_sets;
4860
 
4861
  /* True if we're counting stores, false otherwise.  */
4862
  bool store_p;
4863
};
4864
 
4865
/* Find a VALUE corresponding to X.   */
4866
 
4867
static inline cselib_val *
4868
find_use_val (rtx x, enum machine_mode mode, struct count_use_info *cui)
4869
{
4870
  int i;
4871
 
4872
  if (cui->sets)
4873
    {
4874
      /* This is called after uses are set up and before stores are
4875
         processed by cselib, so it's safe to look up srcs, but not
4876
         dsts.  So we look up expressions that appear in srcs or in
4877
         dest expressions, but we search the sets array for dests of
4878
         stores.  */
4879
      if (cui->store_p)
4880
        {
4881
          /* Some targets represent memset and memcpy patterns
4882
             by (set (mem:BLK ...) (reg:[QHSD]I ...)) or
4883
             (set (mem:BLK ...) (const_int ...)) or
4884
             (set (mem:BLK ...) (mem:BLK ...)).  Don't return anything
4885
             in that case, otherwise we end up with mode mismatches.  */
4886
          if (mode == BLKmode && MEM_P (x))
4887
            return NULL;
4888
          for (i = 0; i < cui->n_sets; i++)
4889
            if (cui->sets[i].dest == x)
4890
              return cui->sets[i].src_elt;
4891
        }
4892
      else
4893
        return cselib_lookup (x, mode, 0, VOIDmode);
4894
    }
4895
 
4896
  return NULL;
4897
}
4898
 
4899
/* Helper function to get mode of MEM's address.  */
4900
 
4901
static inline enum machine_mode
4902
get_address_mode (rtx mem)
4903
{
4904
  enum machine_mode mode = GET_MODE (XEXP (mem, 0));
4905
  if (mode != VOIDmode)
4906
    return mode;
4907
  return targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
4908
}
4909
 
4910
/* Replace all registers and addresses in an expression with VALUE
4911
   expressions that map back to them, unless the expression is a
4912
   register.  If no mapping is or can be performed, returns NULL.  */
4913
 
4914
static rtx
4915
replace_expr_with_values (rtx loc)
4916
{
4917
  if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
4918
    return NULL;
4919
  else if (MEM_P (loc))
4920
    {
4921
      cselib_val *addr = cselib_lookup (XEXP (loc, 0),
4922
                                        get_address_mode (loc), 0,
4923
                                        GET_MODE (loc));
4924
      if (addr)
4925
        return replace_equiv_address_nv (loc, addr->val_rtx);
4926
      else
4927
        return NULL;
4928
    }
4929
  else
4930
    return cselib_subst_to_values (loc, VOIDmode);
4931
}
4932
 
4933
/* Return true if *X is a DEBUG_EXPR.  Usable as an argument to
4934
   for_each_rtx to tell whether there are any DEBUG_EXPRs within
4935
   RTX.  */
4936
 
4937
static int
4938
rtx_debug_expr_p (rtx *x, void *data ATTRIBUTE_UNUSED)
4939
{
4940
  rtx loc = *x;
4941
 
4942
  return GET_CODE (loc) == DEBUG_EXPR;
4943
}
4944
 
4945
/* Determine what kind of micro operation to choose for a USE.  Return
4946
   MO_CLOBBER if no micro operation is to be generated.  */
4947
 
4948
static enum micro_operation_type
4949
use_type (rtx loc, struct count_use_info *cui, enum machine_mode *modep)
4950
{
4951
  tree expr;
4952
 
4953
  if (cui && cui->sets)
4954
    {
4955
      if (GET_CODE (loc) == VAR_LOCATION)
4956
        {
4957
          if (track_expr_p (PAT_VAR_LOCATION_DECL (loc), false))
4958
            {
4959
              rtx ploc = PAT_VAR_LOCATION_LOC (loc);
4960
              if (! VAR_LOC_UNKNOWN_P (ploc))
4961
                {
4962
                  cselib_val *val = cselib_lookup (ploc, GET_MODE (loc), 1,
4963
                                                   VOIDmode);
4964
 
4965
                  /* ??? flag_float_store and volatile mems are never
4966
                     given values, but we could in theory use them for
4967
                     locations.  */
4968
                  gcc_assert (val || 1);
4969
                }
4970
              return MO_VAL_LOC;
4971
            }
4972
          else
4973
            return MO_CLOBBER;
4974
        }
4975
 
4976
      if (REG_P (loc) || MEM_P (loc))
4977
        {
4978
          if (modep)
4979
            *modep = GET_MODE (loc);
4980
          if (cui->store_p)
4981
            {
4982
              if (REG_P (loc)
4983
                  || (find_use_val (loc, GET_MODE (loc), cui)
4984
                      && cselib_lookup (XEXP (loc, 0),
4985
                                        get_address_mode (loc), 0,
4986
                                        GET_MODE (loc))))
4987
                return MO_VAL_SET;
4988
            }
4989
          else
4990
            {
4991
              cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
4992
 
4993
              if (val && !cselib_preserved_value_p (val))
4994
                return MO_VAL_USE;
4995
            }
4996
        }
4997
    }
4998
 
4999
  if (REG_P (loc))
5000
    {
5001
      gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
5002
 
5003
      if (loc == cfa_base_rtx)
5004
        return MO_CLOBBER;
5005
      expr = REG_EXPR (loc);
5006
 
5007
      if (!expr)
5008
        return MO_USE_NO_VAR;
5009
      else if (target_for_debug_bind (var_debug_decl (expr)))
5010
        return MO_CLOBBER;
5011
      else if (track_loc_p (loc, expr, REG_OFFSET (loc),
5012
                            false, modep, NULL))
5013
        return MO_USE;
5014
      else
5015
        return MO_USE_NO_VAR;
5016
    }
5017
  else if (MEM_P (loc))
5018
    {
5019
      expr = MEM_EXPR (loc);
5020
 
5021
      if (!expr)
5022
        return MO_CLOBBER;
5023
      else if (target_for_debug_bind (var_debug_decl (expr)))
5024
        return MO_CLOBBER;
5025
      else if (track_loc_p (loc, expr, INT_MEM_OFFSET (loc),
5026
                            false, modep, NULL)
5027
               /* Multi-part variables shouldn't refer to one-part
5028
                  variable names such as VALUEs (never happens) or
5029
                  DEBUG_EXPRs (only happens in the presence of debug
5030
                  insns).  */
5031
               && (!MAY_HAVE_DEBUG_INSNS
5032
                   || !for_each_rtx (&XEXP (loc, 0), rtx_debug_expr_p, NULL)))
5033
        return MO_USE;
5034
      else
5035
        return MO_CLOBBER;
5036
    }
5037
 
5038
  return MO_CLOBBER;
5039
}
5040
 
5041
/* Log to OUT information about micro-operation MOPT involving X in
5042
   INSN of BB.  */
5043
 
5044
static inline void
5045
log_op_type (rtx x, basic_block bb, rtx insn,
5046
             enum micro_operation_type mopt, FILE *out)
5047
{
5048
  fprintf (out, "bb %i op %i insn %i %s ",
5049
           bb->index, VEC_length (micro_operation, VTI (bb)->mos),
5050
           INSN_UID (insn), micro_operation_type_name[mopt]);
5051
  print_inline_rtx (out, x, 2);
5052
  fputc ('\n', out);
5053
}
5054
 
5055
/* Tell whether the CONCAT used to holds a VALUE and its location
5056
   needs value resolution, i.e., an attempt of mapping the location
5057
   back to other incoming values.  */
5058
#define VAL_NEEDS_RESOLUTION(x) \
5059
  (RTL_FLAG_CHECK1 ("VAL_NEEDS_RESOLUTION", (x), CONCAT)->volatil)
5060
/* Whether the location in the CONCAT is a tracked expression, that
5061
   should also be handled like a MO_USE.  */
5062
#define VAL_HOLDS_TRACK_EXPR(x) \
5063
  (RTL_FLAG_CHECK1 ("VAL_HOLDS_TRACK_EXPR", (x), CONCAT)->used)
5064
/* Whether the location in the CONCAT should be handled like a MO_COPY
5065
   as well.  */
5066
#define VAL_EXPR_IS_COPIED(x) \
5067
  (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_COPIED", (x), CONCAT)->jump)
5068
/* Whether the location in the CONCAT should be handled like a
5069
   MO_CLOBBER as well.  */
5070
#define VAL_EXPR_IS_CLOBBERED(x) \
5071
  (RTL_FLAG_CHECK1 ("VAL_EXPR_IS_CLOBBERED", (x), CONCAT)->unchanging)
5072
 
5073
/* All preserved VALUEs.  */
5074
static VEC (rtx, heap) *preserved_values;
5075
 
5076
/* Ensure VAL is preserved and remember it in a vector for vt_emit_notes.  */
5077
 
5078
static void
5079
preserve_value (cselib_val *val)
5080
{
5081
  cselib_preserve_value (val);
5082
  VEC_safe_push (rtx, heap, preserved_values, val->val_rtx);
5083
}
5084
 
5085
/* Helper function for MO_VAL_LOC handling.  Return non-zero if
5086
   any rtxes not suitable for CONST use not replaced by VALUEs
5087
   are discovered.  */
5088
 
5089
static int
5090
non_suitable_const (rtx *x, void *data ATTRIBUTE_UNUSED)
5091
{
5092
  if (*x == NULL_RTX)
5093
    return 0;
5094
 
5095
  switch (GET_CODE (*x))
5096
    {
5097
    case REG:
5098
    case DEBUG_EXPR:
5099
    case PC:
5100
    case SCRATCH:
5101
    case CC0:
5102
    case ASM_INPUT:
5103
    case ASM_OPERANDS:
5104
      return 1;
5105
    case MEM:
5106
      return !MEM_READONLY_P (*x);
5107
    default:
5108
      return 0;
5109
    }
5110
}
5111
 
5112
/* Add uses (register and memory references) LOC which will be tracked
5113
   to VTI (bb)->mos.  INSN is instruction which the LOC is part of.  */
5114
 
5115
static int
5116
add_uses (rtx *ploc, void *data)
5117
{
5118
  rtx loc = *ploc;
5119
  enum machine_mode mode = VOIDmode;
5120
  struct count_use_info *cui = (struct count_use_info *)data;
5121
  enum micro_operation_type type = use_type (loc, cui, &mode);
5122
 
5123
  if (type != MO_CLOBBER)
5124
    {
5125
      basic_block bb = cui->bb;
5126
      micro_operation mo;
5127
 
5128
      mo.type = type;
5129
      mo.u.loc = type == MO_USE ? var_lowpart (mode, loc) : loc;
5130
      mo.insn = cui->insn;
5131
 
5132
      if (type == MO_VAL_LOC)
5133
        {
5134
          rtx oloc = loc;
5135
          rtx vloc = PAT_VAR_LOCATION_LOC (oloc);
5136
          cselib_val *val;
5137
 
5138
          gcc_assert (cui->sets);
5139
 
5140
          if (MEM_P (vloc)
5141
              && !REG_P (XEXP (vloc, 0))
5142
              && !MEM_P (XEXP (vloc, 0)))
5143
            {
5144
              rtx mloc = vloc;
5145
              enum machine_mode address_mode = get_address_mode (mloc);
5146
              cselib_val *val
5147
                = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5148
                                 GET_MODE (mloc));
5149
 
5150
              if (val && !cselib_preserved_value_p (val))
5151
                preserve_value (val);
5152
            }
5153
 
5154
          if (CONSTANT_P (vloc)
5155
              && (GET_CODE (vloc) != CONST
5156
                  || for_each_rtx (&vloc, non_suitable_const, NULL)))
5157
            /* For constants don't look up any value.  */;
5158
          else if (!VAR_LOC_UNKNOWN_P (vloc) && !unsuitable_loc (vloc)
5159
                   && (val = find_use_val (vloc, GET_MODE (oloc), cui)))
5160
            {
5161
              enum machine_mode mode2;
5162
              enum micro_operation_type type2;
5163
              rtx nloc = NULL;
5164
              bool resolvable = REG_P (vloc) || MEM_P (vloc);
5165
 
5166
              if (resolvable)
5167
                nloc = replace_expr_with_values (vloc);
5168
 
5169
              if (nloc)
5170
                {
5171
                  oloc = shallow_copy_rtx (oloc);
5172
                  PAT_VAR_LOCATION_LOC (oloc) = nloc;
5173
                }
5174
 
5175
              oloc = gen_rtx_CONCAT (mode, val->val_rtx, oloc);
5176
 
5177
              type2 = use_type (vloc, 0, &mode2);
5178
 
5179
              gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5180
                          || type2 == MO_CLOBBER);
5181
 
5182
              if (type2 == MO_CLOBBER
5183
                  && !cselib_preserved_value_p (val))
5184
                {
5185
                  VAL_NEEDS_RESOLUTION (oloc) = resolvable;
5186
                  preserve_value (val);
5187
                }
5188
            }
5189
          else if (!VAR_LOC_UNKNOWN_P (vloc))
5190
            {
5191
              oloc = shallow_copy_rtx (oloc);
5192
              PAT_VAR_LOCATION_LOC (oloc) = gen_rtx_UNKNOWN_VAR_LOC ();
5193
            }
5194
 
5195
          mo.u.loc = oloc;
5196
        }
5197
      else if (type == MO_VAL_USE)
5198
        {
5199
          enum machine_mode mode2 = VOIDmode;
5200
          enum micro_operation_type type2;
5201
          cselib_val *val = find_use_val (loc, GET_MODE (loc), cui);
5202
          rtx vloc, oloc = loc, nloc;
5203
 
5204
          gcc_assert (cui->sets);
5205
 
5206
          if (MEM_P (oloc)
5207
              && !REG_P (XEXP (oloc, 0))
5208
              && !MEM_P (XEXP (oloc, 0)))
5209
            {
5210
              rtx mloc = oloc;
5211
              enum machine_mode address_mode = get_address_mode (mloc);
5212
              cselib_val *val
5213
                = cselib_lookup (XEXP (mloc, 0), address_mode, 0,
5214
                                 GET_MODE (mloc));
5215
 
5216
              if (val && !cselib_preserved_value_p (val))
5217
                preserve_value (val);
5218
            }
5219
 
5220
          type2 = use_type (loc, 0, &mode2);
5221
 
5222
          gcc_assert (type2 == MO_USE || type2 == MO_USE_NO_VAR
5223
                      || type2 == MO_CLOBBER);
5224
 
5225
          if (type2 == MO_USE)
5226
            vloc = var_lowpart (mode2, loc);
5227
          else
5228
            vloc = oloc;
5229
 
5230
          /* The loc of a MO_VAL_USE may have two forms:
5231
 
5232
             (concat val src): val is at src, a value-based
5233
             representation.
5234
 
5235
             (concat (concat val use) src): same as above, with use as
5236
             the MO_USE tracked value, if it differs from src.
5237
 
5238
          */
5239
 
5240
          gcc_checking_assert (REG_P (loc) || MEM_P (loc));
5241
          nloc = replace_expr_with_values (loc);
5242
          if (!nloc)
5243
            nloc = oloc;
5244
 
5245
          if (vloc != nloc)
5246
            oloc = gen_rtx_CONCAT (mode2, val->val_rtx, vloc);
5247
          else
5248
            oloc = val->val_rtx;
5249
 
5250
          mo.u.loc = gen_rtx_CONCAT (mode, oloc, nloc);
5251
 
5252
          if (type2 == MO_USE)
5253
            VAL_HOLDS_TRACK_EXPR (mo.u.loc) = 1;
5254
          if (!cselib_preserved_value_p (val))
5255
            {
5256
              VAL_NEEDS_RESOLUTION (mo.u.loc) = 1;
5257
              preserve_value (val);
5258
            }
5259
        }
5260
      else
5261
        gcc_assert (type == MO_USE || type == MO_USE_NO_VAR);
5262
 
5263
      if (dump_file && (dump_flags & TDF_DETAILS))
5264
        log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5265
      VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5266
    }
5267
 
5268
  return 0;
5269
}
5270
 
5271
/* Helper function for finding all uses of REG/MEM in X in insn INSN.  */
5272
 
5273
static void
5274
add_uses_1 (rtx *x, void *cui)
5275
{
5276
  for_each_rtx (x, add_uses, cui);
5277
}
5278
 
5279
/* This is the value used during expansion of locations.  We want it
5280
   to be unbounded, so that variables expanded deep in a recursion
5281
   nest are fully evaluated, so that their values are cached
5282
   correctly.  We avoid recursion cycles through other means, and we
5283
   don't unshare RTL, so excess complexity is not a problem.  */
5284
#define EXPR_DEPTH (INT_MAX)
5285
/* We use this to keep too-complex expressions from being emitted as
5286
   location notes, and then to debug information.  Users can trade
5287
   compile time for ridiculously complex expressions, although they're
5288
   seldom useful, and they may often have to be discarded as not
5289
   representable anyway.  */
5290
#define EXPR_USE_DEPTH (PARAM_VALUE (PARAM_MAX_VARTRACK_EXPR_DEPTH))
5291
 
5292
/* Attempt to reverse the EXPR operation in the debug info and record
5293
   it in the cselib table.  Say for reg1 = reg2 + 6 even when reg2 is
5294
   no longer live we can express its value as VAL - 6.  */
5295
 
5296
static void
5297
reverse_op (rtx val, const_rtx expr, rtx insn)
5298
{
5299
  rtx src, arg, ret;
5300
  cselib_val *v;
5301
  struct elt_loc_list *l;
5302
  enum rtx_code code;
5303
 
5304
  if (GET_CODE (expr) != SET)
5305
    return;
5306
 
5307
  if (!REG_P (SET_DEST (expr)) || GET_MODE (val) != GET_MODE (SET_DEST (expr)))
5308
    return;
5309
 
5310
  src = SET_SRC (expr);
5311
  switch (GET_CODE (src))
5312
    {
5313
    case PLUS:
5314
    case MINUS:
5315
    case XOR:
5316
    case NOT:
5317
    case NEG:
5318
      if (!REG_P (XEXP (src, 0)))
5319
        return;
5320
      break;
5321
    case SIGN_EXTEND:
5322
    case ZERO_EXTEND:
5323
      if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0)))
5324
        return;
5325
      break;
5326
    default:
5327
      return;
5328
    }
5329
 
5330
  if (!SCALAR_INT_MODE_P (GET_MODE (src)) || XEXP (src, 0) == cfa_base_rtx)
5331
    return;
5332
 
5333
  v = cselib_lookup (XEXP (src, 0), GET_MODE (XEXP (src, 0)), 0, VOIDmode);
5334
  if (!v || !cselib_preserved_value_p (v))
5335
    return;
5336
 
5337
  /* Use canonical V to avoid creating multiple redundant expressions
5338
     for different VALUES equivalent to V.  */
5339
  v = canonical_cselib_val (v);
5340
 
5341
  /* Adding a reverse op isn't useful if V already has an always valid
5342
     location.  Ignore ENTRY_VALUE, while it is always constant, we should
5343
     prefer non-ENTRY_VALUE locations whenever possible.  */
5344
  for (l = v->locs; l; l = l->next)
5345
    if (CONSTANT_P (l->loc)
5346
        && (GET_CODE (l->loc) != CONST || !references_value_p (l->loc, 0)))
5347
      return;
5348
 
5349
  switch (GET_CODE (src))
5350
    {
5351
    case NOT:
5352
    case NEG:
5353
      if (GET_MODE (v->val_rtx) != GET_MODE (val))
5354
        return;
5355
      ret = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (val), val);
5356
      break;
5357
    case SIGN_EXTEND:
5358
    case ZERO_EXTEND:
5359
      ret = gen_lowpart_SUBREG (GET_MODE (v->val_rtx), val);
5360
      break;
5361
    case XOR:
5362
      code = XOR;
5363
      goto binary;
5364
    case PLUS:
5365
      code = MINUS;
5366
      goto binary;
5367
    case MINUS:
5368
      code = PLUS;
5369
      goto binary;
5370
    binary:
5371
      if (GET_MODE (v->val_rtx) != GET_MODE (val))
5372
        return;
5373
      arg = XEXP (src, 1);
5374
      if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5375
        {
5376
          arg = cselib_expand_value_rtx (arg, scratch_regs, 5);
5377
          if (arg == NULL_RTX)
5378
            return;
5379
          if (!CONST_INT_P (arg) && GET_CODE (arg) != SYMBOL_REF)
5380
            return;
5381
        }
5382
      ret = simplify_gen_binary (code, GET_MODE (val), val, arg);
5383
      if (ret == val)
5384
        /* Ensure ret isn't VALUE itself (which can happen e.g. for
5385
           (plus (reg1) (reg2)) when reg2 is known to be 0), as that
5386
           breaks a lot of routines during var-tracking.  */
5387
        ret = gen_rtx_fmt_ee (PLUS, GET_MODE (val), val, const0_rtx);
5388
      break;
5389
    default:
5390
      gcc_unreachable ();
5391
    }
5392
 
5393
  cselib_add_permanent_equiv (v, ret, insn);
5394
}
5395
 
5396
/* Add stores (register and memory references) LOC which will be tracked
5397
   to VTI (bb)->mos.  EXPR is the RTL expression containing the store.
5398
   CUIP->insn is instruction which the LOC is part of.  */
5399
 
5400
static void
5401
add_stores (rtx loc, const_rtx expr, void *cuip)
5402
{
5403
  enum machine_mode mode = VOIDmode, mode2;
5404
  struct count_use_info *cui = (struct count_use_info *)cuip;
5405
  basic_block bb = cui->bb;
5406
  micro_operation mo;
5407
  rtx oloc = loc, nloc, src = NULL;
5408
  enum micro_operation_type type = use_type (loc, cui, &mode);
5409
  bool track_p = false;
5410
  cselib_val *v;
5411
  bool resolve, preserve;
5412
 
5413
  if (type == MO_CLOBBER)
5414
    return;
5415
 
5416
  mode2 = mode;
5417
 
5418
  if (REG_P (loc))
5419
    {
5420
      gcc_assert (loc != cfa_base_rtx);
5421
      if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
5422
          || !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
5423
          || GET_CODE (expr) == CLOBBER)
5424
        {
5425
          mo.type = MO_CLOBBER;
5426
          mo.u.loc = loc;
5427
          if (GET_CODE (expr) == SET
5428
              && SET_DEST (expr) == loc
5429
              && !unsuitable_loc (SET_SRC (expr))
5430
              && find_use_val (loc, mode, cui))
5431
            {
5432
              gcc_checking_assert (type == MO_VAL_SET);
5433
              mo.u.loc = gen_rtx_SET (VOIDmode, loc, SET_SRC (expr));
5434
            }
5435
        }
5436
      else
5437
        {
5438
          if (GET_CODE (expr) == SET
5439
              && SET_DEST (expr) == loc
5440
              && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5441
            src = var_lowpart (mode2, SET_SRC (expr));
5442
          loc = var_lowpart (mode2, loc);
5443
 
5444
          if (src == NULL)
5445
            {
5446
              mo.type = MO_SET;
5447
              mo.u.loc = loc;
5448
            }
5449
          else
5450
            {
5451
              rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5452
              if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
5453
                mo.type = MO_COPY;
5454
              else
5455
                mo.type = MO_SET;
5456
              mo.u.loc = xexpr;
5457
            }
5458
        }
5459
      mo.insn = cui->insn;
5460
    }
5461
  else if (MEM_P (loc)
5462
           && ((track_p = use_type (loc, NULL, &mode2) == MO_USE)
5463
               || cui->sets))
5464
    {
5465
      if (MEM_P (loc) && type == MO_VAL_SET
5466
          && !REG_P (XEXP (loc, 0))
5467
          && !MEM_P (XEXP (loc, 0)))
5468
        {
5469
          rtx mloc = loc;
5470
          enum machine_mode address_mode = get_address_mode (mloc);
5471
          cselib_val *val = cselib_lookup (XEXP (mloc, 0),
5472
                                           address_mode, 0,
5473
                                           GET_MODE (mloc));
5474
 
5475
          if (val && !cselib_preserved_value_p (val))
5476
            preserve_value (val);
5477
        }
5478
 
5479
      if (GET_CODE (expr) == CLOBBER || !track_p)
5480
        {
5481
          mo.type = MO_CLOBBER;
5482
          mo.u.loc = track_p ? var_lowpart (mode2, loc) : loc;
5483
        }
5484
      else
5485
        {
5486
          if (GET_CODE (expr) == SET
5487
              && SET_DEST (expr) == loc
5488
              && GET_CODE (SET_SRC (expr)) != ASM_OPERANDS)
5489
            src = var_lowpart (mode2, SET_SRC (expr));
5490
          loc = var_lowpart (mode2, loc);
5491
 
5492
          if (src == NULL)
5493
            {
5494
              mo.type = MO_SET;
5495
              mo.u.loc = loc;
5496
            }
5497
          else
5498
            {
5499
              rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
5500
              if (same_variable_part_p (SET_SRC (xexpr),
5501
                                        MEM_EXPR (loc),
5502
                                        INT_MEM_OFFSET (loc)))
5503
                mo.type = MO_COPY;
5504
              else
5505
                mo.type = MO_SET;
5506
              mo.u.loc = xexpr;
5507
            }
5508
        }
5509
      mo.insn = cui->insn;
5510
    }
5511
  else
5512
    return;
5513
 
5514
  if (type != MO_VAL_SET)
5515
    goto log_and_return;
5516
 
5517
  v = find_use_val (oloc, mode, cui);
5518
 
5519
  if (!v)
5520
    goto log_and_return;
5521
 
5522
  resolve = preserve = !cselib_preserved_value_p (v);
5523
 
5524
  nloc = replace_expr_with_values (oloc);
5525
  if (nloc)
5526
    oloc = nloc;
5527
 
5528
  if (GET_CODE (PATTERN (cui->insn)) == COND_EXEC)
5529
    {
5530
      cselib_val *oval = cselib_lookup (oloc, GET_MODE (oloc), 0, VOIDmode);
5531
 
5532
      gcc_assert (oval != v);
5533
      gcc_assert (REG_P (oloc) || MEM_P (oloc));
5534
 
5535
      if (oval && !cselib_preserved_value_p (oval))
5536
        {
5537
          micro_operation moa;
5538
 
5539
          preserve_value (oval);
5540
 
5541
          moa.type = MO_VAL_USE;
5542
          moa.u.loc = gen_rtx_CONCAT (mode, oval->val_rtx, oloc);
5543
          VAL_NEEDS_RESOLUTION (moa.u.loc) = 1;
5544
          moa.insn = cui->insn;
5545
 
5546
          if (dump_file && (dump_flags & TDF_DETAILS))
5547
            log_op_type (moa.u.loc, cui->bb, cui->insn,
5548
                         moa.type, dump_file);
5549
          VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &moa);
5550
        }
5551
 
5552
      resolve = false;
5553
    }
5554
  else if (resolve && GET_CODE (mo.u.loc) == SET)
5555
    {
5556
      if (REG_P (SET_SRC (expr)) || MEM_P (SET_SRC (expr)))
5557
        nloc = replace_expr_with_values (SET_SRC (expr));
5558
      else
5559
        nloc = NULL_RTX;
5560
 
5561
      /* Avoid the mode mismatch between oexpr and expr.  */
5562
      if (!nloc && mode != mode2)
5563
        {
5564
          nloc = SET_SRC (expr);
5565
          gcc_assert (oloc == SET_DEST (expr));
5566
        }
5567
 
5568
      if (nloc && nloc != SET_SRC (mo.u.loc))
5569
        oloc = gen_rtx_SET (GET_MODE (mo.u.loc), oloc, nloc);
5570
      else
5571
        {
5572
          if (oloc == SET_DEST (mo.u.loc))
5573
            /* No point in duplicating.  */
5574
            oloc = mo.u.loc;
5575
          if (!REG_P (SET_SRC (mo.u.loc)))
5576
            resolve = false;
5577
        }
5578
    }
5579
  else if (!resolve)
5580
    {
5581
      if (GET_CODE (mo.u.loc) == SET
5582
          && oloc == SET_DEST (mo.u.loc))
5583
        /* No point in duplicating.  */
5584
        oloc = mo.u.loc;
5585
    }
5586
  else
5587
    resolve = false;
5588
 
5589
  loc = gen_rtx_CONCAT (mode, v->val_rtx, oloc);
5590
 
5591
  if (mo.u.loc != oloc)
5592
    loc = gen_rtx_CONCAT (GET_MODE (mo.u.loc), loc, mo.u.loc);
5593
 
5594
  /* The loc of a MO_VAL_SET may have various forms:
5595
 
5596
     (concat val dst): dst now holds val
5597
 
5598
     (concat val (set dst src)): dst now holds val, copied from src
5599
 
5600
     (concat (concat val dstv) dst): dst now holds val; dstv is dst
5601
     after replacing mems and non-top-level regs with values.
5602
 
5603
     (concat (concat val dstv) (set dst src)): dst now holds val,
5604
     copied from src.  dstv is a value-based representation of dst, if
5605
     it differs from dst.  If resolution is needed, src is a REG, and
5606
     its mode is the same as that of val.
5607
 
5608
     (concat (concat val (set dstv srcv)) (set dst src)): src
5609
     copied to dst, holding val.  dstv and srcv are value-based
5610
     representations of dst and src, respectively.
5611
 
5612
  */
5613
 
5614
  if (GET_CODE (PATTERN (cui->insn)) != COND_EXEC)
5615
    reverse_op (v->val_rtx, expr, cui->insn);
5616
 
5617
  mo.u.loc = loc;
5618
 
5619
  if (track_p)
5620
    VAL_HOLDS_TRACK_EXPR (loc) = 1;
5621
  if (preserve)
5622
    {
5623
      VAL_NEEDS_RESOLUTION (loc) = resolve;
5624
      preserve_value (v);
5625
    }
5626
  if (mo.type == MO_CLOBBER)
5627
    VAL_EXPR_IS_CLOBBERED (loc) = 1;
5628
  if (mo.type == MO_COPY)
5629
    VAL_EXPR_IS_COPIED (loc) = 1;
5630
 
5631
  mo.type = MO_VAL_SET;
5632
 
5633
 log_and_return:
5634
  if (dump_file && (dump_flags & TDF_DETAILS))
5635
    log_op_type (mo.u.loc, cui->bb, cui->insn, mo.type, dump_file);
5636
  VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
5637
}
5638
 
5639
/* Arguments to the call.  */
5640
static rtx call_arguments;
5641
 
5642
/* Compute call_arguments.  */
5643
 
5644
static void
5645
prepare_call_arguments (basic_block bb, rtx insn)
5646
{
5647
  rtx link, x;
5648
  rtx prev, cur, next;
5649
  rtx call = PATTERN (insn);
5650
  rtx this_arg = NULL_RTX;
5651
  tree type = NULL_TREE, t, fndecl = NULL_TREE;
5652
  tree obj_type_ref = NULL_TREE;
5653
  CUMULATIVE_ARGS args_so_far_v;
5654
  cumulative_args_t args_so_far;
5655
 
5656
  memset (&args_so_far_v, 0, sizeof (args_so_far_v));
5657
  args_so_far = pack_cumulative_args (&args_so_far_v);
5658
  if (GET_CODE (call) == PARALLEL)
5659
    call = XVECEXP (call, 0, 0);
5660
  if (GET_CODE (call) == SET)
5661
    call = SET_SRC (call);
5662
  if (GET_CODE (call) == CALL && MEM_P (XEXP (call, 0)))
5663
    {
5664
      if (GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
5665
        {
5666
          rtx symbol = XEXP (XEXP (call, 0), 0);
5667
          if (SYMBOL_REF_DECL (symbol))
5668
            fndecl = SYMBOL_REF_DECL (symbol);
5669
        }
5670
      if (fndecl == NULL_TREE)
5671
        fndecl = MEM_EXPR (XEXP (call, 0));
5672
      if (fndecl
5673
          && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
5674
          && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
5675
        fndecl = NULL_TREE;
5676
      if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
5677
        type = TREE_TYPE (fndecl);
5678
      if (fndecl && TREE_CODE (fndecl) != FUNCTION_DECL)
5679
        {
5680
          if (TREE_CODE (fndecl) == INDIRECT_REF
5681
              && TREE_CODE (TREE_OPERAND (fndecl, 0)) == OBJ_TYPE_REF)
5682
            obj_type_ref = TREE_OPERAND (fndecl, 0);
5683
          fndecl = NULL_TREE;
5684
        }
5685
      if (type)
5686
        {
5687
          for (t = TYPE_ARG_TYPES (type); t && t != void_list_node;
5688
               t = TREE_CHAIN (t))
5689
            if (TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE
5690
                && INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (t))))
5691
              break;
5692
          if ((t == NULL || t == void_list_node) && obj_type_ref == NULL_TREE)
5693
            type = NULL;
5694
          else
5695
            {
5696
              int nargs ATTRIBUTE_UNUSED = list_length (TYPE_ARG_TYPES (type));
5697
              link = CALL_INSN_FUNCTION_USAGE (insn);
5698
#ifndef PCC_STATIC_STRUCT_RETURN
5699
              if (aggregate_value_p (TREE_TYPE (type), type)
5700
                  && targetm.calls.struct_value_rtx (type, 0) == 0)
5701
                {
5702
                  tree struct_addr = build_pointer_type (TREE_TYPE (type));
5703
                  enum machine_mode mode = TYPE_MODE (struct_addr);
5704
                  rtx reg;
5705
                  INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5706
                                        nargs + 1);
5707
                  reg = targetm.calls.function_arg (args_so_far, mode,
5708
                                                    struct_addr, true);
5709
                  targetm.calls.function_arg_advance (args_so_far, mode,
5710
                                                      struct_addr, true);
5711
                  if (reg == NULL_RTX)
5712
                    {
5713
                      for (; link; link = XEXP (link, 1))
5714
                        if (GET_CODE (XEXP (link, 0)) == USE
5715
                            && MEM_P (XEXP (XEXP (link, 0), 0)))
5716
                          {
5717
                            link = XEXP (link, 1);
5718
                            break;
5719
                          }
5720
                    }
5721
                }
5722
              else
5723
#endif
5724
                INIT_CUMULATIVE_ARGS (args_so_far_v, type, NULL_RTX, fndecl,
5725
                                      nargs);
5726
              if (obj_type_ref && TYPE_ARG_TYPES (type) != void_list_node)
5727
                {
5728
                  enum machine_mode mode;
5729
                  t = TYPE_ARG_TYPES (type);
5730
                  mode = TYPE_MODE (TREE_VALUE (t));
5731
                  this_arg = targetm.calls.function_arg (args_so_far, mode,
5732
                                                         TREE_VALUE (t), true);
5733
                  if (this_arg && !REG_P (this_arg))
5734
                    this_arg = NULL_RTX;
5735
                  else if (this_arg == NULL_RTX)
5736
                    {
5737
                      for (; link; link = XEXP (link, 1))
5738
                        if (GET_CODE (XEXP (link, 0)) == USE
5739
                            && MEM_P (XEXP (XEXP (link, 0), 0)))
5740
                          {
5741
                            this_arg = XEXP (XEXP (link, 0), 0);
5742
                            break;
5743
                          }
5744
                    }
5745
                }
5746
            }
5747
        }
5748
    }
5749
  t = type ? TYPE_ARG_TYPES (type) : NULL_TREE;
5750
 
5751
  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
5752
    if (GET_CODE (XEXP (link, 0)) == USE)
5753
      {
5754
        rtx item = NULL_RTX;
5755
        x = XEXP (XEXP (link, 0), 0);
5756
        if (GET_MODE (link) == VOIDmode
5757
            || GET_MODE (link) == BLKmode
5758
            || (GET_MODE (link) != GET_MODE (x)
5759
                && (GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
5760
                    || GET_MODE_CLASS (GET_MODE (x)) != MODE_INT)))
5761
          /* Can't do anything for these, if the original type mode
5762
             isn't known or can't be converted.  */;
5763
        else if (REG_P (x))
5764
          {
5765
            cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
5766
            if (val && cselib_preserved_value_p (val))
5767
              item = val->val_rtx;
5768
            else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
5769
              {
5770
                enum machine_mode mode = GET_MODE (x);
5771
 
5772
                while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
5773
                       && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
5774
                  {
5775
                    rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
5776
 
5777
                    if (reg == NULL_RTX || !REG_P (reg))
5778
                      continue;
5779
                    val = cselib_lookup (reg, mode, 0, VOIDmode);
5780
                    if (val && cselib_preserved_value_p (val))
5781
                      {
5782
                        item = val->val_rtx;
5783
                        break;
5784
                      }
5785
                  }
5786
              }
5787
          }
5788
        else if (MEM_P (x))
5789
          {
5790
            rtx mem = x;
5791
            cselib_val *val;
5792
 
5793
            if (!frame_pointer_needed)
5794
              {
5795
                struct adjust_mem_data amd;
5796
                amd.mem_mode = VOIDmode;
5797
                amd.stack_adjust = -VTI (bb)->out.stack_adjust;
5798
                amd.side_effects = NULL_RTX;
5799
                amd.store = true;
5800
                mem = simplify_replace_fn_rtx (mem, NULL_RTX, adjust_mems,
5801
                                               &amd);
5802
                gcc_assert (amd.side_effects == NULL_RTX);
5803
              }
5804
            val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
5805
            if (val && cselib_preserved_value_p (val))
5806
              item = val->val_rtx;
5807
            else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT)
5808
              {
5809
                /* For non-integer stack argument see also if they weren't
5810
                   initialized by integers.  */
5811
                enum machine_mode imode = int_mode_for_mode (GET_MODE (mem));
5812
                if (imode != GET_MODE (mem) && imode != BLKmode)
5813
                  {
5814
                    val = cselib_lookup (adjust_address_nv (mem, imode, 0),
5815
                                         imode, 0, VOIDmode);
5816
                    if (val && cselib_preserved_value_p (val))
5817
                      item = lowpart_subreg (GET_MODE (x), val->val_rtx,
5818
                                             imode);
5819
                  }
5820
              }
5821
          }
5822
        if (item)
5823
          {
5824
            rtx x2 = x;
5825
            if (GET_MODE (item) != GET_MODE (link))
5826
              item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
5827
            if (GET_MODE (x2) != GET_MODE (link))
5828
              x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
5829
            item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
5830
            call_arguments
5831
              = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
5832
          }
5833
        if (t && t != void_list_node)
5834
          {
5835
            tree argtype = TREE_VALUE (t);
5836
            enum machine_mode mode = TYPE_MODE (argtype);
5837
            rtx reg;
5838
            if (pass_by_reference (&args_so_far_v, mode, argtype, true))
5839
              {
5840
                argtype = build_pointer_type (argtype);
5841
                mode = TYPE_MODE (argtype);
5842
              }
5843
            reg = targetm.calls.function_arg (args_so_far, mode,
5844
                                              argtype, true);
5845
            if (TREE_CODE (argtype) == REFERENCE_TYPE
5846
                && INTEGRAL_TYPE_P (TREE_TYPE (argtype))
5847
                && reg
5848
                && REG_P (reg)
5849
                && GET_MODE (reg) == mode
5850
                && GET_MODE_CLASS (mode) == MODE_INT
5851
                && REG_P (x)
5852
                && REGNO (x) == REGNO (reg)
5853
                && GET_MODE (x) == mode
5854
                && item)
5855
              {
5856
                enum machine_mode indmode
5857
                  = TYPE_MODE (TREE_TYPE (argtype));
5858
                rtx mem = gen_rtx_MEM (indmode, x);
5859
                cselib_val *val = cselib_lookup (mem, indmode, 0, VOIDmode);
5860
                if (val && cselib_preserved_value_p (val))
5861
                  {
5862
                    item = gen_rtx_CONCAT (indmode, mem, val->val_rtx);
5863
                    call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
5864
                                                        call_arguments);
5865
                  }
5866
                else
5867
                  {
5868
                    struct elt_loc_list *l;
5869
                    tree initial;
5870
 
5871
                    /* Try harder, when passing address of a constant
5872
                       pool integer it can be easily read back.  */
5873
                    item = XEXP (item, 1);
5874
                    if (GET_CODE (item) == SUBREG)
5875
                      item = SUBREG_REG (item);
5876
                    gcc_assert (GET_CODE (item) == VALUE);
5877
                    val = CSELIB_VAL_PTR (item);
5878
                    for (l = val->locs; l; l = l->next)
5879
                      if (GET_CODE (l->loc) == SYMBOL_REF
5880
                          && TREE_CONSTANT_POOL_ADDRESS_P (l->loc)
5881
                          && SYMBOL_REF_DECL (l->loc)
5882
                          && DECL_INITIAL (SYMBOL_REF_DECL (l->loc)))
5883
                        {
5884
                          initial = DECL_INITIAL (SYMBOL_REF_DECL (l->loc));
5885
                          if (host_integerp (initial, 0))
5886
                            {
5887
                              item = GEN_INT (tree_low_cst (initial, 0));
5888
                              item = gen_rtx_CONCAT (indmode, mem, item);
5889
                              call_arguments
5890
                                = gen_rtx_EXPR_LIST (VOIDmode, item,
5891
                                                     call_arguments);
5892
                            }
5893
                          break;
5894
                        }
5895
                  }
5896
              }
5897
            targetm.calls.function_arg_advance (args_so_far, mode,
5898
                                                argtype, true);
5899
            t = TREE_CHAIN (t);
5900
          }
5901
      }
5902
 
5903
  /* Add debug arguments.  */
5904
  if (fndecl
5905
      && TREE_CODE (fndecl) == FUNCTION_DECL
5906
      && DECL_HAS_DEBUG_ARGS_P (fndecl))
5907
    {
5908
      VEC(tree, gc) **debug_args = decl_debug_args_lookup (fndecl);
5909
      if (debug_args)
5910
        {
5911
          unsigned int ix;
5912
          tree param;
5913
          for (ix = 0; VEC_iterate (tree, *debug_args, ix, param); ix += 2)
5914
            {
5915
              rtx item;
5916
              tree dtemp = VEC_index (tree, *debug_args, ix + 1);
5917
              enum machine_mode mode = DECL_MODE (dtemp);
5918
              item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
5919
              item = gen_rtx_CONCAT (mode, item, DECL_RTL_KNOWN_SET (dtemp));
5920
              call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
5921
                                                  call_arguments);
5922
            }
5923
        }
5924
    }
5925
 
5926
  /* Reverse call_arguments chain.  */
5927
  prev = NULL_RTX;
5928
  for (cur = call_arguments; cur; cur = next)
5929
    {
5930
      next = XEXP (cur, 1);
5931
      XEXP (cur, 1) = prev;
5932
      prev = cur;
5933
    }
5934
  call_arguments = prev;
5935
 
5936
  x = PATTERN (insn);
5937
  if (GET_CODE (x) == PARALLEL)
5938
    x = XVECEXP (x, 0, 0);
5939
  if (GET_CODE (x) == SET)
5940
    x = SET_SRC (x);
5941
  if (GET_CODE (x) == CALL && MEM_P (XEXP (x, 0)))
5942
    {
5943
      x = XEXP (XEXP (x, 0), 0);
5944
      if (GET_CODE (x) == SYMBOL_REF)
5945
        /* Don't record anything.  */;
5946
      else if (CONSTANT_P (x))
5947
        {
5948
          x = gen_rtx_CONCAT (GET_MODE (x) == VOIDmode ? Pmode : GET_MODE (x),
5949
                              pc_rtx, x);
5950
          call_arguments
5951
            = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5952
        }
5953
      else
5954
        {
5955
          cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
5956
          if (val && cselib_preserved_value_p (val))
5957
            {
5958
              x = gen_rtx_CONCAT (GET_MODE (x), pc_rtx, val->val_rtx);
5959
              call_arguments
5960
                = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5961
            }
5962
        }
5963
    }
5964
  if (this_arg)
5965
    {
5966
      enum machine_mode mode
5967
        = TYPE_MODE (TREE_TYPE (OBJ_TYPE_REF_EXPR (obj_type_ref)));
5968
      rtx clobbered = gen_rtx_MEM (mode, this_arg);
5969
      HOST_WIDE_INT token
5970
        = tree_low_cst (OBJ_TYPE_REF_TOKEN (obj_type_ref), 0);
5971
      if (token)
5972
        clobbered = plus_constant (clobbered, token * GET_MODE_SIZE (mode));
5973
      clobbered = gen_rtx_MEM (mode, clobbered);
5974
      x = gen_rtx_CONCAT (mode, gen_rtx_CLOBBER (VOIDmode, pc_rtx), clobbered);
5975
      call_arguments
5976
        = gen_rtx_EXPR_LIST (VOIDmode, x, call_arguments);
5977
    }
5978
}
5979
 
5980
/* Callback for cselib_record_sets_hook, that records as micro
5981
   operations uses and stores in an insn after cselib_record_sets has
5982
   analyzed the sets in an insn, but before it modifies the stored
5983
   values in the internal tables, unless cselib_record_sets doesn't
5984
   call it directly (perhaps because we're not doing cselib in the
5985
   first place, in which case sets and n_sets will be 0).  */
5986
 
5987
static void
5988
add_with_sets (rtx insn, struct cselib_set *sets, int n_sets)
5989
{
5990
  basic_block bb = BLOCK_FOR_INSN (insn);
5991
  int n1, n2;
5992
  struct count_use_info cui;
5993
  micro_operation *mos;
5994
 
5995
  cselib_hook_called = true;
5996
 
5997
  cui.insn = insn;
5998
  cui.bb = bb;
5999
  cui.sets = sets;
6000
  cui.n_sets = n_sets;
6001
 
6002
  n1 = VEC_length (micro_operation, VTI (bb)->mos);
6003
  cui.store_p = false;
6004
  note_uses (&PATTERN (insn), add_uses_1, &cui);
6005
  n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6006
  mos = VEC_address (micro_operation, VTI (bb)->mos);
6007
 
6008
  /* Order the MO_USEs to be before MO_USE_NO_VARs and MO_VAL_USE, and
6009
     MO_VAL_LOC last.  */
6010
  while (n1 < n2)
6011
    {
6012
      while (n1 < n2 && mos[n1].type == MO_USE)
6013
        n1++;
6014
      while (n1 < n2 && mos[n2].type != MO_USE)
6015
        n2--;
6016
      if (n1 < n2)
6017
        {
6018
          micro_operation sw;
6019
 
6020
          sw = mos[n1];
6021
          mos[n1] = mos[n2];
6022
          mos[n2] = sw;
6023
        }
6024
    }
6025
 
6026
  n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6027
  while (n1 < n2)
6028
    {
6029
      while (n1 < n2 && mos[n1].type != MO_VAL_LOC)
6030
        n1++;
6031
      while (n1 < n2 && mos[n2].type == MO_VAL_LOC)
6032
        n2--;
6033
      if (n1 < n2)
6034
        {
6035
          micro_operation sw;
6036
 
6037
          sw = mos[n1];
6038
          mos[n1] = mos[n2];
6039
          mos[n2] = sw;
6040
        }
6041
    }
6042
 
6043
  if (CALL_P (insn))
6044
    {
6045
      micro_operation mo;
6046
 
6047
      mo.type = MO_CALL;
6048
      mo.insn = insn;
6049
      mo.u.loc = call_arguments;
6050
      call_arguments = NULL_RTX;
6051
 
6052
      if (dump_file && (dump_flags & TDF_DETAILS))
6053
        log_op_type (PATTERN (insn), bb, insn, mo.type, dump_file);
6054
      VEC_safe_push (micro_operation, heap, VTI (bb)->mos, &mo);
6055
    }
6056
 
6057
  n1 = VEC_length (micro_operation, VTI (bb)->mos);
6058
  /* This will record NEXT_INSN (insn), such that we can
6059
     insert notes before it without worrying about any
6060
     notes that MO_USEs might emit after the insn.  */
6061
  cui.store_p = true;
6062
  note_stores (PATTERN (insn), add_stores, &cui);
6063
  n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6064
  mos = VEC_address (micro_operation, VTI (bb)->mos);
6065
 
6066
  /* Order the MO_VAL_USEs first (note_stores does nothing
6067
     on DEBUG_INSNs, so there are no MO_VAL_LOCs from this
6068
     insn), then MO_CLOBBERs, then MO_SET/MO_COPY/MO_VAL_SET.  */
6069
  while (n1 < n2)
6070
    {
6071
      while (n1 < n2 && mos[n1].type == MO_VAL_USE)
6072
        n1++;
6073
      while (n1 < n2 && mos[n2].type != MO_VAL_USE)
6074
        n2--;
6075
      if (n1 < n2)
6076
        {
6077
          micro_operation sw;
6078
 
6079
          sw = mos[n1];
6080
          mos[n1] = mos[n2];
6081
          mos[n2] = sw;
6082
        }
6083
    }
6084
 
6085
  n2 = VEC_length (micro_operation, VTI (bb)->mos) - 1;
6086
  while (n1 < n2)
6087
    {
6088
      while (n1 < n2 && mos[n1].type == MO_CLOBBER)
6089
        n1++;
6090
      while (n1 < n2 && mos[n2].type != MO_CLOBBER)
6091
        n2--;
6092
      if (n1 < n2)
6093
        {
6094
          micro_operation sw;
6095
 
6096
          sw = mos[n1];
6097
          mos[n1] = mos[n2];
6098
          mos[n2] = sw;
6099
        }
6100
    }
6101
}
6102
 
6103
static enum var_init_status
6104
find_src_status (dataflow_set *in, rtx src)
6105
{
6106
  tree decl = NULL_TREE;
6107
  enum var_init_status status = VAR_INIT_STATUS_UNINITIALIZED;
6108
 
6109
  if (! flag_var_tracking_uninit)
6110
    status = VAR_INIT_STATUS_INITIALIZED;
6111
 
6112
  if (src && REG_P (src))
6113
    decl = var_debug_decl (REG_EXPR (src));
6114
  else if (src && MEM_P (src))
6115
    decl = var_debug_decl (MEM_EXPR (src));
6116
 
6117
  if (src && decl)
6118
    status = get_init_value (in, src, dv_from_decl (decl));
6119
 
6120
  return status;
6121
}
6122
 
6123
/* SRC is the source of an assignment.  Use SET to try to find what
6124
   was ultimately assigned to SRC.  Return that value if known,
6125
   otherwise return SRC itself.  */
6126
 
6127
static rtx
6128
find_src_set_src (dataflow_set *set, rtx src)
6129
{
6130
  tree decl = NULL_TREE;   /* The variable being copied around.          */
6131
  rtx set_src = NULL_RTX;  /* The value for "decl" stored in "src".      */
6132
  variable var;
6133
  location_chain nextp;
6134
  int i;
6135
  bool found;
6136
 
6137
  if (src && REG_P (src))
6138
    decl = var_debug_decl (REG_EXPR (src));
6139
  else if (src && MEM_P (src))
6140
    decl = var_debug_decl (MEM_EXPR (src));
6141
 
6142
  if (src && decl)
6143
    {
6144
      decl_or_value dv = dv_from_decl (decl);
6145
 
6146
      var = shared_hash_find (set->vars, dv);
6147
      if (var)
6148
        {
6149
          found = false;
6150
          for (i = 0; i < var->n_var_parts && !found; i++)
6151
            for (nextp = var->var_part[i].loc_chain; nextp && !found;
6152
                 nextp = nextp->next)
6153
              if (rtx_equal_p (nextp->loc, src))
6154
                {
6155
                  set_src = nextp->set_src;
6156
                  found = true;
6157
                }
6158
 
6159
        }
6160
    }
6161
 
6162
  return set_src;
6163
}
6164
 
6165
/* Compute the changes of variable locations in the basic block BB.  */
6166
 
6167
static bool
6168
compute_bb_dataflow (basic_block bb)
6169
{
6170
  unsigned int i;
6171
  micro_operation *mo;
6172
  bool changed;
6173
  dataflow_set old_out;
6174
  dataflow_set *in = &VTI (bb)->in;
6175
  dataflow_set *out = &VTI (bb)->out;
6176
 
6177
  dataflow_set_init (&old_out);
6178
  dataflow_set_copy (&old_out, out);
6179
  dataflow_set_copy (out, in);
6180
 
6181
  FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
6182
    {
6183
      rtx insn = mo->insn;
6184
 
6185
      switch (mo->type)
6186
        {
6187
          case MO_CALL:
6188
            dataflow_set_clear_at_call (out);
6189
            break;
6190
 
6191
          case MO_USE:
6192
            {
6193
              rtx loc = mo->u.loc;
6194
 
6195
              if (REG_P (loc))
6196
                var_reg_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6197
              else if (MEM_P (loc))
6198
                var_mem_set (out, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
6199
            }
6200
            break;
6201
 
6202
          case MO_VAL_LOC:
6203
            {
6204
              rtx loc = mo->u.loc;
6205
              rtx val, vloc;
6206
              tree var;
6207
 
6208
              if (GET_CODE (loc) == CONCAT)
6209
                {
6210
                  val = XEXP (loc, 0);
6211
                  vloc = XEXP (loc, 1);
6212
                }
6213
              else
6214
                {
6215
                  val = NULL_RTX;
6216
                  vloc = loc;
6217
                }
6218
 
6219
              var = PAT_VAR_LOCATION_DECL (vloc);
6220
 
6221
              clobber_variable_part (out, NULL_RTX,
6222
                                     dv_from_decl (var), 0, NULL_RTX);
6223
              if (val)
6224
                {
6225
                  if (VAL_NEEDS_RESOLUTION (loc))
6226
                    val_resolve (out, val, PAT_VAR_LOCATION_LOC (vloc), insn);
6227
                  set_variable_part (out, val, dv_from_decl (var), 0,
6228
                                     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6229
                                     INSERT);
6230
                }
6231
              else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
6232
                set_variable_part (out, PAT_VAR_LOCATION_LOC (vloc),
6233
                                   dv_from_decl (var), 0,
6234
                                   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
6235
                                   INSERT);
6236
            }
6237
            break;
6238
 
6239
          case MO_VAL_USE:
6240
            {
6241
              rtx loc = mo->u.loc;
6242
              rtx val, vloc, uloc;
6243
 
6244
              vloc = uloc = XEXP (loc, 1);
6245
              val = XEXP (loc, 0);
6246
 
6247
              if (GET_CODE (val) == CONCAT)
6248
                {
6249
                  uloc = XEXP (val, 1);
6250
                  val = XEXP (val, 0);
6251
                }
6252
 
6253
              if (VAL_NEEDS_RESOLUTION (loc))
6254
                val_resolve (out, val, vloc, insn);
6255
              else
6256
                val_store (out, val, uloc, insn, false);
6257
 
6258
              if (VAL_HOLDS_TRACK_EXPR (loc))
6259
                {
6260
                  if (GET_CODE (uloc) == REG)
6261
                    var_reg_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6262
                                 NULL);
6263
                  else if (GET_CODE (uloc) == MEM)
6264
                    var_mem_set (out, uloc, VAR_INIT_STATUS_UNINITIALIZED,
6265
                                 NULL);
6266
                }
6267
            }
6268
            break;
6269
 
6270
          case MO_VAL_SET:
6271
            {
6272
              rtx loc = mo->u.loc;
6273
              rtx val, vloc, uloc;
6274
 
6275
              vloc = loc;
6276
              uloc = XEXP (vloc, 1);
6277
              val = XEXP (vloc, 0);
6278
              vloc = uloc;
6279
 
6280
              if (GET_CODE (val) == CONCAT)
6281
                {
6282
                  vloc = XEXP (val, 1);
6283
                  val = XEXP (val, 0);
6284
                }
6285
 
6286
              if (GET_CODE (vloc) == SET)
6287
                {
6288
                  rtx vsrc = SET_SRC (vloc);
6289
 
6290
                  gcc_assert (val != vsrc);
6291
                  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
6292
 
6293
                  vloc = SET_DEST (vloc);
6294
 
6295
                  if (VAL_NEEDS_RESOLUTION (loc))
6296
                    val_resolve (out, val, vsrc, insn);
6297
                }
6298
              else if (VAL_NEEDS_RESOLUTION (loc))
6299
                {
6300
                  gcc_assert (GET_CODE (uloc) == SET
6301
                              && GET_CODE (SET_SRC (uloc)) == REG);
6302
                  val_resolve (out, val, SET_SRC (uloc), insn);
6303
                }
6304
 
6305
              if (VAL_HOLDS_TRACK_EXPR (loc))
6306
                {
6307
                  if (VAL_EXPR_IS_CLOBBERED (loc))
6308
                    {
6309
                      if (REG_P (uloc))
6310
                        var_reg_delete (out, uloc, true);
6311
                      else if (MEM_P (uloc))
6312
                        var_mem_delete (out, uloc, true);
6313
                    }
6314
                  else
6315
                    {
6316
                      bool copied_p = VAL_EXPR_IS_COPIED (loc);
6317
                      rtx set_src = NULL;
6318
                      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
6319
 
6320
                      if (GET_CODE (uloc) == SET)
6321
                        {
6322
                          set_src = SET_SRC (uloc);
6323
                          uloc = SET_DEST (uloc);
6324
                        }
6325
 
6326
                      if (copied_p)
6327
                        {
6328
                          if (flag_var_tracking_uninit)
6329
                            {
6330
                              status = find_src_status (in, set_src);
6331
 
6332
                              if (status == VAR_INIT_STATUS_UNKNOWN)
6333
                                status = find_src_status (out, set_src);
6334
                            }
6335
 
6336
                          set_src = find_src_set_src (in, set_src);
6337
                        }
6338
 
6339
                      if (REG_P (uloc))
6340
                        var_reg_delete_and_set (out, uloc, !copied_p,
6341
                                                status, set_src);
6342
                      else if (MEM_P (uloc))
6343
                        var_mem_delete_and_set (out, uloc, !copied_p,
6344
                                                status, set_src);
6345
                    }
6346
                }
6347
              else if (REG_P (uloc))
6348
                var_regno_delete (out, REGNO (uloc));
6349
 
6350
              val_store (out, val, vloc, insn, true);
6351
            }
6352
            break;
6353
 
6354
          case MO_SET:
6355
            {
6356
              rtx loc = mo->u.loc;
6357
              rtx set_src = NULL;
6358
 
6359
              if (GET_CODE (loc) == SET)
6360
                {
6361
                  set_src = SET_SRC (loc);
6362
                  loc = SET_DEST (loc);
6363
                }
6364
 
6365
              if (REG_P (loc))
6366
                var_reg_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6367
                                        set_src);
6368
              else if (MEM_P (loc))
6369
                var_mem_delete_and_set (out, loc, true, VAR_INIT_STATUS_INITIALIZED,
6370
                                        set_src);
6371
            }
6372
            break;
6373
 
6374
          case MO_COPY:
6375
            {
6376
              rtx loc = mo->u.loc;
6377
              enum var_init_status src_status;
6378
              rtx set_src = NULL;
6379
 
6380
              if (GET_CODE (loc) == SET)
6381
                {
6382
                  set_src = SET_SRC (loc);
6383
                  loc = SET_DEST (loc);
6384
                }
6385
 
6386
              if (! flag_var_tracking_uninit)
6387
                src_status = VAR_INIT_STATUS_INITIALIZED;
6388
              else
6389
                {
6390
                  src_status = find_src_status (in, set_src);
6391
 
6392
                  if (src_status == VAR_INIT_STATUS_UNKNOWN)
6393
                    src_status = find_src_status (out, set_src);
6394
                }
6395
 
6396
              set_src = find_src_set_src (in, set_src);
6397
 
6398
              if (REG_P (loc))
6399
                var_reg_delete_and_set (out, loc, false, src_status, set_src);
6400
              else if (MEM_P (loc))
6401
                var_mem_delete_and_set (out, loc, false, src_status, set_src);
6402
            }
6403
            break;
6404
 
6405
          case MO_USE_NO_VAR:
6406
            {
6407
              rtx loc = mo->u.loc;
6408
 
6409
              if (REG_P (loc))
6410
                var_reg_delete (out, loc, false);
6411
              else if (MEM_P (loc))
6412
                var_mem_delete (out, loc, false);
6413
            }
6414
            break;
6415
 
6416
          case MO_CLOBBER:
6417
            {
6418
              rtx loc = mo->u.loc;
6419
 
6420
              if (REG_P (loc))
6421
                var_reg_delete (out, loc, true);
6422
              else if (MEM_P (loc))
6423
                var_mem_delete (out, loc, true);
6424
            }
6425
            break;
6426
 
6427
          case MO_ADJUST:
6428
            out->stack_adjust += mo->u.adjust;
6429
            break;
6430
        }
6431
    }
6432
 
6433
  if (MAY_HAVE_DEBUG_INSNS)
6434
    {
6435
      dataflow_set_equiv_regs (out);
6436
      htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
6437
                     out);
6438
      htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
6439
                     out);
6440
#if ENABLE_CHECKING
6441
      htab_traverse (shared_hash_htab (out->vars),
6442
                     canonicalize_loc_order_check, out);
6443
#endif
6444
    }
6445
  changed = dataflow_set_different (&old_out, out);
6446
  dataflow_set_destroy (&old_out);
6447
  return changed;
6448
}
6449
 
6450
/* Find the locations of variables in the whole function.  */
6451
 
6452
static bool
6453
vt_find_locations (void)
6454
{
6455
  fibheap_t worklist, pending, fibheap_swap;
6456
  sbitmap visited, in_worklist, in_pending, sbitmap_swap;
6457
  basic_block bb;
6458
  edge e;
6459
  int *bb_order;
6460
  int *rc_order;
6461
  int i;
6462
  int htabsz = 0;
6463
  int htabmax = PARAM_VALUE (PARAM_MAX_VARTRACK_SIZE);
6464
  bool success = true;
6465
 
6466
  timevar_push (TV_VAR_TRACKING_DATAFLOW);
6467
  /* Compute reverse completion order of depth first search of the CFG
6468
     so that the data-flow runs faster.  */
6469
  rc_order = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
6470
  bb_order = XNEWVEC (int, last_basic_block);
6471
  pre_and_rev_post_order_compute (NULL, rc_order, false);
6472
  for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; i++)
6473
    bb_order[rc_order[i]] = i;
6474
  free (rc_order);
6475
 
6476
  worklist = fibheap_new ();
6477
  pending = fibheap_new ();
6478
  visited = sbitmap_alloc (last_basic_block);
6479
  in_worklist = sbitmap_alloc (last_basic_block);
6480
  in_pending = sbitmap_alloc (last_basic_block);
6481
  sbitmap_zero (in_worklist);
6482
 
6483
  FOR_EACH_BB (bb)
6484
    fibheap_insert (pending, bb_order[bb->index], bb);
6485
  sbitmap_ones (in_pending);
6486
 
6487
  while (success && !fibheap_empty (pending))
6488
    {
6489
      fibheap_swap = pending;
6490
      pending = worklist;
6491
      worklist = fibheap_swap;
6492
      sbitmap_swap = in_pending;
6493
      in_pending = in_worklist;
6494
      in_worklist = sbitmap_swap;
6495
 
6496
      sbitmap_zero (visited);
6497
 
6498
      while (!fibheap_empty (worklist))
6499
        {
6500
          bb = (basic_block) fibheap_extract_min (worklist);
6501
          RESET_BIT (in_worklist, bb->index);
6502
          gcc_assert (!TEST_BIT (visited, bb->index));
6503
          if (!TEST_BIT (visited, bb->index))
6504
            {
6505
              bool changed;
6506
              edge_iterator ei;
6507
              int oldinsz, oldoutsz;
6508
 
6509
              SET_BIT (visited, bb->index);
6510
 
6511
              if (VTI (bb)->in.vars)
6512
                {
6513
                  htabsz
6514
                    -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6515
                        + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6516
                  oldinsz
6517
                    = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
6518
                  oldoutsz
6519
                    = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
6520
                }
6521
              else
6522
                oldinsz = oldoutsz = 0;
6523
 
6524
              if (MAY_HAVE_DEBUG_INSNS)
6525
                {
6526
                  dataflow_set *in = &VTI (bb)->in, *first_out = NULL;
6527
                  bool first = true, adjust = false;
6528
 
6529
                  /* Calculate the IN set as the intersection of
6530
                     predecessor OUT sets.  */
6531
 
6532
                  dataflow_set_clear (in);
6533
                  dst_can_be_shared = true;
6534
 
6535
                  FOR_EACH_EDGE (e, ei, bb->preds)
6536
                    if (!VTI (e->src)->flooded)
6537
                      gcc_assert (bb_order[bb->index]
6538
                                  <= bb_order[e->src->index]);
6539
                    else if (first)
6540
                      {
6541
                        dataflow_set_copy (in, &VTI (e->src)->out);
6542
                        first_out = &VTI (e->src)->out;
6543
                        first = false;
6544
                      }
6545
                    else
6546
                      {
6547
                        dataflow_set_merge (in, &VTI (e->src)->out);
6548
                        adjust = true;
6549
                      }
6550
 
6551
                  if (adjust)
6552
                    {
6553
                      dataflow_post_merge_adjust (in, &VTI (bb)->permp);
6554
#if ENABLE_CHECKING
6555
                      /* Merge and merge_adjust should keep entries in
6556
                         canonical order.  */
6557
                      htab_traverse (shared_hash_htab (in->vars),
6558
                                     canonicalize_loc_order_check,
6559
                                     in);
6560
#endif
6561
                      if (dst_can_be_shared)
6562
                        {
6563
                          shared_hash_destroy (in->vars);
6564
                          in->vars = shared_hash_copy (first_out->vars);
6565
                        }
6566
                    }
6567
 
6568
                  VTI (bb)->flooded = true;
6569
                }
6570
              else
6571
                {
6572
                  /* Calculate the IN set as union of predecessor OUT sets.  */
6573
                  dataflow_set_clear (&VTI (bb)->in);
6574
                  FOR_EACH_EDGE (e, ei, bb->preds)
6575
                    dataflow_set_union (&VTI (bb)->in, &VTI (e->src)->out);
6576
                }
6577
 
6578
              changed = compute_bb_dataflow (bb);
6579
              htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
6580
                         + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
6581
 
6582
              if (htabmax && htabsz > htabmax)
6583
                {
6584
                  if (MAY_HAVE_DEBUG_INSNS)
6585
                    inform (DECL_SOURCE_LOCATION (cfun->decl),
6586
                            "variable tracking size limit exceeded with "
6587
                            "-fvar-tracking-assignments, retrying without");
6588
                  else
6589
                    inform (DECL_SOURCE_LOCATION (cfun->decl),
6590
                            "variable tracking size limit exceeded");
6591
                  success = false;
6592
                  break;
6593
                }
6594
 
6595
              if (changed)
6596
                {
6597
                  FOR_EACH_EDGE (e, ei, bb->succs)
6598
                    {
6599
                      if (e->dest == EXIT_BLOCK_PTR)
6600
                        continue;
6601
 
6602
                      if (TEST_BIT (visited, e->dest->index))
6603
                        {
6604
                          if (!TEST_BIT (in_pending, e->dest->index))
6605
                            {
6606
                              /* Send E->DEST to next round.  */
6607
                              SET_BIT (in_pending, e->dest->index);
6608
                              fibheap_insert (pending,
6609
                                              bb_order[e->dest->index],
6610
                                              e->dest);
6611
                            }
6612
                        }
6613
                      else if (!TEST_BIT (in_worklist, e->dest->index))
6614
                        {
6615
                          /* Add E->DEST to current round.  */
6616
                          SET_BIT (in_worklist, e->dest->index);
6617
                          fibheap_insert (worklist, bb_order[e->dest->index],
6618
                                          e->dest);
6619
                        }
6620
                    }
6621
                }
6622
 
6623
              if (dump_file)
6624
                fprintf (dump_file,
6625
                         "BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
6626
                         bb->index,
6627
                         (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
6628
                         oldinsz,
6629
                         (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
6630
                         oldoutsz,
6631
                         (int)worklist->nodes, (int)pending->nodes, htabsz);
6632
 
6633
              if (dump_file && (dump_flags & TDF_DETAILS))
6634
                {
6635
                  fprintf (dump_file, "BB %i IN:\n", bb->index);
6636
                  dump_dataflow_set (&VTI (bb)->in);
6637
                  fprintf (dump_file, "BB %i OUT:\n", bb->index);
6638
                  dump_dataflow_set (&VTI (bb)->out);
6639
                }
6640
            }
6641
        }
6642
    }
6643
 
6644
  if (success && MAY_HAVE_DEBUG_INSNS)
6645
    FOR_EACH_BB (bb)
6646
      gcc_assert (VTI (bb)->flooded);
6647
 
6648
  free (bb_order);
6649
  fibheap_delete (worklist);
6650
  fibheap_delete (pending);
6651
  sbitmap_free (visited);
6652
  sbitmap_free (in_worklist);
6653
  sbitmap_free (in_pending);
6654
 
6655
  timevar_pop (TV_VAR_TRACKING_DATAFLOW);
6656
  return success;
6657
}
6658
 
6659
/* Print the content of the LIST to dump file.  */
6660
 
6661
static void
6662
dump_attrs_list (attrs list)
6663
{
6664
  for (; list; list = list->next)
6665
    {
6666
      if (dv_is_decl_p (list->dv))
6667
        print_mem_expr (dump_file, dv_as_decl (list->dv));
6668
      else
6669
        print_rtl_single (dump_file, dv_as_value (list->dv));
6670
      fprintf (dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
6671
    }
6672
  fprintf (dump_file, "\n");
6673
}
6674
 
6675
/* Print the information about variable *SLOT to dump file.  */
6676
 
6677
static int
6678
dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
6679
{
6680
  variable var = (variable) *slot;
6681
 
6682
  dump_var (var);
6683
 
6684
  /* Continue traversing the hash table.  */
6685
  return 1;
6686
}
6687
 
6688
/* Print the information about variable VAR to dump file.  */
6689
 
6690
static void
6691
dump_var (variable var)
6692
{
6693
  int i;
6694
  location_chain node;
6695
 
6696
  if (dv_is_decl_p (var->dv))
6697
    {
6698
      const_tree decl = dv_as_decl (var->dv);
6699
 
6700
      if (DECL_NAME (decl))
6701
        {
6702
          fprintf (dump_file, "  name: %s",
6703
                   IDENTIFIER_POINTER (DECL_NAME (decl)));
6704
          if (dump_flags & TDF_UID)
6705
            fprintf (dump_file, "D.%u", DECL_UID (decl));
6706
        }
6707
      else if (TREE_CODE (decl) == DEBUG_EXPR_DECL)
6708
        fprintf (dump_file, "  name: D#%u", DEBUG_TEMP_UID (decl));
6709
      else
6710
        fprintf (dump_file, "  name: D.%u", DECL_UID (decl));
6711
      fprintf (dump_file, "\n");
6712
    }
6713
  else
6714
    {
6715
      fputc (' ', dump_file);
6716
      print_rtl_single (dump_file, dv_as_value (var->dv));
6717
    }
6718
 
6719
  for (i = 0; i < var->n_var_parts; i++)
6720
    {
6721
      fprintf (dump_file, "    offset %ld\n",
6722
               (long)(var->onepart ? 0 : VAR_PART_OFFSET (var, i)));
6723
      for (node = var->var_part[i].loc_chain; node; node = node->next)
6724
        {
6725
          fprintf (dump_file, "      ");
6726
          if (node->init == VAR_INIT_STATUS_UNINITIALIZED)
6727
            fprintf (dump_file, "[uninit]");
6728
          print_rtl_single (dump_file, node->loc);
6729
        }
6730
    }
6731
}
6732
 
6733
/* Print the information about variables from hash table VARS to dump file.  */
6734
 
6735
static void
6736
dump_vars (htab_t vars)
6737
{
6738
  if (htab_elements (vars) > 0)
6739
    {
6740
      fprintf (dump_file, "Variables:\n");
6741
      htab_traverse (vars, dump_var_slot, NULL);
6742
    }
6743
}
6744
 
6745
/* Print the dataflow set SET to dump file.  */
6746
 
6747
static void
6748
dump_dataflow_set (dataflow_set *set)
6749
{
6750
  int i;
6751
 
6752
  fprintf (dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
6753
           set->stack_adjust);
6754
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6755
    {
6756
      if (set->regs[i])
6757
        {
6758
          fprintf (dump_file, "Reg %d:", i);
6759
          dump_attrs_list (set->regs[i]);
6760
        }
6761
    }
6762
  dump_vars (shared_hash_htab (set->vars));
6763
  fprintf (dump_file, "\n");
6764
}
6765
 
6766
/* Print the IN and OUT sets for each basic block to dump file.  */
6767
 
6768
static void
6769
dump_dataflow_sets (void)
6770
{
6771
  basic_block bb;
6772
 
6773
  FOR_EACH_BB (bb)
6774
    {
6775
      fprintf (dump_file, "\nBasic block %d:\n", bb->index);
6776
      fprintf (dump_file, "IN:\n");
6777
      dump_dataflow_set (&VTI (bb)->in);
6778
      fprintf (dump_file, "OUT:\n");
6779
      dump_dataflow_set (&VTI (bb)->out);
6780
    }
6781
}
6782
 
6783
/* Return the variable for DV in dropped_values, inserting one if
6784
   requested with INSERT.  */
6785
 
6786
static inline variable
6787
variable_from_dropped (decl_or_value dv, enum insert_option insert)
6788
{
6789
  void **slot;
6790
  variable empty_var;
6791
  onepart_enum_t onepart;
6792
 
6793
  slot = htab_find_slot_with_hash (dropped_values, dv, dv_htab_hash (dv),
6794
                                   insert);
6795
 
6796
  if (!slot)
6797
    return NULL;
6798
 
6799
  if (*slot)
6800
    return (variable) *slot;
6801
 
6802
  gcc_checking_assert (insert == INSERT);
6803
 
6804
  onepart = dv_onepart_p (dv);
6805
 
6806
  gcc_checking_assert (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR);
6807
 
6808
  empty_var = (variable) pool_alloc (onepart_pool (onepart));
6809
  empty_var->dv = dv;
6810
  empty_var->refcount = 1;
6811
  empty_var->n_var_parts = 0;
6812
  empty_var->onepart = onepart;
6813
  empty_var->in_changed_variables = false;
6814
  empty_var->var_part[0].loc_chain = NULL;
6815
  empty_var->var_part[0].cur_loc = NULL;
6816
  VAR_LOC_1PAUX (empty_var) = NULL;
6817
  set_dv_changed (dv, true);
6818
 
6819
  *slot = empty_var;
6820
 
6821
  return empty_var;
6822
}
6823
 
6824
/* Recover the one-part aux from dropped_values.  */
6825
 
6826
static struct onepart_aux *
6827
recover_dropped_1paux (variable var)
6828
{
6829
  variable dvar;
6830
 
6831
  gcc_checking_assert (var->onepart);
6832
 
6833
  if (VAR_LOC_1PAUX (var))
6834
    return VAR_LOC_1PAUX (var);
6835
 
6836
  if (var->onepart == ONEPART_VDECL)
6837
    return NULL;
6838
 
6839
  dvar = variable_from_dropped (var->dv, NO_INSERT);
6840
 
6841
  if (!dvar)
6842
    return NULL;
6843
 
6844
  VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (dvar);
6845
  VAR_LOC_1PAUX (dvar) = NULL;
6846
 
6847
  return VAR_LOC_1PAUX (var);
6848
}
6849
 
6850
/* Add variable VAR to the hash table of changed variables and
6851
   if it has no locations delete it from SET's hash table.  */
6852
 
6853
static void
6854
variable_was_changed (variable var, dataflow_set *set)
6855
{
6856
  hashval_t hash = dv_htab_hash (var->dv);
6857
 
6858
  if (emit_notes)
6859
    {
6860
      void **slot;
6861
 
6862
      /* Remember this decl or VALUE has been added to changed_variables.  */
6863
      set_dv_changed (var->dv, true);
6864
 
6865
      slot = htab_find_slot_with_hash (changed_variables,
6866
                                       var->dv,
6867
                                       hash, INSERT);
6868
 
6869
      if (*slot)
6870
        {
6871
          variable old_var = (variable) *slot;
6872
          gcc_assert (old_var->in_changed_variables);
6873
          old_var->in_changed_variables = false;
6874
          if (var != old_var && var->onepart)
6875
            {
6876
              /* Restore the auxiliary info from an empty variable
6877
                 previously created for changed_variables, so it is
6878
                 not lost.  */
6879
              gcc_checking_assert (!VAR_LOC_1PAUX (var));
6880
              VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (old_var);
6881
              VAR_LOC_1PAUX (old_var) = NULL;
6882
            }
6883
          variable_htab_free (*slot);
6884
        }
6885
 
6886
      if (set && var->n_var_parts == 0)
6887
        {
6888
          onepart_enum_t onepart = var->onepart;
6889
          variable empty_var = NULL;
6890
          void **dslot = NULL;
6891
 
6892
          if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
6893
            {
6894
              dslot = htab_find_slot_with_hash (dropped_values, var->dv,
6895
                                                dv_htab_hash (var->dv),
6896
                                                INSERT);
6897
              empty_var = (variable) *dslot;
6898
 
6899
              if (empty_var)
6900
                {
6901
                  gcc_checking_assert (!empty_var->in_changed_variables);
6902
                  if (!VAR_LOC_1PAUX (var))
6903
                    {
6904
                      VAR_LOC_1PAUX (var) = VAR_LOC_1PAUX (empty_var);
6905
                      VAR_LOC_1PAUX (empty_var) = NULL;
6906
                    }
6907
                  else
6908
                    gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
6909
                }
6910
            }
6911
 
6912
          if (!empty_var)
6913
            {
6914
              empty_var = (variable) pool_alloc (onepart_pool (onepart));
6915
              empty_var->dv = var->dv;
6916
              empty_var->refcount = 1;
6917
              empty_var->n_var_parts = 0;
6918
              empty_var->onepart = onepart;
6919
              if (dslot)
6920
                {
6921
                  empty_var->refcount++;
6922
                  *dslot = empty_var;
6923
                }
6924
            }
6925
          else
6926
            empty_var->refcount++;
6927
          empty_var->in_changed_variables = true;
6928
          *slot = empty_var;
6929
          if (onepart)
6930
            {
6931
              empty_var->var_part[0].loc_chain = NULL;
6932
              empty_var->var_part[0].cur_loc = NULL;
6933
              VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (var);
6934
              VAR_LOC_1PAUX (var) = NULL;
6935
            }
6936
          goto drop_var;
6937
        }
6938
      else
6939
        {
6940
          if (var->onepart && !VAR_LOC_1PAUX (var))
6941
            recover_dropped_1paux (var);
6942
          var->refcount++;
6943
          var->in_changed_variables = true;
6944
          *slot = var;
6945
        }
6946
    }
6947
  else
6948
    {
6949
      gcc_assert (set);
6950
      if (var->n_var_parts == 0)
6951
        {
6952
          void **slot;
6953
 
6954
        drop_var:
6955
          slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
6956
          if (slot)
6957
            {
6958
              if (shared_hash_shared (set->vars))
6959
                slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
6960
                                                      NO_INSERT);
6961
              htab_clear_slot (shared_hash_htab (set->vars), slot);
6962
            }
6963
        }
6964
    }
6965
}
6966
 
6967
/* Look for the index in VAR->var_part corresponding to OFFSET.
6968
   Return -1 if not found.  If INSERTION_POINT is non-NULL, the
6969
   referenced int will be set to the index that the part has or should
6970
   have, if it should be inserted.  */
6971
 
6972
static inline int
6973
find_variable_location_part (variable var, HOST_WIDE_INT offset,
6974
                             int *insertion_point)
6975
{
6976
  int pos, low, high;
6977
 
6978
  if (var->onepart)
6979
    {
6980
      if (offset != 0)
6981
        return -1;
6982
 
6983
      if (insertion_point)
6984
        *insertion_point = 0;
6985
 
6986
      return var->n_var_parts - 1;
6987
    }
6988
 
6989
  /* Find the location part.  */
6990
  low = 0;
6991
  high = var->n_var_parts;
6992
  while (low != high)
6993
    {
6994
      pos = (low + high) / 2;
6995
      if (VAR_PART_OFFSET (var, pos) < offset)
6996
        low = pos + 1;
6997
      else
6998
        high = pos;
6999
    }
7000
  pos = low;
7001
 
7002
  if (insertion_point)
7003
    *insertion_point = pos;
7004
 
7005
  if (pos < var->n_var_parts && VAR_PART_OFFSET (var, pos) == offset)
7006
    return pos;
7007
 
7008
  return -1;
7009
}
7010
 
7011
static void **
7012
set_slot_part (dataflow_set *set, rtx loc, void **slot,
7013
               decl_or_value dv, HOST_WIDE_INT offset,
7014
               enum var_init_status initialized, rtx set_src)
7015
{
7016
  int pos;
7017
  location_chain node, next;
7018
  location_chain *nextp;
7019
  variable var;
7020
  onepart_enum_t onepart;
7021
 
7022
  var = (variable) *slot;
7023
 
7024
  if (var)
7025
    onepart = var->onepart;
7026
  else
7027
    onepart = dv_onepart_p (dv);
7028
 
7029
  gcc_checking_assert (offset == 0 || !onepart);
7030
  gcc_checking_assert (loc != dv_as_opaque (dv));
7031
 
7032
  if (! flag_var_tracking_uninit)
7033
    initialized = VAR_INIT_STATUS_INITIALIZED;
7034
 
7035
  if (!var)
7036
    {
7037
      /* Create new variable information.  */
7038
      var = (variable) pool_alloc (onepart_pool (onepart));
7039
      var->dv = dv;
7040
      var->refcount = 1;
7041
      var->n_var_parts = 1;
7042
      var->onepart = onepart;
7043
      var->in_changed_variables = false;
7044
      if (var->onepart)
7045
        VAR_LOC_1PAUX (var) = NULL;
7046
      else
7047
        VAR_PART_OFFSET (var, 0) = offset;
7048
      var->var_part[0].loc_chain = NULL;
7049
      var->var_part[0].cur_loc = NULL;
7050
      *slot = var;
7051
      pos = 0;
7052
      nextp = &var->var_part[0].loc_chain;
7053
    }
7054
  else if (onepart)
7055
    {
7056
      int r = -1, c = 0;
7057
 
7058
      gcc_assert (dv_as_opaque (var->dv) == dv_as_opaque (dv));
7059
 
7060
      pos = 0;
7061
 
7062
      if (GET_CODE (loc) == VALUE)
7063
        {
7064
          for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7065
               nextp = &node->next)
7066
            if (GET_CODE (node->loc) == VALUE)
7067
              {
7068
                if (node->loc == loc)
7069
                  {
7070
                    r = 0;
7071
                    break;
7072
                  }
7073
                if (canon_value_cmp (node->loc, loc))
7074
                  c++;
7075
                else
7076
                  {
7077
                    r = 1;
7078
                    break;
7079
                  }
7080
              }
7081
            else if (REG_P (node->loc) || MEM_P (node->loc))
7082
              c++;
7083
            else
7084
              {
7085
                r = 1;
7086
                break;
7087
              }
7088
        }
7089
      else if (REG_P (loc))
7090
        {
7091
          for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7092
               nextp = &node->next)
7093
            if (REG_P (node->loc))
7094
              {
7095
                if (REGNO (node->loc) < REGNO (loc))
7096
                  c++;
7097
                else
7098
                  {
7099
                    if (REGNO (node->loc) == REGNO (loc))
7100
                      r = 0;
7101
                    else
7102
                      r = 1;
7103
                    break;
7104
                  }
7105
              }
7106
            else
7107
              {
7108
                r = 1;
7109
                break;
7110
              }
7111
        }
7112
      else if (MEM_P (loc))
7113
        {
7114
          for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7115
               nextp = &node->next)
7116
            if (REG_P (node->loc))
7117
              c++;
7118
            else if (MEM_P (node->loc))
7119
              {
7120
                if ((r = loc_cmp (XEXP (node->loc, 0), XEXP (loc, 0))) >= 0)
7121
                  break;
7122
                else
7123
                  c++;
7124
              }
7125
            else
7126
              {
7127
                r = 1;
7128
                break;
7129
              }
7130
        }
7131
      else
7132
        for (nextp = &var->var_part[0].loc_chain; (node = *nextp);
7133
             nextp = &node->next)
7134
          if ((r = loc_cmp (node->loc, loc)) >= 0)
7135
            break;
7136
          else
7137
            c++;
7138
 
7139
      if (r == 0)
7140
        return slot;
7141
 
7142
      if (shared_var_p (var, set->vars))
7143
        {
7144
          slot = unshare_variable (set, slot, var, initialized);
7145
          var = (variable)*slot;
7146
          for (nextp = &var->var_part[0].loc_chain; c;
7147
               nextp = &(*nextp)->next)
7148
            c--;
7149
          gcc_assert ((!node && !*nextp) || node->loc == (*nextp)->loc);
7150
        }
7151
    }
7152
  else
7153
    {
7154
      int inspos = 0;
7155
 
7156
      gcc_assert (dv_as_decl (var->dv) == dv_as_decl (dv));
7157
 
7158
      pos = find_variable_location_part (var, offset, &inspos);
7159
 
7160
      if (pos >= 0)
7161
        {
7162
          node = var->var_part[pos].loc_chain;
7163
 
7164
          if (node
7165
              && ((REG_P (node->loc) && REG_P (loc)
7166
                   && REGNO (node->loc) == REGNO (loc))
7167
                  || rtx_equal_p (node->loc, loc)))
7168
            {
7169
              /* LOC is in the beginning of the chain so we have nothing
7170
                 to do.  */
7171
              if (node->init < initialized)
7172
                node->init = initialized;
7173
              if (set_src != NULL)
7174
                node->set_src = set_src;
7175
 
7176
              return slot;
7177
            }
7178
          else
7179
            {
7180
              /* We have to make a copy of a shared variable.  */
7181
              if (shared_var_p (var, set->vars))
7182
                {
7183
                  slot = unshare_variable (set, slot, var, initialized);
7184
                  var = (variable)*slot;
7185
                }
7186
            }
7187
        }
7188
      else
7189
        {
7190
          /* We have not found the location part, new one will be created.  */
7191
 
7192
          /* We have to make a copy of the shared variable.  */
7193
          if (shared_var_p (var, set->vars))
7194
            {
7195
              slot = unshare_variable (set, slot, var, initialized);
7196
              var = (variable)*slot;
7197
            }
7198
 
7199
          /* We track only variables whose size is <= MAX_VAR_PARTS bytes
7200
             thus there are at most MAX_VAR_PARTS different offsets.  */
7201
          gcc_assert (var->n_var_parts < MAX_VAR_PARTS
7202
                      && (!var->n_var_parts || !onepart));
7203
 
7204
          /* We have to move the elements of array starting at index
7205
             inspos to the next position.  */
7206
          for (pos = var->n_var_parts; pos > inspos; pos--)
7207
            var->var_part[pos] = var->var_part[pos - 1];
7208
 
7209
          var->n_var_parts++;
7210
          gcc_checking_assert (!onepart);
7211
          VAR_PART_OFFSET (var, pos) = offset;
7212
          var->var_part[pos].loc_chain = NULL;
7213
          var->var_part[pos].cur_loc = NULL;
7214
        }
7215
 
7216
      /* Delete the location from the list.  */
7217
      nextp = &var->var_part[pos].loc_chain;
7218
      for (node = var->var_part[pos].loc_chain; node; node = next)
7219
        {
7220
          next = node->next;
7221
          if ((REG_P (node->loc) && REG_P (loc)
7222
               && REGNO (node->loc) == REGNO (loc))
7223
              || rtx_equal_p (node->loc, loc))
7224
            {
7225
              /* Save these values, to assign to the new node, before
7226
                 deleting this one.  */
7227
              if (node->init > initialized)
7228
                initialized = node->init;
7229
              if (node->set_src != NULL && set_src == NULL)
7230
                set_src = node->set_src;
7231
              if (var->var_part[pos].cur_loc == node->loc)
7232
                var->var_part[pos].cur_loc = NULL;
7233
              pool_free (loc_chain_pool, node);
7234
              *nextp = next;
7235
              break;
7236
            }
7237
          else
7238
            nextp = &node->next;
7239
        }
7240
 
7241
      nextp = &var->var_part[pos].loc_chain;
7242
    }
7243
 
7244
  /* Add the location to the beginning.  */
7245
  node = (location_chain) pool_alloc (loc_chain_pool);
7246
  node->loc = loc;
7247
  node->init = initialized;
7248
  node->set_src = set_src;
7249
  node->next = *nextp;
7250
  *nextp = node;
7251
 
7252
  /* If no location was emitted do so.  */
7253
  if (var->var_part[pos].cur_loc == NULL)
7254
    variable_was_changed (var, set);
7255
 
7256
  return slot;
7257
}
7258
 
7259
/* Set the part of variable's location in the dataflow set SET.  The
7260
   variable part is specified by variable's declaration in DV and
7261
   offset OFFSET and the part's location by LOC.  IOPT should be
7262
   NO_INSERT if the variable is known to be in SET already and the
7263
   variable hash table must not be resized, and INSERT otherwise.  */
7264
 
7265
static void
7266
set_variable_part (dataflow_set *set, rtx loc,
7267
                   decl_or_value dv, HOST_WIDE_INT offset,
7268
                   enum var_init_status initialized, rtx set_src,
7269
                   enum insert_option iopt)
7270
{
7271
  void **slot;
7272
 
7273
  if (iopt == NO_INSERT)
7274
    slot = shared_hash_find_slot_noinsert (set->vars, dv);
7275
  else
7276
    {
7277
      slot = shared_hash_find_slot (set->vars, dv);
7278
      if (!slot)
7279
        slot = shared_hash_find_slot_unshare (&set->vars, dv, iopt);
7280
    }
7281
  set_slot_part (set, loc, slot, dv, offset, initialized, set_src);
7282
}
7283
 
7284
/* Remove all recorded register locations for the given variable part
7285
   from dataflow set SET, except for those that are identical to loc.
7286
   The variable part is specified by variable's declaration or value
7287
   DV and offset OFFSET.  */
7288
 
7289
static void **
7290
clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
7291
                   HOST_WIDE_INT offset, rtx set_src)
7292
{
7293
  variable var = (variable) *slot;
7294
  int pos = find_variable_location_part (var, offset, NULL);
7295
 
7296
  if (pos >= 0)
7297
    {
7298
      location_chain node, next;
7299
 
7300
      /* Remove the register locations from the dataflow set.  */
7301
      next = var->var_part[pos].loc_chain;
7302
      for (node = next; node; node = next)
7303
        {
7304
          next = node->next;
7305
          if (node->loc != loc
7306
              && (!flag_var_tracking_uninit
7307
                  || !set_src
7308
                  || MEM_P (set_src)
7309
                  || !rtx_equal_p (set_src, node->set_src)))
7310
            {
7311
              if (REG_P (node->loc))
7312
                {
7313
                  attrs anode, anext;
7314
                  attrs *anextp;
7315
 
7316
                  /* Remove the variable part from the register's
7317
                     list, but preserve any other variable parts
7318
                     that might be regarded as live in that same
7319
                     register.  */
7320
                  anextp = &set->regs[REGNO (node->loc)];
7321
                  for (anode = *anextp; anode; anode = anext)
7322
                    {
7323
                      anext = anode->next;
7324
                      if (dv_as_opaque (anode->dv) == dv_as_opaque (var->dv)
7325
                          && anode->offset == offset)
7326
                        {
7327
                          pool_free (attrs_pool, anode);
7328
                          *anextp = anext;
7329
                        }
7330
                      else
7331
                        anextp = &anode->next;
7332
                    }
7333
                }
7334
 
7335
              slot = delete_slot_part (set, node->loc, slot, offset);
7336
            }
7337
        }
7338
    }
7339
 
7340
  return slot;
7341
}
7342
 
7343
/* Remove all recorded register locations for the given variable part
7344
   from dataflow set SET, except for those that are identical to loc.
7345
   The variable part is specified by variable's declaration or value
7346
   DV and offset OFFSET.  */
7347
 
7348
static void
7349
clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7350
                       HOST_WIDE_INT offset, rtx set_src)
7351
{
7352
  void **slot;
7353
 
7354
  if (!dv_as_opaque (dv)
7355
      || (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
7356
    return;
7357
 
7358
  slot = shared_hash_find_slot_noinsert (set->vars, dv);
7359
  if (!slot)
7360
    return;
7361
 
7362
  clobber_slot_part (set, loc, slot, offset, set_src);
7363
}
7364
 
7365
/* Delete the part of variable's location from dataflow set SET.  The
7366
   variable part is specified by its SET->vars slot SLOT and offset
7367
   OFFSET and the part's location by LOC.  */
7368
 
7369
static void **
7370
delete_slot_part (dataflow_set *set, rtx loc, void **slot,
7371
                  HOST_WIDE_INT offset)
7372
{
7373
  variable var = (variable) *slot;
7374
  int pos = find_variable_location_part (var, offset, NULL);
7375
 
7376
  if (pos >= 0)
7377
    {
7378
      location_chain node, next;
7379
      location_chain *nextp;
7380
      bool changed;
7381
      rtx cur_loc;
7382
 
7383
      if (shared_var_p (var, set->vars))
7384
        {
7385
          /* If the variable contains the location part we have to
7386
             make a copy of the variable.  */
7387
          for (node = var->var_part[pos].loc_chain; node;
7388
               node = node->next)
7389
            {
7390
              if ((REG_P (node->loc) && REG_P (loc)
7391
                   && REGNO (node->loc) == REGNO (loc))
7392
                  || rtx_equal_p (node->loc, loc))
7393
                {
7394
                  slot = unshare_variable (set, slot, var,
7395
                                           VAR_INIT_STATUS_UNKNOWN);
7396
                  var = (variable)*slot;
7397
                  break;
7398
                }
7399
            }
7400
        }
7401
 
7402
      if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7403
        cur_loc = VAR_LOC_FROM (var);
7404
      else
7405
        cur_loc = var->var_part[pos].cur_loc;
7406
 
7407
      /* Delete the location part.  */
7408
      changed = false;
7409
      nextp = &var->var_part[pos].loc_chain;
7410
      for (node = *nextp; node; node = next)
7411
        {
7412
          next = node->next;
7413
          if ((REG_P (node->loc) && REG_P (loc)
7414
               && REGNO (node->loc) == REGNO (loc))
7415
              || rtx_equal_p (node->loc, loc))
7416
            {
7417
              /* If we have deleted the location which was last emitted
7418
                 we have to emit new location so add the variable to set
7419
                 of changed variables.  */
7420
              if (cur_loc == node->loc)
7421
                {
7422
                  changed = true;
7423
                  var->var_part[pos].cur_loc = NULL;
7424
                  if (pos == 0 && var->onepart && VAR_LOC_1PAUX (var))
7425
                    VAR_LOC_FROM (var) = NULL;
7426
                }
7427
              pool_free (loc_chain_pool, node);
7428
              *nextp = next;
7429
              break;
7430
            }
7431
          else
7432
            nextp = &node->next;
7433
        }
7434
 
7435
      if (var->var_part[pos].loc_chain == NULL)
7436
        {
7437
          changed = true;
7438
          var->n_var_parts--;
7439
          while (pos < var->n_var_parts)
7440
            {
7441
              var->var_part[pos] = var->var_part[pos + 1];
7442
              pos++;
7443
            }
7444
        }
7445
      if (changed)
7446
        variable_was_changed (var, set);
7447
    }
7448
 
7449
  return slot;
7450
}
7451
 
7452
/* Delete the part of variable's location from dataflow set SET.  The
7453
   variable part is specified by variable's declaration or value DV
7454
   and offset OFFSET and the part's location by LOC.  */
7455
 
7456
static void
7457
delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
7458
                      HOST_WIDE_INT offset)
7459
{
7460
  void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
7461
  if (!slot)
7462
    return;
7463
 
7464
  delete_slot_part (set, loc, slot, offset);
7465
}
7466
 
7467
DEF_VEC_P (variable);
7468
DEF_VEC_ALLOC_P (variable, heap);
7469
 
7470
DEF_VEC_ALLOC_P_STACK (rtx);
7471
#define VEC_rtx_stack_alloc(alloc) VEC_stack_alloc (rtx, alloc)
7472
 
7473
/* Structure for passing some other parameters to function
7474
   vt_expand_loc_callback.  */
7475
struct expand_loc_callback_data
7476
{
7477
  /* The variables and values active at this point.  */
7478
  htab_t vars;
7479
 
7480
  /* Stack of values and debug_exprs under expansion, and their
7481
     children.  */
7482
  VEC (rtx, stack) *expanding;
7483
 
7484
  /* Stack of values and debug_exprs whose expansion hit recursion
7485
     cycles.  They will have VALUE_RECURSED_INTO marked when added to
7486
     this list.  This flag will be cleared if any of its dependencies
7487
     resolves to a valid location.  So, if the flag remains set at the
7488
     end of the search, we know no valid location for this one can
7489
     possibly exist.  */
7490
  VEC (rtx, stack) *pending;
7491
 
7492
  /* The maximum depth among the sub-expressions under expansion.
7493
     Zero indicates no expansion so far.  */
7494
  int depth;
7495
};
7496
 
7497
/* Allocate the one-part auxiliary data structure for VAR, with enough
7498
   room for COUNT dependencies.  */
7499
 
7500
static void
7501
loc_exp_dep_alloc (variable var, int count)
7502
{
7503
  size_t allocsize;
7504
 
7505
  gcc_checking_assert (var->onepart);
7506
 
7507
  /* We can be called with COUNT == 0 to allocate the data structure
7508
     without any dependencies, e.g. for the backlinks only.  However,
7509
     if we are specifying a COUNT, then the dependency list must have
7510
     been emptied before.  It would be possible to adjust pointers or
7511
     force it empty here, but this is better done at an earlier point
7512
     in the algorithm, so we instead leave an assertion to catch
7513
     errors.  */
7514
  gcc_checking_assert (!count
7515
                       || VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)));
7516
 
7517
  if (VAR_LOC_1PAUX (var)
7518
      && VEC_space (loc_exp_dep, VAR_LOC_DEP_VEC (var), count))
7519
    return;
7520
 
7521
  allocsize = offsetof (struct onepart_aux, deps)
7522
    + VEC_embedded_size (loc_exp_dep, count);
7523
 
7524
  if (VAR_LOC_1PAUX (var))
7525
    {
7526
      VAR_LOC_1PAUX (var) = XRESIZEVAR (struct onepart_aux,
7527
                                        VAR_LOC_1PAUX (var), allocsize);
7528
      /* If the reallocation moves the onepaux structure, the
7529
         back-pointer to BACKLINKS in the first list member will still
7530
         point to its old location.  Adjust it.  */
7531
      if (VAR_LOC_DEP_LST (var))
7532
        VAR_LOC_DEP_LST (var)->pprev = VAR_LOC_DEP_LSTP (var);
7533
    }
7534
  else
7535
    {
7536
      VAR_LOC_1PAUX (var) = XNEWVAR (struct onepart_aux, allocsize);
7537
      *VAR_LOC_DEP_LSTP (var) = NULL;
7538
      VAR_LOC_FROM (var) = NULL;
7539
      VAR_LOC_DEPTH (var) = 0;
7540
    }
7541
  VEC_embedded_init (loc_exp_dep, VAR_LOC_DEP_VEC (var), count);
7542
}
7543
 
7544
/* Remove all entries from the vector of active dependencies of VAR,
7545
   removing them from the back-links lists too.  */
7546
 
7547
static void
7548
loc_exp_dep_clear (variable var)
7549
{
7550
  while (!VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)))
7551
    {
7552
      loc_exp_dep *led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7553
      if (led->next)
7554
        led->next->pprev = led->pprev;
7555
      if (led->pprev)
7556
        *led->pprev = led->next;
7557
      VEC_pop (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7558
    }
7559
}
7560
 
7561
/* Insert an active dependency from VAR on X to the vector of
7562
   dependencies, and add the corresponding back-link to X's list of
7563
   back-links in VARS.  */
7564
 
7565
static void
7566
loc_exp_insert_dep (variable var, rtx x, htab_t vars)
7567
{
7568
  decl_or_value dv;
7569
  variable xvar;
7570
  loc_exp_dep *led;
7571
 
7572
  dv = dv_from_rtx (x);
7573
 
7574
  /* ??? Build a vector of variables parallel to EXPANDING, to avoid
7575
     an additional look up?  */
7576
  xvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
7577
 
7578
  if (!xvar)
7579
    {
7580
      xvar = variable_from_dropped (dv, NO_INSERT);
7581
      gcc_checking_assert (xvar);
7582
    }
7583
 
7584
  /* No point in adding the same backlink more than once.  This may
7585
     arise if say the same value appears in two complex expressions in
7586
     the same loc_list, or even more than once in a single
7587
     expression.  */
7588
  if (VAR_LOC_DEP_LST (xvar) && VAR_LOC_DEP_LST (xvar)->dv == var->dv)
7589
    return;
7590
 
7591
  VEC_quick_push (loc_exp_dep, VAR_LOC_DEP_VEC (var), NULL);
7592
  led = VEC_last (loc_exp_dep, VAR_LOC_DEP_VEC (var));
7593
  led->dv = var->dv;
7594
  led->value = x;
7595
 
7596
  loc_exp_dep_alloc (xvar, 0);
7597
  led->pprev = VAR_LOC_DEP_LSTP (xvar);
7598
  led->next = *led->pprev;
7599
  if (led->next)
7600
    led->next->pprev = &led->next;
7601
  *led->pprev = led;
7602
}
7603
 
7604
/* Create active dependencies of VAR on COUNT values starting at
7605
   VALUE, and corresponding back-links to the entries in VARS.  Return
7606
   true if we found any pending-recursion results.  */
7607
 
7608
static bool
7609
loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
7610
{
7611
  bool pending_recursion = false;
7612
 
7613
  gcc_checking_assert (VEC_empty (loc_exp_dep, VAR_LOC_DEP_VEC (var)));
7614
 
7615
  /* Set up all dependencies from last_child (as set up at the end of
7616
     the loop above) to the end.  */
7617
  loc_exp_dep_alloc (var, count);
7618
 
7619
  while (count--)
7620
    {
7621
      rtx x = *value++;
7622
 
7623
      if (!pending_recursion)
7624
        pending_recursion = !result && VALUE_RECURSED_INTO (x);
7625
 
7626
      loc_exp_insert_dep (var, x, vars);
7627
    }
7628
 
7629
  return pending_recursion;
7630
}
7631
 
7632
/* Notify the back-links of IVAR that are pending recursion that we
7633
   have found a non-NIL value for it, so they are cleared for another
7634
   attempt to compute a current location.  */
7635
 
7636
static void
7637
notify_dependents_of_resolved_value (variable ivar, htab_t vars)
7638
{
7639
  loc_exp_dep *led, *next;
7640
 
7641
  for (led = VAR_LOC_DEP_LST (ivar); led; led = next)
7642
    {
7643
      decl_or_value dv = led->dv;
7644
      variable var;
7645
 
7646
      next = led->next;
7647
 
7648
      if (dv_is_value_p (dv))
7649
        {
7650
          rtx value = dv_as_value (dv);
7651
 
7652
          /* If we have already resolved it, leave it alone.  */
7653
          if (!VALUE_RECURSED_INTO (value))
7654
            continue;
7655
 
7656
          /* Check that VALUE_RECURSED_INTO, true from the test above,
7657
             implies NO_LOC_P.  */
7658
          gcc_checking_assert (NO_LOC_P (value));
7659
 
7660
          /* We won't notify variables that are being expanded,
7661
             because their dependency list is cleared before
7662
             recursing.  */
7663
          NO_LOC_P (value) = false;
7664
          VALUE_RECURSED_INTO (value) = false;
7665
 
7666
          gcc_checking_assert (dv_changed_p (dv));
7667
        }
7668
      else if (!dv_changed_p (dv))
7669
        continue;
7670
 
7671
      var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
7672
 
7673
      if (!var)
7674
        var = variable_from_dropped (dv, NO_INSERT);
7675
 
7676
      if (var)
7677
        notify_dependents_of_resolved_value (var, vars);
7678
 
7679
      if (next)
7680
        next->pprev = led->pprev;
7681
      if (led->pprev)
7682
        *led->pprev = next;
7683
      led->next = NULL;
7684
      led->pprev = NULL;
7685
    }
7686
}
7687
 
7688
static rtx vt_expand_loc_callback (rtx x, bitmap regs,
7689
                                   int max_depth, void *data);
7690
 
7691
/* Return the combined depth, when one sub-expression evaluated to
7692
   BEST_DEPTH and the previous known depth was SAVED_DEPTH.  */
7693
 
7694
static inline int
7695
update_depth (int saved_depth, int best_depth)
7696
{
7697
  /* If we didn't find anything, stick with what we had.  */
7698
  if (!best_depth)
7699
    return saved_depth;
7700
 
7701
  /* If we found hadn't found anything, use the depth of the current
7702
     expression.  Do NOT add one extra level, we want to compute the
7703
     maximum depth among sub-expressions.  We'll increment it later,
7704
     if appropriate.  */
7705
  if (!saved_depth)
7706
    return best_depth;
7707
 
7708
  if (saved_depth < best_depth)
7709
    return best_depth;
7710
  else
7711
    return saved_depth;
7712
}
7713
 
7714
/* Expand VAR to a location RTX, updating its cur_loc.  Use REGS and
7715
   DATA for cselib expand callback.  If PENDRECP is given, indicate in
7716
   it whether any sub-expression couldn't be fully evaluated because
7717
   it is pending recursion resolution.  */
7718
 
7719
static inline rtx
7720
vt_expand_var_loc_chain (variable var, bitmap regs, void *data, bool *pendrecp)
7721
{
7722
  struct expand_loc_callback_data *elcd
7723
    = (struct expand_loc_callback_data *) data;
7724
  location_chain loc, next;
7725
  rtx result = NULL;
7726
  int first_child, result_first_child, last_child;
7727
  bool pending_recursion;
7728
  rtx loc_from = NULL;
7729
  struct elt_loc_list *cloc = NULL;
7730
  int depth = 0, saved_depth = elcd->depth;
7731
 
7732
  /* Clear all backlinks pointing at this, so that we're not notified
7733
     while we're active.  */
7734
  loc_exp_dep_clear (var);
7735
 
7736
  if (var->onepart == ONEPART_VALUE)
7737
    {
7738
      cselib_val *val = CSELIB_VAL_PTR (dv_as_value (var->dv));
7739
 
7740
      gcc_checking_assert (cselib_preserved_value_p (val));
7741
 
7742
      cloc = val->locs;
7743
    }
7744
 
7745
  first_child = result_first_child = last_child
7746
    = VEC_length (rtx, elcd->expanding);
7747
 
7748
  /* Attempt to expand each available location in turn.  */
7749
  for (next = loc = var->n_var_parts ? var->var_part[0].loc_chain : NULL;
7750
       loc || cloc; loc = next)
7751
    {
7752
      result_first_child = last_child;
7753
 
7754
      if (!loc || (GET_CODE (loc->loc) == ENTRY_VALUE && cloc))
7755
        {
7756
          loc_from = cloc->loc;
7757
          next = loc;
7758
          cloc = cloc->next;
7759
          if (unsuitable_loc (loc_from))
7760
            continue;
7761
        }
7762
      else
7763
        {
7764
          loc_from = loc->loc;
7765
          next = loc->next;
7766
        }
7767
 
7768
      gcc_checking_assert (!unsuitable_loc (loc_from));
7769
 
7770
      elcd->depth = 0;
7771
      result = cselib_expand_value_rtx_cb (loc_from, regs, EXPR_DEPTH,
7772
                                           vt_expand_loc_callback, data);
7773
      last_child = VEC_length (rtx, elcd->expanding);
7774
 
7775
      if (result)
7776
        {
7777
          depth = elcd->depth;
7778
 
7779
          gcc_checking_assert (depth || result_first_child == last_child);
7780
 
7781
          if (last_child - result_first_child != 1)
7782
            depth++;
7783
 
7784
          if (depth <= EXPR_USE_DEPTH)
7785
            break;
7786
 
7787
          result = NULL;
7788
        }
7789
 
7790
      /* Set it up in case we leave the loop.  */
7791
      depth = 0;
7792
      loc_from = NULL;
7793
      result_first_child = first_child;
7794
    }
7795
 
7796
  /* Register all encountered dependencies as active.  */
7797
  pending_recursion = loc_exp_dep_set
7798
    (var, result, VEC_address (rtx, elcd->expanding) + result_first_child,
7799
     last_child - result_first_child, elcd->vars);
7800
 
7801
  VEC_truncate (rtx, elcd->expanding, first_child);
7802
 
7803
  /* Record where the expansion came from.  */
7804
  gcc_checking_assert (!result || !pending_recursion);
7805
  VAR_LOC_FROM (var) = loc_from;
7806
  VAR_LOC_DEPTH (var) = depth;
7807
 
7808
  gcc_checking_assert (!depth == !result);
7809
 
7810
  elcd->depth = update_depth (saved_depth, depth);
7811
 
7812
  /* Indicate whether any of the dependencies are pending recursion
7813
     resolution.  */
7814
  if (pendrecp)
7815
    *pendrecp = pending_recursion;
7816
 
7817
  if (!pendrecp || !pending_recursion)
7818
    var->var_part[0].cur_loc = result;
7819
 
7820
  return result;
7821
}
7822
 
7823
/* Callback for cselib_expand_value, that looks for expressions
7824
   holding the value in the var-tracking hash tables.  Return X for
7825
   standard processing, anything else is to be used as-is.  */
7826
 
7827
static rtx
7828
vt_expand_loc_callback (rtx x, bitmap regs,
7829
                        int max_depth ATTRIBUTE_UNUSED,
7830
                        void *data)
7831
{
7832
  struct expand_loc_callback_data *elcd
7833
    = (struct expand_loc_callback_data *) data;
7834
  decl_or_value dv;
7835
  variable var;
7836
  rtx result, subreg;
7837
  bool pending_recursion = false;
7838
  bool from_empty = false;
7839
 
7840
  switch (GET_CODE (x))
7841
    {
7842
    case SUBREG:
7843
      subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs,
7844
                                           EXPR_DEPTH,
7845
                                           vt_expand_loc_callback, data);
7846
 
7847
      if (!subreg)
7848
        return NULL;
7849
 
7850
      result = simplify_gen_subreg (GET_MODE (x), subreg,
7851
                                    GET_MODE (SUBREG_REG (x)),
7852
                                    SUBREG_BYTE (x));
7853
 
7854
      /* Invalid SUBREGs are ok in debug info.  ??? We could try
7855
         alternate expansions for the VALUE as well.  */
7856
      if (!result)
7857
        result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
7858
 
7859
      return result;
7860
 
7861
    case DEBUG_EXPR:
7862
    case VALUE:
7863
      dv = dv_from_rtx (x);
7864
      break;
7865
 
7866
    default:
7867
      return x;
7868
    }
7869
 
7870
  VEC_safe_push (rtx, stack, elcd->expanding, x);
7871
 
7872
  /* Check that VALUE_RECURSED_INTO implies NO_LOC_P.  */
7873
  gcc_checking_assert (!VALUE_RECURSED_INTO (x) || NO_LOC_P (x));
7874
 
7875
  if (NO_LOC_P (x))
7876
    {
7877
      gcc_checking_assert (VALUE_RECURSED_INTO (x) || !dv_changed_p (dv));
7878
      return NULL;
7879
    }
7880
 
7881
  var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
7882
 
7883
  if (!var)
7884
    {
7885
      from_empty = true;
7886
      var = variable_from_dropped (dv, INSERT);
7887
    }
7888
 
7889
  gcc_checking_assert (var);
7890
 
7891
  if (!dv_changed_p (dv))
7892
    {
7893
      gcc_checking_assert (!NO_LOC_P (x));
7894
      gcc_checking_assert (var->var_part[0].cur_loc);
7895
      gcc_checking_assert (VAR_LOC_1PAUX (var));
7896
      gcc_checking_assert (VAR_LOC_1PAUX (var)->depth);
7897
 
7898
      elcd->depth = update_depth (elcd->depth, VAR_LOC_1PAUX (var)->depth);
7899
 
7900
      return var->var_part[0].cur_loc;
7901
    }
7902
 
7903
  VALUE_RECURSED_INTO (x) = true;
7904
  /* This is tentative, but it makes some tests simpler.  */
7905
  NO_LOC_P (x) = true;
7906
 
7907
  gcc_checking_assert (var->n_var_parts == 1 || from_empty);
7908
 
7909
  result = vt_expand_var_loc_chain (var, regs, data, &pending_recursion);
7910
 
7911
  if (pending_recursion)
7912
    {
7913
      gcc_checking_assert (!result);
7914
      VEC_safe_push (rtx, stack, elcd->pending, x);
7915
    }
7916
  else
7917
    {
7918
      NO_LOC_P (x) = !result;
7919
      VALUE_RECURSED_INTO (x) = false;
7920
      set_dv_changed (dv, false);
7921
 
7922
      if (result)
7923
        notify_dependents_of_resolved_value (var, elcd->vars);
7924
    }
7925
 
7926
  return result;
7927
}
7928
 
7929
/* While expanding variables, we may encounter recursion cycles
7930
   because of mutual (possibly indirect) dependencies between two
7931
   particular variables (or values), say A and B.  If we're trying to
7932
   expand A when we get to B, which in turn attempts to expand A, if
7933
   we can't find any other expansion for B, we'll add B to this
7934
   pending-recursion stack, and tentatively return NULL for its
7935
   location.  This tentative value will be used for any other
7936
   occurrences of B, unless A gets some other location, in which case
7937
   it will notify B that it is worth another try at computing a
7938
   location for it, and it will use the location computed for A then.
7939
   At the end of the expansion, the tentative NULL locations become
7940
   final for all members of PENDING that didn't get a notification.
7941
   This function performs this finalization of NULL locations.  */
7942
 
7943
static void
7944
resolve_expansions_pending_recursion (VEC (rtx, stack) *pending)
7945
{
7946
  while (!VEC_empty (rtx, pending))
7947
    {
7948
      rtx x = VEC_pop (rtx, pending);
7949
      decl_or_value dv;
7950
 
7951
      if (!VALUE_RECURSED_INTO (x))
7952
        continue;
7953
 
7954
      gcc_checking_assert (NO_LOC_P (x));
7955
      VALUE_RECURSED_INTO (x) = false;
7956
      dv = dv_from_rtx (x);
7957
      gcc_checking_assert (dv_changed_p (dv));
7958
      set_dv_changed (dv, false);
7959
    }
7960
}
7961
 
7962
/* Initialize expand_loc_callback_data D with variable hash table V.
7963
   It must be a macro because of alloca (VEC stack).  */
7964
#define INIT_ELCD(d, v)                                         \
7965
  do                                                            \
7966
    {                                                           \
7967
      (d).vars = (v);                                           \
7968
      (d).expanding = VEC_alloc (rtx, stack, 4);                \
7969
      (d).pending = VEC_alloc (rtx, stack, 4);                  \
7970
      (d).depth = 0;                                             \
7971
    }                                                           \
7972
  while (0)
7973
/* Finalize expand_loc_callback_data D, resolved to location L.  */
7974
#define FINI_ELCD(d, l)                                         \
7975
  do                                                            \
7976
    {                                                           \
7977
      resolve_expansions_pending_recursion ((d).pending);       \
7978
      VEC_free (rtx, stack, (d).pending);                       \
7979
      VEC_free (rtx, stack, (d).expanding);                     \
7980
                                                                \
7981
      if ((l) && MEM_P (l))                                     \
7982
        (l) = targetm.delegitimize_address (l);                 \
7983
    }                                                           \
7984
  while (0)
7985
 
7986
/* Expand VALUEs and DEBUG_EXPRs in LOC to a location, using the
7987
   equivalences in VARS, updating their CUR_LOCs in the process.  */
7988
 
7989
static rtx
7990
vt_expand_loc (rtx loc, htab_t vars)
7991
{
7992
  struct expand_loc_callback_data data;
7993
  rtx result;
7994
 
7995
  if (!MAY_HAVE_DEBUG_INSNS)
7996
    return loc;
7997
 
7998
  INIT_ELCD (data, vars);
7999
 
8000
  result = cselib_expand_value_rtx_cb (loc, scratch_regs, EXPR_DEPTH,
8001
                                       vt_expand_loc_callback, &data);
8002
 
8003
  FINI_ELCD (data, result);
8004
 
8005
  return result;
8006
}
8007
 
8008
/* Expand the one-part VARiable to a location, using the equivalences
8009
   in VARS, updating their CUR_LOCs in the process.  */
8010
 
8011
static rtx
8012
vt_expand_1pvar (variable var, htab_t vars)
8013
{
8014
  struct expand_loc_callback_data data;
8015
  rtx loc;
8016
 
8017
  gcc_checking_assert (var->onepart && var->n_var_parts == 1);
8018
 
8019
  if (!dv_changed_p (var->dv))
8020
    return var->var_part[0].cur_loc;
8021
 
8022
  INIT_ELCD (data, vars);
8023
 
8024
  loc = vt_expand_var_loc_chain (var, scratch_regs, &data, NULL);
8025
 
8026
  gcc_checking_assert (VEC_empty (rtx, data.expanding));
8027
 
8028
  FINI_ELCD (data, loc);
8029
 
8030
  return loc;
8031
}
8032
 
8033
/* Emit the NOTE_INSN_VAR_LOCATION for variable *VARP.  DATA contains
8034
   additional parameters: WHERE specifies whether the note shall be emitted
8035
   before or after instruction INSN.  */
8036
 
8037
static int
8038
emit_note_insn_var_location (void **varp, void *data)
8039
{
8040
  variable var = (variable) *varp;
8041
  rtx insn = ((emit_note_data *)data)->insn;
8042
  enum emit_note_where where = ((emit_note_data *)data)->where;
8043
  htab_t vars = ((emit_note_data *)data)->vars;
8044
  rtx note, note_vl;
8045
  int i, j, n_var_parts;
8046
  bool complete;
8047
  enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED;
8048
  HOST_WIDE_INT last_limit;
8049
  tree type_size_unit;
8050
  HOST_WIDE_INT offsets[MAX_VAR_PARTS];
8051
  rtx loc[MAX_VAR_PARTS];
8052
  tree decl;
8053
  location_chain lc;
8054
 
8055
  gcc_checking_assert (var->onepart == NOT_ONEPART
8056
                       || var->onepart == ONEPART_VDECL);
8057
 
8058
  decl = dv_as_decl (var->dv);
8059
 
8060
  complete = true;
8061
  last_limit = 0;
8062
  n_var_parts = 0;
8063
  if (!var->onepart)
8064
    for (i = 0; i < var->n_var_parts; i++)
8065
      if (var->var_part[i].cur_loc == NULL && var->var_part[i].loc_chain)
8066
        var->var_part[i].cur_loc = var->var_part[i].loc_chain->loc;
8067
  for (i = 0; i < var->n_var_parts; i++)
8068
    {
8069
      enum machine_mode mode, wider_mode;
8070
      rtx loc2;
8071
      HOST_WIDE_INT offset;
8072
 
8073
      if (i == 0 && var->onepart)
8074
        {
8075
          gcc_checking_assert (var->n_var_parts == 1);
8076
          offset = 0;
8077
          initialized = VAR_INIT_STATUS_INITIALIZED;
8078
          loc2 = vt_expand_1pvar (var, vars);
8079
        }
8080
      else
8081
        {
8082
          if (last_limit < VAR_PART_OFFSET (var, i))
8083
            {
8084
              complete = false;
8085
              break;
8086
            }
8087
          else if (last_limit > VAR_PART_OFFSET (var, i))
8088
            continue;
8089
          offset = VAR_PART_OFFSET (var, i);
8090
          if (!var->var_part[i].cur_loc)
8091
            {
8092
              complete = false;
8093
              continue;
8094
            }
8095
          for (lc = var->var_part[i].loc_chain; lc; lc = lc->next)
8096
            if (var->var_part[i].cur_loc == lc->loc)
8097
              {
8098
                initialized = lc->init;
8099
                break;
8100
              }
8101
          gcc_assert (lc);
8102
          loc2 = var->var_part[i].cur_loc;
8103
        }
8104
 
8105
      offsets[n_var_parts] = offset;
8106
      if (!loc2)
8107
        {
8108
          complete = false;
8109
          continue;
8110
        }
8111
      loc[n_var_parts] = loc2;
8112
      mode = GET_MODE (var->var_part[i].cur_loc);
8113
      if (mode == VOIDmode && var->onepart)
8114
        mode = DECL_MODE (decl);
8115
      last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8116
 
8117
      /* Attempt to merge adjacent registers or memory.  */
8118
      wider_mode = GET_MODE_WIDER_MODE (mode);
8119
      for (j = i + 1; j < var->n_var_parts; j++)
8120
        if (last_limit <= VAR_PART_OFFSET (var, j))
8121
          break;
8122
      if (j < var->n_var_parts
8123
          && wider_mode != VOIDmode
8124
          && var->var_part[j].cur_loc
8125
          && mode == GET_MODE (var->var_part[j].cur_loc)
8126
          && (REG_P (loc[n_var_parts]) || MEM_P (loc[n_var_parts]))
8127
          && last_limit == (var->onepart ? 0 : VAR_PART_OFFSET (var, j))
8128
          && (loc2 = vt_expand_loc (var->var_part[j].cur_loc, vars))
8129
          && GET_CODE (loc[n_var_parts]) == GET_CODE (loc2))
8130
        {
8131
          rtx new_loc = NULL;
8132
 
8133
          if (REG_P (loc[n_var_parts])
8134
              && hard_regno_nregs[REGNO (loc[n_var_parts])][mode] * 2
8135
                 == hard_regno_nregs[REGNO (loc[n_var_parts])][wider_mode]
8136
              && end_hard_regno (mode, REGNO (loc[n_var_parts]))
8137
                 == REGNO (loc2))
8138
            {
8139
              if (! WORDS_BIG_ENDIAN && ! BYTES_BIG_ENDIAN)
8140
                new_loc = simplify_subreg (wider_mode, loc[n_var_parts],
8141
                                           mode, 0);
8142
              else if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
8143
                new_loc = simplify_subreg (wider_mode, loc2, mode, 0);
8144
              if (new_loc)
8145
                {
8146
                  if (!REG_P (new_loc)
8147
                      || REGNO (new_loc) != REGNO (loc[n_var_parts]))
8148
                    new_loc = NULL;
8149
                  else
8150
                    REG_ATTRS (new_loc) = REG_ATTRS (loc[n_var_parts]);
8151
                }
8152
            }
8153
          else if (MEM_P (loc[n_var_parts])
8154
                   && GET_CODE (XEXP (loc2, 0)) == PLUS
8155
                   && REG_P (XEXP (XEXP (loc2, 0), 0))
8156
                   && CONST_INT_P (XEXP (XEXP (loc2, 0), 1)))
8157
            {
8158
              if ((REG_P (XEXP (loc[n_var_parts], 0))
8159
                   && rtx_equal_p (XEXP (loc[n_var_parts], 0),
8160
                                   XEXP (XEXP (loc2, 0), 0))
8161
                   && INTVAL (XEXP (XEXP (loc2, 0), 1))
8162
                      == GET_MODE_SIZE (mode))
8163
                  || (GET_CODE (XEXP (loc[n_var_parts], 0)) == PLUS
8164
                      && CONST_INT_P (XEXP (XEXP (loc[n_var_parts], 0), 1))
8165
                      && rtx_equal_p (XEXP (XEXP (loc[n_var_parts], 0), 0),
8166
                                      XEXP (XEXP (loc2, 0), 0))
8167
                      && INTVAL (XEXP (XEXP (loc[n_var_parts], 0), 1))
8168
                         + GET_MODE_SIZE (mode)
8169
                         == INTVAL (XEXP (XEXP (loc2, 0), 1))))
8170
                new_loc = adjust_address_nv (loc[n_var_parts],
8171
                                             wider_mode, 0);
8172
            }
8173
 
8174
          if (new_loc)
8175
            {
8176
              loc[n_var_parts] = new_loc;
8177
              mode = wider_mode;
8178
              last_limit = offsets[n_var_parts] + GET_MODE_SIZE (mode);
8179
              i = j;
8180
            }
8181
        }
8182
      ++n_var_parts;
8183
    }
8184
  type_size_unit = TYPE_SIZE_UNIT (TREE_TYPE (decl));
8185
  if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
8186
    complete = false;
8187
 
8188
  if (! flag_var_tracking_uninit)
8189
    initialized = VAR_INIT_STATUS_INITIALIZED;
8190
 
8191
  note_vl = NULL_RTX;
8192
  if (!complete)
8193
    note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, NULL_RTX,
8194
                                    (int) initialized);
8195
  else if (n_var_parts == 1)
8196
    {
8197
      rtx expr_list;
8198
 
8199
      if (offsets[0] || GET_CODE (loc[0]) == PARALLEL)
8200
        expr_list = gen_rtx_EXPR_LIST (VOIDmode, loc[0], GEN_INT (offsets[0]));
8201
      else
8202
        expr_list = loc[0];
8203
 
8204
      note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl, expr_list,
8205
                                      (int) initialized);
8206
    }
8207
  else if (n_var_parts)
8208
    {
8209
      rtx parallel;
8210
 
8211
      for (i = 0; i < n_var_parts; i++)
8212
        loc[i]
8213
          = gen_rtx_EXPR_LIST (VOIDmode, loc[i], GEN_INT (offsets[i]));
8214
 
8215
      parallel = gen_rtx_PARALLEL (VOIDmode,
8216
                                   gen_rtvec_v (n_var_parts, loc));
8217
      note_vl = gen_rtx_VAR_LOCATION (VOIDmode, decl,
8218
                                      parallel, (int) initialized);
8219
    }
8220
 
8221
  if (where != EMIT_NOTE_BEFORE_INSN)
8222
    {
8223
      note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8224
      if (where == EMIT_NOTE_AFTER_CALL_INSN)
8225
        NOTE_DURING_CALL_P (note) = true;
8226
    }
8227
  else
8228
    {
8229
      /* Make sure that the call related notes come first.  */
8230
      while (NEXT_INSN (insn)
8231
             && NOTE_P (insn)
8232
             && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8233
                  && NOTE_DURING_CALL_P (insn))
8234
                 || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8235
        insn = NEXT_INSN (insn);
8236
      if (NOTE_P (insn)
8237
          && ((NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
8238
               && NOTE_DURING_CALL_P (insn))
8239
              || NOTE_KIND (insn) == NOTE_INSN_CALL_ARG_LOCATION))
8240
        note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
8241
      else
8242
        note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
8243
    }
8244
  NOTE_VAR_LOCATION (note) = note_vl;
8245
 
8246
  set_dv_changed (var->dv, false);
8247
  gcc_assert (var->in_changed_variables);
8248
  var->in_changed_variables = false;
8249
  htab_clear_slot (changed_variables, varp);
8250
 
8251
  /* Continue traversing the hash table.  */
8252
  return 1;
8253
}
8254
 
8255
/* While traversing changed_variables, push onto DATA (a stack of RTX
8256
   values) entries that aren't user variables.  */
8257
 
8258
static int
8259
values_to_stack (void **slot, void *data)
8260
{
8261
  VEC (rtx, stack) **changed_values_stack = (VEC (rtx, stack) **)data;
8262
  variable var = (variable) *slot;
8263
 
8264
  if (var->onepart == ONEPART_VALUE)
8265
    VEC_safe_push (rtx, stack, *changed_values_stack, dv_as_value (var->dv));
8266
  else if (var->onepart == ONEPART_DEXPR)
8267
    VEC_safe_push (rtx, stack, *changed_values_stack,
8268
                   DECL_RTL_KNOWN_SET (dv_as_decl (var->dv)));
8269
 
8270
  return 1;
8271
}
8272
 
8273
/* Remove from changed_variables the entry whose DV corresponds to
8274
   value or debug_expr VAL.  */
8275
static void
8276
remove_value_from_changed_variables (rtx val)
8277
{
8278
  decl_or_value dv = dv_from_rtx (val);
8279
  void **slot;
8280
  variable var;
8281
 
8282
  slot = htab_find_slot_with_hash (changed_variables,
8283
                                   dv, dv_htab_hash (dv), NO_INSERT);
8284
  var = (variable) *slot;
8285
  var->in_changed_variables = false;
8286
  htab_clear_slot (changed_variables, slot);
8287
}
8288
 
8289
/* If VAL (a value or debug_expr) has backlinks to variables actively
8290
   dependent on it in HTAB or in CHANGED_VARIABLES, mark them as
8291
   changed, adding to CHANGED_VALUES_STACK any dependencies that may
8292
   have dependencies of their own to notify.  */
8293
 
8294
static void
8295
notify_dependents_of_changed_value (rtx val, htab_t htab,
8296
                                    VEC (rtx, stack) **changed_values_stack)
8297
{
8298
  void **slot;
8299
  variable var;
8300
  loc_exp_dep *led;
8301
  decl_or_value dv = dv_from_rtx (val);
8302
 
8303
  slot = htab_find_slot_with_hash (changed_variables,
8304
                                   dv, dv_htab_hash (dv), NO_INSERT);
8305
  if (!slot)
8306
    slot = htab_find_slot_with_hash (htab,
8307
                                     dv, dv_htab_hash (dv), NO_INSERT);
8308
  if (!slot)
8309
    slot = htab_find_slot_with_hash (dropped_values,
8310
                                     dv, dv_htab_hash (dv), NO_INSERT);
8311
  var = (variable) *slot;
8312
 
8313
  while ((led = VAR_LOC_DEP_LST (var)))
8314
    {
8315
      decl_or_value ldv = led->dv;
8316
      void **islot;
8317
      variable ivar;
8318
 
8319
      /* Deactivate and remove the backlink, as it was “used up”.  It
8320
         makes no sense to attempt to notify the same entity again:
8321
         either it will be recomputed and re-register an active
8322
         dependency, or it will still have the changed mark.  */
8323
      if (led->next)
8324
        led->next->pprev = led->pprev;
8325
      if (led->pprev)
8326
        *led->pprev = led->next;
8327
      led->next = NULL;
8328
      led->pprev = NULL;
8329
 
8330
      if (dv_changed_p (ldv))
8331
        continue;
8332
 
8333
      switch (dv_onepart_p (ldv))
8334
        {
8335
        case ONEPART_VALUE:
8336
        case ONEPART_DEXPR:
8337
          set_dv_changed (ldv, true);
8338
          VEC_safe_push (rtx, stack, *changed_values_stack, dv_as_rtx (ldv));
8339
          break;
8340
 
8341
        default:
8342
          islot = htab_find_slot_with_hash (htab, ldv, dv_htab_hash (ldv),
8343
                                            NO_INSERT);
8344
          ivar = (variable) *islot;
8345
          gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
8346
          variable_was_changed (ivar, NULL);
8347
          break;
8348
        }
8349
    }
8350
}
8351
 
8352
/* Take out of changed_variables any entries that don't refer to use
8353
   variables.  Back-propagate change notifications from values and
8354
   debug_exprs to their active dependencies in HTAB or in
8355
   CHANGED_VARIABLES.  */
8356
 
8357
static void
8358
process_changed_values (htab_t htab)
8359
{
8360
  int i, n;
8361
  rtx val;
8362
  VEC (rtx, stack) *changed_values_stack = VEC_alloc (rtx, stack, 20);
8363
 
8364
  /* Move values from changed_variables to changed_values_stack.  */
8365
  htab_traverse (changed_variables, values_to_stack, &changed_values_stack);
8366
 
8367
  /* Back-propagate change notifications in values while popping
8368
     them from the stack.  */
8369
  for (n = i = VEC_length (rtx, changed_values_stack);
8370
       i > 0; i = VEC_length (rtx, changed_values_stack))
8371
    {
8372
      val = VEC_pop (rtx, changed_values_stack);
8373
      notify_dependents_of_changed_value (val, htab, &changed_values_stack);
8374
 
8375
      /* This condition will hold when visiting each of the entries
8376
         originally in changed_variables.  We can't remove them
8377
         earlier because this could drop the backlinks before we got a
8378
         chance to use them.  */
8379
      if (i == n)
8380
        {
8381
          remove_value_from_changed_variables (val);
8382
          n--;
8383
        }
8384
    }
8385
 
8386
  VEC_free (rtx, stack, changed_values_stack);
8387
}
8388
 
8389
/* Emit NOTE_INSN_VAR_LOCATION note for each variable from a chain
8390
   CHANGED_VARIABLES and delete this chain.  WHERE specifies whether
8391
   the notes shall be emitted before of after instruction INSN.  */
8392
 
8393
static void
8394
emit_notes_for_changes (rtx insn, enum emit_note_where where,
8395
                        shared_hash vars)
8396
{
8397
  emit_note_data data;
8398
  htab_t htab = shared_hash_htab (vars);
8399
 
8400
  if (!htab_elements (changed_variables))
8401
    return;
8402
 
8403
  if (MAY_HAVE_DEBUG_INSNS)
8404
    process_changed_values (htab);
8405
 
8406
  data.insn = insn;
8407
  data.where = where;
8408
  data.vars = htab;
8409
 
8410
  htab_traverse (changed_variables, emit_note_insn_var_location, &data);
8411
}
8412
 
8413
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
8414
   same variable in hash table DATA or is not there at all.  */
8415
 
8416
static int
8417
emit_notes_for_differences_1 (void **slot, void *data)
8418
{
8419
  htab_t new_vars = (htab_t) data;
8420
  variable old_var, new_var;
8421
 
8422
  old_var = (variable) *slot;
8423
  new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
8424
                                            dv_htab_hash (old_var->dv));
8425
 
8426
  if (!new_var)
8427
    {
8428
      /* Variable has disappeared.  */
8429
      variable empty_var = NULL;
8430
 
8431
      if (old_var->onepart == ONEPART_VALUE
8432
          || old_var->onepart == ONEPART_DEXPR)
8433
        {
8434
          empty_var = variable_from_dropped (old_var->dv, NO_INSERT);
8435
          if (empty_var)
8436
            {
8437
              gcc_checking_assert (!empty_var->in_changed_variables);
8438
              if (!VAR_LOC_1PAUX (old_var))
8439
                {
8440
                  VAR_LOC_1PAUX (old_var) = VAR_LOC_1PAUX (empty_var);
8441
                  VAR_LOC_1PAUX (empty_var) = NULL;
8442
                }
8443
              else
8444
                gcc_checking_assert (!VAR_LOC_1PAUX (empty_var));
8445
            }
8446
        }
8447
 
8448
      if (!empty_var)
8449
        {
8450
          empty_var = (variable) pool_alloc (onepart_pool (old_var->onepart));
8451
          empty_var->dv = old_var->dv;
8452
          empty_var->refcount = 0;
8453
          empty_var->n_var_parts = 0;
8454
          empty_var->onepart = old_var->onepart;
8455
          empty_var->in_changed_variables = false;
8456
        }
8457
 
8458
      if (empty_var->onepart)
8459
        {
8460
          /* Propagate the auxiliary data to (ultimately)
8461
             changed_variables.  */
8462
          empty_var->var_part[0].loc_chain = NULL;
8463
          empty_var->var_part[0].cur_loc = NULL;
8464
          VAR_LOC_1PAUX (empty_var) = VAR_LOC_1PAUX (old_var);
8465
          VAR_LOC_1PAUX (old_var) = NULL;
8466
        }
8467
      variable_was_changed (empty_var, NULL);
8468
      /* Continue traversing the hash table.  */
8469
      return 1;
8470
    }
8471
  /* Update cur_loc and one-part auxiliary data, before new_var goes
8472
     through variable_was_changed.  */
8473
  if (old_var != new_var && new_var->onepart)
8474
    {
8475
      gcc_checking_assert (VAR_LOC_1PAUX (new_var) == NULL);
8476
      VAR_LOC_1PAUX (new_var) = VAR_LOC_1PAUX (old_var);
8477
      VAR_LOC_1PAUX (old_var) = NULL;
8478
      new_var->var_part[0].cur_loc = old_var->var_part[0].cur_loc;
8479
    }
8480
  if (variable_different_p (old_var, new_var))
8481
    variable_was_changed (new_var, NULL);
8482
 
8483
  /* Continue traversing the hash table.  */
8484
  return 1;
8485
}
8486
 
8487
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
8488
   table DATA.  */
8489
 
8490
static int
8491
emit_notes_for_differences_2 (void **slot, void *data)
8492
{
8493
  htab_t old_vars = (htab_t) data;
8494
  variable old_var, new_var;
8495
 
8496
  new_var = (variable) *slot;
8497
  old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
8498
                                            dv_htab_hash (new_var->dv));
8499
  if (!old_var)
8500
    {
8501
      int i;
8502
      for (i = 0; i < new_var->n_var_parts; i++)
8503
        new_var->var_part[i].cur_loc = NULL;
8504
      variable_was_changed (new_var, NULL);
8505
    }
8506
 
8507
  /* Continue traversing the hash table.  */
8508
  return 1;
8509
}
8510
 
8511
/* Emit notes before INSN for differences between dataflow sets OLD_SET and
8512
   NEW_SET.  */
8513
 
8514
static void
8515
emit_notes_for_differences (rtx insn, dataflow_set *old_set,
8516
                            dataflow_set *new_set)
8517
{
8518
  htab_traverse (shared_hash_htab (old_set->vars),
8519
                 emit_notes_for_differences_1,
8520
                 shared_hash_htab (new_set->vars));
8521
  htab_traverse (shared_hash_htab (new_set->vars),
8522
                 emit_notes_for_differences_2,
8523
                 shared_hash_htab (old_set->vars));
8524
  emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
8525
}
8526
 
8527
/* Return the next insn after INSN that is not a NOTE_INSN_VAR_LOCATION.  */
8528
 
8529
static rtx
8530
next_non_note_insn_var_location (rtx insn)
8531
{
8532
  while (insn)
8533
    {
8534
      insn = NEXT_INSN (insn);
8535
      if (insn == 0
8536
          || !NOTE_P (insn)
8537
          || NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION)
8538
        break;
8539
    }
8540
 
8541
  return insn;
8542
}
8543
 
8544
/* Emit the notes for changes of location parts in the basic block BB.  */
8545
 
8546
static void
8547
emit_notes_in_bb (basic_block bb, dataflow_set *set)
8548
{
8549
  unsigned int i;
8550
  micro_operation *mo;
8551
 
8552
  dataflow_set_clear (set);
8553
  dataflow_set_copy (set, &VTI (bb)->in);
8554
 
8555
  FOR_EACH_VEC_ELT (micro_operation, VTI (bb)->mos, i, mo)
8556
    {
8557
      rtx insn = mo->insn;
8558
      rtx next_insn = next_non_note_insn_var_location (insn);
8559
 
8560
      switch (mo->type)
8561
        {
8562
          case MO_CALL:
8563
            dataflow_set_clear_at_call (set);
8564
            emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars);
8565
            {
8566
              rtx arguments = mo->u.loc, *p = &arguments, note;
8567
              while (*p)
8568
                {
8569
                  XEXP (XEXP (*p, 0), 1)
8570
                    = vt_expand_loc (XEXP (XEXP (*p, 0), 1),
8571
                                     shared_hash_htab (set->vars));
8572
                  /* If expansion is successful, keep it in the list.  */
8573
                  if (XEXP (XEXP (*p, 0), 1))
8574
                    p = &XEXP (*p, 1);
8575
                  /* Otherwise, if the following item is data_value for it,
8576
                     drop it too too.  */
8577
                  else if (XEXP (*p, 1)
8578
                           && REG_P (XEXP (XEXP (*p, 0), 0))
8579
                           && MEM_P (XEXP (XEXP (XEXP (*p, 1), 0), 0))
8580
                           && REG_P (XEXP (XEXP (XEXP (XEXP (*p, 1), 0), 0),
8581
                                           0))
8582
                           && REGNO (XEXP (XEXP (*p, 0), 0))
8583
                              == REGNO (XEXP (XEXP (XEXP (XEXP (*p, 1), 0),
8584
                                                    0), 0)))
8585
                    *p = XEXP (XEXP (*p, 1), 1);
8586
                  /* Just drop this item.  */
8587
                  else
8588
                    *p = XEXP (*p, 1);
8589
                }
8590
              note = emit_note_after (NOTE_INSN_CALL_ARG_LOCATION, insn);
8591
              NOTE_VAR_LOCATION (note) = arguments;
8592
            }
8593
            break;
8594
 
8595
          case MO_USE:
8596
            {
8597
              rtx loc = mo->u.loc;
8598
 
8599
              if (REG_P (loc))
8600
                var_reg_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8601
              else
8602
                var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
8603
 
8604
              emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8605
            }
8606
            break;
8607
 
8608
          case MO_VAL_LOC:
8609
            {
8610
              rtx loc = mo->u.loc;
8611
              rtx val, vloc;
8612
              tree var;
8613
 
8614
              if (GET_CODE (loc) == CONCAT)
8615
                {
8616
                  val = XEXP (loc, 0);
8617
                  vloc = XEXP (loc, 1);
8618
                }
8619
              else
8620
                {
8621
                  val = NULL_RTX;
8622
                  vloc = loc;
8623
                }
8624
 
8625
              var = PAT_VAR_LOCATION_DECL (vloc);
8626
 
8627
              clobber_variable_part (set, NULL_RTX,
8628
                                     dv_from_decl (var), 0, NULL_RTX);
8629
              if (val)
8630
                {
8631
                  if (VAL_NEEDS_RESOLUTION (loc))
8632
                    val_resolve (set, val, PAT_VAR_LOCATION_LOC (vloc), insn);
8633
                  set_variable_part (set, val, dv_from_decl (var), 0,
8634
                                     VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8635
                                     INSERT);
8636
                }
8637
              else if (!VAR_LOC_UNKNOWN_P (PAT_VAR_LOCATION_LOC (vloc)))
8638
                set_variable_part (set, PAT_VAR_LOCATION_LOC (vloc),
8639
                                   dv_from_decl (var), 0,
8640
                                   VAR_INIT_STATUS_INITIALIZED, NULL_RTX,
8641
                                   INSERT);
8642
 
8643
              emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8644
            }
8645
            break;
8646
 
8647
          case MO_VAL_USE:
8648
            {
8649
              rtx loc = mo->u.loc;
8650
              rtx val, vloc, uloc;
8651
 
8652
              vloc = uloc = XEXP (loc, 1);
8653
              val = XEXP (loc, 0);
8654
 
8655
              if (GET_CODE (val) == CONCAT)
8656
                {
8657
                  uloc = XEXP (val, 1);
8658
                  val = XEXP (val, 0);
8659
                }
8660
 
8661
              if (VAL_NEEDS_RESOLUTION (loc))
8662
                val_resolve (set, val, vloc, insn);
8663
              else
8664
                val_store (set, val, uloc, insn, false);
8665
 
8666
              if (VAL_HOLDS_TRACK_EXPR (loc))
8667
                {
8668
                  if (GET_CODE (uloc) == REG)
8669
                    var_reg_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
8670
                                 NULL);
8671
                  else if (GET_CODE (uloc) == MEM)
8672
                    var_mem_set (set, uloc, VAR_INIT_STATUS_UNINITIALIZED,
8673
                                 NULL);
8674
                }
8675
 
8676
              emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
8677
            }
8678
            break;
8679
 
8680
          case MO_VAL_SET:
8681
            {
8682
              rtx loc = mo->u.loc;
8683
              rtx val, vloc, uloc;
8684
 
8685
              vloc = loc;
8686
              uloc = XEXP (vloc, 1);
8687
              val = XEXP (vloc, 0);
8688
              vloc = uloc;
8689
 
8690
              if (GET_CODE (val) == CONCAT)
8691
                {
8692
                  vloc = XEXP (val, 1);
8693
                  val = XEXP (val, 0);
8694
                }
8695
 
8696
              if (GET_CODE (vloc) == SET)
8697
                {
8698
                  rtx vsrc = SET_SRC (vloc);
8699
 
8700
                  gcc_assert (val != vsrc);
8701
                  gcc_assert (vloc == uloc || VAL_NEEDS_RESOLUTION (loc));
8702
 
8703
                  vloc = SET_DEST (vloc);
8704
 
8705
                  if (VAL_NEEDS_RESOLUTION (loc))
8706
                    val_resolve (set, val, vsrc, insn);
8707
                }
8708
              else if (VAL_NEEDS_RESOLUTION (loc))
8709
                {
8710
                  gcc_assert (GET_CODE (uloc) == SET
8711
                              && GET_CODE (SET_SRC (uloc)) == REG);
8712
                  val_resolve (set, val, SET_SRC (uloc), insn);
8713
                }
8714
 
8715
              if (VAL_HOLDS_TRACK_EXPR (loc))
8716
                {
8717
                  if (VAL_EXPR_IS_CLOBBERED (loc))
8718
                    {
8719
                      if (REG_P (uloc))
8720
                        var_reg_delete (set, uloc, true);
8721
                      else if (MEM_P (uloc))
8722
                        var_mem_delete (set, uloc, true);
8723
                    }
8724
                  else
8725
                    {
8726
                      bool copied_p = VAL_EXPR_IS_COPIED (loc);
8727
                      rtx set_src = NULL;
8728
                      enum var_init_status status = VAR_INIT_STATUS_INITIALIZED;
8729
 
8730
                      if (GET_CODE (uloc) == SET)
8731
                        {
8732
                          set_src = SET_SRC (uloc);
8733
                          uloc = SET_DEST (uloc);
8734
                        }
8735
 
8736
                      if (copied_p)
8737
                        {
8738
                          status = find_src_status (set, set_src);
8739
 
8740
                          set_src = find_src_set_src (set, set_src);
8741
                        }
8742
 
8743
                      if (REG_P (uloc))
8744
                        var_reg_delete_and_set (set, uloc, !copied_p,
8745
                                                status, set_src);
8746
                      else if (MEM_P (uloc))
8747
                        var_mem_delete_and_set (set, uloc, !copied_p,
8748
                                                status, set_src);
8749
                    }
8750
                }
8751
              else if (REG_P (uloc))
8752
                var_regno_delete (set, REGNO (uloc));
8753
 
8754
              val_store (set, val, vloc, insn, true);
8755
 
8756
              emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
8757
                                      set->vars);
8758
            }
8759
            break;
8760
 
8761
          case MO_SET:
8762
            {
8763
              rtx loc = mo->u.loc;
8764
              rtx set_src = NULL;
8765
 
8766
              if (GET_CODE (loc) == SET)
8767
                {
8768
                  set_src = SET_SRC (loc);
8769
                  loc = SET_DEST (loc);
8770
                }
8771
 
8772
              if (REG_P (loc))
8773
                var_reg_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
8774
                                        set_src);
8775
              else
8776
                var_mem_delete_and_set (set, loc, true, VAR_INIT_STATUS_INITIALIZED,
8777
                                        set_src);
8778
 
8779
              emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
8780
                                      set->vars);
8781
            }
8782
            break;
8783
 
8784
          case MO_COPY:
8785
            {
8786
              rtx loc = mo->u.loc;
8787
              enum var_init_status src_status;
8788
              rtx set_src = NULL;
8789
 
8790
              if (GET_CODE (loc) == SET)
8791
                {
8792
                  set_src = SET_SRC (loc);
8793
                  loc = SET_DEST (loc);
8794
                }
8795
 
8796
              src_status = find_src_status (set, set_src);
8797
              set_src = find_src_set_src (set, set_src);
8798
 
8799
              if (REG_P (loc))
8800
                var_reg_delete_and_set (set, loc, false, src_status, set_src);
8801
              else
8802
                var_mem_delete_and_set (set, loc, false, src_status, set_src);
8803
 
8804
              emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
8805
                                      set->vars);
8806
            }
8807
            break;
8808
 
8809
          case MO_USE_NO_VAR:
8810
            {
8811
              rtx loc = mo->u.loc;
8812
 
8813
              if (REG_P (loc))
8814
                var_reg_delete (set, loc, false);
8815
              else
8816
                var_mem_delete (set, loc, false);
8817
 
8818
              emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
8819
            }
8820
            break;
8821
 
8822
          case MO_CLOBBER:
8823
            {
8824
              rtx loc = mo->u.loc;
8825
 
8826
              if (REG_P (loc))
8827
                var_reg_delete (set, loc, true);
8828
              else
8829
                var_mem_delete (set, loc, true);
8830
 
8831
              emit_notes_for_changes (next_insn, EMIT_NOTE_BEFORE_INSN,
8832
                                      set->vars);
8833
            }
8834
            break;
8835
 
8836
          case MO_ADJUST:
8837
            set->stack_adjust += mo->u.adjust;
8838
            break;
8839
        }
8840
    }
8841
}
8842
 
8843
/* Emit notes for the whole function.  */
8844
 
8845
static void
8846
vt_emit_notes (void)
8847
{
8848
  basic_block bb;
8849
  dataflow_set cur;
8850
 
8851
  gcc_assert (!htab_elements (changed_variables));
8852
 
8853
  /* Free memory occupied by the out hash tables, as they aren't used
8854
     anymore.  */
8855
  FOR_EACH_BB (bb)
8856
    dataflow_set_clear (&VTI (bb)->out);
8857
 
8858
  /* Enable emitting notes by functions (mainly by set_variable_part and
8859
     delete_variable_part).  */
8860
  emit_notes = true;
8861
 
8862
  if (MAY_HAVE_DEBUG_INSNS)
8863
    dropped_values = htab_create (cselib_get_next_uid () * 2,
8864
                                  variable_htab_hash, variable_htab_eq,
8865
                                  variable_htab_free);
8866
 
8867
  dataflow_set_init (&cur);
8868
 
8869
  FOR_EACH_BB (bb)
8870
    {
8871
      /* Emit the notes for changes of variable locations between two
8872
         subsequent basic blocks.  */
8873
      emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
8874
 
8875
      /* Emit the notes for the changes in the basic block itself.  */
8876
      emit_notes_in_bb (bb, &cur);
8877
 
8878
      /* Free memory occupied by the in hash table, we won't need it
8879
         again.  */
8880
      dataflow_set_clear (&VTI (bb)->in);
8881
    }
8882
#ifdef ENABLE_CHECKING
8883
  htab_traverse (shared_hash_htab (cur.vars),
8884
                 emit_notes_for_differences_1,
8885
                 shared_hash_htab (empty_shared_hash));
8886
#endif
8887
  dataflow_set_destroy (&cur);
8888
 
8889
  if (MAY_HAVE_DEBUG_INSNS)
8890
    htab_delete (dropped_values);
8891
 
8892
  emit_notes = false;
8893
}
8894
 
8895
/* If there is a declaration and offset associated with register/memory RTL
8896
   assign declaration to *DECLP and offset to *OFFSETP, and return true.  */
8897
 
8898
static bool
8899
vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
8900
{
8901
  if (REG_P (rtl))
8902
    {
8903
      if (REG_ATTRS (rtl))
8904
        {
8905
          *declp = REG_EXPR (rtl);
8906
          *offsetp = REG_OFFSET (rtl);
8907
          return true;
8908
        }
8909
    }
8910
  else if (MEM_P (rtl))
8911
    {
8912
      if (MEM_ATTRS (rtl))
8913
        {
8914
          *declp = MEM_EXPR (rtl);
8915
          *offsetp = INT_MEM_OFFSET (rtl);
8916
          return true;
8917
        }
8918
    }
8919
  return false;
8920
}
8921
 
8922
/* Record the value for the ENTRY_VALUE of RTL as a global equivalence
8923
   of VAL.  */
8924
 
8925
static void
8926
record_entry_value (cselib_val *val, rtx rtl)
8927
{
8928
  rtx ev = gen_rtx_ENTRY_VALUE (GET_MODE (rtl));
8929
 
8930
  ENTRY_VALUE_EXP (ev) = rtl;
8931
 
8932
  cselib_add_permanent_equiv (val, ev, get_insns ());
8933
}
8934
 
8935
/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK.  */
8936
 
8937
static void
8938
vt_add_function_parameter (tree parm)
8939
{
8940
  rtx decl_rtl = DECL_RTL_IF_SET (parm);
8941
  rtx incoming = DECL_INCOMING_RTL (parm);
8942
  tree decl;
8943
  enum machine_mode mode;
8944
  HOST_WIDE_INT offset;
8945
  dataflow_set *out;
8946
  decl_or_value dv;
8947
 
8948
  if (TREE_CODE (parm) != PARM_DECL)
8949
    return;
8950
 
8951
  if (!decl_rtl || !incoming)
8952
    return;
8953
 
8954
  if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
8955
    return;
8956
 
8957
  /* If there is a DRAP register, rewrite the incoming location of parameters
8958
     passed on the stack into MEMs based on the argument pointer, as the DRAP
8959
     register can be reused for other purposes and we do not track locations
8960
     based on generic registers.  But the prerequisite is that this argument
8961
     pointer be also the virtual CFA pointer, see vt_initialize.  */
8962
  if (MEM_P (incoming)
8963
      && stack_realign_drap
8964
      && arg_pointer_rtx == cfa_base_rtx
8965
      && (XEXP (incoming, 0) == crtl->args.internal_arg_pointer
8966
          || (GET_CODE (XEXP (incoming, 0)) == PLUS
8967
              && XEXP (XEXP (incoming, 0), 0)
8968
                 == crtl->args.internal_arg_pointer
8969
              && CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
8970
    {
8971
      HOST_WIDE_INT off = -FIRST_PARM_OFFSET (current_function_decl);
8972
      if (GET_CODE (XEXP (incoming, 0)) == PLUS)
8973
        off += INTVAL (XEXP (XEXP (incoming, 0), 1));
8974
      incoming
8975
        = replace_equiv_address_nv (incoming,
8976
                                    plus_constant (arg_pointer_rtx, off));
8977
    }
8978
 
8979
#ifdef HAVE_window_save
8980
  /* DECL_INCOMING_RTL uses the INCOMING_REGNO of parameter registers.
8981
     If the target machine has an explicit window save instruction, the
8982
     actual entry value is the corresponding OUTGOING_REGNO instead.  */
8983
  if (REG_P (incoming)
8984
      && HARD_REGISTER_P (incoming)
8985
      && OUTGOING_REGNO (REGNO (incoming)) != REGNO (incoming))
8986
    {
8987
      parm_reg_t *p
8988
        = VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, NULL);
8989
      p->incoming = incoming;
8990
      incoming
8991
        = gen_rtx_REG_offset (incoming, GET_MODE (incoming),
8992
                              OUTGOING_REGNO (REGNO (incoming)), 0);
8993
      p->outgoing = incoming;
8994
    }
8995
  else if (MEM_P (incoming)
8996
           && REG_P (XEXP (incoming, 0))
8997
           && HARD_REGISTER_P (XEXP (incoming, 0)))
8998
    {
8999
      rtx reg = XEXP (incoming, 0);
9000
      if (OUTGOING_REGNO (REGNO (reg)) != REGNO (reg))
9001
        {
9002
          parm_reg_t *p
9003
            = VEC_safe_push (parm_reg_t, gc, windowed_parm_regs, NULL);
9004
          p->incoming = reg;
9005
          reg = gen_raw_REG (GET_MODE (reg), OUTGOING_REGNO (REGNO (reg)));
9006
          p->outgoing = reg;
9007
          incoming = replace_equiv_address_nv (incoming, reg);
9008
        }
9009
    }
9010
#endif
9011
 
9012
  if (!vt_get_decl_and_offset (incoming, &decl, &offset))
9013
    {
9014
      if (REG_P (incoming) || MEM_P (incoming))
9015
        {
9016
          /* This means argument is passed by invisible reference.  */
9017
          offset = 0;
9018
          decl = parm;
9019
          incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
9020
        }
9021
      else
9022
        {
9023
          if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
9024
            return;
9025
          offset += byte_lowpart_offset (GET_MODE (incoming),
9026
                                         GET_MODE (decl_rtl));
9027
        }
9028
    }
9029
 
9030
  if (!decl)
9031
    return;
9032
 
9033
  if (parm != decl)
9034
    {
9035
      /* Assume that DECL_RTL was a pseudo that got spilled to
9036
         memory.  The spill slot sharing code will force the
9037
         memory to reference spill_slot_decl (%sfp), so we don't
9038
         match above.  That's ok, the pseudo must have referenced
9039
         the entire parameter, so just reset OFFSET.  */
9040
      gcc_assert (decl == get_spill_slot_decl (false));
9041
      offset = 0;
9042
    }
9043
 
9044
  if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
9045
    return;
9046
 
9047
  out = &VTI (ENTRY_BLOCK_PTR)->out;
9048
 
9049
  dv = dv_from_decl (parm);
9050
 
9051
  if (target_for_debug_bind (parm)
9052
      /* We can't deal with these right now, because this kind of
9053
         variable is single-part.  ??? We could handle parallels
9054
         that describe multiple locations for the same single
9055
         value, but ATM we don't.  */
9056
      && GET_CODE (incoming) != PARALLEL)
9057
    {
9058
      cselib_val *val;
9059
 
9060
      /* ??? We shouldn't ever hit this, but it may happen because
9061
         arguments passed by invisible reference aren't dealt with
9062
         above: incoming-rtl will have Pmode rather than the
9063
         expected mode for the type.  */
9064
      if (offset)
9065
        return;
9066
 
9067
      val = cselib_lookup_from_insn (var_lowpart (mode, incoming), mode, true,
9068
                                     VOIDmode, get_insns ());
9069
 
9070
      /* ??? Float-typed values in memory are not handled by
9071
         cselib.  */
9072
      if (val)
9073
        {
9074
          preserve_value (val);
9075
          set_variable_part (out, val->val_rtx, dv, offset,
9076
                             VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9077
          dv = dv_from_value (val->val_rtx);
9078
        }
9079
    }
9080
 
9081
  if (REG_P (incoming))
9082
    {
9083
      incoming = var_lowpart (mode, incoming);
9084
      gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
9085
      attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
9086
                         incoming);
9087
      set_variable_part (out, incoming, dv, offset,
9088
                         VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9089
      if (dv_is_value_p (dv))
9090
        {
9091
          record_entry_value (CSELIB_VAL_PTR (dv_as_value (dv)), incoming);
9092
          if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE
9093
              && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (parm))))
9094
            {
9095
              enum machine_mode indmode
9096
                = TYPE_MODE (TREE_TYPE (TREE_TYPE (parm)));
9097
              rtx mem = gen_rtx_MEM (indmode, incoming);
9098
              cselib_val *val = cselib_lookup_from_insn (mem, indmode, true,
9099
                                                         VOIDmode,
9100
                                                         get_insns ());
9101
              if (val)
9102
                {
9103
                  preserve_value (val);
9104
                  record_entry_value (val, mem);
9105
                  set_variable_part (out, mem, dv_from_value (val->val_rtx), 0,
9106
                                     VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9107
                }
9108
            }
9109
        }
9110
    }
9111
  else if (MEM_P (incoming))
9112
    {
9113
      incoming = var_lowpart (mode, incoming);
9114
      set_variable_part (out, incoming, dv, offset,
9115
                         VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
9116
    }
9117
}
9118
 
9119
/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK.  */
9120
 
9121
static void
9122
vt_add_function_parameters (void)
9123
{
9124
  tree parm;
9125
 
9126
  for (parm = DECL_ARGUMENTS (current_function_decl);
9127
       parm; parm = DECL_CHAIN (parm))
9128
    vt_add_function_parameter (parm);
9129
 
9130
  if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
9131
    {
9132
      tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
9133
 
9134
      if (TREE_CODE (vexpr) == INDIRECT_REF)
9135
        vexpr = TREE_OPERAND (vexpr, 0);
9136
 
9137
      if (TREE_CODE (vexpr) == PARM_DECL
9138
          && DECL_ARTIFICIAL (vexpr)
9139
          && !DECL_IGNORED_P (vexpr)
9140
          && DECL_NAMELESS (vexpr))
9141
        vt_add_function_parameter (vexpr);
9142
    }
9143
}
9144
 
9145
/* Return true if INSN in the prologue initializes hard_frame_pointer_rtx.  */
9146
 
9147
static bool
9148
fp_setter (rtx insn)
9149
{
9150
  rtx pat = PATTERN (insn);
9151
  if (RTX_FRAME_RELATED_P (insn))
9152
    {
9153
      rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
9154
      if (expr)
9155
        pat = XEXP (expr, 0);
9156
    }
9157
  if (GET_CODE (pat) == SET)
9158
    return SET_DEST (pat) == hard_frame_pointer_rtx;
9159
  else if (GET_CODE (pat) == PARALLEL)
9160
    {
9161
      int i;
9162
      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
9163
        if (GET_CODE (XVECEXP (pat, 0, i)) == SET
9164
            && SET_DEST (XVECEXP (pat, 0, i)) == hard_frame_pointer_rtx)
9165
          return true;
9166
    }
9167
  return false;
9168
}
9169
 
9170
/* Initialize cfa_base_rtx, create a preserved VALUE for it and
9171
   ensure it isn't flushed during cselib_reset_table.
9172
   Can be called only if frame_pointer_rtx resp. arg_pointer_rtx
9173
   has been eliminated.  */
9174
 
9175
static void
9176
vt_init_cfa_base (void)
9177
{
9178
  cselib_val *val;
9179
 
9180
#ifdef FRAME_POINTER_CFA_OFFSET
9181
  cfa_base_rtx = frame_pointer_rtx;
9182
  cfa_base_offset = -FRAME_POINTER_CFA_OFFSET (current_function_decl);
9183
#else
9184
  cfa_base_rtx = arg_pointer_rtx;
9185
  cfa_base_offset = -ARG_POINTER_CFA_OFFSET (current_function_decl);
9186
#endif
9187
  if (cfa_base_rtx == hard_frame_pointer_rtx
9188
      || !fixed_regs[REGNO (cfa_base_rtx)])
9189
    {
9190
      cfa_base_rtx = NULL_RTX;
9191
      return;
9192
    }
9193
  if (!MAY_HAVE_DEBUG_INSNS)
9194
    return;
9195
 
9196
  /* Tell alias analysis that cfa_base_rtx should share
9197
     find_base_term value with stack pointer or hard frame pointer.  */
9198
  if (!frame_pointer_needed)
9199
    vt_equate_reg_base_value (cfa_base_rtx, stack_pointer_rtx);
9200
  else if (!crtl->stack_realign_tried)
9201
    vt_equate_reg_base_value (cfa_base_rtx, hard_frame_pointer_rtx);
9202
 
9203
  val = cselib_lookup_from_insn (cfa_base_rtx, GET_MODE (cfa_base_rtx), 1,
9204
                                 VOIDmode, get_insns ());
9205
  preserve_value (val);
9206
  cselib_preserve_cfa_base_value (val, REGNO (cfa_base_rtx));
9207
  var_reg_decl_set (&VTI (ENTRY_BLOCK_PTR)->out, cfa_base_rtx,
9208
                    VAR_INIT_STATUS_INITIALIZED, dv_from_value (val->val_rtx),
9209
                    0, NULL_RTX, INSERT);
9210
}
9211
 
9212
/* Allocate and initialize the data structures for variable tracking
9213
   and parse the RTL to get the micro operations.  */
9214
 
9215
static bool
9216
vt_initialize (void)
9217
{
9218
  basic_block bb, prologue_bb = single_succ (ENTRY_BLOCK_PTR);
9219
  HOST_WIDE_INT fp_cfa_offset = -1;
9220
 
9221
  alloc_aux_for_blocks (sizeof (struct variable_tracking_info_def));
9222
 
9223
  attrs_pool = create_alloc_pool ("attrs_def pool",
9224
                                  sizeof (struct attrs_def), 1024);
9225
  var_pool = create_alloc_pool ("variable_def pool",
9226
                                sizeof (struct variable_def)
9227
                                + (MAX_VAR_PARTS - 1)
9228
                                * sizeof (((variable)NULL)->var_part[0]), 64);
9229
  loc_chain_pool = create_alloc_pool ("location_chain_def pool",
9230
                                      sizeof (struct location_chain_def),
9231
                                      1024);
9232
  shared_hash_pool = create_alloc_pool ("shared_hash_def pool",
9233
                                        sizeof (struct shared_hash_def), 256);
9234
  empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
9235
  empty_shared_hash->refcount = 1;
9236
  empty_shared_hash->htab
9237
    = htab_create (1, variable_htab_hash, variable_htab_eq,
9238
                   variable_htab_free);
9239
  changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
9240
                                   variable_htab_free);
9241
 
9242
  /* Init the IN and OUT sets.  */
9243
  FOR_ALL_BB (bb)
9244
    {
9245
      VTI (bb)->visited = false;
9246
      VTI (bb)->flooded = false;
9247
      dataflow_set_init (&VTI (bb)->in);
9248
      dataflow_set_init (&VTI (bb)->out);
9249
      VTI (bb)->permp = NULL;
9250
    }
9251
 
9252
  if (MAY_HAVE_DEBUG_INSNS)
9253
    {
9254
      cselib_init (CSELIB_RECORD_MEMORY | CSELIB_PRESERVE_CONSTANTS);
9255
      scratch_regs = BITMAP_ALLOC (NULL);
9256
      valvar_pool = create_alloc_pool ("small variable_def pool",
9257
                                       sizeof (struct variable_def), 256);
9258
      preserved_values = VEC_alloc (rtx, heap, 256);
9259
    }
9260
  else
9261
    {
9262
      scratch_regs = NULL;
9263
      valvar_pool = NULL;
9264
    }
9265
 
9266
  /* In order to factor out the adjustments made to the stack pointer or to
9267
     the hard frame pointer and thus be able to use DW_OP_fbreg operations
9268
     instead of individual location lists, we're going to rewrite MEMs based
9269
     on them into MEMs based on the CFA by de-eliminating stack_pointer_rtx
9270
     or hard_frame_pointer_rtx to the virtual CFA pointer frame_pointer_rtx
9271
     resp. arg_pointer_rtx.  We can do this either when there is no frame
9272
     pointer in the function and stack adjustments are consistent for all
9273
     basic blocks or when there is a frame pointer and no stack realignment.
9274
     But we first have to check that frame_pointer_rtx resp. arg_pointer_rtx
9275
     has been eliminated.  */
9276
  if (!frame_pointer_needed)
9277
    {
9278
      rtx reg, elim;
9279
 
9280
      if (!vt_stack_adjustments ())
9281
        return false;
9282
 
9283
#ifdef FRAME_POINTER_CFA_OFFSET
9284
      reg = frame_pointer_rtx;
9285
#else
9286
      reg = arg_pointer_rtx;
9287
#endif
9288
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9289
      if (elim != reg)
9290
        {
9291
          if (GET_CODE (elim) == PLUS)
9292
            elim = XEXP (elim, 0);
9293
          if (elim == stack_pointer_rtx)
9294
            vt_init_cfa_base ();
9295
        }
9296
    }
9297
  else if (!crtl->stack_realign_tried)
9298
    {
9299
      rtx reg, elim;
9300
 
9301
#ifdef FRAME_POINTER_CFA_OFFSET
9302
      reg = frame_pointer_rtx;
9303
      fp_cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl);
9304
#else
9305
      reg = arg_pointer_rtx;
9306
      fp_cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl);
9307
#endif
9308
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9309
      if (elim != reg)
9310
        {
9311
          if (GET_CODE (elim) == PLUS)
9312
            {
9313
              fp_cfa_offset -= INTVAL (XEXP (elim, 1));
9314
              elim = XEXP (elim, 0);
9315
            }
9316
          if (elim != hard_frame_pointer_rtx)
9317
            fp_cfa_offset = -1;
9318
        }
9319
      else
9320
        fp_cfa_offset = -1;
9321
    }
9322
 
9323
  /* If the stack is realigned and a DRAP register is used, we're going to
9324
     rewrite MEMs based on it representing incoming locations of parameters
9325
     passed on the stack into MEMs based on the argument pointer.  Although
9326
     we aren't going to rewrite other MEMs, we still need to initialize the
9327
     virtual CFA pointer in order to ensure that the argument pointer will
9328
     be seen as a constant throughout the function.
9329
 
9330
     ??? This doesn't work if FRAME_POINTER_CFA_OFFSET is defined.  */
9331
  else if (stack_realign_drap)
9332
    {
9333
      rtx reg, elim;
9334
 
9335
#ifdef FRAME_POINTER_CFA_OFFSET
9336
      reg = frame_pointer_rtx;
9337
#else
9338
      reg = arg_pointer_rtx;
9339
#endif
9340
      elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
9341
      if (elim != reg)
9342
        {
9343
          if (GET_CODE (elim) == PLUS)
9344
            elim = XEXP (elim, 0);
9345
          if (elim == hard_frame_pointer_rtx)
9346
            vt_init_cfa_base ();
9347
        }
9348
    }
9349
 
9350
  hard_frame_pointer_adjustment = -1;
9351
 
9352
  vt_add_function_parameters ();
9353
 
9354
  FOR_EACH_BB (bb)
9355
    {
9356
      rtx insn;
9357
      HOST_WIDE_INT pre, post = 0;
9358
      basic_block first_bb, last_bb;
9359
 
9360
      if (MAY_HAVE_DEBUG_INSNS)
9361
        {
9362
          cselib_record_sets_hook = add_with_sets;
9363
          if (dump_file && (dump_flags & TDF_DETAILS))
9364
            fprintf (dump_file, "first value: %i\n",
9365
                     cselib_get_next_uid ());
9366
        }
9367
 
9368
      first_bb = bb;
9369
      for (;;)
9370
        {
9371
          edge e;
9372
          if (bb->next_bb == EXIT_BLOCK_PTR
9373
              || ! single_pred_p (bb->next_bb))
9374
            break;
9375
          e = find_edge (bb, bb->next_bb);
9376
          if (! e || (e->flags & EDGE_FALLTHRU) == 0)
9377
            break;
9378
          bb = bb->next_bb;
9379
        }
9380
      last_bb = bb;
9381
 
9382
      /* Add the micro-operations to the vector.  */
9383
      FOR_BB_BETWEEN (bb, first_bb, last_bb->next_bb, next_bb)
9384
        {
9385
          HOST_WIDE_INT offset = VTI (bb)->out.stack_adjust;
9386
          VTI (bb)->out.stack_adjust = VTI (bb)->in.stack_adjust;
9387
          for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
9388
               insn = NEXT_INSN (insn))
9389
            {
9390
              if (INSN_P (insn))
9391
                {
9392
                  if (!frame_pointer_needed)
9393
                    {
9394
                      insn_stack_adjust_offset_pre_post (insn, &pre, &post);
9395
                      if (pre)
9396
                        {
9397
                          micro_operation mo;
9398
                          mo.type = MO_ADJUST;
9399
                          mo.u.adjust = pre;
9400
                          mo.insn = insn;
9401
                          if (dump_file && (dump_flags & TDF_DETAILS))
9402
                            log_op_type (PATTERN (insn), bb, insn,
9403
                                         MO_ADJUST, dump_file);
9404
                          VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
9405
                                         &mo);
9406
                          VTI (bb)->out.stack_adjust += pre;
9407
                        }
9408
                    }
9409
 
9410
                  cselib_hook_called = false;
9411
                  adjust_insn (bb, insn);
9412
                  if (MAY_HAVE_DEBUG_INSNS)
9413
                    {
9414
                      if (CALL_P (insn))
9415
                        prepare_call_arguments (bb, insn);
9416
                      cselib_process_insn (insn);
9417
                      if (dump_file && (dump_flags & TDF_DETAILS))
9418
                        {
9419
                          print_rtl_single (dump_file, insn);
9420
                          dump_cselib_table (dump_file);
9421
                        }
9422
                    }
9423
                  if (!cselib_hook_called)
9424
                    add_with_sets (insn, 0, 0);
9425
                  cancel_changes (0);
9426
 
9427
                  if (!frame_pointer_needed && post)
9428
                    {
9429
                      micro_operation mo;
9430
                      mo.type = MO_ADJUST;
9431
                      mo.u.adjust = post;
9432
                      mo.insn = insn;
9433
                      if (dump_file && (dump_flags & TDF_DETAILS))
9434
                        log_op_type (PATTERN (insn), bb, insn,
9435
                                     MO_ADJUST, dump_file);
9436
                      VEC_safe_push (micro_operation, heap, VTI (bb)->mos,
9437
                                     &mo);
9438
                      VTI (bb)->out.stack_adjust += post;
9439
                    }
9440
 
9441
                  if (bb == prologue_bb
9442
                      && fp_cfa_offset != -1
9443
                      && hard_frame_pointer_adjustment == -1
9444
                      && RTX_FRAME_RELATED_P (insn)
9445
                      && fp_setter (insn))
9446
                    {
9447
                      vt_init_cfa_base ();
9448
                      hard_frame_pointer_adjustment = fp_cfa_offset;
9449
                    }
9450
                }
9451
            }
9452
          gcc_assert (offset == VTI (bb)->out.stack_adjust);
9453
        }
9454
 
9455
      bb = last_bb;
9456
 
9457
      if (MAY_HAVE_DEBUG_INSNS)
9458
        {
9459
          cselib_preserve_only_values ();
9460
          cselib_reset_table (cselib_get_next_uid ());
9461
          cselib_record_sets_hook = NULL;
9462
        }
9463
    }
9464
 
9465
  hard_frame_pointer_adjustment = -1;
9466
  VTI (ENTRY_BLOCK_PTR)->flooded = true;
9467
  cfa_base_rtx = NULL_RTX;
9468
  return true;
9469
}
9470
 
9471
/* This is *not* reset after each function.  It gives each
9472
   NOTE_INSN_DELETED_DEBUG_LABEL in the entire compilation
9473
   a unique label number.  */
9474
 
9475
static int debug_label_num = 1;
9476
 
9477
/* Get rid of all debug insns from the insn stream.  */
9478
 
9479
static void
9480
delete_debug_insns (void)
9481
{
9482
  basic_block bb;
9483
  rtx insn, next;
9484
 
9485
  if (!MAY_HAVE_DEBUG_INSNS)
9486
    return;
9487
 
9488
  FOR_EACH_BB (bb)
9489
    {
9490
      FOR_BB_INSNS_SAFE (bb, insn, next)
9491
        if (DEBUG_INSN_P (insn))
9492
          {
9493
            tree decl = INSN_VAR_LOCATION_DECL (insn);
9494
            if (TREE_CODE (decl) == LABEL_DECL
9495
                && DECL_NAME (decl)
9496
                && !DECL_RTL_SET_P (decl))
9497
              {
9498
                PUT_CODE (insn, NOTE);
9499
                NOTE_KIND (insn) = NOTE_INSN_DELETED_DEBUG_LABEL;
9500
                NOTE_DELETED_LABEL_NAME (insn)
9501
                  = IDENTIFIER_POINTER (DECL_NAME (decl));
9502
                SET_DECL_RTL (decl, insn);
9503
                CODE_LABEL_NUMBER (insn) = debug_label_num++;
9504
              }
9505
            else
9506
              delete_insn (insn);
9507
          }
9508
    }
9509
}
9510
 
9511
/* Run a fast, BB-local only version of var tracking, to take care of
9512
   information that we don't do global analysis on, such that not all
9513
   information is lost.  If SKIPPED holds, we're skipping the global
9514
   pass entirely, so we should try to use information it would have
9515
   handled as well..  */
9516
 
9517
static void
9518
vt_debug_insns_local (bool skipped ATTRIBUTE_UNUSED)
9519
{
9520
  /* ??? Just skip it all for now.  */
9521
  delete_debug_insns ();
9522
}
9523
 
9524
/* Free the data structures needed for variable tracking.  */
9525
 
9526
static void
9527
vt_finalize (void)
9528
{
9529
  basic_block bb;
9530
 
9531
  FOR_EACH_BB (bb)
9532
    {
9533
      VEC_free (micro_operation, heap, VTI (bb)->mos);
9534
    }
9535
 
9536
  FOR_ALL_BB (bb)
9537
    {
9538
      dataflow_set_destroy (&VTI (bb)->in);
9539
      dataflow_set_destroy (&VTI (bb)->out);
9540
      if (VTI (bb)->permp)
9541
        {
9542
          dataflow_set_destroy (VTI (bb)->permp);
9543
          XDELETE (VTI (bb)->permp);
9544
        }
9545
    }
9546
  free_aux_for_blocks ();
9547
  htab_delete (empty_shared_hash->htab);
9548
  htab_delete (changed_variables);
9549
  free_alloc_pool (attrs_pool);
9550
  free_alloc_pool (var_pool);
9551
  free_alloc_pool (loc_chain_pool);
9552
  free_alloc_pool (shared_hash_pool);
9553
 
9554
  if (MAY_HAVE_DEBUG_INSNS)
9555
    {
9556
      free_alloc_pool (valvar_pool);
9557
      VEC_free (rtx, heap, preserved_values);
9558
      cselib_finish ();
9559
      BITMAP_FREE (scratch_regs);
9560
      scratch_regs = NULL;
9561
    }
9562
 
9563
#ifdef HAVE_window_save
9564
  VEC_free (parm_reg_t, gc, windowed_parm_regs);
9565
#endif
9566
 
9567
  if (vui_vec)
9568
    XDELETEVEC (vui_vec);
9569
  vui_vec = NULL;
9570
  vui_allocated = 0;
9571
}
9572
 
9573
/* The entry point to variable tracking pass.  */
9574
 
9575
static inline unsigned int
9576
variable_tracking_main_1 (void)
9577
{
9578
  bool success;
9579
 
9580
  if (flag_var_tracking_assignments < 0)
9581
    {
9582
      delete_debug_insns ();
9583
      return 0;
9584
    }
9585
 
9586
  if (n_basic_blocks > 500 && n_edges / n_basic_blocks >= 20)
9587
    {
9588
      vt_debug_insns_local (true);
9589
      return 0;
9590
    }
9591
 
9592
  mark_dfs_back_edges ();
9593
  if (!vt_initialize ())
9594
    {
9595
      vt_finalize ();
9596
      vt_debug_insns_local (true);
9597
      return 0;
9598
    }
9599
 
9600
  success = vt_find_locations ();
9601
 
9602
  if (!success && flag_var_tracking_assignments > 0)
9603
    {
9604
      vt_finalize ();
9605
 
9606
      delete_debug_insns ();
9607
 
9608
      /* This is later restored by our caller.  */
9609
      flag_var_tracking_assignments = 0;
9610
 
9611
      success = vt_initialize ();
9612
      gcc_assert (success);
9613
 
9614
      success = vt_find_locations ();
9615
    }
9616
 
9617
  if (!success)
9618
    {
9619
      vt_finalize ();
9620
      vt_debug_insns_local (false);
9621
      return 0;
9622
    }
9623
 
9624
  if (dump_file && (dump_flags & TDF_DETAILS))
9625
    {
9626
      dump_dataflow_sets ();
9627
      dump_flow_info (dump_file, dump_flags);
9628
    }
9629
 
9630
  timevar_push (TV_VAR_TRACKING_EMIT);
9631
  vt_emit_notes ();
9632
  timevar_pop (TV_VAR_TRACKING_EMIT);
9633
 
9634
  vt_finalize ();
9635
  vt_debug_insns_local (false);
9636
  return 0;
9637
}
9638
 
9639
unsigned int
9640
variable_tracking_main (void)
9641
{
9642
  unsigned int ret;
9643
  int save = flag_var_tracking_assignments;
9644
 
9645
  ret = variable_tracking_main_1 ();
9646
 
9647
  flag_var_tracking_assignments = save;
9648
 
9649
  return ret;
9650
}
9651
 
9652
static bool
9653
gate_handle_var_tracking (void)
9654
{
9655
  return (flag_var_tracking && !targetm.delay_vartrack);
9656
}
9657
 
9658
 
9659
 
9660
struct rtl_opt_pass pass_variable_tracking =
9661
{
9662
 {
9663
  RTL_PASS,
9664
  "vartrack",                           /* name */
9665
  gate_handle_var_tracking,             /* gate */
9666
  variable_tracking_main,               /* execute */
9667
  NULL,                                 /* sub */
9668
  NULL,                                 /* next */
9669
  0,                                    /* static_pass_number */
9670
  TV_VAR_TRACKING,                      /* tv_id */
9671
  0,                                    /* properties_required */
9672
  0,                                    /* properties_provided */
9673
  0,                                    /* properties_destroyed */
9674
  0,                                    /* todo_flags_start */
9675
  TODO_verify_rtl_sharing               /* todo_flags_finish */
9676
 }
9677
};

powered by: WebSVN 2.1.0

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