Re: About GSOC.

2019-06-03 Thread Tejas Joshi
Hello.
I have already sent a patch for roundeven implementation but I do not
know how do I commit my changes to GCC. Am I supposed to create a
branch or anything etc?
Also I have been trying to do folding for constant arguments and
inspecting for only func (func (x)) -> func (x) right now. I made some
changes to make this work including like :
+(for fns (TRUNC_ALL FLOOR_ALL CEIL_ALL ROUND_ALL ROUNDEVEN_ALL
NEARBYINT_ALL RINT_ALL)

Also, BUILT_IN_ROUNDEVEN instead of ROUNDEVEN_ALL is not working here.
Other changes regarding to this after inspecting round are included in
this patch, but this seems not working and I am surely missing
something. Do I need to include roundeven like round:

DEFINE_INT_AND_FLOAT_ROUND_FN (ROUND)

but this would require defining IROUNDEVEN in builtins.def but it is
not supposed to?

Thanks,
--Tejas

On Fri, 31 May 2019 at 19:00, Eric Gallager  wrote:
>
> On 5/31/19, Nathan Sidwell  wrote:
> > On 5/30/19 5:38 PM, Segher Boessenkool wrote:
> >> On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote:
> >>> Interesting, I was also puzzled for a moment.  But notice that:
> >>>
> >>> int main ()
> >>> {
> >>>  _Float128 x = 18446744073709551617.5f128;
> >>>  _Float128 y = __builtin_roundf128 (x);
> >>> }
> >>>
> >>> behaves as expected... the difference is of course the suffix pegged to
> >>> the literal constant (see
> >>> https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html).
> >>>
> >>> I would also expect GCC to use a larger type if a constant does not fit
> >>> into a double, but apparently that does not happen.  I would have to
> >>> check but it is probably the right behavior according to the standard.
> >>
> >> 6.4.4.2/4: "An unsuffixed floating constant has type double."  I don't
> >> think your suggestion would be okay?
> >
> > Not only that, but
> >
> > 1) there isn't a literal suffix to mean 'double', so one couldn't
> > override that extended type.
>
> There's not a standard one, but there is 'D' or 'd' as a GNU
> extension. The fact that it's nonstandard, though, is what causes some
> projects to ignore -Wunsuffixed-float-constants:
> https://lists.gnu.org/archive/html/bug-gzip/2011-11/msg00017.html
>
> > 2) how do you define 'doesn't fit'?  decimal 0.1 has a recurring binary
> > representation.  Should that become the longest floating point type?
> >
> > nathan
> >
> > --
> > Nathan Sidwell
> >
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 25e01e4092b..0b2d6bf82f9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -2067,6 +2067,7 @@ mathfn_built_in_2 (tree type, combined_fn fn)
 CASE_MATHFN (REMQUO)
 CASE_MATHFN_FLOATN (RINT)
 CASE_MATHFN_FLOATN (ROUND)
+CASE_MATHFN (ROUNDEVEN)
 CASE_MATHFN (SCALB)
 CASE_MATHFN (SCALBLN)
 CASE_MATHFN (SCALBN)
diff --git a/gcc/builtins.def b/gcc/builtins.def
index ef89729fd0c..f284a3eae3b 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -542,12 +542,18 @@ DEF_C99_BUILTIN(BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, AT
 #define RINT_TYPE(F) BT_FN_##F##_##F
 DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_RINT, "rint", RINT_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef RINT_TYPE
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVEN, "roundeven", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENF, "roundevenf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENL, "roundevenl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_C99_BUILTIN(BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #define ROUND_TYPE(F) BT_FN_##F##_##F
 DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUND, "round", ROUND_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
 #undef ROUND_TYPE
+#define ROUNDEVEN_TYPE(F) BT_FN_##F##_##F
+DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUNDEVEN, "roundeven", ROUNDEVEN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST)
+#undef ROUNDEVEN_TYPE
 DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
 DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 06a420601c0..54315d057a2 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -792,6 +792,15 @@ fold_const_call_ss (real_value *result, combined_fn fn,
 	}
   return false;
 
+CASE_CFN_ROUNDEVEN:
+CASE_CFN_ROUNDEVEN_FN:
+  if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math)
+  {
+real_roundeven (result, format, arg);
+return true;
+  }
+  return false;
+
 CASE_CFN_LOGB:
   return fold

Re: About GSOC.

2019-06-03 Thread Joseph Myers
On Fri, 31 May 2019, Tejas Joshi wrote:

> +/* Return true if integer part of R is even, else return false. */
> +
> +bool
> +is_even (REAL_VALUE_TYPE *r)
> +{
> +  if (REAL_EXP (r) <= 0)
> +return false;

But the integer part (truncation towards 0) of something in the interval 
(-1, 1) is of course even.

> +  else if (REAL_EXP (r) < SIGNIFICAND_BITS)
> +  {
> +unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r);
> +int w = n / HOST_BITS_PER_LONG;
> +
> +unsigned long num = ((unsigned long)1 << (n % HOST_BITS_PER_LONG));
> +
> +if ((r->sig[w] & num) == 0)
> +  return true;
> +  }
> +  return false;
> +}

Suppose REAL_EXP (r) == SIGNIFICAND_BITS.  Then you still need to check 
the low bit in that case.

Suppose REAL_EXP (r) > SIGNIFICAND_BITS.  Then the number is definitely 
even, so you should return true, not false.

The comment on this function needs to define what it does for infinity / 
NaN, and you should make sure it behaves accordingly.  (If it should never 
be called for them, a gcc_assert would be appropriate.)

What does this function do for zero?  It should, of course, return that it 
is even.

> +/* Return true if R is halfway between two integers, else return false. */

Again, define what this does for infinity / NaN and make sure it behaves 
accordingly.

> +bool
> +is_halfway_below (const REAL_VALUE_TYPE *r)
> +{
> +  if (REAL_EXP (r) < 0)
> +return false;
> +
> +  if (REAL_EXP (r) == 0)
> +  {
> +unsigned long temp = ((unsigned long)1 << 63);

unsigned long might be 32-bit; you can't assume it's 64-bit.  You may mean 
(HOST_BITS_PER_LONG - 1) instead of 63.

> +if (((r->sig[SIGSZ-1] & temp) != 0) && ((r->sig[SIGSZ-1] & (temp-1)) == 
> 0))
> +  return true;
> +else
> +  return false;

This appears only to be checking the high word, not lower bits.

> +  else if (REAL_EXP (r) < SIGNIFICAND_BITS)
> +  {
> +unsigned int n = SIGNIFICAND_BITS - REAL_EXP (r);
> +int i, w = n / HOST_BITS_PER_LONG;

So n is the bit position, and w is the word position, of the bit with 
value 1; n-1 is the position of the bit with value 0.5.

> +for (i = 0; i < w; ++i)
> +{
> +  if (r->sig[i] != 0)
> +return false;
> +}

If n is a multiple of HOST_BITS_PER_LONG (that is, the bits with values 
0.5 and 1 are in different words), this will incorrectly return false when 
the 0.5 bit is set.

> +unsigned long num = ((unsigned long)1 << ((n - 1) % HOST_BITS_PER_LONG));
> +
> +if (((r->sig[w] & num) != 0) && ((r->sig[w] & (num-1)) == 0))
> +  return true;

And this also needs updating to handle the case where 0.5 and 1 are in 
different words correctly; currently it's checking bits that are all one 
word too high.  It's possible that for both issues, you want w to be the 
word with the 0.5 bit, not the word with the 1 bit.

For all the above, please add appropriate tests in the testsuite (for 
example, where 0.5 and 1 are in different words and the above would have 
produced incorrect results).

-- 
Joseph S. Myers
jos...@codesourcery.com


[GSoC'19, libgomp work-stealing] Task parallelism runtime

2019-06-03 Thread 김규래
Hi,
I've been studying the libgomp task parallelism system.
I have a few questions.
First, Tracing the events shows that only the main thread calls GOMP_task.
How do the other worker threads enter the libgomp runtime?
I can't find the entry point of the worker threads from the event tracing and 
the assembly dump. 
Second, How is the task priority set?
 
Ray Kim


Re: [GSoC'19, libgomp work-stealing] Task parallelism runtime

2019-06-03 Thread Jakub Jelinek
On Tue, Jun 04, 2019 at 03:01:13AM +0900, 김규래 wrote:
> Hi,
> I've been studying the libgomp task parallelism system.
> I have a few questions.
> First, Tracing the events shows that only the main thread calls GOMP_task.

No, any thread can call GOMP_task, in particular the thread that encountered
the #pragma omp task construct.

The GOMP_task function then decides based on the clauses of the construct
(passed in various ways through the arguments of that function) whether it
will be included (executed by the encountering thread), or queued for
later execution.  In the latter case, it will be scheduled during a barrier
(implicit or explicit), see gomp_barrier_handle_tasks called from the
bar.[ch] code, or at other spots, e.g. during taskwait construct
(GOMP_taskwait) or at the end of taskgroup (GOMP_taskgroup_end).

> How do the other worker threads enter the libgomp runtime?

If you never encounter a parallel, teams or target construct, then there is
just one thread that does everything (well, the library is written such that
if you by hand pthread_create, each such thread acts as a separate initial
thread from OpenMP POV).
Threads are created e.g. during parallel construct (GOMP_parallel), where
for non-nested parallelism as the standard requires it reuses existing
threads if possible or spawns new ones, see mainly team.c (gomp_team_start)
for the function that spawns new threads or awakes the ones waiting for
work, or gomp_thread_start in the same file for the function actually run by
the libgomp library created threads.

> I can't find the entry point of the worker threads from the event tracing and 
> the assembly dump. 
> Second, How is the task priority set?

By the user, through priority clause, passed to GOMP_task and then taken
into account when handling tasks in the various queues.

Jakub