RFC: reload unit tests (Was: [Bug optimization/15265] New: delete_output_reload deletes necessary insn) (fwd)

Joern Rennecke joern.rennecke@superh.com
Wed May 26 22:13:00 GMT 2004


>From renneckej  Wed May 26 18:45:38 2004
Received: from sh-uk-ex01.uk.w2k.superh.com [192.168.16.17]
	by localhost with IMAP (fetchmail-5.9.0)
	for renneckej@localhost (single-drop); Wed, 26 May 2004 18:45:38 +0100 (BST)
Received: from linsvr1.uk.superh.com ([192.168.16.50]) by sh-uk-ex01.uk.w2k.superh.com with Microsoft SMTPSVC(5.0.2195.6713);
	 Wed, 26 May 2004 18:48:03 +0100
Received: (from renneckej@localhost)
	by linsvr1.uk.superh.com (8.11.6/8.11.6) id i4QHk6P14796;
	Wed, 26 May 2004 18:46:06 +0100
From: Joern Rennecke <joern.rennecke@superh.com>
Message-Id: <200405261746.i4QHk6P14796@linsvr1.uk.superh.com>
Subject: RFC: reload unit tests (Was: [Bug optimization/15265] New: delete_output_reload deletes necessary insn)
To: gcc-bugzilla@gcc.gnu.org, gcc-patches@gc.gnu.org
Date: Wed, 26 May 2004 18:46:06 +0100 (BST)
Cc: joern.rennecke@superh.com
In-Reply-To: <20040503152115.15265.matz@suse.de> from "matz at suse dot de" at May 03, 2004 03:21:19 
X-Mailer: ELM [version 2.5 PL6]
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Return-Path: joern.rennecke@superh.com
X-OriginalArrivalTime: 26 May 2004 17:48:03.0612 (UTC) FILETIME=[9810ADC0:01C44349]

A problem with reload is that it is very hard to test specifically,
since C code test you write tends look differently at reload
time in different compiler versions.  I therefore have set out
to feed raw rtl into reload, for cases which I recall required some
work on reload to get right in the past.  It turns out that you actually
need quite a lot of initialization code just to feed rtl into reload.
I've made an executable that is linked basically like cc1, except I
replace main.o with my own code .  This is purely for sh-elf at the
moment because I know some interesting test cases for this target,
and creating a new input language hased on rtl is a lot of extra work
and could raise FSF policy issues worse than we had for java bytecode
and precompiled headers.  I am not averse to make this more multi-platform,
but there should be a clear consensus what it should look like first,
and some ideas for test cases specific to one or more other platforms
too.

Of course, declarations for the formerly static functions of toplev.c
should be moved into a heder file - or the new code moved into toplev.c .

This is still based on sources from the 10th May because the current
mainline doesn't build for sh-elf
(see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15521) .

2004-05-26  J"orn Rennecke <joern.rennecke@superh.com>

	* Makefile.in (rld-tst): New rule.
	* toplev.c (general_init, backend_init, lang_dependent_init):
	no longer static.
	(rld-debug.c): New file.

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1274
diff -p -r1.1274 Makefile.in
*** Makefile.in	28 Apr 2004 20:40:44 -0000	1.1274
--- Makefile.in	26 May 2004 17:17:42 -0000
*************** po/$(PACKAGE).pot: force options.c
*** 3909,3911 ****
--- 3909,3915 ----
  	$(MAKE) srcextra
  	AWK=$(AWK) $(SHELL) $(srcdir)/po/exgettext \
  		$(XGETTEXT) $(PACKAGE) $(srcdir)
+ 
+ rld-tst$(exeext): rld-debug.o $(C_OBJS) libbackend.a $(LIBDEPS)
+ 	$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o rld-tst$(exeext) \
+ 	rld-debug.o $(C_OBJS) libbackend.a $(LIBS)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.895
diff -p -r1.895 toplev.c
*** toplev.c	20 Apr 2004 09:27:41 -0000	1.895
--- toplev.c	26 May 2004 17:17:44 -0000
*************** Software Foundation, 59 Temple Place - S
*** 98,108 ****
  				   declarations for e.g. AIX 4.x.  */
  #endif
  
! static void general_init (const char *);
  static void do_compile (void);
  static void process_options (void);
! static void backend_init (void);
! static int lang_dependent_init (const char *);
  static void init_asm_output (const char *);
  static void finalize (void);
  
--- 98,108 ----
  				   declarations for e.g. AIX 4.x.  */
  #endif
  
! void general_init (const char *);
  static void do_compile (void);
  static void process_options (void);
! void backend_init (void);
! int lang_dependent_init (const char *);
  static void init_asm_output (const char *);
  static void finalize (void);
  
*************** default_tree_printer (pretty_printer * p
*** 2153,2159 ****
  /* Initialization of the front end environment, before command line
     options are parsed.  Signal handlers, internationalization etc.
     ARGV0 is main's argv[0].  */
! static void
  general_init (const char *argv0)
  {
    const char *p;
--- 2153,2159 ----
  /* Initialization of the front end environment, before command line
     options are parsed.  Signal handlers, internationalization etc.
     ARGV0 is main's argv[0].  */
! void
  general_init (const char *argv0)
  {
    const char *p;
*************** process_options (void)
*** 2490,2496 ****
  }
  
  /* Initialize the compiler back end.  */
! static void
  backend_init (void)
  {
    init_adjust_machine_modes ();
--- 2490,2496 ----
  }
  
  /* Initialize the compiler back end.  */
! void
  backend_init (void)
  {
    init_adjust_machine_modes ();
*************** backend_init (void)
*** 2522,2528 ****
  }
  
  /* Language-dependent initialization.  Returns nonzero on success.  */
! static int
  lang_dependent_init (const char *name)
  {
    if (dump_base_name == 0)
--- 2522,2528 ----
  }
  
  /* Language-dependent initialization.  Returns nonzero on success.  */
! int
  lang_dependent_init (const char *name)
  {
    if (dump_base_name == 0)
*** /dev/null	Thu Aug 30 21:30:55 2001
--- rld-debug.c	Wed May 26 18:25:17 2004
***************
*** 0 ****
--- 1,200 ----
+ /* reload unit test (currently only for sh-elf)
+    Copyright (C) 2004 Free Software Foundation, Inc.
+    Contributed by Joern Rennecke <joern.rennecke@superh.com>
+ 
+    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 2, 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 GNU General Public License for more
+    details.
+ 
+    You should have received a copy of the GNU General Public License along
+    with GCC; see the file COPYING.  If not, write to the Free Software
+    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "rtl.h"
+ #include "insn-config.h"
+ #include "reload.h"
+ #include "function.h"
+ #include "regs.h"
+ #include "tree.h"
+ #include "toplev.h"
+ #include "output.h" /* ??? For c_common_init_options */
+ #include "flags.h"
+ #include "c-common.h"
+ #include "debug.h"
+ #include "expr.h"
+ #include "opts.h"
+ 
+ extern void general_init (const char *);
+ extern void backend_init (void);
+ extern int lang_dependent_init (const char *);
+ 
+ static struct renumber_s { int from, to; } renumber[9];
+ 
+ static void
+ autoinc0 (void)
+ {
+   rtx pia = gen_reg_rtx (SImode);
+   rtx pda = gen_reg_rtx (SImode);
+   rtx pi = gen_rtx_POST_INC (Pmode, pia);
+   rtx pd = gen_rtx_PRE_DEC (Pmode, pda);
+ 
+   emit_insn (gen_movsi (gen_rtx_REG (SImode, R1_REG),
+ 			gen_rtx_MEM (SImode, copy_rtx (pi))));
+   emit_insn (gen_movsi (gen_rtx_REG (SImode, R2_REG),
+ 			gen_rtx_MEM (SImode, copy_rtx (pi))));
+   emit_insn (gen_movsi (gen_rtx_MEM (SImode, copy_rtx (pd)),
+ 			gen_rtx_REG (SImode, R2_REG)));
+   emit_insn (gen_movsi (gen_rtx_MEM (SImode, copy_rtx (pd)),
+ 			gen_rtx_REG (SImode, R1_REG)));
+ }
+ 
+ static void
+ autoinc1 (void)
+ {
+   assign_stack_temp (BLKmode, 100, 1);
+   autoinc0 ();
+ }
+ 
+ static void
+ autoinc2 (void)
+ {
+   assign_stack_temp (BLKmode, 40000, 1);
+   autoinc0 ();
+ }
+ 
+ static void
+ subreg0 (void)
+ {
+   rtx src = gen_reg_rtx (SImode);
+   emit_insn (gen_add2_insn (gen_rtx_REG (SImode, R1_REG), src));
+   emit_insn (gen_movhi (gen_rtx_REG (HImode, R2_REG),
+ 			gen_rtx_SUBREG (HImode, src,
+ 					BYTES_BIG_ENDIAN ? 2 : 0)));
+ }
+ 
+ static void
+ subreg1 (void)
+ {
+   rtx r1 = gen_reg_rtx (SImode);
+   rtx r2 = gen_reg_rtx (HImode);
+   rtx src = gen_reg_rtx (SImode);
+ 
+   assign_stack_temp (BLKmode, 8, 1);
+   renumber[0].from = REGNO (r1);
+   renumber[0].to = R1_REG;
+   emit_insn (gen_add2_insn (r1, src));
+   emit_insn (gen_movhi (r2,
+ 			gen_rtx_SUBREG (HImode, src,
+ 					BYTES_BIG_ENDIAN ? 2 : 0)));
+ }
+ 
+ static void
+ init_once (int argc, const char **argv)
+ {
+   general_init (argv[0]);
+   decode_options (argc, argv);
+ 
+   c_common_init_options (argc, argv);
+   debug_hooks = &do_nothing_debug_hooks;
+ 
+   backend_init ();
+ 
+   lang_dependent_init (NULL);
+ 
+   init_flow ();
+ }
+ 
+ static void
+ rld_debug (const char *fun_name, void (*fun_gen) (void))
+ {
+   rtx insns;
+   struct function this_fun;
+   struct expr_status this_expr;
+   tree fun_id, fun_type, block;
+   struct renumber_s *p;
+ 
+   printf ("Running test: %s\n", fun_name);
+   fun_id = get_identifier (fun_name);
+   fun_type = default_function_type;
+   current_function_decl = build_decl (FUNCTION_DECL, fun_id, fun_type);
+   block = make_node (BLOCK);
+   DECL_INITIAL (current_function_decl) = block;
+   memset (&this_fun, 0, sizeof this_fun);
+   this_fun.decl = current_function_decl;
+   cfun = &this_fun;
+   cfun->expr = &this_expr;
+   memset (&this_expr, 0, sizeof this_expr);
+   init_emit ();
+   memset (renumber, 0, sizeof renumber);
+ 
+   cfun->expr = &this_expr;
+   memset (&this_expr, 0, sizeof this_expr);
+ 
+   reload_completed = 0;
+   epilogue_completed = 0;
+   flow2_completed = 0;
+   no_new_pseudos = 0;
+ 
+   (*fun_gen) ();
+ 
+   insns = get_insns ();
+ 
+   instantiate_virtual_regs (current_function_decl, insns);
+ 
+   max_regno = max_reg_num ();
+ 
+   rtl_register_cfg_hooks ();
+   find_basic_blocks (insns, max_regno, NULL);
+   regclass_init ();
+   life_analysis (insns, NULL,
+ 		 PROP_DEATH_NOTES | PROP_LOG_LINKS | PROP_REG_INFO);
+ 
+   no_new_pseudos = 1;
+   regclass (insns, max_regno, NULL);
+ 
+   /* Allocate the reg_renumber array.  */
+   allocate_reg_info (max_regno, FALSE, TRUE);
+ 
+   for (p = renumber; p->from != p->to; p++)
+     reg_renumber[p->from] = p->to;
+   /* Allocate the reg_equiv_memory_loc array.  */
+   reg_equiv_memory_loc = xcalloc (max_regno, sizeof (rtx)); /* FIXME */
+ 
+   build_insn_chain (insns);
+   reload (insns, 0);
+ 
+   debug_rtx_list(get_insns(),999);
+ }
+ 
+ static struct { const char *name; void (*gen_fun) (void); } test_list[]
+ = {
+   { "subreg inheritance", subreg1 },
+   { "auto-increment inheritance", autoinc0 },
+   { "auto-increment inheritance w/ medium stack temp", autoinc1 },
+   { "auto-increment inheritance w/ large stack temp", autoinc2 },
+   { "subreg inheritance", subreg0 },
+ };
+ 
+ int
+ main (int argc, const char **argv)
+ {
+   unsigned i;
+ 
+   optimize = 2;
+   flag_expensive_optimizations = 1;
+   init_once (argc, argv);
+   for (i = 0; i < ARRAY_SIZE (test_list); i++)
+     rld_debug (test_list[i].name, test_list[i].gen_fun);
+   exit (0);
+ }



More information about the Gcc-patches mailing list