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]

cleanup CALL_PLACEHOLDER


Hi,

CALL_PLACEHOLDERs are now obsolete since we expand
tail calls properly from calls.c.
Bootstrapped and tested on amd64 and i686.  OK?

Gr.
Steven

	* basic-block.c (tail_recursion_label_list): Don't declare.
	(CLEANUP_PRE_SIBCALL): Remove.  Renumber the other CLEANUP_*
	accordingly.
	* cfgbuild.c (find_label_refs): Remove.
	(find_basic_blocks_1): Don't handle CALL_PLACEHOLDER insns.
	* cfgcleanup.c (tail_recursion_label_p): Remove.
	(merge_blocks_move): Do not check for tail recursion.
	(try_optimize_cfg): Likewise.
	(cleanup_cfg): Never handle CLEANUP_PRE_SIBCALL.
	* cfgrtl.c (tail_recursion_label_list): Remove.
	* except.c (remove_unreachable_regions): Don't handle
	CALL_PLACEHOLDER insns.
	(convert_from_eh_region_ranges_1, can_throw_internal,
	can_throw_external): Likewise.
	* function.c (free_after_compilation): Don't clear
	x_tail_recursion_label.
	(fixup_var_refs_insns): Don't handle CALL_PLACEHOLDER insns.
	(identify_blocks_1): Don't recurse for CALL_PLACEHOLDER insns.
	(reorder_blocks_1): Likewise.
	* function.h (struct function): Remove x_tail_recursion_label
	member.  Don't define tail_recursion_label.
	* jump.c (mark_all_labels): Don't handle CALL_PLACEHOLDER insns.
	* print-rtl.c (print_rtx): Likewise.
	* rtl.def (CALL_PLACEHOLDER): Remove.
	* rtl.h (sibcall_use_t): Remove enum.
	(optimize_sibling_and_tail_recursive_calls,
	replace_call_placeholder): Remove function prototypes.
	* stmt.c (tail_recursion_args): Remove.
	(optimize_tail_recursion): Remove.
	(expand_return): Don't check for possible tail recursion.
	* tree.h (optimize_tail_recursion): Remove prototype.

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.195
diff -c -3 -p -r1.195 basic-block.h
*** basic-block.h	13 May 2004 06:39:26 -0000	1.195
--- basic-block.h	14 May 2004 15:48:43 -0000
*************** extern regset regs_live_at_setjmp;
*** 367,373 ****
  /* Special labels found during CFG build.  */
  
  extern GTY(()) rtx label_value_list;
- extern GTY(()) rtx tail_recursion_label_list;
  
  extern struct obstack flow_obstack;
  
--- 367,372 ----
*************** enum update_life_extent
*** 554,569 ****
  #define CLEANUP_CROSSJUMP	2	/* Do crossjumping.  */
  #define CLEANUP_POST_REGSTACK	4	/* We run after reg-stack and need
  					   to care REG_DEAD notes.  */
! #define CLEANUP_PRE_SIBCALL	8	/* Do not get confused by code hidden
! 					   inside call_placeholders..  */
! #define CLEANUP_PRE_LOOP	16	/* Take care to preserve syntactic loop
  					   notes.  */
! #define CLEANUP_UPDATE_LIFE	32	/* Keep life information up to date.  */
! #define CLEANUP_THREADING	64	/* Do jump threading.  */
! #define CLEANUP_NO_INSN_DEL	128	/* Do not try to delete trivially dead
  					   insns.  */
! #define CLEANUP_CFGLAYOUT	256	/* Do cleanup in cfglayout mode.  */
! #define CLEANUP_LOG_LINKS	512	/* Update log links.  */
  extern void life_analysis (rtx, FILE *, int);
  extern int update_life_info (sbitmap, enum update_life_extent, int);
  extern int update_life_info_in_dirty_blocks (enum update_life_extent, int);
--- 553,566 ----
  #define CLEANUP_CROSSJUMP	2	/* Do crossjumping.  */
  #define CLEANUP_POST_REGSTACK	4	/* We run after reg-stack and need
  					   to care REG_DEAD notes.  */
! #define CLEANUP_PRE_LOOP	8	/* Take care to preserve syntactic loop
  					   notes.  */
! #define CLEANUP_UPDATE_LIFE	16	/* Keep life information up to date.  */
! #define CLEANUP_THREADING	32	/* Do jump threading.  */
! #define CLEANUP_NO_INSN_DEL	64	/* Do not try to delete trivially dead
  					   insns.  */
! #define CLEANUP_CFGLAYOUT	128	/* Do cleanup in cfglayout mode.  */
! #define CLEANUP_LOG_LINKS	256	/* Update log links.  */
  extern void life_analysis (rtx, FILE *, int);
  extern int update_life_info (sbitmap, enum update_life_extent, int);
  extern int update_life_info_in_dirty_blocks (enum update_life_extent, int);
Index: cfgbuild.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgbuild.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 cfgbuild.c
*** cfgbuild.c	13 May 2004 06:39:32 -0000	1.45
--- cfgbuild.c	14 May 2004 15:48:45 -0000
*************** Software Foundation, 59 Temple Place - S
*** 50,56 ****
  
  static int count_basic_blocks (rtx);
  static void find_basic_blocks_1 (rtx);
- static rtx find_label_refs (rtx, rtx);
  static void make_edges (rtx, basic_block, basic_block, int);
  static void make_label_edge (sbitmap *, basic_block, rtx, int);
  static void find_bb_boundaries (basic_block);
--- 50,55 ----
*************** count_basic_blocks (rtx f)
*** 169,219 ****
  
    return count;
  }
- 
- /* Scan a list of insns for labels referred to other than by jumps.
-    This is used to scan the alternatives of a call placeholder.  */
- 
- static rtx
- find_label_refs (rtx f, rtx lvl)
- {
-   rtx insn;
- 
-   for (insn = f; insn; insn = NEXT_INSN (insn))
-     if (INSN_P (insn) && GET_CODE (insn) != JUMP_INSN)
-       {
- 	rtx note;
- 
- 	/* Make a list of all labels referred to other than by jumps
- 	   (which just don't have the REG_LABEL notes).
- 
- 	   Make a special exception for labels followed by an ADDR*VEC,
- 	   as this would be a part of the tablejump setup code.
- 
- 	   Make a special exception to registers loaded with label
- 	   values just before jump insns that use them.  */
- 
- 	for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- 	  if (REG_NOTE_KIND (note) == REG_LABEL)
- 	    {
- 	      rtx lab = XEXP (note, 0), next;
- 
- 	      if ((next = next_nonnote_insn (lab)) != NULL
- 		  && GET_CODE (next) == JUMP_INSN
- 		  && (GET_CODE (PATTERN (next)) == ADDR_VEC
- 		      || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
- 		;
- 	      else if (GET_CODE (lab) == NOTE)
- 		;
- 	      else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
- 		       && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
- 		;
- 	      else
- 		lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
- 	    }
-       }
- 
-   return lvl;
- }
  
  /* Create an edge between two basic blocks.  FLAGS are auxiliary information
     about the edge that is accumulated between calls.  */
--- 168,173 ----
*************** find_basic_blocks_1 (rtx f)
*** 458,464 ****
    rtx insn, next;
    rtx bb_note = NULL_RTX;
    rtx lvl = NULL_RTX;
-   rtx trll = NULL_RTX;
    rtx head = NULL_RTX;
    rtx end = NULL_RTX;
    basic_block prev = ENTRY_BLOCK_PTR;
--- 412,417 ----
*************** find_basic_blocks_1 (rtx f)
*** 519,541 ****
  
  	case CODE_LABEL:
  	case JUMP_INSN:
  	case INSN:
  	case BARRIER:
  	  break;
  
- 	case CALL_INSN:
- 	  if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- 	    {
- 	      /* Scan each of the alternatives for label refs.  */
- 	      lvl = find_label_refs (XEXP (PATTERN (insn), 0), lvl);
- 	      lvl = find_label_refs (XEXP (PATTERN (insn), 1), lvl);
- 	      lvl = find_label_refs (XEXP (PATTERN (insn), 2), lvl);
- 	      /* Record its tail recursion label, if any.  */
- 	      if (XEXP (PATTERN (insn), 3) != NULL_RTX)
- 		trll = alloc_EXPR_LIST (0, XEXP (PATTERN (insn), 3), trll);
- 	    }
- 	  break;
- 
  	default:
  	  abort ();
  	}
--- 472,482 ----
  
  	case CODE_LABEL:
  	case JUMP_INSN:
+ 	case CALL_INSN:
  	case INSN:
  	case BARRIER:
  	  break;
  
  	default:
  	  abort ();
  	}
*************** find_basic_blocks_1 (rtx f)
*** 582,588 ****
      abort ();
  
    label_value_list = lvl;
-   tail_recursion_label_list = trll;
    clear_aux_for_blocks ();
  }
  
--- 523,528 ----
Index: cfgcleanup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v
retrieving revision 1.113
diff -c -3 -p -r1.113 cfgcleanup.c
*** cfgcleanup.c	13 May 2004 06:39:32 -0000	1.113
--- cfgcleanup.c	14 May 2004 15:48:46 -0000
*************** static bool outgoing_edges_match (int, b
*** 78,84 ****
  static int flow_find_cross_jump (int, basic_block, basic_block, rtx *, rtx *);
  static bool insns_match_p (int, rtx, rtx);
  
- static bool tail_recursion_label_p (rtx);
  static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
  static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
  static bool try_optimize_cfg (int);
--- 78,83 ----
*************** try_forward_edges (int mode, basic_block
*** 670,688 ****
    return changed;
  }
  
- /* Return true if LABEL is used for tail recursion.  */
- 
- static bool
- tail_recursion_label_p (rtx label)
- {
-   rtx x;
- 
-   for (x = tail_recursion_label_list; x; x = XEXP (x, 1))
-     if (label == XEXP (x, 0))
-       return true;
- 
-   return false;
- }
  
  /* Blocks A and B are to be merged into a single block.  A has no incoming
     fallthru edge, so it can be moved before B without adding or modifying
--- 669,674 ----
*************** static basic_block
*** 809,822 ****
  merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
  {
    basic_block next;
-   /* If C has a tail recursion label, do not merge.  There is no
-      edge recorded from the call_placeholder back to this label, as
-      that would make optimize_sibling_and_tail_recursive_calls more
-      complex for no gain.  */
-   if ((mode & CLEANUP_PRE_SIBCALL)
-       && GET_CODE (BB_HEAD (c)) == CODE_LABEL
-       && tail_recursion_label_p (BB_HEAD (c)))
-     return NULL;
  
    /* If we are partitioning hot/cold basic blocks, we don't want to
       mess up unconditional or indirect jumps that cross between hot
--- 795,800 ----
*************** try_optimize_cfg (int mode)
*** 1852,1866 ****
  		  b = c;
  		}
  
! 	      /* Remove code labels no longer used.  Don't do this
! 		 before CALL_PLACEHOLDER is removed, as some branches
! 		 may be hidden within.  */
  	      if (b->pred->pred_next == NULL
  		  && (b->pred->flags & EDGE_FALLTHRU)
  		  && !(b->pred->flags & EDGE_COMPLEX)
  		  && GET_CODE (BB_HEAD (b)) == CODE_LABEL
- 		  && (!(mode & CLEANUP_PRE_SIBCALL)
- 		      || !tail_recursion_label_p (BB_HEAD (b)))
  		  /* If the previous block ends with a branch to this
  		     block, we can't delete the label.  Normally this
  		     is a condjump that is yet to be simplified, but
--- 1830,1840 ----
  		  b = c;
  		}
  
! 	      /* Remove code labels no longer used.  */
  	      if (b->pred->pred_next == NULL
  		  && (b->pred->flags & EDGE_FALLTHRU)
  		  && !(b->pred->flags & EDGE_COMPLEX)
  		  && GET_CODE (BB_HEAD (b)) == CODE_LABEL
  		  /* If the previous block ends with a branch to this
  		     block, we can't delete the label.  Normally this
  		     is a condjump that is yet to be simplified, but
*************** cleanup_cfg (int mode)
*** 2075,2082 ****
        changed = true;
        /* We've possibly created trivially dead code.  Cleanup it right
  	 now to introduce more opportunities for try_optimize_cfg.  */
!       if (!(mode & (CLEANUP_NO_INSN_DEL
! 		    | CLEANUP_UPDATE_LIFE | CLEANUP_PRE_SIBCALL))
  	  && !reload_completed)
  	delete_trivially_dead_insns (get_insns(), max_reg_num ());
      }
--- 2049,2055 ----
        changed = true;
        /* We've possibly created trivially dead code.  Cleanup it right
  	 now to introduce more opportunities for try_optimize_cfg.  */
!       if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_UPDATE_LIFE))
  	  && !reload_completed)
  	delete_trivially_dead_insns (get_insns(), max_reg_num ());
      }
*************** cleanup_cfg (int mode)
*** 2099,2105 ****
  						    ? PROP_LOG_LINKS : 0)))
  	    break;
  	}
!       else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
  	       && (mode & CLEANUP_EXPENSIVE)
  	       && !reload_completed)
  	{
--- 2072,2078 ----
  						    ? PROP_LOG_LINKS : 0)))
  	    break;
  	}
!       else if (!(mode & CLEANUP_NO_INSN_DEL)
  	       && (mode & CLEANUP_EXPENSIVE)
  	       && !reload_completed)
  	{
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.118
diff -c -3 -p -r1.118 cfgrtl.c
*** cfgrtl.c	13 May 2004 06:39:32 -0000	1.118
--- cfgrtl.c	14 May 2004 15:48:46 -0000
*************** Software Foundation, 59 Temple Place - S
*** 62,68 ****
  /* ??? Should probably be using LABEL_NUSES instead.  It would take a
     bit of surgery to be able to use or co-opt the routines in jump.  */
  rtx label_value_list;
- rtx tail_recursion_label_list;
  
  static int can_delete_note_p (rtx);
  static int can_delete_label_p (rtx);
--- 62,67 ----
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.268
diff -c -3 -p -r1.268 except.c
*** except.c	13 May 2004 06:39:38 -0000	1.268
--- except.c	14 May 2004 15:48:51 -0000
*************** remove_unreachable_regions (rtx insns)
*** 1157,1174 ****
      }
  
    for (insn = insns; insn; insn = NEXT_INSN (insn))
!     {
!       reachable[uid_region_num[INSN_UID (insn)]] = true;
! 
!       if (GET_CODE (insn) == CALL_INSN
! 	  && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
! 	for (i = 0; i < 3; i++)
! 	  {
! 	    rtx sub = XEXP (PATTERN (insn), i);
! 	    for (; sub ; sub = NEXT_INSN (sub))
! 	      reachable[uid_region_num[INSN_UID (sub)]] = true;
! 	  }
!     }
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
--- 1157,1163 ----
      }
  
    for (insn = insns; insn; insn = NEXT_INSN (insn))
!     reachable[uid_region_num[INSN_UID (insn)]] = true;
  
    for (i = cfun->eh->last_region_number; i > 0; --i)
      {
*************** convert_from_eh_region_ranges_1 (rtx *pi
*** 1259,1266 ****
  	      else
  		cur = *--sp;
  
- 	      /* Removing the first insn of a CALL_PLACEHOLDER sequence
- 		 requires extra care to adjust sequence start.  */
  	      if (insn == *pinsns)
  		*pinsns = next;
  	      remove_insn (insn);
--- 1248,1253 ----
*************** convert_from_eh_region_ranges_1 (rtx *pi
*** 1285,1301 ****
  	      REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
  						  REG_NOTES (insn));
  	    }
- 
- 	  if (GET_CODE (insn) == CALL_INSN
- 	      && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- 	    {
- 	      convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 0),
- 					       sp, cur);
- 	      convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 1),
- 					       sp, cur);
- 	      convert_from_eh_region_ranges_1 (&XEXP (PATTERN (insn), 2),
- 					       sp, cur);
- 	    }
  	}
      }
  
--- 1272,1277 ----
*************** can_throw_internal (rtx insn)
*** 3131,3150 ****
        && GET_CODE (PATTERN (insn)) == SEQUENCE)
      insn = XVECEXP (PATTERN (insn), 0, 0);
  
-   if (GET_CODE (insn) == CALL_INSN
-       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-     {
-       int i;
-       for (i = 0; i < 3; ++i)
- 	{
- 	  rtx sub = XEXP (PATTERN (insn), i);
- 	  for (; sub ; sub = NEXT_INSN (sub))
- 	    if (can_throw_internal (sub))
- 	      return true;
- 	}
-       return false;
-     }
- 
    /* Every insn that might throw has an EH_REGION note.  */
    note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    if (!note || INTVAL (XEXP (note, 0)) <= 0)
--- 3107,3112 ----
*************** can_throw_external (rtx insn)
*** 3191,3210 ****
    if (GET_CODE (insn) == INSN
        && GET_CODE (PATTERN (insn)) == SEQUENCE)
      insn = XVECEXP (PATTERN (insn), 0, 0);
- 
-   if (GET_CODE (insn) == CALL_INSN
-       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
-     {
-       int i;
-       for (i = 0; i < 3; ++i)
- 	{
- 	  rtx sub = XEXP (PATTERN (insn), i);
- 	  for (; sub ; sub = NEXT_INSN (sub))
- 	    if (can_throw_external (sub))
- 	      return true;
- 	}
-       return false;
-     }
  
    note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
    if (!note)
--- 3153,3158 ----
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.516
diff -c -3 -p -r1.516 function.c
*** function.c	13 May 2004 06:39:39 -0000	1.516
--- function.c	14 May 2004 15:48:55 -0000
*************** free_after_compilation (struct function 
*** 440,446 ****
    f->x_save_expr_regs = NULL;
    f->x_stack_slot_list = NULL;
    f->x_rtl_expr_chain = NULL;
-   f->x_tail_recursion_label = NULL;
    f->x_tail_recursion_reentry = NULL;
    f->x_arg_pointer_save_area = NULL;
    f->x_parm_birth_insn = NULL;
--- 440,445 ----
*************** fixup_var_refs_insns (rtx insn, rtx var,
*** 1588,1619 ****
           pointer now.  */
        rtx next = NEXT_INSN (insn);
  
!       /* CALL_PLACEHOLDERs are special; we have to switch into each of
! 	 the three sequences they (potentially) contain, and process
! 	 them recursively.  The CALL_INSN itself is not interesting.  */
! 
!       if (GET_CODE (insn) == CALL_INSN
! 	  && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
! 	{
! 	  int i;
! 
! 	  /* Look at the Normal call, sibling call and tail recursion
! 	     sequences attached to the CALL_PLACEHOLDER.  */
! 	  for (i = 0; i < 3; i++)
! 	    {
! 	      rtx seq = XEXP (PATTERN (insn), i);
! 	      if (seq)
! 		{
! 		  push_to_sequence (seq);
! 		  fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0,
! 					may_share);
! 		  XEXP (PATTERN (insn), i) = get_insns ();
! 		  end_sequence ();
! 		}
! 	    }
! 	}
! 
!       else if (INSN_P (insn))
  	fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel,
  			     may_share);
  
--- 1587,1593 ----
           pointer now.  */
        rtx next = NEXT_INSN (insn);
  
!       if (INSN_P (insn))
  	fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel,
  			     may_share);
  
*************** fixup_var_refs_insns (rtx insn, rtx var,
*** 1622,1632 ****
  }
  
  /* Look up the insns which reference VAR in HT and fix them up.  Other
!    arguments are the same as fixup_var_refs_insns.
! 
!    N.B. No need for special processing of CALL_PLACEHOLDERs here,
!    because the hash table will point straight to the interesting insn
!    (inside the CALL_PLACEHOLDER).  */
  
  static void
  fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_mode,
--- 1596,1602 ----
  }
  
  /* Look up the insns which reference VAR in HT and fix them up.  Other
!    arguments are the same as fixup_var_refs_insns.  */
  
  static void
  fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_mode,
*************** identify_blocks (void)
*** 5808,5814 ****
  }
  
  /* Subroutine of identify_blocks.  Do the block substitution on the
!    insn chain beginning with INSNS.  Recurse for CALL_PLACEHOLDER chains.
  
     BLOCK_STACK is pushed and popped for each BLOCK_BEGIN/BLOCK_END pair.
     BLOCK_VECTOR is incremented for each block seen.  */
--- 5778,5784 ----
  }
  
  /* Subroutine of identify_blocks.  Do the block substitution on the
!    insn chain beginning with INSNS.
  
     BLOCK_STACK is pushed and popped for each BLOCK_BEGIN/BLOCK_END pair.
     BLOCK_VECTOR is incremented for each block seen.  */
*************** identify_blocks_1 (rtx insns, tree *bloc
*** 5847,5866 ****
  	      NOTE_BLOCK (insn) = *--block_stack;
  	    }
  	}
-       else if (GET_CODE (insn) == CALL_INSN
- 	       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- 	{
- 	  rtx cp = PATTERN (insn);
- 
- 	  block_vector = identify_blocks_1 (XEXP (cp, 0), block_vector,
- 					    end_block_vector, block_stack);
- 	  if (XEXP (cp, 1))
- 	    block_vector = identify_blocks_1 (XEXP (cp, 1), block_vector,
- 					      end_block_vector, block_stack);
- 	  if (XEXP (cp, 2))
- 	    block_vector = identify_blocks_1 (XEXP (cp, 2), block_vector,
- 					      end_block_vector, block_stack);
- 	}
      }
  
    /* If there are more NOTE_INSN_BLOCK_BEGINs than NOTE_INSN_BLOCK_ENDs,
--- 5817,5822 ----
*************** reorder_blocks_1 (rtx insns, tree curren
*** 5970,5985 ****
  		= blocks_nreverse (BLOCK_SUBBLOCKS (current_block));
  	      current_block = BLOCK_SUPERCONTEXT (current_block);
  	    }
- 	}
-       else if (GET_CODE (insn) == CALL_INSN
- 	       && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- 	{
- 	  rtx cp = PATTERN (insn);
- 	  reorder_blocks_1 (XEXP (cp, 0), current_block, p_block_stack);
- 	  if (XEXP (cp, 1))
- 	    reorder_blocks_1 (XEXP (cp, 1), current_block, p_block_stack);
- 	  if (XEXP (cp, 2))
- 	    reorder_blocks_1 (XEXP (cp, 2), current_block, p_block_stack);
  	}
      }
  }
--- 5926,5931 ----
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.114
diff -c -3 -p -r1.114 function.h
*** function.h	13 May 2004 06:39:40 -0000	1.114
--- function.h	14 May 2004 15:48:55 -0000
*************** struct function GTY(())
*** 278,287 ****
    /* Chain of all RTL_EXPRs that have insns in them.  */
    tree x_rtl_expr_chain;
  
-   /* Label to jump back to for tail recursion, or 0 if we have
-      not yet needed one for this function.  */
-   rtx x_tail_recursion_label;
- 
    /* Place after which to insert the tail_recursion_label if we need one.  */
    rtx x_tail_recursion_reentry;
  
--- 278,283 ----
*************** extern int trampolines_created;
*** 557,563 ****
  #define stack_slot_list (cfun->x_stack_slot_list)
  #define parm_birth_insn (cfun->x_parm_birth_insn)
  #define frame_offset (cfun->x_frame_offset)
- #define tail_recursion_label (cfun->x_tail_recursion_label)
  #define tail_recursion_reentry (cfun->x_tail_recursion_reentry)
  #define arg_pointer_save_area (cfun->x_arg_pointer_save_area)
  #define rtl_expr_chain (cfun->x_rtl_expr_chain)
--- 553,558 ----
Index: jump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/jump.c,v
retrieving revision 1.244
diff -c -3 -p -r1.244 jump.c
*** jump.c	13 May 2004 06:39:43 -0000	1.244
--- jump.c	14 May 2004 15:48:56 -0000
*************** mark_all_labels (rtx f)
*** 192,217 ****
    for (insn = f; insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
        {
- 	if (GET_CODE (insn) == CALL_INSN
- 	    && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- 	  {
- 	    mark_all_labels (XEXP (PATTERN (insn), 0));
- 	    mark_all_labels (XEXP (PATTERN (insn), 1));
- 	    mark_all_labels (XEXP (PATTERN (insn), 2));
- 
- 	    /* Canonicalize the tail recursion label attached to the
- 	       CALL_PLACEHOLDER insn.  */
- 	    if (XEXP (PATTERN (insn), 3))
- 	      {
- 		rtx label_ref = gen_rtx_LABEL_REF (VOIDmode,
- 						   XEXP (PATTERN (insn), 3));
- 		mark_jump_label (label_ref, insn, 0);
- 		XEXP (PATTERN (insn), 3) = XEXP (label_ref, 0);
- 	      }
- 
- 	    continue;
- 	  }
- 
  	mark_jump_label (PATTERN (insn), insn, 0);
  	if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
  	  {
--- 192,197 ----
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/print-rtl.c,v
retrieving revision 1.108
diff -c -3 -p -r1.108 print-rtl.c
*** print-rtl.c	13 May 2004 06:39:44 -0000	1.108
--- print-rtl.c	14 May 2004 15:48:57 -0000
*************** int flag_simple = 0;
*** 60,68 ****
  /* Nonzero if we are dumping graphical description.  */
  int dump_for_graph;
  
- /* Nonzero to dump all call_placeholder alternatives.  */
- static int debug_call_placeholder_verbose;
- 
  void
  print_mem_expr (FILE *outfile, tree expr)
  {
--- 60,65 ----
*************** print_rtx (rtx in_rtx)
*** 99,105 ****
    int j;
    const char *format_ptr;
    int is_insn;
-   rtx tem;
  
    if (sawclose)
      {
--- 96,101 ----
*************** print_rtx (rtx in_rtx)
*** 571,619 ****
  	  case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
  	  default: abort();
  	}
-       break;
- 
-     case CALL_PLACEHOLDER:
-       if (debug_call_placeholder_verbose)
- 	{
- 	  fputs (" (cond [\n  (const_string \"normal\") (sequence [", outfile);
- 	  for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
- 	    {
- 	      fputs ("\n    ", outfile);
- 	      print_inline_rtx (outfile, tem, 4);
- 	    }
- 
- 	  tem = XEXP (in_rtx, 1);
- 	  if (tem)
- 	    fputs ("\n    ])\n  (const_string \"tail_call\") (sequence [",
- 		   outfile);
- 	  for (; tem != 0; tem = NEXT_INSN (tem))
- 	    {
- 	      fputs ("\n    ", outfile);
- 	      print_inline_rtx (outfile, tem, 4);
- 	    }
- 
- 	  tem = XEXP (in_rtx, 2);
- 	  if (tem)
- 	    fputs ("\n    ])\n  (const_string \"tail_recursion\") (sequence [",
- 		   outfile);
- 	  for (; tem != 0; tem = NEXT_INSN (tem))
- 	    {
- 	      fputs ("\n    ", outfile);
- 	      print_inline_rtx (outfile, tem, 4);
- 	    }
- 
- 	  fputs ("\n    ])\n  ])", outfile);
- 	  break;
- 	}
- 
-       for (tem = XEXP (in_rtx, 0); tem != 0; tem = NEXT_INSN (tem))
- 	if (GET_CODE (tem) == CALL_INSN)
- 	  {
- 	    fprintf (outfile, " ");
- 	    print_rtx (tem);
- 	    break;
- 	  }
        break;
  
      default:
--- 567,572 ----
Index: rtl.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.def,v
retrieving revision 1.83
diff -c -3 -p -r1.83 rtl.def
*** rtl.def	13 May 2004 06:39:45 -0000	1.83
--- rtl.def	14 May 2004 15:48:59 -0000
*************** DEF_RTL_EXPR(RANGE_VAR, "range_var", "et
*** 1153,1179 ****
     0 is the live bitmap.  Operand 1 is the original block number.  */
  DEF_RTL_EXPR(RANGE_LIVE, "range_live", "bi", RTX_EXTRA)
  
- /* A placeholder for a CALL_INSN which may be turned into a normal call,
-    a sibling (tail) call or tail recursion.
- 
-    Immediately after RTL generation, this placeholder will be replaced
-    by the insns to perform the call, sibcall or tail recursion.
- 
-    This RTX has 4 operands.  The first three are lists of instructions to
-    perform the call as a normal call, sibling call and tail recursion
-    respectively.  The latter two lists may be NULL, the first may never
-    be NULL.
- 
-    The last operand is the tail recursion CODE_LABEL, which may be NULL if no 
-    potential tail recursive calls were found.
- 
-    The tail recursion label is needed so that we can clear LABEL_PRESERVE_P
-    after we select a call method.
- 
-    This method of tail-call elimination is intended to be replaced by
-    tree-based optimizations once front-end conversions are complete.  */
- DEF_RTL_EXPR(CALL_PLACEHOLDER, "call_placeholder", "uuuu", RTX_EXTRA)
- 
  /* Describes a merge operation between two vector values.
     Operands 0 and 1 are the vectors to be merged, operand 2 is a bitmask
     that specifies where the parts of the result are taken from.  Set bits
--- 1153,1158 ----
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.471
diff -c -3 -p -r1.471 rtl.h
*** rtl.h	13 May 2004 06:39:45 -0000	1.471
--- rtl.h	14 May 2004 15:48:59 -0000
*************** extern rtx gen_hard_reg_clobber (enum ma
*** 2415,2430 ****
  extern rtx get_reg_known_value (unsigned int);
  extern bool get_reg_known_equiv_p (unsigned int);
  
- /* In sibcall.c */
- typedef enum {
-   sibcall_use_normal = 1,
-   sibcall_use_tail_recursion,
-   sibcall_use_sibcall
- } sibcall_use_t;
- 
- extern void optimize_sibling_and_tail_recursive_calls (void);
- extern void replace_call_placeholder (rtx, sibcall_use_t);
- 
  #ifdef STACK_REGS
  extern int stack_regs_mentioned (rtx insn);
  #endif
--- 2415,2420 ----
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.354
diff -c -3 -p -r1.354 stmt.c
*** stmt.c	13 May 2004 06:39:45 -0000	1.354
--- stmt.c	14 May 2004 15:48:59 -0000
*************** static void expand_null_return_1 (rtx);
*** 400,406 ****
  static enum br_predictor return_prediction (rtx);
  static rtx shift_return_value (rtx);
  static void expand_value_return (rtx);
- static int tail_recursion_args (tree, tree);
  static void expand_cleanups (tree, int, int);
  static void check_seenlabel (void);
  static void do_jump_if_equal (rtx, rtx, rtx, int);
--- 400,405 ----
*************** expand_return (tree retval)
*** 3057,3095 ****
  
    last_insn = get_last_insn ();
  
-   /* Distribute return down conditional expr if either of the sides
-      may involve tail recursion (see test below).  This enhances the number
-      of tail recursions we see.  Don't do this always since it can produce
-      sub-optimal code in some cases and we distribute assignments into
-      conditional expressions when it would help.  */
- 
-   if (optimize && retval_rhs != 0
-       && frame_offset == 0
-       && TREE_CODE (retval_rhs) == COND_EXPR
-       && (TREE_CODE (TREE_OPERAND (retval_rhs, 1)) == CALL_EXPR
- 	  || TREE_CODE (TREE_OPERAND (retval_rhs, 2)) == CALL_EXPR))
-     {
-       rtx label = gen_label_rtx ();
-       tree expr;
- 
-       do_jump (TREE_OPERAND (retval_rhs, 0), label, NULL_RTX);
-       start_cleanup_deferral ();
-       expr = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (current_function_decl)),
- 		    DECL_RESULT (current_function_decl),
- 		    TREE_OPERAND (retval_rhs, 1));
-       TREE_SIDE_EFFECTS (expr) = 1;
-       expand_return (expr);
-       emit_label (label);
- 
-       expr = build (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (current_function_decl)),
- 		    DECL_RESULT (current_function_decl),
- 		    TREE_OPERAND (retval_rhs, 2));
-       TREE_SIDE_EFFECTS (expr) = 1;
-       expand_return (expr);
-       end_cleanup_deferral ();
-       return;
-     }
- 
    result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
  
    /* If the result is an aggregate that is being returned in one (or more)
--- 3056,3061 ----
*************** expand_return (tree retval)
*** 3237,3350 ****
        emit_queue ();
        expand_value_return (result_rtl);
      }
- }
- 
- /* Attempt to optimize a potential tail recursion call into a goto.
-    ARGUMENTS are the arguments to a CALL_EXPR; LAST_INSN indicates
-    where to place the jump to the tail recursion label.
- 
-    Return TRUE if the call was optimized into a goto.  */
- 
- int
- optimize_tail_recursion (tree arguments, rtx last_insn)
- {
-   /* Finish checking validity, and if valid emit code to set the
-      argument variables for the new call.  */
-   if (tail_recursion_args (arguments, DECL_ARGUMENTS (current_function_decl)))
-     {
-       if (tail_recursion_label == 0)
- 	{
- 	  tail_recursion_label = gen_label_rtx ();
- 	  emit_label_after (tail_recursion_label,
- 			    tail_recursion_reentry);
- 	}
-       emit_queue ();
-       expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
-       emit_barrier ();
-       return 1;
-     }
-   return 0;
- }
- 
- /* Emit code to alter this function's formal parms for a tail-recursive call.
-    ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
-    FORMALS is the chain of decls of formals.
-    Return 1 if this can be done;
-    otherwise return 0 and do not emit any code.  */
- 
- static int
- tail_recursion_args (tree actuals, tree formals)
- {
-   tree a = actuals, f = formals;
-   int i;
-   rtx *argvec;
- 
-   /* Check that number and types of actuals are compatible
-      with the formals.  This is not always true in valid C code.
-      Also check that no formal needs to be addressable
-      and that all formals are scalars.  */
- 
-   /* Also count the args.  */
- 
-   for (a = actuals, f = formals, i = 0; a && f; a = TREE_CHAIN (a), f = TREE_CHAIN (f), i++)
-     {
-       if (!lang_hooks.types_compatible_p (TREE_TYPE (TREE_VALUE (a)), 
- 	      TREE_TYPE (f)))
- 	return 0;
-       if (GET_CODE (DECL_RTL (f)) != REG || DECL_MODE (f) == BLKmode)
- 	return 0;
-     }
-   if (a != 0 || f != 0)
-     return 0;
- 
-   /* Compute all the actuals.  */
- 
-   argvec = alloca (i * sizeof (rtx));
- 
-   for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
-     argvec[i] = expand_expr (TREE_VALUE (a), NULL_RTX, VOIDmode, 0);
- 
-   /* Find which actual values refer to current values of previous formals.
-      Copy each of them now, before any formal is changed.  */
- 
-   for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
-     {
-       int copy = 0;
-       int j;
-       for (f = formals, j = 0; j < i; f = TREE_CHAIN (f), j++)
- 	if (reg_mentioned_p (DECL_RTL (f), argvec[i]))
- 	  {
- 	    copy = 1;
- 	    break;
- 	  }
-       if (copy)
- 	argvec[i] = copy_to_reg (argvec[i]);
-     }
- 
-   /* Store the values of the actuals into the formals.  */
- 
-   for (f = formals, a = actuals, i = 0; f;
-        f = TREE_CHAIN (f), a = TREE_CHAIN (a), i++)
-     {
-       if (GET_MODE (DECL_RTL (f)) == GET_MODE (argvec[i]))
- 	emit_move_insn (DECL_RTL (f), argvec[i]);
-       else
- 	{
- 	  rtx tmp = argvec[i];
- 	  int unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_VALUE (a)));
- 	  promote_mode(TREE_TYPE (TREE_VALUE (a)), GET_MODE (tmp),
- 		       &unsignedp, 0);
- 	  if (DECL_MODE (f) != GET_MODE (DECL_RTL (f)))
- 	    {
- 	      tmp = gen_reg_rtx (DECL_MODE (f));
- 	      convert_move (tmp, argvec[i], unsignedp);
- 	    }
- 	  convert_move (DECL_RTL (f), tmp, unsignedp);
- 	}
-     }
- 
-   free_temp_slots ();
-   return 1;
  }
  
  /* Generate the RTL code for entering a binding contour.
--- 3203,3208 ----
Index: tree-tailcall.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-tailcall.c,v
retrieving revision 2.1
diff -c -3 -p -r2.1 tree-tailcall.c
*** tree-tailcall.c	13 May 2004 06:39:50 -0000	2.1
--- tree-tailcall.c	14 May 2004 15:49:02 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 72,78 ****
     omit the accumulator.
  
     There are three cases how the function may exit.  The first one is
!    handled in adjust_return_value, the later two in adjust_accumulator_values
     (the second case is actually a special case of the third one and we
     present it separately just for clarity):
  
--- 72,78 ----
     omit the accumulator.
  
     There are three cases how the function may exit.  The first one is
!    handled in adjust_return_value, the other two in adjust_accumulator_values
     (the second case is actually a special case of the third one and we
     present it separately just for clarity):
  
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.492
diff -c -3 -p -r1.492 tree.h
*** tree.h	13 May 2004 06:39:50 -0000	1.492
--- tree.h	14 May 2004 15:49:02 -0000
*************** extern void expand_stack_alloc (tree, tr
*** 3406,3412 ****
  extern rtx expand_stack_save (void);
  extern void expand_stack_restore (tree);
  extern void expand_return (tree);
- extern int optimize_tail_recursion (tree, rtx);
  extern void expand_start_bindings_and_block (int, tree);
  #define expand_start_bindings(flags) \
    expand_start_bindings_and_block(flags, NULL_TREE)
--- 3406,3411 ----

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