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: [tree-ssa] Get rid of LOOP_EXPRs


The patch to remove LOOP_EXPRs is currently blocked on a couple 
regressions that you still need to fix.

  1. 920929-1.c fails without the change to reset DECL_TOO_LATE.  In
     a separate thread both Jason and I asked you for more details
     about the integrate.c change which resets DECL_TOO_LATE.

     My main concern is that you could lose valid error messages 
     in inlined functions if you reset this bit.  Consider the case
     if we end up threading a jump from outside the contour to the
     too-late label inside the contour.

  2. I get regressions for gcc.misc-tests/gcov-10.c when I use your
     LOOP_EXPR removal patch.  In a nutshell we have a line which
     is supposed to be executed 11 times, yet the gcov data shows
     is as being executed only 6 times.

Both of these issues must be addressed before we can integrate your
LOOP_EXPR removal patch.

FWIW, I tweaked the code slightly so that front-ends don't have to
set cfun->recreate_loop_notes, so that specific issue has been
addressed.  Basically we just use keep_function_tree_in_gimple_form
to determine if we need to recreate loop notes.

Attached in my version of the patch.  Again, the two issues noted above
are blocking integration of this patch.  I've got other work to do and
don't have the time to fix those problems for you.

I'd really like to get this code integrated, so if you can get the
two problems noted above addressed, I'll give it the highest priority
I can for final review/integration :-)

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.153.2.28
diff -c -3 -p -r1.153.2.28 basic-block.h
*** basic-block.h	4 Aug 2003 18:44:02 -0000	1.153.2.28
--- basic-block.h	25 Aug 2003 15:17:09 -0000
*************** typedef struct basic_block_def {
*** 272,280 ****
  /* Block contains a control flow expression.  */
  #define BB_CONTROL_EXPR		16
  
- /* Block contains a control flow expression for a loop.  */
- #define BB_LOOP_CONTROL_EXPR	32
- 
  /* Number of basic blocks in the current function.  */
  
  extern int n_basic_blocks;
--- 272,277 ----
Index: c-simplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-simplify.c,v
retrieving revision 1.1.4.67
diff -c -3 -p -r1.1.4.67 c-simplify.c
*** c-simplify.c	21 Aug 2003 15:59:44 -0000	1.1.4.67
--- c-simplify.c	25 Aug 2003 15:17:11 -0000
*************** gimplify_c_loop (tree cond, tree body, t
*** 584,590 ****
    tree exit, cont_block, break_block, loop;
    const char *stmt_filename;
    int stmt_lineno;
!   tree stuff;
  
    stmt_filename = input_filename;
    stmt_lineno = input_line;
--- 584,590 ----
    tree exit, cont_block, break_block, loop;
    const char *stmt_filename;
    int stmt_lineno;
!   tree stuff, entry = NULL_TREE;
  
    stmt_filename = input_filename;
    stmt_lineno = input_line;
*************** gimplify_c_loop (tree cond, tree body, t
*** 612,620 ****
    stuff = NULL_TREE;
    if (cond_is_first)
      {
!       add_tree (exit, &stuff);
!       add_tree (body, &stuff);
!       add_tree (incr, &stuff);
      }
    else
      {
--- 612,630 ----
    stuff = NULL_TREE;
    if (cond_is_first)
      {
!       if (exit)
! 	{
! 	  entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
! 	  add_tree (body, &stuff);
! 	  add_tree (incr, &stuff);
! 	  add_tree (entry, &stuff);
! 	  add_tree (exit, &stuff);
! 	}
!       else
! 	{
! 	  add_tree (body, &stuff);
! 	  add_tree (incr, &stuff);
! 	}
      }
    else
      {
*************** gimplify_c_loop (tree cond, tree body, t
*** 628,633 ****
--- 638,649 ----
    LOOP_EXPR_BODY (loop) = rationalize_compound_expr (stuff);
  
    loop = finish_bc_block (break_block, loop);
+   if (entry)
+     {
+       stuff = build_and_jump (&LABEL_EXPR_LABEL (entry));
+       add_tree (loop, &stuff);
+       loop = stuff;
+     }
  
    /* This catches do ... while (0) loops and eliminates their looping
       structure.  Conditions for detecting these loops:
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloop.h,v
retrieving revision 1.2.4.6
diff -c -3 -p -r1.2.4.6 cfgloop.h
*** cfgloop.h	4 Aug 2003 18:44:02 -0000	1.2.4.6
--- cfgloop.h	25 Aug 2003 15:17:11 -0000
*************** extern void flow_loop_dump (const struct
*** 265,270 ****
--- 265,271 ----
  extern int flow_loop_scan (struct loops *, struct loop *, int);
  extern void flow_loop_free (struct loop *);
  void mark_irreducible_loops (struct loops *);
+ extern void create_loop_notes (void);
  
  /* Loop data structure manipulation/querying.  */
  extern void flow_loop_tree_node_add (struct loop *, struct loop *);
Index: cfgloopmanip.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopmanip.c,v
retrieving revision 1.3.2.6
diff -c -3 -p -r1.3.2.6 cfgloopmanip.c
*** cfgloopmanip.c	20 Aug 2003 20:44:01 -0000	1.3.2.6
--- cfgloopmanip.c	25 Aug 2003 15:17:12 -0000
*************** loop_split_edge_with (edge e, rtx insns,
*** 1250,1252 ****
--- 1250,1347 ----
  
    return new_bb;
  }
+ 
+ /* Uses the natural loop discovery to recreate loop notes.  */
+ void
+ create_loop_notes ()
+ {
+   rtx insn, head, end;
+   struct loops loops;
+   struct loop *loop;
+   basic_block *first, *last, bb, pbb;
+   struct loop **stack, **top;
+ 
+ #ifdef ENABLE_CHECKING
+   /* Verify that there really are no loop notes.  */
+   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+     if (GET_CODE (insn) == NOTE
+ 	&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
+       abort ();
+ #endif
+ 
+   flow_loops_find (&loops, LOOP_TREE);
+   if (loops.num > 1)
+     {
+       last = xcalloc (loops.num, sizeof (basic_block));
+ 
+       FOR_EACH_BB (bb)
+ 	{
+ 	  for (loop = bb->loop_father; loop->outer; loop = loop->outer)
+ 	    last[loop->num] = bb;
+ 	}
+ 
+       first = xcalloc (loops.num, sizeof (basic_block));
+       stack = xcalloc (loops.num, sizeof (struct loop *));
+       top = stack;
+ 
+       FOR_EACH_BB (bb)
+ 	{
+ 	  for (loop = bb->loop_father; loop->outer; loop = loop->outer)
+ 	    {
+ 	      if (!first[loop->num])
+ 		{
+ 		  *top++ = loop;
+ 		  first[loop->num] = bb;
+ 		}
+ 
+ 	      if (bb == last[loop->num])
+ 		{
+ 		  /* Prevent loops from overlapping.  */
+ 		  while (*--top != loop)
+ 		    last[(*top)->num] = EXIT_BLOCK_PTR;
+ 
+ 		  /* If loop starts with jump into it, place the note in
+ 		     front of the jump.  */
+ 		  insn = PREV_INSN (first[loop->num]->head);
+ 		  if (insn
+ 		      && GET_CODE (insn) == BARRIER)
+ 		    insn = PREV_INSN (insn);
+ 		  
+ 		  if (insn
+ 		      && GET_CODE (insn) == JUMP_INSN
+ 		      && any_uncondjump_p (insn)
+ 		      && onlyjump_p (insn))
+ 		    {
+ 		      pbb = BLOCK_FOR_INSN (insn);
+ 		      if (!pbb || !pbb->succ || pbb->succ->succ_next)
+ 			abort ();
+ 
+ 		      if (!flow_bb_inside_loop_p (loop, pbb->succ->dest))
+ 			insn = first[loop->num]->head;
+ 		    }
+ 		  else
+ 		    insn = first[loop->num]->head;
+ 		    
+ 		  head = first[loop->num]->head;
+ 		  emit_note_before (NOTE_INSN_LOOP_BEG, insn);
+ 		  first[loop->num]->head = head;
+ 
+ 		  /* Position the note correctly wrto barrier.  */
+ 		  insn = last[loop->num]->end;
+ 		  if (NEXT_INSN (insn)
+ 		      && GET_CODE (NEXT_INSN (insn)) == BARRIER)
+ 		    insn = NEXT_INSN (insn);
+ 		  
+ 		  end = last[loop->num]->end;
+ 		  emit_note_after (NOTE_INSN_LOOP_END, insn);
+ 		  last[loop->num]->end = end;
+ 		}
+ 	    }
+ 	}
+ 
+       free (first);
+       free (last);
+       free (stack);
+     }
+   flow_loops_free (&loops);
+ }
Index: explow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/explow.c,v
retrieving revision 1.94.2.16
diff -c -3 -p -r1.94.2.16 explow.c
*** explow.c	21 Jul 2003 13:50:44 -0000	1.94.2.16
--- explow.c	25 Aug 2003 15:17:14 -0000
*************** probe_stack_range (HOST_WIDE_INT first, 
*** 1489,1506 ****
        rtx test_lab = gen_label_rtx ();
        rtx end_lab = gen_label_rtx ();
        rtx temp;
  
        if (GET_CODE (test_addr) != REG
  	  || REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
  	test_addr = force_reg (Pmode, test_addr);
  
!       emit_note (NOTE_INSN_LOOP_BEG);
        emit_jump (test_lab);
  
        emit_label (loop_lab);
        emit_stack_probe (test_addr);
  
!       emit_note (NOTE_INSN_LOOP_CONT);
  
  #ifdef STACK_GROWS_DOWNWARD
  #define CMP_OPCODE GTU
--- 1489,1510 ----
        rtx test_lab = gen_label_rtx ();
        rtx end_lab = gen_label_rtx ();
        rtx temp;
+       int create_notes
+ 	= ! keep_function_tree_in_gimple_form (current_function_decl);
  
        if (GET_CODE (test_addr) != REG
  	  || REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
  	test_addr = force_reg (Pmode, test_addr);
  
!       if (create_notes)
! 	emit_note (NOTE_INSN_LOOP_BEG);
        emit_jump (test_lab);
  
        emit_label (loop_lab);
        emit_stack_probe (test_addr);
  
!       if (create_notes)
! 	emit_note (NOTE_INSN_LOOP_CONT);
  
  #ifdef STACK_GROWS_DOWNWARD
  #define CMP_OPCODE GTU
*************** probe_stack_range (HOST_WIDE_INT first, 
*** 1519,1525 ****
        emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
  			       NULL_RTX, Pmode, 1, loop_lab);
        emit_jump (end_lab);
!       emit_note (NOTE_INSN_LOOP_END);
        emit_label (end_lab);
  
        emit_stack_probe (last_addr);
--- 1523,1530 ----
        emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
  			       NULL_RTX, Pmode, 1, loop_lab);
        emit_jump (end_lab);
!       if (create_notes)
! 	emit_note (NOTE_INSN_LOOP_END);
        emit_label (end_lab);
  
        emit_stack_probe (last_addr);
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.44
diff -c -3 -p -r1.467.2.44 expr.c
*** expr.c	21 Aug 2003 07:44:56 -0000	1.467.2.44
--- expr.c	25 Aug 2003 15:17:40 -0000
*************** emit_block_move_via_loop (rtx x, rtx y, 
*** 2091,2096 ****
--- 2091,2099 ----
  {
    rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
    enum machine_mode iter_mode;
+   int create_notes
+     = ! keep_function_tree_in_gimple_form (current_function_decl);
+ 
  
    iter_mode = GET_MODE (size);
    if (iter_mode == VOIDmode)
*************** emit_block_move_via_loop (rtx x, rtx y, 
*** 2106,2112 ****
    y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    do_pending_stack_adjust ();
  
!   emit_note (NOTE_INSN_LOOP_BEG);
  
    emit_jump (cmp_label);
    emit_label (top_label);
--- 2109,2116 ----
    y_addr = force_operand (XEXP (y, 0), NULL_RTX);
    do_pending_stack_adjust ();
  
!   if (create_notes)
!     emit_note (NOTE_INSN_LOOP_BEG);
  
    emit_jump (cmp_label);
    emit_label (top_label);
*************** emit_block_move_via_loop (rtx x, rtx y, 
*** 2124,2136 ****
    if (tmp != iter)
      emit_move_insn (iter, tmp);
  
!   emit_note (NOTE_INSN_LOOP_CONT);
    emit_label (cmp_label);
  
    emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
  			   true, top_label);
  
!   emit_note (NOTE_INSN_LOOP_END);
  }
  
  /* Copy all or part of a value X into registers starting at REGNO.
--- 2128,2142 ----
    if (tmp != iter)
      emit_move_insn (iter, tmp);
  
!   if (create_notes)
!     emit_note (NOTE_INSN_LOOP_CONT);
    emit_label (cmp_label);
  
    emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
  			   true, top_label);
  
!   if (create_notes)
!     emit_note (NOTE_INSN_LOOP_END);
  }
  
  /* Copy all or part of a value X into registers starting at REGNO.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.72
diff -c -3 -p -r1.1.2.72 gimplify.c
*** gimplify.c	22 Aug 2003 20:30:19 -0000	1.1.2.72
--- gimplify.c	25 Aug 2003 15:18:04 -0000
*************** static hashval_t gimple_tree_hash (const
*** 83,89 ****
  static int gimple_tree_eq (const void *, const void *);
  static tree lookup_tmp_var (tree, bool);
  static tree internal_get_tmp_var (tree, tree *, bool);
- static tree build_and_jump (tree *);
  static tree shortcut_cond_expr (tree);
  static tree gimple_boolify (tree);
  static void gimplify_conversion (tree *);
--- 83,88 ----
*************** gimplify_return_expr (tree stmt, tree *p
*** 984,1001 ****
      }
  }
  
! /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body,
!    but if the loop contains an EXIT_EXPR, we need to append a label for it
!    to jump to.  */
  
  static void
  gimplify_loop_expr (tree *expr_p)
  {
    tree saved_label = gimplify_ctxp->exit_label;
    gimplify_ctxp->exit_label = NULL_TREE;
  
    gimplify_stmt (&LOOP_EXPR_BODY (*expr_p));
  
    if (gimplify_ctxp->exit_label)
      {
        tree expr = build1 (LABEL_EXPR, void_type_node,
--- 983,1005 ----
      }
  }
  
! /* Gimplify a LOOP_EXPR.  Normally this just involves gimplifying the body
!    and replacing the LOOP_EXPR with goto, but if the loop contains an 
EXIT_EXPR,
!    we need to append a label for it to jump to.  */
  
  static void
  gimplify_loop_expr (tree *expr_p)
  {
    tree saved_label = gimplify_ctxp->exit_label;
+   tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+ 
    gimplify_ctxp->exit_label = NULL_TREE;
  
    gimplify_stmt (&LOOP_EXPR_BODY (*expr_p));
+   *expr_p = LOOP_EXPR_BODY (*expr_p);
  
+   add_tree (build_and_jump (&LABEL_EXPR_LABEL (start_label)), expr_p);
+   *expr_p = add_stmt_to_compound (start_label, *expr_p);
    if (gimplify_ctxp->exit_label)
      {
        tree expr = build1 (LABEL_EXPR, void_type_node,
*************** gimplify_exit_block_expr (tree *expr_p)
*** 1086,1092 ****
  /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
     if necessary.  */
  
! static tree
  build_and_jump (tree *label_p)
  {
    if (label_p == NULL)
--- 1090,1096 ----
  /* Build a GOTO to the LABEL_DECL pointed to by LABEL_P, building it first
     if necessary.  */
  
! tree
  build_and_jump (tree *label_p)
  {
    if (label_p == NULL)
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.62
diff -c -3 -p -r1.654.2.62 toplev.c
*** toplev.c	20 Aug 2003 20:44:30 -0000	1.654.2.62
--- toplev.c	25 Aug 2003 15:18:29 -0000
*************** rest_of_compilation (tree decl)
*** 3206,3211 ****
--- 3206,3214 ----
    cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
  	       | (flag_thread_jumps ? CLEANUP_THREADING : 0));
  
+   if (keep_function_tree_in_gimple_form (current_function_decl))
+     create_loop_notes ();
+ 
    if (optimize)
      {
        free_bb_for_insn ();
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.155
diff -c -3 -p -r1.1.4.155 tree-cfg.c
*** tree-cfg.c	24 Aug 2003 03:04:40 -0000	1.1.4.155
--- tree-cfg.c	25 Aug 2003 15:18:44 -0000
*************** static void create_block_annotation (bas
*** 85,91 ****
  static void free_blocks_annotations (void);
  static void clear_blocks_annotations (void);
  static basic_block make_blocks (tree *, tree, tree, basic_block, tree);
- static void make_loop_expr_blocks (tree *, basic_block, tree);
  static void make_cond_expr_blocks (tree *, tree, basic_block, tree);
  static void make_catch_expr_blocks (tree *, tree, basic_block, tree);
  static void make_eh_filter_expr_blocks (tree *, tree, basic_block, tree);
--- 85,90 ----
*************** static inline void set_parent_stmt (tree
*** 101,107 ****
  static void make_edges (void);
  static void make_ctrl_stmt_edges (basic_block);
  static void make_exit_edges (basic_block);
- static void make_loop_expr_edges (basic_block);
  static void make_cond_expr_edges (basic_block);
  static void make_goto_expr_edges (basic_block);
  static void make_case_label_edges (basic_block);
--- 100,105 ----
*************** static void remove_bb (basic_block, int)
*** 136,142 ****
  static void remove_stmt (tree *, bool);
  static bool blocks_unreachable_p (bitmap);
  static void remove_blocks (bitmap);
- static bool is_parent (basic_block, basic_block);
  static void cleanup_control_flow (void);
  static void cleanup_cond_expr_graph (basic_block);
  static void cleanup_switch_expr_graph (basic_block);
--- 134,139 ----
*************** make_blocks (tree *first_p, tree next_bl
*** 436,444 ****
        append_stmt_to_bb (stmt_p, bb, parent_stmt);
        get_stmt_ann (stmt)->scope = scope;
  
!       if (code == LOOP_EXPR)
! 	make_loop_expr_blocks (stmt_p, bb, scope);
!       else if (code == COND_EXPR)
  	make_cond_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == SWITCH_EXPR)
  	make_switch_expr_blocks (stmt_p, next_block_link, bb, scope);
--- 433,439 ----
        append_stmt_to_bb (stmt_p, bb, parent_stmt);
        get_stmt_ann (stmt)->scope = scope;
  
!       if (code == COND_EXPR)
  	make_cond_expr_blocks (stmt_p, next_block_link, bb, scope);
        else if (code == SWITCH_EXPR)
  	make_switch_expr_blocks (stmt_p, next_block_link, bb, scope);
*************** could_trap_p (tree expr)
*** 550,605 ****
  	      && (TREE_CODE (TREE_OPERAND (expr, 0)) == INDIRECT_REF)));
  }
  
- /* Create the blocks for the LOOP_EXPR node pointed by LOOP_P.
- 
-    NEXT_BLOCK_LINK is the first statement of the successor basic block for
-       the block holding *LOOP_P.  If *LOOP_P is the last statement inside a
-       lexical scope, this will be the statement that comes after LOOP_P's
-       container (see the documentation for NEXT_BLOCK_LINK).
- 
-    ENTRY is the block whose last statement is *LOOP_P.
-    
-    SCOPE is the BIND_EXPR node holding *LOOP_P. */
- 
- static void
- make_loop_expr_blocks (tree *loop_p, basic_block entry, tree scope)
- {
-   tree_stmt_iterator si;
-   tree loop = *loop_p;
-   tree next_block_link;
- 
-   entry->flags |= BB_CONTROL_EXPR | BB_LOOP_CONTROL_EXPR;
- 
-   /* Determine NEXT_BLOCK_LINK for statements inside the LOOP_EXPR body.
-      Note that in the case of a loop, NEXT_BLOCK_LINK should be the
-      first statement of the LOOP_EXPR body.  This is because LOOP_EXPR
-      statements are actually infinite loops, so they can only be left with a
-      'goto' statement.  Any other statement that reaches the end of the
-      LOOP_EXPR body, will naturally loop back.  */
-   STRIP_CONTAINERS (loop);
-   si = tsi_start (&LOOP_EXPR_BODY (loop));
-   next_block_link = *(tsi_container (si));
- 
-   /* If the loop body is empty, point NEXT_BLOCK_LINK to the statement
-      following the LOOP_EXPR node, as we do with the other control
-      structures.  */
-   if (body_is_empty (LOOP_EXPR_BODY (loop)))
-     {
-       si = tsi_start (loop_p);
-       tsi_next (&si);
- 
-       /* Ignore any empty statements at the tail of this tree.  */
-       while (!tsi_end_p (si) && tsi_stmt (si) == NULL)
- 	tsi_next (&si);
- 
-       if (!tsi_end_p (si) && tsi_stmt (si) != NULL_TREE)
- 	next_block_link = *(tsi_container (si));
-     }
- 
-   make_blocks (&LOOP_EXPR_BODY (loop), next_block_link, loop, NULL, scope);
- }
- 
- 
  /* Create the blocks for the COND_EXPR node pointed by COND_P.
  
     NEXT_BLOCK_LINK is the first statement of the successor basic block for
--- 545,550 ----
*************** find_contained_blocks (tree *stmt_p, bit
*** 1114,1124 ****
  
        /* And recurse down into control structures.  */
        code = TREE_CODE (stmt);
!       if (code == LOOP_EXPR)
! 	{
! 	  find_contained_blocks (&LOOP_EXPR_BODY (stmt), my_blocks, last_p);
! 	}
!       else if (code == COND_EXPR)
  	{
  	  find_contained_blocks (&COND_EXPR_THEN (stmt), my_blocks, last_p);
  	  find_contained_blocks (&COND_EXPR_ELSE (stmt), my_blocks, last_p);
--- 1059,1065 ----
  
        /* And recurse down into control structures.  */
        code = TREE_CODE (stmt);
!       if (code == COND_EXPR)
  	{
  	  find_contained_blocks (&COND_EXPR_THEN (stmt), my_blocks, last_p);
  	  find_contained_blocks (&COND_EXPR_ELSE (stmt), my_blocks, last_p);
*************** make_ctrl_stmt_edges (basic_block bb)
*** 1180,1189 ****
  
    switch (TREE_CODE (last))
      {
-     case LOOP_EXPR:
-       make_loop_expr_edges (bb);
-       break;
- 
      case COND_EXPR:
        make_cond_expr_edges (bb);
        break;
--- 1121,1126 ----
*************** make_exit_edges (basic_block bb)
*** 1350,1381 ****
  }
  
  
- /* Create the edges for the LOOP_EXPR structure starting at block BB.
-    Only create the edge that join the LOOP_EXPR header block to the loop
-    body.  The edge out of the loop and back into the LOOP_EXPR header will
-    be naturally created by the main loop in create_edges().
- 
-                LOOP_EXPR
- 	           |
-                    v
-              LOOP_EXPR_BODY  */
- 
- static void
- make_loop_expr_edges (basic_block bb)
- {
-   tree entry = last_stmt (bb);
-   basic_block body_bb;
- 
- #if defined ENABLE_CHECKING
-   if (entry == NULL_TREE || TREE_CODE (entry) != LOOP_EXPR)
-     abort ();
- #endif
- 
-   body_bb = bb_for_stmt (LOOP_EXPR_BODY (entry));
-   if (body_bb)
-     make_edge (bb, body_bb, 0);
- }
- 
  
  /* Create the edges for a COND_EXPR starting at block BB.
  
--- 1287,1292 ----
*************** remove_useless_stmts_and_vars (tree *fir
*** 1587,1596 ****
        /* Dive into control structures.  */
        stmt_p = tsi_stmt_ptr (i);
        code = TREE_CODE (*stmt_p);
!       if (code == LOOP_EXPR)
! 	repeat |= remove_useless_stmts_and_vars (&LOOP_EXPR_BODY (*stmt_p),
! 						 remove_unused_vars);
!       else if (code == COND_EXPR)
  	{
  	  tree then_clause, else_clause, cond;
  	  repeat |= remove_useless_stmts_and_vars (&COND_EXPR_THEN (*stmt_p),
--- 1498,1504 ----
        /* Dive into control structures.  */
        stmt_p = tsi_stmt_ptr (i);
        code = TREE_CODE (*stmt_p);
!       if (code == COND_EXPR)
  	{
  	  tree then_clause, else_clause, cond;
  	  repeat |= remove_useless_stmts_and_vars (&COND_EXPR_THEN (*stmt_p),
*************** blocks_unreachable_p (bitmap blocks)
*** 2064,2102 ****
    return true;
  }
  
- /* Return true if BB is a control parent for CHILD_BB.
- 
-    Notice that this property is not the same as dominance.  This
-    is a test for containment.  Given two blocks A and B, A DOM B
-    does not imply A is-parent-of B.  For instance,
- 
- 	    1	{
- 	    2	  s1;
- 	    3	}
- 	    4	{
- 	    5	  s2;
- 	    6	}
- 
-    The block at line 1 dominates the block at line 4, but line 4
-    is not contained in 1's compound structure.  */
- 
- static bool
- is_parent (basic_block bb, basic_block child_bb)
- {
-   basic_block parent;
- 
-   if (bb == child_bb)
-     return true;
- 
-   for (parent = parent_block (child_bb);
-        parent && parent->index != INVALID_BLOCK;
-        parent = parent_block (parent))
-     if (parent == bb)
-       return true;
- 
-   return false;
- }
- 
  /* Remove statement pointed by iterator I.
  
      Note that this function will wipe out control statements that
--- 1972,1977 ----
*************** remove_stmt (tree *stmt_p, bool remove_a
*** 2217,2227 ****
    /* If the statement is a control structure, clear the appropriate BB_*
       flags from the basic block.  */
    if (bb && is_ctrl_stmt (stmt))
!     {
!       bb->flags &= ~BB_CONTROL_EXPR;
!       if (TREE_CODE (stmt) == LOOP_EXPR)
! 	bb->flags &= ~BB_LOOP_CONTROL_EXPR;
!     }
  
    /* If the statement is a LABEL_EXPR, remove the LABEL_DECL from
       the symbol table.  */
--- 2092,2098 ----
    /* If the statement is a control structure, clear the appropriate BB_*
       flags from the basic block.  */
    if (bb && is_ctrl_stmt (stmt))
!     bb->flags &= ~BB_CONTROL_EXPR;
  
    /* If the statement is a LABEL_EXPR, remove the LABEL_DECL from
       the symbol table.  */
*************** find_taken_edge (basic_block bb, tree va
*** 2476,2482 ****
    if (TREE_CODE (stmt) == SWITCH_EXPR)
      return find_taken_edge_switch_expr (bb, val);
  
-   /* LOOP_EXPR nodes are always followed by their successor block.  */
    return bb->succ;
  }
  
--- 2347,2352 ----
*************** dump_tree_bb (FILE *outf, const char *pr
*** 2787,2793 ****
  {
    edge e;
    char *s_indent;
-   basic_block loop_bb;
    block_stmt_iterator si;
    tree phi;
  
--- 2657,2662 ----
*************** dump_tree_bb (FILE *outf, const char *pr
*** 2795,2807 ****
    memset ((void *) s_indent, ' ', (size_t) indent);
    s_indent[indent] = '\0';
  
!   fprintf (outf, "%s%sBLOCK       %d", s_indent, prefix, bb->index);
! 
!   loop_bb = is_latch_block_for (bb);
!   if (loop_bb)
!     fprintf (outf, " (latch for #%d)\n", loop_bb->index);
!   else
!     fprintf (outf, "\n");
  
    fprintf (outf, "%s%sPRED:      ", s_indent, prefix);
    for (e = bb->pred; e; e = e->pred_next)
--- 2664,2670 ----
    memset ((void *) s_indent, ' ', (size_t) indent);
    s_indent[indent] = '\0';
  
!   fprintf (outf, "%s%sBLOCK       %d\n", s_indent, prefix, bb->index);
  
    fprintf (outf, "%s%sPRED:      ", s_indent, prefix);
    for (e = bb->pred; e; e = e->pred_next)
*************** call_expr_flags (tree t)
*** 3221,3235 ****
  }
  
  
- /* Return true if T represent a loop statement.  */
- 
- bool
- is_loop_stmt (tree t)
- {
-   return (TREE_CODE (t) == LOOP_EXPR);
- }
- 
- 
  /* Return true if T is a computed goto.  */
  
  bool
--- 3084,3089 ----
*************** stmt_ends_bb_p (tree t)
*** 3293,3299 ****
  
    return (code == COND_EXPR
  	  || code == SWITCH_EXPR
- 	  || code == LOOP_EXPR
  	  || code == EH_FILTER_EXPR
  	  || code == TRY_CATCH_EXPR
  	  || code == TRY_FINALLY_EXPR
--- 3147,3152 ----
*************** delete_tree_cfg (void)
*** 3314,3339 ****
  }
  
  
- /* If BB is a latch block, return the header block controlling the loop.
-    FIXME: the name of this function stinks, but I can't think of a better
-    one at the moment.  */
- 
- basic_block
- is_latch_block_for (basic_block bb)
- {
-   edge e;
- 
-   /* BB is a latch if one of its successors is a loop entry block and BB is
-      a block in that loop's body.  */
-   for (e = bb->succ; e; e = e->succ_next)
-     if (e->dest->flags & BB_LOOP_CONTROL_EXPR
- 	&& is_parent (e->dest, bb))
-       return e->dest;
- 
-   return NULL;
- }
- 
- 
  /* Return a pointer to the first executable statement starting at ENTRY_P.  
*/
  
  static tree *
--- 3167,3172 ----
*************** bsi_insert_before (block_stmt_iterator *
*** 3955,3961 ****
    if (curr_container == curr_bb->head_tree_p)
      {
        curr_bb->head_tree_p = tsi_container (inserted_tsi);
!       /* If the parent block is a COND_EXPR or LOOP_EXPR, check if this
  	 is the block which they point to and update if necessary.  */
        if (parent)
          {
--- 3788,3794 ----
    if (curr_container == curr_bb->head_tree_p)
      {
        curr_bb->head_tree_p = tsi_container (inserted_tsi);
!       /* If the parent block is a COND_EXPR, check if this
  	 is the block which they point to and update if necessary.  */
        if (parent)
          {
*************** bsi_insert_before (block_stmt_iterator *
*** 3970,3980 ****
  		    COND_EXPR_ELSE (parent) = insert_container;
  		break;
  
- 	      case LOOP_EXPR:
- 		if (bb_for_stmt (LOOP_EXPR_BODY (parent)) == curr_bb)
- 		  LOOP_EXPR_BODY (parent) = insert_container;
- 		break;
- 
  	      default:
  		break;
  	    }
--- 3803,3808 ----
*************** find_insert_location (basic_block src, b
*** 4275,4285 ****
  	    break;
  
  
- 	  case LOOP_EXPR:
- 	    ret = src->end_tree_p;
- 	    *location = EDGE_INSERT_LOCATION_AFTER;
- 	    break;
- 
  	  case SWITCH_EXPR:
  	    bsi = bsi_start (dest);
  	    if (TREE_CODE (bsi_stmt (bsi)) != CASE_LABEL_EXPR)
--- 4103,4108 ----
*************** bsi_insert_on_edge_immediate (edge e, tr
*** 4409,4415 ****
  	}
  
        /* If the last stmt is a GOTO, the we can simply insert before it.  */
!       if (TREE_CODE (last) == GOTO_EXPR || TREE_CODE (last) == LOOP_EXPR)
  	{
  	  bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
  	  if (old_bsi)
--- 4232,4238 ----
  	}
  
        /* If the last stmt is a GOTO, the we can simply insert before it.  */
!       if (TREE_CODE (last) == GOTO_EXPR)
  	{
  	  bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
  	  if (old_bsi)
*************** merge_tree_blocks (basic_block bb1, basi
*** 4790,4797 ****
  	 C's body.  In this case we don't need to insert statements from
  	 BB2 into BB1, we can simply replace C with the first statement of
  	 BB2.  */
!       if (TREE_CODE (t1) == COND_EXPR
! 	  || TREE_CODE (t1) == LOOP_EXPR)
  	replace_stmt (bb1->end_tree_p, bb2->head_tree_p);
        else if (TREE_CODE (t1) == SWITCH_EXPR)
  	{
--- 4613,4619 ----
  	 C's body.  In this case we don't need to insert statements from
  	 BB2 into BB1, we can simply replace C with the first statement of
  	 BB2.  */
!       if (TREE_CODE (t1) == COND_EXPR)
  	replace_stmt (bb1->end_tree_p, bb2->head_tree_p);
        else if (TREE_CODE (t1) == SWITCH_EXPR)
  	{
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.149
diff -c -3 -p -r1.1.4.149 tree-dfa.c
*** tree-dfa.c	25 Aug 2003 02:44:23 -0000	1.1.4.149
--- tree-dfa.c	25 Aug 2003 15:19:07 -0000
*************** get_stmt_operands (tree stmt)
*** 236,242 ****
        break;
  
        /* These nodes contain no variable references.  */
-     case LOOP_EXPR:
      case BIND_EXPR:
      case CASE_LABEL_EXPR:
      case TRY_CATCH_EXPR:
--- 236,241 ----
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow.h,v
retrieving revision 1.1.4.106
diff -c -3 -p -r1.1.4.106 tree-flow.h
*** tree-flow.h	25 Aug 2003 02:44:23 -0000	1.1.4.106
--- tree-flow.h	25 Aug 2003 15:19:11 -0000
*************** extern void build_tree_cfg (tree);
*** 410,419 ****
  extern void delete_tree_cfg (void);
  extern bool is_ctrl_stmt (tree);
  extern bool is_ctrl_altering_stmt (tree);
- extern bool is_loop_stmt (tree);
  extern bool is_computed_goto (tree);
- extern tree loop_body (tree);
- extern void set_loop_body (tree, tree);
  extern void dump_tree_bb (FILE *, const char *, basic_block, int);
  extern void debug_tree_bb (basic_block);
  extern void dump_tree_cfg (FILE *, int);
--- 410,416 ----
*************** extern void remove_phi_nodes_and_edges_f
*** 427,433 ****
  extern tree first_stmt (basic_block);
  extern tree last_stmt (basic_block);
  extern tree *last_stmt_ptr (basic_block);
- extern basic_block is_latch_block_for (basic_block);
  extern edge find_taken_edge (basic_block, tree);
  extern int call_expr_flags (tree);
  extern int remove_useless_stmts_and_vars (tree *, int);
--- 424,429 ----
Index: tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.50
diff -c -3 -p -r1.1.4.50 tree-simple.c
*** tree-simple.c	25 Aug 2003 02:44:23 -0000	1.1.4.50
--- tree-simple.c	25 Aug 2003 15:19:11 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 53,59 ****
     stmt: compound-stmt | non-compound-stmt
     non-compound-stmt:
       block
-      | loop-stmt
       | if-stmt
       | switch-stmt
       | jump-stmt
--- 53,58 ----
*************** Boston, MA 02111-1307, USA.  */
*** 61,71 ****
       | try-stmt
       | modify-stmt
       | call-stmt
-    loop-stmt:
-      LOOP_EXPR
-        LOOP_EXPR_BODY -> stmt | NULL_TREE
-      | DO_LOOP_EXPR
-        (to be defined later)
     if-stmt:
       COND_EXPR
         op0 -> condition
--- 60,65 ----
*************** is_gimple_stmt (tree t)
*** 370,376 ****
        /* These are only valid if they're void.  */
        return VOID_TYPE_P (TREE_TYPE (t));
  
-     case LOOP_EXPR:
      case SWITCH_EXPR:
      case GOTO_EXPR:
      case RETURN_EXPR:
--- 364,369 ----
Index: tree-simple.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.h,v
retrieving revision 1.1.4.28
diff -c -3 -p -r1.1.4.28 tree-simple.h
*** tree-simple.h	22 Aug 2003 20:30:20 -0000	1.1.4.28
--- tree-simple.h	25 Aug 2003 15:19:11 -0000
*************** void unshare_all_trees (tree);
*** 103,108 ****
--- 103,109 ----
  tree voidify_wrapper_expr (tree);
  tree gimple_build_eh_filter (tree, tree, tree);
  tree maybe_protect_cleanup (tree);
+ tree build_and_jump (tree *);
  
  
  #endif /* _TREE_SIMPLE_H  */
Index: fortran/f95-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/Attic/f95-lang.c,v
retrieving revision 1.1.2.1
diff -c -3 -p -r1.1.2.1 f95-lang.c
*** fortran/f95-lang.c	26 Jul 2003 16:27:45 -0000	1.1.2.1
--- fortran/f95-lang.c	25 Aug 2003 15:20:02 -0000
*************** expand_function_body (tree fndecl, int n
*** 232,237 ****
--- 232,238 ----
          optimize_function_tree (fndecl);
      }
  #endif
+ 
    /* create RTL for startup code of function, such as saving registers */
    expand_function_start (fndecl, 0);
  






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