Makefile.in (INTERNAL_FN_DEF, [...]): Define.
gcc/ * Makefile.in (INTERNAL_FN_DEF, INTERNAL_FN_H): Define. (GIMPLE_H): Include $(INTERNAL_FN_H). (OBJS-common): Add internal-fn.o. (internal-fn.o): New rule. * internal-fn.def: New file. * internal-fn.h: Likewise. * internal-fn.c: Likewise. * gimple.h: Include internal-fn.h. (GF_CALL_INTERNAL): New gf_mask. (gimple_statement_call): Put fntype into a union with a new internal_fn field. (gimple_build_call_internal): Declare. (gimple_build_call_internal_vec): Likewise. (gimple_call_same_target_p): Likewise. (gimple_call_internal_p): New function. (gimple_call_internal_fn): Likewise. (gimple_call_fntype): Return null for internal calls. (gimple_call_set_fntype): Assert that the function is not internal. (gimple_call_set_fn): Likewise. (gimple_call_set_fndecl): Likewise. (gimple_call_set_internal_fn): New function. (gimple_call_addr_fndecl): Handle null functions. (gimple_call_return_type): Likewise null types. * gimple.c (gimple_build_call_internal_1): New function. (gimple_build_call_internal): Likewise. (gimple_build_call_internal_vec): Likewise. (gimple_call_same_target_p): Likewise. (gimple_call_flags): Handle calls to internal functions. (gimple_call_fnspec): New function. (gimple_call_arg_flags, gimple_call_return_flags): Use it. (gimple_has_side_effects): Handle null functions. (gimple_rhs_has_side_effects): Likewise. (gimple_call_copy_skip_args): Handle calls to internal functions. * cfgexpand.c (expand_call_stmt): Likewise. * expr.c (expand_expr_real_1): Assert that the call isn't internal. * gimple-fold.c (gimple_fold_call): Handle null functions. (gimple_fold_stmt_to_constant_1): Don't fold calls to internal functions. * gimple-low.c (gimple_check_call_args): Handle calls to internal functions. * gimple-pretty-print.c (dump_gimple_call): Likewise. * ipa-prop.c (ipa_analyze_call_uses): Handle null functions. * tree-cfg.c (verify_gimple_call): Handle calls to internal functions. (do_warn_unused_result): Likewise. * tree-eh.c (same_handler_p): Use gimple_call_same_target_p. * tree-ssa-ccp.c (ccp_fold_stmt): Handle calls to internal functions. * tree-ssa-dom.c (hashable_expr): Use the gimple statement to record the target of a call. (initialize_hash_element): Update accordingly. (hashable_expr_equal_p): Use gimple_call_same_target_p. (iterative_hash_hashable_expr): Handle calls to internal functions. (print_expr_hash_elt): Likewise. * tree-ssa-pre.c (can_value_number_call): Likewise. (eliminate): Handle null functions. * tree-ssa-sccvn.c (visit_use): Handle calls to internal functions. * tree-ssa-structalias.c (get_fi_for_callee): Likewise. (find_func_aliases): Likewise. * value-prof.c (gimple_ic_transform): Likewise. (gimple_indirect_call_to_profile): Likewise. * lto-streamer-in.c (input_gimple_stmt): Likewise. * lto-streamer-out.c (output_gimple_stmt): Likewise. From-SVN: r172758
This commit is contained in:
parent
7da29ed0cb
commit
25583c4f45
|
@ -1,3 +1,67 @@
|
|||
2011-04-20 Richard Sandiford <richard.sandiford@linaro.org>
|
||||
|
||||
* Makefile.in (INTERNAL_FN_DEF, INTERNAL_FN_H): Define.
|
||||
(GIMPLE_H): Include $(INTERNAL_FN_H).
|
||||
(OBJS-common): Add internal-fn.o.
|
||||
(internal-fn.o): New rule.
|
||||
* internal-fn.def: New file.
|
||||
* internal-fn.h: Likewise.
|
||||
* internal-fn.c: Likewise.
|
||||
* gimple.h: Include internal-fn.h.
|
||||
(GF_CALL_INTERNAL): New gf_mask.
|
||||
(gimple_statement_call): Put fntype into a union with a new
|
||||
internal_fn field.
|
||||
(gimple_build_call_internal): Declare.
|
||||
(gimple_build_call_internal_vec): Likewise.
|
||||
(gimple_call_same_target_p): Likewise.
|
||||
(gimple_call_internal_p): New function.
|
||||
(gimple_call_internal_fn): Likewise.
|
||||
(gimple_call_fntype): Return null for internal calls.
|
||||
(gimple_call_set_fntype): Assert that the function is not internal.
|
||||
(gimple_call_set_fn): Likewise.
|
||||
(gimple_call_set_fndecl): Likewise.
|
||||
(gimple_call_set_internal_fn): New function.
|
||||
(gimple_call_addr_fndecl): Handle null functions.
|
||||
(gimple_call_return_type): Likewise null types.
|
||||
* gimple.c (gimple_build_call_internal_1): New function.
|
||||
(gimple_build_call_internal): Likewise.
|
||||
(gimple_build_call_internal_vec): Likewise.
|
||||
(gimple_call_same_target_p): Likewise.
|
||||
(gimple_call_flags): Handle calls to internal functions.
|
||||
(gimple_call_fnspec): New function.
|
||||
(gimple_call_arg_flags, gimple_call_return_flags): Use it.
|
||||
(gimple_has_side_effects): Handle null functions.
|
||||
(gimple_rhs_has_side_effects): Likewise.
|
||||
(gimple_call_copy_skip_args): Handle calls to internal functions.
|
||||
* cfgexpand.c (expand_call_stmt): Likewise.
|
||||
* expr.c (expand_expr_real_1): Assert that the call isn't internal.
|
||||
* gimple-fold.c (gimple_fold_call): Handle null functions.
|
||||
(gimple_fold_stmt_to_constant_1): Don't fold
|
||||
calls to internal functions.
|
||||
* gimple-low.c (gimple_check_call_args): Handle calls to internal
|
||||
functions.
|
||||
* gimple-pretty-print.c (dump_gimple_call): Likewise.
|
||||
* ipa-prop.c (ipa_analyze_call_uses): Handle null functions.
|
||||
* tree-cfg.c (verify_gimple_call): Handle calls to internal functions.
|
||||
(do_warn_unused_result): Likewise.
|
||||
* tree-eh.c (same_handler_p): Use gimple_call_same_target_p.
|
||||
* tree-ssa-ccp.c (ccp_fold_stmt): Handle calls to internal functions.
|
||||
* tree-ssa-dom.c (hashable_expr): Use the gimple statement to record
|
||||
the target of a call.
|
||||
(initialize_hash_element): Update accordingly.
|
||||
(hashable_expr_equal_p): Use gimple_call_same_target_p.
|
||||
(iterative_hash_hashable_expr): Handle calls to internal functions.
|
||||
(print_expr_hash_elt): Likewise.
|
||||
* tree-ssa-pre.c (can_value_number_call): Likewise.
|
||||
(eliminate): Handle null functions.
|
||||
* tree-ssa-sccvn.c (visit_use): Handle calls to internal functions.
|
||||
* tree-ssa-structalias.c (get_fi_for_callee): Likewise.
|
||||
(find_func_aliases): Likewise.
|
||||
* value-prof.c (gimple_ic_transform): Likewise.
|
||||
(gimple_indirect_call_to_profile): Likewise.
|
||||
* lto-streamer-in.c (input_gimple_stmt): Likewise.
|
||||
* lto-streamer-out.c (output_gimple_stmt): Likewise.
|
||||
|
||||
2011-04-19 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* ipa-inline-transform.c (save_inline_function_body): Add comments.
|
||||
|
|
|
@ -893,6 +893,8 @@ RTL_ERROR_H = $(RTL_H) $(DIAGNOSTIC_CORE_H)
|
|||
READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h
|
||||
PARAMS_H = params.h params.def
|
||||
BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
|
||||
INTERNAL_FN_DEF = internal-fn.def
|
||||
INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF)
|
||||
TREE_H = tree.h all-tree.def tree.def c-family/c-common.def \
|
||||
$(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
|
||||
$(INPUT_H) statistics.h $(VEC_H) treestruct.def $(HASHTAB_H) \
|
||||
|
@ -901,8 +903,8 @@ TREE_H = tree.h all-tree.def tree.def c-family/c-common.def \
|
|||
REGSET_H = regset.h $(BITMAP_H) hard-reg-set.h
|
||||
BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) cfghooks.h
|
||||
GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h $(VEC_H) \
|
||||
$(GGC_H) $(BASIC_BLOCK_H) $(TARGET_H) tree-ssa-operands.h \
|
||||
tree-ssa-alias.h vecir.h
|
||||
vecir.h $(GGC_H) $(BASIC_BLOCK_H) $(TARGET_H) tree-ssa-operands.h \
|
||||
tree-ssa-alias.h $(INTERNAL_FN_H)
|
||||
GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
|
||||
COVERAGE_H = coverage.h $(GCOV_IO_H)
|
||||
DEMANGLE_H = $(srcdir)/../include/demangle.h
|
||||
|
@ -1274,6 +1276,7 @@ OBJS-common = \
|
|||
init-regs.o \
|
||||
input.o \
|
||||
integrate.o \
|
||||
internal-fn.o \
|
||||
intl.o \
|
||||
ira.o \
|
||||
ira-build.o \
|
||||
|
@ -2760,6 +2763,8 @@ tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
|||
$(TM_H) $(TREE_H) $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) \
|
||||
$(TREE_PASS_H) tree-ssa-propagate.h tree-pretty-print.h \
|
||||
gimple-pretty-print.h
|
||||
internal-fn.o : internal-fn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
|
||||
$(INTERNAL_FN_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) $(GIMPLE_H)
|
||||
gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
|
||||
$(GGC_H) $(GIMPLE_H) $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_H) gt-gimple.h \
|
||||
$(TREE_FLOW_H) value-prof.h $(FLAGS_H) $(DEMANGLE_H) \
|
||||
|
|
|
@ -1837,10 +1837,16 @@ expand_gimple_cond (basic_block bb, gimple stmt)
|
|||
static void
|
||||
expand_call_stmt (gimple stmt)
|
||||
{
|
||||
tree exp, decl, lhs = gimple_call_lhs (stmt);
|
||||
tree exp, decl, lhs;
|
||||
bool builtin_p;
|
||||
size_t i;
|
||||
|
||||
if (gimple_call_internal_p (stmt))
|
||||
{
|
||||
expand_internal_call (stmt);
|
||||
return;
|
||||
}
|
||||
|
||||
exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
|
||||
|
||||
CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
|
||||
|
@ -1890,6 +1896,7 @@ expand_call_stmt (gimple stmt)
|
|||
SET_EXPR_LOCATION (exp, gimple_location (stmt));
|
||||
TREE_BLOCK (exp) = gimple_block (stmt);
|
||||
|
||||
lhs = gimple_call_lhs (stmt);
|
||||
if (lhs)
|
||||
expand_assignment (lhs, exp, false);
|
||||
else
|
||||
|
|
|
@ -8528,9 +8528,12 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
|||
if (code == SSA_NAME
|
||||
&& (g = SSA_NAME_DEF_STMT (ssa_name))
|
||||
&& gimple_code (g) == GIMPLE_CALL)
|
||||
pmode = promote_function_mode (type, mode, &unsignedp,
|
||||
gimple_call_fntype (g),
|
||||
2);
|
||||
{
|
||||
gcc_assert (!gimple_call_internal_p (g));
|
||||
pmode = promote_function_mode (type, mode, &unsignedp,
|
||||
gimple_call_fntype (g),
|
||||
2);
|
||||
}
|
||||
else
|
||||
pmode = promote_decl_mode (exp, &unsignedp);
|
||||
gcc_assert (GET_MODE (decl_rtl) == pmode);
|
||||
|
|
|
@ -1541,7 +1541,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
|
|||
|
||||
/* Check for virtual calls that became direct calls. */
|
||||
callee = gimple_call_fn (stmt);
|
||||
if (TREE_CODE (callee) == OBJ_TYPE_REF)
|
||||
if (callee && TREE_CODE (callee) == OBJ_TYPE_REF)
|
||||
{
|
||||
tree binfo, fndecl, delta, obj;
|
||||
HOST_WIDE_INT token;
|
||||
|
@ -2958,7 +2958,13 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
|
|||
|
||||
case GIMPLE_CALL:
|
||||
{
|
||||
tree fn = (*valueize) (gimple_call_fn (stmt));
|
||||
tree fn;
|
||||
|
||||
if (gimple_call_internal_p (stmt))
|
||||
/* No folding yet for these functions. */
|
||||
return NULL_TREE;
|
||||
|
||||
fn = (*valueize) (gimple_call_fn (stmt));
|
||||
if (TREE_CODE (fn) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
|
||||
&& DECL_BUILT_IN (TREE_OPERAND (fn, 0)))
|
||||
|
|
|
@ -219,6 +219,10 @@ gimple_check_call_args (gimple stmt, tree fndecl)
|
|||
tree parms, p;
|
||||
unsigned int i, nargs;
|
||||
|
||||
/* Calls to internal functions always match their signature. */
|
||||
if (gimple_call_internal_p (stmt))
|
||||
return true;
|
||||
|
||||
nargs = gimple_call_num_args (stmt);
|
||||
|
||||
/* Get argument types for verification. */
|
||||
|
|
|
@ -616,8 +616,12 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
|
|||
|
||||
if (flags & TDF_RAW)
|
||||
{
|
||||
dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T",
|
||||
gs, gimple_call_fn (gs), lhs);
|
||||
if (gimple_call_internal_p (gs))
|
||||
dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs,
|
||||
internal_fn_name (gimple_call_internal_fn (gs)), lhs);
|
||||
else
|
||||
dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T",
|
||||
gs, gimple_call_fn (gs), lhs);
|
||||
if (gimple_call_num_args (gs) > 0)
|
||||
{
|
||||
pp_string (buffer, ", ");
|
||||
|
@ -637,7 +641,10 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
|
|||
|
||||
pp_space (buffer);
|
||||
}
|
||||
print_call_name (buffer, gimple_call_fn (gs), flags);
|
||||
if (gimple_call_internal_p (gs))
|
||||
pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs)));
|
||||
else
|
||||
print_call_name (buffer, gimple_call_fn (gs), flags);
|
||||
pp_string (buffer, " (");
|
||||
dump_gimple_call_args (buffer, gs, flags);
|
||||
pp_character (buffer, ')');
|
||||
|
|
123
gcc/gimple.c
123
gcc/gimple.c
|
@ -277,6 +277,59 @@ gimple_build_call (tree fn, unsigned nargs, ...)
|
|||
}
|
||||
|
||||
|
||||
/* Helper for gimple_build_call_internal and gimple_build_call_internal_vec.
|
||||
Build the basic components of a GIMPLE_CALL statement to internal
|
||||
function FN with NARGS arguments. */
|
||||
|
||||
static inline gimple
|
||||
gimple_build_call_internal_1 (enum internal_fn fn, unsigned nargs)
|
||||
{
|
||||
gimple s = gimple_build_with_ops (GIMPLE_CALL, ERROR_MARK, nargs + 3);
|
||||
s->gsbase.subcode |= GF_CALL_INTERNAL;
|
||||
gimple_call_set_internal_fn (s, fn);
|
||||
gimple_call_reset_alias_info (s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_CALL statement to internal function FN. NARGS is
|
||||
the number of arguments. The ... are the arguments. */
|
||||
|
||||
gimple
|
||||
gimple_build_call_internal (enum internal_fn fn, unsigned nargs, ...)
|
||||
{
|
||||
va_list ap;
|
||||
gimple call;
|
||||
unsigned i;
|
||||
|
||||
call = gimple_build_call_internal_1 (fn, nargs);
|
||||
va_start (ap, nargs);
|
||||
for (i = 0; i < nargs; i++)
|
||||
gimple_call_set_arg (call, i, va_arg (ap, tree));
|
||||
va_end (ap);
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_CALL statement to internal function FN with the arguments
|
||||
specified in vector ARGS. */
|
||||
|
||||
gimple
|
||||
gimple_build_call_internal_vec (enum internal_fn fn, VEC(tree, heap) *args)
|
||||
{
|
||||
unsigned i, nargs;
|
||||
gimple call;
|
||||
|
||||
nargs = VEC_length (tree, args);
|
||||
call = gimple_build_call_internal_1 (fn, nargs);
|
||||
for (i = 0; i < nargs; i++)
|
||||
gimple_call_set_arg (call, i, VEC_index (tree, args, i));
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_CALL statement from CALL_EXPR T. Note that T is
|
||||
assumed to be in GIMPLE form already. Minimal checking is done of
|
||||
this fact. */
|
||||
|
@ -1778,6 +1831,20 @@ gimple_has_body_p (tree fndecl)
|
|||
return (gimple_body (fndecl) || (fn && fn->cfg));
|
||||
}
|
||||
|
||||
/* Return true if calls C1 and C2 are known to go to the same function. */
|
||||
|
||||
bool
|
||||
gimple_call_same_target_p (const_gimple c1, const_gimple c2)
|
||||
{
|
||||
if (gimple_call_internal_p (c1))
|
||||
return (gimple_call_internal_p (c2)
|
||||
&& gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2));
|
||||
else
|
||||
return (gimple_call_fn (c1) == gimple_call_fn (c2)
|
||||
|| (gimple_call_fndecl (c1)
|
||||
&& gimple_call_fndecl (c1) == gimple_call_fndecl (c2)));
|
||||
}
|
||||
|
||||
/* Detect flags from a GIMPLE_CALL. This is just like
|
||||
call_expr_flags, but for gimple tuples. */
|
||||
|
||||
|
@ -1789,6 +1856,8 @@ gimple_call_flags (const_gimple stmt)
|
|||
|
||||
if (decl)
|
||||
flags = flags_from_decl_or_type (decl);
|
||||
else if (gimple_call_internal_p (stmt))
|
||||
flags = internal_fn_flags (gimple_call_internal_fn (stmt));
|
||||
else
|
||||
flags = flags_from_decl_or_type (gimple_call_fntype (stmt));
|
||||
|
||||
|
@ -1798,18 +1867,32 @@ gimple_call_flags (const_gimple stmt)
|
|||
return flags;
|
||||
}
|
||||
|
||||
/* Return the "fn spec" string for call STMT. */
|
||||
|
||||
static tree
|
||||
gimple_call_fnspec (const_gimple stmt)
|
||||
{
|
||||
tree type, attr;
|
||||
|
||||
type = gimple_call_fntype (stmt);
|
||||
if (!type)
|
||||
return NULL_TREE;
|
||||
|
||||
attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
|
||||
if (!attr)
|
||||
return NULL_TREE;
|
||||
|
||||
return TREE_VALUE (TREE_VALUE (attr));
|
||||
}
|
||||
|
||||
/* Detects argument flags for argument number ARG on call STMT. */
|
||||
|
||||
int
|
||||
gimple_call_arg_flags (const_gimple stmt, unsigned arg)
|
||||
{
|
||||
tree type = gimple_call_fntype (stmt);
|
||||
tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
|
||||
if (!attr)
|
||||
return 0;
|
||||
tree attr = gimple_call_fnspec (stmt);
|
||||
|
||||
attr = TREE_VALUE (TREE_VALUE (attr));
|
||||
if (1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
|
||||
if (!attr || 1 + arg >= (unsigned) TREE_STRING_LENGTH (attr))
|
||||
return 0;
|
||||
|
||||
switch (TREE_STRING_POINTER (attr)[1 + arg])
|
||||
|
@ -1841,19 +1924,13 @@ gimple_call_arg_flags (const_gimple stmt, unsigned arg)
|
|||
int
|
||||
gimple_call_return_flags (const_gimple stmt)
|
||||
{
|
||||
tree type;
|
||||
tree attr = NULL_TREE;
|
||||
tree attr;
|
||||
|
||||
if (gimple_call_flags (stmt) & ECF_MALLOC)
|
||||
return ERF_NOALIAS;
|
||||
|
||||
type = gimple_call_fntype (stmt);
|
||||
attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type));
|
||||
if (!attr)
|
||||
return 0;
|
||||
|
||||
attr = TREE_VALUE (TREE_VALUE (attr));
|
||||
if (TREE_STRING_LENGTH (attr) < 1)
|
||||
attr = gimple_call_fnspec (stmt);
|
||||
if (!attr || TREE_STRING_LENGTH (attr) < 1)
|
||||
return 0;
|
||||
|
||||
switch (TREE_STRING_POINTER (attr)[0])
|
||||
|
@ -2278,6 +2355,7 @@ gimple_has_side_effects (const_gimple s)
|
|||
if (is_gimple_call (s))
|
||||
{
|
||||
unsigned nargs = gimple_call_num_args (s);
|
||||
tree fn;
|
||||
|
||||
if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE)))
|
||||
return true;
|
||||
|
@ -2292,7 +2370,8 @@ gimple_has_side_effects (const_gimple s)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (TREE_SIDE_EFFECTS (gimple_call_fn (s)))
|
||||
fn = gimple_call_fn (s);
|
||||
if (fn && TREE_SIDE_EFFECTS (fn))
|
||||
return true;
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
|
@ -2331,14 +2410,15 @@ gimple_rhs_has_side_effects (const_gimple s)
|
|||
if (is_gimple_call (s))
|
||||
{
|
||||
unsigned nargs = gimple_call_num_args (s);
|
||||
tree fn;
|
||||
|
||||
if (!(gimple_call_flags (s) & (ECF_CONST | ECF_PURE)))
|
||||
return true;
|
||||
|
||||
/* We cannot use gimple_has_volatile_ops here,
|
||||
because we must ignore a volatile LHS. */
|
||||
if (TREE_SIDE_EFFECTS (gimple_call_fn (s))
|
||||
|| TREE_THIS_VOLATILE (gimple_call_fn (s)))
|
||||
fn = gimple_call_fn (s);
|
||||
if (fn && (TREE_SIDE_EFFECTS (fn) || TREE_THIS_VOLATILE (fn)))
|
||||
{
|
||||
gcc_assert (gimple_has_volatile_ops (s));
|
||||
return true;
|
||||
|
@ -3094,7 +3174,6 @@ gimple
|
|||
gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
|
||||
{
|
||||
int i;
|
||||
tree fn = gimple_call_fn (stmt);
|
||||
int nargs = gimple_call_num_args (stmt);
|
||||
VEC(tree, heap) *vargs = VEC_alloc (tree, heap, nargs);
|
||||
gimple new_stmt;
|
||||
|
@ -3103,7 +3182,11 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
|
|||
if (!bitmap_bit_p (args_to_skip, i))
|
||||
VEC_quick_push (tree, vargs, gimple_call_arg (stmt, i));
|
||||
|
||||
new_stmt = gimple_build_call_vec (fn, vargs);
|
||||
if (gimple_call_internal_p (stmt))
|
||||
new_stmt = gimple_build_call_internal_vec (gimple_call_internal_fn (stmt),
|
||||
vargs);
|
||||
else
|
||||
new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs);
|
||||
VEC_free (tree, heap, vargs);
|
||||
if (gimple_call_lhs (stmt))
|
||||
gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
|
||||
|
|
57
gcc/gimple.h
57
gcc/gimple.h
|
@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "basic-block.h"
|
||||
#include "tree-ssa-operands.h"
|
||||
#include "tree-ssa-alias.h"
|
||||
#include "internal-fn.h"
|
||||
|
||||
struct gimple_seq_node_d;
|
||||
typedef struct gimple_seq_node_d *gimple_seq_node;
|
||||
|
@ -103,6 +104,7 @@ enum gf_mask {
|
|||
GF_CALL_VA_ARG_PACK = 1 << 4,
|
||||
GF_CALL_NOTHROW = 1 << 5,
|
||||
GF_CALL_ALLOCA_FOR_VAR = 1 << 6,
|
||||
GF_CALL_INTERNAL = 1 << 7,
|
||||
GF_OMP_PARALLEL_COMBINED = 1 << 0,
|
||||
|
||||
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
|
||||
|
@ -407,7 +409,10 @@ struct GTY(()) gimple_statement_call
|
|||
struct pt_solution call_clobbered;
|
||||
|
||||
/* [ WORD 13 ] */
|
||||
tree fntype;
|
||||
union GTY ((desc ("%1.membase.opbase.gsbase.subcode & GF_CALL_INTERNAL"))) {
|
||||
tree GTY ((tag ("0"))) fntype;
|
||||
enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn;
|
||||
} u;
|
||||
|
||||
/* [ WORD 14 ]
|
||||
Operand vector. NOTE! This must always be the last field
|
||||
|
@ -821,6 +826,8 @@ gimple gimple_build_debug_bind_stat (tree, tree, gimple MEM_STAT_DECL);
|
|||
|
||||
gimple gimple_build_call_vec (tree, VEC(tree, heap) *);
|
||||
gimple gimple_build_call (tree, unsigned, ...);
|
||||
gimple gimple_build_call_internal (enum internal_fn, unsigned, ...);
|
||||
gimple gimple_build_call_internal_vec (enum internal_fn, VEC(tree, heap) *);
|
||||
gimple gimple_build_call_from_tree (tree);
|
||||
gimple gimplify_assign (tree, tree, gimple_seq *);
|
||||
gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
|
||||
|
@ -865,6 +872,7 @@ gimple_seq gimple_seq_alloc (void);
|
|||
void gimple_seq_free (gimple_seq);
|
||||
void gimple_seq_add_seq (gimple_seq *, gimple_seq);
|
||||
gimple_seq gimple_seq_copy (gimple_seq);
|
||||
bool gimple_call_same_target_p (const_gimple, const_gimple);
|
||||
int gimple_call_flags (const_gimple);
|
||||
int gimple_call_return_flags (const_gimple);
|
||||
int gimple_call_arg_flags (const_gimple, unsigned);
|
||||
|
@ -2007,13 +2015,36 @@ gimple_call_set_lhs (gimple gs, tree lhs)
|
|||
}
|
||||
|
||||
|
||||
/* Return true if call GS calls an internal-only function, as enumerated
|
||||
by internal_fn. */
|
||||
|
||||
static inline bool
|
||||
gimple_call_internal_p (const_gimple gs)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
return (gs->gsbase.subcode & GF_CALL_INTERNAL) != 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return the target of internal call GS. */
|
||||
|
||||
static inline enum internal_fn
|
||||
gimple_call_internal_fn (const_gimple gs)
|
||||
{
|
||||
gcc_gimple_checking_assert (gimple_call_internal_p (gs));
|
||||
return gs->gimple_call.u.internal_fn;
|
||||
}
|
||||
|
||||
|
||||
/* Return the function type of the function called by GS. */
|
||||
|
||||
static inline tree
|
||||
gimple_call_fntype (const_gimple gs)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
return gs->gimple_call.fntype;
|
||||
if (gimple_call_internal_p (gs))
|
||||
return NULL_TREE;
|
||||
return gs->gimple_call.u.fntype;
|
||||
}
|
||||
|
||||
/* Set the type of the function called by GS to FNTYPE. */
|
||||
|
@ -2022,7 +2053,8 @@ static inline void
|
|||
gimple_call_set_fntype (gimple gs, tree fntype)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
gs->gimple_call.fntype = fntype;
|
||||
gcc_gimple_checking_assert (!gimple_call_internal_p (gs));
|
||||
gs->gimple_call.u.fntype = fntype;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2053,6 +2085,7 @@ static inline void
|
|||
gimple_call_set_fn (gimple gs, tree fn)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
gcc_gimple_checking_assert (!gimple_call_internal_p (gs));
|
||||
gimple_set_op (gs, 1, fn);
|
||||
}
|
||||
|
||||
|
@ -2063,16 +2096,29 @@ static inline void
|
|||
gimple_call_set_fndecl (gimple gs, tree decl)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
gcc_gimple_checking_assert (!gimple_call_internal_p (gs));
|
||||
gimple_set_op (gs, 1, build_fold_addr_expr_loc (gimple_location (gs), decl));
|
||||
}
|
||||
|
||||
|
||||
/* Set internal function FN to be the function called by call statement GS. */
|
||||
|
||||
static inline void
|
||||
gimple_call_set_internal_fn (gimple gs, enum internal_fn fn)
|
||||
{
|
||||
GIMPLE_CHECK (gs, GIMPLE_CALL);
|
||||
gcc_gimple_checking_assert (gimple_call_internal_p (gs));
|
||||
gs->gimple_call.u.internal_fn = fn;
|
||||
}
|
||||
|
||||
|
||||
/* Given a valid GIMPLE_CALL function address return the FUNCTION_DECL
|
||||
associated with the callee if known. Otherwise return NULL_TREE. */
|
||||
|
||||
static inline tree
|
||||
gimple_call_addr_fndecl (const_tree fn)
|
||||
{
|
||||
if (TREE_CODE (fn) == ADDR_EXPR)
|
||||
if (fn && TREE_CODE (fn) == ADDR_EXPR)
|
||||
{
|
||||
tree fndecl = TREE_OPERAND (fn, 0);
|
||||
if (TREE_CODE (fndecl) == MEM_REF
|
||||
|
@ -2103,6 +2149,9 @@ gimple_call_return_type (const_gimple gs)
|
|||
{
|
||||
tree type = gimple_call_fntype (gs);
|
||||
|
||||
if (type == NULL_TREE)
|
||||
return TREE_TYPE (gimple_call_lhs (gs));
|
||||
|
||||
/* The type returned by a function is the type of its
|
||||
function type. */
|
||||
return TREE_TYPE (type);
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/* Internal functions.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "internal-fn.h"
|
||||
#include "tree.h"
|
||||
#include "expr.h"
|
||||
#include "optabs.h"
|
||||
#include "gimple.h"
|
||||
|
||||
/* The names of each internal function, indexed by function number. */
|
||||
const char *const internal_fn_name_array[] = {
|
||||
#define DEF_INTERNAL_FN(CODE, FLAGS) #CODE,
|
||||
#include "internal-fn.def"
|
||||
#undef DEF_INTERNAL_FN
|
||||
"<invalid-fn>"
|
||||
};
|
||||
|
||||
/* The ECF_* flags of each internal function, indexed by function number. */
|
||||
const int internal_fn_flags_array[] = {
|
||||
#define DEF_INTERNAL_FN(CODE, FLAGS) FLAGS,
|
||||
#include "internal-fn.def"
|
||||
#undef DEF_INTERNAL_FN
|
||||
0
|
||||
};
|
||||
|
||||
/* Routines to expand each internal function, indexed by function number.
|
||||
Each routine has the prototype:
|
||||
|
||||
expand_<NAME> (gimple stmt)
|
||||
|
||||
where STMT is the statement that performs the call. */
|
||||
static void (*const internal_fn_expanders[]) (gimple) = {
|
||||
#define DEF_INTERNAL_FN(CODE, FLAGS) expand_##CODE,
|
||||
#include "internal-fn.def"
|
||||
#undef DEF_INTERNAL_FN
|
||||
0
|
||||
};
|
||||
|
||||
/* Expand STMT, which is a call to internal function FN. */
|
||||
|
||||
void
|
||||
expand_internal_call (gimple stmt)
|
||||
{
|
||||
internal_fn_expanders[(int) gimple_call_internal_fn (stmt)] (stmt);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* Internal functions.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This file specifies a list of internal "functions". These functions
|
||||
differ from built-in functions in that they have no linkage and cannot
|
||||
be called directly by the user. They represent operations that are only
|
||||
synthesised by GCC itself.
|
||||
|
||||
Internal functions are used instead of tree codes if the operation
|
||||
and its operands are more naturally represented as a GIMPLE_CALL
|
||||
than a GIMPLE_ASSIGN.
|
||||
|
||||
Each entry in this file has the form:
|
||||
|
||||
DEF_INTERNAL_FN (NAME, FLAGS)
|
||||
|
||||
where NAME is the name of the function and FLAGS is a set of
|
||||
ECF_* flags. Each entry must have a corresponding expander
|
||||
of the form:
|
||||
|
||||
void expand_NAME (gimple stmt)
|
||||
|
||||
where STMT is the statement that performs the call. */
|
|
@ -0,0 +1,51 @@
|
|||
/* Internal functions.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_INTERNAL_FN_H
|
||||
#define GCC_INTERNAL_FN_H
|
||||
|
||||
enum internal_fn {
|
||||
#define DEF_INTERNAL_FN(CODE, FLAGS) IFN_##CODE,
|
||||
#include "internal-fn.def"
|
||||
#undef DEF_INTERNAL_FN
|
||||
IFN_LAST
|
||||
};
|
||||
|
||||
/* Return the name of internal function FN. The name is only meaningful
|
||||
for dumps; it has no linkage. */
|
||||
|
||||
static inline const char *
|
||||
internal_fn_name (enum internal_fn fn)
|
||||
{
|
||||
extern const char *const internal_fn_name_array[];
|
||||
return internal_fn_name_array[(int) fn];
|
||||
}
|
||||
|
||||
/* Return the ECF_* flags for function FN. */
|
||||
|
||||
static inline int
|
||||
internal_fn_flags (enum internal_fn fn)
|
||||
{
|
||||
extern const int internal_fn_flags_array[];
|
||||
return internal_fn_flags_array[(int) fn];
|
||||
}
|
||||
|
||||
extern void expand_internal_call (gimple);
|
||||
|
||||
#endif
|
|
@ -1456,6 +1456,8 @@ ipa_analyze_call_uses (struct cgraph_node *node,
|
|||
{
|
||||
tree target = gimple_call_fn (call);
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
if (TREE_CODE (target) == SSA_NAME)
|
||||
ipa_analyze_indirect_call_uses (node, info, parms_info, call, target);
|
||||
else if (TREE_CODE (target) == OBJ_TYPE_REF)
|
||||
|
|
|
@ -1063,7 +1063,13 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
|
|||
}
|
||||
}
|
||||
if (is_gimple_call (stmt))
|
||||
gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in));
|
||||
{
|
||||
if (gimple_call_internal_p (stmt))
|
||||
gimple_call_set_internal_fn
|
||||
(stmt, (enum internal_fn) lto_input_sleb128 (ib));
|
||||
else
|
||||
gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in));
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_NOP:
|
||||
|
|
|
@ -1760,7 +1760,12 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
|
|||
lto_output_tree_ref (ob, op);
|
||||
}
|
||||
if (is_gimple_call (stmt))
|
||||
lto_output_tree_ref (ob, gimple_call_fntype (stmt));
|
||||
{
|
||||
if (gimple_call_internal_p (stmt))
|
||||
output_sleb128 (ob, (int) gimple_call_internal_fn (stmt));
|
||||
else
|
||||
lto_output_tree_ref (ob, gimple_call_fntype (stmt));
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMPLE_NOP:
|
||||
|
|
|
@ -3046,16 +3046,35 @@ verify_gimple_call (gimple stmt)
|
|||
tree fntype, fndecl;
|
||||
unsigned i;
|
||||
|
||||
if (!is_gimple_call_addr (fn))
|
||||
if (gimple_call_internal_p (stmt))
|
||||
{
|
||||
if (fn)
|
||||
{
|
||||
error ("gimple call has two targets");
|
||||
debug_generic_stmt (fn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fn)
|
||||
{
|
||||
error ("gimple call has no target");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fn && !is_gimple_call_addr (fn))
|
||||
{
|
||||
error ("invalid function in gimple call");
|
||||
debug_generic_stmt (fn);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (fn))
|
||||
|| (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE))
|
||||
if (fn
|
||||
&& (!POINTER_TYPE_P (TREE_TYPE (fn))
|
||||
|| (TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != FUNCTION_TYPE
|
||||
&& TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) != METHOD_TYPE)))
|
||||
{
|
||||
error ("non-function in gimple call");
|
||||
return true;
|
||||
|
@ -3087,7 +3106,8 @@ verify_gimple_call (gimple stmt)
|
|||
}
|
||||
|
||||
fntype = gimple_call_fntype (stmt);
|
||||
if (gimple_call_lhs (stmt)
|
||||
if (fntype
|
||||
&& gimple_call_lhs (stmt)
|
||||
&& !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)),
|
||||
TREE_TYPE (fntype))
|
||||
/* ??? At least C++ misses conversions at assignments from
|
||||
|
@ -7436,6 +7456,8 @@ do_warn_unused_result (gimple_seq seq)
|
|||
case GIMPLE_CALL:
|
||||
if (gimple_call_lhs (g))
|
||||
break;
|
||||
if (gimple_call_internal_p (g))
|
||||
break;
|
||||
|
||||
/* This is a naked call, as opposed to a GIMPLE_CALL with an
|
||||
LHS. All calls whose value is ignored should be
|
||||
|
|
|
@ -2743,7 +2743,7 @@ same_handler_p (gimple_seq oneh, gimple_seq twoh)
|
|||
|| gimple_call_lhs (twos)
|
||||
|| gimple_call_chain (ones)
|
||||
|| gimple_call_chain (twos)
|
||||
|| !operand_equal_p (gimple_call_fn (ones), gimple_call_fn (twos), 0)
|
||||
|| !gimple_call_same_target_p (ones, twos)
|
||||
|| gimple_call_num_args (ones) != gimple_call_num_args (twos))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1722,6 +1722,11 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Internal calls provide no argument types, so the extra laxity
|
||||
for normal calls does not apply. */
|
||||
if (gimple_call_internal_p (stmt))
|
||||
return false;
|
||||
|
||||
/* Propagate into the call arguments. Compared to replace_uses_in
|
||||
this can use the argument slot types for type verification
|
||||
instead of the current argument type. We also can safely
|
||||
|
|
|
@ -64,7 +64,7 @@ struct hashable_expr
|
|||
struct { enum tree_code op; tree opnd; } unary;
|
||||
struct { enum tree_code op; tree opnd0, opnd1; } binary;
|
||||
struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary;
|
||||
struct { tree fn; bool pure; size_t nargs; tree *args; } call;
|
||||
struct { gimple fn_from; bool pure; size_t nargs; tree *args; } call;
|
||||
} ops;
|
||||
};
|
||||
|
||||
|
@ -258,7 +258,7 @@ initialize_hash_element (gimple stmt, tree lhs,
|
|||
|
||||
expr->type = TREE_TYPE (gimple_call_lhs (stmt));
|
||||
expr->kind = EXPR_CALL;
|
||||
expr->ops.call.fn = gimple_call_fn (stmt);
|
||||
expr->ops.call.fn_from = stmt;
|
||||
|
||||
if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
|
||||
expr->ops.call.pure = true;
|
||||
|
@ -422,8 +422,8 @@ hashable_expr_equal_p (const struct hashable_expr *expr0,
|
|||
|
||||
/* If the calls are to different functions, then they
|
||||
clearly cannot be equal. */
|
||||
if (! operand_equal_p (expr0->ops.call.fn,
|
||||
expr1->ops.call.fn, 0))
|
||||
if (!gimple_call_same_target_p (expr0->ops.call.fn_from,
|
||||
expr1->ops.call.fn_from))
|
||||
return false;
|
||||
|
||||
if (! expr0->ops.call.pure)
|
||||
|
@ -503,9 +503,15 @@ iterative_hash_hashable_expr (const struct hashable_expr *expr, hashval_t val)
|
|||
{
|
||||
size_t i;
|
||||
enum tree_code code = CALL_EXPR;
|
||||
gimple fn_from;
|
||||
|
||||
val = iterative_hash_object (code, val);
|
||||
val = iterative_hash_expr (expr->ops.call.fn, val);
|
||||
fn_from = expr->ops.call.fn_from;
|
||||
if (gimple_call_internal_p (fn_from))
|
||||
val = iterative_hash_hashval_t
|
||||
((hashval_t) gimple_call_internal_fn (fn_from), val);
|
||||
else
|
||||
val = iterative_hash_expr (gimple_call_fn (fn_from), val);
|
||||
for (i = 0; i < expr->ops.call.nargs; i++)
|
||||
val = iterative_hash_expr (expr->ops.call.args[i], val);
|
||||
}
|
||||
|
@ -565,8 +571,14 @@ print_expr_hash_elt (FILE * stream, const struct expr_hash_elt *element)
|
|||
{
|
||||
size_t i;
|
||||
size_t nargs = element->expr.ops.call.nargs;
|
||||
gimple fn_from;
|
||||
|
||||
print_generic_expr (stream, element->expr.ops.call.fn, 0);
|
||||
fn_from = element->expr.ops.call.fn_from;
|
||||
if (gimple_call_internal_p (fn_from))
|
||||
fputs (internal_fn_name (gimple_call_internal_fn (fn_from)),
|
||||
stream);
|
||||
else
|
||||
print_generic_expr (stream, gimple_call_fn (fn_from), 0);
|
||||
fprintf (stream, " (");
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
|
|
|
@ -2657,11 +2657,13 @@ compute_antic (void)
|
|||
}
|
||||
|
||||
/* Return true if we can value number the call in STMT. This is true
|
||||
if we have a pure or constant call. */
|
||||
if we have a pure or constant call to a real function. */
|
||||
|
||||
static bool
|
||||
can_value_number_call (gimple stmt)
|
||||
{
|
||||
if (gimple_call_internal_p (stmt))
|
||||
return false;
|
||||
if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
|
||||
return true;
|
||||
return false;
|
||||
|
@ -4384,6 +4386,8 @@ eliminate (void)
|
|||
{
|
||||
tree orig_fn = gimple_call_fn (stmt);
|
||||
tree fn;
|
||||
if (!orig_fn)
|
||||
continue;
|
||||
if (TREE_CODE (orig_fn) == SSA_NAME)
|
||||
fn = VN_INFO (orig_fn)->valnum;
|
||||
else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF
|
||||
|
|
|
@ -3125,7 +3125,8 @@ visit_use (tree use)
|
|||
/* ??? We should handle stores from calls. */
|
||||
else if (TREE_CODE (lhs) == SSA_NAME)
|
||||
{
|
||||
if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
|
||||
if (!gimple_call_internal_p (stmt)
|
||||
&& gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
|
||||
changed = visit_reference_op_call (lhs, stmt);
|
||||
else
|
||||
changed = defs_to_varying (stmt);
|
||||
|
|
|
@ -4026,6 +4026,8 @@ get_fi_for_callee (gimple call)
|
|||
{
|
||||
tree decl;
|
||||
|
||||
gcc_assert (!gimple_call_internal_p (call));
|
||||
|
||||
/* If we can directly resolve the function being called, do so.
|
||||
Otherwise, it must be some sort of indirect expression that
|
||||
we should still be able to handle. */
|
||||
|
@ -4319,6 +4321,7 @@ find_func_aliases (gimple origt)
|
|||
/* Fallthru to general call handling. */;
|
||||
}
|
||||
if (!in_ipa_mode
|
||||
|| gimple_call_internal_p (t)
|
||||
|| (fndecl
|
||||
&& (!(fi = lookup_vi_for_tree (fndecl))
|
||||
|| !fi->is_fn_info)))
|
||||
|
|
|
@ -1258,6 +1258,9 @@ gimple_ic_transform (gimple stmt)
|
|||
if (gimple_call_fndecl (stmt) != NULL_TREE)
|
||||
return false;
|
||||
|
||||
if (gimple_call_internal_p (stmt))
|
||||
return false;
|
||||
|
||||
histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);
|
||||
if (!histogram)
|
||||
return false;
|
||||
|
@ -1649,6 +1652,7 @@ gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
|
|||
tree callee;
|
||||
|
||||
if (gimple_code (stmt) != GIMPLE_CALL
|
||||
|| gimple_call_internal_p (stmt)
|
||||
|| gimple_call_fndecl (stmt) != NULL_TREE)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Reference in New Issue