1 /*
2  * Copyright (c) 1993-2019, 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 #ifndef REGUTIL_H_
19 #define REGUTIL_H_
20 
21 /**
22  * \file
23  * \brief Machine independent register utilities
24  *
25  * C/FTN macros, typedefs, and data declarations used to access the register
26  * candidate table, the register assigned table, and the register temporaries.
27  * This information is machine independent. The machine dependent stuff is in
28  * machreg.h.
29  */
30 
31 #include <stdint.h>
32 
33 #define RTEMPS 11
34 
35 #define LST_AREA 6
36 #define AR_AREA 7
37 
38 /*   Linked list item */
39 typedef struct LST_TAG {
40   int item;
41   struct LST_TAG *next;
42 } LST;
43 
44 #define ADDNODE(l, entry)                                          \
45   {                                                                \
46     LST *node;                                                     \
47     node = (LST *)getitem(LST_AREA, sizeof(struct LST_TAG));       \
48     assert(node != 0, "no space allocated for linked-list", 0, ERR_Severe); \
49     node->item = entry;                                            \
50     node->next = l;                                                \
51     l = node;                                                      \
52   }
53 
54 /***** node for ar assignment of common block addresses *****/
55 typedef struct arasgntag {
56   INT max;
57   INT min;
58   short weight;
59   short ar;
60   int sym; /* 0 ==> statics, 1 ==> constants, ow sym. */
61   INT offset;
62   struct arasgntag *next;
63 } ARASGN;
64 
65 /***** Register Constant Flags *****/
66 
67 /**
68    \brief For restricting the assignment of registers to constants per RTYPE.
69    Used in machreg.c to init reg[...].const_flag; checked where assignments
70    occur (i.e., globalreg.c).
71  */
72 typedef enum RegConstFlags_t {
73   RCF_NONE   = 0,    /**< constants not assigned */
74   RCF_ALL    = 1,    /**< no restriction on value */
75   RCF_NOT0   = 2,    /**< not if value is 0 */
76   RCF_NOT32K = 4,    /**< not if int value in [-32768, 32767] */
77   RCF_NOTL16 = 8,    /**< not if high 16 bits of mask value == 0 */
78   RCF_NOTH16 = 0x10, /**< not if low 16 bits of mask value == 0 */
79   RCF_NOTA8B = 0x20, /**< not if abs(v) <= 255 (8 bits) */
80   RCF_NOTA9B = 0x40  /**< not if abs(v) <= 511 (9 bits) */
81 } RegrConstFlags_t;
82 
83 /*****  Register Assigned Table  *****/
84 
85 typedef struct {
86   int reg;    /* ili index of register define or temp
87                * load.
88                */
89   int addr;   /* ILI addr of value assigned */
90   char atype; /* type of candidate:
91                *   RATA_NME, RATA_CONST, RATA_ILI,
92                *   RATA_TEMP, RATA_IND, RATA_UPLV
93                */
94   char rtype; /* register type:
95                *   RATA_IR, RATA_SP, RATA_DP, RATA_AR
96                */
97   union {
98     uint16_t all;
99     struct {
100       unsigned confl : 1; /* ILI usage conflicts with the existing*/
101                           /*     msize - opt 2 only */
102       unsigned store : 1; /* a store of the variable occurred */
103       unsigned eint : 1;  /* extended int (ST100) */
104       unsigned vint : 1;  /* vectorial int (ST140) */
105     } bits;
106   } flags;
107   INT msize; /* memory size of register; also, the dtype
108               * record if vector
109               */
110   int val;   /* value assigned to register:
111               *     names entry, constant st item,
112               *     ili entry
113               * If this is the first entry, this is the
114               * number of elements (assignments).
115               */
116 } RAT;
117 
118 /*****  Storage Information for RAT  *****/
119 
120 typedef struct {
121   RAT *stg_base;
122   int stg_avail;
123   int stg_size;
124   bool mexits;   /* true => multiple exits in current loop */
125   bool use_agra; /* true => alternate global reg alloc */
126 } RATB;
127 
128 /*****  Macros for RAT *****/
129 
130 /* NOTE: if these rtype values change,
131  *         inits of il_rtype_df,il_mv_rtype, il_free_rtype
132  *         in regutil.c and reg in machreg.c will have to change
133  */
134 /* rtypes */
135 #define RATA_IR 0
136 #define RATA_SP 1
137 #define RATA_DP 2
138 #define RATA_AR 3
139 #define RATA_KR 4
140 #define RATA_VECT 5
141 #define RATA_QP 6
142 #define RATA_CSP 7
143 #define RATA_CDP 8
144 #define RATA_CQP 9
145 #define RATA_X87 10
146 #define RATA_CX87 11
147 
148 #define RATA_RTYPES_ACTIVE RATA_X87
149 
150 /* these RTYPES are not actively processed.
151  * They are mapped onto the RATA_SP or RATA_DP rtypes.
152  * XM are used for sse xmm registers. STK are the old x87 stack-based regs.
153  */
154 #define RATA_SPXM 12
155 #define RATA_DPXM 13
156 #define RATA_RTYPES_TOTAL RATA_DPXM + 1
157 
158 #define RATA_NME 0
159 #define RATA_CONST 1
160 #define RATA_ILI 2
161 #define RATA_TEMP 3
162 #define RATA_IND 4
163 #define RATA_ARR 5
164 #define RATA_RPL 6
165 #define RATA_UPLV 7
166 
167 #define RAT_REG(i) ratb.stg_base[i].reg
168 #define RAT_ADDR(i) ratb.stg_base[i].addr
169 #define RAT_RTYPE(i) ratb.stg_base[i].rtype
170 #define RAT_ATYPE(i) ratb.stg_base[i].atype
171 #define RAT_FLAGS(i) ratb.stg_base[i].flags.all
172 #define RAT_CONFL(i) ratb.stg_base[i].flags.bits.confl
173 #define RAT_STORE(i) ratb.stg_base[i].flags.bits.store
174 #define RAT_EINT(i) ratb.stg_base[i].flags.bits.eint
175 #define RAT_VINT(i) ratb.stg_base[i].flags.bits.vint
176 #define RAT_MSIZE(i) ratb.stg_base[i].msize
177 #define RAT_VAL(i) ratb.stg_base[i].val
178 #define RAT_ISIR(i) (RAT_RTYPE(i) == RATA_IR)
179 #define RAT_ISAR(i) (RAT_RTYPE(i) == RATA_AR)
180 #define RAT_ISSP(i) (RAT_RTYPE(i) == RATA_SP)
181 #define RAT_ISDP(i) (RAT_RTYPE(i) == RATA_DP)
182 #define RAT_ISCSP(i) (RAT_RTYPE(i) == RATA_CSP)
183 #define RAT_ISCDP(i) (RAT_RTYPE(i) == RATA_CDP)
184 #define RAT_ISCQP(i) (RAT_RTYPE(i) == RATA_CQP)
185 #define RAT_ISKR(i) (RAT_RTYPE(i) == RATA_KR)
186 #define RAT_ISNME(i) (RAT_ATYPE(i) == RATA_NME)
187 #define RAT_ISCONST(i) (RAT_ATYPE(i) == RATA_CONST)
188 #define RAT_ISILI(i) (RAT_ATYPE(i) == RATA_ILI)
189 #define RAT_ISTEMP(i) (RAT_ATYPE(i) == RATA_TEMP)
190 #define RAT_ISUPLV(i) (RAT_ATYPE(i) == RATA_UPLV)
191 #define MAXRAT 67108864
192 
193 #define GET_RAT(i)                                          \
194   {                                                         \
195     i = ratb.stg_avail++;                                   \
196     if (ratb.stg_avail > MAXRAT)                            \
197       error((error_code_t)7, ERR_Severe, 0, CNULL, CNULL); \
198     NEED(ratb.stg_avail, ratb.stg_base, RAT, ratb.stg_size, \
199          ratb.stg_size + 100);                              \
200     if (ratb.stg_base == NULL)                              \
201       error((error_code_t)7, ERR_Severe, 0, CNULL, CNULL); \
202   }
203 
204 /*****  Register Candidate Table  *****/
205 
206 typedef struct {
207   char atype; /* type of candidate:
208                *   RATA_NME, RATA_CONST, RATA_ILI,
209                *   RATA_TEMP, RATA_IND, RATA_ARR,
210                *   RATA_UPL
211                */
212   char rtype; /* register type:			*/
213   /*   RATA_IR, RATA_SP, RATA_DP, RATA_AR	*/
214 
215   union {
216     unsigned all;
217     struct {
218       unsigned confl : 1;  /* ILI usage conflicts with the existing
219                             *   msize
220                             */
221       unsigned store : 1;  /* variable was stored */
222       unsigned cse : 1;    /* candidate is an induction cse
223                             * use - for opt 2 only
224                             */
225       unsigned ok : 1;     /* ok to assign register to const cand */
226       unsigned noreg : 1;  /* do not assign register to non-const cand */
227       unsigned ignore : 1; /* ignore this candidate */
228       unsigned eint : 1;   /* extended int (ST100) */
229       unsigned vint : 1;   /* vectorial int (ST140) */
230       unsigned inv : 1;    /* this candidate is for an invariant */
231       unsigned tinv : 1;   /* this candidate is for a transitive invariant */
232     } bits;
233   } flags;
234   INT msize; /* memory size of register; also, the dtype
235               * record if vector
236               */
237   int val;   /* index of candidate (depends on atype)*/
238   int temp;  /* register temp if RATA_TEMP */
239   int next;  /* next candidate */
240   int count; /* number of uses */
241   int oload; /* other load ili for the same variable */
242   int ocand; /* other load candidate that produces the same value */
243   int rat;   /* RAT for this candidate */
244 } RCAND;
245 
246 /*****  Storage Information for RCAND  *****/
247 
248 typedef struct {
249   RCAND *stg_base;
250   int stg_avail;
251   int stg_size;
252   int count;      /* count of a candidate   */
253   int weight;     /* value used to increment the count of a
254                    * candidate  */
255   int static_cnt; /* count of statics in a function; init'd
256                    * by reg_init.  */
257   int const_cnt;  /* count of constants in a function */
258   int kr;         /* any KR loads, stores, constants */
259 } RCANDB;
260 
261 /*****  Macros for RCAND  *****/
262 
263 #define RCAND_RTYPE(i) rcandb.stg_base[i].rtype
264 #define RCAND_ATYPE(i) rcandb.stg_base[i].atype
265 #define RCAND_FLAGS(i) rcandb.stg_base[i].flags.all
266 #define RCAND_CONFL(i) rcandb.stg_base[i].flags.bits.confl
267 #define RCAND_STORE(i) rcandb.stg_base[i].flags.bits.store
268 #define RCAND_CSE(i) rcandb.stg_base[i].flags.bits.cse
269 #define RCAND_OK(i) rcandb.stg_base[i].flags.bits.ok
270 #define RCAND_NOREG(i) rcandb.stg_base[i].flags.bits.noreg
271 #define RCAND_IGNORE(i) rcandb.stg_base[i].flags.bits.ignore
272 #define RCAND_EINT(i) rcandb.stg_base[i].flags.bits.eint
273 #define RCAND_VINT(i) rcandb.stg_base[i].flags.bits.vint
274 #define RCAND_INV(i) rcandb.stg_base[i].flags.bits.inv
275 #define RCAND_TINV(i) rcandb.stg_base[i].flags.bits.tinv
276 #define RCAND_MSIZE(i) rcandb.stg_base[i].msize
277 #define RCAND_VAL(i) rcandb.stg_base[i].val
278 #define RCAND_TEMP(i) rcandb.stg_base[i].temp
279 #define RCAND_NEXT(i) rcandb.stg_base[i].next
280 #define RCAND_COUNT(i) rcandb.stg_base[i].count
281 #define RCAND_OLOAD(i) rcandb.stg_base[i].oload
282 #define RCAND_OCAND(i) rcandb.stg_base[i].ocand
283 #define RCAND_RAT(i) rcandb.stg_base[i].rat
284 #define RCAND_ISNME(i) (RCAND_ATYPE(i) == RATA_NME)
285 #define RCAND_ISCONST(i) (RCAND_ATYPE(i) == RATA_CONST)
286 #define RCAND_ISILI(i) (RCAND_ATYPE(i) == RATA_ILI)
287 #define RCAND_ISTEMP(i) (RCAND_ATYPE(i) == RATA_TEMP)
288 #define RCAND_ISUPLV(i) (RCAND_ATYPE(i) == RATA_UPLV)
289 
290 #define MAXRCAND 131072
291 #define GET_RCAND(i)                                                \
292   {                                                                 \
293     i = rcandb.stg_avail++;                                         \
294     if (rcandb.stg_avail > MAXRCAND)                                \
295       error((error_code_t)7, ERR_Fatal, 0, CNULL, CNULL);           \
296     NEED(rcandb.stg_avail, rcandb.stg_base, RCAND, rcandb.stg_size, \
297          rcandb.stg_size + 100);                                    \
298     if (rcandb.stg_base == NULL)                                    \
299       error((error_code_t)7, ERR_Fatal, 0, CNULL, CNULL);           \
300     RCAND_FLAGS(i) = 0;                                             \
301     RCAND_OCAND(i) = 0;                                             \
302     RCAND_RAT(i) = 0;                                               \
303   }
304 
305 /*****  Symbol table stuff relevant to the assignment of registers  *****/
306 /*****  These are used throughout the expander and optimizer        *****/
307 
308 /* FTN's storage classes */
309 #define IS_LCL(s) (SCG(s) == SC_LOCAL || SCG(s) == SC_PRIVATE)
310 #define IS_EXTERN(s) (SC_ISCMBLK(SCG(s)) || SCG(s) == SC_EXTERN)
311 #define IS_STATIC(s) (SCG(s) == SC_STATIC)
312 #define IS_CMNBLK(s) (SC_ISCMBLK(SCG(s)))
313 #define IS_DUM(s) (SCG(s) == SC_DUMMY)
314 #define IS_LCL_OR_DUM(s) (IS_LCL(s) || IS_DUM(s))
315 #define IS_REGARG(s) (REGARGG(s) && REDUCG(s))
316 
317 #define IS_PRIVATE(s) (SCG(s) == SC_PRIVATE)
318 
319 /* macros used to access register defining/moving ili */
320 #define RTYPE_DF(rtype) ((ILI_OP)il_rtype_df[rtype])
321 #define MV_RTYPE(rtype) ((ILI_OP)il_mv_rtype[rtype])
322 
323 /*****  External Data Declarations  *****/
324 
325 extern RATB ratb;
326 extern RCANDB rcandb;
327 
328 extern int il_rtype_df[RATA_RTYPES_TOTAL];
329 extern int il_mv_rtype[RATA_RTYPES_TOTAL];
330 
331 /*****  Function Declarations (defined in regutil.c)  *****/
332 
333 /**
334    \brief ...
335  */
336 int assn_rtemp(int ili);
337 
338 /**
339    \brief ...
340  */
341 int assn_rtemp_sc(int ili, SC_KIND sc);
342 
343 /**
344    \brief ...
345  */
346 int assn_sclrtemp(int ili, SC_KIND sc);
347 
348 /**
349    \brief ...
350  */
351 int getrcand(int candl);
352 
353 /**
354    \brief ...
355  */
356 SPTR mkrtemp_arg1_sc(DTYPE dtype, SC_KIND sc);
357 
358 /**
359    \brief ...
360  */
361 SPTR mkrtemp_cpx(DTYPE dtype);
362 
363 /**
364    \brief ...
365  */
366 SPTR mkrtemp_cpx_sc(DTYPE dtype, SC_KIND sc);
367 
368 /**
369    \brief ...
370  */
371 SPTR mkrtemp(int ilix);
372 
373 /**
374    \brief ...
375  */
376 SPTR mkrtemp_sc(int ilix, SC_KIND sc);
377 
378 /**
379    \brief ...
380  */
381 void addrcand(int ilix);
382 
383 /**
384    \brief ...
385  */
386 void assn_input_rtemp(int ili, int temp);
387 
388 #if DEBUG
389 /**
390    \brief ...
391  */
392 void dmp_rat(int rat);
393 #endif
394 
395 #if DEBUG
396 /**
397    \brief ...
398  */
399 void dmprat(int rat);
400 #endif
401 
402 /**
403    \brief ...
404  */
405 void dmprcand(void);
406 
407 /**
408    \brief ...
409  */
410 void endrcand(void);
411 
412 /**
413    \brief ...
414  */
415 void mkrtemp_copy(int *rt);
416 
417 /**
418    \brief ...
419  */
420 void mkrtemp_end(void);
421 
422 /**
423    \brief ...
424  */
425 void mkrtemp_init(void);
426 
427 /**
428    \brief ...
429  */
430 void mkrtemp_reinit(int *rt);
431 
432 /**
433    \brief ...
434  */
435 void mkrtemp_update(int *rt);
436 
437 /**
438    \brief ...
439  */
440 void reg_init(int entr);
441 
442 /**
443    \brief ...
444  */
445 void storedums(int exitbih, int first_rat);
446 
447 #endif // REGUTIL_H_
448