Hi, the first patch mainly introduces access methods to read parts of jump functions. I am no particular fan of these but the are now more widely spread than originally and above all checking asserts verifying that the correct part of the union is read should really be useful.
I have also unified creation of jump function in ipa-prop.c to new functions so that all fields are initialized. On the contrary, I have left update_jump_functions_after_inlining largely alone because it modifies jump functions in place (and there may be good reason not to touch some parts in the future, if not now), dumping functions and streaming because they are a bit special and simple too. There is also a tiny amount of other cleanup. Bootstrapped separately on x86_64-linux. OK for trunk? Thanks, Martin 2012-05-03 Martin Jambor <mjam...@suse.cz> * ipa-prop.h (ipa_get_jf_known_type_offset): New function. (ipa_get_jf_known_type_base_type): Likewise. (ipa_get_jf_known_type_component_type): Likewise. (ipa_get_jf_constant): Likewise. (ipa_get_jf_pass_through_formal_id): Likewise. (ipa_get_jf_pass_through_operation): Likewise. (ipa_get_jf_ancestor_offset): Likewise. (ipa_get_jf_ancestor_type): Likewise. (ipa_get_jf_ancestor_formal_id): Likewise. (ipa_get_jf_member_ptr_pfn): Likewise. * ipa-prop.c (ipa_set_jf_known_type): New function. (ipa_set_jf_constant): Likewise. (ipa_set_jf_simple_pass_through): Likewise. (ipa_set_jf_arith_pass_through): Likewise. (ipa_set_ancestor_jf): Likewise. (fill_member_ptr_cst_jump_function): Moved up and renamed to ipa_set_jf_member_ptr_cst. (detect_type_change_1): Use the new jump function creation functions. (compute_complex_assign_jump_func): Likewise. (compute_complex_ancestor_jump_func): Likewise. (compute_known_type_jump_func): Likewise. (compute_scalar_jump_functions): Likewise. (compute_pass_through_member_ptrs): Likewise. (determine_cst_member_ptr): Likewise. (combine_known_type_and_ancestor_jfs): Likewise. (try_make_edge_direct_simple_call): Likewise. (try_make_edge_direct_virtual_call): Likewise. (update_indirect_edges_after_inlining): Likewise. * ipa-cp.c (ipa_get_jf_pass_through_result): Use jump function access functions. Incorporat NOP_EXPR and BINFO handling from its callers. (ipa_get_jf_ancestor_result): Likewise. Incorporate handling BINFOs which was in its callers. (ipa_value_from_jfunc): Use jump function access functions. Some functionality moved to functions above. (propagate_vals_accross_ancestor): Likewise. (propagate_vals_accross_pass_through): Use jump function access functions. (propagate_accross_jump_function): Likewise. * ipa-inline-analysis.c (remap_edge_change_prob): Use jump function access functions. (inline_merge_summary): Likewise. Index: src/gcc/ipa-cp.c =================================================================== --- src.orig/gcc/ipa-cp.c +++ src/gcc/ipa-cp.c @@ -638,17 +638,19 @@ ipa_get_jf_pass_through_result (struct i { tree restype, res; - gcc_checking_assert (is_gimple_ip_invariant (input)); - if (jfunc->value.pass_through.operation == NOP_EXPR) + if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) return input; + else if (TREE_CODE (input) == TREE_BINFO) + return NULL_TREE; - if (TREE_CODE_CLASS (jfunc->value.pass_through.operation) + gcc_checking_assert (is_gimple_ip_invariant (input)); + if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) == tcc_comparison) restype = boolean_type_node; else restype = TREE_TYPE (input); - res = fold_binary (jfunc->value.pass_through.operation, restype, - input, jfunc->value.pass_through.operand); + res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype, + input, ipa_get_jf_pass_through_operand (jfunc)); if (res && !is_gimple_ip_invariant (res)) return NULL_TREE; @@ -662,12 +664,16 @@ ipa_get_jf_pass_through_result (struct i static tree ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input) { - if (TREE_CODE (input) == ADDR_EXPR) + if (TREE_CODE (input) == TREE_BINFO) + return get_binfo_at_offset (input, + ipa_get_jf_ancestor_offset (jfunc), + ipa_get_jf_ancestor_type (jfunc)); + else if (TREE_CODE (input) == ADDR_EXPR) { tree t = TREE_OPERAND (input, 0); t = build_ref_for_offset (EXPR_LOCATION (t), t, - jfunc->value.ancestor.offset, - jfunc->value.ancestor.type, NULL, false); + ipa_get_jf_ancestor_offset (jfunc), + ipa_get_jf_ancestor_type (jfunc), NULL, false); return build_fold_addr_expr (t); } else @@ -680,12 +686,12 @@ ipa_get_jf_ancestor_result (struct ipa_j static tree ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc) { - tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type); + tree base_binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc)); if (!base_binfo) return NULL_TREE; return get_binfo_at_offset (base_binfo, - jfunc->value.known_type.offset, - jfunc->value.known_type.component_type); + ipa_get_jf_known_type_offset (jfunc), + ipa_get_jf_known_type_component_type (jfunc)); } /* Determine whether JFUNC evaluates to a known value (that is either a @@ -697,7 +703,7 @@ tree ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) { if (jfunc->type == IPA_JF_CONST) - return jfunc->value.constant; + return ipa_get_jf_constant (jfunc); else if (jfunc->type == IPA_JF_KNOWN_TYPE) return ipa_value_from_known_type_jfunc (jfunc); else if (jfunc->type == IPA_JF_PASS_THROUGH @@ -707,9 +713,9 @@ ipa_value_from_jfunc (struct ipa_node_pa int idx; if (jfunc->type == IPA_JF_PASS_THROUGH) - idx = jfunc->value.pass_through.formal_id; + idx = ipa_get_jf_pass_through_formal_id (jfunc); else - idx = jfunc->value.ancestor.formal_id; + idx = ipa_get_jf_ancestor_formal_id (jfunc); if (info->ipcp_orig_node) input = VEC_index (tree, info->known_vals, idx); @@ -732,22 +738,9 @@ ipa_value_from_jfunc (struct ipa_node_pa return NULL_TREE; if (jfunc->type == IPA_JF_PASS_THROUGH) - { - if (jfunc->value.pass_through.operation == NOP_EXPR) - return input; - else if (TREE_CODE (input) == TREE_BINFO) - return NULL_TREE; - else - return ipa_get_jf_pass_through_result (jfunc, input); - } + return ipa_get_jf_pass_through_result (jfunc, input); else - { - if (TREE_CODE (input) == TREE_BINFO) - return get_binfo_at_offset (input, jfunc->value.ancestor.offset, - jfunc->value.ancestor.type); - else - return ipa_get_jf_ancestor_result (jfunc, input); - } + return ipa_get_jf_ancestor_result (jfunc, input); } else return NULL_TREE; @@ -907,13 +900,13 @@ propagate_vals_accross_pass_through (str struct ipcp_value *src_val; bool ret = false; - if (jfunc->value.pass_through.operation == NOP_EXPR) + if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) for (src_val = src_lat->values; src_val; src_val = src_val->next) ret |= add_value_to_lattice (dest_lat, src_val->value, cs, src_val, src_idx); /* Do not create new values when propagating within an SCC because if there - arithmetic functions with circular dependencies, there is infinite number - of them and we would just make lattices bottom. */ + are arithmetic functions with circular dependencies, there is infinite + number of them and we would just make lattices bottom. */ else if (edge_within_scc (cs)) ret = set_lattice_contains_variable (dest_lat); else @@ -956,13 +949,7 @@ propagate_vals_accross_ancestor (struct for (src_val = src_lat->values; src_val; src_val = src_val->next) { - tree t = src_val->value; - - if (TREE_CODE (t) == TREE_BINFO) - t = get_binfo_at_offset (t, jfunc->value.ancestor.offset, - jfunc->value.ancestor.type); - else - t = ipa_get_jf_ancestor_result (jfunc, t); + tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value); if (t) ret |= add_value_to_lattice (dest_lat, t, cs, src_val, src_idx); @@ -996,7 +983,7 @@ propagate_accross_jump_function (struct return set_lattice_contains_variable (dest_lat); } else - val = jfunc->value.constant; + val = ipa_get_jf_constant (jfunc); return add_value_to_lattice (dest_lat, val, cs, NULL, 0); } else if (jfunc->type == IPA_JF_PASS_THROUGH @@ -1008,9 +995,9 @@ propagate_accross_jump_function (struct bool ret; if (jfunc->type == IPA_JF_PASS_THROUGH) - src_idx = jfunc->value.pass_through.formal_id; + src_idx = ipa_get_jf_pass_through_formal_id (jfunc); else - src_idx = jfunc->value.ancestor.formal_id; + src_idx = ipa_get_jf_ancestor_formal_id (jfunc); src_lat = ipa_get_lattice (caller_info, src_idx); if (src_lat->bottom) Index: src/gcc/ipa-inline-analysis.c =================================================================== --- src.orig/gcc/ipa-inline-analysis.c +++ src/gcc/ipa-inline-analysis.c @@ -2514,16 +2514,16 @@ remap_edge_change_prob (struct cgraph_ed { struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i); if (jfunc->type == IPA_JF_PASS_THROUGH - && (jfunc->value.pass_through.formal_id + && (ipa_get_jf_pass_through_formal_id (jfunc) < (int) VEC_length (inline_param_summary_t, - inlined_es->param))) + inlined_es->param))) { + int jf_formal_id = ipa_get_jf_pass_through_formal_id (jfunc); int prob1 = VEC_index (inline_param_summary_t, es->param, i)->change_prob; int prob2 = VEC_index (inline_param_summary_t, - inlined_es->param, - jfunc->value.pass_through.formal_id)->change_prob; + inlined_es->param, jf_formal_id)->change_prob; int prob = ((prob1 * prob2 + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE); @@ -2649,8 +2649,8 @@ inline_merge_summary (struct cgraph_edge int map = -1; /* TODO: handle non-NOPs when merging. */ if (jfunc->type == IPA_JF_PASS_THROUGH - && jfunc->value.pass_through.operation == NOP_EXPR) - map = jfunc->value.pass_through.formal_id; + && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) + map = ipa_get_jf_pass_through_formal_id (jfunc); VEC_replace (int, operand_map, i, map); gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to))); } Index: src/gcc/ipa-prop.c =================================================================== --- src.orig/gcc/ipa-prop.c +++ src/gcc/ipa-prop.c @@ -266,6 +266,73 @@ ipa_print_all_jump_functions (FILE *f) } } +/* Set JFUNC to be a known type jump function. */ + +static void +ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset, + tree base_type, tree component_type) +{ + jfunc->type = IPA_JF_KNOWN_TYPE; + jfunc->value.known_type.offset = offset, + jfunc->value.known_type.base_type = base_type; + jfunc->value.known_type.component_type = component_type; +} + +/* Set JFUNC to be a constant jmp function. */ + +static void +ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant) +{ + jfunc->type = IPA_JF_CONST; + jfunc->value.constant = constant; +} + +/* Set JFUNC to be a simple pass-through jump function. */ +static void +ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id) +{ + jfunc->type = IPA_JF_PASS_THROUGH; + jfunc->value.pass_through.operand = NULL_TREE; + jfunc->value.pass_through.formal_id = formal_id; + jfunc->value.pass_through.operation = NOP_EXPR; +} + +/* Set JFUNC to be an arithmetic pass through jump function. */ + +static void +ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id, + tree operand, enum tree_code operation) +{ + jfunc->type = IPA_JF_PASS_THROUGH; + jfunc->value.pass_through.operand = operand; + jfunc->value.pass_through.formal_id = formal_id; + jfunc->value.pass_through.operation = operation; +} + +/* Set JFUNC to be an ancestor jump function. */ + +static void +ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset, + tree type, int formal_id) +{ + jfunc->type = IPA_JF_ANCESTOR; + jfunc->value.ancestor.formal_id = formal_id; + jfunc->value.ancestor.offset = offset; + jfunc->value.ancestor.type = type; +} + +/* Simple function filling in a member pointer constant jump function (with PFN + and DELTA as the constant value) into JFUNC. */ + +static void +ipa_set_jf_member_ptr_cst (struct ipa_jump_func *jfunc, + tree pfn, tree delta) +{ + jfunc->type = IPA_JF_CONST_MEMBER_PTR; + jfunc->value.member_cst.pfn = pfn; + jfunc->value.member_cst.delta = delta; +} + /* Structure to be passed in between detect_type_change and check_stmt_for_type_change. */ @@ -464,11 +531,7 @@ detect_type_change_1 (tree arg, tree bas || offset != 0) jfunc->type = IPA_JF_UNKNOWN; else - { - jfunc->type = IPA_JF_KNOWN_TYPE; - jfunc->value.known_type.base_type = tci.known_current_type; - jfunc->value.known_type.component_type = comp_type; - } + ipa_set_jf_known_type (jfunc, 0, tci.known_current_type, comp_type); return true; } @@ -666,18 +729,12 @@ compute_complex_assign_jump_func (struct TREE_TYPE (op1)))) return; - jfunc->type = IPA_JF_PASS_THROUGH; - jfunc->value.pass_through.formal_id = index; - jfunc->value.pass_through.operation = gimple_assign_rhs_code (stmt); - jfunc->value.pass_through.operand = op2; + ipa_set_jf_arith_pass_through (jfunc, index, op2, + gimple_assign_rhs_code (stmt)); } else if (gimple_assign_single_p (stmt) && !detect_type_change_ssa (tc_ssa, call, jfunc)) - { - jfunc->type = IPA_JF_PASS_THROUGH; - jfunc->value.pass_through.formal_id = index; - jfunc->value.pass_through.operation = NOP_EXPR; - } + ipa_set_jf_simple_pass_through (jfunc, index); return; } @@ -703,12 +760,7 @@ compute_complex_assign_jump_func (struct index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa)); if (index >= 0 && !detect_type_change (op1, base, call, jfunc, offset)) - { - jfunc->type = IPA_JF_ANCESTOR; - jfunc->value.ancestor.formal_id = index; - jfunc->value.ancestor.offset = offset; - jfunc->value.ancestor.type = TREE_TYPE (op1); - } + ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index); } /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if @@ -832,12 +884,7 @@ compute_complex_ancestor_jump_func (stru } if (!detect_type_change (obj, expr, call, jfunc, offset)) - { - jfunc->type = IPA_JF_ANCESTOR; - jfunc->value.ancestor.formal_id = index; - jfunc->value.ancestor.offset = offset; - jfunc->value.ancestor.type = TREE_TYPE (obj); - } + ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (obj), index); } /* Given OP which is passed as an actual argument to a called function, @@ -869,10 +916,7 @@ compute_known_type_jump_func (tree op, s || !TYPE_BINFO (TREE_TYPE (base))) return; - jfunc->type = IPA_JF_KNOWN_TYPE; - jfunc->value.known_type.base_type = TREE_TYPE (base); - jfunc->value.known_type.offset = offset; - jfunc->value.known_type.component_type = TREE_TYPE (op); + ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base), TREE_TYPE (op)); } @@ -898,10 +942,7 @@ compute_scalar_jump_functions (struct ip arg = gimple_call_arg (call, num); if (is_gimple_ip_invariant (arg)) - { - jfunc->type = IPA_JF_CONST; - jfunc->value.constant = arg; - } + ipa_set_jf_constant (jfunc, arg); else if (TREE_CODE (arg) == SSA_NAME) { if (SSA_NAME_IS_DEFAULT_DEF (arg)) @@ -910,11 +951,7 @@ compute_scalar_jump_functions (struct ip if (index >= 0 && !detect_type_change_ssa (arg, call, jfunc)) - { - jfunc->type = IPA_JF_PASS_THROUGH; - jfunc->value.pass_through.formal_id = index; - jfunc->value.pass_through.operation = NOP_EXPR; - } + ipa_set_jf_simple_pass_through (jfunc, index); } else { @@ -997,9 +1034,7 @@ compute_pass_through_member_ptrs (struct { struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, num); - jfunc->type = IPA_JF_PASS_THROUGH; - jfunc->value.pass_through.formal_id = index; - jfunc->value.pass_through.operation = NOP_EXPR; + ipa_set_jf_simple_pass_through (jfunc, index); } else undecided_members = true; @@ -1012,18 +1047,6 @@ compute_pass_through_member_ptrs (struct return undecided_members; } -/* Simple function filling in a member pointer constant jump function (with PFN - and DELTA as the constant value) into JFUNC. */ - -static void -fill_member_ptr_cst_jump_function (struct ipa_jump_func *jfunc, - tree pfn, tree delta) -{ - jfunc->type = IPA_JF_CONST_MEMBER_PTR; - jfunc->value.member_cst.pfn = pfn; - jfunc->value.member_cst.delta = delta; -} - /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement, return the rhs of its defining statement. */ @@ -1091,7 +1114,7 @@ determine_cst_member_ptr (gimple call, t method = TREE_OPERAND (rhs, 0); if (delta) { - fill_member_ptr_cst_jump_function (jfunc, rhs, delta); + ipa_set_jf_member_ptr_cst (jfunc, rhs, delta); return; } } @@ -1107,7 +1130,7 @@ determine_cst_member_ptr (gimple call, t delta = rhs; if (method) { - fill_member_ptr_cst_jump_function (jfunc, rhs, delta); + ipa_set_jf_member_ptr_cst (jfunc, rhs, delta); return; } } @@ -1681,13 +1704,13 @@ combine_known_type_and_ancestor_jfs (str HOST_WIDE_INT combined_offset; tree combined_type; - combined_offset = src->value.known_type.offset + dst->value.ancestor.offset; - combined_type = dst->value.ancestor.type; - - dst->type = IPA_JF_KNOWN_TYPE; - dst->value.known_type.base_type = src->value.known_type.base_type; - dst->value.known_type.offset = combined_offset; - dst->value.known_type.component_type = combined_type; + combined_offset = ipa_get_jf_known_type_offset (src) + + ipa_get_jf_ancestor_offset (dst); + combined_type = ipa_get_jf_ancestor_type (dst); + + ipa_set_jf_known_type (dst, combined_offset, + ipa_get_jf_known_type_base_type (src), + combined_type); } /* Update the jump functions associated with call graph edge E when the call @@ -1804,9 +1827,9 @@ try_make_edge_direct_simple_call (struct tree target; if (jfunc->type == IPA_JF_CONST) - target = jfunc->value.constant; + target = ipa_get_jf_constant (jfunc); else if (jfunc->type == IPA_JF_CONST_MEMBER_PTR) - target = jfunc->value.member_cst.pfn; + target = ipa_get_jf_member_ptr_pfn (jfunc); else return NULL; @@ -1827,9 +1850,9 @@ try_make_edge_direct_virtual_call (struc if (jfunc->type != IPA_JF_KNOWN_TYPE) return NULL; - binfo = TYPE_BINFO (jfunc->value.known_type.base_type); + binfo = TYPE_BINFO (ipa_get_jf_known_type_base_type (jfunc)); gcc_checking_assert (binfo); - binfo = get_binfo_at_offset (binfo, jfunc->value.known_type.offset + binfo = get_binfo_at_offset (binfo, ipa_get_jf_known_type_offset (jfunc) + ie->indirect_info->anc_offset, ie->indirect_info->otr_type); if (binfo) @@ -1881,12 +1904,12 @@ update_indirect_edges_after_inlining (st jfunc = ipa_get_ith_jump_func (top, ici->param_index); if (jfunc->type == IPA_JF_PASS_THROUGH - && jfunc->value.pass_through.operation == NOP_EXPR) - ici->param_index = jfunc->value.pass_through.formal_id; + && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) + ici->param_index = ipa_get_jf_pass_through_formal_id (jfunc); else if (jfunc->type == IPA_JF_ANCESTOR) { - ici->param_index = jfunc->value.ancestor.formal_id; - ici->anc_offset += jfunc->value.ancestor.offset; + ici->param_index = ipa_get_jf_ancestor_formal_id (jfunc); + ici->anc_offset += ipa_get_jf_ancestor_offset (jfunc); } else /* Either we can find a destination for this edge now or never. */ Index: src/gcc/ipa-prop.h =================================================================== --- src.orig/gcc/ipa-prop.h +++ src/gcc/ipa-prop.h @@ -113,7 +113,7 @@ struct GTY(()) ipa_ancestor_jf_data { /* Offset of the field representing the ancestor. */ HOST_WIDE_INT offset; - /* TYpe of the result. */ + /* Type of the result. */ tree type; /* Number of the caller's formal parameter being passed. */ int formal_id; @@ -149,6 +149,108 @@ typedef struct GTY (()) ipa_jump_func DEF_VEC_O (ipa_jump_func_t); DEF_VEC_ALLOC_O (ipa_jump_func_t, gc); +/* Return the offset of the component that is decribed by a known type jump + function JFUNC. */ + +static inline HOST_WIDE_INT +ipa_get_jf_known_type_offset (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE); + return jfunc->value.known_type.offset; +} + +/* Return the base type of a known type jump function JFUNC. */ + +static inline tree +ipa_get_jf_known_type_base_type (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE); + return jfunc->value.known_type.base_type; +} + +/* Return the component type of a known type jump function JFUNC. */ + +static inline tree +ipa_get_jf_known_type_component_type (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_KNOWN_TYPE); + return jfunc->value.known_type.component_type; +} + +/* Return the constant stored in a constant jump functin JFUNC. */ + +static inline tree +ipa_get_jf_constant (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_CONST); + return jfunc->value.constant; +} + +/* Return the operand of a pass through jmp function JFUNC. */ + +static inline tree +ipa_get_jf_pass_through_operand (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH); + return jfunc->value.pass_through.operand; +} + +/* Return the number of the caller's formal parameter that a pass through jump + function JFUNC refers to. */ + +static inline int +ipa_get_jf_pass_through_formal_id (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH); + return jfunc->value.pass_through.formal_id; +} + +/* Return operation of a pass through jump function JFUNC. */ + +static inline enum tree_code +ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH); + return jfunc->value.pass_through.operation; +} + +/* Return the offset of an ancestor jump function JFUNC. */ + +static inline HOST_WIDE_INT +ipa_get_jf_ancestor_offset (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR); + return jfunc->value.ancestor.offset; +} + +/* Return the result type of an ancestor jump function JFUNC. */ + +static inline tree +ipa_get_jf_ancestor_type (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR); + return jfunc->value.ancestor.type; +} + +/* Return the number of the caller's formal parameter that an ancestor jump + function JFUNC refers to. */ + +static inline int +ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR); + return jfunc->value.ancestor.formal_id; +} + +/* Return the pfn part of a member pointer constant jump function JFUNC. */ + +static inline tree +ipa_get_jf_member_ptr_pfn (struct ipa_jump_func *jfunc) +{ + gcc_checking_assert (jfunc->type == IPA_JF_CONST_MEMBER_PTR); + return jfunc->value.member_cst.pfn; +} + /* Summary describing a single formal parameter. */ struct ipa_param_descriptor