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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [lto-wpa-fixup.c] - Blame information for rev 837

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

Line No. Rev Author Line
1 280 jeremybenn
/* Write and read any fix-up information generated by the WPA mode.
2
 
3
   Copyright 2009 Free Software Foundation, Inc.
4
   Contributed by Doug Kwan <dougkwan@google.com>
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 "toplev.h"
27
#include "tree.h"
28
#include "expr.h"
29
#include "flags.h"
30
#include "cgraph.h"
31
#include "function.h"
32
#include "diagnostic.h"
33
#include "vec.h"
34
#include "bitmap.h"
35
#include "timevar.h"
36
#include "tree-flow.h"
37
#include "tree-pass.h"
38
#include "lto-streamer.h"
39
 
40
/* LTO fix-up.
41
 
42
   In WPA mode, LTO cannot access function bodies.  Some modifications in
43
   IR require additional updates in function bodies,  which are not possible
44
   in WPA mode.  So we write out information about these modifications for
45
   LTRANS to fix up the function bodies accordingly.  */
46
 
47
/* The vectors records function DECLs having multiple copies with different
48
   exception throwing attributes.  We do not mark a DECL if all copies of it
49
   have the same exception throwing attribute. */
50
static bitmap lto_nothrow_fndecls;
51
 
52
/* We need to fix up GIMPLE bodies due to changes in exception setting.
53
   Consider this example:
54
 
55
   a.h:
56
   class a {
57
   public:
58
     a();
59
     ~a();
60
   };
61
 
62
   main.cc:
63
   #include "a.h"
64
 
65
   int
66
   main (int argc, char **argv)
67
   {
68
     a x;
69
     return 0;
70
   }
71
 
72
   a.cc:
73
   #include "a.h"
74
   a::a() {}
75
   a::~a() {}
76
 
77
   When main.cc is compiled, gcc only sees the constructor declaration, so
78
   the constructor and hence the call to it are marked as exception throwing.
79
   When a.cc is compiled, the body of the constructor is available and is
80
   obviously not exception throwing. Thus DECL of a::a in a.o has the NOTHROW
81
   attribute.  When LTO runs, two DECLs of a::a with different exception
82
   attributes are merged.  We want the merged DECL to be not exception
83
   throwing for better generated code.  To do that, we need to fix up any
84
   function calls that have been marked as exception throwing.  */
85
 
86
/* Fix up all the call statements whose target fndecls might have changed
87
   to NOTHROW.   Note that this problem is not WPA specific.  We can also
88
   run into this problem in normal LTO with multiple input files.  */
89
 
90
void
91
lto_fixup_nothrow_decls (void)
92
{
93
  struct cgraph_node *node;
94
  struct cgraph_edge *edge;
95
  struct function *caller_function;
96
  gimple call_stmt;
97
 
98
  /* Quit if we are in WPA mode or have not marked any DECLs.  */
99
  if (flag_wpa || !lto_nothrow_fndecls)
100
    return;
101
 
102
  /* For each node that has been marked, go over all call edges to it.  */
103
  for (node = cgraph_nodes; node; node = node->next)
104
    if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (node->decl)))
105
      {
106
        gcc_assert (TREE_NOTHROW (node->decl));
107
        for (edge = node->callers; edge; edge = edge->next_caller)
108
          {
109
            caller_function = DECL_STRUCT_FUNCTION (edge->caller->decl);
110
            call_stmt = edge->call_stmt;
111
            gcc_assert (call_stmt);
112
            if (lookup_stmt_eh_lp_fn (caller_function, call_stmt) != 0)
113
              remove_stmt_from_eh_lp_fn (caller_function, call_stmt);
114
          }
115
      }
116
}
117
 
118
/* Mark FNDECL as becoming not exception throwing.  */
119
 
120
void
121
lto_mark_nothrow_fndecl (tree fndecl)
122
{
123
  gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
124
  if (!lto_nothrow_fndecls)
125
    lto_nothrow_fndecls = lto_bitmap_alloc ();
126
 
127
  bitmap_set_bit (lto_nothrow_fndecls, DECL_UID (fndecl));
128
}
129
 
130
/* Write out fix-up information.  Currently the only WPA fix-up
131
   information is the list of DECLs marked as not exception throwing. SET
132
   is a cgraph node set whose fix-up information is to be written.  */
133
 
134
static void
135
lto_output_wpa_fixup (cgraph_node_set set)
136
{
137
  struct lto_simple_output_block *ob;
138
  cgraph_node_set_iterator csi;
139
  tree fndecl;
140
  bitmap seen_decls;
141
  VEC(tree, heap) *decls = NULL;
142
  unsigned HOST_WIDE_INT i, count;
143
 
144
  ob = lto_create_simple_output_block (LTO_section_wpa_fixup);
145
 
146
  /* Accumulate the DECLs to be written out.  Since we do not want
147
     duplicates, we need to use a bitmap and a vector to save the
148
     DECLs we want.  Note that we need to check if lto_nothrow_fndecls
149
     is NULL.  This happens when no DECL has been marked.  */
150
  seen_decls = lto_bitmap_alloc ();
151
  if (lto_nothrow_fndecls)
152
    for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
153
      {
154
        struct cgraph_edge *e;
155
        struct cgraph_node *n;
156
 
157
        n = csi_node (csi);
158
        fndecl = n->decl;
159
 
160
        /* Check if the N's function is in the set of nothrow functions.  */
161
        if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl)))
162
          {
163
            bitmap_set_bit (seen_decls, (DECL_UID (fndecl)));
164
            if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl)))
165
              VEC_safe_push (tree, heap, decls, fndecl);
166
          }
167
 
168
        /* Now check the callees and also add them if they are nothrow.  This
169
           is needed because node N may end up in a different partition than
170
           its callees.  In which case, when the file holding N is compiled,
171
           the calls it makes to nothrow functions will not be fixed up,
172
           causing verification issues.  */
173
        for (e = n->callees; e; e = e->next_callee)
174
          {
175
            fndecl = e->callee->decl;
176
            if (!bitmap_bit_p (seen_decls, DECL_UID (fndecl)))
177
              {
178
                bitmap_set_bit (seen_decls, (DECL_UID (fndecl)));
179
                if (bitmap_bit_p (lto_nothrow_fndecls, DECL_UID (fndecl)))
180
                  VEC_safe_push (tree, heap, decls, fndecl);
181
              }
182
          }
183
      }
184
 
185
  /* Write out number of DECLs, followed by the DECLs.  */
186
  count = VEC_length (tree, decls);
187
  lto_output_uleb128_stream (ob->main_stream, count);
188
  for (i = 0; i < count; i++)
189
    {
190
      fndecl = VEC_index (tree, decls, i);
191
      lto_output_fn_decl_index (ob->decl_state, ob->main_stream, fndecl);
192
    }
193
 
194
  /* Release resources.  */
195
  lto_destroy_simple_output_block (ob);
196
  VEC_free(tree, heap, decls);
197
  lto_bitmap_free (seen_decls);
198
}
199
 
200
/* Read in WPA fix-up information from one file. FILE_DATA points to
201
   DECL information of the file where as IB is the input block for the
202
   WPA fix-up section.  */
203
 
204
static void
205
lto_input_wpa_fixup_1 (struct lto_file_decl_data *file_data,
206
                   struct lto_input_block *ib)
207
{
208
  unsigned HOST_WIDE_INT i, count, decl_index;
209
  tree fndecl;
210
 
211
  count = lto_input_uleb128 (ib);
212
  for (i = 0; i < count; i++)
213
    {
214
      decl_index = lto_input_uleb128 (ib);
215
      fndecl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
216
      lto_mark_nothrow_fndecl (fndecl);
217
    }
218
}
219
 
220
/* Read in WPA fix-up information. */
221
 
222
static void
223
lto_input_wpa_fixup (void)
224
{
225
  struct lto_file_decl_data ** file_data_vec
226
    = lto_get_file_decl_data ();
227
  struct lto_file_decl_data * file_data;
228
  int i = 0;
229
 
230
  /* Fix up information is only used in LTRANS mode.  */
231
  if (!flag_ltrans)
232
    return;
233
 
234
  while ((file_data = file_data_vec[i++]))
235
    {
236
      const char *data;
237
      size_t len;
238
      struct lto_input_block *ib
239
        = lto_create_simple_input_block (file_data, LTO_section_wpa_fixup,
240
                                         &data, &len);
241
 
242
      lto_input_wpa_fixup_1 (file_data, ib);
243
      lto_destroy_simple_input_block (file_data, LTO_section_wpa_fixup, ib,
244
                                      data, len);
245
    }
246
}
247
 
248
/* Gate function for all lto streaming passes.  */
249
 
250
static bool
251
gate_wpa_fixup (void)
252
{
253
  return (flag_wpa || flag_ltrans) && gate_lto_out ();
254
}
255
 
256
struct ipa_opt_pass_d pass_ipa_lto_wpa_fixup =
257
{
258
 {
259
  IPA_PASS,
260
  "lto_wpa_fixup",                      /* name */
261
  gate_wpa_fixup,                       /* gate */
262
  NULL,                                 /* execute */
263
  NULL,                                 /* sub */
264
  NULL,                                 /* next */
265
  0,                                     /* static_pass_number */
266
  TV_WHOPR_WPA_FIXUP,                   /* tv_id */
267
  0,                                     /* properties_required */
268
  0,                                     /* properties_provided */
269
  0,                                     /* properties_destroyed */
270
  0,                             /* todo_flags_start */
271
  TODO_dump_func                        /* todo_flags_finish */
272
 },
273
 NULL,                                  /* generate_summary */
274
 lto_output_wpa_fixup,                  /* write_summary */
275
 lto_input_wpa_fixup,                   /* read_summary */
276
 NULL,                                  /* function_read_summary */
277
 NULL,                                  /* stmt_fixup */
278
 0,                                      /* TODOs */
279
 NULL,                                  /* function_transform */
280
 NULL                                   /* variable_transform */
281
};
282
 

powered by: WebSVN 2.1.0

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