Re: [RFC PATCH] __builtin_escape/__builtin_bless

2020-02-04 Thread Uecker, Martin


Am Dienstag, den 04.02.2020, 15:01 +0100 schrieb Richard Biener:
> On Sat, Feb 1, 2020 at 1:04 AM Uecker, Martin
>  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.

Ok. I thought it might be useful for testing...

> I expect the builtins to show as quite invasive with their
> data dependence blocking many optimizations. 

Yes, I wondering about the impact of this on
optimization and whether this could be made
more light-weight somehow.

Do you think it is worth investigating
the use of some other kind of marker?

> Any reason that __builtin_escape is not marked as const? 

Conceptually, letting something escape (or marking
it "exposed" according to the formal semantics
in the PVNI proposal) is a side-effect.

Practically, if I mark it constant, I think the
problem was that it was getting optimized away
completely.

> Do you try to prevent code motion of it so flow-sensitive 
> "escape" analysis can be used? 

If I don't miss something important, there is 
no  flow-sensitive analysis done in GCC.

> But nothing prevents hoisting of the bless call
> across the escape one.

With flow-sensitive analysis, this would be
incorrect.

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 000..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)) __built

Re: [RFC PATCH] __builtin_escape/__builtin_bless

2020-02-04 Thread Richard Biener
On Sat, Feb 1, 2020 at 1:04 AM Uecker, Martin
 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 000..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 built

[RFC PATCH] __builtin_escape/__builtin_bless

2020-01-31 Thread Uecker, Martin


Hi Richard and Joseph,

for discussion: here is my simple patch
for __builtin_escape/__builtin_bless.

Maybe it does something stupid. 


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 000..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:
+   {
+