1 /* Interprocedural analyses.
2 Copyright (C) 2005-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
28 #include "fold-const.h"
31 #include "hard-reg-set.h"
33 #include "dominance.h"
35 #include "basic-block.h"
36 #include "tree-ssa-alias.h"
37 #include "internal-fn.h"
38 #include "gimple-fold.h"
40 #include "gimple-expr.h"
45 #include "insn-config.h"
54 #include "stor-layout.h"
55 #include "print-tree.h"
57 #include "gimple-iterator.h"
58 #include "gimplify-me.h"
59 #include "gimple-walk.h"
60 #include "langhooks.h"
62 #include "plugin-api.h"
65 #include "alloc-pool.h"
66 #include "symbol-summary.h"
69 #include "gimple-ssa.h"
71 #include "tree-phinodes.h"
72 #include "ssa-iterators.h"
73 #include "tree-into-ssa.h"
75 #include "tree-pass.h"
76 #include "tree-inline.h"
77 #include "ipa-inline.h"
78 #include "diagnostic.h"
79 #include "gimple-pretty-print.h"
80 #include "lto-streamer.h"
81 #include "data-streamer.h"
82 #include "tree-streamer.h"
84 #include "ipa-utils.h"
85 #include "stringpool.h"
86 #include "tree-ssanames.h"
91 /* Intermediate information that we get from alias analysis about a particular
92 parameter in a particular basic_block. When a parameter or the memory it
93 references is marked modified, we use that information in all dominatd
94 blocks without cosulting alias analysis oracle. */
96 struct param_aa_status
98 /* Set when this structure contains meaningful information. If not, the
99 structure describing a dominating BB should be used instead. */
102 /* Whether we have seen something which might have modified the data in
103 question. PARM is for the parameter itself, REF is for data it points to
104 but using the alias type of individual accesses and PT is the same thing
105 but for computing aggregate pass-through functions using a very inclusive
107 bool parm_modified
, ref_modified
, pt_modified
;
110 /* Information related to a given BB that used only when looking at function
115 /* Call graph edges going out of this BB. */
116 vec
<cgraph_edge
*> cg_edges
;
117 /* Alias analysis statuses of each formal parameter at this bb. */
118 vec
<param_aa_status
> param_aa_statuses
;
121 /* Structure with global information that is only used when looking at function
124 struct func_body_info
126 /* The node that is being analyzed. */
130 struct ipa_node_params
*info
;
132 /* Information about individual BBs. */
133 vec
<ipa_bb_info
> bb_infos
;
135 /* Number of parameters. */
138 /* Number of statements already walked by when analyzing this function. */
139 unsigned int aa_walked
;
142 /* Function summary where the parameter infos are actually stored. */
143 ipa_node_params_t
*ipa_node_params_sum
= NULL
;
144 /* Vector of IPA-CP transformation data for each clone. */
145 vec
<ipcp_transformation_summary
, va_gc
> *ipcp_transformations
;
146 /* Vector where the parameter infos are actually stored. */
147 vec
<ipa_edge_args
, va_gc
> *ipa_edge_args_vector
;
149 /* Holders of ipa cgraph hooks: */
150 static struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
151 static struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
152 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
154 /* Description of a reference to an IPA constant. */
155 struct ipa_cst_ref_desc
157 /* Edge that corresponds to the statement which took the reference. */
158 struct cgraph_edge
*cs
;
159 /* Linked list of duplicates created when call graph edges are cloned. */
160 struct ipa_cst_ref_desc
*next_duplicate
;
161 /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
162 if out of control. */
166 /* Allocation pool for reference descriptions. */
168 static pool_allocator
<ipa_cst_ref_desc
> ipa_refdesc_pool
169 ("IPA-PROP ref descriptions", 32);
171 /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
172 with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
175 ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node
*node
)
177 tree fs_opts
= DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node
->decl
);
181 return !opt_for_fn (node
->decl
, optimize
) || !opt_for_fn (node
->decl
, flag_ipa_cp
);
184 /* Return index of the formal whose tree is PTREE in function which corresponds
188 ipa_get_param_decl_index_1 (vec
<ipa_param_descriptor
> descriptors
, tree ptree
)
192 count
= descriptors
.length ();
193 for (i
= 0; i
< count
; i
++)
194 if (descriptors
[i
].decl
== ptree
)
200 /* Return index of the formal whose tree is PTREE in function which corresponds
204 ipa_get_param_decl_index (struct ipa_node_params
*info
, tree ptree
)
206 return ipa_get_param_decl_index_1 (info
->descriptors
, ptree
);
209 /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
213 ipa_populate_param_decls (struct cgraph_node
*node
,
214 vec
<ipa_param_descriptor
> &descriptors
)
222 gcc_assert (gimple_has_body_p (fndecl
));
223 fnargs
= DECL_ARGUMENTS (fndecl
);
225 for (parm
= fnargs
; parm
; parm
= DECL_CHAIN (parm
))
227 descriptors
[param_num
].decl
= parm
;
228 descriptors
[param_num
].move_cost
= estimate_move_cost (TREE_TYPE (parm
),
234 /* Return how many formal parameters FNDECL has. */
237 count_formal_params (tree fndecl
)
241 gcc_assert (gimple_has_body_p (fndecl
));
243 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
249 /* Return the declaration of Ith formal parameter of the function corresponding
250 to INFO. Note there is no setter function as this array is built just once
251 using ipa_initialize_node_params. */
254 ipa_dump_param (FILE *file
, struct ipa_node_params
*info
, int i
)
256 fprintf (file
, "param #%i", i
);
257 if (info
->descriptors
[i
].decl
)
260 print_generic_expr (file
, info
->descriptors
[i
].decl
, 0);
264 /* Initialize the ipa_node_params structure associated with NODE
265 to hold PARAM_COUNT parameters. */
268 ipa_alloc_node_params (struct cgraph_node
*node
, int param_count
)
270 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
272 if (!info
->descriptors
.exists () && param_count
)
273 info
->descriptors
.safe_grow_cleared (param_count
);
276 /* Initialize the ipa_node_params structure associated with NODE by counting
277 the function parameters, creating the descriptors and populating their
281 ipa_initialize_node_params (struct cgraph_node
*node
)
283 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
285 if (!info
->descriptors
.exists ())
287 ipa_alloc_node_params (node
, count_formal_params (node
->decl
));
288 ipa_populate_param_decls (node
, info
->descriptors
);
292 /* Print the jump functions associated with call graph edge CS to file F. */
295 ipa_print_node_jump_functions_for_edge (FILE *f
, struct cgraph_edge
*cs
)
299 count
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
300 for (i
= 0; i
< count
; i
++)
302 struct ipa_jump_func
*jump_func
;
303 enum jump_func_type type
;
305 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
306 type
= jump_func
->type
;
308 fprintf (f
, " param %d: ", i
);
309 if (type
== IPA_JF_UNKNOWN
)
310 fprintf (f
, "UNKNOWN\n");
311 else if (type
== IPA_JF_CONST
)
313 tree val
= jump_func
->value
.constant
.value
;
314 fprintf (f
, "CONST: ");
315 print_generic_expr (f
, val
, 0);
316 if (TREE_CODE (val
) == ADDR_EXPR
317 && TREE_CODE (TREE_OPERAND (val
, 0)) == CONST_DECL
)
320 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (val
, 0)),
325 else if (type
== IPA_JF_PASS_THROUGH
)
327 fprintf (f
, "PASS THROUGH: ");
328 fprintf (f
, "%d, op %s",
329 jump_func
->value
.pass_through
.formal_id
,
330 get_tree_code_name(jump_func
->value
.pass_through
.operation
));
331 if (jump_func
->value
.pass_through
.operation
!= NOP_EXPR
)
334 print_generic_expr (f
,
335 jump_func
->value
.pass_through
.operand
, 0);
337 if (jump_func
->value
.pass_through
.agg_preserved
)
338 fprintf (f
, ", agg_preserved");
341 else if (type
== IPA_JF_ANCESTOR
)
343 fprintf (f
, "ANCESTOR: ");
344 fprintf (f
, "%d, offset " HOST_WIDE_INT_PRINT_DEC
,
345 jump_func
->value
.ancestor
.formal_id
,
346 jump_func
->value
.ancestor
.offset
);
347 if (jump_func
->value
.ancestor
.agg_preserved
)
348 fprintf (f
, ", agg_preserved");
352 if (jump_func
->agg
.items
)
354 struct ipa_agg_jf_item
*item
;
357 fprintf (f
, " Aggregate passed by %s:\n",
358 jump_func
->agg
.by_ref
? "reference" : "value");
359 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, j
, item
)
361 fprintf (f
, " offset: " HOST_WIDE_INT_PRINT_DEC
", ",
363 if (TYPE_P (item
->value
))
364 fprintf (f
, "clobber of " HOST_WIDE_INT_PRINT_DEC
" bits",
365 tree_to_uhwi (TYPE_SIZE (item
->value
)));
368 fprintf (f
, "cst: ");
369 print_generic_expr (f
, item
->value
, 0);
375 struct ipa_polymorphic_call_context
*ctx
376 = ipa_get_ith_polymorhic_call_context (IPA_EDGE_REF (cs
), i
);
377 if (ctx
&& !ctx
->useless_p ())
379 fprintf (f
, " Context: ");
380 ctx
->dump (dump_file
);
383 if (jump_func
->alignment
.known
)
385 fprintf (f
, " Alignment: %u, misalignment: %u\n",
386 jump_func
->alignment
.align
,
387 jump_func
->alignment
.misalign
);
390 fprintf (f
, " Unknown alignment\n");
395 /* Print the jump functions of all arguments on all call graph edges going from
399 ipa_print_node_jump_functions (FILE *f
, struct cgraph_node
*node
)
401 struct cgraph_edge
*cs
;
403 fprintf (f
, " Jump functions of caller %s/%i:\n", node
->name (),
405 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
407 if (!ipa_edge_args_info_available_for_edge_p (cs
))
410 fprintf (f
, " callsite %s/%i -> %s/%i : \n",
411 xstrdup_for_dump (node
->name ()), node
->order
,
412 xstrdup_for_dump (cs
->callee
->name ()),
414 ipa_print_node_jump_functions_for_edge (f
, cs
);
417 for (cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
419 struct cgraph_indirect_call_info
*ii
;
420 if (!ipa_edge_args_info_available_for_edge_p (cs
))
423 ii
= cs
->indirect_info
;
424 if (ii
->agg_contents
)
425 fprintf (f
, " indirect %s callsite, calling param %i, "
426 "offset " HOST_WIDE_INT_PRINT_DEC
", %s",
427 ii
->member_ptr
? "member ptr" : "aggregate",
428 ii
->param_index
, ii
->offset
,
429 ii
->by_ref
? "by reference" : "by_value");
431 fprintf (f
, " indirect %s callsite, calling param %i, "
432 "offset " HOST_WIDE_INT_PRINT_DEC
,
433 ii
->polymorphic
? "polymorphic" : "simple", ii
->param_index
,
438 fprintf (f
, ", for stmt ");
439 print_gimple_stmt (f
, cs
->call_stmt
, 0, TDF_SLIM
);
444 ii
->context
.dump (f
);
445 ipa_print_node_jump_functions_for_edge (f
, cs
);
449 /* Print ipa_jump_func data structures of all nodes in the call graph to F. */
452 ipa_print_all_jump_functions (FILE *f
)
454 struct cgraph_node
*node
;
456 fprintf (f
, "\nJump functions:\n");
457 FOR_EACH_FUNCTION (node
)
459 ipa_print_node_jump_functions (f
, node
);
463 /* Set jfunc to be a know-really nothing jump function. */
466 ipa_set_jf_unknown (struct ipa_jump_func
*jfunc
)
468 jfunc
->type
= IPA_JF_UNKNOWN
;
469 jfunc
->alignment
.known
= false;
472 /* Set JFUNC to be a copy of another jmp (to be used by jump function
473 combination code). The two functions will share their rdesc. */
476 ipa_set_jf_cst_copy (struct ipa_jump_func
*dst
,
477 struct ipa_jump_func
*src
)
480 gcc_checking_assert (src
->type
== IPA_JF_CONST
);
481 dst
->type
= IPA_JF_CONST
;
482 dst
->value
.constant
= src
->value
.constant
;
485 /* Set JFUNC to be a constant jmp function. */
488 ipa_set_jf_constant (struct ipa_jump_func
*jfunc
, tree constant
,
489 struct cgraph_edge
*cs
)
491 constant
= unshare_expr (constant
);
492 if (constant
&& EXPR_P (constant
))
493 SET_EXPR_LOCATION (constant
, UNKNOWN_LOCATION
);
494 jfunc
->type
= IPA_JF_CONST
;
495 jfunc
->value
.constant
.value
= unshare_expr_without_location (constant
);
497 if (TREE_CODE (constant
) == ADDR_EXPR
498 && TREE_CODE (TREE_OPERAND (constant
, 0)) == FUNCTION_DECL
)
500 struct ipa_cst_ref_desc
*rdesc
;
502 rdesc
= ipa_refdesc_pool
.allocate ();
504 rdesc
->next_duplicate
= NULL
;
506 jfunc
->value
.constant
.rdesc
= rdesc
;
509 jfunc
->value
.constant
.rdesc
= NULL
;
512 /* Set JFUNC to be a simple pass-through jump function. */
514 ipa_set_jf_simple_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
517 jfunc
->type
= IPA_JF_PASS_THROUGH
;
518 jfunc
->value
.pass_through
.operand
= NULL_TREE
;
519 jfunc
->value
.pass_through
.formal_id
= formal_id
;
520 jfunc
->value
.pass_through
.operation
= NOP_EXPR
;
521 jfunc
->value
.pass_through
.agg_preserved
= agg_preserved
;
524 /* Set JFUNC to be an arithmetic pass through jump function. */
527 ipa_set_jf_arith_pass_through (struct ipa_jump_func
*jfunc
, int formal_id
,
528 tree operand
, enum tree_code operation
)
530 jfunc
->type
= IPA_JF_PASS_THROUGH
;
531 jfunc
->value
.pass_through
.operand
= unshare_expr_without_location (operand
);
532 jfunc
->value
.pass_through
.formal_id
= formal_id
;
533 jfunc
->value
.pass_through
.operation
= operation
;
534 jfunc
->value
.pass_through
.agg_preserved
= false;
537 /* Set JFUNC to be an ancestor jump function. */
540 ipa_set_ancestor_jf (struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
,
541 int formal_id
, bool agg_preserved
)
543 jfunc
->type
= IPA_JF_ANCESTOR
;
544 jfunc
->value
.ancestor
.formal_id
= formal_id
;
545 jfunc
->value
.ancestor
.offset
= offset
;
546 jfunc
->value
.ancestor
.agg_preserved
= agg_preserved
;
549 /* Get IPA BB information about the given BB. FBI is the context of analyzis
550 of this function body. */
552 static struct ipa_bb_info
*
553 ipa_get_bb_info (struct func_body_info
*fbi
, basic_block bb
)
555 gcc_checking_assert (fbi
);
556 return &fbi
->bb_infos
[bb
->index
];
559 /* Structure to be passed in between detect_type_change and
560 check_stmt_for_type_change. */
562 struct prop_type_change_info
564 /* Offset into the object where there is the virtual method pointer we are
566 HOST_WIDE_INT offset
;
567 /* The declaration or SSA_NAME pointer of the base that we are checking for
570 /* Set to true if dynamic type change has been detected. */
571 bool type_maybe_changed
;
574 /* Return true if STMT can modify a virtual method table pointer.
576 This function makes special assumptions about both constructors and
577 destructors which are all the functions that are allowed to alter the VMT
578 pointers. It assumes that destructors begin with assignment into all VMT
579 pointers and that constructors essentially look in the following way:
581 1) The very first thing they do is that they call constructors of ancestor
582 sub-objects that have them.
584 2) Then VMT pointers of this and all its ancestors is set to new values
585 corresponding to the type corresponding to the constructor.
587 3) Only afterwards, other stuff such as constructor of member sub-objects
588 and the code written by the user is run. Only this may include calling
589 virtual functions, directly or indirectly.
591 There is no way to call a constructor of an ancestor sub-object in any
594 This means that we do not have to care whether constructors get the correct
595 type information because they will always change it (in fact, if we define
596 the type to be given by the VMT pointer, it is undefined).
598 The most important fact to derive from the above is that if, for some
599 statement in the section 3, we try to detect whether the dynamic type has
600 changed, we can safely ignore all calls as we examine the function body
601 backwards until we reach statements in section 2 because these calls cannot
602 be ancestor constructors or destructors (if the input is not bogus) and so
603 do not change the dynamic type (this holds true only for automatically
604 allocated objects but at the moment we devirtualize only these). We then
605 must detect that statements in section 2 change the dynamic type and can try
606 to derive the new type. That is enough and we can stop, we will never see
607 the calls into constructors of sub-objects in this code. Therefore we can
608 safely ignore all call statements that we traverse.
612 stmt_may_be_vtbl_ptr_store (gimple stmt
)
614 if (is_gimple_call (stmt
))
616 if (gimple_clobber_p (stmt
))
618 else if (is_gimple_assign (stmt
))
620 tree lhs
= gimple_assign_lhs (stmt
);
622 if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs
)))
624 if (flag_strict_aliasing
625 && !POINTER_TYPE_P (TREE_TYPE (lhs
)))
628 if (TREE_CODE (lhs
) == COMPONENT_REF
629 && !DECL_VIRTUAL_P (TREE_OPERAND (lhs
, 1)))
631 /* In the future we might want to use get_base_ref_and_offset to find
632 if there is a field corresponding to the offset and if so, proceed
633 almost like if it was a component ref. */
639 /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
640 to check whether a particular statement may modify the virtual table
641 pointerIt stores its result into DATA, which points to a
642 prop_type_change_info structure. */
645 check_stmt_for_type_change (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
647 gimple stmt
= SSA_NAME_DEF_STMT (vdef
);
648 struct prop_type_change_info
*tci
= (struct prop_type_change_info
*) data
;
650 if (stmt_may_be_vtbl_ptr_store (stmt
))
652 tci
->type_maybe_changed
= true;
659 /* See if ARG is PARAM_DECl describing instance passed by pointer
660 or reference in FUNCTION. Return false if the dynamic type may change
661 in between beggining of the function until CALL is invoked.
663 Generally functions are not allowed to change type of such instances,
664 but they call destructors. We assume that methods can not destroy the THIS
665 pointer. Also as a special cases, constructor and destructors may change
666 type of the THIS pointer. */
669 param_type_may_change_p (tree function
, tree arg
, gimple call
)
671 /* Pure functions can not do any changes on the dynamic type;
672 that require writting to memory. */
673 if (flags_from_decl_or_type (function
) & (ECF_PURE
| ECF_CONST
))
675 /* We need to check if we are within inlined consturctor
676 or destructor (ideally we would have way to check that the
677 inline cdtor is actually working on ARG, but we don't have
678 easy tie on this, so punt on all non-pure cdtors.
679 We may also record the types of cdtors and once we know type
680 of the instance match them.
682 Also code unification optimizations may merge calls from
683 different blocks making return values unreliable. So
684 do nothing during late optimization. */
685 if (DECL_STRUCT_FUNCTION (function
)->after_inlining
)
687 if (TREE_CODE (arg
) == SSA_NAME
688 && SSA_NAME_IS_DEFAULT_DEF (arg
)
689 && TREE_CODE (SSA_NAME_VAR (arg
)) == PARM_DECL
)
691 /* Normal (non-THIS) argument. */
692 if ((SSA_NAME_VAR (arg
) != DECL_ARGUMENTS (function
)
693 || TREE_CODE (TREE_TYPE (function
)) != METHOD_TYPE
)
694 /* THIS pointer of an method - here we we want to watch constructors
695 and destructors as those definitely may change the dynamic
697 || (TREE_CODE (TREE_TYPE (function
)) == METHOD_TYPE
698 && !DECL_CXX_CONSTRUCTOR_P (function
)
699 && !DECL_CXX_DESTRUCTOR_P (function
)
700 && (SSA_NAME_VAR (arg
) == DECL_ARGUMENTS (function
))))
702 /* Walk the inline stack and watch out for ctors/dtors. */
703 for (tree block
= gimple_block (call
); block
&& TREE_CODE (block
) == BLOCK
;
704 block
= BLOCK_SUPERCONTEXT (block
))
705 if (inlined_polymorphic_ctor_dtor_block_p (block
, false))
713 /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
714 callsite CALL) by looking for assignments to its virtual table pointer. If
715 it is, return true and fill in the jump function JFUNC with relevant type
716 information or set it to unknown. ARG is the object itself (not a pointer
717 to it, unless dereferenced). BASE is the base of the memory access as
718 returned by get_ref_base_and_extent, as is the offset.
720 This is helper function for detect_type_change and detect_type_change_ssa
721 that does the heavy work which is usually unnecesary. */
724 detect_type_change_from_memory_writes (tree arg
, tree base
, tree comp_type
,
725 gcall
*call
, struct ipa_jump_func
*jfunc
,
726 HOST_WIDE_INT offset
)
728 struct prop_type_change_info tci
;
730 bool entry_reached
= false;
732 gcc_checking_assert (DECL_P (arg
)
733 || TREE_CODE (arg
) == MEM_REF
734 || handled_component_p (arg
));
736 comp_type
= TYPE_MAIN_VARIANT (comp_type
);
738 /* Const calls cannot call virtual methods through VMT and so type changes do
740 if (!flag_devirtualize
|| !gimple_vuse (call
)
741 /* Be sure expected_type is polymorphic. */
743 || TREE_CODE (comp_type
) != RECORD_TYPE
744 || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))
745 || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type
))))
748 ao_ref_init (&ao
, arg
);
751 ao
.size
= POINTER_SIZE
;
752 ao
.max_size
= ao
.size
;
755 tci
.object
= get_base_address (arg
);
756 tci
.type_maybe_changed
= false;
758 walk_aliased_vdefs (&ao
, gimple_vuse (call
), check_stmt_for_type_change
,
759 &tci
, NULL
, &entry_reached
);
760 if (!tci
.type_maybe_changed
)
763 ipa_set_jf_unknown (jfunc
);
767 /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
768 If it is, return true and fill in the jump function JFUNC with relevant type
769 information or set it to unknown. ARG is the object itself (not a pointer
770 to it, unless dereferenced). BASE is the base of the memory access as
771 returned by get_ref_base_and_extent, as is the offset. */
774 detect_type_change (tree arg
, tree base
, tree comp_type
, gcall
*call
,
775 struct ipa_jump_func
*jfunc
, HOST_WIDE_INT offset
)
777 if (!flag_devirtualize
)
780 if (TREE_CODE (base
) == MEM_REF
781 && !param_type_may_change_p (current_function_decl
,
782 TREE_OPERAND (base
, 0),
785 return detect_type_change_from_memory_writes (arg
, base
, comp_type
,
786 call
, jfunc
, offset
);
789 /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
790 SSA name (its dereference will become the base and the offset is assumed to
794 detect_type_change_ssa (tree arg
, tree comp_type
,
795 gcall
*call
, struct ipa_jump_func
*jfunc
)
797 gcc_checking_assert (TREE_CODE (arg
) == SSA_NAME
);
798 if (!flag_devirtualize
799 || !POINTER_TYPE_P (TREE_TYPE (arg
)))
802 if (!param_type_may_change_p (current_function_decl
, arg
, call
))
805 arg
= build2 (MEM_REF
, ptr_type_node
, arg
,
806 build_int_cst (ptr_type_node
, 0));
808 return detect_type_change_from_memory_writes (arg
, arg
, comp_type
,
812 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
813 boolean variable pointed to by DATA. */
816 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
819 bool *b
= (bool *) data
;
824 /* Return true if we have already walked so many statements in AA that we
825 should really just start giving up. */
828 aa_overwalked (struct func_body_info
*fbi
)
830 gcc_checking_assert (fbi
);
831 return fbi
->aa_walked
> (unsigned) PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS
);
834 /* Find the nearest valid aa status for parameter specified by INDEX that
837 static struct param_aa_status
*
838 find_dominating_aa_status (struct func_body_info
*fbi
, basic_block bb
,
843 bb
= get_immediate_dominator (CDI_DOMINATORS
, bb
);
846 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
847 if (!bi
->param_aa_statuses
.is_empty ()
848 && bi
->param_aa_statuses
[index
].valid
)
849 return &bi
->param_aa_statuses
[index
];
853 /* Get AA status structure for the given BB and parameter with INDEX. Allocate
854 structures and/or intialize the result with a dominating description as
857 static struct param_aa_status
*
858 parm_bb_aa_status_for_bb (struct func_body_info
*fbi
, basic_block bb
,
861 gcc_checking_assert (fbi
);
862 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
863 if (bi
->param_aa_statuses
.is_empty ())
864 bi
->param_aa_statuses
.safe_grow_cleared (fbi
->param_count
);
865 struct param_aa_status
*paa
= &bi
->param_aa_statuses
[index
];
868 gcc_checking_assert (!paa
->parm_modified
869 && !paa
->ref_modified
870 && !paa
->pt_modified
);
871 struct param_aa_status
*dom_paa
;
872 dom_paa
= find_dominating_aa_status (fbi
, bb
, index
);
882 /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
883 a value known not to be modified in this function before reaching the
884 statement STMT. FBI holds information about the function we have so far
885 gathered but do not survive the summary building stage. */
888 parm_preserved_before_stmt_p (struct func_body_info
*fbi
, int index
,
889 gimple stmt
, tree parm_load
)
891 struct param_aa_status
*paa
;
892 bool modified
= false;
895 /* FIXME: FBI can be NULL if we are being called from outside
896 ipa_node_analysis or ipcp_transform_function, which currently happens
897 during inlining analysis. It would be great to extend fbi's lifetime and
898 always have it. Currently, we are just not afraid of too much walking in
902 if (aa_overwalked (fbi
))
904 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
905 if (paa
->parm_modified
)
911 gcc_checking_assert (gimple_vuse (stmt
) != NULL_TREE
);
912 ao_ref_init (&refd
, parm_load
);
913 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
916 fbi
->aa_walked
+= walked
;
918 paa
->parm_modified
= true;
922 /* If STMT is an assignment that loads a value from an parameter declaration,
923 return the index of the parameter in ipa_node_params which has not been
924 modified. Otherwise return -1. */
927 load_from_unmodified_param (struct func_body_info
*fbi
,
928 vec
<ipa_param_descriptor
> descriptors
,
934 if (!gimple_assign_single_p (stmt
))
937 op1
= gimple_assign_rhs1 (stmt
);
938 if (TREE_CODE (op1
) != PARM_DECL
)
941 index
= ipa_get_param_decl_index_1 (descriptors
, op1
);
943 || !parm_preserved_before_stmt_p (fbi
, index
, stmt
, op1
))
949 /* Return true if memory reference REF (which must be a load through parameter
950 with INDEX) loads data that are known to be unmodified in this function
951 before reaching statement STMT. */
954 parm_ref_data_preserved_p (struct func_body_info
*fbi
,
955 int index
, gimple stmt
, tree ref
)
957 struct param_aa_status
*paa
;
958 bool modified
= false;
961 /* FIXME: FBI can be NULL if we are being called from outside
962 ipa_node_analysis or ipcp_transform_function, which currently happens
963 during inlining analysis. It would be great to extend fbi's lifetime and
964 always have it. Currently, we are just not afraid of too much walking in
968 if (aa_overwalked (fbi
))
970 paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (stmt
), index
);
971 if (paa
->ref_modified
)
977 gcc_checking_assert (gimple_vuse (stmt
));
978 ao_ref_init (&refd
, ref
);
979 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
,
982 fbi
->aa_walked
+= walked
;
984 paa
->ref_modified
= true;
988 /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
989 is known to be unmodified in this function before reaching call statement
990 CALL into which it is passed. FBI describes the function body. */
993 parm_ref_data_pass_through_p (struct func_body_info
*fbi
, int index
,
994 gimple call
, tree parm
)
996 bool modified
= false;
999 /* It's unnecessary to calculate anything about memory contnets for a const
1000 function because it is not goin to use it. But do not cache the result
1001 either. Also, no such calculations for non-pointers. */
1002 if (!gimple_vuse (call
)
1003 || !POINTER_TYPE_P (TREE_TYPE (parm
))
1004 || aa_overwalked (fbi
))
1007 struct param_aa_status
*paa
= parm_bb_aa_status_for_bb (fbi
, gimple_bb (call
),
1009 if (paa
->pt_modified
)
1012 ao_ref_init_from_ptr_and_size (&refd
, parm
, NULL_TREE
);
1013 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (call
), mark_modified
,
1015 fbi
->aa_walked
+= walked
;
1017 paa
->pt_modified
= true;
1021 /* Return true if we can prove that OP is a memory reference loading unmodified
1022 data from an aggregate passed as a parameter and if the aggregate is passed
1023 by reference, that the alias type of the load corresponds to the type of the
1024 formal parameter (so that we can rely on this type for TBAA in callers).
1025 INFO and PARMS_AINFO describe parameters of the current function (but the
1026 latter can be NULL), STMT is the load statement. If function returns true,
1027 *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
1028 within the aggregate and whether it is a load from a value passed by
1029 reference respectively. */
1032 ipa_load_from_parm_agg_1 (struct func_body_info
*fbi
,
1033 vec
<ipa_param_descriptor
> descriptors
,
1034 gimple stmt
, tree op
, int *index_p
,
1035 HOST_WIDE_INT
*offset_p
, HOST_WIDE_INT
*size_p
,
1039 HOST_WIDE_INT size
, max_size
;
1040 tree base
= get_ref_base_and_extent (op
, offset_p
, &size
, &max_size
);
1042 if (max_size
== -1 || max_size
!= size
|| *offset_p
< 0)
1047 int index
= ipa_get_param_decl_index_1 (descriptors
, base
);
1049 && parm_preserved_before_stmt_p (fbi
, index
, stmt
, op
))
1060 if (TREE_CODE (base
) != MEM_REF
1061 || TREE_CODE (TREE_OPERAND (base
, 0)) != SSA_NAME
1062 || !integer_zerop (TREE_OPERAND (base
, 1)))
1065 if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base
, 0)))
1067 tree parm
= SSA_NAME_VAR (TREE_OPERAND (base
, 0));
1068 index
= ipa_get_param_decl_index_1 (descriptors
, parm
);
1072 /* This branch catches situations where a pointer parameter is not a
1073 gimple register, for example:
1075 void hip7(S*) (struct S * p)
1077 void (*<T2e4>) (struct S *) D.1867;
1082 D.1867_2 = p.1_1->f;
1087 gimple def
= SSA_NAME_DEF_STMT (TREE_OPERAND (base
, 0));
1088 index
= load_from_unmodified_param (fbi
, descriptors
, def
);
1092 && parm_ref_data_preserved_p (fbi
, index
, stmt
, op
))
1103 /* Just like the previous function, just without the param_analysis_info
1104 pointer, for users outside of this file. */
1107 ipa_load_from_parm_agg (struct ipa_node_params
*info
, gimple stmt
,
1108 tree op
, int *index_p
, HOST_WIDE_INT
*offset_p
,
1111 return ipa_load_from_parm_agg_1 (NULL
, info
->descriptors
, stmt
, op
, index_p
,
1112 offset_p
, NULL
, by_ref_p
);
1115 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
1116 of an assignment statement STMT, try to determine whether we are actually
1117 handling any of the following cases and construct an appropriate jump
1118 function into JFUNC if so:
1120 1) The passed value is loaded from a formal parameter which is not a gimple
1121 register (most probably because it is addressable, the value has to be
1122 scalar) and we can guarantee the value has not changed. This case can
1123 therefore be described by a simple pass-through jump function. For example:
1132 2) The passed value can be described by a simple arithmetic pass-through
1139 D.2064_4 = a.1(D) + 4;
1142 This case can also occur in combination of the previous one, e.g.:
1150 D.2064_4 = a.0_3 + 4;
1153 3) The passed value is an address of an object within another one (which
1154 also passed by reference). Such situations are described by an ancestor
1155 jump function and describe situations such as:
1157 B::foo() (struct B * const this)
1161 D.1845_2 = &this_1(D)->D.1748;
1164 INFO is the structure describing individual parameters access different
1165 stages of IPA optimizations. PARMS_AINFO contains the information that is
1166 only needed for intraprocedural analysis. */
1169 compute_complex_assign_jump_func (struct func_body_info
*fbi
,
1170 struct ipa_node_params
*info
,
1171 struct ipa_jump_func
*jfunc
,
1172 gcall
*call
, gimple stmt
, tree name
,
1175 HOST_WIDE_INT offset
, size
, max_size
;
1176 tree op1
, tc_ssa
, base
, ssa
;
1179 op1
= gimple_assign_rhs1 (stmt
);
1181 if (TREE_CODE (op1
) == SSA_NAME
)
1183 if (SSA_NAME_IS_DEFAULT_DEF (op1
))
1184 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (op1
));
1186 index
= load_from_unmodified_param (fbi
, info
->descriptors
,
1187 SSA_NAME_DEF_STMT (op1
));
1192 index
= load_from_unmodified_param (fbi
, info
->descriptors
, stmt
);
1193 tc_ssa
= gimple_assign_lhs (stmt
);
1198 tree op2
= gimple_assign_rhs2 (stmt
);
1202 if (!is_gimple_ip_invariant (op2
)
1203 || (TREE_CODE_CLASS (gimple_expr_code (stmt
)) != tcc_comparison
1204 && !useless_type_conversion_p (TREE_TYPE (name
),
1208 ipa_set_jf_arith_pass_through (jfunc
, index
, op2
,
1209 gimple_assign_rhs_code (stmt
));
1211 else if (gimple_assign_single_p (stmt
))
1213 bool agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, tc_ssa
);
1214 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
1219 if (TREE_CODE (op1
) != ADDR_EXPR
)
1221 op1
= TREE_OPERAND (op1
, 0);
1222 if (TREE_CODE (TREE_TYPE (op1
)) != RECORD_TYPE
)
1224 base
= get_ref_base_and_extent (op1
, &offset
, &size
, &max_size
);
1225 if (TREE_CODE (base
) != MEM_REF
1226 /* If this is a varying address, punt. */
1228 || max_size
!= size
)
1230 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
1231 ssa
= TREE_OPERAND (base
, 0);
1232 if (TREE_CODE (ssa
) != SSA_NAME
1233 || !SSA_NAME_IS_DEFAULT_DEF (ssa
)
1237 /* Dynamic types are changed in constructors and destructors. */
1238 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (ssa
));
1239 if (index
>= 0 && param_type
&& POINTER_TYPE_P (param_type
))
1240 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1241 parm_ref_data_pass_through_p (fbi
, index
, call
, ssa
));
1244 /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
1247 iftmp.1_3 = &obj_2(D)->D.1762;
1249 The base of the MEM_REF must be a default definition SSA NAME of a
1250 parameter. Return NULL_TREE if it looks otherwise. If case of success, the
1251 whole MEM_REF expression is returned and the offset calculated from any
1252 handled components and the MEM_REF itself is stored into *OFFSET. The whole
1253 RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
1256 get_ancestor_addr_info (gimple assign
, tree
*obj_p
, HOST_WIDE_INT
*offset
)
1258 HOST_WIDE_INT size
, max_size
;
1259 tree expr
, parm
, obj
;
1261 if (!gimple_assign_single_p (assign
))
1263 expr
= gimple_assign_rhs1 (assign
);
1265 if (TREE_CODE (expr
) != ADDR_EXPR
)
1267 expr
= TREE_OPERAND (expr
, 0);
1269 expr
= get_ref_base_and_extent (expr
, offset
, &size
, &max_size
);
1271 if (TREE_CODE (expr
) != MEM_REF
1272 /* If this is a varying address, punt. */
1277 parm
= TREE_OPERAND (expr
, 0);
1278 if (TREE_CODE (parm
) != SSA_NAME
1279 || !SSA_NAME_IS_DEFAULT_DEF (parm
)
1280 || TREE_CODE (SSA_NAME_VAR (parm
)) != PARM_DECL
)
1283 *offset
+= mem_ref_offset (expr
).to_short_addr () * BITS_PER_UNIT
;
1289 /* Given that an actual argument is an SSA_NAME that is a result of a phi
1290 statement PHI, try to find out whether NAME is in fact a
1291 multiple-inheritance typecast from a descendant into an ancestor of a formal
1292 parameter and thus can be described by an ancestor jump function and if so,
1293 write the appropriate function into JFUNC.
1295 Essentially we want to match the following pattern:
1303 iftmp.1_3 = &obj_2(D)->D.1762;
1306 # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
1307 D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
1311 compute_complex_ancestor_jump_func (struct func_body_info
*fbi
,
1312 struct ipa_node_params
*info
,
1313 struct ipa_jump_func
*jfunc
,
1314 gcall
*call
, gphi
*phi
)
1316 HOST_WIDE_INT offset
;
1317 gimple assign
, cond
;
1318 basic_block phi_bb
, assign_bb
, cond_bb
;
1319 tree tmp
, parm
, expr
, obj
;
1322 if (gimple_phi_num_args (phi
) != 2)
1325 if (integer_zerop (PHI_ARG_DEF (phi
, 1)))
1326 tmp
= PHI_ARG_DEF (phi
, 0);
1327 else if (integer_zerop (PHI_ARG_DEF (phi
, 0)))
1328 tmp
= PHI_ARG_DEF (phi
, 1);
1331 if (TREE_CODE (tmp
) != SSA_NAME
1332 || SSA_NAME_IS_DEFAULT_DEF (tmp
)
1333 || !POINTER_TYPE_P (TREE_TYPE (tmp
))
1334 || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp
))) != RECORD_TYPE
)
1337 assign
= SSA_NAME_DEF_STMT (tmp
);
1338 assign_bb
= gimple_bb (assign
);
1339 if (!single_pred_p (assign_bb
))
1341 expr
= get_ancestor_addr_info (assign
, &obj
, &offset
);
1344 parm
= TREE_OPERAND (expr
, 0);
1345 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (parm
));
1349 cond_bb
= single_pred (assign_bb
);
1350 cond
= last_stmt (cond_bb
);
1352 || gimple_code (cond
) != GIMPLE_COND
1353 || gimple_cond_code (cond
) != NE_EXPR
1354 || gimple_cond_lhs (cond
) != parm
1355 || !integer_zerop (gimple_cond_rhs (cond
)))
1358 phi_bb
= gimple_bb (phi
);
1359 for (i
= 0; i
< 2; i
++)
1361 basic_block pred
= EDGE_PRED (phi_bb
, i
)->src
;
1362 if (pred
!= assign_bb
&& pred
!= cond_bb
)
1366 ipa_set_ancestor_jf (jfunc
, offset
, index
,
1367 parm_ref_data_pass_through_p (fbi
, index
, call
, parm
));
1370 /* Inspect the given TYPE and return true iff it has the same structure (the
1371 same number of fields of the same types) as a C++ member pointer. If
1372 METHOD_PTR and DELTA are non-NULL, store the trees representing the
1373 corresponding fields there. */
1376 type_like_member_ptr_p (tree type
, tree
*method_ptr
, tree
*delta
)
1380 if (TREE_CODE (type
) != RECORD_TYPE
)
1383 fld
= TYPE_FIELDS (type
);
1384 if (!fld
|| !POINTER_TYPE_P (TREE_TYPE (fld
))
1385 || TREE_CODE (TREE_TYPE (TREE_TYPE (fld
))) != METHOD_TYPE
1386 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1392 fld
= DECL_CHAIN (fld
);
1393 if (!fld
|| INTEGRAL_TYPE_P (fld
)
1394 || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld
)))
1399 if (DECL_CHAIN (fld
))
1405 /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
1406 return the rhs of its defining statement. Otherwise return RHS as it
1410 get_ssa_def_if_simple_copy (tree rhs
)
1412 while (TREE_CODE (rhs
) == SSA_NAME
&& !SSA_NAME_IS_DEFAULT_DEF (rhs
))
1414 gimple def_stmt
= SSA_NAME_DEF_STMT (rhs
);
1416 if (gimple_assign_single_p (def_stmt
))
1417 rhs
= gimple_assign_rhs1 (def_stmt
);
1424 /* Simple linked list, describing known contents of an aggregate beforere
1427 struct ipa_known_agg_contents_list
1429 /* Offset and size of the described part of the aggregate. */
1430 HOST_WIDE_INT offset
, size
;
1431 /* Known constant value or NULL if the contents is known to be unknown. */
1433 /* Pointer to the next structure in the list. */
1434 struct ipa_known_agg_contents_list
*next
;
1437 /* Find the proper place in linked list of ipa_known_agg_contents_list
1438 structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
1439 unless there is a partial overlap, in which case return NULL, or such
1440 element is already there, in which case set *ALREADY_THERE to true. */
1442 static struct ipa_known_agg_contents_list
**
1443 get_place_in_agg_contents_list (struct ipa_known_agg_contents_list
**list
,
1444 HOST_WIDE_INT lhs_offset
,
1445 HOST_WIDE_INT lhs_size
,
1446 bool *already_there
)
1448 struct ipa_known_agg_contents_list
**p
= list
;
1449 while (*p
&& (*p
)->offset
< lhs_offset
)
1451 if ((*p
)->offset
+ (*p
)->size
> lhs_offset
)
1456 if (*p
&& (*p
)->offset
< lhs_offset
+ lhs_size
)
1458 if ((*p
)->offset
== lhs_offset
&& (*p
)->size
== lhs_size
)
1459 /* We already know this value is subsequently overwritten with
1461 *already_there
= true;
1463 /* Otherwise this is a partial overlap which we cannot
1470 /* Build aggregate jump function from LIST, assuming there are exactly
1471 CONST_COUNT constant entries there and that th offset of the passed argument
1472 is ARG_OFFSET and store it into JFUNC. */
1475 build_agg_jump_func_from_list (struct ipa_known_agg_contents_list
*list
,
1476 int const_count
, HOST_WIDE_INT arg_offset
,
1477 struct ipa_jump_func
*jfunc
)
1479 vec_alloc (jfunc
->agg
.items
, const_count
);
1484 struct ipa_agg_jf_item item
;
1485 item
.offset
= list
->offset
- arg_offset
;
1486 gcc_assert ((item
.offset
% BITS_PER_UNIT
) == 0);
1487 item
.value
= unshare_expr_without_location (list
->constant
);
1488 jfunc
->agg
.items
->quick_push (item
);
1494 /* Traverse statements from CALL backwards, scanning whether an aggregate given
1495 in ARG is filled in with constant values. ARG can either be an aggregate
1496 expression or a pointer to an aggregate. ARG_TYPE is the type of the
1497 aggregate. JFUNC is the jump function into which the constants are
1498 subsequently stored. */
1501 determine_locally_known_aggregate_parts (gcall
*call
, tree arg
,
1503 struct ipa_jump_func
*jfunc
)
1505 struct ipa_known_agg_contents_list
*list
= NULL
;
1506 int item_count
= 0, const_count
= 0;
1507 HOST_WIDE_INT arg_offset
, arg_size
;
1508 gimple_stmt_iterator gsi
;
1510 bool check_ref
, by_ref
;
1513 /* The function operates in three stages. First, we prepare check_ref, r,
1514 arg_base and arg_offset based on what is actually passed as an actual
1517 if (POINTER_TYPE_P (arg_type
))
1520 if (TREE_CODE (arg
) == SSA_NAME
)
1523 if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type
))))
1528 type_size
= TYPE_SIZE (TREE_TYPE (arg_type
));
1529 arg_size
= tree_to_uhwi (type_size
);
1530 ao_ref_init_from_ptr_and_size (&r
, arg_base
, NULL_TREE
);
1532 else if (TREE_CODE (arg
) == ADDR_EXPR
)
1534 HOST_WIDE_INT arg_max_size
;
1536 arg
= TREE_OPERAND (arg
, 0);
1537 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1539 if (arg_max_size
== -1
1540 || arg_max_size
!= arg_size
1543 if (DECL_P (arg_base
))
1546 ao_ref_init (&r
, arg_base
);
1556 HOST_WIDE_INT arg_max_size
;
1558 gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg
)));
1562 arg_base
= get_ref_base_and_extent (arg
, &arg_offset
, &arg_size
,
1564 if (arg_max_size
== -1
1565 || arg_max_size
!= arg_size
1569 ao_ref_init (&r
, arg
);
1572 /* Second stage walks back the BB, looks at individual statements and as long
1573 as it is confident of how the statements affect contents of the
1574 aggregates, it builds a sorted linked list of ipa_agg_jf_list structures
1576 gsi
= gsi_for_stmt (call
);
1578 for (; !gsi_end_p (gsi
); gsi_prev (&gsi
))
1580 struct ipa_known_agg_contents_list
*n
, **p
;
1581 gimple stmt
= gsi_stmt (gsi
);
1582 HOST_WIDE_INT lhs_offset
, lhs_size
, lhs_max_size
;
1583 tree lhs
, rhs
, lhs_base
;
1585 if (!stmt_may_clobber_ref_p_1 (stmt
, &r
))
1587 if (!gimple_assign_single_p (stmt
))
1590 lhs
= gimple_assign_lhs (stmt
);
1591 rhs
= gimple_assign_rhs1 (stmt
);
1592 if (!is_gimple_reg_type (TREE_TYPE (rhs
))
1593 || TREE_CODE (lhs
) == BIT_FIELD_REF
1594 || contains_bitfld_component_ref_p (lhs
))
1597 lhs_base
= get_ref_base_and_extent (lhs
, &lhs_offset
, &lhs_size
,
1599 if (lhs_max_size
== -1
1600 || lhs_max_size
!= lhs_size
)
1605 if (TREE_CODE (lhs_base
) != MEM_REF
1606 || TREE_OPERAND (lhs_base
, 0) != arg_base
1607 || !integer_zerop (TREE_OPERAND (lhs_base
, 1)))
1610 else if (lhs_base
!= arg_base
)
1612 if (DECL_P (lhs_base
))
1618 bool already_there
= false;
1619 p
= get_place_in_agg_contents_list (&list
, lhs_offset
, lhs_size
,
1626 rhs
= get_ssa_def_if_simple_copy (rhs
);
1627 n
= XALLOCA (struct ipa_known_agg_contents_list
);
1629 n
->offset
= lhs_offset
;
1630 if (is_gimple_ip_invariant (rhs
))
1636 n
->constant
= NULL_TREE
;
1641 if (const_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
)
1642 || item_count
== 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
1646 /* Third stage just goes over the list and creates an appropriate vector of
1647 ipa_agg_jf_item structures out of it, of sourse only if there are
1648 any known constants to begin with. */
1652 jfunc
->agg
.by_ref
= by_ref
;
1653 build_agg_jump_func_from_list (list
, const_count
, arg_offset
, jfunc
);
1658 ipa_get_callee_param_type (struct cgraph_edge
*e
, int i
)
1661 tree type
= (e
->callee
1662 ? TREE_TYPE (e
->callee
->decl
)
1663 : gimple_call_fntype (e
->call_stmt
));
1664 tree t
= TYPE_ARG_TYPES (type
);
1666 for (n
= 0; n
< i
; n
++)
1673 return TREE_VALUE (t
);
1676 t
= DECL_ARGUMENTS (e
->callee
->decl
);
1677 for (n
= 0; n
< i
; n
++)
1684 return TREE_TYPE (t
);
1688 /* Compute jump function for all arguments of callsite CS and insert the
1689 information in the jump_functions array in the ipa_edge_args corresponding
1690 to this callsite. */
1693 ipa_compute_jump_functions_for_edge (struct func_body_info
*fbi
,
1694 struct cgraph_edge
*cs
)
1696 struct ipa_node_params
*info
= IPA_NODE_REF (cs
->caller
);
1697 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1698 gcall
*call
= cs
->call_stmt
;
1699 int n
, arg_num
= gimple_call_num_args (call
);
1700 bool useful_context
= false;
1702 if (arg_num
== 0 || args
->jump_functions
)
1704 vec_safe_grow_cleared (args
->jump_functions
, arg_num
);
1705 if (flag_devirtualize
)
1706 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, arg_num
);
1708 if (gimple_call_internal_p (call
))
1710 if (ipa_func_spec_opts_forbid_analysis_p (cs
->caller
))
1713 for (n
= 0; n
< arg_num
; n
++)
1715 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, n
);
1716 tree arg
= gimple_call_arg (call
, n
);
1717 tree param_type
= ipa_get_callee_param_type (cs
, n
);
1718 if (flag_devirtualize
&& POINTER_TYPE_P (TREE_TYPE (arg
)))
1721 struct ipa_polymorphic_call_context
context (cs
->caller
->decl
,
1724 context
.get_dynamic_type (instance
, arg
, NULL
, cs
->call_stmt
);
1725 *ipa_get_ith_polymorhic_call_context (args
, n
) = context
;
1726 if (!context
.useless_p ())
1727 useful_context
= true;
1730 if (POINTER_TYPE_P (TREE_TYPE(arg
)))
1732 unsigned HOST_WIDE_INT hwi_bitpos
;
1735 if (get_pointer_alignment_1 (arg
, &align
, &hwi_bitpos
)
1736 && align
% BITS_PER_UNIT
== 0
1737 && hwi_bitpos
% BITS_PER_UNIT
== 0)
1739 jfunc
->alignment
.known
= true;
1740 jfunc
->alignment
.align
= align
/ BITS_PER_UNIT
;
1741 jfunc
->alignment
.misalign
= hwi_bitpos
/ BITS_PER_UNIT
;
1744 gcc_assert (!jfunc
->alignment
.known
);
1747 gcc_assert (!jfunc
->alignment
.known
);
1749 if (is_gimple_ip_invariant (arg
))
1750 ipa_set_jf_constant (jfunc
, arg
, cs
);
1751 else if (!is_gimple_reg_type (TREE_TYPE (arg
))
1752 && TREE_CODE (arg
) == PARM_DECL
)
1754 int index
= ipa_get_param_decl_index (info
, arg
);
1756 gcc_assert (index
>=0);
1757 /* Aggregate passed by value, check for pass-through, otherwise we
1758 will attempt to fill in aggregate contents later in this
1760 if (parm_preserved_before_stmt_p (fbi
, index
, call
, arg
))
1762 ipa_set_jf_simple_pass_through (jfunc
, index
, false);
1766 else if (TREE_CODE (arg
) == SSA_NAME
)
1768 if (SSA_NAME_IS_DEFAULT_DEF (arg
))
1770 int index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (arg
));
1774 agg_p
= parm_ref_data_pass_through_p (fbi
, index
, call
, arg
);
1775 ipa_set_jf_simple_pass_through (jfunc
, index
, agg_p
);
1780 gimple stmt
= SSA_NAME_DEF_STMT (arg
);
1781 if (is_gimple_assign (stmt
))
1782 compute_complex_assign_jump_func (fbi
, info
, jfunc
,
1783 call
, stmt
, arg
, param_type
);
1784 else if (gimple_code (stmt
) == GIMPLE_PHI
)
1785 compute_complex_ancestor_jump_func (fbi
, info
, jfunc
,
1787 as_a
<gphi
*> (stmt
));
1791 /* If ARG is pointer, we can not use its type to determine the type of aggregate
1792 passed (because type conversions are ignored in gimple). Usually we can
1793 safely get type from function declaration, but in case of K&R prototypes or
1794 variadic functions we can try our luck with type of the pointer passed.
1795 TODO: Since we look for actual initialization of the memory object, we may better
1796 work out the type based on the memory stores we find. */
1798 param_type
= TREE_TYPE (arg
);
1800 if ((jfunc
->type
!= IPA_JF_PASS_THROUGH
1801 || !ipa_get_jf_pass_through_agg_preserved (jfunc
))
1802 && (jfunc
->type
!= IPA_JF_ANCESTOR
1803 || !ipa_get_jf_ancestor_agg_preserved (jfunc
))
1804 && (AGGREGATE_TYPE_P (TREE_TYPE (arg
))
1805 || POINTER_TYPE_P (param_type
)))
1806 determine_locally_known_aggregate_parts (call
, arg
, param_type
, jfunc
);
1808 if (!useful_context
)
1809 vec_free (args
->polymorphic_call_contexts
);
1812 /* Compute jump functions for all edges - both direct and indirect - outgoing
1816 ipa_compute_jump_functions_for_bb (struct func_body_info
*fbi
, basic_block bb
)
1818 struct ipa_bb_info
*bi
= ipa_get_bb_info (fbi
, bb
);
1820 struct cgraph_edge
*cs
;
1822 FOR_EACH_VEC_ELT_REVERSE (bi
->cg_edges
, i
, cs
)
1824 struct cgraph_node
*callee
= cs
->callee
;
1828 callee
->ultimate_alias_target ();
1829 /* We do not need to bother analyzing calls to unknown functions
1830 unless they may become known during lto/whopr. */
1831 if (!callee
->definition
&& !flag_lto
)
1834 ipa_compute_jump_functions_for_edge (fbi
, cs
);
1838 /* If STMT looks like a statement loading a value from a member pointer formal
1839 parameter, return that parameter and store the offset of the field to
1840 *OFFSET_P, if it is non-NULL. Otherwise return NULL (but *OFFSET_P still
1841 might be clobbered). If USE_DELTA, then we look for a use of the delta
1842 field rather than the pfn. */
1845 ipa_get_stmt_member_ptr_load_param (gimple stmt
, bool use_delta
,
1846 HOST_WIDE_INT
*offset_p
)
1848 tree rhs
, rec
, ref_field
, ref_offset
, fld
, ptr_field
, delta_field
;
1850 if (!gimple_assign_single_p (stmt
))
1853 rhs
= gimple_assign_rhs1 (stmt
);
1854 if (TREE_CODE (rhs
) == COMPONENT_REF
)
1856 ref_field
= TREE_OPERAND (rhs
, 1);
1857 rhs
= TREE_OPERAND (rhs
, 0);
1860 ref_field
= NULL_TREE
;
1861 if (TREE_CODE (rhs
) != MEM_REF
)
1863 rec
= TREE_OPERAND (rhs
, 0);
1864 if (TREE_CODE (rec
) != ADDR_EXPR
)
1866 rec
= TREE_OPERAND (rec
, 0);
1867 if (TREE_CODE (rec
) != PARM_DECL
1868 || !type_like_member_ptr_p (TREE_TYPE (rec
), &ptr_field
, &delta_field
))
1870 ref_offset
= TREE_OPERAND (rhs
, 1);
1877 *offset_p
= int_bit_position (fld
);
1881 if (integer_nonzerop (ref_offset
))
1883 return ref_field
== fld
? rec
: NULL_TREE
;
1886 return tree_int_cst_equal (byte_position (fld
), ref_offset
) ? rec
1890 /* Returns true iff T is an SSA_NAME defined by a statement. */
1893 ipa_is_ssa_with_stmt_def (tree t
)
1895 if (TREE_CODE (t
) == SSA_NAME
1896 && !SSA_NAME_IS_DEFAULT_DEF (t
))
1902 /* Find the indirect call graph edge corresponding to STMT and mark it as a
1903 call to a parameter number PARAM_INDEX. NODE is the caller. Return the
1904 indirect call graph edge. */
1906 static struct cgraph_edge
*
1907 ipa_note_param_call (struct cgraph_node
*node
, int param_index
,
1910 struct cgraph_edge
*cs
;
1912 cs
= node
->get_edge (stmt
);
1913 cs
->indirect_info
->param_index
= param_index
;
1914 cs
->indirect_info
->agg_contents
= 0;
1915 cs
->indirect_info
->member_ptr
= 0;
1919 /* Analyze the CALL and examine uses of formal parameters of the caller NODE
1920 (described by INFO). PARMS_AINFO is a pointer to a vector containing
1921 intermediate information about each formal parameter. Currently it checks
1922 whether the call calls a pointer that is a formal parameter and if so, the
1923 parameter is marked with the called flag and an indirect call graph edge
1924 describing the call is created. This is very simple for ordinary pointers
1925 represented in SSA but not-so-nice when it comes to member pointers. The
1926 ugly part of this function does nothing more than trying to match the
1927 pattern of such a call. An example of such a pattern is the gimple dump
1928 below, the call is on the last line:
1931 f$__delta_5 = f.__delta;
1932 f$__pfn_24 = f.__pfn;
1936 f$__delta_5 = MEM[(struct *)&f];
1937 f$__pfn_24 = MEM[(struct *)&f + 4B];
1939 and a few lines below:
1942 D.2496_3 = (int) f$__pfn_24;
1943 D.2497_4 = D.2496_3 & 1;
1950 D.2500_7 = (unsigned int) f$__delta_5;
1951 D.2501_8 = &S + D.2500_7;
1952 D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
1953 D.2503_10 = *D.2502_9;
1954 D.2504_12 = f$__pfn_24 + -1;
1955 D.2505_13 = (unsigned int) D.2504_12;
1956 D.2506_14 = D.2503_10 + D.2505_13;
1957 D.2507_15 = *D.2506_14;
1958 iftmp.11_16 = (String:: *) D.2507_15;
1961 # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
1962 D.2500_19 = (unsigned int) f$__delta_5;
1963 D.2508_20 = &S + D.2500_19;
1964 D.2493_21 = iftmp.11_1 (D.2508_20, 4);
1966 Such patterns are results of simple calls to a member pointer:
1968 int doprinting (int (MyString::* f)(int) const)
1970 MyString S ("somestring");
1975 Moreover, the function also looks for called pointers loaded from aggregates
1976 passed by value or reference. */
1979 ipa_analyze_indirect_call_uses (struct func_body_info
*fbi
, gcall
*call
,
1982 struct ipa_node_params
*info
= fbi
->info
;
1983 HOST_WIDE_INT offset
;
1986 if (SSA_NAME_IS_DEFAULT_DEF (target
))
1988 tree var
= SSA_NAME_VAR (target
);
1989 int index
= ipa_get_param_decl_index (info
, var
);
1991 ipa_note_param_call (fbi
->node
, index
, call
);
1996 gimple def
= SSA_NAME_DEF_STMT (target
);
1997 if (gimple_assign_single_p (def
)
1998 && ipa_load_from_parm_agg_1 (fbi
, info
->descriptors
, def
,
1999 gimple_assign_rhs1 (def
), &index
, &offset
,
2002 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2003 cs
->indirect_info
->offset
= offset
;
2004 cs
->indirect_info
->agg_contents
= 1;
2005 cs
->indirect_info
->by_ref
= by_ref
;
2009 /* Now we need to try to match the complex pattern of calling a member
2011 if (gimple_code (def
) != GIMPLE_PHI
2012 || gimple_phi_num_args (def
) != 2
2013 || !POINTER_TYPE_P (TREE_TYPE (target
))
2014 || TREE_CODE (TREE_TYPE (TREE_TYPE (target
))) != METHOD_TYPE
)
2017 /* First, we need to check whether one of these is a load from a member
2018 pointer that is a parameter to this function. */
2019 tree n1
= PHI_ARG_DEF (def
, 0);
2020 tree n2
= PHI_ARG_DEF (def
, 1);
2021 if (!ipa_is_ssa_with_stmt_def (n1
) || !ipa_is_ssa_with_stmt_def (n2
))
2023 gimple d1
= SSA_NAME_DEF_STMT (n1
);
2024 gimple d2
= SSA_NAME_DEF_STMT (n2
);
2027 basic_block bb
, virt_bb
;
2028 basic_block join
= gimple_bb (def
);
2029 if ((rec
= ipa_get_stmt_member_ptr_load_param (d1
, false, &offset
)))
2031 if (ipa_get_stmt_member_ptr_load_param (d2
, false, NULL
))
2034 bb
= EDGE_PRED (join
, 0)->src
;
2035 virt_bb
= gimple_bb (d2
);
2037 else if ((rec
= ipa_get_stmt_member_ptr_load_param (d2
, false, &offset
)))
2039 bb
= EDGE_PRED (join
, 1)->src
;
2040 virt_bb
= gimple_bb (d1
);
2045 /* Second, we need to check that the basic blocks are laid out in the way
2046 corresponding to the pattern. */
2048 if (!single_pred_p (virt_bb
) || !single_succ_p (virt_bb
)
2049 || single_pred (virt_bb
) != bb
2050 || single_succ (virt_bb
) != join
)
2053 /* Third, let's see that the branching is done depending on the least
2054 significant bit of the pfn. */
2056 gimple branch
= last_stmt (bb
);
2057 if (!branch
|| gimple_code (branch
) != GIMPLE_COND
)
2060 if ((gimple_cond_code (branch
) != NE_EXPR
2061 && gimple_cond_code (branch
) != EQ_EXPR
)
2062 || !integer_zerop (gimple_cond_rhs (branch
)))
2065 tree cond
= gimple_cond_lhs (branch
);
2066 if (!ipa_is_ssa_with_stmt_def (cond
))
2069 def
= SSA_NAME_DEF_STMT (cond
);
2070 if (!is_gimple_assign (def
)
2071 || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
2072 || !integer_onep (gimple_assign_rhs2 (def
)))
2075 cond
= gimple_assign_rhs1 (def
);
2076 if (!ipa_is_ssa_with_stmt_def (cond
))
2079 def
= SSA_NAME_DEF_STMT (cond
);
2081 if (is_gimple_assign (def
)
2082 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def
)))
2084 cond
= gimple_assign_rhs1 (def
);
2085 if (!ipa_is_ssa_with_stmt_def (cond
))
2087 def
= SSA_NAME_DEF_STMT (cond
);
2091 rec2
= ipa_get_stmt_member_ptr_load_param (def
,
2092 (TARGET_PTRMEMFUNC_VBIT_LOCATION
2093 == ptrmemfunc_vbit_in_delta
),
2098 index
= ipa_get_param_decl_index (info
, rec
);
2100 && parm_preserved_before_stmt_p (fbi
, index
, call
, rec
))
2102 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2103 cs
->indirect_info
->offset
= offset
;
2104 cs
->indirect_info
->agg_contents
= 1;
2105 cs
->indirect_info
->member_ptr
= 1;
2111 /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
2112 object referenced in the expression is a formal parameter of the caller
2113 FBI->node (described by FBI->info), create a call note for the
2117 ipa_analyze_virtual_call_uses (struct func_body_info
*fbi
,
2118 gcall
*call
, tree target
)
2120 tree obj
= OBJ_TYPE_REF_OBJECT (target
);
2122 HOST_WIDE_INT anc_offset
;
2124 if (!flag_devirtualize
)
2127 if (TREE_CODE (obj
) != SSA_NAME
)
2130 struct ipa_node_params
*info
= fbi
->info
;
2131 if (SSA_NAME_IS_DEFAULT_DEF (obj
))
2133 struct ipa_jump_func jfunc
;
2134 if (TREE_CODE (SSA_NAME_VAR (obj
)) != PARM_DECL
)
2138 index
= ipa_get_param_decl_index (info
, SSA_NAME_VAR (obj
));
2139 gcc_assert (index
>= 0);
2140 if (detect_type_change_ssa (obj
, obj_type_ref_class (target
),
2146 struct ipa_jump_func jfunc
;
2147 gimple stmt
= SSA_NAME_DEF_STMT (obj
);
2150 expr
= get_ancestor_addr_info (stmt
, &obj
, &anc_offset
);
2153 index
= ipa_get_param_decl_index (info
,
2154 SSA_NAME_VAR (TREE_OPERAND (expr
, 0)));
2155 gcc_assert (index
>= 0);
2156 if (detect_type_change (obj
, expr
, obj_type_ref_class (target
),
2157 call
, &jfunc
, anc_offset
))
2161 struct cgraph_edge
*cs
= ipa_note_param_call (fbi
->node
, index
, call
);
2162 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
2163 ii
->offset
= anc_offset
;
2164 ii
->otr_token
= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target
));
2165 ii
->otr_type
= obj_type_ref_class (target
);
2166 ii
->polymorphic
= 1;
2169 /* Analyze a call statement CALL whether and how it utilizes formal parameters
2170 of the caller (described by INFO). PARMS_AINFO is a pointer to a vector
2171 containing intermediate information about each formal parameter. */
2174 ipa_analyze_call_uses (struct func_body_info
*fbi
, gcall
*call
)
2176 tree target
= gimple_call_fn (call
);
2179 || (TREE_CODE (target
) != SSA_NAME
2180 && !virtual_method_call_p (target
)))
2183 struct cgraph_edge
*cs
= fbi
->node
->get_edge (call
);
2184 /* If we previously turned the call into a direct call, there is
2185 no need to analyze. */
2186 if (cs
&& !cs
->indirect_unknown_callee
)
2189 if (cs
->indirect_info
->polymorphic
&& flag_devirtualize
)
2192 tree target
= gimple_call_fn (call
);
2193 ipa_polymorphic_call_context
context (current_function_decl
,
2194 target
, call
, &instance
);
2196 gcc_checking_assert (cs
->indirect_info
->otr_type
2197 == obj_type_ref_class (target
));
2198 gcc_checking_assert (cs
->indirect_info
->otr_token
2199 == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target
)));
2201 cs
->indirect_info
->vptr_changed
2202 = !context
.get_dynamic_type (instance
,
2203 OBJ_TYPE_REF_OBJECT (target
),
2204 obj_type_ref_class (target
), call
);
2205 cs
->indirect_info
->context
= context
;
2208 if (TREE_CODE (target
) == SSA_NAME
)
2209 ipa_analyze_indirect_call_uses (fbi
, call
, target
);
2210 else if (virtual_method_call_p (target
))
2211 ipa_analyze_virtual_call_uses (fbi
, call
, target
);
2215 /* Analyze the call statement STMT with respect to formal parameters (described
2216 in INFO) of caller given by FBI->NODE. Currently it only checks whether
2217 formal parameters are called. */
2220 ipa_analyze_stmt_uses (struct func_body_info
*fbi
, gimple stmt
)
2222 if (is_gimple_call (stmt
))
2223 ipa_analyze_call_uses (fbi
, as_a
<gcall
*> (stmt
));
2226 /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
2227 If OP is a parameter declaration, mark it as used in the info structure
2231 visit_ref_for_mod_analysis (gimple
, tree op
, tree
, void *data
)
2233 struct ipa_node_params
*info
= (struct ipa_node_params
*) data
;
2235 op
= get_base_address (op
);
2237 && TREE_CODE (op
) == PARM_DECL
)
2239 int index
= ipa_get_param_decl_index (info
, op
);
2240 gcc_assert (index
>= 0);
2241 ipa_set_param_used (info
, index
, true);
2247 /* Scan the statements in BB and inspect the uses of formal parameters. Store
2248 the findings in various structures of the associated ipa_node_params
2249 structure, such as parameter flags, notes etc. FBI holds various data about
2250 the function being analyzed. */
2253 ipa_analyze_params_uses_in_bb (struct func_body_info
*fbi
, basic_block bb
)
2255 gimple_stmt_iterator gsi
;
2256 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2258 gimple stmt
= gsi_stmt (gsi
);
2260 if (is_gimple_debug (stmt
))
2263 ipa_analyze_stmt_uses (fbi
, stmt
);
2264 walk_stmt_load_store_addr_ops (stmt
, fbi
->info
,
2265 visit_ref_for_mod_analysis
,
2266 visit_ref_for_mod_analysis
,
2267 visit_ref_for_mod_analysis
);
2269 for (gsi
= gsi_start_phis (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2270 walk_stmt_load_store_addr_ops (gsi_stmt (gsi
), fbi
->info
,
2271 visit_ref_for_mod_analysis
,
2272 visit_ref_for_mod_analysis
,
2273 visit_ref_for_mod_analysis
);
2276 /* Calculate controlled uses of parameters of NODE. */
2279 ipa_analyze_controlled_uses (struct cgraph_node
*node
)
2281 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2283 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2285 tree parm
= ipa_get_param (info
, i
);
2286 int controlled_uses
= 0;
2288 /* For SSA regs see if parameter is used. For non-SSA we compute
2289 the flag during modification analysis. */
2290 if (is_gimple_reg (parm
))
2292 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
),
2294 if (ddef
&& !has_zero_uses (ddef
))
2296 imm_use_iterator imm_iter
;
2297 use_operand_p use_p
;
2299 ipa_set_param_used (info
, i
, true);
2300 FOR_EACH_IMM_USE_FAST (use_p
, imm_iter
, ddef
)
2301 if (!is_gimple_call (USE_STMT (use_p
)))
2303 if (!is_gimple_debug (USE_STMT (use_p
)))
2305 controlled_uses
= IPA_UNDESCRIBED_USE
;
2313 controlled_uses
= 0;
2316 controlled_uses
= IPA_UNDESCRIBED_USE
;
2317 ipa_set_controlled_uses (info
, i
, controlled_uses
);
2321 /* Free stuff in BI. */
2324 free_ipa_bb_info (struct ipa_bb_info
*bi
)
2326 bi
->cg_edges
.release ();
2327 bi
->param_aa_statuses
.release ();
2330 /* Dominator walker driving the analysis. */
2332 class analysis_dom_walker
: public dom_walker
2335 analysis_dom_walker (struct func_body_info
*fbi
)
2336 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
) {}
2338 virtual void before_dom_children (basic_block
);
2341 struct func_body_info
*m_fbi
;
2345 analysis_dom_walker::before_dom_children (basic_block bb
)
2347 ipa_analyze_params_uses_in_bb (m_fbi
, bb
);
2348 ipa_compute_jump_functions_for_bb (m_fbi
, bb
);
2351 /* Initialize the array describing properties of of formal parameters
2352 of NODE, analyze their uses and compute jump functions associated
2353 with actual arguments of calls from within NODE. */
2356 ipa_analyze_node (struct cgraph_node
*node
)
2358 struct func_body_info fbi
;
2359 struct ipa_node_params
*info
;
2361 ipa_check_create_node_params ();
2362 ipa_check_create_edge_args ();
2363 info
= IPA_NODE_REF (node
);
2365 if (info
->analysis_done
)
2367 info
->analysis_done
= 1;
2369 if (ipa_func_spec_opts_forbid_analysis_p (node
))
2371 for (int i
= 0; i
< ipa_get_param_count (info
); i
++)
2373 ipa_set_param_used (info
, i
, true);
2374 ipa_set_controlled_uses (info
, i
, IPA_UNDESCRIBED_USE
);
2379 struct function
*func
= DECL_STRUCT_FUNCTION (node
->decl
);
2381 calculate_dominance_info (CDI_DOMINATORS
);
2382 ipa_initialize_node_params (node
);
2383 ipa_analyze_controlled_uses (node
);
2386 fbi
.info
= IPA_NODE_REF (node
);
2387 fbi
.bb_infos
= vNULL
;
2388 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
2389 fbi
.param_count
= ipa_get_param_count (info
);
2392 for (struct cgraph_edge
*cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
2394 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2395 bi
->cg_edges
.safe_push (cs
);
2398 for (struct cgraph_edge
*cs
= node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
2400 ipa_bb_info
*bi
= ipa_get_bb_info (&fbi
, gimple_bb (cs
->call_stmt
));
2401 bi
->cg_edges
.safe_push (cs
);
2404 analysis_dom_walker (&fbi
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
2407 struct ipa_bb_info
*bi
;
2408 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
2409 free_ipa_bb_info (bi
);
2410 fbi
.bb_infos
.release ();
2411 free_dominance_info (CDI_DOMINATORS
);
2415 /* Update the jump functions associated with call graph edge E when the call
2416 graph edge CS is being inlined, assuming that E->caller is already (possibly
2417 indirectly) inlined into CS->callee and that E has not been inlined. */
2420 update_jump_functions_after_inlining (struct cgraph_edge
*cs
,
2421 struct cgraph_edge
*e
)
2423 struct ipa_edge_args
*top
= IPA_EDGE_REF (cs
);
2424 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
2425 int count
= ipa_get_cs_argument_count (args
);
2428 for (i
= 0; i
< count
; i
++)
2430 struct ipa_jump_func
*dst
= ipa_get_ith_jump_func (args
, i
);
2431 struct ipa_polymorphic_call_context
*dst_ctx
2432 = ipa_get_ith_polymorhic_call_context (args
, i
);
2434 if (dst
->type
== IPA_JF_ANCESTOR
)
2436 struct ipa_jump_func
*src
;
2437 int dst_fid
= dst
->value
.ancestor
.formal_id
;
2438 struct ipa_polymorphic_call_context
*src_ctx
2439 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
2441 /* Variable number of arguments can cause havoc if we try to access
2442 one that does not exist in the inlined edge. So make sure we
2444 if (dst_fid
>= ipa_get_cs_argument_count (top
))
2446 ipa_set_jf_unknown (dst
);
2450 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2452 if (src_ctx
&& !src_ctx
->useless_p ())
2454 struct ipa_polymorphic_call_context ctx
= *src_ctx
;
2456 /* TODO: Make type preserved safe WRT contexts. */
2457 if (!ipa_get_jf_ancestor_type_preserved (dst
))
2458 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
2459 ctx
.offset_by (dst
->value
.ancestor
.offset
);
2460 if (!ctx
.useless_p ())
2462 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
2464 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
2466 dst_ctx
->combine_with (ctx
);
2470 && (dst
->value
.ancestor
.agg_preserved
|| !src
->agg
.by_ref
))
2472 struct ipa_agg_jf_item
*item
;
2475 /* Currently we do not produce clobber aggregate jump functions,
2476 replace with merging when we do. */
2477 gcc_assert (!dst
->agg
.items
);
2479 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2480 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2481 FOR_EACH_VEC_SAFE_ELT (dst
->agg
.items
, j
, item
)
2482 item
->offset
-= dst
->value
.ancestor
.offset
;
2485 if (src
->type
== IPA_JF_PASS_THROUGH
2486 && src
->value
.pass_through
.operation
== NOP_EXPR
)
2488 dst
->value
.ancestor
.formal_id
= src
->value
.pass_through
.formal_id
;
2489 dst
->value
.ancestor
.agg_preserved
&=
2490 src
->value
.pass_through
.agg_preserved
;
2492 else if (src
->type
== IPA_JF_ANCESTOR
)
2494 dst
->value
.ancestor
.formal_id
= src
->value
.ancestor
.formal_id
;
2495 dst
->value
.ancestor
.offset
+= src
->value
.ancestor
.offset
;
2496 dst
->value
.ancestor
.agg_preserved
&=
2497 src
->value
.ancestor
.agg_preserved
;
2500 ipa_set_jf_unknown (dst
);
2502 else if (dst
->type
== IPA_JF_PASS_THROUGH
)
2504 struct ipa_jump_func
*src
;
2505 /* We must check range due to calls with variable number of arguments
2506 and we cannot combine jump functions with operations. */
2507 if (dst
->value
.pass_through
.operation
== NOP_EXPR
2508 && (dst
->value
.pass_through
.formal_id
2509 < ipa_get_cs_argument_count (top
)))
2511 int dst_fid
= dst
->value
.pass_through
.formal_id
;
2512 src
= ipa_get_ith_jump_func (top
, dst_fid
);
2513 bool dst_agg_p
= ipa_get_jf_pass_through_agg_preserved (dst
);
2514 struct ipa_polymorphic_call_context
*src_ctx
2515 = ipa_get_ith_polymorhic_call_context (top
, dst_fid
);
2517 if (src_ctx
&& !src_ctx
->useless_p ())
2519 struct ipa_polymorphic_call_context ctx
= *src_ctx
;
2521 /* TODO: Make type preserved safe WRT contexts. */
2522 if (!ipa_get_jf_pass_through_type_preserved (dst
))
2523 ctx
.possible_dynamic_type_change (e
->in_polymorphic_cdtor
);
2524 if (!ctx
.useless_p ())
2528 vec_safe_grow_cleared (args
->polymorphic_call_contexts
,
2530 dst_ctx
= ipa_get_ith_polymorhic_call_context (args
, i
);
2532 dst_ctx
->combine_with (ctx
);
2537 case IPA_JF_UNKNOWN
:
2538 ipa_set_jf_unknown (dst
);
2541 ipa_set_jf_cst_copy (dst
, src
);
2544 case IPA_JF_PASS_THROUGH
:
2546 int formal_id
= ipa_get_jf_pass_through_formal_id (src
);
2547 enum tree_code operation
;
2548 operation
= ipa_get_jf_pass_through_operation (src
);
2550 if (operation
== NOP_EXPR
)
2554 && ipa_get_jf_pass_through_agg_preserved (src
);
2555 ipa_set_jf_simple_pass_through (dst
, formal_id
, agg_p
);
2559 tree operand
= ipa_get_jf_pass_through_operand (src
);
2560 ipa_set_jf_arith_pass_through (dst
, formal_id
, operand
,
2565 case IPA_JF_ANCESTOR
:
2569 && ipa_get_jf_ancestor_agg_preserved (src
);
2570 ipa_set_ancestor_jf (dst
,
2571 ipa_get_jf_ancestor_offset (src
),
2572 ipa_get_jf_ancestor_formal_id (src
),
2581 && (dst_agg_p
|| !src
->agg
.by_ref
))
2583 /* Currently we do not produce clobber aggregate jump
2584 functions, replace with merging when we do. */
2585 gcc_assert (!dst
->agg
.items
);
2587 dst
->agg
.by_ref
= src
->agg
.by_ref
;
2588 dst
->agg
.items
= vec_safe_copy (src
->agg
.items
);
2592 ipa_set_jf_unknown (dst
);
2597 /* If TARGET is an addr_expr of a function declaration, make it the
2598 (SPECULATIVE)destination of an indirect edge IE and return the edge.
2599 Otherwise, return NULL. */
2601 struct cgraph_edge
*
2602 ipa_make_edge_direct_to_target (struct cgraph_edge
*ie
, tree target
,
2605 struct cgraph_node
*callee
;
2606 struct inline_edge_summary
*es
= inline_edge_summary (ie
);
2607 bool unreachable
= false;
2609 if (TREE_CODE (target
) == ADDR_EXPR
)
2610 target
= TREE_OPERAND (target
, 0);
2611 if (TREE_CODE (target
) != FUNCTION_DECL
)
2613 target
= canonicalize_constructor_val (target
, NULL
);
2614 if (!target
|| TREE_CODE (target
) != FUNCTION_DECL
)
2616 /* Member pointer call that goes through a VMT lookup. */
2617 if (ie
->indirect_info
->member_ptr
2618 /* Or if target is not an invariant expression and we do not
2619 know if it will evaulate to function at runtime.
2620 This can happen when folding through &VAR, where &VAR
2621 is IP invariant, but VAR itself is not.
2623 TODO: Revisit this when GCC 5 is branched. It seems that
2624 member_ptr check is not needed and that we may try to fold
2625 the expression and see if VAR is readonly. */
2626 || !is_gimple_ip_invariant (target
))
2628 if (dump_enabled_p ())
2630 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2631 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2632 "discovered direct call non-invariant "
2634 ie
->caller
->name (), ie
->caller
->order
);
2640 if (dump_enabled_p ())
2642 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2643 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2644 "discovered direct call to non-function in %s/%i, "
2645 "making it __builtin_unreachable\n",
2646 ie
->caller
->name (), ie
->caller
->order
);
2649 target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
2650 callee
= cgraph_node::get_create (target
);
2654 callee
= cgraph_node::get (target
);
2657 callee
= cgraph_node::get (target
);
2659 /* Because may-edges are not explicitely represented and vtable may be external,
2660 we may create the first reference to the object in the unit. */
2661 if (!callee
|| callee
->global
.inlined_to
)
2664 /* We are better to ensure we can refer to it.
2665 In the case of static functions we are out of luck, since we already
2666 removed its body. In the case of public functions we may or may
2667 not introduce the reference. */
2668 if (!canonicalize_constructor_val (target
, NULL
)
2669 || !TREE_PUBLIC (target
))
2672 fprintf (dump_file
, "ipa-prop: Discovered call to a known target "
2673 "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n",
2674 xstrdup_for_dump (ie
->caller
->name ()),
2676 xstrdup_for_dump (ie
->callee
->name ()),
2680 callee
= cgraph_node::get_create (target
);
2683 /* If the edge is already speculated. */
2684 if (speculative
&& ie
->speculative
)
2686 struct cgraph_edge
*e2
;
2687 struct ipa_ref
*ref
;
2688 ie
->speculative_call_info (e2
, ie
, ref
);
2689 if (e2
->callee
->ultimate_alias_target ()
2690 != callee
->ultimate_alias_target ())
2693 fprintf (dump_file
, "ipa-prop: Discovered call to a speculative target "
2694 "(%s/%i -> %s/%i) but the call is already speculated to %s/%i. Giving up.\n",
2695 xstrdup_for_dump (ie
->caller
->name ()),
2697 xstrdup_for_dump (callee
->name ()),
2699 xstrdup_for_dump (e2
->callee
->name ()),
2705 fprintf (dump_file
, "ipa-prop: Discovered call to a speculative target "
2706 "(%s/%i -> %s/%i) this agree with previous speculation.\n",
2707 xstrdup_for_dump (ie
->caller
->name ()),
2709 xstrdup_for_dump (callee
->name ()),
2715 if (!dbg_cnt (devirt
))
2718 ipa_check_create_node_params ();
2720 /* We can not make edges to inline clones. It is bug that someone removed
2721 the cgraph node too early. */
2722 gcc_assert (!callee
->global
.inlined_to
);
2724 if (dump_file
&& !unreachable
)
2726 fprintf (dump_file
, "ipa-prop: Discovered %s call to a %s target "
2727 "(%s/%i -> %s/%i), for stmt ",
2728 ie
->indirect_info
->polymorphic
? "a virtual" : "an indirect",
2729 speculative
? "speculative" : "known",
2730 xstrdup_for_dump (ie
->caller
->name ()),
2732 xstrdup_for_dump (callee
->name ()),
2735 print_gimple_stmt (dump_file
, ie
->call_stmt
, 2, TDF_SLIM
);
2737 fprintf (dump_file
, "with uid %i\n", ie
->lto_stmt_uid
);
2739 if (dump_enabled_p ())
2741 location_t loc
= gimple_location_safe (ie
->call_stmt
);
2743 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS
, loc
,
2744 "converting indirect call in %s to direct call to %s\n",
2745 ie
->caller
->name (), callee
->name ());
2749 struct cgraph_edge
*orig
= ie
;
2750 ie
= ie
->make_direct (callee
);
2751 /* If we resolved speculative edge the cost is already up to date
2752 for direct call (adjusted by inline_edge_duplication_hook). */
2755 es
= inline_edge_summary (ie
);
2756 es
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
2757 - eni_size_weights
.call_cost
);
2758 es
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
2759 - eni_time_weights
.call_cost
);
2764 if (!callee
->can_be_discarded_p ())
2767 alias
= dyn_cast
<cgraph_node
*> (callee
->noninterposable_alias ());
2771 /* make_speculative will update ie's cost to direct call cost. */
2772 ie
= ie
->make_speculative
2773 (callee
, ie
->count
* 8 / 10, ie
->frequency
* 8 / 10);
2779 /* Retrieve value from aggregate jump function AGG for the given OFFSET or
2780 return NULL if there is not any. BY_REF specifies whether the value has to
2781 be passed by reference or by value. */
2784 ipa_find_agg_cst_for_param (struct ipa_agg_jump_function
*agg
,
2785 HOST_WIDE_INT offset
, bool by_ref
)
2787 struct ipa_agg_jf_item
*item
;
2790 if (by_ref
!= agg
->by_ref
)
2793 FOR_EACH_VEC_SAFE_ELT (agg
->items
, i
, item
)
2794 if (item
->offset
== offset
)
2796 /* Currently we do not have clobber values, return NULL for them once
2798 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
2804 /* Remove a reference to SYMBOL from the list of references of a node given by
2805 reference description RDESC. Return true if the reference has been
2806 successfully found and removed. */
2809 remove_described_reference (symtab_node
*symbol
, struct ipa_cst_ref_desc
*rdesc
)
2811 struct ipa_ref
*to_del
;
2812 struct cgraph_edge
*origin
;
2817 to_del
= origin
->caller
->find_reference (symbol
, origin
->call_stmt
,
2818 origin
->lto_stmt_uid
);
2822 to_del
->remove_reference ();
2824 fprintf (dump_file
, "ipa-prop: Removed a reference from %s/%i to %s.\n",
2825 xstrdup_for_dump (origin
->caller
->name ()),
2826 origin
->caller
->order
, xstrdup_for_dump (symbol
->name ()));
2830 /* If JFUNC has a reference description with refcount different from
2831 IPA_UNDESCRIBED_USE, return the reference description, otherwise return
2832 NULL. JFUNC must be a constant jump function. */
2834 static struct ipa_cst_ref_desc
*
2835 jfunc_rdesc_usable (struct ipa_jump_func
*jfunc
)
2837 struct ipa_cst_ref_desc
*rdesc
= ipa_get_jf_constant_rdesc (jfunc
);
2838 if (rdesc
&& rdesc
->refcount
!= IPA_UNDESCRIBED_USE
)
2844 /* If the value of constant jump function JFUNC is an address of a function
2845 declaration, return the associated call graph node. Otherwise return
2848 static cgraph_node
*
2849 cgraph_node_for_jfunc (struct ipa_jump_func
*jfunc
)
2851 gcc_checking_assert (jfunc
->type
== IPA_JF_CONST
);
2852 tree cst
= ipa_get_jf_constant (jfunc
);
2853 if (TREE_CODE (cst
) != ADDR_EXPR
2854 || TREE_CODE (TREE_OPERAND (cst
, 0)) != FUNCTION_DECL
)
2857 return cgraph_node::get (TREE_OPERAND (cst
, 0));
2861 /* If JFUNC is a constant jump function with a usable rdesc, decrement its
2862 refcount and if it hits zero, remove reference to SYMBOL from the caller of
2863 the edge specified in the rdesc. Return false if either the symbol or the
2864 reference could not be found, otherwise return true. */
2867 try_decrement_rdesc_refcount (struct ipa_jump_func
*jfunc
)
2869 struct ipa_cst_ref_desc
*rdesc
;
2870 if (jfunc
->type
== IPA_JF_CONST
2871 && (rdesc
= jfunc_rdesc_usable (jfunc
))
2872 && --rdesc
->refcount
== 0)
2874 symtab_node
*symbol
= cgraph_node_for_jfunc (jfunc
);
2878 return remove_described_reference (symbol
, rdesc
);
2883 /* Try to find a destination for indirect edge IE that corresponds to a simple
2884 call or a call of a member function pointer and where the destination is a
2885 pointer formal parameter described by jump function JFUNC. If it can be
2886 determined, return the newly direct edge, otherwise return NULL.
2887 NEW_ROOT_INFO is the node info that JFUNC lattices are relative to. */
2889 static struct cgraph_edge
*
2890 try_make_edge_direct_simple_call (struct cgraph_edge
*ie
,
2891 struct ipa_jump_func
*jfunc
,
2892 struct ipa_node_params
*new_root_info
)
2894 struct cgraph_edge
*cs
;
2896 bool agg_contents
= ie
->indirect_info
->agg_contents
;
2898 if (ie
->indirect_info
->agg_contents
)
2899 target
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
2900 ie
->indirect_info
->offset
,
2901 ie
->indirect_info
->by_ref
);
2903 target
= ipa_value_from_jfunc (new_root_info
, jfunc
);
2906 cs
= ipa_make_edge_direct_to_target (ie
, target
);
2908 if (cs
&& !agg_contents
)
2911 gcc_checking_assert (cs
->callee
2913 || jfunc
->type
!= IPA_JF_CONST
2914 || !cgraph_node_for_jfunc (jfunc
)
2915 || cs
->callee
== cgraph_node_for_jfunc (jfunc
)));
2916 ok
= try_decrement_rdesc_refcount (jfunc
);
2917 gcc_checking_assert (ok
);
2923 /* Return the target to be used in cases of impossible devirtualization. IE
2924 and target (the latter can be NULL) are dumped when dumping is enabled. */
2927 ipa_impossible_devirt_target (struct cgraph_edge
*ie
, tree target
)
2933 "Type inconsistent devirtualization: %s/%i->%s\n",
2934 ie
->caller
->name (), ie
->caller
->order
,
2935 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target
)));
2938 "No devirtualization target in %s/%i\n",
2939 ie
->caller
->name (), ie
->caller
->order
);
2941 tree new_target
= builtin_decl_implicit (BUILT_IN_UNREACHABLE
);
2942 cgraph_node::get_create (new_target
);
2946 /* Try to find a destination for indirect edge IE that corresponds to a virtual
2947 call based on a formal parameter which is described by jump function JFUNC
2948 and if it can be determined, make it direct and return the direct edge.
2949 Otherwise, return NULL. CTX describes the polymorphic context that the
2950 parameter the call is based on brings along with it. */
2952 static struct cgraph_edge
*
2953 try_make_edge_direct_virtual_call (struct cgraph_edge
*ie
,
2954 struct ipa_jump_func
*jfunc
,
2955 struct ipa_polymorphic_call_context ctx
)
2958 bool speculative
= false;
2960 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
2963 gcc_assert (!ie
->indirect_info
->by_ref
);
2965 /* Try to do lookup via known virtual table pointer value. */
2966 if (!ie
->indirect_info
->vptr_changed
2967 || opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
))
2970 unsigned HOST_WIDE_INT offset
;
2971 tree t
= ipa_find_agg_cst_for_param (&jfunc
->agg
,
2972 ie
->indirect_info
->offset
,
2974 if (t
&& vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
2976 t
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
2980 if ((TREE_CODE (TREE_TYPE (t
)) == FUNCTION_TYPE
2981 && DECL_FUNCTION_CODE (t
) == BUILT_IN_UNREACHABLE
)
2982 || !possible_polymorphic_call_target_p
2983 (ie
, cgraph_node::get (t
)))
2985 /* Do not speculate builtin_unreachable, it is stupid! */
2986 if (!ie
->indirect_info
->vptr_changed
)
2987 target
= ipa_impossible_devirt_target (ie
, target
);
2992 speculative
= ie
->indirect_info
->vptr_changed
;
2998 ipa_polymorphic_call_context
ie_context (ie
);
2999 vec
<cgraph_node
*>targets
;
3002 ctx
.offset_by (ie
->indirect_info
->offset
);
3003 if (ie
->indirect_info
->vptr_changed
)
3004 ctx
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3005 ie
->indirect_info
->otr_type
);
3006 ctx
.combine_with (ie_context
, ie
->indirect_info
->otr_type
);
3007 targets
= possible_polymorphic_call_targets
3008 (ie
->indirect_info
->otr_type
,
3009 ie
->indirect_info
->otr_token
,
3011 if (final
&& targets
.length () <= 1)
3013 speculative
= false;
3014 if (targets
.length () == 1)
3015 target
= targets
[0]->decl
;
3017 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3019 else if (!target
&& opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
3020 && !ie
->speculative
&& ie
->maybe_hot_p ())
3023 n
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
3024 ie
->indirect_info
->otr_token
,
3025 ie
->indirect_info
->context
);
3035 if (!possible_polymorphic_call_target_p
3036 (ie
, cgraph_node::get_create (target
)))
3040 target
= ipa_impossible_devirt_target (ie
, target
);
3042 return ipa_make_edge_direct_to_target (ie
, target
, speculative
);
3048 /* Update the param called notes associated with NODE when CS is being inlined,
3049 assuming NODE is (potentially indirectly) inlined into CS->callee.
3050 Moreover, if the callee is discovered to be constant, create a new cgraph
3051 edge for it. Newly discovered indirect edges will be added to *NEW_EDGES,
3052 unless NEW_EDGES is NULL. Return true iff a new edge(s) were created. */
3055 update_indirect_edges_after_inlining (struct cgraph_edge
*cs
,
3056 struct cgraph_node
*node
,
3057 vec
<cgraph_edge
*> *new_edges
)
3059 struct ipa_edge_args
*top
;
3060 struct cgraph_edge
*ie
, *next_ie
, *new_direct_edge
;
3061 struct ipa_node_params
*new_root_info
;
3064 ipa_check_create_edge_args ();
3065 top
= IPA_EDGE_REF (cs
);
3066 new_root_info
= IPA_NODE_REF (cs
->caller
->global
.inlined_to
3067 ? cs
->caller
->global
.inlined_to
3070 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3072 struct cgraph_indirect_call_info
*ici
= ie
->indirect_info
;
3073 struct ipa_jump_func
*jfunc
;
3075 cgraph_node
*spec_target
= NULL
;
3077 next_ie
= ie
->next_callee
;
3079 if (ici
->param_index
== -1)
3082 /* We must check range due to calls with variable number of arguments: */
3083 if (ici
->param_index
>= ipa_get_cs_argument_count (top
))
3085 ici
->param_index
= -1;
3089 param_index
= ici
->param_index
;
3090 jfunc
= ipa_get_ith_jump_func (top
, param_index
);
3092 if (ie
->speculative
)
3094 struct cgraph_edge
*de
;
3095 struct ipa_ref
*ref
;
3096 ie
->speculative_call_info (de
, ie
, ref
);
3097 spec_target
= de
->callee
;
3100 if (!opt_for_fn (node
->decl
, flag_indirect_inlining
))
3101 new_direct_edge
= NULL
;
3102 else if (ici
->polymorphic
)
3104 ipa_polymorphic_call_context ctx
;
3105 ctx
= ipa_context_from_jfunc (new_root_info
, cs
, param_index
, jfunc
);
3106 new_direct_edge
= try_make_edge_direct_virtual_call (ie
, jfunc
, ctx
);
3109 new_direct_edge
= try_make_edge_direct_simple_call (ie
, jfunc
,
3111 /* If speculation was removed, then we need to do nothing. */
3112 if (new_direct_edge
&& new_direct_edge
!= ie
3113 && new_direct_edge
->callee
== spec_target
)
3115 new_direct_edge
->indirect_inlining_edge
= 1;
3116 top
= IPA_EDGE_REF (cs
);
3118 if (!new_direct_edge
->speculative
)
3121 else if (new_direct_edge
)
3123 new_direct_edge
->indirect_inlining_edge
= 1;
3124 if (new_direct_edge
->call_stmt
)
3125 new_direct_edge
->call_stmt_cannot_inline_p
3126 = !gimple_check_call_matching_types (
3127 new_direct_edge
->call_stmt
,
3128 new_direct_edge
->callee
->decl
, false);
3131 new_edges
->safe_push (new_direct_edge
);
3134 top
= IPA_EDGE_REF (cs
);
3135 /* If speculative edge was introduced we still need to update
3136 call info of the indirect edge. */
3137 if (!new_direct_edge
->speculative
)
3140 if (jfunc
->type
== IPA_JF_PASS_THROUGH
3141 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
3143 if (ici
->agg_contents
3144 && !ipa_get_jf_pass_through_agg_preserved (jfunc
)
3145 && !ici
->polymorphic
)
3146 ici
->param_index
= -1;
3149 ici
->param_index
= ipa_get_jf_pass_through_formal_id (jfunc
);
3150 if (ici
->polymorphic
3151 && !ipa_get_jf_pass_through_type_preserved (jfunc
))
3152 ici
->vptr_changed
= true;
3155 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
3157 if (ici
->agg_contents
3158 && !ipa_get_jf_ancestor_agg_preserved (jfunc
)
3159 && !ici
->polymorphic
)
3160 ici
->param_index
= -1;
3163 ici
->param_index
= ipa_get_jf_ancestor_formal_id (jfunc
);
3164 ici
->offset
+= ipa_get_jf_ancestor_offset (jfunc
);
3165 if (ici
->polymorphic
3166 && !ipa_get_jf_ancestor_type_preserved (jfunc
))
3167 ici
->vptr_changed
= true;
3171 /* Either we can find a destination for this edge now or never. */
3172 ici
->param_index
= -1;
3178 /* Recursively traverse subtree of NODE (including node) made of inlined
3179 cgraph_edges when CS has been inlined and invoke
3180 update_indirect_edges_after_inlining on all nodes and
3181 update_jump_functions_after_inlining on all non-inlined edges that lead out
3182 of this subtree. Newly discovered indirect edges will be added to
3183 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were
3187 propagate_info_to_inlined_callees (struct cgraph_edge
*cs
,
3188 struct cgraph_node
*node
,
3189 vec
<cgraph_edge
*> *new_edges
)
3191 struct cgraph_edge
*e
;
3194 res
= update_indirect_edges_after_inlining (cs
, node
, new_edges
);
3196 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3197 if (!e
->inline_failed
)
3198 res
|= propagate_info_to_inlined_callees (cs
, e
->callee
, new_edges
);
3200 update_jump_functions_after_inlining (cs
, e
);
3201 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3202 update_jump_functions_after_inlining (cs
, e
);
3207 /* Combine two controlled uses counts as done during inlining. */
3210 combine_controlled_uses_counters (int c
, int d
)
3212 if (c
== IPA_UNDESCRIBED_USE
|| d
== IPA_UNDESCRIBED_USE
)
3213 return IPA_UNDESCRIBED_USE
;
3218 /* Propagate number of controlled users from CS->caleee to the new root of the
3219 tree of inlined nodes. */
3222 propagate_controlled_uses (struct cgraph_edge
*cs
)
3224 struct ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
3225 struct cgraph_node
*new_root
= cs
->caller
->global
.inlined_to
3226 ? cs
->caller
->global
.inlined_to
: cs
->caller
;
3227 struct ipa_node_params
*new_root_info
= IPA_NODE_REF (new_root
);
3228 struct ipa_node_params
*old_root_info
= IPA_NODE_REF (cs
->callee
);
3231 count
= MIN (ipa_get_cs_argument_count (args
),
3232 ipa_get_param_count (old_root_info
));
3233 for (i
= 0; i
< count
; i
++)
3235 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3236 struct ipa_cst_ref_desc
*rdesc
;
3238 if (jf
->type
== IPA_JF_PASS_THROUGH
)
3241 src_idx
= ipa_get_jf_pass_through_formal_id (jf
);
3242 c
= ipa_get_controlled_uses (new_root_info
, src_idx
);
3243 d
= ipa_get_controlled_uses (old_root_info
, i
);
3245 gcc_checking_assert (ipa_get_jf_pass_through_operation (jf
)
3246 == NOP_EXPR
|| c
== IPA_UNDESCRIBED_USE
);
3247 c
= combine_controlled_uses_counters (c
, d
);
3248 ipa_set_controlled_uses (new_root_info
, src_idx
, c
);
3249 if (c
== 0 && new_root_info
->ipcp_orig_node
)
3251 struct cgraph_node
*n
;
3252 struct ipa_ref
*ref
;
3253 tree t
= new_root_info
->known_csts
[src_idx
];
3255 if (t
&& TREE_CODE (t
) == ADDR_EXPR
3256 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
3257 && (n
= cgraph_node::get (TREE_OPERAND (t
, 0)))
3258 && (ref
= new_root
->find_reference (n
, NULL
, 0)))
3261 fprintf (dump_file
, "ipa-prop: Removing cloning-created "
3262 "reference from %s/%i to %s/%i.\n",
3263 xstrdup_for_dump (new_root
->name ()),
3265 xstrdup_for_dump (n
->name ()), n
->order
);
3266 ref
->remove_reference ();
3270 else if (jf
->type
== IPA_JF_CONST
3271 && (rdesc
= jfunc_rdesc_usable (jf
)))
3273 int d
= ipa_get_controlled_uses (old_root_info
, i
);
3274 int c
= rdesc
->refcount
;
3275 rdesc
->refcount
= combine_controlled_uses_counters (c
, d
);
3276 if (rdesc
->refcount
== 0)
3278 tree cst
= ipa_get_jf_constant (jf
);
3279 struct cgraph_node
*n
;
3280 gcc_checking_assert (TREE_CODE (cst
) == ADDR_EXPR
3281 && TREE_CODE (TREE_OPERAND (cst
, 0))
3283 n
= cgraph_node::get (TREE_OPERAND (cst
, 0));
3286 struct cgraph_node
*clone
;
3288 ok
= remove_described_reference (n
, rdesc
);
3289 gcc_checking_assert (ok
);
3292 while (clone
->global
.inlined_to
3293 && clone
!= rdesc
->cs
->caller
3294 && IPA_NODE_REF (clone
)->ipcp_orig_node
)
3296 struct ipa_ref
*ref
;
3297 ref
= clone
->find_reference (n
, NULL
, 0);
3301 fprintf (dump_file
, "ipa-prop: Removing "
3302 "cloning-created reference "
3303 "from %s/%i to %s/%i.\n",
3304 xstrdup_for_dump (clone
->name ()),
3306 xstrdup_for_dump (n
->name ()),
3308 ref
->remove_reference ();
3310 clone
= clone
->callers
->caller
;
3317 for (i
= ipa_get_param_count (old_root_info
);
3318 i
< ipa_get_cs_argument_count (args
);
3321 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
3323 if (jf
->type
== IPA_JF_CONST
)
3325 struct ipa_cst_ref_desc
*rdesc
= jfunc_rdesc_usable (jf
);
3327 rdesc
->refcount
= IPA_UNDESCRIBED_USE
;
3329 else if (jf
->type
== IPA_JF_PASS_THROUGH
)
3330 ipa_set_controlled_uses (new_root_info
,
3331 jf
->value
.pass_through
.formal_id
,
3332 IPA_UNDESCRIBED_USE
);
3336 /* Update jump functions and call note functions on inlining the call site CS.
3337 CS is expected to lead to a node already cloned by
3338 cgraph_clone_inline_nodes. Newly discovered indirect edges will be added to
3339 *NEW_EDGES, unless NEW_EDGES is NULL. Return true iff a new edge(s) were +
3343 ipa_propagate_indirect_call_infos (struct cgraph_edge
*cs
,
3344 vec
<cgraph_edge
*> *new_edges
)
3347 /* Do nothing if the preparation phase has not been carried out yet
3348 (i.e. during early inlining). */
3349 if (!ipa_node_params_sum
)
3351 gcc_assert (ipa_edge_args_vector
);
3353 propagate_controlled_uses (cs
);
3354 changed
= propagate_info_to_inlined_callees (cs
, cs
->callee
, new_edges
);
3359 /* Frees all dynamically allocated structures that the argument info points
3363 ipa_free_edge_args_substructures (struct ipa_edge_args
*args
)
3365 vec_free (args
->jump_functions
);
3366 memset (args
, 0, sizeof (*args
));
3369 /* Free all ipa_edge structures. */
3372 ipa_free_all_edge_args (void)
3375 struct ipa_edge_args
*args
;
3377 if (!ipa_edge_args_vector
)
3380 FOR_EACH_VEC_ELT (*ipa_edge_args_vector
, i
, args
)
3381 ipa_free_edge_args_substructures (args
);
3383 vec_free (ipa_edge_args_vector
);
3386 /* Frees all dynamically allocated structures that the param info points
3389 ipa_node_params::~ipa_node_params ()
3391 descriptors
.release ();
3393 /* Lattice values and their sources are deallocated with their alocation
3395 known_contexts
.release ();
3398 ipcp_orig_node
= NULL
;
3401 do_clone_for_all_contexts
= 0;
3402 is_all_contexts_clone
= 0;
3406 /* Free all ipa_node_params structures. */
3409 ipa_free_all_node_params (void)
3411 delete ipa_node_params_sum
;
3412 ipa_node_params_sum
= NULL
;
3415 /* Grow ipcp_transformations if necessary. */
3418 ipcp_grow_transformations_if_necessary (void)
3420 if (vec_safe_length (ipcp_transformations
)
3421 <= (unsigned) symtab
->cgraph_max_uid
)
3422 vec_safe_grow_cleared (ipcp_transformations
, symtab
->cgraph_max_uid
+ 1);
3425 /* Set the aggregate replacements of NODE to be AGGVALS. */
3428 ipa_set_node_agg_value_chain (struct cgraph_node
*node
,
3429 struct ipa_agg_replacement_value
*aggvals
)
3431 ipcp_grow_transformations_if_necessary ();
3432 (*ipcp_transformations
)[node
->uid
].agg_values
= aggvals
;
3435 /* Hook that is called by cgraph.c when an edge is removed. */
3438 ipa_edge_removal_hook (struct cgraph_edge
*cs
, void *data ATTRIBUTE_UNUSED
)
3440 struct ipa_edge_args
*args
;
3442 /* During IPA-CP updating we can be called on not-yet analyzed clones. */
3443 if (vec_safe_length (ipa_edge_args_vector
) <= (unsigned)cs
->uid
)
3446 args
= IPA_EDGE_REF (cs
);
3447 if (args
->jump_functions
)
3449 struct ipa_jump_func
*jf
;
3451 FOR_EACH_VEC_ELT (*args
->jump_functions
, i
, jf
)
3453 struct ipa_cst_ref_desc
*rdesc
;
3454 try_decrement_rdesc_refcount (jf
);
3455 if (jf
->type
== IPA_JF_CONST
3456 && (rdesc
= ipa_get_jf_constant_rdesc (jf
))
3462 ipa_free_edge_args_substructures (IPA_EDGE_REF (cs
));
3465 /* Hook that is called by cgraph.c when an edge is duplicated. */
3468 ipa_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
3471 struct ipa_edge_args
*old_args
, *new_args
;
3474 ipa_check_create_edge_args ();
3476 old_args
= IPA_EDGE_REF (src
);
3477 new_args
= IPA_EDGE_REF (dst
);
3479 new_args
->jump_functions
= vec_safe_copy (old_args
->jump_functions
);
3480 if (old_args
->polymorphic_call_contexts
)
3481 new_args
->polymorphic_call_contexts
3482 = vec_safe_copy (old_args
->polymorphic_call_contexts
);
3484 for (i
= 0; i
< vec_safe_length (old_args
->jump_functions
); i
++)
3486 struct ipa_jump_func
*src_jf
= ipa_get_ith_jump_func (old_args
, i
);
3487 struct ipa_jump_func
*dst_jf
= ipa_get_ith_jump_func (new_args
, i
);
3489 dst_jf
->agg
.items
= vec_safe_copy (dst_jf
->agg
.items
);
3491 if (src_jf
->type
== IPA_JF_CONST
)
3493 struct ipa_cst_ref_desc
*src_rdesc
= jfunc_rdesc_usable (src_jf
);
3496 dst_jf
->value
.constant
.rdesc
= NULL
;
3497 else if (src
->caller
== dst
->caller
)
3499 struct ipa_ref
*ref
;
3500 symtab_node
*n
= cgraph_node_for_jfunc (src_jf
);
3501 gcc_checking_assert (n
);
3502 ref
= src
->caller
->find_reference (n
, src
->call_stmt
,
3504 gcc_checking_assert (ref
);
3505 dst
->caller
->clone_reference (ref
, ref
->stmt
);
3507 struct ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
3508 dst_rdesc
->cs
= dst
;
3509 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3510 dst_rdesc
->next_duplicate
= NULL
;
3511 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3513 else if (src_rdesc
->cs
== src
)
3515 struct ipa_cst_ref_desc
*dst_rdesc
= ipa_refdesc_pool
.allocate ();
3516 dst_rdesc
->cs
= dst
;
3517 dst_rdesc
->refcount
= src_rdesc
->refcount
;
3518 dst_rdesc
->next_duplicate
= src_rdesc
->next_duplicate
;
3519 src_rdesc
->next_duplicate
= dst_rdesc
;
3520 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3524 struct ipa_cst_ref_desc
*dst_rdesc
;
3525 /* This can happen during inlining, when a JFUNC can refer to a
3526 reference taken in a function up in the tree of inline clones.
3527 We need to find the duplicate that refers to our tree of
3530 gcc_assert (dst
->caller
->global
.inlined_to
);
3531 for (dst_rdesc
= src_rdesc
->next_duplicate
;
3533 dst_rdesc
= dst_rdesc
->next_duplicate
)
3535 struct cgraph_node
*top
;
3536 top
= dst_rdesc
->cs
->caller
->global
.inlined_to
3537 ? dst_rdesc
->cs
->caller
->global
.inlined_to
3538 : dst_rdesc
->cs
->caller
;
3539 if (dst
->caller
->global
.inlined_to
== top
)
3542 gcc_assert (dst_rdesc
);
3543 dst_jf
->value
.constant
.rdesc
= dst_rdesc
;
3546 else if (dst_jf
->type
== IPA_JF_PASS_THROUGH
3547 && src
->caller
== dst
->caller
)
3549 struct cgraph_node
*inline_root
= dst
->caller
->global
.inlined_to
3550 ? dst
->caller
->global
.inlined_to
: dst
->caller
;
3551 struct ipa_node_params
*root_info
= IPA_NODE_REF (inline_root
);
3552 int idx
= ipa_get_jf_pass_through_formal_id (dst_jf
);
3554 int c
= ipa_get_controlled_uses (root_info
, idx
);
3555 if (c
!= IPA_UNDESCRIBED_USE
)
3558 ipa_set_controlled_uses (root_info
, idx
, c
);
3564 /* Analyze newly added function into callgraph. */
3567 ipa_add_new_function (cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
3569 if (node
->has_gimple_body_p ())
3570 ipa_analyze_node (node
);
3573 /* Hook that is called by summary when a node is duplicated. */
3576 ipa_node_params_t::duplicate(cgraph_node
*src
, cgraph_node
*dst
,
3577 ipa_node_params
*old_info
,
3578 ipa_node_params
*new_info
)
3580 ipa_agg_replacement_value
*old_av
, *new_av
;
3582 new_info
->descriptors
= old_info
->descriptors
.copy ();
3583 new_info
->lattices
= NULL
;
3584 new_info
->ipcp_orig_node
= old_info
->ipcp_orig_node
;
3586 new_info
->analysis_done
= old_info
->analysis_done
;
3587 new_info
->node_enqueued
= old_info
->node_enqueued
;
3589 old_av
= ipa_get_agg_replacements_for_node (src
);
3595 struct ipa_agg_replacement_value
*v
;
3597 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
3598 memcpy (v
, old_av
, sizeof (*v
));
3601 old_av
= old_av
->next
;
3603 ipa_set_node_agg_value_chain (dst
, new_av
);
3606 ipcp_transformation_summary
*src_trans
= ipcp_get_transformation_summary (src
);
3608 if (src_trans
&& vec_safe_length (src_trans
->alignments
) > 0)
3610 ipcp_grow_transformations_if_necessary ();
3611 src_trans
= ipcp_get_transformation_summary (src
);
3612 const vec
<ipa_alignment
, va_gc
> *src_alignments
= src_trans
->alignments
;
3613 vec
<ipa_alignment
, va_gc
> *&dst_alignments
3614 = ipcp_get_transformation_summary (dst
)->alignments
;
3615 vec_safe_reserve_exact (dst_alignments
, src_alignments
->length ());
3616 for (unsigned i
= 0; i
< src_alignments
->length (); ++i
)
3617 dst_alignments
->quick_push ((*src_alignments
)[i
]);
3621 /* Register our cgraph hooks if they are not already there. */
3624 ipa_register_cgraph_hooks (void)
3626 ipa_check_create_node_params ();
3628 if (!edge_removal_hook_holder
)
3629 edge_removal_hook_holder
=
3630 symtab
->add_edge_removal_hook (&ipa_edge_removal_hook
, NULL
);
3631 if (!edge_duplication_hook_holder
)
3632 edge_duplication_hook_holder
=
3633 symtab
->add_edge_duplication_hook (&ipa_edge_duplication_hook
, NULL
);
3634 function_insertion_hook_holder
=
3635 symtab
->add_cgraph_insertion_hook (&ipa_add_new_function
, NULL
);
3638 /* Unregister our cgraph hooks if they are not already there. */
3641 ipa_unregister_cgraph_hooks (void)
3643 symtab
->remove_edge_removal_hook (edge_removal_hook_holder
);
3644 edge_removal_hook_holder
= NULL
;
3645 symtab
->remove_edge_duplication_hook (edge_duplication_hook_holder
);
3646 edge_duplication_hook_holder
= NULL
;
3647 symtab
->remove_cgraph_insertion_hook (function_insertion_hook_holder
);
3648 function_insertion_hook_holder
= NULL
;
3651 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3652 longer needed after ipa-cp. */
3655 ipa_free_all_structures_after_ipa_cp (void)
3657 if (!optimize
&& !in_lto_p
)
3659 ipa_free_all_edge_args ();
3660 ipa_free_all_node_params ();
3661 ipcp_sources_pool
.release ();
3662 ipcp_cst_values_pool
.release ();
3663 ipcp_poly_ctx_values_pool
.release ();
3664 ipcp_agg_lattice_pool
.release ();
3665 ipa_unregister_cgraph_hooks ();
3666 ipa_refdesc_pool
.release ();
3670 /* Free all ipa_node_params and all ipa_edge_args structures if they are no
3671 longer needed after indirect inlining. */
3674 ipa_free_all_structures_after_iinln (void)
3676 ipa_free_all_edge_args ();
3677 ipa_free_all_node_params ();
3678 ipa_unregister_cgraph_hooks ();
3679 ipcp_sources_pool
.release ();
3680 ipcp_cst_values_pool
.release ();
3681 ipcp_poly_ctx_values_pool
.release ();
3682 ipcp_agg_lattice_pool
.release ();
3683 ipa_refdesc_pool
.release ();
3686 /* Print ipa_tree_map data structures of all functions in the
3690 ipa_print_node_params (FILE *f
, struct cgraph_node
*node
)
3693 struct ipa_node_params
*info
;
3695 if (!node
->definition
)
3697 info
= IPA_NODE_REF (node
);
3698 fprintf (f
, " function %s/%i parameter descriptors:\n",
3699 node
->name (), node
->order
);
3700 count
= ipa_get_param_count (info
);
3701 for (i
= 0; i
< count
; i
++)
3706 ipa_dump_param (f
, info
, i
);
3707 if (ipa_is_param_used (info
, i
))
3708 fprintf (f
, " used");
3709 c
= ipa_get_controlled_uses (info
, i
);
3710 if (c
== IPA_UNDESCRIBED_USE
)
3711 fprintf (f
, " undescribed_use");
3713 fprintf (f
, " controlled_uses=%i", c
);
3718 /* Print ipa_tree_map data structures of all functions in the
3722 ipa_print_all_params (FILE * f
)
3724 struct cgraph_node
*node
;
3726 fprintf (f
, "\nFunction parameters:\n");
3727 FOR_EACH_FUNCTION (node
)
3728 ipa_print_node_params (f
, node
);
3731 /* Return a heap allocated vector containing formal parameters of FNDECL. */
3734 ipa_get_vector_of_formal_parms (tree fndecl
)
3740 gcc_assert (!flag_wpa
);
3741 count
= count_formal_params (fndecl
);
3742 args
.create (count
);
3743 for (parm
= DECL_ARGUMENTS (fndecl
); parm
; parm
= DECL_CHAIN (parm
))
3744 args
.quick_push (parm
);
3749 /* Return a heap allocated vector containing types of formal parameters of
3750 function type FNTYPE. */
3753 ipa_get_vector_of_formal_parm_types (tree fntype
)
3759 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3762 types
.create (count
);
3763 for (t
= TYPE_ARG_TYPES (fntype
); t
; t
= TREE_CHAIN (t
))
3764 types
.quick_push (TREE_VALUE (t
));
3769 /* Modify the function declaration FNDECL and its type according to the plan in
3770 ADJUSTMENTS. It also sets base fields of individual adjustments structures
3771 to reflect the actual parameters being modified which are determined by the
3772 base_index field. */
3775 ipa_modify_formal_parameters (tree fndecl
, ipa_parm_adjustment_vec adjustments
)
3777 vec
<tree
> oparms
= ipa_get_vector_of_formal_parms (fndecl
);
3778 tree orig_type
= TREE_TYPE (fndecl
);
3779 tree old_arg_types
= TYPE_ARG_TYPES (orig_type
);
3781 /* The following test is an ugly hack, some functions simply don't have any
3782 arguments in their type. This is probably a bug but well... */
3783 bool care_for_types
= (old_arg_types
!= NULL_TREE
);
3784 bool last_parm_void
;
3788 last_parm_void
= (TREE_VALUE (tree_last (old_arg_types
))
3790 otypes
= ipa_get_vector_of_formal_parm_types (orig_type
);
3792 gcc_assert (oparms
.length () + 1 == otypes
.length ());
3794 gcc_assert (oparms
.length () == otypes
.length ());
3798 last_parm_void
= false;
3802 int len
= adjustments
.length ();
3803 tree
*link
= &DECL_ARGUMENTS (fndecl
);
3804 tree new_arg_types
= NULL
;
3805 for (int i
= 0; i
< len
; i
++)
3807 struct ipa_parm_adjustment
*adj
;
3810 adj
= &adjustments
[i
];
3812 if (adj
->op
== IPA_PARM_OP_NEW
)
3815 parm
= oparms
[adj
->base_index
];
3818 if (adj
->op
== IPA_PARM_OP_COPY
)
3821 new_arg_types
= tree_cons (NULL_TREE
, otypes
[adj
->base_index
],
3824 link
= &DECL_CHAIN (parm
);
3826 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
3832 ptype
= build_pointer_type (adj
->type
);
3836 if (is_gimple_reg_type (ptype
))
3838 unsigned malign
= GET_MODE_ALIGNMENT (TYPE_MODE (ptype
));
3839 if (TYPE_ALIGN (ptype
) < malign
)
3840 ptype
= build_aligned_type (ptype
, malign
);
3845 new_arg_types
= tree_cons (NULL_TREE
, ptype
, new_arg_types
);
3847 new_parm
= build_decl (UNKNOWN_LOCATION
, PARM_DECL
, NULL_TREE
,
3849 const char *prefix
= adj
->arg_prefix
? adj
->arg_prefix
: "SYNTH";
3850 DECL_NAME (new_parm
) = create_tmp_var_name (prefix
);
3851 DECL_ARTIFICIAL (new_parm
) = 1;
3852 DECL_ARG_TYPE (new_parm
) = ptype
;
3853 DECL_CONTEXT (new_parm
) = fndecl
;
3854 TREE_USED (new_parm
) = 1;
3855 DECL_IGNORED_P (new_parm
) = 1;
3856 layout_decl (new_parm
, 0);
3858 if (adj
->op
== IPA_PARM_OP_NEW
)
3862 adj
->new_decl
= new_parm
;
3865 link
= &DECL_CHAIN (new_parm
);
3871 tree new_reversed
= NULL
;
3874 new_reversed
= nreverse (new_arg_types
);
3878 TREE_CHAIN (new_arg_types
) = void_list_node
;
3880 new_reversed
= void_list_node
;
3884 /* Use copy_node to preserve as much as possible from original type
3885 (debug info, attribute lists etc.)
3886 Exception is METHOD_TYPEs must have THIS argument.
3887 When we are asked to remove it, we need to build new FUNCTION_TYPE
3889 tree new_type
= NULL
;
3890 if (TREE_CODE (orig_type
) != METHOD_TYPE
3891 || (adjustments
[0].op
== IPA_PARM_OP_COPY
3892 && adjustments
[0].base_index
== 0))
3894 new_type
= build_distinct_type_copy (orig_type
);
3895 TYPE_ARG_TYPES (new_type
) = new_reversed
;
3900 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type
),
3902 TYPE_CONTEXT (new_type
) = TYPE_CONTEXT (orig_type
);
3903 DECL_VINDEX (fndecl
) = NULL_TREE
;
3906 /* When signature changes, we need to clear builtin info. */
3907 if (DECL_BUILT_IN (fndecl
))
3909 DECL_BUILT_IN_CLASS (fndecl
) = NOT_BUILT_IN
;
3910 DECL_FUNCTION_CODE (fndecl
) = (enum built_in_function
) 0;
3913 TREE_TYPE (fndecl
) = new_type
;
3914 DECL_VIRTUAL_P (fndecl
) = 0;
3915 DECL_LANG_SPECIFIC (fndecl
) = NULL
;
3920 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
3921 If this is a directly recursive call, CS must be NULL. Otherwise it must
3922 contain the corresponding call graph edge. */
3925 ipa_modify_call_arguments (struct cgraph_edge
*cs
, gcall
*stmt
,
3926 ipa_parm_adjustment_vec adjustments
)
3928 struct cgraph_node
*current_node
= cgraph_node::get (current_function_decl
);
3930 vec
<tree
, va_gc
> **debug_args
= NULL
;
3932 gimple_stmt_iterator gsi
, prev_gsi
;
3936 len
= adjustments
.length ();
3938 callee_decl
= !cs
? gimple_call_fndecl (stmt
) : cs
->callee
->decl
;
3939 current_node
->remove_stmt_references (stmt
);
3941 gsi
= gsi_for_stmt (stmt
);
3943 gsi_prev (&prev_gsi
);
3944 for (i
= 0; i
< len
; i
++)
3946 struct ipa_parm_adjustment
*adj
;
3948 adj
= &adjustments
[i
];
3950 if (adj
->op
== IPA_PARM_OP_COPY
)
3952 tree arg
= gimple_call_arg (stmt
, adj
->base_index
);
3954 vargs
.quick_push (arg
);
3956 else if (adj
->op
!= IPA_PARM_OP_REMOVE
)
3958 tree expr
, base
, off
;
3960 unsigned int deref_align
= 0;
3961 bool deref_base
= false;
3963 /* We create a new parameter out of the value of the old one, we can
3964 do the following kind of transformations:
3966 - A scalar passed by reference is converted to a scalar passed by
3967 value. (adj->by_ref is false and the type of the original
3968 actual argument is a pointer to a scalar).
3970 - A part of an aggregate is passed instead of the whole aggregate.
3971 The part can be passed either by value or by reference, this is
3972 determined by value of adj->by_ref. Moreover, the code below
3973 handles both situations when the original aggregate is passed by
3974 value (its type is not a pointer) and when it is passed by
3975 reference (it is a pointer to an aggregate).
3977 When the new argument is passed by reference (adj->by_ref is true)
3978 it must be a part of an aggregate and therefore we form it by
3979 simply taking the address of a reference inside the original
3982 gcc_checking_assert (adj
->offset
% BITS_PER_UNIT
== 0);
3983 base
= gimple_call_arg (stmt
, adj
->base_index
);
3984 loc
= DECL_P (base
) ? DECL_SOURCE_LOCATION (base
)
3985 : EXPR_LOCATION (base
);
3987 if (TREE_CODE (base
) != ADDR_EXPR
3988 && POINTER_TYPE_P (TREE_TYPE (base
)))
3989 off
= build_int_cst (adj
->alias_ptr_type
,
3990 adj
->offset
/ BITS_PER_UNIT
);
3993 HOST_WIDE_INT base_offset
;
3997 if (TREE_CODE (base
) == ADDR_EXPR
)
3999 base
= TREE_OPERAND (base
, 0);
4005 base
= get_addr_base_and_unit_offset (base
, &base_offset
);
4006 /* Aggregate arguments can have non-invariant addresses. */
4009 base
= build_fold_addr_expr (prev_base
);
4010 off
= build_int_cst (adj
->alias_ptr_type
,
4011 adj
->offset
/ BITS_PER_UNIT
);
4013 else if (TREE_CODE (base
) == MEM_REF
)
4018 deref_align
= TYPE_ALIGN (TREE_TYPE (base
));
4020 off
= build_int_cst (adj
->alias_ptr_type
,
4022 + adj
->offset
/ BITS_PER_UNIT
);
4023 off
= int_const_binop (PLUS_EXPR
, TREE_OPERAND (base
, 1),
4025 base
= TREE_OPERAND (base
, 0);
4029 off
= build_int_cst (adj
->alias_ptr_type
,
4031 + adj
->offset
/ BITS_PER_UNIT
);
4032 base
= build_fold_addr_expr (base
);
4038 tree type
= adj
->type
;
4040 unsigned HOST_WIDE_INT misalign
;
4044 align
= deref_align
;
4049 get_pointer_alignment_1 (base
, &align
, &misalign
);
4050 if (TYPE_ALIGN (type
) > align
)
4051 align
= TYPE_ALIGN (type
);
4053 misalign
+= (offset_int::from (off
, SIGNED
).to_short_addr ()
4055 misalign
= misalign
& (align
- 1);
4057 align
= (misalign
& -misalign
);
4058 if (align
< TYPE_ALIGN (type
))
4059 type
= build_aligned_type (type
, align
);
4060 base
= force_gimple_operand_gsi (&gsi
, base
,
4061 true, NULL
, true, GSI_SAME_STMT
);
4062 expr
= fold_build2_loc (loc
, MEM_REF
, type
, base
, off
);
4063 /* If expr is not a valid gimple call argument emit
4064 a load into a temporary. */
4065 if (is_gimple_reg_type (TREE_TYPE (expr
)))
4067 gimple tem
= gimple_build_assign (NULL_TREE
, expr
);
4068 if (gimple_in_ssa_p (cfun
))
4070 gimple_set_vuse (tem
, gimple_vuse (stmt
));
4071 expr
= make_ssa_name (TREE_TYPE (expr
), tem
);
4074 expr
= create_tmp_reg (TREE_TYPE (expr
));
4075 gimple_assign_set_lhs (tem
, expr
);
4076 gsi_insert_before (&gsi
, tem
, GSI_SAME_STMT
);
4081 expr
= fold_build2_loc (loc
, MEM_REF
, adj
->type
, base
, off
);
4082 expr
= build_fold_addr_expr (expr
);
4083 expr
= force_gimple_operand_gsi (&gsi
, expr
,
4084 true, NULL
, true, GSI_SAME_STMT
);
4086 vargs
.quick_push (expr
);
4088 if (adj
->op
!= IPA_PARM_OP_COPY
&& MAY_HAVE_DEBUG_STMTS
)
4091 tree ddecl
= NULL_TREE
, origin
= DECL_ORIGIN (adj
->base
), arg
;
4094 arg
= gimple_call_arg (stmt
, adj
->base_index
);
4095 if (!useless_type_conversion_p (TREE_TYPE (origin
), TREE_TYPE (arg
)))
4097 if (!fold_convertible_p (TREE_TYPE (origin
), arg
))
4099 arg
= fold_convert_loc (gimple_location (stmt
),
4100 TREE_TYPE (origin
), arg
);
4102 if (debug_args
== NULL
)
4103 debug_args
= decl_debug_args_insert (callee_decl
);
4104 for (ix
= 0; vec_safe_iterate (*debug_args
, ix
, &ddecl
); ix
+= 2)
4105 if (ddecl
== origin
)
4107 ddecl
= (**debug_args
)[ix
+ 1];
4112 ddecl
= make_node (DEBUG_EXPR_DECL
);
4113 DECL_ARTIFICIAL (ddecl
) = 1;
4114 TREE_TYPE (ddecl
) = TREE_TYPE (origin
);
4115 DECL_MODE (ddecl
) = DECL_MODE (origin
);
4117 vec_safe_push (*debug_args
, origin
);
4118 vec_safe_push (*debug_args
, ddecl
);
4120 def_temp
= gimple_build_debug_bind (ddecl
, unshare_expr (arg
), stmt
);
4121 gsi_insert_before (&gsi
, def_temp
, GSI_SAME_STMT
);
4125 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4127 fprintf (dump_file
, "replacing stmt:");
4128 print_gimple_stmt (dump_file
, gsi_stmt (gsi
), 0, 0);
4131 new_stmt
= gimple_build_call_vec (callee_decl
, vargs
);
4133 if (gimple_call_lhs (stmt
))
4134 gimple_call_set_lhs (new_stmt
, gimple_call_lhs (stmt
));
4136 gimple_set_block (new_stmt
, gimple_block (stmt
));
4137 if (gimple_has_location (stmt
))
4138 gimple_set_location (new_stmt
, gimple_location (stmt
));
4139 gimple_call_set_chain (new_stmt
, gimple_call_chain (stmt
));
4140 gimple_call_copy_flags (new_stmt
, stmt
);
4141 if (gimple_in_ssa_p (cfun
))
4143 gimple_set_vuse (new_stmt
, gimple_vuse (stmt
));
4144 if (gimple_vdef (stmt
))
4146 gimple_set_vdef (new_stmt
, gimple_vdef (stmt
));
4147 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt
)) = new_stmt
;
4151 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4153 fprintf (dump_file
, "with stmt:");
4154 print_gimple_stmt (dump_file
, new_stmt
, 0, 0);
4155 fprintf (dump_file
, "\n");
4157 gsi_replace (&gsi
, new_stmt
, true);
4159 cs
->set_call_stmt (new_stmt
);
4162 current_node
->record_stmt_references (gsi_stmt (gsi
));
4165 while (gsi_stmt (gsi
) != gsi_stmt (prev_gsi
));
4168 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
4169 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
4170 specifies whether the function should care about type incompatibility the
4171 current and new expressions. If it is false, the function will leave
4172 incompatibility issues to the caller. Return true iff the expression
4176 ipa_modify_expr (tree
*expr
, bool convert
,
4177 ipa_parm_adjustment_vec adjustments
)
4179 struct ipa_parm_adjustment
*cand
4180 = ipa_get_adjustment_candidate (&expr
, &convert
, adjustments
, false);
4186 src
= build_simple_mem_ref (cand
->new_decl
);
4188 src
= cand
->new_decl
;
4190 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4192 fprintf (dump_file
, "About to replace expr ");
4193 print_generic_expr (dump_file
, *expr
, 0);
4194 fprintf (dump_file
, " with ");
4195 print_generic_expr (dump_file
, src
, 0);
4196 fprintf (dump_file
, "\n");
4199 if (convert
&& !useless_type_conversion_p (TREE_TYPE (*expr
), cand
->type
))
4201 tree vce
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (*expr
), src
);
4209 /* If T is an SSA_NAME, return NULL if it is not a default def or
4210 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
4211 the base variable is always returned, regardless if it is a default
4212 def. Return T if it is not an SSA_NAME. */
4215 get_ssa_base_param (tree t
, bool ignore_default_def
)
4217 if (TREE_CODE (t
) == SSA_NAME
)
4219 if (ignore_default_def
|| SSA_NAME_IS_DEFAULT_DEF (t
))
4220 return SSA_NAME_VAR (t
);
4227 /* Given an expression, return an adjustment entry specifying the
4228 transformation to be done on EXPR. If no suitable adjustment entry
4229 was found, returns NULL.
4231 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
4232 default def, otherwise bail on them.
4234 If CONVERT is non-NULL, this function will set *CONVERT if the
4235 expression provided is a component reference. ADJUSTMENTS is the
4236 adjustments vector. */
4238 ipa_parm_adjustment
*
4239 ipa_get_adjustment_candidate (tree
**expr
, bool *convert
,
4240 ipa_parm_adjustment_vec adjustments
,
4241 bool ignore_default_def
)
4243 if (TREE_CODE (**expr
) == BIT_FIELD_REF
4244 || TREE_CODE (**expr
) == IMAGPART_EXPR
4245 || TREE_CODE (**expr
) == REALPART_EXPR
)
4247 *expr
= &TREE_OPERAND (**expr
, 0);
4252 HOST_WIDE_INT offset
, size
, max_size
;
4253 tree base
= get_ref_base_and_extent (**expr
, &offset
, &size
, &max_size
);
4254 if (!base
|| size
== -1 || max_size
== -1)
4257 if (TREE_CODE (base
) == MEM_REF
)
4259 offset
+= mem_ref_offset (base
).to_short_addr () * BITS_PER_UNIT
;
4260 base
= TREE_OPERAND (base
, 0);
4263 base
= get_ssa_base_param (base
, ignore_default_def
);
4264 if (!base
|| TREE_CODE (base
) != PARM_DECL
)
4267 struct ipa_parm_adjustment
*cand
= NULL
;
4268 unsigned int len
= adjustments
.length ();
4269 for (unsigned i
= 0; i
< len
; i
++)
4271 struct ipa_parm_adjustment
*adj
= &adjustments
[i
];
4273 if (adj
->base
== base
4274 && (adj
->offset
== offset
|| adj
->op
== IPA_PARM_OP_REMOVE
))
4281 if (!cand
|| cand
->op
== IPA_PARM_OP_COPY
|| cand
->op
== IPA_PARM_OP_REMOVE
)
4286 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
4289 index_in_adjustments_multiple_times_p (int base_index
,
4290 ipa_parm_adjustment_vec adjustments
)
4292 int i
, len
= adjustments
.length ();
4295 for (i
= 0; i
< len
; i
++)
4297 struct ipa_parm_adjustment
*adj
;
4298 adj
= &adjustments
[i
];
4300 if (adj
->base_index
== base_index
)
4312 /* Return adjustments that should have the same effect on function parameters
4313 and call arguments as if they were first changed according to adjustments in
4314 INNER and then by adjustments in OUTER. */
4316 ipa_parm_adjustment_vec
4317 ipa_combine_adjustments (ipa_parm_adjustment_vec inner
,
4318 ipa_parm_adjustment_vec outer
)
4320 int i
, outlen
= outer
.length ();
4321 int inlen
= inner
.length ();
4323 ipa_parm_adjustment_vec adjustments
, tmp
;
4326 for (i
= 0; i
< inlen
; i
++)
4328 struct ipa_parm_adjustment
*n
;
4331 if (n
->op
== IPA_PARM_OP_REMOVE
)
4335 /* FIXME: Handling of new arguments are not implemented yet. */
4336 gcc_assert (n
->op
!= IPA_PARM_OP_NEW
);
4337 tmp
.quick_push (*n
);
4341 adjustments
.create (outlen
+ removals
);
4342 for (i
= 0; i
< outlen
; i
++)
4344 struct ipa_parm_adjustment r
;
4345 struct ipa_parm_adjustment
*out
= &outer
[i
];
4346 struct ipa_parm_adjustment
*in
= &tmp
[out
->base_index
];
4348 memset (&r
, 0, sizeof (r
));
4349 gcc_assert (in
->op
!= IPA_PARM_OP_REMOVE
);
4350 if (out
->op
== IPA_PARM_OP_REMOVE
)
4352 if (!index_in_adjustments_multiple_times_p (in
->base_index
, tmp
))
4354 r
.op
= IPA_PARM_OP_REMOVE
;
4355 adjustments
.quick_push (r
);
4361 /* FIXME: Handling of new arguments are not implemented yet. */
4362 gcc_assert (out
->op
!= IPA_PARM_OP_NEW
);
4365 r
.base_index
= in
->base_index
;
4368 /* FIXME: Create nonlocal value too. */
4370 if (in
->op
== IPA_PARM_OP_COPY
&& out
->op
== IPA_PARM_OP_COPY
)
4371 r
.op
= IPA_PARM_OP_COPY
;
4372 else if (in
->op
== IPA_PARM_OP_COPY
)
4373 r
.offset
= out
->offset
;
4374 else if (out
->op
== IPA_PARM_OP_COPY
)
4375 r
.offset
= in
->offset
;
4377 r
.offset
= in
->offset
+ out
->offset
;
4378 adjustments
.quick_push (r
);
4381 for (i
= 0; i
< inlen
; i
++)
4383 struct ipa_parm_adjustment
*n
= &inner
[i
];
4385 if (n
->op
== IPA_PARM_OP_REMOVE
)
4386 adjustments
.quick_push (*n
);
4393 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
4394 friendly way, assuming they are meant to be applied to FNDECL. */
4397 ipa_dump_param_adjustments (FILE *file
, ipa_parm_adjustment_vec adjustments
,
4400 int i
, len
= adjustments
.length ();
4402 vec
<tree
> parms
= ipa_get_vector_of_formal_parms (fndecl
);
4404 fprintf (file
, "IPA param adjustments: ");
4405 for (i
= 0; i
< len
; i
++)
4407 struct ipa_parm_adjustment
*adj
;
4408 adj
= &adjustments
[i
];
4411 fprintf (file
, " ");
4415 fprintf (file
, "%i. base_index: %i - ", i
, adj
->base_index
);
4416 print_generic_expr (file
, parms
[adj
->base_index
], 0);
4419 fprintf (file
, ", base: ");
4420 print_generic_expr (file
, adj
->base
, 0);
4424 fprintf (file
, ", new_decl: ");
4425 print_generic_expr (file
, adj
->new_decl
, 0);
4427 if (adj
->new_ssa_base
)
4429 fprintf (file
, ", new_ssa_base: ");
4430 print_generic_expr (file
, adj
->new_ssa_base
, 0);
4433 if (adj
->op
== IPA_PARM_OP_COPY
)
4434 fprintf (file
, ", copy_param");
4435 else if (adj
->op
== IPA_PARM_OP_REMOVE
)
4436 fprintf (file
, ", remove_param");
4438 fprintf (file
, ", offset %li", (long) adj
->offset
);
4440 fprintf (file
, ", by_ref");
4441 print_node_brief (file
, ", type: ", adj
->type
, 0);
4442 fprintf (file
, "\n");
4447 /* Dump the AV linked list. */
4450 ipa_dump_agg_replacement_values (FILE *f
, struct ipa_agg_replacement_value
*av
)
4453 fprintf (f
, " Aggregate replacements:");
4454 for (; av
; av
= av
->next
)
4456 fprintf (f
, "%s %i[" HOST_WIDE_INT_PRINT_DEC
"]=", comma
? "," : "",
4457 av
->index
, av
->offset
);
4458 print_generic_expr (f
, av
->value
, 0);
4464 /* Stream out jump function JUMP_FUNC to OB. */
4467 ipa_write_jump_function (struct output_block
*ob
,
4468 struct ipa_jump_func
*jump_func
)
4470 struct ipa_agg_jf_item
*item
;
4471 struct bitpack_d bp
;
4474 streamer_write_uhwi (ob
, jump_func
->type
);
4475 switch (jump_func
->type
)
4477 case IPA_JF_UNKNOWN
:
4481 EXPR_LOCATION (jump_func
->value
.constant
.value
) == UNKNOWN_LOCATION
);
4482 stream_write_tree (ob
, jump_func
->value
.constant
.value
, true);
4484 case IPA_JF_PASS_THROUGH
:
4485 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.operation
);
4486 if (jump_func
->value
.pass_through
.operation
== NOP_EXPR
)
4488 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4489 bp
= bitpack_create (ob
->main_stream
);
4490 bp_pack_value (&bp
, jump_func
->value
.pass_through
.agg_preserved
, 1);
4491 streamer_write_bitpack (&bp
);
4495 stream_write_tree (ob
, jump_func
->value
.pass_through
.operand
, true);
4496 streamer_write_uhwi (ob
, jump_func
->value
.pass_through
.formal_id
);
4499 case IPA_JF_ANCESTOR
:
4500 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.offset
);
4501 streamer_write_uhwi (ob
, jump_func
->value
.ancestor
.formal_id
);
4502 bp
= bitpack_create (ob
->main_stream
);
4503 bp_pack_value (&bp
, jump_func
->value
.ancestor
.agg_preserved
, 1);
4504 streamer_write_bitpack (&bp
);
4508 count
= vec_safe_length (jump_func
->agg
.items
);
4509 streamer_write_uhwi (ob
, count
);
4512 bp
= bitpack_create (ob
->main_stream
);
4513 bp_pack_value (&bp
, jump_func
->agg
.by_ref
, 1);
4514 streamer_write_bitpack (&bp
);
4517 FOR_EACH_VEC_SAFE_ELT (jump_func
->agg
.items
, i
, item
)
4519 streamer_write_uhwi (ob
, item
->offset
);
4520 stream_write_tree (ob
, item
->value
, true);
4523 bp
= bitpack_create (ob
->main_stream
);
4524 bp_pack_value (&bp
, jump_func
->alignment
.known
, 1);
4525 streamer_write_bitpack (&bp
);
4526 if (jump_func
->alignment
.known
)
4528 streamer_write_uhwi (ob
, jump_func
->alignment
.align
);
4529 streamer_write_uhwi (ob
, jump_func
->alignment
.misalign
);
4533 /* Read in jump function JUMP_FUNC from IB. */
4536 ipa_read_jump_function (struct lto_input_block
*ib
,
4537 struct ipa_jump_func
*jump_func
,
4538 struct cgraph_edge
*cs
,
4539 struct data_in
*data_in
)
4541 enum jump_func_type jftype
;
4542 enum tree_code operation
;
4545 jftype
= (enum jump_func_type
) streamer_read_uhwi (ib
);
4548 case IPA_JF_UNKNOWN
:
4549 ipa_set_jf_unknown (jump_func
);
4552 ipa_set_jf_constant (jump_func
, stream_read_tree (ib
, data_in
), cs
);
4554 case IPA_JF_PASS_THROUGH
:
4555 operation
= (enum tree_code
) streamer_read_uhwi (ib
);
4556 if (operation
== NOP_EXPR
)
4558 int formal_id
= streamer_read_uhwi (ib
);
4559 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4560 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4561 ipa_set_jf_simple_pass_through (jump_func
, formal_id
, agg_preserved
);
4565 tree operand
= stream_read_tree (ib
, data_in
);
4566 int formal_id
= streamer_read_uhwi (ib
);
4567 ipa_set_jf_arith_pass_through (jump_func
, formal_id
, operand
,
4571 case IPA_JF_ANCESTOR
:
4573 HOST_WIDE_INT offset
= streamer_read_uhwi (ib
);
4574 int formal_id
= streamer_read_uhwi (ib
);
4575 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4576 bool agg_preserved
= bp_unpack_value (&bp
, 1);
4577 ipa_set_ancestor_jf (jump_func
, offset
, formal_id
, agg_preserved
);
4582 count
= streamer_read_uhwi (ib
);
4583 vec_alloc (jump_func
->agg
.items
, count
);
4586 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4587 jump_func
->agg
.by_ref
= bp_unpack_value (&bp
, 1);
4589 for (i
= 0; i
< count
; i
++)
4591 struct ipa_agg_jf_item item
;
4592 item
.offset
= streamer_read_uhwi (ib
);
4593 item
.value
= stream_read_tree (ib
, data_in
);
4594 jump_func
->agg
.items
->quick_push (item
);
4597 struct bitpack_d bp
= streamer_read_bitpack (ib
);
4598 bool alignment_known
= bp_unpack_value (&bp
, 1);
4599 if (alignment_known
)
4601 jump_func
->alignment
.known
= true;
4602 jump_func
->alignment
.align
= streamer_read_uhwi (ib
);
4603 jump_func
->alignment
.misalign
= streamer_read_uhwi (ib
);
4606 jump_func
->alignment
.known
= false;
4609 /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
4610 relevant to indirect inlining to OB. */
4613 ipa_write_indirect_edge_info (struct output_block
*ob
,
4614 struct cgraph_edge
*cs
)
4616 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4617 struct bitpack_d bp
;
4619 streamer_write_hwi (ob
, ii
->param_index
);
4620 bp
= bitpack_create (ob
->main_stream
);
4621 bp_pack_value (&bp
, ii
->polymorphic
, 1);
4622 bp_pack_value (&bp
, ii
->agg_contents
, 1);
4623 bp_pack_value (&bp
, ii
->member_ptr
, 1);
4624 bp_pack_value (&bp
, ii
->by_ref
, 1);
4625 bp_pack_value (&bp
, ii
->vptr_changed
, 1);
4626 streamer_write_bitpack (&bp
);
4627 if (ii
->agg_contents
|| ii
->polymorphic
)
4628 streamer_write_hwi (ob
, ii
->offset
);
4630 gcc_assert (ii
->offset
== 0);
4632 if (ii
->polymorphic
)
4634 streamer_write_hwi (ob
, ii
->otr_token
);
4635 stream_write_tree (ob
, ii
->otr_type
, true);
4636 ii
->context
.stream_out (ob
);
4640 /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
4641 relevant to indirect inlining from IB. */
4644 ipa_read_indirect_edge_info (struct lto_input_block
*ib
,
4645 struct data_in
*data_in
,
4646 struct cgraph_edge
*cs
)
4648 struct cgraph_indirect_call_info
*ii
= cs
->indirect_info
;
4649 struct bitpack_d bp
;
4651 ii
->param_index
= (int) streamer_read_hwi (ib
);
4652 bp
= streamer_read_bitpack (ib
);
4653 ii
->polymorphic
= bp_unpack_value (&bp
, 1);
4654 ii
->agg_contents
= bp_unpack_value (&bp
, 1);
4655 ii
->member_ptr
= bp_unpack_value (&bp
, 1);
4656 ii
->by_ref
= bp_unpack_value (&bp
, 1);
4657 ii
->vptr_changed
= bp_unpack_value (&bp
, 1);
4658 if (ii
->agg_contents
|| ii
->polymorphic
)
4659 ii
->offset
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4662 if (ii
->polymorphic
)
4664 ii
->otr_token
= (HOST_WIDE_INT
) streamer_read_hwi (ib
);
4665 ii
->otr_type
= stream_read_tree (ib
, data_in
);
4666 ii
->context
.stream_in (ib
, data_in
);
4670 /* Stream out NODE info to OB. */
4673 ipa_write_node_info (struct output_block
*ob
, struct cgraph_node
*node
)
4676 lto_symtab_encoder_t encoder
;
4677 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4679 struct cgraph_edge
*e
;
4680 struct bitpack_d bp
;
4682 encoder
= ob
->decl_state
->symtab_node_encoder
;
4683 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4684 streamer_write_uhwi (ob
, node_ref
);
4686 streamer_write_uhwi (ob
, ipa_get_param_count (info
));
4687 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4688 streamer_write_uhwi (ob
, ipa_get_param_move_cost (info
, j
));
4689 bp
= bitpack_create (ob
->main_stream
);
4690 gcc_assert (info
->analysis_done
4691 || ipa_get_param_count (info
) == 0);
4692 gcc_assert (!info
->node_enqueued
);
4693 gcc_assert (!info
->ipcp_orig_node
);
4694 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4695 bp_pack_value (&bp
, ipa_is_param_used (info
, j
), 1);
4696 streamer_write_bitpack (&bp
);
4697 for (j
= 0; j
< ipa_get_param_count (info
); j
++)
4698 streamer_write_hwi (ob
, ipa_get_controlled_uses (info
, j
));
4699 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4701 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4703 streamer_write_uhwi (ob
,
4704 ipa_get_cs_argument_count (args
) * 2
4705 + (args
->polymorphic_call_contexts
!= NULL
));
4706 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4708 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4709 if (args
->polymorphic_call_contexts
!= NULL
)
4710 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
4713 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4715 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4717 streamer_write_uhwi (ob
,
4718 ipa_get_cs_argument_count (args
) * 2
4719 + (args
->polymorphic_call_contexts
!= NULL
));
4720 for (j
= 0; j
< ipa_get_cs_argument_count (args
); j
++)
4722 ipa_write_jump_function (ob
, ipa_get_ith_jump_func (args
, j
));
4723 if (args
->polymorphic_call_contexts
!= NULL
)
4724 ipa_get_ith_polymorhic_call_context (args
, j
)->stream_out (ob
);
4726 ipa_write_indirect_edge_info (ob
, e
);
4730 /* Stream in NODE info from IB. */
4733 ipa_read_node_info (struct lto_input_block
*ib
, struct cgraph_node
*node
,
4734 struct data_in
*data_in
)
4736 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4738 struct cgraph_edge
*e
;
4739 struct bitpack_d bp
;
4741 ipa_alloc_node_params (node
, streamer_read_uhwi (ib
));
4743 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4744 info
->descriptors
[k
].move_cost
= streamer_read_uhwi (ib
);
4746 bp
= streamer_read_bitpack (ib
);
4747 if (ipa_get_param_count (info
) != 0)
4748 info
->analysis_done
= true;
4749 info
->node_enqueued
= false;
4750 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4751 ipa_set_param_used (info
, k
, bp_unpack_value (&bp
, 1));
4752 for (k
= 0; k
< ipa_get_param_count (info
); k
++)
4753 ipa_set_controlled_uses (info
, k
, streamer_read_hwi (ib
));
4754 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4756 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4757 int count
= streamer_read_uhwi (ib
);
4758 bool contexts_computed
= count
& 1;
4763 vec_safe_grow_cleared (args
->jump_functions
, count
);
4764 if (contexts_computed
)
4765 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
);
4767 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4769 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4771 if (contexts_computed
)
4772 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in (ib
, data_in
);
4775 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4777 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
4778 int count
= streamer_read_uhwi (ib
);
4779 bool contexts_computed
= count
& 1;
4784 vec_safe_grow_cleared (args
->jump_functions
, count
);
4785 if (contexts_computed
)
4786 vec_safe_grow_cleared (args
->polymorphic_call_contexts
, count
);
4787 for (k
= 0; k
< ipa_get_cs_argument_count (args
); k
++)
4789 ipa_read_jump_function (ib
, ipa_get_ith_jump_func (args
, k
), e
,
4791 if (contexts_computed
)
4792 ipa_get_ith_polymorhic_call_context (args
, k
)->stream_in (ib
, data_in
);
4795 ipa_read_indirect_edge_info (ib
, data_in
, e
);
4799 /* Write jump functions for nodes in SET. */
4802 ipa_prop_write_jump_functions (void)
4804 struct cgraph_node
*node
;
4805 struct output_block
*ob
;
4806 unsigned int count
= 0;
4807 lto_symtab_encoder_iterator lsei
;
4808 lto_symtab_encoder_t encoder
;
4810 if (!ipa_node_params_sum
)
4813 ob
= create_output_block (LTO_section_jump_functions
);
4814 encoder
= ob
->decl_state
->symtab_node_encoder
;
4816 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4817 lsei_next_function_in_partition (&lsei
))
4819 node
= lsei_cgraph_node (lsei
);
4820 if (node
->has_gimple_body_p ()
4821 && IPA_NODE_REF (node
) != NULL
)
4825 streamer_write_uhwi (ob
, count
);
4827 /* Process all of the functions. */
4828 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4829 lsei_next_function_in_partition (&lsei
))
4831 node
= lsei_cgraph_node (lsei
);
4832 if (node
->has_gimple_body_p ()
4833 && IPA_NODE_REF (node
) != NULL
)
4834 ipa_write_node_info (ob
, node
);
4836 streamer_write_char_stream (ob
->main_stream
, 0);
4837 produce_asm (ob
, NULL
);
4838 destroy_output_block (ob
);
4841 /* Read section in file FILE_DATA of length LEN with data DATA. */
4844 ipa_prop_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
4847 const struct lto_function_header
*header
=
4848 (const struct lto_function_header
*) data
;
4849 const int cfg_offset
= sizeof (struct lto_function_header
);
4850 const int main_offset
= cfg_offset
+ header
->cfg_size
;
4851 const int string_offset
= main_offset
+ header
->main_size
;
4852 struct data_in
*data_in
;
4856 lto_input_block
ib_main ((const char *) data
+ main_offset
,
4857 header
->main_size
, file_data
->mode_table
);
4860 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
4861 header
->string_size
, vNULL
);
4862 count
= streamer_read_uhwi (&ib_main
);
4864 for (i
= 0; i
< count
; i
++)
4867 struct cgraph_node
*node
;
4868 lto_symtab_encoder_t encoder
;
4870 index
= streamer_read_uhwi (&ib_main
);
4871 encoder
= file_data
->symtab_node_encoder
;
4872 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
4874 gcc_assert (node
->definition
);
4875 ipa_read_node_info (&ib_main
, node
, data_in
);
4877 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
4879 lto_data_in_delete (data_in
);
4882 /* Read ipcp jump functions. */
4885 ipa_prop_read_jump_functions (void)
4887 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
4888 struct lto_file_decl_data
*file_data
;
4891 ipa_check_create_node_params ();
4892 ipa_check_create_edge_args ();
4893 ipa_register_cgraph_hooks ();
4895 while ((file_data
= file_data_vec
[j
++]))
4898 const char *data
= lto_get_section_data (file_data
, LTO_section_jump_functions
, NULL
, &len
);
4901 ipa_prop_read_section (file_data
, data
, len
);
4905 /* After merging units, we can get mismatch in argument counts.
4906 Also decl merging might've rendered parameter lists obsolete.
4907 Also compute called_with_variable_arg info. */
4910 ipa_update_after_lto_read (void)
4912 ipa_check_create_node_params ();
4913 ipa_check_create_edge_args ();
4917 write_ipcp_transformation_info (output_block
*ob
, cgraph_node
*node
)
4920 unsigned int count
= 0;
4921 lto_symtab_encoder_t encoder
;
4922 struct ipa_agg_replacement_value
*aggvals
, *av
;
4924 aggvals
= ipa_get_agg_replacements_for_node (node
);
4925 encoder
= ob
->decl_state
->symtab_node_encoder
;
4926 node_ref
= lto_symtab_encoder_encode (encoder
, node
);
4927 streamer_write_uhwi (ob
, node_ref
);
4929 for (av
= aggvals
; av
; av
= av
->next
)
4931 streamer_write_uhwi (ob
, count
);
4933 for (av
= aggvals
; av
; av
= av
->next
)
4935 struct bitpack_d bp
;
4937 streamer_write_uhwi (ob
, av
->offset
);
4938 streamer_write_uhwi (ob
, av
->index
);
4939 stream_write_tree (ob
, av
->value
, true);
4941 bp
= bitpack_create (ob
->main_stream
);
4942 bp_pack_value (&bp
, av
->by_ref
, 1);
4943 streamer_write_bitpack (&bp
);
4946 ipcp_transformation_summary
*ts
= ipcp_get_transformation_summary (node
);
4947 if (ts
&& vec_safe_length (ts
->alignments
) > 0)
4949 count
= ts
->alignments
->length ();
4951 streamer_write_uhwi (ob
, count
);
4952 for (unsigned i
= 0; i
< count
; ++i
)
4954 ipa_alignment
*parm_al
= &(*ts
->alignments
)[i
];
4956 struct bitpack_d bp
;
4957 bp
= bitpack_create (ob
->main_stream
);
4958 bp_pack_value (&bp
, parm_al
->known
, 1);
4959 streamer_write_bitpack (&bp
);
4962 streamer_write_uhwi (ob
, parm_al
->align
);
4963 streamer_write_hwi_in_range (ob
->main_stream
, 0, parm_al
->align
,
4969 streamer_write_uhwi (ob
, 0);
4972 /* Stream in the aggregate value replacement chain for NODE from IB. */
4975 read_ipcp_transformation_info (lto_input_block
*ib
, cgraph_node
*node
,
4978 struct ipa_agg_replacement_value
*aggvals
= NULL
;
4979 unsigned int count
, i
;
4981 count
= streamer_read_uhwi (ib
);
4982 for (i
= 0; i
<count
; i
++)
4984 struct ipa_agg_replacement_value
*av
;
4985 struct bitpack_d bp
;
4987 av
= ggc_alloc
<ipa_agg_replacement_value
> ();
4988 av
->offset
= streamer_read_uhwi (ib
);
4989 av
->index
= streamer_read_uhwi (ib
);
4990 av
->value
= stream_read_tree (ib
, data_in
);
4991 bp
= streamer_read_bitpack (ib
);
4992 av
->by_ref
= bp_unpack_value (&bp
, 1);
4996 ipa_set_node_agg_value_chain (node
, aggvals
);
4998 count
= streamer_read_uhwi (ib
);
5001 ipcp_grow_transformations_if_necessary ();
5003 ipcp_transformation_summary
*ts
= ipcp_get_transformation_summary (node
);
5004 vec_safe_grow_cleared (ts
->alignments
, count
);
5006 for (i
= 0; i
< count
; i
++)
5008 ipa_alignment
*parm_al
;
5009 parm_al
= &(*ts
->alignments
)[i
];
5010 struct bitpack_d bp
;
5011 bp
= streamer_read_bitpack (ib
);
5012 parm_al
->known
= bp_unpack_value (&bp
, 1);
5015 parm_al
->align
= streamer_read_uhwi (ib
);
5017 = streamer_read_hwi_in_range (ib
, "ipa-prop misalign",
5024 /* Write all aggregate replacement for nodes in set. */
5027 ipcp_write_transformation_summaries (void)
5029 struct cgraph_node
*node
;
5030 struct output_block
*ob
;
5031 unsigned int count
= 0;
5032 lto_symtab_encoder_iterator lsei
;
5033 lto_symtab_encoder_t encoder
;
5035 ob
= create_output_block (LTO_section_ipcp_transform
);
5036 encoder
= ob
->decl_state
->symtab_node_encoder
;
5038 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5039 lsei_next_function_in_partition (&lsei
))
5041 node
= lsei_cgraph_node (lsei
);
5042 if (node
->has_gimple_body_p ())
5046 streamer_write_uhwi (ob
, count
);
5048 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
5049 lsei_next_function_in_partition (&lsei
))
5051 node
= lsei_cgraph_node (lsei
);
5052 if (node
->has_gimple_body_p ())
5053 write_ipcp_transformation_info (ob
, node
);
5055 streamer_write_char_stream (ob
->main_stream
, 0);
5056 produce_asm (ob
, NULL
);
5057 destroy_output_block (ob
);
5060 /* Read replacements section in file FILE_DATA of length LEN with data
5064 read_replacements_section (struct lto_file_decl_data
*file_data
,
5068 const struct lto_function_header
*header
=
5069 (const struct lto_function_header
*) data
;
5070 const int cfg_offset
= sizeof (struct lto_function_header
);
5071 const int main_offset
= cfg_offset
+ header
->cfg_size
;
5072 const int string_offset
= main_offset
+ header
->main_size
;
5073 struct data_in
*data_in
;
5077 lto_input_block
ib_main ((const char *) data
+ main_offset
,
5078 header
->main_size
, file_data
->mode_table
);
5080 data_in
= lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
5081 header
->string_size
, vNULL
);
5082 count
= streamer_read_uhwi (&ib_main
);
5084 for (i
= 0; i
< count
; i
++)
5087 struct cgraph_node
*node
;
5088 lto_symtab_encoder_t encoder
;
5090 index
= streamer_read_uhwi (&ib_main
);
5091 encoder
= file_data
->symtab_node_encoder
;
5092 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
5094 gcc_assert (node
->definition
);
5095 read_ipcp_transformation_info (&ib_main
, node
, data_in
);
5097 lto_free_section_data (file_data
, LTO_section_jump_functions
, NULL
, data
,
5099 lto_data_in_delete (data_in
);
5102 /* Read IPA-CP aggregate replacements. */
5105 ipcp_read_transformation_summaries (void)
5107 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
5108 struct lto_file_decl_data
*file_data
;
5111 while ((file_data
= file_data_vec
[j
++]))
5114 const char *data
= lto_get_section_data (file_data
,
5115 LTO_section_ipcp_transform
,
5118 read_replacements_section (file_data
, data
, len
);
5122 /* Adjust the aggregate replacements in AGGVAL to reflect parameters skipped in
5126 adjust_agg_replacement_values (struct cgraph_node
*node
,
5127 struct ipa_agg_replacement_value
*aggval
)
5129 struct ipa_agg_replacement_value
*v
;
5130 int i
, c
= 0, d
= 0, *adj
;
5132 if (!node
->clone
.combined_args_to_skip
)
5135 for (v
= aggval
; v
; v
= v
->next
)
5137 gcc_assert (v
->index
>= 0);
5143 adj
= XALLOCAVEC (int, c
);
5144 for (i
= 0; i
< c
; i
++)
5145 if (bitmap_bit_p (node
->clone
.combined_args_to_skip
, i
))
5153 for (v
= aggval
; v
; v
= v
->next
)
5154 v
->index
= adj
[v
->index
];
5157 /* Dominator walker driving the ipcp modification phase. */
5159 class ipcp_modif_dom_walker
: public dom_walker
5162 ipcp_modif_dom_walker (struct func_body_info
*fbi
,
5163 vec
<ipa_param_descriptor
> descs
,
5164 struct ipa_agg_replacement_value
*av
,
5166 : dom_walker (CDI_DOMINATORS
), m_fbi (fbi
), m_descriptors (descs
),
5167 m_aggval (av
), m_something_changed (sc
), m_cfg_changed (cc
) {}
5169 virtual void before_dom_children (basic_block
);
5172 struct func_body_info
*m_fbi
;
5173 vec
<ipa_param_descriptor
> m_descriptors
;
5174 struct ipa_agg_replacement_value
*m_aggval
;
5175 bool *m_something_changed
, *m_cfg_changed
;
5179 ipcp_modif_dom_walker::before_dom_children (basic_block bb
)
5181 gimple_stmt_iterator gsi
;
5182 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5184 struct ipa_agg_replacement_value
*v
;
5185 gimple stmt
= gsi_stmt (gsi
);
5187 HOST_WIDE_INT offset
, size
;
5191 if (!gimple_assign_load_p (stmt
))
5193 rhs
= gimple_assign_rhs1 (stmt
);
5194 if (!is_gimple_reg_type (TREE_TYPE (rhs
)))
5199 while (handled_component_p (t
))
5201 /* V_C_E can do things like convert an array of integers to one
5202 bigger integer and similar things we do not handle below. */
5203 if (TREE_CODE (rhs
) == VIEW_CONVERT_EXPR
)
5208 t
= TREE_OPERAND (t
, 0);
5213 if (!ipa_load_from_parm_agg_1 (m_fbi
, m_descriptors
, stmt
, rhs
, &index
,
5214 &offset
, &size
, &by_ref
))
5216 for (v
= m_aggval
; v
; v
= v
->next
)
5217 if (v
->index
== index
5218 && v
->offset
== offset
)
5221 || v
->by_ref
!= by_ref
5222 || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v
->value
))) != size
)
5225 gcc_checking_assert (is_gimple_ip_invariant (v
->value
));
5226 if (!useless_type_conversion_p (TREE_TYPE (rhs
), TREE_TYPE (v
->value
)))
5228 if (fold_convertible_p (TREE_TYPE (rhs
), v
->value
))
5229 val
= fold_build1 (NOP_EXPR
, TREE_TYPE (rhs
), v
->value
);
5230 else if (TYPE_SIZE (TREE_TYPE (rhs
))
5231 == TYPE_SIZE (TREE_TYPE (v
->value
)))
5232 val
= fold_build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (rhs
), v
->value
);
5237 fprintf (dump_file
, " const ");
5238 print_generic_expr (dump_file
, v
->value
, 0);
5239 fprintf (dump_file
, " can't be converted to type of ");
5240 print_generic_expr (dump_file
, rhs
, 0);
5241 fprintf (dump_file
, "\n");
5249 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5251 fprintf (dump_file
, "Modifying stmt:\n ");
5252 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5254 gimple_assign_set_rhs_from_tree (&gsi
, val
);
5257 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5259 fprintf (dump_file
, "into:\n ");
5260 print_gimple_stmt (dump_file
, stmt
, 0, 0);
5261 fprintf (dump_file
, "\n");
5264 *m_something_changed
= true;
5265 if (maybe_clean_eh_stmt (stmt
)
5266 && gimple_purge_dead_eh_edges (gimple_bb (stmt
)))
5267 *m_cfg_changed
= true;
5272 /* Update alignment of formal parameters as described in
5273 ipcp_transformation_summary. */
5276 ipcp_update_alignments (struct cgraph_node
*node
)
5278 tree fndecl
= node
->decl
;
5279 tree parm
= DECL_ARGUMENTS (fndecl
);
5280 tree next_parm
= parm
;
5281 ipcp_transformation_summary
*ts
= ipcp_get_transformation_summary (node
);
5282 if (!ts
|| vec_safe_length (ts
->alignments
) == 0)
5284 const vec
<ipa_alignment
, va_gc
> &alignments
= *ts
->alignments
;
5285 unsigned count
= alignments
.length ();
5287 for (unsigned i
= 0; i
< count
; ++i
, parm
= next_parm
)
5289 if (node
->clone
.combined_args_to_skip
5290 && bitmap_bit_p (node
->clone
.combined_args_to_skip
, i
))
5292 gcc_checking_assert (parm
);
5293 next_parm
= DECL_CHAIN (parm
);
5295 if (!alignments
[i
].known
|| !is_gimple_reg (parm
))
5297 tree ddef
= ssa_default_def (DECL_STRUCT_FUNCTION (node
->decl
), parm
);
5302 fprintf (dump_file
, " Adjusting alignment of param %u to %u, "
5303 "misalignment to %u\n", i
, alignments
[i
].align
,
5304 alignments
[i
].misalign
);
5306 struct ptr_info_def
*pi
= get_ptr_info (ddef
);
5307 gcc_checking_assert (pi
);
5309 unsigned old_misalign
;
5310 bool old_known
= get_ptr_info_alignment (pi
, &old_align
, &old_misalign
);
5313 && old_align
>= alignments
[i
].align
)
5316 fprintf (dump_file
, " But the alignment was already %u.\n",
5320 set_ptr_info_alignment (pi
, alignments
[i
].align
, alignments
[i
].misalign
);
5324 /* IPCP transformation phase doing propagation of aggregate values. */
5327 ipcp_transform_function (struct cgraph_node
*node
)
5329 vec
<ipa_param_descriptor
> descriptors
= vNULL
;
5330 struct func_body_info fbi
;
5331 struct ipa_agg_replacement_value
*aggval
;
5333 bool cfg_changed
= false, something_changed
= false;
5335 gcc_checking_assert (cfun
);
5336 gcc_checking_assert (current_function_decl
);
5339 fprintf (dump_file
, "Modification phase of node %s/%i\n",
5340 node
->name (), node
->order
);
5342 ipcp_update_alignments (node
);
5343 aggval
= ipa_get_agg_replacements_for_node (node
);
5346 param_count
= count_formal_params (node
->decl
);
5347 if (param_count
== 0)
5349 adjust_agg_replacement_values (node
, aggval
);
5351 ipa_dump_agg_replacement_values (dump_file
, aggval
);
5355 fbi
.bb_infos
= vNULL
;
5356 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
5357 fbi
.param_count
= param_count
;
5360 descriptors
.safe_grow_cleared (param_count
);
5361 ipa_populate_param_decls (node
, descriptors
);
5362 calculate_dominance_info (CDI_DOMINATORS
);
5363 ipcp_modif_dom_walker (&fbi
, descriptors
, aggval
, &something_changed
,
5364 &cfg_changed
).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun
));
5367 struct ipa_bb_info
*bi
;
5368 FOR_EACH_VEC_ELT (fbi
.bb_infos
, i
, bi
)
5369 free_ipa_bb_info (bi
);
5370 fbi
.bb_infos
.release ();
5371 free_dominance_info (CDI_DOMINATORS
);
5372 (*ipcp_transformations
)[node
->uid
].agg_values
= NULL
;
5373 (*ipcp_transformations
)[node
->uid
].alignments
= NULL
;
5374 descriptors
.release ();
5376 if (!something_changed
)
5378 else if (cfg_changed
)
5379 return TODO_update_ssa_only_virtuals
| TODO_cleanup_cfg
;
5381 return TODO_update_ssa_only_virtuals
;