summaryrefslogtreecommitdiff
path: root/gcc/gimple.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gimple.h')
-rw-r--r--gcc/gimple.h163
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,