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]

Re: [PATCH/RFA] PR target/13250


> Your patch for post-call group sheduling fixes all of them except
> a failure compiling local-inst.cc for -fPIC.

Thanks for the testcase (sent off-list).
It turns out that the loop optimizer has inserted a jump between
the call and the instruction that copied the return value.
I.e. before loop2 we have:

(call_insn 2975 2974 3094 88 (parallel [
            (set (reg:SI 0 r0)
                (call (mem:SI (symbol_ref:SI ("_ZNKSt6locale2id5_M_idEv") [flags 0x41] <function_decl 0x408077b4 _M_id>) [0 S4 A32])
                    (const_int 0 [0x0])))
            (use (reg:PSI 151 ))
            (use (reg:SI 12 r12))
            (clobber (reg:SI 146 pr))
            (clobber (scratch:SI))
        ]) 172 {call_value_pcrel} (nil)
    (expr_list:REG_EH_REGION (const_int 1 [0x1])
        (nil))
    (expr_list (use (reg:SI 4 r4))
        (nil)))
;; End of basic block 88, registers live:
 (nil)

;; Start of basic block 89, registers live: (nil)
(note 3094 2975 2976 89 [bb 89] NOTE_INSN_BASIC_BLOCK)

(insn 2976 3094 2978 89 (set (reg:SI 182 [ T.678 ])
        (reg:SI 0 r0)) 123 {movsi_ie} (nil)
    (nil))

and after loop2 we got:

(call_insn 2975 2974 3463 90 (parallel [
            (set (reg:SI 0 r0)
                (call (mem:SI (symbol_ref:SI ("_ZNKSt6locale2id5_M_idEv") [flags 0x41] <function_decl 0x408077b4 _M_id>) [0 S4 A32])
                    (const_int 0 [0x0])))
            (use (reg:PSI 151 ))
            (use (reg:SI 12 r12))
            (clobber (reg:SI 146 pr))
            (clobber (scratch:SI))
        ]) 172 {call_value_pcrel} (nil)
    (expr_list:REG_EH_REGION (const_int 1 [0x1])
        (nil))
    (expr_list (use (reg:SI 4 r4))
        (nil)))
;; End of basic block 90, registers live:
 (nil)

;; Start of basic block 91, registers live: (nil)
(note 3463 2975 3465 91 [bb 91] NOTE_INSN_BASIC_BLOCK)

(jump_insn 3465 3463 3466 91 (set (pc)
        (label_ref 3464)) -1 (nil)
    (nil))
;; End of basic block 91, registers live:
 (nil)

(barrier 3466 3465 3250)

;; Start of basic block 92, registers live: (nil)
(code_label/s 3250 3466 3253 92 352 "" [1 uses])

(note 3253 3250 3251 92 [bb 92] NOTE_INSN_BASIC_BLOCK)

(insn 3251 3253 3252 92 (set (reg:SI 374 [ save_eptr.1036 ])
        (reg:SI 4 r4)) 123 {movsi_ie} (nil)
    (nil))

(insn 3252 3251 3097 92 (set (reg:SI 373 [ save_filt.1037 ])
        (reg:SI 5 r5)) 123 {movsi_ie} (nil)
    (nil))
;; End of basic block 92, registers live:
 (nil)

;; Start of basic block 93, registers live: (nil)
(code_label 3097 3252 3102 93 327 "" [16 uses])

(note 3102 3097 3098 93 [bb 93] NOTE_INSN_BASIC_BLOCK)

(insn 3098 3102 3099 93 (set (reg:SI 147 t)
        (eq:SI (reg:SI 373 [ save_filt.1037 ])
            (const_int -1 [0xffffffff]))) 1 {cmpeqsi_t} (nil)
    (nil))

(jump_insn 3099 3098 3254 93 (set (pc)
        (if_then_else (ne (reg:SI 147 t)
                (const_int 0 [0x0]))
            (label_ref 2987)
            (pc))) 153 {branch_true} (nil)
    (expr_list:REG_BR_PROB (const_int 2901 [0xb55])
        (nil)))
;; End of basic block 93, registers live:
 (nil)

;; Start of basic block 94, registers live: (nil)
(note 3254 3099 3151 94 [bb 94] NOTE_INSN_BASIC_BLOCK)

(insn 3151 3254 3152 94 (set (reg:SI 4 r4 [ save_eptr.1036 ])
        (reg:SI 374 [ save_eptr.1036 ])) 123 {movsi_ie} (nil)
    (nil))

(call_insn 3152 3151 3101 94 (parallel [
            (call (mem:SI (symbol_ref:SI ("_Unwind_Resume") [flags 0x41]) [0 S4 A32])
                (const_int 0 [0x0]))
            (use (reg:PSI 151 ))
            (use (reg:SI 12 r12))
            (clobber (reg:SI 146 pr))
            (clobber (scratch:SI))
        ]) 166 {call_pcrel} (nil)
    (expr_list:REG_NORETURN (const_int 0 [0x0])
        (nil))
    (expr_list (use (reg:SI 4 r4 [ save_eptr.1036 ]))
        (nil)))
;; End of basic block 94, registers live:
 (nil)

(barrier 3101 3152 2987)

;; Start of basic block 95, registers live: (nil)
(code_label/s 2987 3101 3095 95 326 "" [2 uses])

(note 3095 2987 2990 95 [bb 95] NOTE_INSN_BASIC_BLOCK)

(insn 2990 3095 2991 95 (set (reg:SI 4 r4 [ save_eptr.1036 ])
        (reg:SI 374 [ save_eptr.1036 ])) 123 {movsi_ie} (nil)
    (nil))

(call_insn 2991 2990 2992 95 (parallel [
            (call (mem:SI (symbol_ref:SI ("__cxa_call_unexpected") [flags 0x41] <function_decl 0x402ac740 __cxa_call_unexpected>) [0 S4 A32])
                (const_int 0 [0x0]))
            (use (reg:PSI 151 ))
            (use (reg:SI 12 r12))
            (clobber (reg:SI 146 pr))
            (clobber (scratch:SI))
        ]) 166 {call_pcrel} (nil)
    (expr_list:REG_NORETURN (const_int 0 [0x0])
        (nil))
    (expr_list (use (reg:SI 4 r4 [ save_eptr.1036 ]))
        (nil)))
;; End of basic block 95, registers live:
 (nil)

(barrier 2992 2991 3464)

;; Start of basic block 96, registers live: (nil)
(code_label 3464 2992 3094 96 373 "" [1 uses])

(note 3094 3464 2976 96 [bb 96] NOTE_INSN_BASIC_BLOCK)

(insn 2976 3094 2978 96 (set (reg:SI 182 [ T.678 ])
        (reg:SI 0 r0)) 123 {movsi_ie} (nil)
    (nil))

This in itself doesn't cause a reload problem, but it means that
we have to look harder to find out if we got a post-call group.

I must admit that I'm at a bit of a loss what the point of the
reordering is.  Unfortunately, the new cfg handling makes it harder
to track down changes to the code that cause them.

#0  make_jump_insn_raw (pattern=0x401d8340) at ../../srcw/gcc/emit-rtl.c:3439
#1  0x08365a7b in emit_jump_insn (x=0x401d8340)
    at ../../srcw/gcc/emit-rtl.c:4548
#2  0x08464794 in gen_jump (operand0=0x40d0191c) at insn-emit.c:9990
#3  0x08309be0 in force_nonfallthru_and_redirect (e=0x40ca3ef4, 
    target=0x406ffef4) at ../../srcw/gcc/cfgrtl.c:1142
#4  0x08309c63 in force_nonfallthru (e=0x40ca3ef4)
    at ../../srcw/gcc/cfgrtl.c:1163
#5  0x08300637 in fixup_reorder_chain () at ../../srcw/gcc/cfglayout.c:778
#6  0x083012ca in cfg_layout_finalize () at ../../srcw/gcc/cfglayout.c:1180
#7  0x085c6859 in rest_of_handle_loop2 (decl=0x4080fb54, insns=0x4077f168)
    at ../../srcw/gcc/passes.c:1337

At any rate, this is how this can be fixed in sched-deps too:

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

	* sched-int.h (in_post_call_group_p): Change type to enum.
	* sched-deps.c (sched_analyze_insn):
	(sched_analyze): When in_post_call_group_p is post_call_initial,
	don't add a dependency, but still set SCHED_GROUP_P and CANT_MOVE,
	and also reset in_post_call_group_p to post_call.
	(sched_analyze): When the previous basic block ended in a CALL_INSN,
	initialize in_post_call_group_p as post_call_initial.
	(init_deps): initialize in_post_call_group_p to not_post_call.
	
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.72
diff -p -r1.72 sched-deps.c
*** sched-deps.c	25 Mar 2004 00:58:57 -0000	1.72
--- sched-deps.c	28 May 2004 17:45:49 -0000
*************** sched_analyze_insn (struct deps *deps, r
*** 1145,1157 ****
        if (src_regno < FIRST_PSEUDO_REGISTER
  	  || dest_regno < FIRST_PSEUDO_REGISTER)
  	{
! 	  set_sched_group_p (insn);
  	  CANT_MOVE (insn) = 1;
  	}
        else
  	{
  	end_call_group:
! 	  deps->in_post_call_group_p = false;
  	}
      }
  }
--- 1145,1165 ----
        if (src_regno < FIRST_PSEUDO_REGISTER
  	  || dest_regno < FIRST_PSEUDO_REGISTER)
  	{
! 	  /* If we are inside a post-call group right at the start of the
! 	     scheduling region, we must not add a dependency.  */
! 	  if (deps->in_post_call_group_p == post_call_initial)
! 	    {
! 	      SCHED_GROUP_P (insn) = 1;
! 	      deps->in_post_call_group_p = post_call;
! 	    }
! 	  else
! 	    set_sched_group_p (insn);
  	  CANT_MOVE (insn) = 1;
  	}
        else
  	{
  	end_call_group:
! 	  deps->in_post_call_group_p = not_post_call;
  	}
      }
  }
*************** sched_analyze (struct deps *deps, rtx he
*** 1168,1173 ****
--- 1176,1213 ----
    if (current_sched_info->use_cselib)
      cselib_init (true);
  
+   /* Before reload, if the previous block ended in a call, show that
+      we are inside a post-call group, so as to keep the lifetimes of
+      hard registers correct.  */
+   if (! reload_completed)
+     {
+       insn = prev_nonnote_insn (head);
+       if (insn && GET_CODE (insn) != CODE_LABEL)
+ 	{
+ 	  if (insn && GET_CODE (insn) == CALL_INSN)
+ 	    deps->in_post_call_group_p = post_call_initial;
+ 	}
+       else if (insn)
+ 	{
+ 	  /* The new loop optimizer can insert jumps in strange places -
+              between a call and the insn that copies the return value.
+ 	     This is in itself harmless, but makes it harder here to
+ 	     recognize post-call groups.  */
+ 	  edge e;
+ 	  basic_block pred_bb;
+ 
+ 	  for (e = BLOCK_FOR_INSN (head)->pred; e; e = e->pred_next)
+ 	    {
+ 	      pred_bb = e->src;
+ 	      insn = BB_END(pred_bb);
+ 	      if (GET_CODE (insn) != JUMP_INSN)
+ 		continue;
+ 	      insn = prev_nonnote_insn (insn);
+ 	      if (insn && GET_CODE (insn) == CALL_INSN)
+ 		deps->in_post_call_group_p = post_call_initial;
+ 	    }
+ 	}
+     }
    for (insn = head;; insn = NEXT_INSN (insn))
      {
        rtx link, end_seq, r0, set;
*************** sched_analyze (struct deps *deps, rtx he
*** 1259,1265 ****
  	  /* Before reload, begin a post-call group, so as to keep the
  	     lifetimes of hard registers correct.  */
  	  if (! reload_completed)
! 	    deps->in_post_call_group_p = true;
  	}
  
        /* See comments on reemit_notes as to why we do this.
--- 1299,1305 ----
  	  /* Before reload, begin a post-call group, so as to keep the
  	     lifetimes of hard registers correct.  */
  	  if (! reload_completed)
! 	    deps->in_post_call_group_p = post_call;
  	}
  
        /* See comments on reemit_notes as to why we do this.
*************** init_deps (struct deps *deps)
*** 1420,1426 ****
    deps->last_pending_memory_flush = 0;
    deps->last_function_call = 0;
    deps->sched_before_next_call = 0;
!   deps->in_post_call_group_p = false;
    deps->libcall_block_tail_insn = 0;
  }
  
--- 1460,1466 ----
    deps->last_pending_memory_flush = 0;
    deps->last_function_call = 0;
    deps->sched_before_next_call = 0;
!   deps->in_post_call_group_p = not_post_call;
    deps->libcall_block_tail_insn = 0;
  }
  


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