2014-04-16 17:11 GMT+04:00 Ilya Enkovich <enkovich....@gmail.com>: > Hi, > > This patch adds flags and ifaces to mark instrumented calls, extends return > stms with additional operand and introduces some basic bounds predicates. > These changes were previously reverted from 4.9 and I'll assume patch is OK > for trunk if no objections arise. > > Patch was bootstrapped and tested for linux-x86_64. > > Thanks, > Ilya > -- > gcc/ > > 2014-04-16 Ilya Enkovich <ilya.enkov...@intel.com> > > * gimple.h (gf_mask): Add GF_CALL_WITH_BOUNDS. > (gimple_call_with_bounds_p): New. > (gimple_call_set_with_bounds): New. > (gimple_return_retbnd): New. > (gimple_return_set_retbnd): New > * rtl.h (CALL_EXPR_WITH_BOUNDS_P): New. > * tree.h (POINTER_BOUNDS_P): New. > (BOUNDED_TYPE_P): New. > (BOUNDED_P): New. > (CALL_WITH_BOUNDS_P): New. > * gimple.c (gimple_build_return): Increase number of ops > for return statement. > (gimple_build_call_from_tree): Propagate CALL_WITH_BOUNDS_P > flag. > * gimple-pretty-print.c (dump_gimple_return): Print second op. > > > diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c > index 741cd92..a792bb9 100644 > --- a/gcc/gimple-pretty-print.c > +++ b/gcc/gimple-pretty-print.c > @@ -547,11 +547,12 @@ dump_gimple_assign (pretty_printer *buffer, gimple gs, > int spc, int flags) > static void > dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags) > { > - tree t; > + tree t, t2; > > t = gimple_return_retval (gs); > + t2 = gimple_return_retbnd (gs); > if (flags & TDF_RAW) > - dump_gimple_fmt (buffer, spc, flags, "%G <%T>", gs, t); > + dump_gimple_fmt (buffer, spc, flags, "%G <%T %T>", gs, t, t2); > else > { > pp_string (buffer, "return"); > @@ -560,6 +561,11 @@ dump_gimple_return (pretty_printer *buffer, gimple gs, > int spc, int flags) > pp_space (buffer); > dump_generic_node (buffer, t, spc, flags, false); > } > + if (t2) > + { > + pp_string (buffer, ", "); > + dump_generic_node (buffer, t2, spc, flags, false); > + } > pp_semicolon (buffer); > } > } > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 2a278e4..89f9b4c 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -180,7 +180,7 @@ gimple_build_with_ops_stat (enum gimple_code code, > unsigned subcode, > gimple > gimple_build_return (tree retval) > { > - gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 1); > + gimple s = gimple_build_with_ops (GIMPLE_RETURN, ERROR_MARK, 2); > if (retval) > gimple_return_set_retval (s, retval); > return s; > @@ -367,6 +367,7 @@ gimple_build_call_from_tree (tree t) > gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); > gimple_call_set_nothrow (call, TREE_NOTHROW (t)); > gimple_set_no_warning (call, TREE_NO_WARNING (t)); > + gimple_call_set_with_bounds (call, CALL_WITH_BOUNDS_P (t)); > > return call; > } > diff --git a/gcc/gimple.h b/gcc/gimple.h > index 11959a8..8b8693c 100644 > --- a/gcc/gimple.h > +++ b/gcc/gimple.h > @@ -90,6 +90,7 @@ enum gf_mask { > GF_CALL_NOTHROW = 1 << 4, > GF_CALL_ALLOCA_FOR_VAR = 1 << 5, > GF_CALL_INTERNAL = 1 << 6, > + GF_CALL_WITH_BOUNDS = 1 << 7, > GF_OMP_PARALLEL_COMBINED = 1 << 0, > GF_OMP_FOR_KIND_MASK = 3 << 0, > GF_OMP_FOR_KIND_FOR = 0 << 0, > @@ -2438,6 +2439,31 @@ gimple_call_internal_p (const_gimple gs) > } > > > +/* Return true if call GS is marked as instrumented by > + Pointer Bounds Checker. */ > + > +static inline bool > +gimple_call_with_bounds_p (const_gimple gs) > +{ > + GIMPLE_CHECK (gs, GIMPLE_CALL); > + return (gs->subcode & GF_CALL_WITH_BOUNDS) != 0; > +} > + > + > +/* If INSTRUMENTED_P is true, marm statement GS as instrumented by > + Pointer Bounds Checker. */ > + > +static inline void > +gimple_call_set_with_bounds (gimple gs, bool with_bounds) > +{ > + GIMPLE_CHECK (gs, GIMPLE_CALL); > + if (with_bounds) > + gs->subcode |= GF_CALL_WITH_BOUNDS; > + else > + gs->subcode &= ~GF_CALL_WITH_BOUNDS; > +} > + > + > /* Return the target of internal call GS. */ > > static inline enum internal_fn > @@ -5517,6 +5543,26 @@ gimple_return_set_retval (gimple gs, tree retval) > } > > > +/* Return the return bounds for GIMPLE_RETURN GS. */ > + > +static inline tree > +gimple_return_retbnd (const_gimple gs) > +{ > + GIMPLE_CHECK (gs, GIMPLE_RETURN); > + return gimple_op (gs, 1); > +} > + > + > +/* Set RETVAL to be the return bounds for GIMPLE_RETURN GS. */ > + > +static inline void > +gimple_return_set_retbnd (gimple gs, tree retval) > +{ > + GIMPLE_CHECK (gs, GIMPLE_RETURN); > + gimple_set_op (gs, 1, retval); > +} > + > + > /* Returns true when the gimple statement STMT is any of the OpenMP types. > */ > > #define CASE_GIMPLE_OMP \ > diff --git a/gcc/rtl.h b/gcc/rtl.h > index f1cda4c..54d1cf1 100644 > --- a/gcc/rtl.h > +++ b/gcc/rtl.h > @@ -265,7 +265,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), > In a CODE_LABEL, part of the two-bit alternate entry field. > 1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c. > 1 in a VALUE is SP_BASED_VALUE_P in cselib.c. > - 1 in a SUBREG generated by LRA for reload insns. */ > + 1 in a SUBREG generated by LRA for reload insns. > + 1 in a CALL for calls instrumented by Pointer Bounds Checker. */ > unsigned int jump : 1; > /* In a CODE_LABEL, part of the two-bit alternate entry field. > 1 in a MEM if it cannot trap. > @@ -1419,6 +1420,10 @@ do { > \ > #define LRA_SUBREG_P(RTX) \ > (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump) > > +/* True if call is instrumented by Pointer Bounds Checker. */ > +#define CALL_EXPR_WITH_BOUNDS_P(RTX) \ > + (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump) > + > /* Access various components of an ASM_OPERANDS rtx. */ > > #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS) > diff --git a/gcc/tree.h b/gcc/tree.h > index 801d564..f783701 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -552,6 +552,17 @@ extern void omp_clause_range_check_failed (const_tree, > const char *, int, > #define POINTER_BOUNDS_TYPE_P(NODE) \ > (TREE_CODE (NODE) == POINTER_BOUNDS_TYPE) > > +/* Nonzero if this node has a pointer bounds type. */ > +#define POINTER_BOUNDS_P(NODE) \ > + (POINTER_BOUNDS_TYPE_P (TREE_TYPE (NODE))) > + > +/* Nonzero if this type supposes bounds existence. */ > +#define BOUNDED_TYPE_P(type) (POINTER_TYPE_P (type)) > + > +/* Nonzero for objects with bounded type. */ > +#define BOUNDED_P(node) \ > + BOUNDED_TYPE_P (TREE_TYPE (node)) > + > /* Nonzero if this type is the (possibly qualified) void type. */ > #define VOID_TYPE_P(NODE) (TREE_CODE (NODE) == VOID_TYPE) > > @@ -825,6 +836,9 @@ extern void omp_clause_range_check_failed (const_tree, > const char *, int, > #define CALL_ALLOCA_FOR_VAR_P(NODE) \ > (CALL_EXPR_CHECK (NODE)->base.protected_flag) > > +/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */ > +#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK > (NODE)->base.deprecated_flag) > + > /* In a type, nonzero means that all objects of the type are guaranteed by > the > language or front-end to be properly aligned, so we can indicate that a > MEM > of this type is aligned at least to the alignment of the type, even if it
Will install it in a couple of days. Ilya