1 /*
2  * Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 /**
19  *  \file
20  *  \brief - include file for high-level vectorizer
21  */
22 
23 #ifndef NOVECTORIZE
24 
25 #include <stdint.h>
26 
27 /* maximum nesting level we consider */
28 #define MAX_LOOPS 14
29 
30 typedef struct {
31   int depchk : 1;   /* [no]depchk */
32   int assoc : 1;    /* [no]assoc */
33   int eqvchk : 1;   /* [no]eqvchk */
34   int lstval : 1;   /* [no]lastval */
35   int recog : 1;    /* [no]recog */
36   int trans : 1;    /* [no]transform */
37   int safecall : 1; /* permit calls in loops */
38   int shortloop;    /* a.k.a. smallvect */
39   int mincnt;       /* flg.x[30] = min lp count for vectorization */
40   int ldstsplit;    /* flg.x[40] = load/store threshhold for splitting */
41   int opsplit;      /* flg.x[41] = op threshhold for splitting */
42 } VPRAGMAS;
43 
44 /*
45  * Vectorizer loop structure.
46  */
47 typedef struct {
48   int child;   /* first child of this loop (nested loop) */
49   int sibling; /* next loop at this nesting level */
50   int nest;    /* number of loops enclosing this loop */
51   int mrstart; /* start of memory references in this loop */
52   int mrcnt;   /* number of memory references in this loop */
53   int mrecnt;  /* number of mem refs in this+enclosed loops */
54   int istart;  /* start of BIVs for this loop */
55   int icnt;    /* number of BIVs in this loop */
56   int ubnd;    /* subs ref for loop upper bound  (temporary ) */
57   int lbnd;    /* subs ref for loop lower bound  (temporary ) */
58   int iubnd;   /* ILT for upper bound */
59   int aubnd;   /* AST for upper bound */
60   int ilbnd;   /* ILT for lower bound */
61   int albnd;   /* AST for upper bound */
62   int lpcnt;   /* ILI for loopcount */
63   int sclist;  /* expandable scalars */
64   int ealist;  /* expandable arrays */
65   int prebih;  /* bih of preheader */
66   int exitbih; /* bih of exit */
67   int ivlist;  /* list of initial value mem refs (store) */
68   union {
69     uint16_t all;
70     struct {
71       uint16_t cand : 1;  /* candidate */
72       uint16_t ztrip : 1; /* ztrip */
73       uint16_t perf : 1;  /* perfectly nested */
74       uint16_t del : 1;   /* deleted */
75     } bits;
76   } flags;
77   VPRAGMAS pragmas;
78 } VLOOP;
79 
80 #define VL_LOOP(i) hlv.lpbase[i].lp
81 #define VL_CHILD(i) hlv.lpbase[i].child
82 #define VL_SIBLING(i) hlv.lpbase[i].sibling
83 #define VL_NEST(i) hlv.lpbase[i].nest
84 #define VL_FLAGS(i) hlv.lpbase[i].flags.all
85 #define VL_MRSTART(i) hlv.lpbase[i].mrstart
86 #define VL_MRCNT(i) hlv.lpbase[i].mrcnt
87 #define VL_MRECNT(i) hlv.lpbase[i].mrecnt
88 #define VL_ISTART(i) hlv.lpbase[i].istart
89 #define VL_ICNT(i) hlv.lpbase[i].icnt
90 #define VL_UBND(i) hlv.lpbase[i].ubnd
91 #define VL_LBND(i) hlv.lpbase[i].lbnd
92 #define VL_IUBND(i) hlv.lpbase[i].iubnd
93 #define VL_AUBND(i) hlv.lpbase[i].aubnd
94 #define VL_ILBND(i) hlv.lpbase[i].ilbnd
95 #define VL_ALBND(i) hlv.lpbase[i].albnd
96 #define VL_LPCNT(i) hlv.lpbase[i].lpcnt
97 #define VL_SCLIST(i) hlv.lpbase[i].sclist
98 #define VL_EALIST(i) hlv.lpbase[i].ealist
99 #define VL_PREBIH(i) hlv.lpbase[i].prebih
100 #define VL_EXITBIH(i) hlv.lpbase[i].exitbih
101 #define VL_IVLIST(i) hlv.lpbase[i].ivlist
102 #define VL_PRAGMAS(i) hlv.lpbase[i].pragmas
103 
104 #define VLP_DEPCHK(i) hlv.lpbase[i].pragmas.depchk
105 #define VLP_ASSOC(i) hlv.lpbase[i].pragmas.assoc
106 #define VLP_EQVCHK(i) hlv.lpbase[i].pragmas.eqvchk
107 #define VLP_LSTVAL(i) hlv.lpbase[i].pragmas.lstval
108 #define VLP_RECOG(i) hlv.lpbase[i].pragmas.recog
109 #define VLP_TRANS(i) hlv.lpbase[i].pragmas.trans
110 #define VLP_SAFECALL(i) hlv.lpbase[i].pragmas.safecall
111 #define VLP_SHORTLP(i) hlv.lpbase[i].pragmas.shortloop
112 #define VLP_MINCNT(i) hlv.lpbase[i].pragmas.mincnt
113 #define VLP_LDSTSPLIT(i) hlv.lpbase[i].pragmas.ldstsplit
114 #define VLP_OPSPLIT(i) hlv.lpbase[i].pragmas.opsplit
115 
116 #define VP_DEPCHK(i) i.depchk
117 #define VP_ASSOC(i) i.assoc
118 #define VP_EQVCHK(i) i.eqvchk
119 #define VP_LSTVAL(i) i.lstval
120 #define VP_RECOG(i) i.recog
121 #define VP_TRANS(i) i.trans
122 #define VP_SAFECALL(i) i.safecall
123 #define VP_SHORTLP(i) i.shortloop
124 #define VP_MINCNT(i) i.mincnt
125 #define VP_LDSTSPLIT(i) i.ldstsplit
126 #define VP_OPSPLIT(i) i.opsplit
127 
128 /* flags */
129 #define VL_CAND(i) hlv.lpbase[i].flags.bits.cand
130 #define VL_PERF(i) hlv.lpbase[i].flags.bits.perf
131 #define VL_DEL(i) hlv.lpbase[i].flags.bits.del
132 #define VL_ZTRIP(i) hlv.lpbase[i].flags.bits.ztrip
133 
134 /*
135  * A direction vector is a 32-bit integer.  It consists of up to
136  * 7 4-bit fields, together with a 4-bit type field.
137  * The 4-bit fields give the directions <, =, >, and reduction;
138  * the type field gives the information as to whether the all-equals
139  * direction is allowed.
140  *
141  * For a loop nest, the innermost loop corresponds to the rightmost bit
142  * field.  This bit field is accessed with value 0.  And so forth.
143  */
144 
145 typedef BIGUINT64 DIRVEC;
146 
147 #define DIRV_ENTSIZ 4
148 #define DIRV_ENTMSK (DIRVEC)15
149 
150 /* get dirvec entry */
151 #define DIRV_ENTRYG(dirv, idx) (((dirv) >> ((idx)*DIRV_ENTSIZ)) & DIRV_ENTMSK)
152 /* put dirvec entry (assume clear) */
153 #define DIRV_ENTRYP(dirv, idx, dirent) \
154   ((dirv) |= ((dirent & DIRV_ENTMSK) << ((idx)*DIRV_ENTSIZ)))
155 /* clear dirvec entry */
156 #define DIRV_ENTRYC(dirv, idx) ((dirv) &= ~(DIRV_ENTMSK << ((idx)*DIRV_ENTSIZ)))
157 
158 #define DIRV_ALLEQ ((DIRVEC)0x8000000000000000L)
159 #define DIRV_MASK ((DIRVEC)0x0FFFFFFFFFFFFFFFL)
160 
161 /*
162  * Dirvec Bits
163  */
164 #define DIRV_LT (DIRVEC)1L
165 #define DIRV_EQ (DIRVEC)2L
166 #define DIRV_GT (DIRVEC)4L
167 #define DIRV_RD (DIRVEC)8L
168 #define DIRV_NONE (DIRVEC)0L
169 
170 #define DIRV_STAR (DIRV_LT | DIRV_EQ | DIRV_GT)
171 
172 /*
173  * Macros to get dirvec portion and information portion
174  */
175 #define DIRV_DIRPART(dirv) ((dirv) & (DIRV_MASK))
176 #define DIRV_INFOPART(dirv) ((dirv) & ~(DIRV_MASK))
177 
178 /* getitem area for HLV */
179 #define HLV_AREA 10
180 
181 /* tsort successor area */
182 #define HLV_AREA1 11
183 
184 /*
185  * Data dependence successor
186  */
187 typedef struct DDEDGE {
188   int sink;
189   union {
190     uint16_t all;
191     struct {
192       uint16_t type : 3;
193     } bits;
194   } flags;
195   DIRVEC dirvec;
196   struct DDEDGE *next;
197 } DDEDGE;
198 
199 #define DD_SINK(p) (p)->sink
200 #define DD_DIRVEC(p) (p)->dirvec
201 #define DD_FLAGS(p) (p)->flags.all
202 #define DD_NEXT(p) (p)->next
203 
204 #define DIRV_FFLOW 0
205 #define DIRV_FANTI 1
206 #define DIRV_FOUT 2
207 
208 #define DD_TYPE(i) (i)->flags.bits.type
209 
210 /* a number bigger than max # of elements in a direction vector */
211 #define DIRV_BIGPOS (MAX_LOOPS + 1)
212 
213 /*
214  * Subscript information
215  *
216  * For a given subscript and loop nest, where the loop nest is numbered
217  * from 1 to N outer to inner, the subscript has the form
218  * base + stride[N-1] * CI1 + ... + stride[0] * CIN, where CIj is the
219  * zero-based current iteration for loop j.
220  *
221  */
222 typedef struct {
223   int bases[MAX_LOOPS + 1];
224   int stride[MAX_LOOPS];
225   union {
226     uint16_t all;
227     struct {
228       uint16_t stop : 1;
229       uint16_t ptr : 1;
230       uint16_t ivuse : 1;
231     } bits;
232   } flags;
233 } SUBS;
234 
235 #define SB_STOP(i) hlv.subbase[i].flags.bits.stop
236 #define SB_PTR(i) hlv.subbase[i].flags.bits.ptr
237 #define SB_IVUSE(i) hlv.subbase[i].flags.bits.ivuse
238 #define SB_BASE(i) hlv.subbase[i].bases[0]
239 #define SB_BASES(i) hlv.subbase[i].bases
240 #define SB_STRIDE(i) hlv.subbase[i].stride
241 
242 /*
243  * Memory references
244  */
245 typedef struct {
246   int fg;         /* flowgraph node containing this ilt */
247   int ili;        /* ili for this mem ref */
248   int ilt;        /* ilt containing the ili */
249   int nme;        /* nme of ILI if load or store */
250   int stmt;       /* statement containing this memory reference */
251   int subst;      /* index into subscript info */
252   int subcnt;     /* number of subscripts */
253   int loop;       /* loop containing this memory reference */
254   int rg;         /* region containing this memory reference */
255   int fsubs;      /* folded subscript entry */
256   int cseili;     /* CSE ili for this load, if exists */
257   int next, prev; /* linked list pointers */
258   int iv;         /* induction var if this is iuse */
259   char type;      /* type of mem ref: */
260                   /* 'l' = load, */
261                   /* 's' = store, */
262   char nest;      /* nesting depth of loop containing this mr */
263   int rewr;       /* new ili replacing the ili field */
264   union {
265     uint16_t all;
266     struct {
267       /* first five are mutually exclusive */
268       uint16_t ivuse : 1; /* use of induction variable */
269       uint16_t array : 1; /* array reference */
270       uint16_t indir : 1; /* indirection */
271       uint16_t scalr : 1; /* scalar */
272       uint16_t based : 1; /* based */
273       /* */
274       uint16_t inval : 1; /* invariant assignment or use */
275       uint16_t exp : 1;   /* expandable scalar */
276       uint16_t init : 1;  /* initial value assignment (store) */
277       /* next three only apply to arrays */
278       uint16_t induc : 1; /* induction in inner loop */
279       uint16_t invar : 1; /* invar array elem in inner loop */
280       uint16_t invec : 1; /* invariant vector in two nested loops */
281       /* spare bits */
282       uint16_t spare : 4;
283     } bits;
284   } flags;
285   DDEDGE *succ; /* successor list */
286 } MEMREF;
287 
288 #define MR_ILI(i) hlv.mrbase[i].ili
289 #define MR_ILT(i) hlv.mrbase[i].ilt
290 #define MR_FG(i) hlv.mrbase[i].fg
291 #define MR_NME(i) hlv.mrbase[i].nme
292 #define MR_STMT(i) hlv.mrbase[i].stmt
293 #define MR_TYPE(i) hlv.mrbase[i].type
294 #define MR_NEST(i) hlv.mrbase[i].nest
295 #define MR_FLAGS(i) hlv.mrbase[i].flags.all
296 #define MR_SUBST(i) hlv.mrbase[i].subst
297 #define MR_SUBCNT(i) hlv.mrbase[i].subcnt
298 #define MR_LOOP(i) hlv.mrbase[i].loop
299 #define MR_RG(i) hlv.mrbase[i].rg
300 #define MR_SUCC(i) hlv.mrbase[i].succ
301 #define MR_FSUBS(i) hlv.mrbase[i].fsubs
302 #define MR_CSEILI(i) hlv.mrbase[i].cseili
303 #define MR_NEXT(i) hlv.mrbase[i].next
304 #define MR_PREV(i) hlv.mrbase[i].prev
305 #define MR_IV(i) hlv.mrbase[i].iv
306 #define MR_SCLR(i) hlv.mrbase[i].iv
307 #define MR_EXPARR(i) hlv.mrbase[i].iv
308 #define MR_REWR(i) hlv.mrbase[i].rewr
309 
310 #define MR_IVUSE(i) hlv.mrbase[i].flags.bits.ivuse
311 #define MR_ARRAY(i) hlv.mrbase[i].flags.bits.array
312 #define MR_INDIR(i) hlv.mrbase[i].flags.bits.indir
313 #define MR_SCALR(i) hlv.mrbase[i].flags.bits.scalr
314 #define MR_BASED(i) hlv.mrbase[i].flags.bits.based
315 
316 #define MR_EXP(i) hlv.mrbase[i].flags.bits.exp
317 #define MR_INVAL(i) hlv.mrbase[i].flags.bits.inval
318 #define MR_INIT(i) hlv.mrbase[i].flags.bits.init
319 
320 #define MR_INDUC(i) hlv.mrbase[i].flags.bits.induc
321 #define MR_INVAR(i) hlv.mrbase[i].flags.bits.invar
322 #define MR_INVEC(i) hlv.mrbase[i].flags.bits.invec
323 
324 /*
325  * Vectorizer induction information
326  */
327 typedef struct {
328   int nm;       /* names entry */
329   int load;     /* ili of the load */
330   int init;     /* initial value -- load or single def */
331   int originit; /* original initial value */
332   union {
333     uint16_t all;
334     struct {
335       uint16_t ptr : 1;    /* induction variable is a pointer */
336       uint16_t delete : 1; /* induction variable can be deleted */
337       uint16_t niu : 1;    /* non-induction use */
338       uint16_t midf : 1;   /* multiple inductions */
339       uint16_t alias : 1;  /* induction alias */
340       uint16_t noinv : 1;  /* Initial value is not invariant in loop */
341       uint16_t omit : 1;   /* Omit this iv */
342       uint16_t visit : 1;  /* Visited */
343       uint16_t alast : 1;  /* Last value --> true if count-1 used */
344       uint16_t save : 1;   /* must leave def in (perm) */
345       uint16_t tsave : 1;  /* must leave def in (temp) */
346     } bits;
347   } flags;
348   short opc;   /* ili opcode of skip expression */
349   int totskip; /* total skip */
350   int skip;    /* skip ili */
351 } VIND;
352 
353 #define VIND_NM(i) hlv.indbase[i].nm
354 #define VIND_LOAD(i) hlv.indbase[i].load
355 #define VIND_INIT(i) hlv.indbase[i].init
356 #define VIND_ORIGINIT(i) hlv.indbase[i].originit
357 #define VIND_PTR(i) hlv.indbase[i].flags.bits.ptr
358 #define VIND_DELETE(i) hlv.indbase[i].flags.bits.delete
359 #define VIND_NIU(i) hlv.indbase[i].flags.bits.niu
360 #define VIND_MIDF(i) hlv.indbase[i].flags.bits.midf
361 #define VIND_ALIAS(i) hlv.indbase[i].flags.bits.alias
362 #define VIND_NOINV(i) hlv.indbase[i].flags.bits.noinv
363 #define VIND_OMIT(i) hlv.indbase[i].flags.bits.omit
364 #define VIND_VISIT(i) hlv.indbase[i].flags.bits.visit
365 #define VIND_ALAST(i) hlv.indbase[i].flags.bits.alast
366 #define VIND_SAVE(i) hlv.indbase[i].flags.bits.save
367 #define VIND_OPC(i) hlv.indbase[i].opc
368 #define VIND_TOTSKIP(i) hlv.indbase[i].totskip
369 #define VIND_SKIP(i) hlv.indbase[i].skip
370 
371 /*
372  * Statement list for distribution and interchange.
373  */
374 typedef struct {
375   int ilt;    /* ilt to which this statement refers */
376   int mrlist; /* linked list of memory references */
377   int next;   /* next statement */
378   int prev;   /* previous statement */
379   int flag;   /* useful word */
380   union {
381     uint16_t all;
382     struct {
383       uint16_t reduc : 1; /* statement is a reduction */
384     } bits;
385   } flags;
386 } STMT;
387 
388 #define ST_ILT(i) hlv.stbase[i].ilt
389 #define ST_MRLIST(i) hlv.stbase[i].mrlist
390 #define ST_NEXT(i) hlv.stbase[i].next
391 #define ST_PREV(i) hlv.stbase[i].prev
392 #define ST_FLAG(i) hlv.stbase[i].flag
393 #define ST_REDUC(i) hlv.stbase[i].flags.bits.reduc
394 
395 typedef struct VPSI {
396   struct VPSI *next;
397   int node;
398   int flag;
399 } VPSI, *VPSI_P;
400 
401 /*
402  * Loop interchange and distribute is performed on loop regions.
403  */
404 typedef struct {
405   int next;         /* next region at this level */
406   int prev;         /* previous region at this level */
407   int outer;        /* parent region */
408   int inner;        /* child region */
409   int orig;         /* original loop for this region */
410   int slist;        /* list of statements in this region */
411   int nodenum;      /* node number */
412   int cycle;        /* cycle number */
413   int nest;         /* nesting depth */
414   int orignest;     /* original nesting depth */
415   int top, ztrip;   /* labels */
416   int cnt;          /* loop count temp */
417   int llvi;         /* low-level vectorizer info */
418   int bih;          /* bih */
419   int bihtl;        /* tail bih */
420   int bihafter;     /* bih of block after tail */
421   int miv;          /* master induction variable */
422   int miv_store;    /* ili of initial store into miv */
423   int cnt_load;     /* ili of load into loop count */
424   int slbnd, subnd; /* lower & upper bound statement */
425   int ilbnd, iubnd; /* lower & upper bound subscripts */
426   int mreg;         /* marked region # */
427   int label;        /* label from orig bih */
428   int blockrg;      /* the block loop for a strip loop */
429   union {
430     uint16_t all;
431     struct {
432       uint16_t cif : 1;        /* contains if statement */
433       uint16_t marked : 1;     /* general marker */
434       uint16_t recurrence : 1; /* recurrence region */
435       uint16_t strip : 1;      /* must be strip-mined */
436       uint16_t self : 1;       /* in a self-cycle */
437       uint16_t block : 1;      /* block-loop of stripmine */
438       uint16_t parallel : 1;   /* parallelizable */
439       uint16_t call : 1;       /* contains call */
440     } bits;
441   } flags;
442   VPSI_P succ; /* list of successors of this region */
443 } REGION;
444 
445 #define RG_NEXT(i) hlv.rgbase[i].next
446 #define RG_PREV(i) hlv.rgbase[i].prev
447 #define RG_OUTER(i) hlv.rgbase[i].outer
448 #define RG_INNER(i) hlv.rgbase[i].inner
449 #define RG_ORIG(i) hlv.rgbase[i].orig
450 #define RG_SLIST(i) hlv.rgbase[i].slist
451 #define RG_NODENUM(i) hlv.rgbase[i].nodenum
452 #define RG_STRIPLEN(i) hlv.rgbase[i].nodenum
453 #define RG_CYCLE(i) hlv.rgbase[i].cycle
454 #define RG_NEST(i) hlv.rgbase[i].nest
455 #define RG_ORIGNEST(i) hlv.rgbase[i].orignest
456 #define RG_TOP(i) hlv.rgbase[i].top
457 #define RG_ZTRIP(i) hlv.rgbase[i].ztrip
458 #define RG_CNT(i) hlv.rgbase[i].cnt
459 #define RG_SUCC(i) hlv.rgbase[i].succ
460 #define RG_FLAGS(i) hlv.rgbase[i].flags.all
461 #define RG_BIH(i) hlv.rgbase[i].bih
462 #define RG_BIHHD(i) hlv.rgbase[i].bih
463 #define RG_BIHTL(i) hlv.rgbase[i].bihtl
464 #define RG_BIHAFTER(i) hlv.rgbase[i].bihafter
465 #define RG_LLVI(i) hlv.rgbase[i].llvi
466 #define RG_SLBND(i) hlv.rgbase[i].slbnd
467 #define RG_SUBND(i) hlv.rgbase[i].subnd
468 #define RG_LBND(i) hlv.rgbase[i].ilbnd
469 #define RG_UBND(i) hlv.rgbase[i].iubnd
470 #define RG_MIV(i) hlv.rgbase[i].miv
471 #define RG_MREG(i) hlv.rgbase[i].mreg
472 #define RG_MIVSTORE(i) hlv.rgbase[i].miv_store
473 #define RG_CNTLOAD(i) hlv.rgbase[i].cnt_load
474 #define RG_CIF(i) hlv.rgbase[i].flags.bits.cif
475 #define RG_MARKED(i) hlv.rgbase[i].flags.bits.marked
476 #define RG_RECURRENCE(i) hlv.rgbase[i].flags.bits.recurrence
477 #define RG_SELF(i) hlv.rgbase[i].flags.bits.self
478 #define RG_STRIP(i) hlv.rgbase[i].flags.bits.strip
479 #define RG_BLOCK(i) hlv.rgbase[i].flags.bits.block
480 #define RG_PARALLEL(i) hlv.rgbase[i].flags.bits.parallel
481 #define RG_CALL(i) hlv.rgbase[i].flags.bits.call
482 #define RG_LABEL(i) hlv.rgbase[i].label
483 #define RG_BLOCKRG(i) hlv.rgbase[i].blockrg
484 
485 /*
486  * Temp management
487  */
488 typedef struct {
489   int iavl;      /* available pointer */
490   int iavl_max;  /* high-water for this function */
491   int iavl_base; /* base for this function */
492   char *pfx;     /* prefix for this temp */
493   int dtype;     /* data type for this temp */
494 } VTMP;
495 
496 #define VT_INT 0 /* integer temp */
497 #define VT_PTR 1 /* pointer temp */
498 #define VT_SP 2  /* single precision */
499 #define VT_DP 3  /* double precision */
500 #define VT_MAX 4
501 
502 #define VT_PHINIT 0 /* initial value phase */
503 #define VT_PHIND 1  /* induction phase */
504 #define VT_PHASES 2 /* number of phases of temps */
505 
506 extern VTMP hlv_temps[VT_PHASES][VT_MAX];
507 /* array temps */
508 extern VTMP hlv_vtemps;
509 
510 /*
511  * Expandable scalars
512  */
513 typedef struct {
514   int nme;  /* nme of expandable scalar */
515   int next; /* next scalar in list */
516   union {
517     uint16_t all;
518     struct {
519       uint16_t flag : 1; /* needs last value */
520       uint16_t span : 1; /* spans loops */
521     } bits;
522   } flags;
523   int arrsym;  /* symbol for array if this spans loops */
524   int masksym; /* symbol for mask array if conditional assignment */
525 } SCALAR;
526 
527 #define SCLR_NME(i) hlv.scbase[i].nme
528 #define SCLR_NEXT(i) hlv.scbase[i].next
529 #define SCLR_FLAG(i) hlv.scbase[i].flags.bits.flag
530 #define SCLR_SPAN(i) hlv.scbase[i].flags.bits.span
531 #define SCLR_ARRSYM(i) hlv.scbase[i].arrsym
532 #define SCLR_MASKSYM(i) hlv.scbase[i].masksym
533 
534 /*
535  * Loop masks: ith bit (0 <= i < MAX_LOOPS) reflects information
536  *	about the ith outer loop.
537  */
538 typedef UINT16 LOOPMASK;
539 
540 #define LOOPMASKG(m, i) ((m >> i) & 1)
541 #define LOOPMASKC(m, i) (m &= ~(1 << i))
542 #define LOOPMASKS(m, i) (m |= (1 << i))
543 
544 /*
545  * Expandable arrays
546  */
547 typedef struct {
548   int nest;          /* length of invloops mask */
549   LOOPMASK invloops; /* ith bit is 1 if invariant on ith outer loop
550                       * at stddef */
551   int tmpsym;        /* symbol for replacement array */
552   int next;          /* next expandable array in loop */
553   union {
554     uint16_t all;
555     struct {
556       uint16_t lastval : 1;    /* needs last value */
557       uint16_t uniquesecn : 1; /* all array refs have a unique section
558                                 *  descriptor */
559     } bits;
560   } flags;
561 } EXPARR;
562 
563 #define EXPARR_NEST(e) hlv.eabase[e].nest
564 #define EXPARR_INVLOOPS(e) hlv.eabase[e].invloops
565 #define EXPARR_TMPSYM(e) hlv.eabase[e].tmpsym
566 #define EXPARR_NEXT(e) hlv.eabase[e].next
567 #define EXPARR_LASTVAL(e) hlv.eabase[e].flags.bits.lastval
568 #define EXPARR_UNIQUESECN(e) hlv.eabase[e].flags.bits.uniquesecn
569 
570 typedef struct {
571   VLOOP *lpbase;
572   int lpavail, lpsize;
573   int looplist;
574   MEMREF *mrbase;
575   int mravail, mrsize;
576   VIND *indbase;
577   int indavail, indsize;
578   SUBS *subbase;
579   int subavail, subsize;
580   int stavail, stsize;
581   STMT *stbase;
582   int rgavail, rgsize;
583   REGION *rgbase;
584   int scavail, scsize;
585   SCALAR *scbase;
586   int eaavail, easize;
587   EXPARR *eabase;
588   int *fgmap;
589   int fgn;
590   int natural_loop;
591   double (*score_loop)(int *);
592 } HLVECT;
593 
594 extern HLVECT hlv;
595 
596 extern void vect_flg_defaults(void);
597 extern void vectorize(void);
598 extern void mark_vinduc(int loop);
599 extern void unmark_vinduc(int loop);
600 extern int hlv_getsym(int phase, int type);
601 extern int hlv_getvsym(int baseDtype);
602 extern void vdel_bih(int bihx);
603 extern void open_vpragma(int lp);
604 extern LOGICAL is_parent_loop(int lpParent, int lpChild);
605 
606 #if DEBUG
607 extern void dump_memref_hdr(void);
608 extern void dump_one_memref(int i);
609 extern void dump_memrefs(int start, int cnt);
610 extern void dump_memrefs(int start, int cnt);
611 extern void dump_vloops(int first, int base);
612 extern void dump_vinduc(int start, int cnt);
613 #endif
614 extern void build_dd(int loop);
615 extern void dd_edge(int src, int sink, DIRVEC vec);
616 extern DIRVEC dirv_inverse(DIRVEC vec);
617 extern DIRVEC dirv_fulldep(int level);
618 extern DIRVEC dirv_exo(int level, int flag);
619 extern int dirv_chkzero(DIRVEC dir, int n);
620 extern void dirv_gen(DIRVEC dir, int *map, int nest, int ig, void (*f)(DIRVEC));
621 extern LOGICAL dd_array_conflict(int astliTriples, int astArrSrc,
622                                  int astArrSink, int bSinkAfterSrc);
623 extern int dd_symbolic(int il);
624 #if DEBUG
625 extern char *dirv_print(DIRVEC dir);
626 extern void dump_dd(DDEDGE *p);
627 #endif
628 extern void hlvtrans(int loop);
629 extern void regmark(int rg, int rgm, int flag);
630 extern int remove_accum(int astx, int subast, int optype);
631 extern int is_perfect(int rg);
632 extern int get_generic_minmax(int optype);
633 extern double score_loop_i860(int *a);
634 extern double score_loop_sparc(int *a);
635 extern double score_loop_vpu(int *a);
636 extern double score_loop_hpf(int *a);
637 extern LOGICAL has_reduction(int rg, int *map, int nest);
638 #if DEBUG
639 extern void dump_vregionf(int r, int level, LOGICAL flag);
640 #endif
641 extern void vpar(void);
642 extern void llvect(void);
643 extern void gen_llinfo(int reg);
644 extern void reg_parmark(int rg);
645 extern LOGICAL has_recurrence(int rg, int nest, int *mapx, int *mapy);
646 extern int parmethod(int rg, int nest, int *mapx, int *mapy);
647 #if DEBUG
648 extern void dump1_llv(int k);
649 extern void dump_llv(void);
650 extern void dump_one_vloop(int i, int level);
651 #endif
652 #endif
653 #define STRIPSIZE 1024
654