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