On Sat, Feb 1, 2020 at 1:04 AM Uecker, Martin
<[email protected]> wrote:
>
>
>
> Hi Richard and Joseph,
>
> for discussion: here is my simple patch
> for __builtin_escape/__builtin_bless.
>
> Maybe it does something stupid.
I'd use an internal function once the frontend inserts the calls,
we shouldn't expose those to the user.
I expect the builtins to show as quite invasive with their
data dependence blocking many optimizations. Any reason
that __builtin_escape is not marked as const? Do you try
to prevent code motion of it so flow-sensitive "escape" analysis
can be used? But nothing prevents hoisting of the bless call
across the escape one.
Richard.
>
> Best,
> Martin
>
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index e4a8694054e..d0046135213 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -6014,6 +6014,31 @@ expand_builtin_unreachable (void)
> emit_barrier ();
> }
>
> +
> +static rtx
> +expand_builtin_escape (tree exp, rtx target)
> +{
> + if (call_expr_nargs (exp) < 1)
> + return const0_rtx;
> +
> + target = expand_expr (CALL_EXPR_ARG (exp, 0), target, Pmode,
> + EXPAND_NORMAL);
> +
> + return target;
> +}
> +
> +static rtx
> +expand_builtin_bless (tree exp, rtx target)
> +{
> + if (call_expr_nargs (exp) < 1)
> + return const0_rtx;
> +
> + target = expand_expr (CALL_EXPR_ARG (exp, 0), target, Pmode,
> + EXPAND_NORMAL);
> +
> + return target;
> +}
> +
> /* Expand EXP, a call to fabs, fabsf or fabsl.
> Return NULL_RTX if a normal call should be emitted rather than expanding
> the function inline. If convenient, the result should be placed
> @@ -8304,6 +8329,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget,
> machine_mode mode,
> expand_builtin_unreachable ();
> return const0_rtx;
>
> + case BUILT_IN_ESCAPE:
> + return expand_builtin_escape (exp, target);
> +
> + case BUILT_IN_BLESS:
> + return expand_builtin_bless (exp, target);
> +
> CASE_FLT_FN (BUILT_IN_SIGNBIT):
> case BUILT_IN_SIGNBITD32:
> case BUILT_IN_SIGNBITD64:
> diff --git a/gcc/builtins.def b/gcc/builtins.def
> index fa8b0641ab1..9264a0fdaab 100644
> --- a/gcc/builtins.def
> +++ b/gcc/builtins.def
> @@ -865,6 +865,8 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp",
> BT_FN_INT_CONST_STRING_PT
> DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve",
> BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST)
> DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT,
> ATTR_NORETURN_NOTHROW_LIST)
> DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG,
> ATTR_CONST_NOTHROW_LEAF_LIST)
> +DEF_GCC_BUILTIN (BUILT_IN_ESCAPE, "escape", BT_FN_PTR_PTR,
> ATTR_NOTHROW_LEAF_LIST)
> +DEF_GCC_BUILTIN (BUILT_IN_BLESS, "bless", BT_FN_PTR_PTR,
> ATTR_CONST_NOTHROW_LEAF_LIST)
> DEF_GCC_BUILTIN (BUILT_IN_EXPECT_WITH_PROBABILITY,
> "expect_with_probability", BT_FN_LONG_LONG_LONG_DOUBLE,
> ATTR_CONST_NOTHROW_LEAF_LIST)
> DEF_GCC_BUILTIN (BUILT_IN_ASSUME_ALIGNED, "assume_aligned",
> BT_FN_PTR_CONST_PTR_SIZE_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
> DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer",
> BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LEAF_LIST)
> diff --git a/gcc/testsuite/gcc.dg/alias-17.c b/gcc/testsuite/gcc.dg/alias-17.c
> new file mode 100644
> index 00000000000..c375e4027ca
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/alias-17.c
> @@ -0,0 +1,29 @@
> +/* { dg-do run } */
> +/* { dg-options "-O1" } */
> +
> +
> +static
> +int test(int a, int b, int c)
> +{
> + int x, y;
> + int d = (&x < &y) ? 1 : -1;
> + if (a) __builtin_escape(&y);
> + y = 0; //!
> + int *q = &x;
> + q += d;
> + int *r = q;
> + if (b) r = __builtin_bless(q);
> + *(c ? r : q) = 1;
> + return y;
> +}
> +
> +int main()
> +{
> + if (0 != test(0, 0, 1)) __builtin_abort();
> + if (0 != test(0, 1, 0)) __builtin_abort();
> + if (0 != test(0, 1, 1)) __builtin_abort();
> + if (0 != test(1, 0, 1)) __builtin_abort();
> +// if (0 != test(1, 1, 0)) __builtin_abort();
> + if (0 == test(1, 1, 1)) __builtin_abort();
> + return 0;
> +}
> diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
> index 670676f20c3..d5befff71a6 100644
> --- a/gcc/tree-ssa-alias.c
> +++ b/gcc/tree-ssa-alias.c
> @@ -2462,6 +2462,8 @@ ref_maybe_used_by_call_p_1 (gcall *call, ao_ref *ref,
> bool tbaa_p)
> }
>
> /* The following builtins do not read from memory. */
> + case BUILT_IN_ESCAPE:
> + case BUILT_IN_BLESS:
> case BUILT_IN_FREE:
> case BUILT_IN_MALLOC:
> case BUILT_IN_POSIX_MEMALIGN:
> diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
> index be6647db894..53a38a04ebb 100644
> --- a/gcc/tree-ssa-ccp.c
> +++ b/gcc/tree-ssa-ccp.c
> @@ -1963,6 +1963,8 @@ evaluate_stmt (gimple *stmt)
> break;
>
> /* These builtins return their first argument, unmodified. */
> + case BUILT_IN_ESCAPE:
> + case BUILT_IN_BLESS:
> case BUILT_IN_MEMCPY:
> case BUILT_IN_MEMMOVE:
> case BUILT_IN_MEMSET:
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index 416a26c996c..003349c7278 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -4381,6 +4381,24 @@ find_func_aliases_for_builtin_call (struct function
> *fn, gcall *t)
> in the alias-oracle query functions explicitly! */
> switch (DECL_FUNCTION_CODE (fndecl))
> {
> + case BUILT_IN_ESCAPE:
> + {
> + make_escape_constraint (gimple_call_arg (t, 0));
> + return true;
> + }
> + case BUILT_IN_BLESS:
> + {
> + tree lhs = gimple_call_lhs (t);
> + struct constraint_expr rhsc, *lhsp;
> + unsigned j;
> + get_constraint_for (lhs, &lhsc);
> + rhsc.var = nonlocal_id;
> + rhsc.offset = 0;
> + rhsc.type = SCALAR;
> + FOR_EACH_VEC_ELT (lhsc, j, lhsp)
> + process_constraint (new_constraint (*lhsp, rhsc));
> + return true;
> + }
> /* All the following functions return a pointer to the same object
> as their first argument points to. The functions do not add
> to the ESCAPED solution. The functions make the first argument
> @@ -5257,6 +5275,7 @@ find_func_clobbers (struct function *fn, gimple *origt)
> if (gimple_call_builtin_p (t, BUILT_IN_NORMAL))
> switch (DECL_FUNCTION_CODE (decl))
> {
> +
> /* The following functions use and clobber memory pointed to
> by their arguments. */
> case BUILT_IN_STRCPY:
> @@ -5349,6 +5368,9 @@ find_func_clobbers (struct function *fn, gimple *origt)
> case BUILT_IN_ASSUME_ALIGNED:
> case BUILT_IN_FREE:
> return;
> + case BUILT_IN_ESCAPE:
> + case BUILT_IN_BLESS:
> + return;
> /* Trampolines are of no interest to us. */
> case BUILT_IN_INIT_TRAMPOLINE:
> case BUILT_IN_ADJUST_TRAMPOLINE: