tree-ssa-loop-ch.c 7.96 KB
Newer Older
1
/* Loop header copying on trees.
2
   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3 4 5 6 7
   
This file is part of GCC.
   
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
8
Free Software Foundation; either version 3, or (at your option) any
9 10 11 12 13 14 15 16
later version.
   
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
   
You should have received a copy of the GNU General Public License
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "timevar.h"
#include "cfgloop.h"
#include "tree-inline.h"
#include "flags.h"
#include "tree-inline.h"

/* Duplicates headers of loops if they are small enough, so that the statements
   in the loop body are always executed when the loop is entered.  This
42
   increases effectiveness of code motion optimizations, and reduces the need
43 44 45 46 47 48 49 50 51 52
   for loop preconditioning.  */

/* Check whether we should duplicate HEADER of LOOP.  At most *LIMIT
   instructions should be duplicated, limit is decreased by the actual
   amount.  */

static bool
should_duplicate_loop_header_p (basic_block header, struct loop *loop,
				int *limit)
{
53 54
  gimple_stmt_iterator bsi;
  gimple last;
55 56 57 58 59 60

  /* Do not copy one block more than once (we do not really want to do
     loop peeling here).  */
  if (header->aux)
    return false;

61 62 63 64 65 66 67
  /* Loop header copying usually increases size of the code.  This used not to
     be true, since quite often it is possible to verify that the condition is
     satisfied in the first iteration and therefore to eliminate it.  Jump
     threading handles these cases now.  */
  if (optimize_loop_for_size_p (loop))
    return false;

68
  gcc_assert (EDGE_COUNT (header->succs) > 0);
69
  if (single_succ_p (header))
70
    return false;
71 72
  if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)
      && flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 1)->dest))
73 74 75 76
    return false;

  /* If this is not the original loop header, we want it to have just
     one predecessor in order to match the && pattern.  */
77
  if (header != loop->header && !single_pred_p (header))
78 79 80
    return false;

  last = last_stmt (header);
81
  if (gimple_code (last) != GIMPLE_COND)
82 83 84 85
    return false;

  /* Approximately copy the conditions that used to be used in jump.c --
     at most 20 insns and no calls.  */
86
  for (bsi = gsi_start_bb (header); !gsi_end_p (bsi); gsi_next (&bsi))
87
    {
88
      last = gsi_stmt (bsi);
89

90
      if (gimple_code (last) == GIMPLE_LABEL)
91 92
	continue;

93
      if (is_gimple_call (last))
94 95
	return false;

96
      *limit -= estimate_num_insns (last, &eni_size_weights);
97 98 99 100 101 102 103 104 105 106 107 108
      if (*limit < 0)
	return false;
    }

  return true;
}

/* Checks whether LOOP is a do-while style loop.  */

static bool
do_while_loop_p (struct loop *loop)
{
109
  gimple stmt = last_stmt (loop->latch);
110 111 112

  /* If the latch of the loop is not empty, it is not a do-while loop.  */
  if (stmt
113
      && gimple_code (stmt) != GIMPLE_LABEL)
114 115 116 117 118
    return false;

  /* If the header contains just a condition, it is not a do-while loop.  */
  stmt = last_and_only_stmt (loop->header);
  if (stmt
119
      && gimple_code (stmt) == GIMPLE_COND)
120 121 122 123 124 125 126 127 128
    return false;

  return true;
}

/* For all loops, copy the condition at the end of the loop body in front
   of the loop.  This is beneficial since it increases efficiency of
   code motion optimizations.  It also saves one jump on entry to the loop.  */

129
static unsigned int
130 131
copy_loop_headers (void)
{
132
  loop_iterator li;
133 134
  struct loop *loop;
  basic_block header;
135 136
  edge exit, entry;
  basic_block *bbs, *copied_bbs;
137
  unsigned n_bbs;
138
  unsigned bbs_size;
139

140 141
  loop_optimizer_init (LOOPS_HAVE_PREHEADERS
		       | LOOPS_HAVE_SIMPLE_LATCHES);
142 143 144 145 146
  if (number_of_loops () <= 1)
    {
      loop_optimizer_finalize ();
      return 0;
    }
147 148

#ifdef ENABLE_CHECKING
149
  verify_loop_structure ();
150 151
#endif

152 153
  bbs = XNEWVEC (basic_block, n_basic_blocks);
  copied_bbs = XNEWVEC (basic_block, n_basic_blocks);
154
  bbs_size = n_basic_blocks;
155

156
  FOR_EACH_LOOP (li, loop, 0)
157 158 159 160
    {
      /* Copy at most 20 insns.  */
      int limit = 20;

161
      header = loop->header;
162 163 164 165 166 167 168 169 170 171 172 173

      /* If the loop is already a do-while style one (either because it was
	 written as such, or because jump threading transformed it into one),
	 we might be in fact peeling the first iteration of the loop.  This
	 in general is not a good idea.  */
      if (do_while_loop_p (loop))
	continue;

      /* Iterate the header copying up to limit; this takes care of the cases
	 like while (a && b) {...}, where we want to have both of the conditions
	 copied.  TODO -- handle while (a || b) - like cases, by not requiring
	 the header to have just a single successor and copying up to
174 175 176 177
	 postdominator.  */

      exit = NULL;
      n_bbs = 0;
178 179 180 181
      while (should_duplicate_loop_header_p (header, loop, &limit))
	{
	  /* Find a successor of header that is inside a loop; i.e. the new
	     header after the condition is copied.  */
182 183
	  if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest))
	    exit = EDGE_SUCC (header, 0);
184
	  else
185
	    exit = EDGE_SUCC (header, 1);
186
	  bbs[n_bbs++] = header;
187
	  gcc_assert (bbs_size > n_bbs);
188
	  header = exit->dest;
189 190
	}

191 192
      if (!exit)
	continue;
193

194 195 196 197 198 199 200
      if (dump_file && (dump_flags & TDF_DETAILS))
	fprintf (dump_file,
		 "Duplicating header of the loop %d up to edge %d->%d.\n",
		 loop->num, exit->src->index, exit->dest->index);

      /* Ensure that the header will have just the latch as a predecessor
	 inside the loop.  */
201
      if (!single_pred_p (exit->dest))
202
	exit = single_pred_edge (split_edge (exit));
203

204 205
      entry = loop_preheader_edge (loop);

206
      if (!gimple_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs))
207 208 209 210 211
	{
	  fprintf (dump_file, "Duplication failed.\n");
	  continue;
	}

212 213 214 215 216 217
      /* If the loop has the form "for (i = j; i < j + 10; i++)" then
	 this copying can introduce a case where we rely on undefined
	 signed overflow to eliminate the preheader condition, because
	 we assume that "j < j + 10" is true.  We don't want to warn
	 about that case for -Wstrict-overflow, because in general we
	 don't warn about overflow involving loops.  Prevent the
218
	 warning by setting the no_warning flag in the condition.  */
219 220 221 222 223 224
      if (warn_strict_overflow > 0)
	{
	  unsigned int i;

	  for (i = 0; i < n_bbs; ++i)
	    {
225
	      gimple_stmt_iterator bsi;
226

227 228 229
	      for (bsi = gsi_start_bb (copied_bbs[i]);
		   !gsi_end_p (bsi);
		   gsi_next (&bsi))
230
		{
231 232 233 234
		  gimple stmt = gsi_stmt (bsi);
		  if (gimple_code (stmt) == GIMPLE_COND)
		    gimple_set_no_warning (stmt, true);
		  else if (is_gimple_assign (stmt))
235
		    {
236 237 238
		      enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
		      if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
			gimple_set_no_warning (stmt, true);
239 240
		    }
		}
241 242 243
	    }
	}

244 245
      /* Ensure that the latch and the preheader is simple (we know that they
	 are not now, since there was the loop exit condition.  */
246 247
      split_edge (loop_preheader_edge (loop));
      split_edge (loop_latch_edge (loop));
248 249
    }

250
  free (bbs);
251
  free (copied_bbs);
252

253
  loop_optimizer_finalize ();
254
  return 0;
255 256 257 258 259 260 261 262
}

static bool
gate_ch (void)
{
  return flag_tree_ch != 0;
}

263
struct gimple_opt_pass pass_ch = 
264
{
265 266
 {
  GIMPLE_PASS,
267 268 269 270 271 272 273
  "ch",					/* name */
  gate_ch,				/* gate */
  copy_loop_headers,			/* execute */
  NULL,					/* sub */
  NULL,					/* next */
  0,					/* static_pass_number */
  TV_TREE_CH,				/* tv_id */
274
  PROP_cfg | PROP_ssa,			/* properties_required */
275 276 277
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
278
  TODO_cleanup_cfg | TODO_dump_func 
279 280
  | TODO_verify_ssa			/* todo_flags_finish */
 }
281
};