This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[c++ patch] fix for mi-thunk emission


Hi,

this patch is required at least on sparc for the genattrtab speedup 
patches, to generate the same code with and without them for kdecore.cc.  
But the bug is lurking anyway.  The problem is how some backends 
(alpha,ia64,mips,rs6000 on OSF,sh and sparc) emit mi-thunks by not going 
through the proper channels and instead calling final() themself.

The code in the arch.c usually looks similar to this:
  insn = get_insns ();
  insn_locators_initialize ();
  shorten_branches (insn);
  final_start_function (insn, file, 1);
  final (insn, file, 1);
  final_end_function ();

with the C++ frontend side (in method.c) being (partly):

      current_function_decl = thunk_fndecl;
      init_function_start (thunk_fndecl);
      current_function_is_thunk = 1;
      assemble_start_function (thunk_fndecl, fnname);
      targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
      assemble_end_function (thunk_fndecl, fnname);
      current_function_decl = 0;
      cfun = 0;

Now the problem is, that this together creates a new function calling 
passes from the backend on it, and generally doing stuff.  But it misses 
to call the pass_clean_state, which is done normally right after 
pass_final.  This means that some structures remain initialized 
(incorrectly) for the next function to be compiled.  Unfortunately one 
can't just use pass_clean_state here, as not all structures are set up 
(for instance the basic blocks), also because the backend doesn't go 
through the proper channel of emitting functions.

The problem at hand is the insn_length array used in final.c by 
get_attr_length.  It is set up by shorten_branches to reflect the real 
length per insn.  If it is initialized get_attr_length() will use that 
array, otherwise it will call ultimately insn_default_length() (and 
attribute defined by insn-attrtab.c).

So, what happens is the following:
  mi-thunk is emitted
    shorten_branch is called --> insn_length[] set up
    final and friends are called
  mi-thunk done
  next normal function is compiled
    ... different passes run ...
    pass_delay_slots is run
      dbr_schedule
        requests certain attributes, some of them depend on attr_length
        on sparc --> get_attr_length is called, returns wrong cached 
        length from the mi-thunk *
    pass_shorten_branches is run
      setup insn_length[] correctly for current function
    ...
    pass_clean_state is run
      init_insn_length called, which clears insn_length[]

At * this results in different code depending on if get_attr_length() is 
actually called for the other attributes (like eligible_for_delay in 
sparc's case), or if that call is optimized away by genattrtab (to the 
value insn_default_length would return).  They would agree on the value if 
insn_length[] wouldn't be incorrectly initialized.

Note that this is just _different_, not wrong code.  Just the filling of 
delay slots is different, it's not incorrect.  Of course it could result 
also in wrong code under other circumstances.

I fixed this by just adding a call to init_insn_length() at the right 
place in cp/method.c .  But conceptually how mi-thunks are emitted 
currently is a mess, and could possibly also result in other funny effects 
from not running clean_state afterwards.

bootstrapped + regtested (together with the genattrtab patches) on 
x86-64-linux.  I have no testcase really, as kdecore.cc is much too large, 
and as no wrong code was emitted it would also be hard to check.

Okay for mainline?


Ciao,
Michael.
-- 

	* method.c (use_thunk): Call init_insn_lengths.

Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.336
diff -u -p -r1.336 method.c
--- cp/method.c	25 Jun 2005 00:58:12 -0000	1.336
+++ cp/method.c	30 Jul 2005 22:42:55 -0000
@@ -441,6 +441,7 @@ use_thunk (tree thunk_fndecl, bool emit_
 				       fixed_offset, virtual_value, alias);
 
       assemble_end_function (thunk_fndecl, fnname);
+      init_insn_lengths ();
       current_function_decl = 0;
       cfun = 0;
       TREE_ASM_WRITTEN (thunk_fndecl) = 1;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]