On Fri, Nov 15, 2013 at 3:12 PM, Ilya Enkovich <enkovich....@gmail.com> wrote: > 2013/11/15 Richard Biener <richard.guent...@gmail.com>: >> On Fri, Nov 15, 2013 at 2:19 PM, Ilya Enkovich <enkovich....@gmail.com> >> wrote: >>> Hi, >>> >>> Here is a patch to introduce builtin to bind bounds for call arguments as >>> was discussed here >>> (http://gcc.gnu.org/ml/gcc-patches/2013-11/msg00872.html). Patch also >>> removes outdated gimple ifaces. >> >> Looks good to me in principle but "instrumented" sounds a bit generic, can >> you >> rename it to "with_bounds" in both the gimple and the rtl flag? > > Sure. Will do. > >> Also on RTL it's CALL_INSN, not CALL_EXPR, and the flag is already >> taken to mark sibling calls there (there doesn't seem to be a flag left >> for CALL_INSNs). > > Each call_insn has call expression inside. I use flags for CALL expr > because there are no free flags for CALL_INSN.
Awww, nobody changed that to point to a GIMPLE_CALL? ;) Anyway, that works of course. Richard. > Ilya >> >> Thanks, >> Richard. >> >>> Thanks, >>> Ilya >>> -- >>> 2013-11-15 Ilya Enkovich <ilya.enkov...@intel.com> >>> >>> * builtin-types.def (BT_FN_PTR_CONST_PTR_VAR): New. >>> * chkp-builtins.def (BUILT_IN_CHKP_BIND_BOUNDS): New. >>> * cfgexpand.c (expand_call_stmt): Expand BUILT_IN_CHKP_BIND_BOUNDS. >>> * gimple.c (gimple_call_get_nobnd_arg_index): Remove. >>> * gimple.h (gf_mask): Add GF_CALL_INSTRUMENTED. >>> (gimple_call_instrumented_p): New. >>> (gimple_call_set_instrumented): New. >>> (gimple_call_num_nobnd_args): Remove. >>> (gimple_call_nobnd_arg): Remove. >>> * tree.h (CALL_INSTRUMENTED_P): New. >>> * rtl.h (CALL_EXPR_INSTRUMENTED_P): New. >>> >>> >>> diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def >>> index 1f9ae4e..e7bfaf9 100644 >>> --- a/gcc/builtin-types.def >>> +++ b/gcc/builtin-types.def >>> @@ -542,6 +542,8 @@ DEF_FUNCTION_TYPE_VAR_1 (BT_FN_INT_CONST_STRING_VAR, >>> BT_INT, BT_CONST_STRING) >>> DEF_FUNCTION_TYPE_VAR_1 (BT_FN_UINT32_UINT32_VAR, >>> BT_UINT32, BT_UINT32) >>> +DEF_FUNCTION_TYPE_VAR_1 (BT_FN_PTR_CONST_PTR_VAR, >>> + BT_PTR, BT_CONST_PTR) >>> >>> DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_FILEPTR_CONST_STRING_VAR, >>> BT_INT, BT_FILEPTR, BT_CONST_STRING) >>> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c >>> index 9705036..8a738d4 100644 >>> --- a/gcc/cfgexpand.c >>> +++ b/gcc/cfgexpand.c >>> @@ -2121,12 +2121,22 @@ expand_call_stmt (gimple stmt) >>> return; >>> } >>> >>> - exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); >>> - >>> - CALL_EXPR_FN (exp) = gimple_call_fn (stmt); >>> decl = gimple_call_fndecl (stmt); >>> builtin_p = decl && DECL_BUILT_IN (decl); >>> >>> + /* Bind bounds call is expanded as assignment. */ >>> + if (builtin_p >>> + && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL >>> + && DECL_FUNCTION_CODE (decl) == BUILT_IN_CHKP_BIND_BOUNDS) >>> + { >>> + expand_assignment (gimple_call_lhs (stmt), >>> + gimple_call_arg (stmt, 0), false); >>> + return; >>> + } >>> + >>> + exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3); >>> + CALL_EXPR_FN (exp) = gimple_call_fn (stmt); >>> + >>> /* If this is not a builtin function, the function type through which the >>> call is made may be different from the type of the function. */ >>> if (!builtin_p) >>> diff --git a/gcc/chkp-builtins.def b/gcc/chkp-builtins.def >>> index d19b541..b920950 100644 >>> --- a/gcc/chkp-builtins.def >>> +++ b/gcc/chkp-builtins.def >>> @@ -42,6 +42,9 @@ DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_LOWER, >>> "__chkp_extract_lower") >>> DEF_BUILTIN_STUB (BUILT_IN_CHKP_EXTRACT_UPPER, "__chkp_extract_upper") >>> DEF_BUILTIN_STUB (BUILT_IN_CHKP_NARROW, "__chkp_narrow") >>> >>> +/* Builtins to bind bounds to call arguments. */ >>> +DEF_CHKP_BUILTIN (BUILT_IN_CHKP_BIND_BOUNDS, "__chkp_bind_bounds", >>> BT_FN_PTR_CONST_PTR_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) >>> + >>> /* Pointer Bounds Checker builtins for users. Only >>> BUILT_IN_CHKP_SET_PTR_BOUNDS may be redefined >>> by target. Other builtins calls are expanded >>> diff --git a/gcc/gimple.c b/gcc/gimple.c >>> index 20f6010..72c10c0 100644 >>> --- a/gcc/gimple.c >>> +++ b/gcc/gimple.c >>> @@ -366,26 +366,6 @@ gimple_build_call_from_tree (tree t) >>> } >>> >>> >>> -/* Return index of INDEX's non bound argument of the call. */ >>> - >>> -unsigned >>> -gimple_call_get_nobnd_arg_index (const_gimple gs, unsigned index) >>> -{ >>> - unsigned num_args = gimple_call_num_args (gs); >>> - for (unsigned n = 0; n < num_args; n++) >>> - { >>> - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) >>> - continue; >>> - else if (index) >>> - index--; >>> - else >>> - return n; >>> - } >>> - >>> - gcc_unreachable (); >>> -} >>> - >>> - >>> /* Extract the operands and code for expression EXPR into *SUBCODE_P, >>> *OP1_P, *OP2_P and *OP3_P respectively. */ >>> >>> diff --git a/gcc/gimple.h b/gcc/gimple.h >>> index c7ce394..95d6589 100644 >>> --- a/gcc/gimple.h >>> +++ b/gcc/gimple.h >>> @@ -101,6 +101,7 @@ enum gf_mask { >>> GF_CALL_NOTHROW = 1 << 4, >>> GF_CALL_ALLOCA_FOR_VAR = 1 << 5, >>> GF_CALL_INTERNAL = 1 << 6, >>> + GF_CALL_INSTRUMENTED = 1 << 7, >>> GF_OMP_PARALLEL_COMBINED = 1 << 0, >>> GF_OMP_FOR_KIND_MASK = 3 << 0, >>> GF_OMP_FOR_KIND_FOR = 0 << 0, >>> @@ -919,7 +920,6 @@ extern tree get_initialized_tmp_var (tree, gimple_seq >>> *, gimple_seq *); >>> extern tree get_formal_tmp_var (tree, gimple_seq *); >>> extern void declare_vars (tree, gimple, bool); >>> extern void annotate_all_with_location (gimple_seq, location_t); >>> -extern unsigned gimple_call_get_nobnd_arg_index (const_gimple, unsigned); >>> >>> /* Validation of GIMPLE expressions. Note that these predicates only check >>> the basic form of the expression, they don't recurse to make sure that >>> @@ -2231,6 +2231,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_instrumented_p (const_gimple gs) >>> +{ >>> + GIMPLE_CHECK (gs, GIMPLE_CALL); >>> + return (gs->gsbase.subcode & GF_CALL_INSTRUMENTED) != 0; >>> +} >>> + >>> + >>> +/* If INSTRUMENTED_P is true, marm statement GS as instrumented by >>> + Pointer Bounds Checker. */ >>> + >>> +static inline void >>> +gimple_call_set_instrumented (gimple gs, bool instrumented_p) >>> +{ >>> + GIMPLE_CHECK (gs, GIMPLE_CALL); >>> + if (instrumented_p) >>> + gs->gsbase.subcode |= GF_CALL_INSTRUMENTED; >>> + else >>> + gs->gsbase.subcode &= ~GF_CALL_INSTRUMENTED; >>> +} >>> + >>> + >>> /* Return the target of internal call GS. */ >>> >>> static inline enum internal_fn >>> @@ -2415,32 +2440,6 @@ gimple_call_arg (const_gimple gs, unsigned index) >>> } >>> >>> >>> -/* Return the number of arguments used by call statement GS >>> - ignoring bound ones. */ >>> - >>> -static inline unsigned >>> -gimple_call_num_nobnd_args (const_gimple gs) >>> -{ >>> - unsigned num_args = gimple_call_num_args (gs); >>> - unsigned res = num_args; >>> - for (unsigned n = 0; n < num_args; n++) >>> - if (POINTER_BOUNDS_P (gimple_call_arg (gs, n))) >>> - res--; >>> - return res; >>> -} >>> - >>> - >>> -/* Return INDEX's call argument ignoring bound ones. */ >>> -static inline tree >>> -gimple_call_nobnd_arg (const_gimple gs, unsigned index) >>> -{ >>> - /* No bound args may exist if pointers checker is off. */ >>> - if (!flag_check_pointer_bounds) >>> - return gimple_call_arg (gs, index); >>> - return gimple_call_arg (gs, gimple_call_get_nobnd_arg_index (gs, index)); >>> -} >>> - >>> - >>> /* Return a pointer to the argument at position INDEX for call >>> statement GS. */ >>> >>> diff --git a/gcc/rtl.h b/gcc/rtl.h >>> index 247a0d0..5254411 100644 >>> --- a/gcc/rtl.h >>> +++ b/gcc/rtl.h >>> @@ -266,7 +266,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 CALL for instrumented calls. */ >>> unsigned int jump : 1; >>> /* In a CODE_LABEL, part of the two-bit alternate entry field. >>> 1 in a MEM if it cannot trap. >>> @@ -1420,6 +1421,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_INSTRUMENTED_P(RTX) \ >>> + (RTL_FLAG_CHECK1 ("CALL_INSTRUMENTED_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 3fe751e..5aaea5b 100644 >>> --- a/gcc/tree.h >>> +++ b/gcc/tree.h >>> @@ -828,6 +828,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_INSTRUMENTED_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