diff options
Diffstat (limited to 'gcc/gimple.h')
-rw-r--r-- | gcc/gimple.h | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/gcc/gimple.h b/gcc/gimple.h index 322ce99..a5374a9 100644 --- a/gcc/gimple.h +++ b/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); |