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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [ipa-prop.c] - Blame information for rev 378

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Interprocedural analyses.
2
   Copyright (C) 2005, 2007, 2008, 2009, 2010
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 under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 3, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tree.h"
25
#include "langhooks.h"
26
#include "ggc.h"
27
#include "target.h"
28
#include "cgraph.h"
29
#include "ipa-prop.h"
30
#include "tree-flow.h"
31
#include "tree-pass.h"
32
#include "tree-inline.h"
33
#include "flags.h"
34
#include "timevar.h"
35
#include "flags.h"
36
#include "diagnostic.h"
37
#include "lto-streamer.h"
38
 
39
/* Vector where the parameter infos are actually stored. */
40
VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
41
/* Vector where the parameter infos are actually stored. */
42
VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
43
 
44
/* Holders of ipa cgraph hooks: */
45
static struct cgraph_edge_hook_list *edge_removal_hook_holder;
46
static struct cgraph_node_hook_list *node_removal_hook_holder;
47
static struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
48
static struct cgraph_2node_hook_list *node_duplication_hook_holder;
49
 
50
/* Add cgraph NODE described by INFO to the worklist WL regardless of whether
51
   it is in one or not.  It should almost never be used directly, as opposed to
52
   ipa_push_func_to_list.  */
53
 
54
void
55
ipa_push_func_to_list_1 (struct ipa_func_list **wl,
56
                         struct cgraph_node *node,
57
                         struct ipa_node_params *info)
58
{
59
  struct ipa_func_list *temp;
60
 
61
  info->node_enqueued = 1;
62
  temp = XCNEW (struct ipa_func_list);
63
  temp->node = node;
64
  temp->next = *wl;
65
  *wl = temp;
66
}
67
 
68
/* Initialize worklist to contain all functions.  */
69
 
70
struct ipa_func_list *
71
ipa_init_func_list (void)
72
{
73
  struct cgraph_node *node;
74
  struct ipa_func_list * wl;
75
 
76
  wl = NULL;
77
  for (node = cgraph_nodes; node; node = node->next)
78
    if (node->analyzed)
79
      {
80
        struct ipa_node_params *info = IPA_NODE_REF (node);
81
        /* Unreachable nodes should have been eliminated before ipcp and
82
           inlining.  */
83
        gcc_assert (node->needed || node->reachable);
84
        ipa_push_func_to_list_1 (&wl, node, info);
85
      }
86
 
87
  return wl;
88
}
89
 
90
/* Remove a function from the worklist WL and return it.  */
91
 
92
struct cgraph_node *
93
ipa_pop_func_from_list (struct ipa_func_list **wl)
94
{
95
  struct ipa_node_params *info;
96
  struct ipa_func_list *first;
97
  struct cgraph_node *node;
98
 
99
  first = *wl;
100
  *wl = (*wl)->next;
101
  node = first->node;
102
  free (first);
103
 
104
  info = IPA_NODE_REF (node);
105
  info->node_enqueued = 0;
106
  return node;
107
}
108
 
109
/* Return index of the formal whose tree is PTREE in function which corresponds
110
   to INFO.  */
111
 
112
static int
113
ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
114
{
115
  int i, count;
116
 
117
  count = ipa_get_param_count (info);
118
  for (i = 0; i < count; i++)
119
    if (ipa_get_param(info, i) == ptree)
120
      return i;
121
 
122
  return -1;
123
}
124
 
125
/* Populate the param_decl field in parameter descriptors of INFO that
126
   corresponds to NODE.  */
127
 
128
static void
129
ipa_populate_param_decls (struct cgraph_node *node,
130
                          struct ipa_node_params *info)
131
{
132
  tree fndecl;
133
  tree fnargs;
134
  tree parm;
135
  int param_num;
136
 
137
  fndecl = node->decl;
138
  fnargs = DECL_ARGUMENTS (fndecl);
139
  param_num = 0;
140
  for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
141
    {
142
      info->params[param_num].decl = parm;
143
      param_num++;
144
    }
145
}
146
 
147
/* Return how many formal parameters FNDECL has.  */
148
 
149
static inline int
150
count_formal_params_1 (tree fndecl)
151
{
152
  tree parm;
153
  int count = 0;
154
 
155
  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
156
    count++;
157
 
158
  return count;
159
}
160
 
161
/* Count number of formal parameters in NOTE. Store the result to the
162
   appropriate field of INFO.  */
163
 
164
static void
165
ipa_count_formal_params (struct cgraph_node *node,
166
                         struct ipa_node_params *info)
167
{
168
  int param_num;
169
 
170
  param_num = count_formal_params_1 (node->decl);
171
  ipa_set_param_count (info, param_num);
172
}
173
 
174
/* Initialize the ipa_node_params structure associated with NODE by counting
175
   the function parameters, creating the descriptors and populating their
176
   param_decls.  */
177
 
178
void
179
ipa_initialize_node_params (struct cgraph_node *node)
180
{
181
  struct ipa_node_params *info = IPA_NODE_REF (node);
182
 
183
  if (!info->params)
184
    {
185
      ipa_count_formal_params (node, info);
186
      info->params = XCNEWVEC (struct ipa_param_descriptor,
187
                                    ipa_get_param_count (info));
188
      ipa_populate_param_decls (node, info);
189
    }
190
}
191
 
192
/* Callback of walk_stmt_load_store_addr_ops for the visit_store and visit_addr
193
   parameters.  If OP is a parameter declaration, mark it as modified in the
194
   info structure passed in DATA.  */
195
 
196
static bool
197
visit_store_addr_for_mod_analysis (gimple stmt ATTRIBUTE_UNUSED,
198
                                   tree op, void *data)
199
{
200
  struct ipa_node_params *info = (struct ipa_node_params *) data;
201
 
202
  if (TREE_CODE (op) == PARM_DECL)
203
    {
204
      int index = ipa_get_param_decl_index (info, op);
205
      gcc_assert (index >= 0);
206
      info->params[index].modified = true;
207
    }
208
 
209
  return false;
210
}
211
 
212
/* Compute which formal parameters of function associated with NODE are locally
213
   modified or their address is taken.  Note that this does not apply on
214
   parameters with SSA names but those can and should be analyzed
215
   differently.  */
216
 
217
void
218
ipa_detect_param_modifications (struct cgraph_node *node)
219
{
220
  tree decl = node->decl;
221
  basic_block bb;
222
  struct function *func;
223
  gimple_stmt_iterator gsi;
224
  struct ipa_node_params *info = IPA_NODE_REF (node);
225
 
226
  if (ipa_get_param_count (info) == 0 || info->modification_analysis_done)
227
    return;
228
 
229
  func = DECL_STRUCT_FUNCTION (decl);
230
  FOR_EACH_BB_FN (bb, func)
231
    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
232
      walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info, NULL,
233
                                     visit_store_addr_for_mod_analysis,
234
                                     visit_store_addr_for_mod_analysis);
235
 
236
  info->modification_analysis_done = 1;
237
}
238
 
239
/* Count number of arguments callsite CS has and store it in
240
   ipa_edge_args structure corresponding to this callsite.  */
241
 
242
void
243
ipa_count_arguments (struct cgraph_edge *cs)
244
{
245
  gimple stmt;
246
  int arg_num;
247
 
248
  stmt = cs->call_stmt;
249
  gcc_assert (is_gimple_call (stmt));
250
  arg_num = gimple_call_num_args (stmt);
251
  if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
252
      <= (unsigned) cgraph_edge_max_uid)
253
    VEC_safe_grow_cleared (ipa_edge_args_t, gc,
254
                           ipa_edge_args_vector, cgraph_edge_max_uid + 1);
255
  ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
256
}
257
 
258
/* Print the jump functions of all arguments on all call graph edges going from
259
   NODE to file F.  */
260
 
261
void
262
ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
263
{
264
  int i, count;
265
  struct cgraph_edge *cs;
266
  struct ipa_jump_func *jump_func;
267
  enum jump_func_type type;
268
 
269
  fprintf (f, "  Jump functions of caller  %s:\n", cgraph_node_name (node));
270
  for (cs = node->callees; cs; cs = cs->next_callee)
271
    {
272
      if (!ipa_edge_args_info_available_for_edge_p (cs))
273
        continue;
274
 
275
      fprintf (f, "    callsite  %s ", cgraph_node_name (node));
276
      fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
277
 
278
      count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
279
      for (i = 0; i < count; i++)
280
        {
281
          jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
282
          type = jump_func->type;
283
 
284
          fprintf (f, "       param %d: ", i);
285
          if (type == IPA_JF_UNKNOWN)
286
            fprintf (f, "UNKNOWN\n");
287
          else if (type == IPA_JF_CONST)
288
            {
289
              tree val = jump_func->value.constant;
290
              fprintf (f, "CONST: ");
291
              print_generic_expr (f, val, 0);
292
              fprintf (f, "\n");
293
            }
294
          else if (type == IPA_JF_CONST_MEMBER_PTR)
295
            {
296
              fprintf (f, "CONST MEMBER PTR: ");
297
              print_generic_expr (f, jump_func->value.member_cst.pfn, 0);
298
              fprintf (f, ", ");
299
              print_generic_expr (f, jump_func->value.member_cst.delta, 0);
300
              fprintf (f, "\n");
301
            }
302
          else if (type == IPA_JF_PASS_THROUGH)
303
            {
304
              fprintf (f, "PASS THROUGH: ");
305
              fprintf (f, "%d, op %s ",
306
                       jump_func->value.pass_through.formal_id,
307
                       tree_code_name[(int)
308
                                      jump_func->value.pass_through.operation]);
309
              if (jump_func->value.pass_through.operation != NOP_EXPR)
310
                print_generic_expr (dump_file,
311
                                    jump_func->value.pass_through.operand, 0);
312
              fprintf (dump_file, "\n");
313
            }
314
          else if (type == IPA_JF_ANCESTOR)
315
            {
316
              fprintf (f, "ANCESTOR: ");
317
              fprintf (f, "%d, offset "HOST_WIDE_INT_PRINT_DEC"\n",
318
                       jump_func->value.ancestor.formal_id,
319
                       jump_func->value.ancestor.offset);
320
            }
321
        }
322
    }
323
}
324
 
325
/* Print ipa_jump_func data structures of all nodes in the call graph to F.  */
326
 
327
void
328
ipa_print_all_jump_functions (FILE *f)
329
{
330
  struct cgraph_node *node;
331
 
332
  fprintf (f, "\nJump functions:\n");
333
  for (node = cgraph_nodes; node; node = node->next)
334
    {
335
      ipa_print_node_jump_functions (f, node);
336
    }
337
}
338
 
339
/* Determine whether passing ssa name NAME constitutes a polynomial
340
   pass-through function or getting an address of an acestor and if so, write
341
   such a jump function to JFUNC.  INFO describes the caller.  */
342
 
343
static void
344
compute_complex_pass_through (struct ipa_node_params *info,
345
                              struct ipa_jump_func *jfunc,
346
                              tree name)
347
{
348
  HOST_WIDE_INT offset, size, max_size;
349
  tree op1, op2, type;
350
  int index;
351
  gimple stmt = SSA_NAME_DEF_STMT (name);
352
 
353
  if (!is_gimple_assign (stmt))
354
    return;
355
  op1 = gimple_assign_rhs1 (stmt);
356
  op2 = gimple_assign_rhs2 (stmt);
357
 
358
  if (op2)
359
    {
360
      if (TREE_CODE (op1) != SSA_NAME
361
          || !SSA_NAME_IS_DEFAULT_DEF (op1)
362
          || (TREE_CODE_CLASS (gimple_expr_code (stmt)) != tcc_comparison
363
              && !useless_type_conversion_p (TREE_TYPE (name),
364
                                             TREE_TYPE (op1)))
365
          || !is_gimple_ip_invariant (op2))
366
        return;
367
 
368
      index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
369
      if (index >= 0)
370
        {
371
          jfunc->type = IPA_JF_PASS_THROUGH;
372
          jfunc->value.pass_through.formal_id = index;
373
          jfunc->value.pass_through.operation = gimple_assign_rhs_code (stmt);
374
          jfunc->value.pass_through.operand = op2;
375
        }
376
      return;
377
    }
378
 
379
  if (TREE_CODE (op1) != ADDR_EXPR)
380
    return;
381
  op1 = TREE_OPERAND (op1, 0);
382
  type = TREE_TYPE (op1);
383
 
384
  op1 = get_ref_base_and_extent (op1, &offset, &size, &max_size);
385
  if (TREE_CODE (op1) != INDIRECT_REF
386
      /* If this is a varying address, punt.  */
387
      || max_size == -1
388
      || max_size != size)
389
    return;
390
  op1 = TREE_OPERAND (op1, 0);
391
  if (TREE_CODE (op1) != SSA_NAME
392
      || !SSA_NAME_IS_DEFAULT_DEF (op1))
393
    return;
394
 
395
  index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
396
  if (index >= 0)
397
    {
398
      jfunc->type = IPA_JF_ANCESTOR;
399
      jfunc->value.ancestor.formal_id = index;
400
      jfunc->value.ancestor.offset = offset;
401
      jfunc->value.ancestor.type = type;
402
    }
403
}
404
 
405
 
406
/* Determine the jump functions of scalar arguments.  Scalar means SSA names
407
   and constants of a number of selected types.  INFO is the ipa_node_params
408
   structure associated with the caller, FUNCTIONS is a pointer to an array of
409
   jump function structures associated with CALL which is the call statement
410
   being examined.*/
411
 
412
static void
413
compute_scalar_jump_functions (struct ipa_node_params *info,
414
                               struct ipa_jump_func *functions,
415
                               gimple call)
416
{
417
  tree arg;
418
  unsigned num = 0;
419
 
420
  for (num = 0; num < gimple_call_num_args (call); num++)
421
    {
422
      arg = gimple_call_arg (call, num);
423
 
424
      if (is_gimple_ip_invariant (arg))
425
        {
426
          functions[num].type = IPA_JF_CONST;
427
          functions[num].value.constant = arg;
428
        }
429
      else if (TREE_CODE (arg) == SSA_NAME)
430
        {
431
          if (SSA_NAME_IS_DEFAULT_DEF (arg))
432
            {
433
              int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
434
 
435
              if (index >= 0)
436
                {
437
                  functions[num].type = IPA_JF_PASS_THROUGH;
438
                  functions[num].value.pass_through.formal_id = index;
439
                  functions[num].value.pass_through.operation = NOP_EXPR;
440
                }
441
            }
442
          else
443
            compute_complex_pass_through (info, &functions[num], arg);
444
        }
445
    }
446
}
447
 
448
/* Inspect the given TYPE and return true iff it has the same structure (the
449
   same number of fields of the same types) as a C++ member pointer.  If
450
   METHOD_PTR and DELTA are non-NULL, store the trees representing the
451
   corresponding fields there.  */
452
 
453
static bool
454
type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
455
{
456
  tree fld;
457
 
458
  if (TREE_CODE (type) != RECORD_TYPE)
459
    return false;
460
 
461
  fld = TYPE_FIELDS (type);
462
  if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
463
      || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE)
464
    return false;
465
 
466
  if (method_ptr)
467
    *method_ptr = fld;
468
 
469
  fld = TREE_CHAIN (fld);
470
  if (!fld || INTEGRAL_TYPE_P (fld))
471
    return false;
472
  if (delta)
473
    *delta = fld;
474
 
475
  if (TREE_CHAIN (fld))
476
    return false;
477
 
478
  return true;
479
}
480
 
481
/* Go through arguments of the CALL and for every one that looks like a member
482
   pointer, check whether it can be safely declared pass-through and if so,
483
   mark that to the corresponding item of jump FUNCTIONS.  Return true iff
484
   there are non-pass-through member pointers within the arguments.  INFO
485
   describes formal parameters of the caller.  */
486
 
487
static bool
488
compute_pass_through_member_ptrs (struct ipa_node_params *info,
489
                                  struct ipa_jump_func *functions,
490
                                  gimple call)
491
{
492
  bool undecided_members = false;
493
  unsigned num;
494
  tree arg;
495
 
496
  for (num = 0; num < gimple_call_num_args (call); num++)
497
    {
498
      arg = gimple_call_arg (call, num);
499
 
500
      if (type_like_member_ptr_p (TREE_TYPE (arg), NULL, NULL))
501
        {
502
          if (TREE_CODE (arg) == PARM_DECL)
503
            {
504
              int index = ipa_get_param_decl_index (info, arg);
505
 
506
              gcc_assert (index >=0);
507
              if (!ipa_is_param_modified (info, index))
508
                {
509
                  functions[num].type = IPA_JF_PASS_THROUGH;
510
                  functions[num].value.pass_through.formal_id = index;
511
                  functions[num].value.pass_through.operation = NOP_EXPR;
512
                }
513
              else
514
                undecided_members = true;
515
            }
516
          else
517
            undecided_members = true;
518
        }
519
    }
520
 
521
  return undecided_members;
522
}
523
 
524
/* Simple function filling in a member pointer constant jump function (with PFN
525
   and DELTA as the constant value) into JFUNC.  */
526
 
527
static void
528
fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc,
529
                                   tree pfn, tree delta)
530
{
531
  jfunc->type = IPA_JF_CONST_MEMBER_PTR;
532
  jfunc->value.member_cst.pfn = pfn;
533
  jfunc->value.member_cst.delta = delta;
534
}
535
 
536
/* If RHS is an SSA_NAMe and it is defined by a simple copy assign statement,
537
   return the rhs of its defining statement.  */
538
 
539
static inline tree
540
get_ssa_def_if_simple_copy (tree rhs)
541
{
542
  while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
543
    {
544
      gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
545
 
546
      if (gimple_assign_single_p (def_stmt))
547
        rhs = gimple_assign_rhs1 (def_stmt);
548
      else
549
        break;
550
    }
551
  return rhs;
552
}
553
 
554
/* Traverse statements from CALL backwards, scanning whether the argument ARG
555
   which is a member pointer is filled in with constant values.  If it is, fill
556
   the jump function JFUNC in appropriately.  METHOD_FIELD and DELTA_FIELD are
557
   fields of the record type of the member pointer.  To give an example, we
558
   look for a pattern looking like the following:
559
 
560
     D.2515.__pfn ={v} printStuff;
561
     D.2515.__delta ={v} 0;
562
     i_1 = doprinting (D.2515);  */
563
 
564
static void
565
determine_cst_member_ptr (gimple call, tree arg, tree method_field,
566
                          tree delta_field, struct ipa_jump_func *jfunc)
567
{
568
  gimple_stmt_iterator gsi;
569
  tree method = NULL_TREE;
570
  tree delta = NULL_TREE;
571
 
572
  gsi = gsi_for_stmt (call);
573
 
574
  gsi_prev (&gsi);
575
  for (; !gsi_end_p (gsi); gsi_prev (&gsi))
576
    {
577
      gimple stmt = gsi_stmt (gsi);
578
      tree lhs, rhs, fld;
579
 
580
      if (!gimple_assign_single_p (stmt))
581
        return;
582
 
583
      lhs = gimple_assign_lhs (stmt);
584
      rhs = gimple_assign_rhs1 (stmt);
585
 
586
      if (TREE_CODE (lhs) != COMPONENT_REF
587
          || TREE_OPERAND (lhs, 0) != arg)
588
        continue;
589
 
590
      fld = TREE_OPERAND (lhs, 1);
591
      if (!method && fld == method_field)
592
        {
593
          rhs = get_ssa_def_if_simple_copy (rhs);
594
          if (TREE_CODE (rhs) == ADDR_EXPR
595
              && TREE_CODE (TREE_OPERAND (rhs, 0)) == FUNCTION_DECL
596
              && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) == METHOD_TYPE)
597
            {
598
              method = TREE_OPERAND (rhs, 0);
599
              if (delta)
600
                {
601
                  fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
602
                  return;
603
                }
604
            }
605
          else
606
            return;
607
        }
608
 
609
      if (!delta && fld == delta_field)
610
        {
611
          rhs = get_ssa_def_if_simple_copy (rhs);
612
          if (TREE_CODE (rhs) == INTEGER_CST)
613
            {
614
              delta = rhs;
615
              if (method)
616
                {
617
                  fill_member_ptr_cst_jump_function (jfunc, rhs, delta);
618
                  return;
619
                }
620
            }
621
          else
622
            return;
623
        }
624
    }
625
 
626
  return;
627
}
628
 
629
/* Go through the arguments of the CALL and for every member pointer within
630
   tries determine whether it is a constant.  If it is, create a corresponding
631
   constant jump function in FUNCTIONS which is an array of jump functions
632
   associated with the call.  */
633
 
634
static void
635
compute_cst_member_ptr_arguments (struct ipa_jump_func *functions,
636
                                  gimple call)
637
{
638
  unsigned num;
639
  tree arg, method_field, delta_field;
640
 
641
  for (num = 0; num < gimple_call_num_args (call); num++)
642
    {
643
      arg = gimple_call_arg (call, num);
644
 
645
      if (functions[num].type == IPA_JF_UNKNOWN
646
          && type_like_member_ptr_p (TREE_TYPE (arg), &method_field,
647
                                     &delta_field))
648
        determine_cst_member_ptr (call, arg, method_field, delta_field,
649
                                  &functions[num]);
650
    }
651
}
652
 
653
/* Compute jump function for all arguments of callsite CS and insert the
654
   information in the jump_functions array in the ipa_edge_args corresponding
655
   to this callsite.  */
656
 
657
void
658
ipa_compute_jump_functions (struct cgraph_edge *cs)
659
{
660
  struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
661
  struct ipa_edge_args *arguments = IPA_EDGE_REF (cs);
662
  gimple call;
663
 
664
  if (ipa_get_cs_argument_count (arguments) == 0 || arguments->jump_functions)
665
    return;
666
  arguments->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
667
                                           ipa_get_cs_argument_count (arguments));
668
 
669
  call = cs->call_stmt;
670
  gcc_assert (is_gimple_call (call));
671
 
672
  /* We will deal with constants and SSA scalars first:  */
673
  compute_scalar_jump_functions (info, arguments->jump_functions, call);
674
 
675
  /* Let's check whether there are any potential member pointers and if so,
676
     whether we can determine their functions as pass_through.  */
677
  if (!compute_pass_through_member_ptrs (info, arguments->jump_functions, call))
678
    return;
679
 
680
  /* Finally, let's check whether we actually pass a new constant member
681
     pointer here...  */
682
  compute_cst_member_ptr_arguments (arguments->jump_functions, call);
683
}
684
 
685
/* If RHS looks like a rhs of a statement loading pfn from a member
686
   pointer formal parameter, return the parameter, otherwise return
687
   NULL.  If USE_DELTA, then we look for a use of the delta field
688
   rather than the pfn.  */
689
 
690
static tree
691
ipa_get_member_ptr_load_param (tree rhs, bool use_delta)
692
{
693
  tree rec, fld;
694
  tree ptr_field;
695
  tree delta_field;
696
 
697
  if (TREE_CODE (rhs) != COMPONENT_REF)
698
    return NULL_TREE;
699
 
700
  rec = TREE_OPERAND (rhs, 0);
701
  if (TREE_CODE (rec) != PARM_DECL
702
      || !type_like_member_ptr_p (TREE_TYPE (rec), &ptr_field, &delta_field))
703
    return NULL_TREE;
704
 
705
  fld = TREE_OPERAND (rhs, 1);
706
  if (use_delta ? (fld == delta_field) : (fld == ptr_field))
707
    return rec;
708
  else
709
    return NULL_TREE;
710
}
711
 
712
/* If STMT looks like a statement loading a value from a member pointer formal
713
   parameter, this function returns that parameter.  */
714
 
715
static tree
716
ipa_get_stmt_member_ptr_load_param (gimple stmt, bool use_delta)
717
{
718
  tree rhs;
719
 
720
  if (!gimple_assign_single_p (stmt))
721
    return NULL_TREE;
722
 
723
  rhs = gimple_assign_rhs1 (stmt);
724
  return ipa_get_member_ptr_load_param (rhs, use_delta);
725
}
726
 
727
/* Returns true iff T is an SSA_NAME defined by a statement.  */
728
 
729
static bool
730
ipa_is_ssa_with_stmt_def (tree t)
731
{
732
  if (TREE_CODE (t) == SSA_NAME
733
      && !SSA_NAME_IS_DEFAULT_DEF (t))
734
    return true;
735
  else
736
    return false;
737
}
738
 
739
/* Creates a new note describing a call to a parameter number FORMAL_ID and
740
   attaches it to the linked list of INFO.  It also sets the called flag of the
741
   parameter.  STMT is the corresponding call statement.  */
742
 
743
static void
744
ipa_note_param_call (struct ipa_node_params *info, int formal_id,
745
                     gimple stmt)
746
{
747
  struct ipa_param_call_note *note;
748
  basic_block bb = gimple_bb (stmt);
749
 
750
  note = XCNEW (struct ipa_param_call_note);
751
  note->formal_id = formal_id;
752
  note->stmt = stmt;
753
  note->lto_stmt_uid = gimple_uid (stmt);
754
  note->count = bb->count;
755
  note->frequency = compute_call_stmt_bb_frequency (current_function_decl, bb);
756
  note->loop_nest = bb->loop_depth;
757
 
758
  note->next = info->param_calls;
759
  info->param_calls = note;
760
 
761
  return;
762
}
763
 
764
/* Analyze the CALL and examine uses of formal parameters of the caller
765
   (described by INFO).  Currently it checks whether the call calls a pointer
766
   that is a formal parameter and if so, the parameter is marked with the
767
   called flag and a note describing the call is created.  This is very simple
768
   for ordinary pointers represented in SSA but not-so-nice when it comes to
769
   member pointers.  The ugly part of this function does nothing more than
770
   tries to match the pattern of such a call.  An example of such a pattern is
771
   the gimple dump below, the call is on the last line:
772
 
773
     <bb 2>:
774
       f$__delta_5 = f.__delta;
775
       f$__pfn_24 = f.__pfn;
776
       D.2496_3 = (int) f$__pfn_24;
777
       D.2497_4 = D.2496_3 & 1;
778
       if (D.2497_4 != 0)
779
         goto <bb 3>;
780
       else
781
         goto <bb 4>;
782
 
783
     <bb 3>:
784
       D.2500_7 = (unsigned int) f$__delta_5;
785
       D.2501_8 = &S + D.2500_7;
786
       D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
787
       D.2503_10 = *D.2502_9;
788
       D.2504_12 = f$__pfn_24 + -1;
789
       D.2505_13 = (unsigned int) D.2504_12;
790
       D.2506_14 = D.2503_10 + D.2505_13;
791
       D.2507_15 = *D.2506_14;
792
       iftmp.11_16 = (String:: *) D.2507_15;
793
 
794
     <bb 4>:
795
       # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
796
       D.2500_19 = (unsigned int) f$__delta_5;
797
       D.2508_20 = &S + D.2500_19;
798
       D.2493_21 = iftmp.11_1 (D.2508_20, 4);
799
 
800
   Such patterns are results of simple calls to a member pointer:
801
 
802
     int doprinting (int (MyString::* f)(int) const)
803
     {
804
       MyString S ("somestring");
805
 
806
       return (S.*f)(4);
807
     }
808
*/
809
 
810
static void
811
ipa_analyze_call_uses (struct ipa_node_params *info, gimple call)
812
{
813
  tree target = gimple_call_fn (call);
814
  gimple def;
815
  tree var;
816
  tree n1, n2;
817
  gimple d1, d2;
818
  tree rec, rec2, cond;
819
  gimple branch;
820
  int index;
821
  basic_block bb, virt_bb, join;
822
 
823
  if (TREE_CODE (target) != SSA_NAME)
824
    return;
825
 
826
  var = SSA_NAME_VAR (target);
827
  if (SSA_NAME_IS_DEFAULT_DEF (target))
828
    {
829
      /* assuming TREE_CODE (var) == PARM_DECL */
830
      index = ipa_get_param_decl_index (info, var);
831
      if (index >= 0)
832
        ipa_note_param_call (info, index, call);
833
      return;
834
    }
835
 
836
  /* Now we need to try to match the complex pattern of calling a member
837
     pointer. */
838
 
839
  if (!POINTER_TYPE_P (TREE_TYPE (target))
840
      || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
841
    return;
842
 
843
  def = SSA_NAME_DEF_STMT (target);
844
  if (gimple_code (def) != GIMPLE_PHI)
845
    return;
846
 
847
  if (gimple_phi_num_args (def) != 2)
848
    return;
849
 
850
  /* First, we need to check whether one of these is a load from a member
851
     pointer that is a parameter to this function. */
852
  n1 = PHI_ARG_DEF (def, 0);
853
  n2 = PHI_ARG_DEF (def, 1);
854
  if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
855
    return;
856
  d1 = SSA_NAME_DEF_STMT (n1);
857
  d2 = SSA_NAME_DEF_STMT (n2);
858
 
859
  if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false)))
860
    {
861
      if (ipa_get_stmt_member_ptr_load_param (d2, false))
862
        return;
863
 
864
      bb = gimple_bb (d1);
865
      virt_bb = gimple_bb (d2);
866
    }
867
  else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false)))
868
    {
869
      bb = gimple_bb (d2);
870
      virt_bb = gimple_bb (d1);
871
    }
872
  else
873
    return;
874
 
875
  /* Second, we need to check that the basic blocks are laid out in the way
876
     corresponding to the pattern. */
877
 
878
  join = gimple_bb (def);
879
  if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
880
      || single_pred (virt_bb) != bb
881
      || single_succ (virt_bb) != join)
882
    return;
883
 
884
  /* Third, let's see that the branching is done depending on the least
885
     significant bit of the pfn. */
886
 
887
  branch = last_stmt (bb);
888
  if (gimple_code (branch) != GIMPLE_COND)
889
    return;
890
 
891
  if (gimple_cond_code (branch) != NE_EXPR
892
      || !integer_zerop (gimple_cond_rhs (branch)))
893
    return;
894
 
895
  cond = gimple_cond_lhs (branch);
896
  if (!ipa_is_ssa_with_stmt_def (cond))
897
    return;
898
 
899
  def = SSA_NAME_DEF_STMT (cond);
900
  if (!is_gimple_assign (def)
901
      || gimple_assign_rhs_code (def) != BIT_AND_EXPR
902
      || !integer_onep (gimple_assign_rhs2 (def)))
903
    return;
904
 
905
  cond = gimple_assign_rhs1 (def);
906
  if (!ipa_is_ssa_with_stmt_def (cond))
907
    return;
908
 
909
  def = SSA_NAME_DEF_STMT (cond);
910
 
911
  if (is_gimple_assign (def)
912
      && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
913
    {
914
      cond = gimple_assign_rhs1 (def);
915
      if (!ipa_is_ssa_with_stmt_def (cond))
916
        return;
917
      def = SSA_NAME_DEF_STMT (cond);
918
    }
919
 
920
  rec2 = ipa_get_stmt_member_ptr_load_param (def,
921
                                             (TARGET_PTRMEMFUNC_VBIT_LOCATION
922
                                              == ptrmemfunc_vbit_in_delta));
923
 
924
  if (rec != rec2)
925
    return;
926
 
927
  index = ipa_get_param_decl_index (info, rec);
928
  if (index >= 0 && !ipa_is_param_modified (info, index))
929
    ipa_note_param_call (info, index, call);
930
 
931
  return;
932
}
933
 
934
/* Analyze the statement STMT with respect to formal parameters (described in
935
   INFO) and their uses.  Currently it only checks whether formal parameters
936
   are called.  */
937
 
938
static void
939
ipa_analyze_stmt_uses (struct ipa_node_params *info, gimple stmt)
940
{
941
  if (is_gimple_call (stmt))
942
    ipa_analyze_call_uses (info, stmt);
943
}
944
 
945
/* Scan the function body of NODE and inspect the uses of formal parameters.
946
   Store the findings in various structures of the associated ipa_node_params
947
   structure, such as parameter flags, notes etc.  */
948
 
949
void
950
ipa_analyze_params_uses (struct cgraph_node *node)
951
{
952
  tree decl = node->decl;
953
  basic_block bb;
954
  struct function *func;
955
  gimple_stmt_iterator gsi;
956
  struct ipa_node_params *info = IPA_NODE_REF (node);
957
 
958
  if (ipa_get_param_count (info) == 0 || info->uses_analysis_done)
959
    return;
960
 
961
  func = DECL_STRUCT_FUNCTION (decl);
962
  FOR_EACH_BB_FN (bb, func)
963
    {
964
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
965
        {
966
          gimple stmt = gsi_stmt (gsi);
967
          ipa_analyze_stmt_uses (info, stmt);
968
        }
969
    }
970
 
971
  info->uses_analysis_done = 1;
972
}
973
 
974
/* Update the jump functions associated with call graph edge E when the call
975
   graph edge CS is being inlined, assuming that E->caller is already (possibly
976
   indirectly) inlined into CS->callee and that E has not been inlined.
977
 
978
   We keep pass through functions only if they do not contain any operation.
979
   This is sufficient for inlining and greately simplifies things.  */
980
 
981
static void
982
update_jump_functions_after_inlining (struct cgraph_edge *cs,
983
                                      struct cgraph_edge *e)
984
{
985
  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
986
  struct ipa_edge_args *args = IPA_EDGE_REF (e);
987
  int count = ipa_get_cs_argument_count (args);
988
  int i;
989
 
990
  for (i = 0; i < count; i++)
991
    {
992
      struct ipa_jump_func *src, *dst = ipa_get_ith_jump_func (args, i);
993
 
994
      if (dst->type == IPA_JF_ANCESTOR)
995
        {
996
          dst->type = IPA_JF_UNKNOWN;
997
          continue;
998
        }
999
 
1000
      if (dst->type != IPA_JF_PASS_THROUGH)
1001
        continue;
1002
 
1003
      /* We must check range due to calls with variable number of arguments and
1004
         we cannot combine jump functions with operations.  */
1005
      if (dst->value.pass_through.operation != NOP_EXPR
1006
          || (dst->value.pass_through.formal_id
1007
              >= ipa_get_cs_argument_count (top)))
1008
        {
1009
          dst->type = IPA_JF_UNKNOWN;
1010
          continue;
1011
        }
1012
 
1013
      src = ipa_get_ith_jump_func (top, dst->value.pass_through.formal_id);
1014
      *dst = *src;
1015
    }
1016
}
1017
 
1018
/* Print out a debug message to file F that we have discovered that an indirect
1019
   call described by NT is in fact a call of a known constant function described
1020
   by JFUNC.  NODE is the node where the call is.  */
1021
 
1022
static void
1023
print_edge_addition_message (FILE *f, struct ipa_param_call_note *nt,
1024
                             struct ipa_jump_func *jfunc,
1025
                             struct cgraph_node *node)
1026
{
1027
  fprintf (f, "ipa-prop: Discovered an indirect call to a known target (");
1028
  if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
1029
    {
1030
      print_node_brief (f, "", jfunc->value.member_cst.pfn, 0);
1031
      print_node_brief (f, ", ", jfunc->value.member_cst.delta, 0);
1032
    }
1033
  else
1034
    print_node_brief(f, "", jfunc->value.constant, 0);
1035
 
1036
  fprintf (f, ") in %s: ", cgraph_node_name (node));
1037
  print_gimple_stmt (f, nt->stmt, 2, TDF_SLIM);
1038
}
1039
 
1040
/* Update the param called notes associated with NODE when CS is being inlined,
1041
   assuming NODE is (potentially indirectly) inlined into CS->callee.
1042
   Moreover, if the callee is discovered to be constant, create a new cgraph
1043
   edge for it.  Newly discovered indirect edges will be added to *NEW_EDGES,
1044
   unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
1045
 
1046
static bool
1047
update_call_notes_after_inlining (struct cgraph_edge *cs,
1048
                                  struct cgraph_node *node,
1049
                                  VEC (cgraph_edge_p, heap) **new_edges)
1050
{
1051
  struct ipa_node_params *info = IPA_NODE_REF (node);
1052
  struct ipa_edge_args *top = IPA_EDGE_REF (cs);
1053
  struct ipa_param_call_note *nt;
1054
  bool res = false;
1055
 
1056
  for (nt = info->param_calls; nt; nt = nt->next)
1057
    {
1058
      struct ipa_jump_func *jfunc;
1059
 
1060
      if (nt->processed)
1061
        continue;
1062
 
1063
      /* We must check range due to calls with variable number of arguments:  */
1064
      if (nt->formal_id >= ipa_get_cs_argument_count (top))
1065
        {
1066
          nt->processed = true;
1067
          continue;
1068
        }
1069
 
1070
      jfunc = ipa_get_ith_jump_func (top, nt->formal_id);
1071
      if (jfunc->type == IPA_JF_PASS_THROUGH
1072
          && jfunc->value.pass_through.operation == NOP_EXPR)
1073
        nt->formal_id = jfunc->value.pass_through.formal_id;
1074
      else if (jfunc->type == IPA_JF_CONST
1075
               || jfunc->type == IPA_JF_CONST_MEMBER_PTR)
1076
        {
1077
          struct cgraph_node *callee;
1078
          struct cgraph_edge *new_indirect_edge;
1079
          tree decl;
1080
 
1081
          nt->processed = true;
1082
          if (jfunc->type == IPA_JF_CONST_MEMBER_PTR)
1083
            decl = jfunc->value.member_cst.pfn;
1084
          else
1085
            decl = jfunc->value.constant;
1086
 
1087
          if (TREE_CODE (decl) != ADDR_EXPR)
1088
            continue;
1089
          decl = TREE_OPERAND (decl, 0);
1090
 
1091
          if (TREE_CODE (decl) != FUNCTION_DECL)
1092
            continue;
1093
          callee = cgraph_node (decl);
1094
          if (!callee || !callee->local.inlinable)
1095
            continue;
1096
 
1097
          res = true;
1098
          if (dump_file)
1099
            print_edge_addition_message (dump_file, nt, jfunc, node);
1100
 
1101
          new_indirect_edge = cgraph_create_edge (node, callee, nt->stmt,
1102
                                                  nt->count, nt->frequency,
1103
                                                  nt->loop_nest);
1104
          new_indirect_edge->lto_stmt_uid = nt->lto_stmt_uid;
1105
          new_indirect_edge->indirect_call = 1;
1106
          ipa_check_create_edge_args ();
1107
          if (new_edges)
1108
            VEC_safe_push (cgraph_edge_p, heap, *new_edges, new_indirect_edge);
1109
          top = IPA_EDGE_REF (cs);
1110
        }
1111
      else
1112
        {
1113
          /* Ancestor jum functions and pass theoughs with operations should
1114
             not be used on parameters that then get called.  */
1115
          gcc_assert (jfunc->type == IPA_JF_UNKNOWN);
1116
          nt->processed = true;
1117
        }
1118
    }
1119
  return res;
1120
}
1121
 
1122
/* Recursively traverse subtree of NODE (including node) made of inlined
1123
   cgraph_edges when CS has been inlined and invoke
1124
   update_call_notes_after_inlining on all nodes and
1125
   update_jump_functions_after_inlining on all non-inlined edges that lead out
1126
   of this subtree.  Newly discovered indirect edges will be added to
1127
   *NEW_EDGES, unless NEW_EDGES is NULL.  Return true iff a new edge(s) were
1128
   created.  */
1129
 
1130
static bool
1131
propagate_info_to_inlined_callees (struct cgraph_edge *cs,
1132
                                   struct cgraph_node *node,
1133
                                   VEC (cgraph_edge_p, heap) **new_edges)
1134
{
1135
  struct cgraph_edge *e;
1136
  bool res;
1137
 
1138
  res = update_call_notes_after_inlining (cs, node, new_edges);
1139
 
1140
  for (e = node->callees; e; e = e->next_callee)
1141
    if (!e->inline_failed)
1142
      res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
1143
    else
1144
      update_jump_functions_after_inlining (cs, e);
1145
 
1146
  return res;
1147
}
1148
 
1149
/* Update jump functions and call note functions on inlining the call site CS.
1150
   CS is expected to lead to a node already cloned by
1151
   cgraph_clone_inline_nodes.  Newly discovered indirect edges will be added to
1152
   *NEW_EDGES, unless NEW_EDGES is NULL.  Return true iff a new edge(s) were +
1153
   created.  */
1154
 
1155
bool
1156
ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
1157
                                   VEC (cgraph_edge_p, heap) **new_edges)
1158
{
1159
  /* FIXME lto: We do not stream out indirect call information.  */
1160
  if (flag_wpa)
1161
    return false;
1162
 
1163
  /* Do nothing if the preparation phase has not been carried out yet
1164
     (i.e. during early inlining).  */
1165
  if (!ipa_node_params_vector)
1166
    return false;
1167
  gcc_assert (ipa_edge_args_vector);
1168
 
1169
  return propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
1170
}
1171
 
1172
/* Frees all dynamically allocated structures that the argument info points
1173
   to.  */
1174
 
1175
void
1176
ipa_free_edge_args_substructures (struct ipa_edge_args *args)
1177
{
1178
  if (args->jump_functions)
1179
    ggc_free (args->jump_functions);
1180
 
1181
  memset (args, 0, sizeof (*args));
1182
}
1183
 
1184
/* Free all ipa_edge structures.  */
1185
 
1186
void
1187
ipa_free_all_edge_args (void)
1188
{
1189
  int i;
1190
  struct ipa_edge_args *args;
1191
 
1192
  for (i = 0;
1193
       VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args);
1194
       i++)
1195
    ipa_free_edge_args_substructures (args);
1196
 
1197
  VEC_free (ipa_edge_args_t, gc, ipa_edge_args_vector);
1198
  ipa_edge_args_vector = NULL;
1199
}
1200
 
1201
/* Frees all dynamically allocated structures that the param info points
1202
   to.  */
1203
 
1204
void
1205
ipa_free_node_params_substructures (struct ipa_node_params *info)
1206
{
1207
  if (info->params)
1208
    free (info->params);
1209
 
1210
  while (info->param_calls)
1211
    {
1212
      struct ipa_param_call_note *note = info->param_calls;
1213
      info->param_calls = note->next;
1214
      free (note);
1215
    }
1216
 
1217
  memset (info, 0, sizeof (*info));
1218
}
1219
 
1220
/* Free all ipa_node_params structures.  */
1221
 
1222
void
1223
ipa_free_all_node_params (void)
1224
{
1225
  int i;
1226
  struct ipa_node_params *info;
1227
 
1228
  for (i = 0;
1229
       VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info);
1230
       i++)
1231
    ipa_free_node_params_substructures (info);
1232
 
1233
  VEC_free (ipa_node_params_t, heap, ipa_node_params_vector);
1234
  ipa_node_params_vector = NULL;
1235
}
1236
 
1237
/* Hook that is called by cgraph.c when an edge is removed.  */
1238
 
1239
static void
1240
ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
1241
{
1242
  /* During IPA-CP updating we can be called on not-yet analyze clones.  */
1243
  if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
1244
      <= (unsigned)cs->uid)
1245
    return;
1246
  ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
1247
}
1248
 
1249
/* Hook that is called by cgraph.c when a node is removed.  */
1250
 
1251
static void
1252
ipa_node_removal_hook (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
1253
{
1254
  ipa_free_node_params_substructures (IPA_NODE_REF (node));
1255
}
1256
 
1257
/* Helper function to duplicate an array of size N that is at SRC and store a
1258
   pointer to it to DST.  Nothing is done if SRC is NULL.  */
1259
 
1260
static void *
1261
duplicate_array (void *src, size_t n)
1262
{
1263
  void *p;
1264
 
1265
  if (!src)
1266
    return NULL;
1267
 
1268
  p = xmalloc (n);
1269
  memcpy (p, src, n);
1270
  return p;
1271
}
1272
 
1273
/* Like duplicate_array byt in GGC memory.  */
1274
 
1275
static void *
1276
duplicate_ggc_array (void *src, size_t n)
1277
{
1278
  void *p;
1279
 
1280
  if (!src)
1281
    return NULL;
1282
 
1283
  p = ggc_alloc (n);
1284
  memcpy (p, src, n);
1285
  return p;
1286
}
1287
 
1288
/* Hook that is called by cgraph.c when a node is duplicated.  */
1289
 
1290
static void
1291
ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
1292
                           __attribute__((unused)) void *data)
1293
{
1294
  struct ipa_edge_args *old_args, *new_args;
1295
  int arg_count;
1296
 
1297
  ipa_check_create_edge_args ();
1298
 
1299
  old_args = IPA_EDGE_REF (src);
1300
  new_args = IPA_EDGE_REF (dst);
1301
 
1302
  arg_count = ipa_get_cs_argument_count (old_args);
1303
  ipa_set_cs_argument_count (new_args, arg_count);
1304
  new_args->jump_functions = (struct ipa_jump_func *)
1305
    duplicate_ggc_array (old_args->jump_functions,
1306
                         sizeof (struct ipa_jump_func) * arg_count);
1307
}
1308
 
1309
/* Hook that is called by cgraph.c when a node is duplicated.  */
1310
 
1311
static void
1312
ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
1313
                           __attribute__((unused)) void *data)
1314
{
1315
  struct ipa_node_params *old_info, *new_info;
1316
  struct ipa_param_call_note *note;
1317
  int param_count;
1318
 
1319
  ipa_check_create_node_params ();
1320
  old_info = IPA_NODE_REF (src);
1321
  new_info = IPA_NODE_REF (dst);
1322
  param_count = ipa_get_param_count (old_info);
1323
 
1324
  ipa_set_param_count (new_info, param_count);
1325
  new_info->params = (struct ipa_param_descriptor *)
1326
    duplicate_array (old_info->params,
1327
                     sizeof (struct ipa_param_descriptor) * param_count);
1328
  new_info->ipcp_orig_node = old_info->ipcp_orig_node;
1329
  new_info->count_scale = old_info->count_scale;
1330
 
1331
  for (note = old_info->param_calls; note; note = note->next)
1332
    {
1333
      struct ipa_param_call_note *nn;
1334
 
1335
      nn = (struct ipa_param_call_note *)
1336
        xcalloc (1, sizeof (struct ipa_param_call_note));
1337
      memcpy (nn, note, sizeof (struct ipa_param_call_note));
1338
      nn->next = new_info->param_calls;
1339
      new_info->param_calls = nn;
1340
    }
1341
}
1342
 
1343
/* Register our cgraph hooks if they are not already there.  */
1344
 
1345
void
1346
ipa_register_cgraph_hooks (void)
1347
{
1348
  if (!edge_removal_hook_holder)
1349
    edge_removal_hook_holder =
1350
      cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL);
1351
  if (!node_removal_hook_holder)
1352
    node_removal_hook_holder =
1353
      cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL);
1354
  if (!edge_duplication_hook_holder)
1355
    edge_duplication_hook_holder =
1356
      cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL);
1357
  if (!node_duplication_hook_holder)
1358
    node_duplication_hook_holder =
1359
      cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL);
1360
}
1361
 
1362
/* Unregister our cgraph hooks if they are not already there.  */
1363
 
1364
static void
1365
ipa_unregister_cgraph_hooks (void)
1366
{
1367
  cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
1368
  edge_removal_hook_holder = NULL;
1369
  cgraph_remove_node_removal_hook (node_removal_hook_holder);
1370
  node_removal_hook_holder = NULL;
1371
  cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
1372
  edge_duplication_hook_holder = NULL;
1373
  cgraph_remove_node_duplication_hook (node_duplication_hook_holder);
1374
  node_duplication_hook_holder = NULL;
1375
}
1376
 
1377
/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1378
   longer needed after ipa-cp.  */
1379
 
1380
void
1381
free_all_ipa_structures_after_ipa_cp (void)
1382
{
1383
  if (!flag_indirect_inlining)
1384
    {
1385
      ipa_free_all_edge_args ();
1386
      ipa_free_all_node_params ();
1387
      ipa_unregister_cgraph_hooks ();
1388
    }
1389
}
1390
 
1391
/* Free all ipa_node_params and all ipa_edge_args structures if they are no
1392
   longer needed after indirect inlining.  */
1393
 
1394
void
1395
free_all_ipa_structures_after_iinln (void)
1396
{
1397
  ipa_free_all_edge_args ();
1398
  ipa_free_all_node_params ();
1399
  ipa_unregister_cgraph_hooks ();
1400
}
1401
 
1402
/* Print ipa_tree_map data structures of all functions in the
1403
   callgraph to F.  */
1404
 
1405
void
1406
ipa_print_node_params (FILE * f, struct cgraph_node *node)
1407
{
1408
  int i, count;
1409
  tree temp;
1410
  struct ipa_node_params *info;
1411
 
1412
  if (!node->analyzed)
1413
    return;
1414
  info = IPA_NODE_REF (node);
1415
  fprintf (f, "  function  %s Trees :: \n", cgraph_node_name (node));
1416
  count = ipa_get_param_count (info);
1417
  for (i = 0; i < count; i++)
1418
    {
1419
      temp = ipa_get_param (info, i);
1420
      if (TREE_CODE (temp) == PARM_DECL)
1421
        fprintf (f, "    param %d : %s", i,
1422
                 (DECL_NAME (temp)
1423
                  ? (*lang_hooks.decl_printable_name) (temp, 2)
1424
                  : "(unnamed)"));
1425
      if (ipa_is_param_modified (info, i))
1426
        fprintf (f, " modified");
1427
      fprintf (f, "\n");
1428
    }
1429
}
1430
 
1431
/* Print ipa_tree_map data structures of all functions in the
1432
   callgraph to F.  */
1433
 
1434
void
1435
ipa_print_all_params (FILE * f)
1436
{
1437
  struct cgraph_node *node;
1438
 
1439
  fprintf (f, "\nFunction parameters:\n");
1440
  for (node = cgraph_nodes; node; node = node->next)
1441
    ipa_print_node_params (f, node);
1442
}
1443
 
1444
/* Return a heap allocated vector containing formal parameters of FNDECL.  */
1445
 
1446
VEC(tree, heap) *
1447
ipa_get_vector_of_formal_parms (tree fndecl)
1448
{
1449
  VEC(tree, heap) *args;
1450
  int count;
1451
  tree parm;
1452
 
1453
  count = count_formal_params_1 (fndecl);
1454
  args = VEC_alloc (tree, heap, count);
1455
  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
1456
    VEC_quick_push (tree, args, parm);
1457
 
1458
  return args;
1459
}
1460
 
1461
/* Return a heap allocated vector containing types of formal parameters of
1462
   function type FNTYPE.  */
1463
 
1464
static inline VEC(tree, heap) *
1465
get_vector_of_formal_parm_types (tree fntype)
1466
{
1467
  VEC(tree, heap) *types;
1468
  int count = 0;
1469
  tree t;
1470
 
1471
  for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
1472
    count++;
1473
 
1474
  types = VEC_alloc (tree, heap, count);
1475
  for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
1476
    VEC_quick_push (tree, types, TREE_VALUE (t));
1477
 
1478
  return types;
1479
}
1480
 
1481
/* Modify the function declaration FNDECL and its type according to the plan in
1482
   ADJUSTMENTS.  It also sets base fields of individual adjustments structures
1483
   to reflect the actual parameters being modified which are determined by the
1484
   base_index field.  */
1485
 
1486
void
1487
ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
1488
                              const char *synth_parm_prefix)
1489
{
1490
  VEC(tree, heap) *oparms, *otypes;
1491
  tree orig_type, new_type = NULL;
1492
  tree old_arg_types, t, new_arg_types = NULL;
1493
  tree parm, *link = &DECL_ARGUMENTS (fndecl);
1494
  int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
1495
  tree new_reversed = NULL;
1496
  bool care_for_types, last_parm_void;
1497
 
1498
  if (!synth_parm_prefix)
1499
    synth_parm_prefix = "SYNTH";
1500
 
1501
  oparms = ipa_get_vector_of_formal_parms (fndecl);
1502
  orig_type = TREE_TYPE (fndecl);
1503
  old_arg_types = TYPE_ARG_TYPES (orig_type);
1504
 
1505
  /* The following test is an ugly hack, some functions simply don't have any
1506
     arguments in their type.  This is probably a bug but well... */
1507
  care_for_types = (old_arg_types != NULL_TREE);
1508
  if (care_for_types)
1509
    {
1510
      last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
1511
                        == void_type_node);
1512
      otypes = get_vector_of_formal_parm_types (orig_type);
1513
      if (last_parm_void)
1514
        gcc_assert (VEC_length (tree, oparms) + 1 == VEC_length (tree, otypes));
1515
      else
1516
        gcc_assert (VEC_length (tree, oparms) == VEC_length (tree, otypes));
1517
    }
1518
  else
1519
    {
1520
      last_parm_void = false;
1521
      otypes = NULL;
1522
    }
1523
 
1524
  for (i = 0; i < len; i++)
1525
    {
1526
      struct ipa_parm_adjustment *adj;
1527
      gcc_assert (link);
1528
 
1529
      adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
1530
      parm = VEC_index (tree, oparms, adj->base_index);
1531
      adj->base = parm;
1532
 
1533
      if (adj->copy_param)
1534
        {
1535
          if (care_for_types)
1536
            new_arg_types = tree_cons (NULL_TREE, VEC_index (tree, otypes,
1537
                                                             adj->base_index),
1538
                                       new_arg_types);
1539
          *link = parm;
1540
          link = &TREE_CHAIN (parm);
1541
        }
1542
      else if (!adj->remove_param)
1543
        {
1544
          tree new_parm;
1545
          tree ptype;
1546
 
1547
          if (adj->by_ref)
1548
            ptype = build_pointer_type (adj->type);
1549
          else
1550
            ptype = adj->type;
1551
 
1552
          if (care_for_types)
1553
            new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
1554
 
1555
          new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
1556
                                 ptype);
1557
          DECL_NAME (new_parm) = create_tmp_var_name (synth_parm_prefix);
1558
 
1559
          DECL_ARTIFICIAL (new_parm) = 1;
1560
          DECL_ARG_TYPE (new_parm) = ptype;
1561
          DECL_CONTEXT (new_parm) = fndecl;
1562
          TREE_USED (new_parm) = 1;
1563
          DECL_IGNORED_P (new_parm) = 1;
1564
          layout_decl (new_parm, 0);
1565
 
1566
          add_referenced_var (new_parm);
1567
          mark_sym_for_renaming (new_parm);
1568
          adj->base = parm;
1569
          adj->reduction = new_parm;
1570
 
1571
          *link = new_parm;
1572
 
1573
          link = &TREE_CHAIN (new_parm);
1574
        }
1575
    }
1576
 
1577
  *link = NULL_TREE;
1578
 
1579
  if (care_for_types)
1580
    {
1581
      new_reversed = nreverse (new_arg_types);
1582
      if (last_parm_void)
1583
        {
1584
          if (new_reversed)
1585
            TREE_CHAIN (new_arg_types) = void_list_node;
1586
          else
1587
            new_reversed = void_list_node;
1588
        }
1589
    }
1590
 
1591
  /* Use copy_node to preserve as much as possible from original type
1592
     (debug info, attribute lists etc.)
1593
     Exception is METHOD_TYPEs must have THIS argument.
1594
     When we are asked to remove it, we need to build new FUNCTION_TYPE
1595
     instead.  */
1596
  if (TREE_CODE (orig_type) != METHOD_TYPE
1597
       || (VEC_index (ipa_parm_adjustment_t, adjustments, 0)->copy_param
1598
         && VEC_index (ipa_parm_adjustment_t, adjustments, 0)->base_index == 0))
1599
    {
1600 378 julius
      new_type = build_distinct_type_copy (orig_type);
1601 280 jeremybenn
      TYPE_ARG_TYPES (new_type) = new_reversed;
1602
    }
1603
  else
1604
    {
1605
      new_type
1606
        = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
1607
                                                         new_reversed));
1608
      TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
1609
      DECL_VINDEX (fndecl) = NULL_TREE;
1610
    }
1611
  /* When signature changes, we need to clear builtin info.  */
1612
  if (DECL_BUILT_IN (fndecl))
1613
    {
1614
      DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
1615
      DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
1616
    }
1617
 
1618
  /* This is a new type, not a copy of an old type.  Need to reassociate
1619
     variants.  We can handle everything except the main variant lazily.  */
1620
  t = TYPE_MAIN_VARIANT (orig_type);
1621
  if (orig_type != t)
1622
    {
1623
      TYPE_MAIN_VARIANT (new_type) = t;
1624
      TYPE_NEXT_VARIANT (new_type) = TYPE_NEXT_VARIANT (t);
1625
      TYPE_NEXT_VARIANT (t) = new_type;
1626
    }
1627
  else
1628
    {
1629
      TYPE_MAIN_VARIANT (new_type) = new_type;
1630
      TYPE_NEXT_VARIANT (new_type) = NULL;
1631
    }
1632
 
1633
  TREE_TYPE (fndecl) = new_type;
1634
  if (otypes)
1635
    VEC_free (tree, heap, otypes);
1636
  VEC_free (tree, heap, oparms);
1637
}
1638
 
1639
/* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
1640
   If this is a directly recursive call, CS must be NULL.  Otherwise it must
1641
   contain the corresponding call graph edge.  */
1642
 
1643
void
1644
ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
1645
                           ipa_parm_adjustment_vec adjustments)
1646
{
1647
  VEC(tree, heap) *vargs;
1648
  gimple new_stmt;
1649
  gimple_stmt_iterator gsi;
1650
  tree callee_decl;
1651
  int i, len;
1652
 
1653
  len = VEC_length (ipa_parm_adjustment_t, adjustments);
1654
  vargs = VEC_alloc (tree, heap, len);
1655
 
1656
  gsi = gsi_for_stmt (stmt);
1657
  for (i = 0; i < len; i++)
1658
    {
1659
      struct ipa_parm_adjustment *adj;
1660
 
1661
      adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
1662
 
1663
      if (adj->copy_param)
1664
        {
1665
          tree arg = gimple_call_arg (stmt, adj->base_index);
1666
 
1667
          VEC_quick_push (tree, vargs, arg);
1668
        }
1669
      else if (!adj->remove_param)
1670
        {
1671
          tree expr, orig_expr;
1672
          bool allow_ptr, repl_found;
1673
 
1674
          orig_expr = expr = gimple_call_arg (stmt, adj->base_index);
1675
          if (TREE_CODE (expr) == ADDR_EXPR)
1676
            {
1677
              allow_ptr = false;
1678
              expr = TREE_OPERAND (expr, 0);
1679
            }
1680
          else
1681
            allow_ptr = true;
1682
 
1683
          repl_found = build_ref_for_offset (&expr, TREE_TYPE (expr),
1684
                                             adj->offset, adj->type,
1685
                                             allow_ptr);
1686
          if (repl_found)
1687
            {
1688
              if (adj->by_ref)
1689
                expr = build_fold_addr_expr (expr);
1690
            }
1691
          else
1692
            {
1693
              tree ptrtype = build_pointer_type (adj->type);
1694
              expr = orig_expr;
1695
              if (!POINTER_TYPE_P (TREE_TYPE (expr)))
1696
                expr = build_fold_addr_expr (expr);
1697
              if (!useless_type_conversion_p (ptrtype, TREE_TYPE (expr)))
1698
                expr = fold_convert (ptrtype, expr);
1699
              expr = fold_build2 (POINTER_PLUS_EXPR, ptrtype, expr,
1700
                                  build_int_cst (size_type_node,
1701
                                                 adj->offset / BITS_PER_UNIT));
1702
              if (!adj->by_ref)
1703
                expr = fold_build1 (INDIRECT_REF, adj->type, expr);
1704
            }
1705
          expr = force_gimple_operand_gsi (&gsi, expr,
1706
                                           adj->by_ref
1707
                                           || is_gimple_reg_type (adj->type),
1708
                                           NULL, true, GSI_SAME_STMT);
1709
          VEC_quick_push (tree, vargs, expr);
1710
        }
1711
    }
1712
 
1713
  if (dump_file && (dump_flags & TDF_DETAILS))
1714
    {
1715
      fprintf (dump_file, "replacing stmt:");
1716
      print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
1717
    }
1718
 
1719
  callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
1720
  new_stmt = gimple_build_call_vec (callee_decl, vargs);
1721
  VEC_free (tree, heap, vargs);
1722
  if (gimple_call_lhs (stmt))
1723
    gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
1724
 
1725
  gimple_set_block (new_stmt, gimple_block (stmt));
1726
  if (gimple_has_location (stmt))
1727
    gimple_set_location (new_stmt, gimple_location (stmt));
1728
  gimple_call_copy_flags (new_stmt, stmt);
1729
  gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
1730
 
1731
  if (dump_file && (dump_flags & TDF_DETAILS))
1732
    {
1733
      fprintf (dump_file, "with stmt:");
1734
      print_gimple_stmt (dump_file, new_stmt, 0, 0);
1735
      fprintf (dump_file, "\n");
1736
    }
1737
  gsi_replace (&gsi, new_stmt, true);
1738
  if (cs)
1739
    cgraph_set_call_stmt (cs, new_stmt);
1740
  update_ssa (TODO_update_ssa);
1741
  free_dominance_info (CDI_DOMINATORS);
1742
}
1743
 
1744
/* Return true iff BASE_INDEX is in ADJUSTMENTS more than once.  */
1745
 
1746
static bool
1747
index_in_adjustments_multiple_times_p (int base_index,
1748
                                       ipa_parm_adjustment_vec adjustments)
1749
{
1750
  int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
1751
  bool one = false;
1752
 
1753
  for (i = 0; i < len; i++)
1754
    {
1755
      struct ipa_parm_adjustment *adj;
1756
      adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
1757
 
1758
      if (adj->base_index == base_index)
1759
        {
1760
          if (one)
1761
            return true;
1762
          else
1763
            one = true;
1764
        }
1765
    }
1766
  return false;
1767
}
1768
 
1769
 
1770
/* Return adjustments that should have the same effect on function parameters
1771
   and call arguments as if they were first changed according to adjustments in
1772
   INNER and then by adjustments in OUTER.  */
1773
 
1774
ipa_parm_adjustment_vec
1775
ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
1776
                         ipa_parm_adjustment_vec outer)
1777
{
1778
  int i, outlen = VEC_length (ipa_parm_adjustment_t, outer);
1779
  int inlen = VEC_length (ipa_parm_adjustment_t, inner);
1780
  int removals = 0;
1781
  ipa_parm_adjustment_vec adjustments, tmp;
1782
 
1783
  tmp = VEC_alloc (ipa_parm_adjustment_t, heap, inlen);
1784
  for (i = 0; i < inlen; i++)
1785
    {
1786
      struct ipa_parm_adjustment *n;
1787
      n = VEC_index (ipa_parm_adjustment_t, inner, i);
1788
 
1789
      if (n->remove_param)
1790
        removals++;
1791
      else
1792
        VEC_quick_push (ipa_parm_adjustment_t, tmp, n);
1793
    }
1794
 
1795
  adjustments = VEC_alloc (ipa_parm_adjustment_t, heap, outlen + removals);
1796
  for (i = 0; i < outlen; i++)
1797
    {
1798
      struct ipa_parm_adjustment *r;
1799
      struct ipa_parm_adjustment *out = VEC_index (ipa_parm_adjustment_t,
1800
                                                   outer, i);
1801
      struct ipa_parm_adjustment *in = VEC_index (ipa_parm_adjustment_t, tmp,
1802
                                                  out->base_index);
1803
 
1804
      gcc_assert (!in->remove_param);
1805
      if (out->remove_param)
1806
        {
1807
          if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
1808
            {
1809
              r = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
1810
              memset (r, 0, sizeof (*r));
1811
              r->remove_param = true;
1812
            }
1813
          continue;
1814
        }
1815
 
1816
      r = VEC_quick_push (ipa_parm_adjustment_t, adjustments, NULL);
1817
      memset (r, 0, sizeof (*r));
1818
      r->base_index = in->base_index;
1819
      r->type = out->type;
1820
 
1821
      /* FIXME:  Create nonlocal value too.  */
1822
 
1823
      if (in->copy_param && out->copy_param)
1824
        r->copy_param = true;
1825
      else if (in->copy_param)
1826
        r->offset = out->offset;
1827
      else if (out->copy_param)
1828
        r->offset = in->offset;
1829
      else
1830
        r->offset = in->offset + out->offset;
1831
    }
1832
 
1833
  for (i = 0; i < inlen; i++)
1834
    {
1835
      struct ipa_parm_adjustment *n = VEC_index (ipa_parm_adjustment_t,
1836
                                                 inner, i);
1837
 
1838
      if (n->remove_param)
1839
        VEC_quick_push (ipa_parm_adjustment_t, adjustments, n);
1840
    }
1841
 
1842
  VEC_free (ipa_parm_adjustment_t, heap, tmp);
1843
  return adjustments;
1844
}
1845
 
1846
/* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
1847
   friendly way, assuming they are meant to be applied to FNDECL.  */
1848
 
1849
void
1850
ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
1851
                            tree fndecl)
1852
{
1853
  int i, len = VEC_length (ipa_parm_adjustment_t, adjustments);
1854
  bool first = true;
1855
  VEC(tree, heap) *parms = ipa_get_vector_of_formal_parms (fndecl);
1856
 
1857
  fprintf (file, "IPA param adjustments: ");
1858
  for (i = 0; i < len; i++)
1859
    {
1860
      struct ipa_parm_adjustment *adj;
1861
      adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
1862
 
1863
      if (!first)
1864
        fprintf (file, "                 ");
1865
      else
1866
        first = false;
1867
 
1868
      fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
1869
      print_generic_expr (file, VEC_index (tree, parms, adj->base_index), 0);
1870
      if (adj->base)
1871
        {
1872
          fprintf (file, ", base: ");
1873
          print_generic_expr (file, adj->base, 0);
1874
        }
1875
      if (adj->reduction)
1876
        {
1877
          fprintf (file, ", reduction: ");
1878
          print_generic_expr (file, adj->reduction, 0);
1879
        }
1880
      if (adj->new_ssa_base)
1881
        {
1882
          fprintf (file, ", new_ssa_base: ");
1883
          print_generic_expr (file, adj->new_ssa_base, 0);
1884
        }
1885
 
1886
      if (adj->copy_param)
1887
        fprintf (file, ", copy_param");
1888
      else if (adj->remove_param)
1889
        fprintf (file, ", remove_param");
1890
      else
1891
        fprintf (file, ", offset %li", (long) adj->offset);
1892
      if (adj->by_ref)
1893
        fprintf (file, ", by_ref");
1894
      print_node_brief (file, ", type: ", adj->type, 0);
1895
      fprintf (file, "\n");
1896
    }
1897
  VEC_free (tree, heap, parms);
1898
}
1899
 
1900
/* Stream out jump function JUMP_FUNC to OB.  */
1901
 
1902
static void
1903
ipa_write_jump_function (struct output_block *ob,
1904
                         struct ipa_jump_func *jump_func)
1905
{
1906
  lto_output_uleb128_stream (ob->main_stream,
1907
                             jump_func->type);
1908
 
1909
  switch (jump_func->type)
1910
    {
1911
    case IPA_JF_UNKNOWN:
1912
      break;
1913
    case IPA_JF_CONST:
1914
      lto_output_tree (ob, jump_func->value.constant, true);
1915
      break;
1916
    case IPA_JF_PASS_THROUGH:
1917
      lto_output_tree (ob, jump_func->value.pass_through.operand, true);
1918
      lto_output_uleb128_stream (ob->main_stream,
1919
                                 jump_func->value.pass_through.formal_id);
1920
      lto_output_uleb128_stream (ob->main_stream,
1921
                                 jump_func->value.pass_through.operation);
1922
      break;
1923
    case IPA_JF_ANCESTOR:
1924
      lto_output_uleb128_stream (ob->main_stream,
1925
                                 jump_func->value.ancestor.offset);
1926
      lto_output_tree (ob, jump_func->value.ancestor.type, true);
1927
      lto_output_uleb128_stream (ob->main_stream,
1928
                                 jump_func->value.ancestor.formal_id);
1929
      break;
1930
    case IPA_JF_CONST_MEMBER_PTR:
1931
      lto_output_tree (ob, jump_func->value.member_cst.pfn, true);
1932
      lto_output_tree (ob, jump_func->value.member_cst.delta, false);
1933
      break;
1934
    }
1935
}
1936
 
1937
/* Read in jump function JUMP_FUNC from IB.  */
1938
 
1939
static void
1940
ipa_read_jump_function (struct lto_input_block *ib,
1941
                        struct ipa_jump_func *jump_func,
1942
                        struct data_in *data_in)
1943
{
1944
  jump_func->type = (enum jump_func_type) lto_input_uleb128 (ib);
1945
 
1946
  switch (jump_func->type)
1947
    {
1948
    case IPA_JF_UNKNOWN:
1949
      break;
1950
    case IPA_JF_CONST:
1951
      jump_func->value.constant = lto_input_tree (ib, data_in);
1952
      break;
1953
    case IPA_JF_PASS_THROUGH:
1954
      jump_func->value.pass_through.operand = lto_input_tree (ib, data_in);
1955
      jump_func->value.pass_through.formal_id = lto_input_uleb128 (ib);
1956
      jump_func->value.pass_through.operation = (enum tree_code) lto_input_uleb128 (ib);
1957
      break;
1958
    case IPA_JF_ANCESTOR:
1959
      jump_func->value.ancestor.offset = lto_input_uleb128 (ib);
1960
      jump_func->value.ancestor.type = lto_input_tree (ib, data_in);
1961
      jump_func->value.ancestor.formal_id = lto_input_uleb128 (ib);
1962
      break;
1963
    case IPA_JF_CONST_MEMBER_PTR:
1964
      jump_func->value.member_cst.pfn = lto_input_tree (ib, data_in);
1965
      jump_func->value.member_cst.delta = lto_input_tree (ib, data_in);
1966
      break;
1967
    }
1968
}
1969
 
1970
/* Stream out a parameter call note.  */
1971
 
1972
static void
1973
ipa_write_param_call_note (struct output_block *ob,
1974
                           struct ipa_param_call_note *note)
1975
{
1976
  gcc_assert (!note->processed);
1977
  lto_output_uleb128_stream (ob->main_stream, gimple_uid (note->stmt));
1978
  lto_output_sleb128_stream (ob->main_stream, note->formal_id);
1979
  lto_output_sleb128_stream (ob->main_stream, note->count);
1980
  lto_output_sleb128_stream (ob->main_stream, note->frequency);
1981
  lto_output_sleb128_stream (ob->main_stream, note->loop_nest);
1982
}
1983
 
1984
/* Read in a parameter call note.  */
1985
 
1986
static void
1987
ipa_read_param_call_note (struct lto_input_block *ib,
1988
                          struct ipa_node_params *info)
1989
 
1990
{
1991
  struct ipa_param_call_note *note = XCNEW (struct ipa_param_call_note);
1992
 
1993
  note->lto_stmt_uid = (unsigned int) lto_input_uleb128 (ib);
1994
  note->formal_id = (int) lto_input_sleb128 (ib);
1995
  note->count = (gcov_type) lto_input_sleb128 (ib);
1996
  note->frequency = (int) lto_input_sleb128 (ib);
1997
  note->loop_nest = (int) lto_input_sleb128 (ib);
1998
 
1999
  note->next = info->param_calls;
2000
  info->param_calls = note;
2001
}
2002
 
2003
 
2004
/* Stream out NODE info to OB.  */
2005
 
2006
static void
2007
ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
2008
{
2009
  int node_ref;
2010
  lto_cgraph_encoder_t encoder;
2011
  struct ipa_node_params *info = IPA_NODE_REF (node);
2012
  int j;
2013
  struct cgraph_edge *e;
2014
  struct bitpack_d *bp;
2015
  int note_count = 0;
2016
  struct ipa_param_call_note *note;
2017
 
2018
  encoder = ob->decl_state->cgraph_node_encoder;
2019
  node_ref = lto_cgraph_encoder_encode (encoder, node);
2020
  lto_output_uleb128_stream (ob->main_stream, node_ref);
2021
 
2022
  bp = bitpack_create ();
2023
  bp_pack_value (bp, info->called_with_var_arguments, 1);
2024
  bp_pack_value (bp, info->uses_analysis_done, 1);
2025
  gcc_assert (info->modification_analysis_done
2026
              || ipa_get_param_count (info) == 0);
2027
  gcc_assert (!info->node_enqueued);
2028
  gcc_assert (!info->ipcp_orig_node);
2029
  for (j = 0; j < ipa_get_param_count (info); j++)
2030
    bp_pack_value (bp, info->params[j].modified, 1);
2031
  lto_output_bitpack (ob->main_stream, bp);
2032
  bitpack_delete (bp);
2033
  for (e = node->callees; e; e = e->next_callee)
2034
    {
2035
      struct ipa_edge_args *args = IPA_EDGE_REF (e);
2036
 
2037
      lto_output_uleb128_stream (ob->main_stream,
2038
                                 ipa_get_cs_argument_count (args));
2039
      for (j = 0; j < ipa_get_cs_argument_count (args); j++)
2040
        ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
2041
    }
2042
 
2043
  for (note = info->param_calls; note; note = note->next)
2044
    note_count++;
2045
  lto_output_uleb128_stream (ob->main_stream, note_count);
2046
  for (note = info->param_calls; note; note = note->next)
2047
    ipa_write_param_call_note (ob, note);
2048
}
2049
 
2050
/* Srtream in NODE info from IB.  */
2051
 
2052
static void
2053
ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
2054
                    struct data_in *data_in)
2055
{
2056
  struct ipa_node_params *info = IPA_NODE_REF (node);
2057
  int k;
2058
  struct cgraph_edge *e;
2059
  struct bitpack_d *bp;
2060
  int i, note_count;
2061
 
2062
  ipa_initialize_node_params (node);
2063
 
2064
  bp = lto_input_bitpack (ib);
2065
  info->called_with_var_arguments = bp_unpack_value (bp, 1);
2066
  info->uses_analysis_done = bp_unpack_value (bp, 1);
2067
  if (ipa_get_param_count (info) != 0)
2068
    {
2069
      info->modification_analysis_done = true;
2070
      info->uses_analysis_done = true;
2071
    }
2072
  info->node_enqueued = false;
2073
  for (k = 0; k < ipa_get_param_count (info); k++)
2074
    info->params[k].modified = bp_unpack_value (bp, 1);
2075
  bitpack_delete (bp);
2076
  for (e = node->callees; e; e = e->next_callee)
2077
    {
2078
      struct ipa_edge_args *args = IPA_EDGE_REF (e);
2079
      int count = lto_input_uleb128 (ib);
2080
 
2081
      ipa_set_cs_argument_count (args, count);
2082
      if (!count)
2083
        continue;
2084
 
2085
      args->jump_functions = GGC_CNEWVEC (struct ipa_jump_func,
2086
                                          ipa_get_cs_argument_count (args));
2087
      for (k = 0; k < ipa_get_cs_argument_count (args); k++)
2088
        ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), data_in);
2089
    }
2090
 
2091
  note_count = lto_input_uleb128 (ib);
2092
  for (i = 0; i < note_count; i++)
2093
    ipa_read_param_call_note (ib, info);
2094
}
2095
 
2096
/* Write jump functions for nodes in SET.  */
2097
 
2098
void
2099
ipa_prop_write_jump_functions (cgraph_node_set set)
2100
{
2101
  struct cgraph_node *node;
2102
  struct output_block *ob = create_output_block (LTO_section_jump_functions);
2103
  unsigned int count = 0;
2104
  cgraph_node_set_iterator csi;
2105
 
2106
  ob->cgraph_node = NULL;
2107
 
2108
  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
2109
    {
2110
      node = csi_node (csi);
2111
      if (node->analyzed && IPA_NODE_REF (node) != NULL)
2112
        count++;
2113
    }
2114
 
2115
  lto_output_uleb128_stream (ob->main_stream, count);
2116
 
2117
  /* Process all of the functions.  */
2118
  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
2119
    {
2120
      node = csi_node (csi);
2121
      if (node->analyzed && IPA_NODE_REF (node) != NULL)
2122
        ipa_write_node_info (ob, node);
2123
    }
2124
  lto_output_1_stream (ob->main_stream, 0);
2125
  produce_asm (ob, NULL);
2126
  destroy_output_block (ob);
2127
}
2128
 
2129
/* Read section in file FILE_DATA of length LEN with data DATA.  */
2130
 
2131
static void
2132
ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
2133
                       size_t len)
2134
{
2135
  const struct lto_function_header *header =
2136
    (const struct lto_function_header *) data;
2137
  const int32_t cfg_offset = sizeof (struct lto_function_header);
2138
  const int32_t main_offset = cfg_offset + header->cfg_size;
2139
  const int32_t string_offset = main_offset + header->main_size;
2140
  struct data_in *data_in;
2141
  struct lto_input_block ib_main;
2142
  unsigned int i;
2143
  unsigned int count;
2144
 
2145
  LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
2146
                        header->main_size);
2147
 
2148
  data_in =
2149
    lto_data_in_create (file_data, (const char *) data + string_offset,
2150
                        header->string_size, NULL);
2151
  count = lto_input_uleb128 (&ib_main);
2152
 
2153
  for (i = 0; i < count; i++)
2154
    {
2155
      unsigned int index;
2156
      struct cgraph_node *node;
2157
      lto_cgraph_encoder_t encoder;
2158
 
2159
      index = lto_input_uleb128 (&ib_main);
2160
      encoder = file_data->cgraph_node_encoder;
2161
      node = lto_cgraph_encoder_deref (encoder, index);
2162
      ipa_read_node_info (&ib_main, node, data_in);
2163
    }
2164
  lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
2165
                         len);
2166
  lto_data_in_delete (data_in);
2167
}
2168
 
2169
/* Read ipcp jump functions.  */
2170
 
2171
void
2172
ipa_prop_read_jump_functions (void)
2173
{
2174
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2175
  struct lto_file_decl_data *file_data;
2176
  unsigned int j = 0;
2177
 
2178
  ipa_check_create_node_params ();
2179
  ipa_check_create_edge_args ();
2180
  ipa_register_cgraph_hooks ();
2181
 
2182
  while ((file_data = file_data_vec[j++]))
2183
    {
2184
      size_t len;
2185
      const char *data = lto_get_section_data (file_data, LTO_section_jump_functions, NULL, &len);
2186
 
2187
      if (data)
2188
        ipa_prop_read_section (file_data, data, len);
2189
    }
2190
}
2191
 
2192
/* After merging units, we can get mismatch in argument counts.
2193
   Also decl merging might've rendered parameter lists obsolette.
2194
   Also compute called_with_variable_arg info.  */
2195
 
2196
void
2197
ipa_update_after_lto_read (void)
2198
{
2199
  struct cgraph_node *node;
2200
  struct cgraph_edge *cs;
2201
 
2202
  ipa_check_create_node_params ();
2203
  ipa_check_create_edge_args ();
2204
 
2205
  for (node = cgraph_nodes; node; node = node->next)
2206
    if (node->analyzed)
2207
      ipa_initialize_node_params (node);
2208
 
2209
  for (node = cgraph_nodes; node; node = node->next)
2210
    if (node->analyzed)
2211
      for (cs = node->callees; cs; cs = cs->next_callee)
2212
        {
2213
          if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
2214
              != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
2215
            ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
2216
        }
2217
}
2218
 
2219
/* Walk param call notes of NODE and set their call statements given the uid
2220
   stored in each note and STMTS which is an array of statements indexed by the
2221
   uid.  */
2222
 
2223
void
2224
lto_ipa_fixup_call_notes (struct cgraph_node *node, gimple *stmts)
2225
{
2226
  struct ipa_node_params *info;
2227
  struct ipa_param_call_note *note;
2228
 
2229
  ipa_check_create_node_params ();
2230
  info = IPA_NODE_REF (node);
2231
  note = info->param_calls;
2232
  /* If there are no notes or they have already been fixed up (the same fixup
2233
     is called for both inlining and ipa-cp), there's nothing to do. */
2234
  if (!note || note->stmt)
2235
    return;
2236
 
2237
  do
2238
    {
2239
      note->stmt = stmts[note->lto_stmt_uid];
2240
      note = note->next;
2241
    }
2242
  while (note);
2243
}

powered by: WebSVN 2.1.0

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