sese.h 8.86 KB
Newer Older
Sebastian Pop committed
1
/* Single entry single exit control flow regions.
2
   Copyright (C) 2008-2016 Free Software Foundation, Inc.
Sebastian Pop committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   Contributed by Jan Sjodin <jan.sjodin@amd.com> and
   Sebastian Pop <sebastian.pop@amd.com>.

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 Free Software Foundation; either version 3, or (at your option)
any 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
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef GCC_SESE_H
#define GCC_SESE_H

25
typedef hash_map<tree, tree> parameter_rename_map_t;
26 27 28 29 30 31 32 33
typedef hash_map<basic_block, vec<basic_block> > bb_map_t;
typedef hash_map<tree, vec<tree> > rename_map_t;
typedef struct ifsese_s *ifsese;
/* First phi is the new codegenerated phi second one is original phi.  */
typedef std::pair <gphi *, gphi *> phi_rename;
/* First edge is the init edge and second is the back edge w.r.t. a loop.  */
typedef std::pair<edge, edge> init_back_edge_pair_t;

Sebastian Pop committed
34 35
/* A Single Entry, Single Exit region is a part of the CFG delimited
   by two edges.  */
36
struct sese_l
Sebastian Pop committed
37
{
38 39 40 41 42 43 44 45
  sese_l (edge e, edge x) : entry (e), exit (x) {}

  operator bool () const { return entry && exit; }

  edge entry;
  edge exit;
};

46 47 48 49 50
void print_edge (FILE *file, const_edge e);
void print_sese (FILE *file, const sese_l &s);
void dump_edge (const_edge e);
void dump_sese (const sese_l &);

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/* Get the entry of an sese S.  */

static inline basic_block
get_entry_bb (sese_l &s)
{
  return s.entry->dest;
}

/* Get the exit of an sese S.  */

static inline basic_block
get_exit_bb (sese_l &s)
{
  return s.exit->src;
}

67 68 69 70 71 72 73 74 75 76 77 78 79
/* Returns the index of V where ELEM can be found. -1 Otherwise.  */
template<typename T>
int
vec_find (const vec<T> &v, const T &elem)
{
  int i;
  T t;
  FOR_EACH_VEC_ELT (v, i, t)
    if (elem == t)
      return i;
  return -1;
}

80 81 82 83 84
/* A helper structure for bookkeeping information about a scop in graphite.  */
typedef struct sese_info_t
{
  /* The SESE region.  */
  sese_l region;
Sebastian Pop committed
85 86

  /* Parameters used within the SCOP.  */
87
  vec<tree> params;
Sebastian Pop committed
88

89 90 91 92 93
  /* Maps an old name to one or more new names.  When there are several new
     names, one has to select the definition corresponding to the immediate
     dominator.  */
  rename_map_t *rename_map;

94 95 96
  /* Parameters to be renamed.  */
  parameter_rename_map_t *parameter_rename_map;

Aditya Kumar committed
97
  /* Loops completely contained in this SESE.  */
98
  vec<loop_p> loop_nest;
99 100 101

  /* Basic blocks contained in this SESE.  */
  vec<basic_block> bbs;
Sebastian Pop committed
102

103 104 105 106 107 108 109 110 111 112 113
  /* Copied basic blocks indexed by the original bb.  */
  bb_map_t *copied_bb_map;

  /* A vector of phi nodes to be updated when all arguments are available.  The
     pair contains first the old_phi and second the new_phi.  */
  vec<phi_rename> incomplete_phis;

  /* The condition region generated for this sese.  */
  ifsese if_region;

} *sese_info_p;
Sebastian Pop committed
114

115 116 117 118
extern sese_info_p new_sese_info (edge, edge);
extern void free_sese_info (sese_info_p);
extern void sese_insert_phis_for_liveouts (sese_info_p, basic_block, edge, edge);
extern struct loop *outermost_loop_in_sese (sese_l &, basic_block);
119
extern tree scalar_evolution_in_region (const sese_l &, loop_p, tree);
120
extern bool scev_analyzable_p (tree, sese_l &);
121
extern bool invariant_in_sese_p_rec (tree, const sese_l &, bool *);
Sebastian Pop committed
122 123 124 125

/* The number of parameters in REGION. */

static inline unsigned
126
sese_nb_params (sese_info_p region)
Sebastian Pop committed
127
{
128
  return region->params.length ();
Sebastian Pop committed
129 130 131 132 133 134
}

/* Checks whether BB is contained in the region delimited by ENTRY and
   EXIT blocks.  */

static inline bool
135
bb_in_region (const_basic_block bb, const_basic_block entry, const_basic_block exit)
Sebastian Pop committed
136
{
137 138 139 140 141 142 143 144 145 146 147 148
  /* FIXME: PR67842.  */
#if 0
  if (flag_checking)
    {
      edge e;
      edge_iterator ei;

      /* Check that there are no edges coming in the region: all the
	 predecessors of EXIT are dominated by ENTRY.  */
      FOR_EACH_EDGE (e, ei, exit->preds)
	gcc_assert (dominated_by_p (CDI_DOMINATORS, e->src, entry));
    }
Sebastian Pop committed
149 150 151 152 153 154 155 156 157 158 159
#endif

  return dominated_by_p (CDI_DOMINATORS, bb, entry)
	 && !(dominated_by_p (CDI_DOMINATORS, bb, exit)
	      && !dominated_by_p (CDI_DOMINATORS, entry, exit));
}

/* Checks whether BB is contained in the region delimited by ENTRY and
   EXIT blocks.  */

static inline bool
160
bb_in_sese_p (basic_block bb, const sese_l &r)
Sebastian Pop committed
161
{
162
  return bb_in_region (bb, r.entry->dest, r.exit->dest);
Sebastian Pop committed
163 164
}

165 166 167
/* Returns true when STMT is defined in REGION.  */

static inline bool
168
stmt_in_sese_p (gimple *stmt, const sese_l &r)
169 170
{
  basic_block bb = gimple_bb (stmt);
171
  return bb && bb_in_sese_p (bb, r);
172 173
}

Sebastian Pop committed
174 175 176
/* Returns true when NAME is defined in REGION.  */

static inline bool
177
defined_in_sese_p (tree name, const sese_l &r)
Sebastian Pop committed
178
{
179
  return stmt_in_sese_p (SSA_NAME_DEF_STMT (name), r);
Sebastian Pop committed
180 181 182 183
}

/* Returns true when LOOP is in REGION.  */

H.J. Lu committed
184
static inline bool
185
loop_in_sese_p (struct loop *loop, const sese_l &region)
Sebastian Pop committed
186 187 188 189 190 191 192 193 194 195 196 197 198
{
  return (bb_in_sese_p (loop->header, region)
	  && bb_in_sese_p (loop->latch, region));
}

/* Returns the loop depth of LOOP in REGION.  The loop depth
   is the same as the normal loop depth, but limited by a region.

   Example:

   loop_0
     loop_1
       {
H.J. Lu committed
199
         S0
Sebastian Pop committed
200 201 202 203 204 205 206 207
            <- region start
         S1

         loop_2
           S2

         S3
            <- region end
H.J. Lu committed
208
       }
Sebastian Pop committed
209 210 211 212 213 214

    loop_0 does not exist in the region -> invalid
    loop_1 exists, but is not completely contained in the region -> depth 0
    loop_2 is completely contained -> depth 1  */

static inline unsigned int
215
sese_loop_depth (const sese_l &region, loop_p loop)
Sebastian Pop committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
{
  unsigned int depth = 0;

  while (loop_in_sese_p (loop, region))
    {
      depth++;
      loop = loop_outer (loop);
    }

  return depth;
}

/* A single entry single exit specialized for conditions.  */

typedef struct ifsese_s {
231 232 233
  sese_info_p region;
  sese_info_p true_region;
  sese_info_p false_region;
Sebastian Pop committed
234 235
} *ifsese;

236 237
extern void if_region_set_false_region (ifsese, sese_info_p);
extern ifsese move_sese_in_condition (sese_info_p);
238
extern void set_ifsese_condition (ifsese, tree);
Sebastian Pop committed
239 240 241 242 243 244
extern edge get_true_edge_from_guard_bb (basic_block);
extern edge get_false_edge_from_guard_bb (basic_block);

static inline edge
if_region_entry (ifsese if_region)
{
245
  return if_region->region->region.entry;
Sebastian Pop committed
246 247 248 249 250
}

static inline edge
if_region_exit (ifsese if_region)
{
251
  return if_region->region->region.exit;
Sebastian Pop committed
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
}

static inline basic_block
if_region_get_condition_block (ifsese if_region)
{
  return if_region_entry (if_region)->dest;
}

/* Free and compute again all the dominators information.  */

static inline void
recompute_all_dominators (void)
{
  mark_irreducible_loops ();
  free_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_DOMINATORS);
268 269 270

  free_dominance_info (CDI_POST_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);
Sebastian Pop committed
271 272
}

273 274
typedef std::pair <gimple *, tree> scalar_use;

275
typedef struct gimple_poly_bb
Sebastian Pop committed
276 277
{
  basic_block bb;
278
  struct poly_bb *pbb;
Sebastian Pop committed
279 280 281 282

  /* Lists containing the restrictions of the conditional statements
     dominating this bb.  This bb can only be executed, if all conditions
     are true.
H.J. Lu committed
283

Sebastian Pop committed
284
     Example:
H.J. Lu committed
285

Sebastian Pop committed
286 287 288
     for (i = 0; i <= 20; i++)
     {
       A
H.J. Lu committed
289

Sebastian Pop committed
290 291 292
       if (2i <= 8)
         B
     }
H.J. Lu committed
293

Sebastian Pop committed
294
     So for B there is an additional condition (2i <= 8).
H.J. Lu committed
295

Sebastian Pop committed
296 297 298 299
     List of COND_EXPR and SWITCH_EXPR.  A COND_EXPR is true only if the
     corresponding element in CONDITION_CASES is not NULL_TREE.  For a
     SWITCH_EXPR the corresponding element in CONDITION_CASES is a
     CASE_LABEL_EXPR.  */
300 301
  vec<gimple *> conditions;
  vec<gimple *> condition_cases;
302
  vec<data_reference_p> data_refs;
303 304
  vec<scalar_use> read_scalar_refs;
  vec<tree> write_scalar_refs;
305
} *gimple_poly_bb_p;
Sebastian Pop committed
306

307 308 309 310 311
#define GBB_BB(GBB) (GBB)->bb
#define GBB_PBB(GBB) (GBB)->pbb
#define GBB_DATA_REFS(GBB) (GBB)->data_refs
#define GBB_CONDITIONS(GBB) (GBB)->conditions
#define GBB_CONDITION_CASES(GBB) (GBB)->condition_cases
Sebastian Pop committed
312 313 314 315

/* Return the innermost loop that contains the basic block GBB.  */

static inline struct loop *
316
gbb_loop (gimple_poly_bb_p gbb)
Sebastian Pop committed
317 318 319 320
{
  return GBB_BB (gbb)->loop_father;
}

H.J. Lu committed
321
/* Returns the gimple loop, that corresponds to the loop_iterator_INDEX.
Sebastian Pop committed
322 323 324
   If there is no corresponding gimple loop, we return NULL.  */

static inline loop_p
325
gbb_loop_at_index (gimple_poly_bb_p gbb, sese_l &region, int index)
Sebastian Pop committed
326 327 328 329 330 331 332
{
  loop_p loop = gbb_loop (gbb);
  int depth = sese_loop_depth (region, loop);

  while (--depth > index)
    loop = loop_outer (loop);

333
  gcc_assert (loop_in_sese_p (loop, region));
Sebastian Pop committed
334 335 336 337 338 339 340

  return loop;
}

/* The number of common loops in REGION for GBB1 and GBB2.  */

static inline int
341
nb_common_loops (sese_l &region, gimple_poly_bb_p gbb1, gimple_poly_bb_p gbb2)
Sebastian Pop committed
342 343 344 345
{
  loop_p l1 = gbb_loop (gbb1);
  loop_p l2 = gbb_loop (gbb2);
  loop_p common = find_common_loop (l1, l2);
H.J. Lu committed
346

Sebastian Pop committed
347 348 349 350
  return sese_loop_depth (region, common);
}

#endif