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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [varpool.c] - Blame information for rev 721

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

Line No. Rev Author Line
1 684 jeremybenn
/* Callgraph handling code.
2
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
3
   Free Software Foundation, Inc.
4
   Contributed by Jan Hubicka
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "tree.h"
27
#include "cgraph.h"
28
#include "langhooks.h"
29
#include "diagnostic-core.h"
30
#include "hashtab.h"
31
#include "ggc.h"
32
#include "timevar.h"
33
#include "debug.h"
34
#include "target.h"
35
#include "output.h"
36
#include "gimple.h"
37
#include "tree-flow.h"
38
#include "flags.h"
39
 
40
/*  This file contains basic routines manipulating variable pool.
41
 
42
    Varpool acts as interface in between the front-end and middle-end
43
    and drives the decision process on what variables and when are
44
    going to be compiled.
45
 
46
    The varpool nodes are allocated lazily for declarations
47
    either by frontend or at callgraph construction time.
48
    All variables supposed to be output into final file needs to be
49
    explicitly marked by frontend via VARPOOL_FINALIZE_DECL function.  */
50
 
51
/* Hash table used to convert declarations into nodes.  */
52
static GTY((param_is (struct varpool_node))) htab_t varpool_hash;
53
 
54
/* The linked list of cgraph varpool nodes.
55
   Linked via node->next pointer.  */
56
struct varpool_node *varpool_nodes;
57
 
58
/* Queue of cgraph nodes scheduled to be lowered and output.
59
   The queue is maintained via mark_needed_node, linked via node->next_needed
60
   pointer.
61
 
62
   LAST_NEEDED_NODE points to the end of queue, so it can be
63
   maintained in forward order.  GTY is needed to make it friendly to
64
   PCH.
65
 
66
   During compilation we construct the queue of needed variables
67
   twice: first time it is during cgraph construction, second time it is at the
68
   end of compilation in VARPOOL_REMOVE_UNREFERENCED_DECLS so we can avoid
69
   optimized out variables being output.
70
 
71
   Each variable is thus first analyzed and then later possibly output.
72
   FIRST_UNANALYZED_NODE points to first node in queue that was not analyzed
73
   yet and is moved via VARPOOL_ANALYZE_PENDING_DECLS.  */
74
 
75
struct varpool_node *varpool_nodes_queue;
76
static GTY(()) struct varpool_node *varpool_last_needed_node;
77
static GTY(()) struct varpool_node *varpool_first_unanalyzed_node;
78
 
79
/* Lists all assembled variables to be sent to debugger output later on.  */
80
static GTY(()) struct varpool_node *varpool_assembled_nodes_queue;
81
 
82
/* Return name of the node used in debug output.  */
83
const char *
84
varpool_node_name (struct varpool_node *node)
85
{
86
  return lang_hooks.decl_printable_name (node->decl, 2);
87
}
88
 
89
/* Returns a hash code for P.  */
90
static hashval_t
91
hash_varpool_node (const void *p)
92
{
93
  const struct varpool_node *n = (const struct varpool_node *) p;
94
  return (hashval_t) DECL_UID (n->decl);
95
}
96
 
97
/* Returns nonzero if P1 and P2 are equal.  */
98
static int
99
eq_varpool_node (const void *p1, const void *p2)
100
{
101
  const struct varpool_node *n1 =
102
    (const struct varpool_node *) p1;
103
  const struct varpool_node *n2 =
104
    (const struct varpool_node *) p2;
105
  return DECL_UID (n1->decl) == DECL_UID (n2->decl);
106
}
107
 
108
/* Return varpool node assigned to DECL without creating new one.  */
109
struct varpool_node *
110
varpool_get_node (const_tree decl)
111
{
112
  struct varpool_node key, **slot;
113
 
114
  gcc_assert (TREE_CODE (decl) == VAR_DECL
115
              && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
116
 
117
  if (!varpool_hash)
118
    return NULL;
119
  key.decl = CONST_CAST2 (tree, const_tree, decl);
120
  slot = (struct varpool_node **)
121
    htab_find_slot (varpool_hash, &key, NO_INSERT);
122
  if (!slot)
123
    return NULL;
124
  return *slot;
125
}
126
 
127
/* Return varpool node assigned to DECL.  Create new one when needed.  */
128
struct varpool_node *
129
varpool_node (tree decl)
130
{
131
  struct varpool_node key, *node, **slot;
132
 
133
  gcc_assert (TREE_CODE (decl) == VAR_DECL
134
              && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p));
135
 
136
  if (!varpool_hash)
137
    varpool_hash = htab_create_ggc (10, hash_varpool_node,
138
                                           eq_varpool_node, NULL);
139
  key.decl = decl;
140
  slot = (struct varpool_node **)
141
    htab_find_slot (varpool_hash, &key, INSERT);
142
  if (*slot)
143
    return *slot;
144
  node = ggc_alloc_cleared_varpool_node ();
145
  node->decl = decl;
146
  node->order = cgraph_order++;
147
  node->next = varpool_nodes;
148
  ipa_empty_ref_list (&node->ref_list);
149
  if (varpool_nodes)
150
    varpool_nodes->prev = node;
151
  varpool_nodes = node;
152
  *slot = node;
153
  return node;
154
}
155
 
156
/* Remove node from the varpool.  */
157
void
158
varpool_remove_node (struct varpool_node *node)
159
{
160
  void **slot;
161
  slot = htab_find_slot (varpool_hash, node, NO_INSERT);
162
  gcc_assert (*slot == node);
163
  htab_clear_slot (varpool_hash, slot);
164
  gcc_assert (!varpool_assembled_nodes_queue);
165
  if (node->next)
166
    node->next->prev = node->prev;
167
  if (node->prev)
168
    node->prev->next = node->next;
169
  else
170
    {
171
      gcc_assert (varpool_nodes == node);
172
      varpool_nodes = node->next;
173
    }
174
  if (varpool_first_unanalyzed_node == node)
175
    varpool_first_unanalyzed_node = node->next_needed;
176
  if (node->next_needed)
177
    node->next_needed->prev_needed = node->prev_needed;
178
  else if (node->prev_needed)
179
    {
180
      gcc_assert (varpool_last_needed_node);
181
      varpool_last_needed_node = node->prev_needed;
182
    }
183
  if (node->prev_needed)
184
    node->prev_needed->next_needed = node->next_needed;
185
  else if (node->next_needed)
186
    {
187
      gcc_assert (varpool_nodes_queue == node);
188
      varpool_nodes_queue = node->next_needed;
189
    }
190
  if (node->same_comdat_group)
191
    {
192
      struct varpool_node *prev;
193
      for (prev = node->same_comdat_group;
194
           prev->same_comdat_group != node;
195
           prev = prev->same_comdat_group)
196
        ;
197
      if (node->same_comdat_group == prev)
198
        prev->same_comdat_group = NULL;
199
      else
200
        prev->same_comdat_group = node->same_comdat_group;
201
      node->same_comdat_group = NULL;
202
    }
203
  ipa_remove_all_references (&node->ref_list);
204
  ipa_remove_all_refering (&node->ref_list);
205
  ggc_free (node);
206
}
207
 
208
/* Dump given cgraph node.  */
209
void
210
dump_varpool_node (FILE *f, struct varpool_node *node)
211
{
212
  fprintf (f, "%s:", varpool_node_name (node));
213
  fprintf (f, " availability:%s",
214
           cgraph_function_flags_ready
215
           ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
216
           : "not-ready");
217
  if (DECL_ASSEMBLER_NAME_SET_P (node->decl))
218
    fprintf (f, " (asm: %s)", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
219
  if (DECL_INITIAL (node->decl))
220
    fprintf (f, " initialized");
221
  if (TREE_ASM_WRITTEN (node->decl))
222
    fprintf (f, " (asm written)");
223
  if (node->needed)
224
    fprintf (f, " needed");
225
  if (node->analyzed)
226
    fprintf (f, " analyzed");
227
  if (node->finalized)
228
    fprintf (f, " finalized");
229
  if (node->output)
230
    fprintf (f, " output");
231
  if (node->externally_visible)
232
    fprintf (f, " externally_visible");
233
  if (node->resolution != LDPR_UNKNOWN)
234
    fprintf (f, " %s",
235
             ld_plugin_symbol_resolution_names[(int)node->resolution]);
236
  if (node->in_other_partition)
237
    fprintf (f, " in_other_partition");
238
  else if (node->used_from_other_partition)
239
    fprintf (f, " used_from_other_partition");
240
  fprintf (f, "\n");
241
  fprintf (f, "  References: ");
242
  ipa_dump_references (f, &node->ref_list);
243
  fprintf (f, "  Refering this var: ");
244
  ipa_dump_refering (f, &node->ref_list);
245
}
246
 
247
/* Dump the variable pool.  */
248
void
249
dump_varpool (FILE *f)
250
{
251
  struct varpool_node *node;
252
 
253
  fprintf (f, "variable pool:\n\n");
254
  for (node = varpool_nodes; node; node = node->next)
255
    dump_varpool_node (f, node);
256
}
257
 
258
/* Dump the variable pool to stderr.  */
259
 
260
DEBUG_FUNCTION void
261
debug_varpool (void)
262
{
263
  dump_varpool (stderr);
264
}
265
 
266
/* Given an assembler name, lookup node.  */
267
struct varpool_node *
268
varpool_node_for_asm (tree asmname)
269
{
270
  struct varpool_node *node;
271
 
272
  for (node = varpool_nodes; node ; node = node->next)
273
    if (decl_assembler_name_equal (node->decl, asmname))
274
      return node;
275
 
276
  return NULL;
277
}
278
 
279
/* Helper function for finalization code - add node into lists so it will
280
   be analyzed and compiled.  */
281
static void
282
varpool_enqueue_needed_node (struct varpool_node *node)
283
{
284
  if (varpool_last_needed_node)
285
    {
286
      varpool_last_needed_node->next_needed = node;
287
      node->prev_needed = varpool_last_needed_node;
288
    }
289
  varpool_last_needed_node = node;
290
  node->next_needed = NULL;
291
  if (!varpool_nodes_queue)
292
    varpool_nodes_queue = node;
293
  if (!varpool_first_unanalyzed_node)
294
    varpool_first_unanalyzed_node = node;
295
  notice_global_symbol (node->decl);
296
}
297
 
298
/* Notify finalize_compilation_unit that given node is reachable
299
   or needed.  */
300
void
301
varpool_mark_needed_node (struct varpool_node *node)
302
{
303
  if (!node->needed && node->finalized
304
      && !TREE_ASM_WRITTEN (node->decl))
305
    varpool_enqueue_needed_node (node);
306
  node->needed = 1;
307
}
308
 
309
/* Reset the queue of needed nodes.  */
310
void
311
varpool_reset_queue (void)
312
{
313
  varpool_last_needed_node = NULL;
314
  varpool_nodes_queue = NULL;
315
  varpool_first_unanalyzed_node = NULL;
316
}
317
 
318
/* Determine if variable DECL is needed.  That is, visible to something
319
   either outside this translation unit, something magic in the system
320
   configury */
321
bool
322
decide_is_variable_needed (struct varpool_node *node, tree decl)
323
{
324
  /* If the user told us it is used, then it must be so.  */
325
  if (node->force_output)
326
    return true;
327
 
328
  gcc_assert (!DECL_EXTERNAL (decl));
329
 
330
  /* Externally visible variables must be output.  The exception is
331
     COMDAT variables that must be output only when they are needed.  */
332
  if (TREE_PUBLIC (decl)
333
      && !DECL_COMDAT (decl)
334
      && !DECL_EXTERNAL (decl))
335
    return true;
336
 
337
  /* When not reordering top level variables, we have to assume that
338
     we are going to keep everything.  */
339
  if (!flag_toplevel_reorder)
340
    return true;
341
  return false;
342
}
343
 
344
/* Return if DECL is constant and its initial value is known (so we can do
345
   constant folding using DECL_INITIAL (decl)).  */
346
 
347
bool
348
const_value_known_p (tree decl)
349
{
350
  if (TREE_CODE (decl) != VAR_DECL
351
      &&TREE_CODE (decl) != CONST_DECL)
352
    return false;
353
 
354
  if (TREE_CODE (decl) == CONST_DECL
355
      || DECL_IN_CONSTANT_POOL (decl))
356
    return true;
357
 
358
  gcc_assert (TREE_CODE (decl) == VAR_DECL);
359
 
360
  if (!TREE_READONLY (decl) || TREE_THIS_VOLATILE (decl))
361
    return false;
362
 
363
  /* Gimplifier takes away constructors of local vars  */
364
  if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
365
    return DECL_INITIAL (decl) != NULL;
366
 
367
  gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
368
 
369
  /* Variables declared 'const' without an initializer
370
     have zero as the initializer if they may not be
371
     overridden at link or run time.  */
372
  if (!DECL_INITIAL (decl)
373
      && (DECL_EXTERNAL (decl)
374
          || decl_replaceable_p (decl)))
375
    return false;
376
 
377
  /* Variables declared `const' with an initializer are considered
378
     to not be overwritable with different initializer by default.
379
 
380
     ??? Previously we behaved so for scalar variables but not for array
381
     accesses.  */
382
  return true;
383
}
384
 
385
/* Mark DECL as finalized.  By finalizing the declaration, frontend instruct the
386
   middle end to output the variable to asm file, if needed or externally
387
   visible.  */
388
void
389
varpool_finalize_decl (tree decl)
390
{
391
  struct varpool_node *node = varpool_node (decl);
392
 
393
  gcc_assert (TREE_STATIC (decl));
394
 
395
  /* The first declaration of a variable that comes through this function
396
     decides whether it is global (in C, has external linkage)
397
     or local (in C, has internal linkage).  So do nothing more
398
     if this function has already run.  */
399
  if (node->finalized)
400
    {
401
      if (cgraph_global_info_ready)
402
        varpool_assemble_pending_decls ();
403
      return;
404
    }
405
  if (node->needed)
406
    varpool_enqueue_needed_node (node);
407
  node->finalized = true;
408
  if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl))
409
    node->force_output = true;
410
 
411
  if (decide_is_variable_needed (node, decl))
412
    varpool_mark_needed_node (node);
413
  if (cgraph_global_info_ready)
414
    varpool_assemble_pending_decls ();
415
}
416
 
417
/* Add the variable DECL to the varpool.
418
   Unlike varpool_finalize_decl function is intended to be used
419
   by middle end and allows insertion of new variable at arbitrary point
420
   of compilation.  */
421
void
422
varpool_add_new_variable (tree decl)
423
{
424
  struct varpool_node *node;
425
  varpool_finalize_decl (decl);
426
  node = varpool_node (decl);
427
  if (varpool_externally_visible_p (node, false))
428
    node->externally_visible = true;
429
}
430
 
431
/* Return variable availability.  See cgraph.h for description of individual
432
   return values.  */
433
enum availability
434
cgraph_variable_initializer_availability (struct varpool_node *node)
435
{
436
  gcc_assert (cgraph_function_flags_ready);
437
  if (!node->finalized)
438
    return AVAIL_NOT_AVAILABLE;
439
  if (!TREE_PUBLIC (node->decl))
440
    return AVAIL_AVAILABLE;
441
  /* If the variable can be overwritten, return OVERWRITABLE.  Takes
442
     care of at least two notable extensions - the COMDAT variables
443
     used to share template instantiations in C++.  */
444
  if (!decl_replaceable_p (node->decl))
445
    return AVAIL_OVERWRITABLE;
446
  return AVAIL_AVAILABLE;
447
}
448
 
449
/* Walk the decls we marked as necessary and see if they reference new
450
   variables or functions and add them into the worklists.  */
451
bool
452
varpool_analyze_pending_decls (void)
453
{
454
  bool changed = false;
455
 
456
  timevar_push (TV_VARPOOL);
457
  while (varpool_first_unanalyzed_node)
458
    {
459
      struct varpool_node *node = varpool_first_unanalyzed_node, *next;
460
      tree decl = node->decl;
461
      bool analyzed = node->analyzed;
462
 
463
      varpool_first_unanalyzed_node->analyzed = true;
464
 
465
      varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed;
466
 
467
      /* When reading back varpool at LTO time, we re-construct the queue in order
468
         to have "needed" list right by inserting all needed nodes into varpool.
469
         We however don't want to re-analyze already analyzed nodes.  */
470
      if (!analyzed)
471
        {
472
          gcc_assert (!in_lto_p || cgraph_function_flags_ready);
473
          /* Compute the alignment early so function body expanders are
474
             already informed about increased alignment.  */
475
          align_variable (decl, 0);
476
        }
477
      if (node->alias && node->alias_of)
478
        {
479
          struct varpool_node *tgt = varpool_node (node->alias_of);
480
          struct varpool_node *n;
481
 
482
          for (n = tgt; n && n->alias;
483
               n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
484
            if (n == node)
485
              {
486
                error ("variable %q+D part of alias cycle", node->decl);
487
                node->alias = false;
488
                continue;
489
              }
490
          if (!VEC_length (ipa_ref_t, node->ref_list.references))
491
            ipa_record_reference (NULL, node, NULL, tgt, IPA_REF_ALIAS, NULL);
492
          /* C++ FE sometimes change linkage flags after producing same body aliases.  */
493
          if (node->extra_name_alias)
494
            {
495
              DECL_WEAK (node->decl) = DECL_WEAK (node->alias_of);
496
              TREE_PUBLIC (node->decl) = TREE_PUBLIC (node->alias_of);
497
              DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (node->alias_of);
498
              DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (node->alias_of);
499
              if (TREE_PUBLIC (node->decl))
500
                {
501
                  DECL_COMDAT (node->decl) = DECL_COMDAT (node->alias_of);
502
                  DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (node->alias_of);
503
                  if (DECL_ONE_ONLY (node->alias_of) && !node->same_comdat_group)
504
                    {
505
                      node->same_comdat_group = tgt;
506
                      if (!tgt->same_comdat_group)
507
                        tgt->same_comdat_group = node;
508
                      else
509
                        {
510
                          struct varpool_node *n;
511
                          for (n = tgt->same_comdat_group;
512
                               n->same_comdat_group != tgt;
513
                               n = n->same_comdat_group)
514
                            ;
515
                          n->same_comdat_group = node;
516
                        }
517
                    }
518
                }
519
            }
520
        }
521
      else if (DECL_INITIAL (decl))
522
        record_references_in_initializer (decl, analyzed);
523
      if (node->same_comdat_group)
524
        {
525
          for (next = node->same_comdat_group;
526
               next != node;
527
               next = next->same_comdat_group)
528
            varpool_mark_needed_node (next);
529
        }
530
      changed = true;
531
    }
532
  timevar_pop (TV_VARPOOL);
533
  return changed;
534
}
535
 
536
/* Assemble thunks and aliases asociated to NODE.  */
537
 
538
static void
539
assemble_aliases (struct varpool_node *node)
540
{
541
  int i;
542
  struct ipa_ref *ref;
543
  for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
544
    if (ref->use == IPA_REF_ALIAS)
545
      {
546
        struct varpool_node *alias = ipa_ref_refering_varpool_node (ref);
547
        assemble_alias (alias->decl,
548
                        DECL_ASSEMBLER_NAME (alias->alias_of));
549
        assemble_aliases (alias);
550
      }
551
}
552
 
553
/* Output one variable, if necessary.  Return whether we output it.  */
554
bool
555
varpool_assemble_decl (struct varpool_node *node)
556
{
557
  tree decl = node->decl;
558
 
559
  if (!TREE_ASM_WRITTEN (decl)
560
      && !node->alias
561
      && !node->in_other_partition
562
      && !DECL_EXTERNAL (decl)
563
      && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl)))
564
    {
565
      assemble_variable (decl, 0, 1, 0);
566
      if (TREE_ASM_WRITTEN (decl))
567
        {
568
          node->next_needed = varpool_assembled_nodes_queue;
569
          node->prev_needed = NULL;
570
          if (varpool_assembled_nodes_queue)
571
            varpool_assembled_nodes_queue->prev_needed = node;
572
          varpool_assembled_nodes_queue = node;
573
          node->finalized = 1;
574
          assemble_aliases (node);
575
          return true;
576
        }
577
    }
578
 
579
  return false;
580
}
581
 
582
/* Optimization of function bodies might've rendered some variables as
583
   unnecessary so we want to avoid these from being compiled.
584
 
585
   This is done by pruning the queue and keeping only the variables that
586
   really appear needed (ie they are either externally visible or referenced
587
   by compiled function). Re-doing the reachability analysis on variables
588
   brings back the remaining variables referenced by these.  */
589
void
590
varpool_remove_unreferenced_decls (void)
591
{
592
  struct varpool_node *next, *node = varpool_nodes_queue;
593
 
594
  varpool_reset_queue ();
595
 
596
  if (seen_error ())
597
    return;
598
 
599
  while (node)
600
    {
601
      next = node->next_needed;
602
      node->needed = 0;
603
 
604
      if (node->analyzed
605
          && (!varpool_can_remove_if_no_refs (node)
606
              /* We just expanded all function bodies.  See if any of
607
                 them needed the variable.  */
608
              || DECL_RTL_SET_P (node->decl)))
609
        varpool_mark_needed_node (node);
610
 
611
      node = next;
612
    }
613
  /* Make sure we mark alias targets as used targets.  */
614
  finish_aliases_1 ();
615
  varpool_analyze_pending_decls ();
616
}
617
 
618
/* For variables in named sections make sure get_variable_section
619
   is called before we switch to those sections.  Then section
620
   conflicts between read-only and read-only requiring relocations
621
   sections can be resolved.  */
622
void
623
varpool_finalize_named_section_flags (struct varpool_node *node)
624
{
625
  if (!TREE_ASM_WRITTEN (node->decl)
626
      && !node->alias
627
      && !node->in_other_partition
628
      && !DECL_EXTERNAL (node->decl)
629
      && TREE_CODE (node->decl) == VAR_DECL
630
      && !DECL_HAS_VALUE_EXPR_P (node->decl)
631
      && DECL_SECTION_NAME (node->decl))
632
    get_variable_section (node->decl, false);
633
}
634
 
635
/* Output all variables enqueued to be assembled.  */
636
bool
637
varpool_assemble_pending_decls (void)
638
{
639
  bool changed = false;
640
  struct varpool_node *node;
641
 
642
  if (seen_error ())
643
    return false;
644
 
645
  timevar_push (TV_VAROUT);
646
  /* EH might mark decls as needed during expansion.  This should be safe since
647
     we don't create references to new function, but it should not be used
648
     elsewhere.  */
649
  varpool_analyze_pending_decls ();
650
 
651
  for (node = varpool_nodes_queue; node; node = node->next_needed)
652
    varpool_finalize_named_section_flags (node);
653
 
654
  while (varpool_nodes_queue)
655
    {
656
      struct varpool_node *node = varpool_nodes_queue;
657
 
658
      varpool_nodes_queue = varpool_nodes_queue->next_needed;
659
      if (varpool_assemble_decl (node))
660
        changed = true;
661
      else
662
        {
663
          node->prev_needed = NULL;
664
          node->next_needed = NULL;
665
        }
666
    }
667
  /* varpool_nodes_queue is now empty, clear the pointer to the last element
668
     in the queue.  */
669
  varpool_last_needed_node = NULL;
670
  timevar_pop (TV_VAROUT);
671
  return changed;
672
}
673
 
674
/* Remove all elements from the queue so we can re-use it for debug output.  */
675
void
676
varpool_empty_needed_queue (void)
677
{
678
  /* EH might mark decls as needed during expansion.  This should be safe since
679
     we don't create references to new function, but it should not be used
680
     elsewhere.  */
681
  varpool_analyze_pending_decls ();
682
 
683
  while (varpool_nodes_queue)
684
    {
685
      struct varpool_node *node = varpool_nodes_queue;
686
      varpool_nodes_queue = varpool_nodes_queue->next_needed;
687
      node->next_needed = NULL;
688
      node->prev_needed = NULL;
689
    }
690
  /* varpool_nodes_queue is now empty, clear the pointer to the last element
691
     in the queue.  */
692
  varpool_last_needed_node = NULL;
693
}
694
 
695
/* Create a new global variable of type TYPE.  */
696
tree
697
add_new_static_var (tree type)
698
{
699
  tree new_decl;
700
  struct varpool_node *new_node;
701
 
702
  new_decl = create_tmp_var (type, NULL);
703
  DECL_NAME (new_decl) = create_tmp_var_name (NULL);
704
  TREE_READONLY (new_decl) = 0;
705
  TREE_STATIC (new_decl) = 1;
706
  TREE_USED (new_decl) = 1;
707
  DECL_CONTEXT (new_decl) = NULL_TREE;
708
  DECL_ABSTRACT (new_decl) = 0;
709
  lang_hooks.dup_lang_specific_decl (new_decl);
710
  create_var_ann (new_decl);
711
  new_node = varpool_node (new_decl);
712
  varpool_mark_needed_node (new_node);
713
  add_referenced_var (new_decl);
714
  varpool_finalize_decl (new_decl);
715
 
716
  return new_node->decl;
717
}
718
 
719
/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
720
   Extra name aliases are output whenever DECL is output.  */
721
 
722
struct varpool_node *
723
varpool_create_variable_alias (tree alias, tree decl)
724
{
725
  struct varpool_node *alias_node;
726
 
727
  gcc_assert (TREE_CODE (decl) == VAR_DECL);
728
  gcc_assert (TREE_CODE (alias) == VAR_DECL);
729
  alias_node = varpool_node (alias);
730
  alias_node->alias = 1;
731
  if (!DECL_EXTERNAL (alias))
732
    alias_node->finalized = 1;
733
  alias_node->alias_of = decl;
734
  if ((!DECL_EXTERNAL (alias)
735
       && decide_is_variable_needed (alias_node, alias))
736
      || alias_node->needed)
737
    varpool_mark_needed_node (alias_node);
738
  return alias_node;
739
}
740
 
741
/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
742
   Extra name aliases are output whenever DECL is output.  */
743
 
744
struct varpool_node *
745
varpool_extra_name_alias (tree alias, tree decl)
746
{
747
  struct varpool_node *alias_node;
748
 
749
#ifndef ASM_OUTPUT_DEF
750
  /* If aliases aren't supported by the assembler, fail.  */
751
  return NULL;
752
#endif
753
  alias_node = varpool_create_variable_alias (alias, decl);
754
  alias_node->extra_name_alias = true;
755
  return alias_node;
756
}
757
 
758
/* Return true when NODE is known to be used from other (non-LTO) object file.
759
   Known only when doing LTO via linker plugin.  */
760
 
761
bool
762
varpool_used_from_object_file_p (struct varpool_node *node)
763
{
764
  if (!TREE_PUBLIC (node->decl))
765
    return false;
766
  if (resolution_used_from_other_file_p (node->resolution))
767
    return true;
768
  return false;
769
}
770
 
771
/* Call calback on NODE and aliases asociated to NODE.
772
   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
773
   skipped. */
774
 
775
bool
776
varpool_for_node_and_aliases (struct varpool_node *node,
777
                              bool (*callback) (struct varpool_node *, void *),
778
                              void *data,
779
                              bool include_overwritable)
780
{
781
  int i;
782
  struct ipa_ref *ref;
783
 
784
  if (callback (node, data))
785
    return true;
786
  for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
787
    if (ref->use == IPA_REF_ALIAS)
788
      {
789
        struct varpool_node *alias = ipa_ref_refering_varpool_node (ref);
790
        if (include_overwritable
791
            || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
792
          if (varpool_for_node_and_aliases (alias, callback, data,
793
                                           include_overwritable))
794
            return true;
795
      }
796
  return false;
797
}
798
#include "gt-varpool.h"

powered by: WebSVN 2.1.0

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