LTO remapping/deduction of machine modes of types/decls

2016-12-30 Thread Alexander Monakov
Hello, Richard, Jakub, community,

May I join/restart the old discussion about machine mode remapping at LTO
stream-in time.  To recap, when offloading to NVPTX was introduced, there
was a problem due to differences in the set of supported modes (e.g. there
was no 'XFmode' on NVPTX that would correspond to 'long double' tree type
node in GIMPLE LTO streams produced by x86 host compiler).

The current solution in GCC is to additionally stream a 'mode table' and use it
to remap numeric mode identifiers during LTO stream-in in all trees that have
modes.  This is the solution initially outlined by Jakub in the message
https://gcc.gnu.org/ml/gcc-patches/2015-02/msg00226.html .  In response to that,
Richard said,

> I think (also communicated that on IRC) we should instead try not streaming
> machine-modes at all but generating them at stream-in time via layout_type
> or layout_decl.

and later in the thread also:

> I'm just looking for a way to make this less of a hack (and the LTO IL
> less target dependent).  Not for GCC 5 for which something like your
> patch is probably ok, but for the future.

Now that we're in the future, I've asked Vlad Ivanishin (Cc'ed) to try and
implement Richard's approach.  The motivation is enhancing LTO for offloaded
code, in particular to expose library code for inlining.  In that scenario,
the current scheme has a problem that WPA can arbitrarily mix LTO sections
coming from libraries (where the modes don't need remapping) and LTO sections
produced by the host compiler.  Thus, mode_table would need to be only
selectively applied during stream-in, based on the origin of the section.  And,
we'd need to ensure that WPA duplicates mode tables across all ltrans units.

In light of that, I felt that trying Richard's approach would be proper.
Actually, I don't know why gimple/tree representation carries machine modes in
the first place; it seems to be redundant information deducible from type
information.

Vlad's current patch is adding mode deduction for types and decls, matches the
deduced mode against the streamed-in mode, and ICEs in case of mismatch. To be
clear, he's checking this for native LTO via lto-bootstrap, but nevertheless
it's a nice way of giving confidence that mode inference works as intended.

This seems to be fine for C, but in C++ we are seeing some hard-to-explain cases
where the deduced BLKmode for 7-byte-sized/4-byte-aligned base-class decl is
mismatching against deduced DImode.  The DImode would be obviously correct for
8-byte-sized decl of the corresponding type, but the base class decl does not
have 1 byte of padding in the tail.  What's worse, the issue is just for the
mode of the decl: the mode of the type is BLKmode, as we'd expect.

Unfortunately, just adjusting the C++ frontend to place BLKmode on the decl too
doesn't lead to immediate success, because decl modes have implications for
debug info generation, and the compiler starts ICE'ing there instead.

So we're hitting under-documented places in the compiler here, and personally
I don't have the confidence to judge how they're intended to work.

Basically for now my questions are:

1. Is there an intended invariant that decl modes should match type modes? It
appears that if there was, the above situation with C++ base objects would be a
violation.

2. Do you think we should continue digging in this direction?

I'm not sure how much it'd help a discussion, but for completeness Vlad's
current patchset is provided as attachments. Patch 1/3 adds mode inference for
types (only), patch 2 just reverts Jakub's additions of mode_table handling,
and finally patch 3 adds mode inference for decls, adds checking against
streamed-in modes, and shows where the attempted adjustments in the C++ frontend
and debug info generation were.  There are a few coding style violations; sorry;
I hope they are not too distracting.

Thanks.
AlexanderFrom 58ad9d4d75cbc057c003c701ff3f0e6b8fa35e39 Mon Sep 17 00:00:00 2001
From: Vladislav Ivanishin 
Date: Tue, 13 Dec 2016 14:58:26 +0300
Subject: [PATCH 1/3] Infer modes from types after LTO streaming-in

* gcc/lto/lto.c: New function lto_infer_mode () which calls ...
* gcc/stor-layout.c: ... the new function set_mode_for_type ().
* gcc/stor-layout.h: Declare set_mode_for_type ().
---
 gcc/lto/lto.c |  20 +
 gcc/stor-layout.c | 127 ++
 gcc/stor-layout.h |   2 +
 3 files changed, 149 insertions(+)

diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 6718fbbe..cec54e3 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1656,6 +1656,25 @@ unify_scc (struct data_in *data_in, unsigned from,
   return unified_p;
 }
 
+static void
+lto_infer_mode (tree type)
+{
+  if (!TYPE_P (type))
+return;
+
+  if (!COMPLETE_TYPE_P (type) && TYPE_MODE (type) == VOIDmode)
+return;
+
+  /* C++ FE has complex logic for laying out classes.  We don't have
+ the information here to reproduce the decision process (nor do we
+ w

Help with integrating my test program into dejagnu

2016-12-30 Thread Daniel Santos
Still being pretty new to GCC and having never used dejagnu, expect or 
Tcl, I'm trying to determine how to best integrate my test program into 
GCC's test harness.  I wrote this to help find breakages while working 
on optimizations for Microsoft 64-bit ABI pro/epilogues.  Rather than 
testing specific cases, it generates a few thousand unique tests by 
iterating through variations.  It consists of a C++ program that 
generates a pair of .c files (that I don't want in the same translation 
unit).  These are built along with a static .c and .S file and linked 
into the test program.  It is intended to be built and executed on the 
target machine and I currently run it manually with a frequently-edited 
Makefile.


The first thing I need help with is figuring out if this should be run 
by dejagnu or if I should just write a proper Makefile.in and add it to 
gcc's Makefile.in.  Integrating with dejagnu seems to be the most 
intuitive and simple, but I don't properly understand how this would 
affect a cross-compiler build.  Any advice?


Thanks!
Daniel
>From d38bc80fc793224fb0fbd586824786f5ec178f65 Mon Sep 17 00:00:00 2001
From: Daniel Santos 
Date: Sat, 17 Dec 2016 15:37:28 -0600
Subject: [PATCH] [i386] Test program for ms_abi functions.

---
 gcc/testsuite/gcc.target/i386/msabi/Makefile  |  56 +++
 gcc/testsuite/gcc.target/i386/msabi/do_test.S | 142 ++
 gcc/testsuite/gcc.target/i386/msabi/gen.cc| 653 ++
 gcc/testsuite/gcc.target/i386/msabi/msabi.c   | 304 
 gcc/testsuite/gcc.target/i386/msabi/msabi.h   | 110 +
 5 files changed, 1265 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/msabi/Makefile
 create mode 100644 gcc/testsuite/gcc.target/i386/msabi/do_test.S
 create mode 100644 gcc/testsuite/gcc.target/i386/msabi/gen.cc
 create mode 100644 gcc/testsuite/gcc.target/i386/msabi/msabi.c
 create mode 100644 gcc/testsuite/gcc.target/i386/msabi/msabi.h

diff --git a/gcc/testsuite/gcc.target/i386/msabi/Makefile b/gcc/testsuite/gcc.target/i386/msabi/Makefile
new file mode 100644
index 000..8d762d704ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/msabi/Makefile
@@ -0,0 +1,56 @@
+GEN_OPTIONS ?= -p 6 -m 0
+GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc-github/build/head
+#GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc-github/build/head-test-sp-realigned
+#GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc-github/build/head-test-patched
+#GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc.work0/build/head
+GCC_SRC_DIR  = /home/daniel/proj/sys/gcc-github
+#GCC_SRC_DIR  = /home/daniel/proj/sys/gcc.work0
+COMPFLAGS= -B$(GCC_BUILD_DIR)/gcc
+#CC   = $(GCC_BUILD_DIR)/gcc/xgcc $(COMPFLAGS)
+#CXX  = $(GCC_BUILD_DIR)/gcc/xg++ $(COMPFLAGS) -B$(GCC_BUILD_DIR)/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs \
+#		-isystem $(GCC_BUILD_DIR)/x86_64-pc-linux-gnu/libstdc++-v3/include \
+#		-isystem $(GCC_BUILD_DIR)/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu  \
+#		-isystem $(GCC_SRC_DIR)/libstdc++-v3/libsupc++
+WARN_FLAGS  ?= -Wall -Wextra -Wno-unused-parameter
+CFLAGS	?= -g3 -O2 -m64
+#CFLAGS	?= -g3 -O2 -m64 -moutline-msabi-xlogues
+
+CXXFLAGS?= $(CFLAGS)
+CFLAGS	+= $(WARN_FLAGS)
+CXXFLAGS+= -std=gnu++11 $(WARN_FLAGS)
+ASFLAGS	?= -g3
+
+gen_object_files	= gen.o
+gen_program		= gen
+generated_sources	= fns.c do_tests.c
+headers			= msabi.h
+test_object_files	= msabi.o do_test.o fns.o do_tests.o
+test_program		= msabi
+
+all: $(test_program)
+
+check: $(test_program)
+	$(CURDIR)/$(test_program) && echo PASS || echo FAIL
+
+.PHONY : clean
+clean:
+	rm -f $(gen_object_files) $(gen_program) $(generated_sources) \
+	  $(test_object_files) $(test_program)
+
+%.o: %.cc
+	$(CXX) $(CXXFLAGS) -I. -c -o $@ $<
+
+$(gen_program): $(gen_object_files)
+	$(CXX) $(CXXFLAGS) -o $@ $<
+
+fns.c : $(gen_program)
+	$(CURDIR)/$(gen_program) $(GEN_OPTIONS) fns.c > $@ || rm $@
+
+do_tests.c : $(gen_program)
+	$(CURDIR)/$(gen_program) $(GEN_OPTIONS) do_tests.c > $@ || rm $@
+
+%.o: %.c $(headers)
+	$(CC) $(CFLAGS) -I. -c -o $@ $<
+
+$(test_program): $(headers) $(test_object_files)
+	$(CC) $(CFLAGS) -I. -o $@ $(test_object_files)
diff --git a/gcc/testsuite/gcc.target/i386/msabi/do_test.S b/gcc/testsuite/gcc.target/i386/msabi/do_test.S
new file mode 100644
index 000..f01ea0943ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/msabi/do_test.S
@@ -0,0 +1,142 @@
+/* Assembly proxy functions for ms_abi tests.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Daniel Santos 
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+

Re: Help with integrating my test program into dejagnu

2016-12-30 Thread Mike Stump
On Dec 30, 2016, at 11:58 AM, Daniel Santos  wrote:
> 
> Still being pretty new to GCC and having never used dejagnu, expect or Tcl, 
> I'm trying to determine how to best integrate my test program into GCC's test 
> harness.  I wrote this to help find breakages while working on optimizations 
> for Microsoft 64-bit ABI pro/epilogues.  Rather than testing specific cases, 
> it generates a few thousand unique tests by iterating through variations.  It 
> consists of a C++ program that generates a pair of .c files (that I don't 
> want in the same translation unit).  These are built along with a static .c 
> and .S file and linked into the test program.  It is intended to be built and 
> executed on the target machine and I currently run it manually with a 
> frequently-edited Makefile.
> 
> The first thing I need help with is figuring out if this should be run by 
> dejagnu or if I should just write a proper Makefile.in and add it to gcc's 
> Makefile.in.  Integrating with dejagnu seems to be the most intuitive and 
> simple, but I don't properly understand how this would affect a 
> cross-compiler build.  Any advice?

Yeah, first step:

+GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc-github/build/head
+#GCC_BUILD_DIR   = 
/home/daniel/proj/sys/gcc-github/build/head-test-sp-realigned
+#GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc-github/build/head-test-patched
+#GCC_BUILD_DIR   = /home/daniel/proj/sys/gcc.work0/build/head
+GCC_SRC_DIR  = /home/daniel/proj/sys/gcc-github
+#GCC_SRC_DIR  = /home/daniel/proj/sys/gcc.work0

Any absolute filename is wrong, remove all.

Do:

  srcdir = .
  objdir := $(shell pwd)

in the Makefile at the top, and use use $(srcdir) to locate files in the source 
tree and use $(objdir) to locate files in the build tree.  You can think of . 
as gcc/testsuite/gcc.target/i386/msabi.  You can place any temporary files into 
.

Next step, add some glue code in i386.exp to run it:

Index: testsuite/gcc.target/i386/i386.exp
===
--- testsuite/gcc.target/i386/i386.exp  (revision 243984)
+++ testsuite/gcc.target/i386/i386.exp  (working copy)
@@ -418,6 +418,28 @@ if ![info exists DEFAULT_CFLAGS] then {
 dg-init
 clearcap-init
 
+proc run_msabi { } {
+global srcdir subdir objdir rootme GCC_UNDER_TEST
+
+verbose "orig srcdir is $srcdir" 0
+verbose "orig objdir is $objdir" 0
+verbose "orig subdir is $subdir" 0
+verbose "GCC_UNDER_TEST is $GCC_UNDER_TEST" 0
+if { ![isnative] } {
+   unsupported "$subdir/msabi"
+return
+}
+set status [remote_exec build "make -f $srcdir/$subdir/msabi/Makefile 
srcdir=$srcdir/$subdir/msabi objdir=$rootme GCC_UNDER_TEST=$GCC_UNDER_TEST 
check"]
+set status [lindex $status 0]
+return $status
+}
+
+if { [run_msabi] == 1 } {
+  fail $subdir/msabi
+} else {
+  pass $subdir/msabi
+}
+
 global runtests
 # Special case compilation of vect-args.c so we don't have to
 # replicate it 16 times.

See site.exp in gcc's build directory for all the variables you can use and 
what values they have.  That's be a good start.  I think that would bring it up 
to at least a minimal level for inclusion.

>From there, I'd get rid of the rest of the Makefile, and just put the code 
>into run_msabi.  You'll want to examine struct-layout-1(aka 
>gcc/testsuite/gcc.dg/compat/struct-layout-1.exp), it has a recipe for running 
>a generator program.  compat can also check binary compatibility between two 
>compilers.  For that to work, one would have to run in an environment where 
>one can run the other compiler.

Another way to simplify it would be to just check in the generated program as a 
.h file, and then #include all the bits in msabi.c, and then test msabi.c 
normally.  This is reasonable if the generated program isn't that big.  If big, 
then that should be avoided.

I'll punt to the x86 people on wether or not they want the tester in the tree.  
Also, the .exp file can be created in the msabi directory, and dejagnu will run 
it from there.  You then would have no changes to i386.exp.  Seems slightly 
cleaner.  Once you get comfortable with it, you can remove the verbose lines.  
I just put them in so that you can see those variables.

You might need to conditionalize the test to only run on those systems that can 
compile and run the code, to do that you might need [istarget "triplet"], where 
triplet is a system where you know it will work.  I didn't check the code to 
see how portable it was.

Hope that helps.  Also, see testsuite/lib/*.exp, and testsuite/.../*.exp in the 
source tree for hints on variables, code, coding style, and examples of all 
sorts of things.