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]

Remove some of NOTE_INSN_* notes


Hi,
this patch removes couple of unencesary INSN notes and infrastructure
surrounding them.
In particular:
 - LOOP_BEG/LOOP_END: never used in code anymore.
 - NOTE_INSN_REPERATED_LINE_NUMBER: Output only with -ftest-coverage for no
   good reasons since coverage was rewriten.
 - NOTE_INSN_EXPECTED_VALUE: Useless now when we do the prediction early and
   strip all builtin_expect now.

I've also dropped the requirement on builtin_expect for second opearnd to be
always a constant.  Since our SSA code can deal quite naturaly with simple
cases where you expect value to be variable, I think it is useless now
and I didn't found convenient place to glue that check in anyway.

Those was origianlly spearate patches, I've merged them together as
number of such a simple cleanups in my local queue clearly exceeds my
patch testing bandwidth, hope it is OK.  I've left out
NOTE_INSN_FUNCTION_END as that one needs some minimal care.

OK?

Bootstrapped/regtested i686-linux
:ADDPATCH RTL:

	* extended.texi (__builtin_expect): We no longer require second argument
	to be constant.
	* gengtype.c (adjust_field_rtx_def): Drop NOTE_INSN_EXPECTED_VALUE.
	* builtins.c (expand_builtin_expect): Simplify.
	(expand_builtin_expect_jump): Kill.
	* final.c (final_scan_insn): Do not skip the removed notes.
	* insn-notes.def (LOOP_BEG, LOOP_END, REPEATED_LINE_NUMBER,
	EXPECTED_VALUE): Remove.
	* dojump.c (do_jump): Do not care about __builtin_expect.
	* predict.c (expected_value_to_br_prob): Kill.
	* function.c (expand_function_end): Do not expand
	NOTE_INSN_REPEATED_LINE_NUMBER.
	* print-rtl.c (print_rtx): Do not pretty print the removed notes.
	* expect.c (sjlj_emit_function_enter): Emit directly branch probability.
	* cfgexpand.c (add_reg_br_prob_note): Export.
	* cfgcleanup.c (rest_of_handle_jump2): Do not call
	expected_value_to_br_prob.
	* cfglayout.c (duplicate_insn_chain): Do not deal with removed notes.
	* rtl.h (add_reg_br_prob_note): Declare.
Index: doc/extend.texi
===================================================================
*** doc/extend.texi	(revision 118649)
--- doc/extend.texi	(working copy)
*************** programmers are notoriously bad at predi
*** 5874,5883 ****
  actually perform.  However, there are applications in which this
  data is hard to collect.
  
! The return value is the value of @var{exp}, which should be an
! integral expression.  The value of @var{c} must be a compile-time
! constant.  The semantics of the built-in are that it is expected
! that @var{exp} == @var{c}.  For example:
  
  @smallexample
  if (__builtin_expect (x, 0))
--- 5874,5882 ----
  actually perform.  However, there are applications in which this
  data is hard to collect.
  
! The return value is the value of @var{exp}, which should be an integral
! expression.  The semantics of the built-in are that it is expected that
! @var{exp} == @var{c}.  For example:
  
  @smallexample
  if (__builtin_expect (x, 0))
Index: gengtype.c
===================================================================
*** gengtype.c	(revision 118649)
--- gengtype.c	(working copy)
*************** adjust_field_rtx_def (type_p t, options_
*** 519,525 ****
  	    note_flds = create_field (note_flds, tree_tp, "rt_tree");
  	    break;
  
- 	  case NOTE_INSN_EXPECTED_VALUE:
  	  case NOTE_INSN_VAR_LOCATION:
  	    note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
  	    break;
--- 519,524 ----
Index: final.c
===================================================================
*** final.c	(revision 118650)
--- final.c	(working copy)
*************** final_scan_insn (rtx insn, FILE *file, i
*** 1698,1705 ****
  	{
  	case NOTE_INSN_DELETED:
  	case NOTE_INSN_FUNCTION_END:
- 	case NOTE_INSN_REPEATED_LINE_NUMBER:
- 	case NOTE_INSN_EXPECTED_VALUE:
  	  break;
  
  	case NOTE_INSN_SWITCH_TEXT_SECTIONS:
--- 1698,1703 ----
Index: insn-notes.def
===================================================================
*** insn-notes.def	(revision 118649)
--- insn-notes.def	(working copy)
*************** INSN_NOTE (DELETED_LABEL)
*** 43,52 ****
  INSN_NOTE (BLOCK_BEG)
  INSN_NOTE (BLOCK_END)
  
- /* These mark the extremes of a loop.  */
- INSN_NOTE (LOOP_BEG)
- INSN_NOTE (LOOP_END)
- 
  /* This note indicates the start of the real body of the function,
     i.e. the point just after all of the parms have been moved into
     their homes, etc.  */
--- 43,48 ----
*************** INSN_NOTE (EPILOGUE_BEG)
*** 70,88 ****
  INSN_NOTE (EH_REGION_BEG)
  INSN_NOTE (EH_REGION_END)
  
- /* Generated whenever a duplicate line number note is output.
-    For example, one is output after the end of an inline function,
-    in order to prevent the line containing the inline call from
-    being counted twice in gcov.  */
- INSN_NOTE (REPEATED_LINE_NUMBER)
- 
  /* The location of a variable.  */
  INSN_NOTE (VAR_LOCATION)
  
- /* Record the expected value of a register at a location.  Uses
-    NOTE_EXPECTED_VALUE; stored as (eq (reg) (const_int)).  */
- INSN_NOTE (EXPECTED_VALUE)
- 
  /* Record the struct for the following basic block.  Uses
     NOTE_BASIC_BLOCK.  FIXME: Redundant with the basic block pointer
     now included in every insn.  */
--- 66,74 ----
Index: dojump.c
===================================================================
*** dojump.c	(revision 118649)
--- dojump.c	(working copy)
*************** do_jump (tree exp, rtx if_false_label, r
*** 551,587 ****
  	}
        break;
  
-       /* Special case:
-           __builtin_expect (<test>, 0)	and
-           __builtin_expect (<test>, 1)
- 
-          We need to do this here, so that <test> is not converted to a SCC
-          operation on machines that use condition code registers and COMPARE
-          like the PowerPC, and then the jump is done based on whether the SCC
-          operation produced a 1 or 0.  */
-     case CALL_EXPR:
-       /* Check for a built-in function.  */
-       {
- 	tree fndecl = get_callee_fndecl (exp);
- 	tree arglist = TREE_OPERAND (exp, 1);
- 
- 	if (fndecl
- 	    && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
- 	    && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
- 	    && arglist != NULL_TREE
- 	    && TREE_CHAIN (arglist) != NULL_TREE)
- 	  {
- 	    rtx seq = expand_builtin_expect_jump (exp, if_false_label,
- 						  if_true_label);
- 
- 	    if (seq != NULL_RTX)
- 	      {
- 		emit_insn (seq);
- 		return;
- 	      }
- 	  }
-       }
-  
        /* Fall through and generate the normal code.  */
      default:
      normal:
--- 551,556 ----
Index: predict.c
===================================================================
*** predict.c	(revision 118649)
--- predict.c	(working copy)
*************** tree_estimate_probability (void)
*** 1376,1454 ****
    return 0;
  }
  
- /* __builtin_expect dropped tokens into the insn stream describing expected
-    values of registers.  Generate branch probabilities based off these
-    values.  */
- 
- void
- expected_value_to_br_prob (void)
- {
-   rtx insn, cond, ev = NULL_RTX, ev_reg = NULL_RTX;
- 
-   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
-     {
-       switch (GET_CODE (insn))
- 	{
- 	case NOTE:
- 	  /* Look for expected value notes.  */
- 	  if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE)
- 	    {
- 	      ev = NOTE_EXPECTED_VALUE (insn);
- 	      ev_reg = XEXP (ev, 0);
- 	      delete_insn (insn);
- 	    }
- 	  continue;
- 
- 	case CODE_LABEL:
- 	  /* Never propagate across labels.  */
- 	  ev = NULL_RTX;
- 	  continue;
- 
- 	case JUMP_INSN:
- 	  /* Look for simple conditional branches.  If we haven't got an
- 	     expected value yet, no point going further.  */
- 	  if (!JUMP_P (insn) || ev == NULL_RTX
- 	      || ! any_condjump_p (insn))
- 	    continue;
- 	  break;
- 
- 	default:
- 	  /* Look for insns that clobber the EV register.  */
- 	  if (ev && reg_set_p (ev_reg, insn))
- 	    ev = NULL_RTX;
- 	  continue;
- 	}
- 
-       /* Collect the branch condition, hopefully relative to EV_REG.  */
-       /* ???  At present we'll miss things like
- 		(expected_value (eq r70 0))
- 		(set r71 -1)
- 		(set r80 (lt r70 r71))
- 		(set pc (if_then_else (ne r80 0) ...))
- 	 as canonicalize_condition will render this to us as
- 		(lt r70, r71)
- 	 Could use cselib to try and reduce this further.  */
-       cond = XEXP (SET_SRC (pc_set (insn)), 0);
-       cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg,
- 				     false, false);
-       if (! cond || XEXP (cond, 0) != ev_reg
- 	  || GET_CODE (XEXP (cond, 1)) != CONST_INT)
- 	continue;
- 
-       /* Substitute and simplify.  Given that the expression we're
- 	 building involves two constants, we should wind up with either
- 	 true or false.  */
-       cond = gen_rtx_fmt_ee (GET_CODE (cond), VOIDmode,
- 			     XEXP (ev, 1), XEXP (cond, 1));
-       cond = simplify_rtx (cond);
- 
-       /* Turn the condition into a scaled branch probability.  */
-       gcc_assert (cond == const_true_rtx || cond == const0_rtx);
-       predict_insn_def (insn, PRED_BUILTIN_EXPECT,
- 		        cond == const_true_rtx ? TAKEN : NOT_TAKEN);
-     }
- }
- 
  /* Check whether this is the last basic block of function.  Commonly
     there is one extra common cleanup block.  */
  static bool
--- 1376,1381 ----
Index: function.c
===================================================================
*** function.c	(revision 118649)
--- function.c	(working copy)
*************** expand_function_end (void)
*** 4340,4353 ****
       without returning a value.  */
    emit_note (NOTE_INSN_FUNCTION_END);
  
-   /* Must mark the last line number note in the function, so that the test
-      coverage code can avoid counting the last line twice.  This just tells
-      the code to ignore the immediately following line note, since there
-      already exists a copy of this note somewhere above.  This line number
-      note is still needed for debugging though, so we can't delete it.  */
-   if (flag_test_coverage)
-     emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
- 
    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
    force_next_line_note ();
--- 4340,4345 ----
Index: print-rtl.c
===================================================================
*** print-rtl.c	(revision 118649)
--- print-rtl.c	(working copy)
*************** print_rtx (rtx in_rtx)
*** 299,312 ****
  		  break;
  	        }
  
- 	      case NOTE_INSN_EXPECTED_VALUE:
- 		indent += 2;
- 		if (!sawclose)
- 		  fprintf (outfile, " ");
- 		print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
- 		indent -= 2;
- 		break;
- 
  	      case NOTE_INSN_DELETED_LABEL:
  		{
  		  const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
--- 299,304 ----
Index: except.c
===================================================================
*** except.c	(revision 118649)
--- except.c	(working copy)
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 1875,1885 ****
  				 plus_constant (XEXP (fc, 0),
  						sjlj_fc_jbuf_ofs), Pmode);
  
-     note = emit_note (NOTE_INSN_EXPECTED_VALUE);
-     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
- 
      emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
  			     TYPE_MODE (integer_type_node), 0, dispatch_label);
    }
  #else
    expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
--- 1875,1883 ----
  				 plus_constant (XEXP (fc, 0),
  						sjlj_fc_jbuf_ofs), Pmode);
  
      emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
  			     TYPE_MODE (integer_type_node), 0, dispatch_label);
+     add_reg_br_prob_note (get_insns (), REG_BR_PROB_BASE/100);
    }
  #else
    expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
Index: cfgexpand.c
===================================================================
*** cfgexpand.c	(revision 118649)
--- cfgexpand.c	(working copy)
*************** Boston, MA 02110-1301, USA.  */
*** 45,51 ****
     ??? We really ought to pass the probability down to RTL expanders and let it
     re-distribute it when the conditional expands into multiple conditionals.
     This is however difficult to do.  */
! static void
  add_reg_br_prob_note (rtx last, int probability)
  {
    if (profile_status == PROFILE_ABSENT)
--- 45,51 ----
     ??? We really ought to pass the probability down to RTL expanders and let it
     re-distribute it when the conditional expands into multiple conditionals.
     This is however difficult to do.  */
! void
  add_reg_br_prob_note (rtx last, int probability)
  {
    if (profile_status == PROFILE_ABSENT)
Index: cfgcleanup.c
===================================================================
*** cfgcleanup.c	(revision 118649)
--- cfgcleanup.c	(working copy)
*************** struct tree_opt_pass pass_jump =
*** 2300,2310 ****
  static unsigned int
  rest_of_handle_jump2 (void)
  {
-   /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB.  Do this
-      before jump optimization switches branch directions.  */
-   if (flag_guess_branch_prob)
-     expected_value_to_br_prob ();
- 
    delete_trivially_dead_insns (get_insns (), max_reg_num ());
    reg_scan (get_insns (), max_reg_num ());
    if (dump_file)
--- 2300,2305 ----
Index: cfglayout.c
===================================================================
*** cfglayout.c	(revision 118650)
--- cfglayout.c	(working copy)
*************** duplicate_insn_chain (rtx from, rtx to)
*** 997,1003 ****
  	    case NOTE_INSN_BASIC_BLOCK:
  	      break;
  
- 	    case NOTE_INSN_REPEATED_LINE_NUMBER:
  	    case NOTE_INSN_SWITCH_TEXT_SECTIONS:
  	      emit_note_copy (insn);
  	      break;
--- 997,1002 ----
Index: rtl.h
===================================================================
*** rtl.h	(revision 118649)
--- rtl.h	(working copy)
*************** extern GTY(()) rtx stack_limit_rtx;
*** 2251,2256 ****
--- 2251,2258 ----
  /* In predict.c */
  extern void invert_br_probabilities (rtx);
  extern bool expensive_function_p (int);
+ /* In cfgexpand.c */
+ extern void add_reg_br_prob_note (rtx last, int probability);
  /* In tracer.c */
  extern void tracer (unsigned int);
  
Index: builtins.c
===================================================================
--- builtins.c	(revision 118664)
+++ builtins.c	(working copy)
@@ -4693,15 +4693,14 @@ expand_builtin_fputs (tree arglist, rtx 
   return 0;
 }
 
-/* Expand a call to __builtin_expect.  We return our argument and emit a
-   NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
-   a non-jump context.  */
+/* Expand a call to __builtin_expect.  We just return our argument 
+   as the builtin_expect semantic should've been already executed by
+   tree branch prediction pass. */
 
 static rtx
 expand_builtin_expect (tree arglist, rtx target)
 {
   tree exp, c;
-  rtx note, rtx_c;
 
   if (arglist == NULL_TREE
       || TREE_CHAIN (arglist) == NULL_TREE)
@@ -4709,149 +4708,12 @@ expand_builtin_expect (tree arglist, rtx
   exp = TREE_VALUE (arglist);
   c = TREE_VALUE (TREE_CHAIN (arglist));
 
-  if (TREE_CODE (c) != INTEGER_CST)
-    {
-      error ("second argument to %<__builtin_expect%> must be a constant");
-      c = integer_zero_node;
-    }
-
   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
-
-  /* Don't bother with expected value notes for integral constants.  */
-  if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
-    {
-      /* We do need to force this into a register so that we can be
-	 moderately sure to be able to correctly interpret the branch
-	 condition later.  */
-      target = force_reg (GET_MODE (target), target);
-
-      rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
-
-      note = emit_note (NOTE_INSN_EXPECTED_VALUE);
-      NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
-    }
-
+  /* When guessing was done, the hints should be already stripped away.  */
+  gcc_assert (!flag_guess_branch_prob);
   return target;
 }
 
-/* Like expand_builtin_expect, except do this in a jump context.  This is
-   called from do_jump if the conditional is a __builtin_expect.  Return either
-   a list of insns to emit the jump or NULL if we cannot optimize
-   __builtin_expect.  We need to optimize this at jump time so that machines
-   like the PowerPC don't turn the test into a SCC operation, and then jump
-   based on the test being 0/1.  */
-
-rtx
-expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
-{
-  tree arglist = TREE_OPERAND (exp, 1);
-  tree arg0 = TREE_VALUE (arglist);
-  tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
-  rtx ret = NULL_RTX;
-
-  /* Only handle __builtin_expect (test, 0) and
-     __builtin_expect (test, 1).  */
-  if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
-      && (integer_zerop (arg1) || integer_onep (arg1)))
-    {
-      rtx insn, drop_through_label, temp;
-
-      /* Expand the jump insns.  */
-      start_sequence ();
-      do_jump (arg0, if_false_label, if_true_label);
-      ret = get_insns ();
-
-      drop_through_label = get_last_insn ();
-      if (drop_through_label && NOTE_P (drop_through_label))
-	drop_through_label = prev_nonnote_insn (drop_through_label);
-      if (drop_through_label && !LABEL_P (drop_through_label))
-	drop_through_label = NULL_RTX;
-      end_sequence ();
-
-      if (! if_true_label)
-	if_true_label = drop_through_label;
-      if (! if_false_label)
-	if_false_label = drop_through_label;
-
-      /* Go through and add the expect's to each of the conditional jumps.  */
-      insn = ret;
-      while (insn != NULL_RTX)
-	{
-	  rtx next = NEXT_INSN (insn);
-
-	  if (JUMP_P (insn) && any_condjump_p (insn))
-	    {
-	      rtx ifelse = SET_SRC (pc_set (insn));
-	      rtx then_dest = XEXP (ifelse, 1);
-	      rtx else_dest = XEXP (ifelse, 2);
-	      int taken = -1;
-
-	      /* First check if we recognize any of the labels.  */
-	      if (GET_CODE (then_dest) == LABEL_REF
-		  && XEXP (then_dest, 0) == if_true_label)
-		taken = 1;
-	      else if (GET_CODE (then_dest) == LABEL_REF
-		       && XEXP (then_dest, 0) == if_false_label)
-		taken = 0;
-	      else if (GET_CODE (else_dest) == LABEL_REF
-		       && XEXP (else_dest, 0) == if_false_label)
-		taken = 1;
-	      else if (GET_CODE (else_dest) == LABEL_REF
-		       && XEXP (else_dest, 0) == if_true_label)
-		taken = 0;
-	      /* Otherwise check where we drop through.  */
-	      else if (else_dest == pc_rtx)
-		{
-		  if (next && NOTE_P (next))
-		    next = next_nonnote_insn (next);
-
-		  if (next && JUMP_P (next)
-		      && any_uncondjump_p (next))
-		    temp = XEXP (SET_SRC (pc_set (next)), 0);
-		  else
-		    temp = next;
-
-		  /* TEMP is either a CODE_LABEL, NULL_RTX or something
-		     else that can't possibly match either target label.  */
-		  if (temp == if_false_label)
-		    taken = 1;
-		  else if (temp == if_true_label)
-		    taken = 0;
-		}
-	      else if (then_dest == pc_rtx)
-		{
-		  if (next && NOTE_P (next))
-		    next = next_nonnote_insn (next);
-
-		  if (next && JUMP_P (next)
-		      && any_uncondjump_p (next))
-		    temp = XEXP (SET_SRC (pc_set (next)), 0);
-		  else
-		    temp = next;
-
-		  if (temp == if_false_label)
-		    taken = 0;
-		  else if (temp == if_true_label)
-		    taken = 1;
-		}
-
-	      if (taken != -1)
-		{
-		  /* If the test is expected to fail, reverse the
-		     probabilities.  */
-		  if (integer_zerop (arg1))
-		    taken = 1 - taken;
-		  predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
-		}
-	    }
-
-	  insn = next;
-	}
-    }
-
-  return ret;
-}
-
 void
 expand_builtin_trap (void)
 {


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