OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tree-vectorizer.h] - Blame information for rev 749

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* Vectorizer
2
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3
   Free Software Foundation, Inc.
4
   Contributed by Dorit Naishlos <dorit@il.ibm.com>
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#ifndef GCC_TREE_VECTORIZER_H
23
#define GCC_TREE_VECTORIZER_H
24
 
25
#include "tree-data-ref.h"
26
 
27
typedef source_location LOC;
28
#define UNKNOWN_LOC UNKNOWN_LOCATION
29
#define EXPR_LOC(e) EXPR_LOCATION(e)
30
#define LOC_FILE(l) LOCATION_FILE (l)
31
#define LOC_LINE(l) LOCATION_LINE (l)
32
 
33
/* Used for naming of new temporaries.  */
34
enum vect_var_kind {
35
  vect_simple_var,
36
  vect_pointer_var,
37
  vect_scalar_var
38
};
39
 
40
/* Defines type of operation.  */
41
enum operation_type {
42
  unary_op = 1,
43
  binary_op,
44
  ternary_op
45
};
46
 
47
/* Define type of available alignment support.  */
48
enum dr_alignment_support {
49
  dr_unaligned_unsupported,
50
  dr_unaligned_supported,
51
  dr_explicit_realign,
52
  dr_explicit_realign_optimized,
53
  dr_aligned
54
};
55
 
56
/* Define type of def-use cross-iteration cycle.  */
57
enum vect_def_type {
58
  vect_uninitialized_def = 0,
59
  vect_constant_def = 1,
60
  vect_external_def,
61
  vect_internal_def,
62
  vect_induction_def,
63
  vect_reduction_def,
64
  vect_double_reduction_def,
65
  vect_nested_cycle,
66
  vect_unknown_def_type
67
};
68
 
69
#define VECTORIZABLE_CYCLE_DEF(D) (((D) == vect_reduction_def)           \
70
                                   || ((D) == vect_double_reduction_def) \
71
                                   || ((D) == vect_nested_cycle))
72
 
73
/************************************************************************
74
  SLP
75
 ************************************************************************/
76
typedef void *slp_void_p;
77
DEF_VEC_P (slp_void_p);
78
DEF_VEC_ALLOC_P (slp_void_p, heap);
79
 
80
/* A computation tree of an SLP instance.  Each node corresponds to a group of
81
   stmts to be packed in a SIMD stmt.  */
82
typedef struct _slp_tree {
83
  /* Nodes that contain def-stmts of this node statements operands.  */
84
  VEC (slp_void_p, heap) *children;
85
  /* A group of scalar stmts to be vectorized together.  */
86
  VEC (gimple, heap) *stmts;
87
  /* Vectorized stmt/s.  */
88
  VEC (gimple, heap) *vec_stmts;
89
  /* Number of vector stmts that are created to replace the group of scalar
90
     stmts. It is calculated during the transformation phase as the number of
91
     scalar elements in one scalar iteration (GROUP_SIZE) multiplied by VF
92
     divided by vector size.  */
93
  unsigned int vec_stmts_size;
94
  /* Vectorization costs associated with SLP node.  */
95
  struct
96
  {
97
    int outside_of_loop;     /* Statements generated outside loop.  */
98
    int inside_of_loop;      /* Statements generated inside loop.  */
99
  } cost;
100
} *slp_tree;
101
 
102
DEF_VEC_P(slp_tree);
103
DEF_VEC_ALLOC_P(slp_tree, heap);
104
 
105
/* SLP instance is a sequence of stmts in a loop that can be packed into
106
   SIMD stmts.  */
107
typedef struct _slp_instance {
108
  /* The root of SLP tree.  */
109
  slp_tree root;
110
 
111
  /* Size of groups of scalar stmts that will be replaced by SIMD stmt/s.  */
112
  unsigned int group_size;
113
 
114
  /* The unrolling factor required to vectorized this SLP instance.  */
115
  unsigned int unrolling_factor;
116
 
117
  /* Vectorization costs associated with SLP instance.  */
118
  struct
119
  {
120
    int outside_of_loop;     /* Statements generated outside loop.  */
121
    int inside_of_loop;      /* Statements generated inside loop.  */
122
  } cost;
123
 
124
  /* Loads permutation relatively to the stores, NULL if there is no
125
     permutation.  */
126
  VEC (int, heap) *load_permutation;
127
 
128
  /* The group of nodes that contain loads of this SLP instance.  */
129
  VEC (slp_tree, heap) *loads;
130
 
131
  /* The first scalar load of the instance. The created vector loads will be
132
     inserted before this statement.  */
133
  gimple first_load;
134
} *slp_instance;
135
 
136
DEF_VEC_P(slp_instance);
137
DEF_VEC_ALLOC_P(slp_instance, heap);
138
 
139
/* Access Functions.  */
140
#define SLP_INSTANCE_TREE(S)                     (S)->root
141
#define SLP_INSTANCE_GROUP_SIZE(S)               (S)->group_size
142
#define SLP_INSTANCE_UNROLLING_FACTOR(S)         (S)->unrolling_factor
143
#define SLP_INSTANCE_OUTSIDE_OF_LOOP_COST(S)     (S)->cost.outside_of_loop
144
#define SLP_INSTANCE_INSIDE_OF_LOOP_COST(S)      (S)->cost.inside_of_loop
145
#define SLP_INSTANCE_LOAD_PERMUTATION(S)         (S)->load_permutation
146
#define SLP_INSTANCE_LOADS(S)                    (S)->loads
147
#define SLP_INSTANCE_FIRST_LOAD_STMT(S)          (S)->first_load
148
 
149
#define SLP_TREE_CHILDREN(S)                     (S)->children
150
#define SLP_TREE_SCALAR_STMTS(S)                 (S)->stmts
151
#define SLP_TREE_VEC_STMTS(S)                    (S)->vec_stmts
152
#define SLP_TREE_NUMBER_OF_VEC_STMTS(S)          (S)->vec_stmts_size
153
#define SLP_TREE_OUTSIDE_OF_LOOP_COST(S)         (S)->cost.outside_of_loop
154
#define SLP_TREE_INSIDE_OF_LOOP_COST(S)          (S)->cost.inside_of_loop
155
 
156
/* This structure is used in creation of an SLP tree.  Each instance
157
   corresponds to the same operand in a group of scalar stmts in an SLP
158
   node.  */
159
typedef struct _slp_oprnd_info
160
{
161
  /* Def-stmts for the operands.  */
162
  VEC (gimple, heap) *def_stmts;
163
  /* Information about the first statement, its vector def-type, type, the
164
     operand itself in case it's constant, and an indication if it's a pattern
165
     stmt.  */
166
  enum vect_def_type first_dt;
167
  tree first_def_type;
168
  tree first_const_oprnd;
169
  bool first_pattern;
170
} *slp_oprnd_info;
171
 
172
DEF_VEC_P(slp_oprnd_info);
173
DEF_VEC_ALLOC_P(slp_oprnd_info, heap);
174
 
175
 
176
typedef struct _vect_peel_info
177
{
178
  int npeel;
179
  struct data_reference *dr;
180
  unsigned int count;
181
} *vect_peel_info;
182
 
183
typedef struct _vect_peel_extended_info
184
{
185
  struct _vect_peel_info peel_info;
186
  unsigned int inside_cost;
187
  unsigned int outside_cost;
188
} *vect_peel_extended_info;
189
 
190
/*-----------------------------------------------------------------*/
191
/* Info on vectorized loops.                                       */
192
/*-----------------------------------------------------------------*/
193
typedef struct _loop_vec_info {
194
 
195
  /* The loop to which this info struct refers to.  */
196
  struct loop *loop;
197
 
198
  /* The loop basic blocks.  */
199
  basic_block *bbs;
200
 
201
  /* Number of iterations.  */
202
  tree num_iters;
203
  tree num_iters_unchanged;
204
 
205
  /* Minimum number of iterations below which vectorization is expected to
206
     not be profitable (as estimated by the cost model).
207
     -1 indicates that vectorization will not be profitable.
208
     FORNOW: This field is an int. Will be a tree in the future, to represent
209
             values unknown at compile time.  */
210
  int min_profitable_iters;
211
 
212
  /* Is the loop vectorizable? */
213
  bool vectorizable;
214
 
215
  /* Unrolling factor  */
216
  int vectorization_factor;
217
 
218
  /* The loop location in the source.  */
219
  LOC loop_line_number;
220
 
221
  /* Unknown DRs according to which loop was peeled.  */
222
  struct data_reference *unaligned_dr;
223
 
224
  /* peeling_for_alignment indicates whether peeling for alignment will take
225
     place, and what the peeling factor should be:
226
     peeling_for_alignment = X means:
227
        If X=0: Peeling for alignment will not be applied.
228
        If X>0: Peel first X iterations.
229
        If X=-1: Generate a runtime test to calculate the number of iterations
230
                 to be peeled, using the dataref recorded in the field
231
                 unaligned_dr.  */
232
  int peeling_for_alignment;
233
 
234
  /* The mask used to check the alignment of pointers or arrays.  */
235
  int ptr_mask;
236
 
237
  /* The loop nest in which the data dependences are computed.  */
238
  VEC (loop_p, heap) *loop_nest;
239
 
240
  /* All data references in the loop.  */
241
  VEC (data_reference_p, heap) *datarefs;
242
 
243
  /* All data dependences in the loop.  */
244
  VEC (ddr_p, heap) *ddrs;
245
 
246
  /* Data Dependence Relations defining address ranges that are candidates
247
     for a run-time aliasing check.  */
248
  VEC (ddr_p, heap) *may_alias_ddrs;
249
 
250
  /* Statements in the loop that have data references that are candidates for a
251
     runtime (loop versioning) misalignment check.  */
252
  VEC(gimple,heap) *may_misalign_stmts;
253
 
254
  /* All interleaving chains of stores in the loop, represented by the first
255
     stmt in the chain.  */
256
  VEC(gimple, heap) *strided_stores;
257
 
258
  /* All SLP instances in the loop. This is a subset of the set of STRIDED_STORES
259
     of the loop.  */
260
  VEC(slp_instance, heap) *slp_instances;
261
 
262
  /* The unrolling factor needed to SLP the loop. In case of that pure SLP is
263
     applied to the loop, i.e., no unrolling is needed, this is 1.  */
264
  unsigned slp_unrolling_factor;
265
 
266
  /* Reduction cycles detected in the loop. Used in loop-aware SLP.  */
267
  VEC (gimple, heap) *reductions;
268
 
269
  /* All reduction chains in the loop, represented by the first
270
     stmt in the chain.  */
271
  VEC (gimple, heap) *reduction_chains;
272
 
273
  /* Hash table used to choose the best peeling option.  */
274
  htab_t peeling_htab;
275
 
276
  /* When we have strided data accesses with gaps, we may introduce invalid
277
     memory accesses.  We peel the last iteration of the loop to prevent
278
     this.  */
279
  bool peeling_for_gaps;
280
 
281
} *loop_vec_info;
282
 
283
/* Access Functions.  */
284
#define LOOP_VINFO_LOOP(L)                 (L)->loop
285
#define LOOP_VINFO_BBS(L)                  (L)->bbs
286
#define LOOP_VINFO_NITERS(L)               (L)->num_iters
287
/* Since LOOP_VINFO_NITERS can change after prologue peeling
288
   retain total unchanged scalar loop iterations for cost model.  */
289
#define LOOP_VINFO_NITERS_UNCHANGED(L)     (L)->num_iters_unchanged
290
#define LOOP_VINFO_COST_MODEL_MIN_ITERS(L) (L)->min_profitable_iters
291
#define LOOP_VINFO_VECTORIZABLE_P(L)       (L)->vectorizable
292
#define LOOP_VINFO_VECT_FACTOR(L)          (L)->vectorization_factor
293
#define LOOP_VINFO_PTR_MASK(L)             (L)->ptr_mask
294
#define LOOP_VINFO_LOOP_NEST(L)            (L)->loop_nest
295
#define LOOP_VINFO_DATAREFS(L)             (L)->datarefs
296
#define LOOP_VINFO_DDRS(L)                 (L)->ddrs
297
#define LOOP_VINFO_INT_NITERS(L)           (TREE_INT_CST_LOW ((L)->num_iters))
298
#define LOOP_PEELING_FOR_ALIGNMENT(L)      (L)->peeling_for_alignment
299
#define LOOP_VINFO_UNALIGNED_DR(L)         (L)->unaligned_dr
300
#define LOOP_VINFO_MAY_MISALIGN_STMTS(L)   (L)->may_misalign_stmts
301
#define LOOP_VINFO_LOC(L)                  (L)->loop_line_number
302
#define LOOP_VINFO_MAY_ALIAS_DDRS(L)       (L)->may_alias_ddrs
303
#define LOOP_VINFO_STRIDED_STORES(L)       (L)->strided_stores
304
#define LOOP_VINFO_SLP_INSTANCES(L)        (L)->slp_instances
305
#define LOOP_VINFO_SLP_UNROLLING_FACTOR(L) (L)->slp_unrolling_factor
306
#define LOOP_VINFO_REDUCTIONS(L)           (L)->reductions
307
#define LOOP_VINFO_REDUCTION_CHAINS(L)     (L)->reduction_chains
308
#define LOOP_VINFO_PEELING_HTAB(L)         (L)->peeling_htab
309
#define LOOP_VINFO_PEELING_FOR_GAPS(L)     (L)->peeling_for_gaps
310
 
311
#define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
312
VEC_length (gimple, (L)->may_misalign_stmts) > 0
313
#define LOOP_REQUIRES_VERSIONING_FOR_ALIAS(L)     \
314
VEC_length (ddr_p, (L)->may_alias_ddrs) > 0
315
 
316
#define NITERS_KNOWN_P(n)                     \
317
(host_integerp ((n),0)                        \
318
&& TREE_INT_CST_LOW ((n)) > 0)
319
 
320
#define LOOP_VINFO_NITERS_KNOWN_P(L)          \
321
NITERS_KNOWN_P((L)->num_iters)
322
 
323
static inline loop_vec_info
324
loop_vec_info_for_loop (struct loop *loop)
325
{
326
  return (loop_vec_info) loop->aux;
327
}
328
 
329
static inline bool
330
nested_in_vect_loop_p (struct loop *loop, gimple stmt)
331
{
332
  return (loop->inner
333
          && (loop->inner == (gimple_bb (stmt))->loop_father));
334
}
335
 
336
typedef struct _bb_vec_info {
337
 
338
  basic_block bb;
339
  /* All interleaving chains of stores in the basic block, represented by the
340
     first stmt in the chain.  */
341
  VEC(gimple, heap) *strided_stores;
342
 
343
  /* All SLP instances in the basic block. This is a subset of the set of
344
     STRIDED_STORES of the basic block.  */
345
  VEC(slp_instance, heap) *slp_instances;
346
 
347
  /* All data references in the basic block.  */
348
  VEC (data_reference_p, heap) *datarefs;
349
 
350
  /* All data dependences in the basic block.  */
351
  VEC (ddr_p, heap) *ddrs;
352
} *bb_vec_info;
353
 
354
#define BB_VINFO_BB(B)              (B)->bb
355
#define BB_VINFO_STRIDED_STORES(B)  (B)->strided_stores
356
#define BB_VINFO_SLP_INSTANCES(B)   (B)->slp_instances
357
#define BB_VINFO_DATAREFS(B)        (B)->datarefs
358
#define BB_VINFO_DDRS(B)            (B)->ddrs
359
 
360
static inline bb_vec_info
361
vec_info_for_bb (basic_block bb)
362
{
363
  return (bb_vec_info) bb->aux;
364
}
365
 
366
/*-----------------------------------------------------------------*/
367
/* Info on vectorized defs.                                        */
368
/*-----------------------------------------------------------------*/
369
enum stmt_vec_info_type {
370
  undef_vec_info_type = 0,
371
  load_vec_info_type,
372
  store_vec_info_type,
373
  shift_vec_info_type,
374
  op_vec_info_type,
375
  call_vec_info_type,
376
  assignment_vec_info_type,
377
  condition_vec_info_type,
378
  reduc_vec_info_type,
379
  induc_vec_info_type,
380
  type_promotion_vec_info_type,
381
  type_demotion_vec_info_type,
382
  type_conversion_vec_info_type,
383
  loop_exit_ctrl_vec_info_type
384
};
385
 
386
/* Indicates whether/how a variable is used in the scope of loop/basic
387
   block.  */
388
enum vect_relevant {
389
  vect_unused_in_scope = 0,
390
  /* The def is in the inner loop, and the use is in the outer loop, and the
391
     use is a reduction stmt.  */
392
  vect_used_in_outer_by_reduction,
393
  /* The def is in the inner loop, and the use is in the outer loop (and is
394
     not part of reduction).  */
395
  vect_used_in_outer,
396
 
397
  /* defs that feed computations that end up (only) in a reduction. These
398
     defs may be used by non-reduction stmts, but eventually, any
399
     computations/values that are affected by these defs are used to compute
400
     a reduction (i.e. don't get stored to memory, for example). We use this
401
     to identify computations that we can change the order in which they are
402
     computed.  */
403
  vect_used_by_reduction,
404
 
405
  vect_used_in_scope
406
};
407
 
408
/* The type of vectorization that can be applied to the stmt: regular loop-based
409
   vectorization; pure SLP - the stmt is a part of SLP instances and does not
410
   have uses outside SLP instances; or hybrid SLP and loop-based - the stmt is
411
   a part of SLP instance and also must be loop-based vectorized, since it has
412
   uses outside SLP sequences.
413
 
414
   In the loop context the meanings of pure and hybrid SLP are slightly
415
   different. By saying that pure SLP is applied to the loop, we mean that we
416
   exploit only intra-iteration parallelism in the loop; i.e., the loop can be
417
   vectorized without doing any conceptual unrolling, cause we don't pack
418
   together stmts from different iterations, only within a single iteration.
419
   Loop hybrid SLP means that we exploit both intra-iteration and
420
   inter-iteration parallelism (e.g., number of elements in the vector is 4
421
   and the slp-group-size is 2, in which case we don't have enough parallelism
422
   within an iteration, so we obtain the rest of the parallelism from subsequent
423
   iterations by unrolling the loop by 2).  */
424
enum slp_vect_type {
425
  loop_vect = 0,
426
  pure_slp,
427
  hybrid
428
};
429
 
430
 
431
typedef struct data_reference *dr_p;
432
DEF_VEC_P(dr_p);
433
DEF_VEC_ALLOC_P(dr_p,heap);
434
 
435
typedef struct _stmt_vec_info {
436
 
437
  enum stmt_vec_info_type type;
438
 
439
  /* Indicates whether this stmts is part of a computation whose result is
440
     used outside the loop.  */
441
  bool live;
442
 
443
  /* Stmt is part of some pattern (computation idiom)  */
444
  bool in_pattern_p;
445
 
446
  /* For loads only, if there is a store with the same location, this field is
447
     TRUE.  */
448
  bool read_write_dep;
449
 
450
  /* The stmt to which this info struct refers to.  */
451
  gimple stmt;
452
 
453
  /* The loop_vec_info with respect to which STMT is vectorized.  */
454
  loop_vec_info loop_vinfo;
455
 
456
  /* The vector type to be used for the LHS of this statement.  */
457
  tree vectype;
458
 
459
  /* The vectorized version of the stmt.  */
460
  gimple vectorized_stmt;
461
 
462
 
463
  /** The following is relevant only for stmts that contain a non-scalar
464
     data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have
465
     at most one such data-ref.  **/
466
 
467
  /* Information about the data-ref (access function, etc),
468
     relative to the inner-most containing loop.  */
469
  struct data_reference *data_ref_info;
470
 
471
  /* Information about the data-ref relative to this loop
472
     nest (the loop that is being considered for vectorization).  */
473
  tree dr_base_address;
474
  tree dr_init;
475
  tree dr_offset;
476
  tree dr_step;
477
  tree dr_aligned_to;
478
 
479
  /* Used for various bookkeeping purposes, generally holding a pointer to
480
     some other stmt S that is in some way "related" to this stmt.
481
     Current use of this field is:
482
        If this stmt is part of a pattern (i.e. the field 'in_pattern_p' is
483
        true): S is the "pattern stmt" that represents (and replaces) the
484
        sequence of stmts that constitutes the pattern.  Similarly, the
485
        related_stmt of the "pattern stmt" points back to this stmt (which is
486
        the last stmt in the original sequence of stmts that constitutes the
487
        pattern).  */
488
  gimple related_stmt;
489
 
490
  /* Used to keep a sequence of def stmts of a pattern stmt if such exists.  */
491
  gimple_seq pattern_def_seq;
492
 
493
  /* List of datarefs that are known to have the same alignment as the dataref
494
     of this stmt.  */
495
  VEC(dr_p,heap) *same_align_refs;
496
 
497
  /* Classify the def of this stmt.  */
498
  enum vect_def_type def_type;
499
 
500
  /*  Whether the stmt is SLPed, loop-based vectorized, or both.  */
501
  enum slp_vect_type slp_type;
502
 
503
  /* Interleaving and reduction chains info.  */
504
  /* First element in the group.  */
505
  gimple first_element;
506
  /* Pointer to the next element in the group.  */
507
  gimple next_element;
508
  /* For data-refs, in case that two or more stmts share data-ref, this is the
509
     pointer to the previously detected stmt with the same dr.  */
510
  gimple same_dr_stmt;
511
  /* The size of the group.  */
512
  unsigned int size;
513
  /* For stores, number of stores from this group seen. We vectorize the last
514
     one.  */
515
  unsigned int store_count;
516
  /* For loads only, the gap from the previous load. For consecutive loads, GAP
517
     is 1.  */
518
  unsigned int gap;
519
 
520
  /* Not all stmts in the loop need to be vectorized. e.g, the increment
521
     of the loop induction variable and computation of array indexes. relevant
522
     indicates whether the stmt needs to be vectorized.  */
523
  enum vect_relevant relevant;
524
 
525
  /* Vectorization costs associated with statement.  */
526
  struct
527
  {
528
    int outside_of_loop;     /* Statements generated outside loop.  */
529
    int inside_of_loop;      /* Statements generated inside loop.  */
530
  } cost;
531
 
532
  /* The bb_vec_info with respect to which STMT is vectorized.  */
533
  bb_vec_info bb_vinfo;
534
 
535
  /* Is this statement vectorizable or should it be skipped in (partial)
536
     vectorization.  */
537
  bool vectorizable;
538
 
539
  /* For loads only, true if this is a gather load.  */
540
  bool gather_p;
541
} *stmt_vec_info;
542
 
543
/* Access Functions.  */
544
#define STMT_VINFO_TYPE(S)                 (S)->type
545
#define STMT_VINFO_STMT(S)                 (S)->stmt
546
#define STMT_VINFO_LOOP_VINFO(S)           (S)->loop_vinfo
547
#define STMT_VINFO_BB_VINFO(S)             (S)->bb_vinfo
548
#define STMT_VINFO_RELEVANT(S)             (S)->relevant
549
#define STMT_VINFO_LIVE_P(S)               (S)->live
550
#define STMT_VINFO_VECTYPE(S)              (S)->vectype
551
#define STMT_VINFO_VEC_STMT(S)             (S)->vectorized_stmt
552
#define STMT_VINFO_VECTORIZABLE(S)         (S)->vectorizable
553
#define STMT_VINFO_DATA_REF(S)             (S)->data_ref_info
554
#define STMT_VINFO_GATHER_P(S)             (S)->gather_p
555
 
556
#define STMT_VINFO_DR_BASE_ADDRESS(S)      (S)->dr_base_address
557
#define STMT_VINFO_DR_INIT(S)              (S)->dr_init
558
#define STMT_VINFO_DR_OFFSET(S)            (S)->dr_offset
559
#define STMT_VINFO_DR_STEP(S)              (S)->dr_step
560
#define STMT_VINFO_DR_ALIGNED_TO(S)        (S)->dr_aligned_to
561
 
562
#define STMT_VINFO_IN_PATTERN_P(S)         (S)->in_pattern_p
563
#define STMT_VINFO_RELATED_STMT(S)         (S)->related_stmt
564
#define STMT_VINFO_PATTERN_DEF_SEQ(S)      (S)->pattern_def_seq
565
#define STMT_VINFO_SAME_ALIGN_REFS(S)      (S)->same_align_refs
566
#define STMT_VINFO_DEF_TYPE(S)             (S)->def_type
567
#define STMT_VINFO_GROUP_FIRST_ELEMENT(S)  (S)->first_element
568
#define STMT_VINFO_GROUP_NEXT_ELEMENT(S)   (S)->next_element
569
#define STMT_VINFO_GROUP_SIZE(S)           (S)->size
570
#define STMT_VINFO_GROUP_STORE_COUNT(S)    (S)->store_count
571
#define STMT_VINFO_GROUP_GAP(S)            (S)->gap
572
#define STMT_VINFO_GROUP_SAME_DR_STMT(S)   (S)->same_dr_stmt
573
#define STMT_VINFO_GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
574
#define STMT_VINFO_STRIDED_ACCESS(S)      ((S)->first_element != NULL && (S)->data_ref_info)
575
 
576
#define GROUP_FIRST_ELEMENT(S)          (S)->first_element
577
#define GROUP_NEXT_ELEMENT(S)           (S)->next_element
578
#define GROUP_SIZE(S)                   (S)->size
579
#define GROUP_STORE_COUNT(S)            (S)->store_count
580
#define GROUP_GAP(S)                    (S)->gap
581
#define GROUP_SAME_DR_STMT(S)           (S)->same_dr_stmt
582
#define GROUP_READ_WRITE_DEPENDENCE(S)  (S)->read_write_dep
583
 
584
#define STMT_VINFO_RELEVANT_P(S)          ((S)->relevant != vect_unused_in_scope)
585
#define STMT_VINFO_OUTSIDE_OF_LOOP_COST(S) (S)->cost.outside_of_loop
586
#define STMT_VINFO_INSIDE_OF_LOOP_COST(S)  (S)->cost.inside_of_loop
587
 
588
#define HYBRID_SLP_STMT(S)                ((S)->slp_type == hybrid)
589
#define PURE_SLP_STMT(S)                  ((S)->slp_type == pure_slp)
590
#define STMT_SLP_TYPE(S)                   (S)->slp_type
591
 
592
#define VECT_MAX_COST 1000
593
 
594
/* The maximum number of intermediate steps required in multi-step type
595
   conversion.  */
596
#define MAX_INTERM_CVT_STEPS         3
597
 
598
/* The maximum vectorization factor supported by any target (V32QI).  */
599
#define MAX_VECTORIZATION_FACTOR 32
600
 
601
/* Avoid GTY(()) on stmt_vec_info.  */
602
typedef void *vec_void_p;
603
DEF_VEC_P (vec_void_p);
604
DEF_VEC_ALLOC_P (vec_void_p, heap);
605
 
606
extern VEC(vec_void_p,heap) *stmt_vec_info_vec;
607
 
608
void init_stmt_vec_info_vec (void);
609
void free_stmt_vec_info_vec (void);
610
 
611
/* Return a stmt_vec_info corresponding to STMT.  */
612
 
613
static inline stmt_vec_info
614
vinfo_for_stmt (gimple stmt)
615
{
616
  unsigned int uid = gimple_uid (stmt);
617
  if (uid == 0)
618
    return NULL;
619
 
620
  return (stmt_vec_info) VEC_index (vec_void_p, stmt_vec_info_vec, uid - 1);
621
}
622
 
623
/* Set vectorizer information INFO for STMT.  */
624
 
625
static inline void
626
set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
627
{
628
  unsigned int uid = gimple_uid (stmt);
629
  if (uid == 0)
630
    {
631
      gcc_checking_assert (info);
632
      uid = VEC_length (vec_void_p, stmt_vec_info_vec) + 1;
633
      gimple_set_uid (stmt, uid);
634
      VEC_safe_push (vec_void_p, heap, stmt_vec_info_vec, (vec_void_p) info);
635
    }
636
  else
637
    VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info);
638
}
639
 
640
/* Return the earlier statement between STMT1 and STMT2.  */
641
 
642
static inline gimple
643
get_earlier_stmt (gimple stmt1, gimple stmt2)
644
{
645
  unsigned int uid1, uid2;
646
 
647
  if (stmt1 == NULL)
648
    return stmt2;
649
 
650
  if (stmt2 == NULL)
651
    return stmt1;
652
 
653
  uid1 = gimple_uid (stmt1);
654
  uid2 = gimple_uid (stmt2);
655
 
656
  if (uid1 == 0 || uid2 == 0)
657
    return NULL;
658
 
659
  gcc_checking_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec)
660
                       && uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
661
 
662
  if (uid1 < uid2)
663
    return stmt1;
664
  else
665
    return stmt2;
666
}
667
 
668
/* Return the later statement between STMT1 and STMT2.  */
669
 
670
static inline gimple
671
get_later_stmt (gimple stmt1, gimple stmt2)
672
{
673
  unsigned int uid1, uid2;
674
 
675
  if (stmt1 == NULL)
676
    return stmt2;
677
 
678
  if (stmt2 == NULL)
679
    return stmt1;
680
 
681
  uid1 = gimple_uid (stmt1);
682
  uid2 = gimple_uid (stmt2);
683
 
684
  if (uid1 == 0 || uid2 == 0)
685
    return NULL;
686
 
687
  gcc_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec));
688
  gcc_assert (uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
689
 
690
  if (uid1 > uid2)
691
    return stmt1;
692
  else
693
    return stmt2;
694
}
695
 
696
/* Return TRUE if a statement represented by STMT_INFO is a part of a
697
   pattern.  */
698
 
699
static inline bool
700
is_pattern_stmt_p (stmt_vec_info stmt_info)
701
{
702
  gimple related_stmt;
703
  stmt_vec_info related_stmt_info;
704
 
705
  related_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
706
  if (related_stmt
707
      && (related_stmt_info = vinfo_for_stmt (related_stmt))
708
      && STMT_VINFO_IN_PATTERN_P (related_stmt_info))
709
    return true;
710
 
711
  return false;
712
}
713
 
714
/* Return true if BB is a loop header.  */
715
 
716
static inline bool
717
is_loop_header_bb_p (basic_block bb)
718
{
719
  if (bb == (bb->loop_father)->header)
720
    return true;
721
  gcc_checking_assert (EDGE_COUNT (bb->preds) == 1);
722
  return false;
723
}
724
 
725
/* Set inside loop vectorization cost.  */
726
 
727
static inline void
728
stmt_vinfo_set_inside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node,
729
                                    int cost)
730
{
731
  if (slp_node)
732
    SLP_TREE_INSIDE_OF_LOOP_COST (slp_node) = cost;
733
  else
734
    STMT_VINFO_INSIDE_OF_LOOP_COST (stmt_info) = cost;
735
}
736
 
737
/* Set inside loop vectorization cost.  */
738
 
739
static inline void
740
stmt_vinfo_set_outside_of_loop_cost (stmt_vec_info stmt_info, slp_tree slp_node,
741
                                     int cost)
742
{
743
  if (slp_node)
744
    SLP_TREE_OUTSIDE_OF_LOOP_COST (slp_node) = cost;
745
  else
746
    STMT_VINFO_OUTSIDE_OF_LOOP_COST (stmt_info) = cost;
747
}
748
 
749
/* Return pow2 (X).  */
750
 
751
static inline int
752
vect_pow2 (int x)
753
{
754
  int i, res = 1;
755
 
756
  for (i = 0; i < x; i++)
757
    res *= 2;
758
 
759
  return res;
760
}
761
 
762
/*-----------------------------------------------------------------*/
763
/* Info on data references alignment.                              */
764
/*-----------------------------------------------------------------*/
765
 
766
/* Reflects actual alignment of first access in the vectorized loop,
767
   taking into account peeling/versioning if applied.  */
768
#define DR_MISALIGNMENT(DR)   ((int) (size_t) (DR)->aux)
769
#define SET_DR_MISALIGNMENT(DR, VAL)   ((DR)->aux = (void *) (size_t) (VAL))
770
 
771
/* Return TRUE if the data access is aligned, and FALSE otherwise.  */
772
 
773
static inline bool
774
aligned_access_p (struct data_reference *data_ref_info)
775
{
776
  return (DR_MISALIGNMENT (data_ref_info) == 0);
777
}
778
 
779
/* Return TRUE if the alignment of the data access is known, and FALSE
780
   otherwise.  */
781
 
782
static inline bool
783
known_alignment_for_access_p (struct data_reference *data_ref_info)
784
{
785
  return (DR_MISALIGNMENT (data_ref_info) != -1);
786
}
787
 
788
/* vect_dump will be set to stderr or dump_file if exist.  */
789
extern FILE *vect_dump;
790
extern LOC vect_loop_location;
791
 
792
/*-----------------------------------------------------------------*/
793
/* Function prototypes.                                            */
794
/*-----------------------------------------------------------------*/
795
 
796
/* Simple loop peeling and versioning utilities for vectorizer's purposes -
797
   in tree-vect-loop-manip.c.  */
798
extern void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
799
extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
800
extern void vect_loop_versioning (loop_vec_info, bool, tree *, gimple_seq *);
801
extern void vect_do_peeling_for_loop_bound (loop_vec_info, tree *,
802
                                            tree, gimple_seq);
803
extern void vect_do_peeling_for_alignment (loop_vec_info);
804
extern LOC find_loop_location (struct loop *);
805
extern bool vect_can_advance_ivs_p (loop_vec_info);
806
 
807
/* In tree-vect-stmts.c.  */
808
extern unsigned int current_vector_size;
809
extern tree get_vectype_for_scalar_type (tree);
810
extern tree get_same_sized_vectype (tree, tree);
811
extern bool vect_is_simple_use (tree, gimple, loop_vec_info,
812
                                bb_vec_info, gimple *,
813
                                tree *,  enum vect_def_type *);
814
extern bool vect_is_simple_use_1 (tree, gimple, loop_vec_info,
815
                                  bb_vec_info, gimple *,
816
                                  tree *,  enum vect_def_type *, tree *);
817
extern bool supportable_widening_operation (enum tree_code, gimple, tree, tree,
818
                                            tree *, tree *, enum tree_code *,
819
                                            enum tree_code *, int *,
820
                                            VEC (tree, heap) **);
821
extern bool supportable_narrowing_operation (enum tree_code, tree, tree,
822
                                             enum tree_code *,
823
                                             int *, VEC (tree, heap) **);
824
extern stmt_vec_info new_stmt_vec_info (gimple stmt, loop_vec_info,
825
                                        bb_vec_info);
826
extern void free_stmt_vec_info (gimple stmt);
827
extern tree vectorizable_function (gimple, tree, tree);
828
extern void vect_model_simple_cost (stmt_vec_info, int, enum vect_def_type *,
829
                                    slp_tree);
830
extern void vect_model_store_cost (stmt_vec_info, int, bool,
831
                                   enum vect_def_type, slp_tree);
832
extern void vect_model_load_cost (stmt_vec_info, int, bool, slp_tree);
833
extern void vect_finish_stmt_generation (gimple, gimple,
834
                                         gimple_stmt_iterator *);
835
extern bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
836
extern int cost_for_stmt (gimple);
837
extern tree vect_get_vec_def_for_operand (tree, gimple, tree *);
838
extern tree vect_init_vector (gimple, tree, tree,
839
                              gimple_stmt_iterator *);
840
extern tree vect_get_vec_def_for_stmt_copy (enum vect_def_type, tree);
841
extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *,
842
                                 bool *, slp_tree, slp_instance);
843
extern void vect_remove_stores (gimple);
844
extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
845
extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
846
                                    tree, int, slp_tree);
847
extern void vect_get_load_cost (struct data_reference *, int, bool,
848
                                unsigned int *, unsigned int *);
849
extern void vect_get_store_cost (struct data_reference *, int, unsigned int *);
850
extern bool vect_supportable_shift (enum tree_code, tree);
851
extern void vect_get_vec_defs (tree, tree, gimple, VEC (tree, heap) **,
852
                               VEC (tree, heap) **, slp_tree, int);
853
extern tree vect_gen_perm_mask (tree, unsigned char *);
854
 
855
/* In tree-vect-data-refs.c.  */
856
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
857
extern enum dr_alignment_support vect_supportable_dr_alignment
858
                                           (struct data_reference *, bool);
859
extern tree vect_get_smallest_scalar_type (gimple, HOST_WIDE_INT *,
860
                                           HOST_WIDE_INT *);
861
extern bool vect_analyze_data_ref_dependences (loop_vec_info, bb_vec_info,
862
                                               int *);
863
extern bool vect_enhance_data_refs_alignment (loop_vec_info);
864
extern bool vect_analyze_data_refs_alignment (loop_vec_info, bb_vec_info);
865
extern bool vect_verify_datarefs_alignment (loop_vec_info, bb_vec_info);
866
extern bool vect_analyze_data_ref_accesses (loop_vec_info, bb_vec_info);
867
extern bool vect_prune_runtime_alias_test_list (loop_vec_info);
868
extern tree vect_check_gather (gimple, loop_vec_info, tree *, tree *,
869
                               int *);
870
extern bool vect_analyze_data_refs (loop_vec_info, bb_vec_info, int *);
871
extern tree vect_create_data_ref_ptr (gimple, tree, struct loop *, tree,
872
                                      tree *, gimple_stmt_iterator *,
873
                                      gimple *, bool, bool *);
874
extern tree bump_vector_ptr (tree, gimple, gimple_stmt_iterator *, gimple, tree);
875
extern tree vect_create_destination_var (tree, tree);
876
extern bool vect_strided_store_supported (tree, unsigned HOST_WIDE_INT);
877
extern bool vect_store_lanes_supported (tree, unsigned HOST_WIDE_INT);
878
extern bool vect_strided_load_supported (tree, unsigned HOST_WIDE_INT);
879
extern bool vect_load_lanes_supported (tree, unsigned HOST_WIDE_INT);
880
extern void vect_permute_store_chain (VEC(tree,heap) *,unsigned int, gimple,
881
                                    gimple_stmt_iterator *, VEC(tree,heap) **);
882
extern tree vect_setup_realignment (gimple, gimple_stmt_iterator *, tree *,
883
                                    enum dr_alignment_support, tree,
884
                                    struct loop **);
885
extern void vect_transform_strided_load (gimple, VEC(tree,heap) *, int,
886
                                         gimple_stmt_iterator *);
887
extern void vect_record_strided_load_vectors (gimple, VEC(tree,heap) *);
888
extern int vect_get_place_in_interleaving_chain (gimple, gimple);
889
extern tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
890
extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
891
                                                  tree, struct loop *);
892
 
893
/* In tree-vect-loop.c.  */
894
/* FORNOW: Used in tree-parloops.c.  */
895
extern void destroy_loop_vec_info (loop_vec_info, bool);
896
extern gimple vect_force_simple_reduction (loop_vec_info, gimple, bool, bool *);
897
/* Drive for loop analysis stage.  */
898
extern loop_vec_info vect_analyze_loop (struct loop *);
899
/* Drive for loop transformation stage.  */
900
extern void vect_transform_loop (loop_vec_info);
901
extern loop_vec_info vect_analyze_loop_form (struct loop *);
902
extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *,
903
                                         gimple *);
904
extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *,
905
                                    slp_tree);
906
extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *);
907
extern int vect_estimate_min_profitable_iters (loop_vec_info);
908
extern tree get_initial_def_for_reduction (gimple, tree, tree *);
909
extern int vect_min_worthwhile_factor (enum tree_code);
910
extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int);
911
extern int vect_get_single_scalar_iteraion_cost (loop_vec_info);
912
 
913
/* In tree-vect-slp.c.  */
914
extern void vect_free_slp_instance (slp_instance);
915
extern bool vect_transform_slp_perm_load (gimple, VEC (tree, heap) *,
916
                                          gimple_stmt_iterator *, int,
917
                                          slp_instance, bool);
918
extern bool vect_schedule_slp (loop_vec_info, bb_vec_info);
919
extern void vect_update_slp_costs_according_to_vf (loop_vec_info);
920
extern bool vect_analyze_slp (loop_vec_info, bb_vec_info);
921
extern bool vect_make_slp_decision (loop_vec_info);
922
extern void vect_detect_hybrid_slp (loop_vec_info);
923
extern void vect_get_slp_defs (VEC (tree, heap) *, slp_tree,
924
                               VEC (slp_void_p, heap) **, int);
925
 
926
extern LOC find_bb_location (basic_block);
927
extern bb_vec_info vect_slp_analyze_bb (basic_block);
928
extern void vect_slp_transform_bb (basic_block);
929
 
930
/* In tree-vect-patterns.c.  */
931
/* Pattern recognition functions.
932
   Additional pattern recognition functions can (and will) be added
933
   in the future.  */
934
typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *);
935
#define NUM_PATTERNS 10
936
void vect_pattern_recog (loop_vec_info);
937
 
938
/* In tree-vectorizer.c.  */
939
unsigned vectorize_loops (void);
940
/* Vectorization debug information */
941
extern bool vect_print_dump_info (enum vect_verbosity_levels);
942
 
943
#endif  /* GCC_TREE_VECTORIZER_H  */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.