diff options
Diffstat (limited to 'gcc/gimple.h')
-rw-r--r-- | gcc/gimple.h | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/gcc/gimple.h b/gcc/gimple.h index 2f16c60538a..7a034a1f391 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -117,6 +117,14 @@ enum gf_mask { GF_PREDICT_TAKEN = 1 << 15 }; +/* Currently, there's only one type of gimple debug stmt. Others are + envisioned, for example, to enable the generation of is_stmt notes + in line number information, to mark sequence points, etc. This + subcode is to be used to tell them apart. */ +enum gimple_debug_subcode { + GIMPLE_DEBUG_BIND = 0 +}; + /* Masks for selecting a pass local flag (PLF) to work on. These masks are used by gimple_set_plf and gimple_plf. */ enum plf_mask { @@ -754,6 +762,10 @@ gimple gimple_build_assign_with_ops_stat (enum tree_code, tree, tree, #define gimple_build_assign_with_ops(c,o1,o2,o3) \ gimple_build_assign_with_ops_stat (c, o1, o2, o3 MEM_STAT_INFO) +gimple gimple_build_debug_bind_stat (tree, tree, gimple MEM_STAT_DECL); +#define gimple_build_debug_bind(var,val,stmt) \ + gimple_build_debug_bind_stat ((var), (val), (stmt) MEM_STAT_INFO) + gimple gimple_build_call_vec (tree, VEC(tree, heap) *); gimple gimple_build_call (tree, unsigned, ...); gimple gimple_build_call_from_tree (tree); @@ -3158,6 +3170,105 @@ gimple_switch_set_default_label (gimple gs, tree label) gimple_switch_set_label (gs, 0, label); } +/* Return true if GS is a GIMPLE_DEBUG statement. */ + +static inline bool +is_gimple_debug (const_gimple gs) +{ + return gimple_code (gs) == GIMPLE_DEBUG; +} + +/* Return true if S is a GIMPLE_DEBUG BIND statement. */ + +static inline bool +gimple_debug_bind_p (const_gimple s) +{ + if (is_gimple_debug (s)) + return s->gsbase.subcode == GIMPLE_DEBUG_BIND; + + return false; +} + +/* Return the variable bound in a GIMPLE_DEBUG bind statement. */ + +static inline tree +gimple_debug_bind_get_var (gimple dbg) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + return gimple_op (dbg, 0); +} + +/* Return the value bound to the variable in a GIMPLE_DEBUG bind + statement. */ + +static inline tree +gimple_debug_bind_get_value (gimple dbg) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + return gimple_op (dbg, 1); +} + +/* Return a pointer to the value bound to the variable in a + GIMPLE_DEBUG bind statement. */ + +static inline tree * +gimple_debug_bind_get_value_ptr (gimple dbg) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + return gimple_op_ptr (dbg, 1); +} + +/* Set the variable bound in a GIMPLE_DEBUG bind statement. */ + +static inline void +gimple_debug_bind_set_var (gimple dbg, tree var) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + gimple_set_op (dbg, 0, var); +} + +/* Set the value bound to the variable in a GIMPLE_DEBUG bind + statement. */ + +static inline void +gimple_debug_bind_set_value (gimple dbg, tree value) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + gimple_set_op (dbg, 1, value); +} + +/* The second operand of a GIMPLE_DEBUG_BIND, when the value was + optimized away. */ +#define GIMPLE_DEBUG_BIND_NOVALUE NULL_TREE /* error_mark_node */ + +/* Remove the value bound to the variable in a GIMPLE_DEBUG bind + statement. */ + +static inline void +gimple_debug_bind_reset_value (gimple dbg) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + gimple_set_op (dbg, 1, GIMPLE_DEBUG_BIND_NOVALUE); +} + +/* Return true if the GIMPLE_DEBUG bind statement is bound to a + value. */ + +static inline bool +gimple_debug_bind_has_value_p (gimple dbg) +{ + GIMPLE_CHECK (dbg, GIMPLE_DEBUG); + gcc_assert (gimple_debug_bind_p (dbg)); + return gimple_op (dbg, 1) != GIMPLE_DEBUG_BIND_NOVALUE; +} + +#undef GIMPLE_DEBUG_BIND_NOVALUE /* Return the body for the OMP statement GS. */ @@ -4308,6 +4419,58 @@ gsi_after_labels (basic_block bb) return gsi; } +/* Advance the iterator to the next non-debug gimple statement. */ + +static inline void +gsi_next_nondebug (gimple_stmt_iterator *i) +{ + do + { + gsi_next (i); + } + while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i))); +} + +/* Advance the iterator to the next non-debug gimple statement. */ + +static inline void +gsi_prev_nondebug (gimple_stmt_iterator *i) +{ + do + { + gsi_prev (i); + } + while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i))); +} + +/* Return a new iterator pointing to the first non-debug statement in + basic block BB. */ + +static inline gimple_stmt_iterator +gsi_start_nondebug_bb (basic_block bb) +{ + gimple_stmt_iterator i = gsi_start_bb (bb); + + if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i))) + gsi_next_nondebug (&i); + + return i; +} + +/* Return a new iterator pointing to the last non-debug statement in + basic block BB. */ + +static inline gimple_stmt_iterator +gsi_last_nondebug_bb (basic_block bb) +{ + gimple_stmt_iterator i = gsi_last_bb (bb); + + if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i))) + gsi_prev_nondebug (&i); + + return i; +} + /* Return a pointer to the current stmt. NOTE: You may want to use gsi_replace on the iterator itself, |