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 /** \file
19 * \brief Register allocation module used by the expander and the optimizer
20 *
21 * Contains:
22 * - void reg_init(int) - initializes the register information for a function
23 * - void addrcand(int) - adds an ILI to the appropriate candidate list
24 * - void static dump_cand(int) - dumps a candidate list for debug purposes
25 * - void dmprcand() - dumps the register candidate lists for debug
26 * purposes
27 * - void dmprat(int) - dumps the register assign table for a block
28 * - int getrcand(int) - gets a candidate for register assignment from a
29 * candidate list
30 * - void endrcand() - clean up the register candidate lists
31 * - void storedums(int, int) - store back dummies assigned registers (SCFTN
32 * only)
33 * - void mkrtemp_init() - initialize for register temporaries created for a
34 * function
35 * - int mkrtemp(int) - create a register temporary (based on ili)
36 * - int mkrtemp_sc(int, int) - same as mkrtemp(), but storage class is passed
37 * - int mkrtemp_cpx(int)- create a complex register temporary (base on dtype)
38 * - int mkrtemp_cpx_sc(int, int)- same as mkrtemp_cpx(), but storage class is
39 * passed
40 * - void mkrtemp_end() - end the register temporaries for the current
41 * function
42 * - void mkrtemp_update(int[]) - record maximum values of register temporaries
43 * - void mkrtemp_reinit(int[]) - initialize for register temporaries from the
44 * recorded set of values
45 * - void mkrtemp_copy(int[]) - copy maximum values of register temporaries
46 * - int assn_rtemp(int) - assign a register temporary for an ili and make a
47 * candidate.
48 * - int assn_rtemp_sc(int, int) - same as assn_rtemp, but storage class is
49 * passed
50 */
51 #include "gbldefs.h"
52 #include "error.h"
53 #include "global.h"
54 #include "symtab.h"
55 #include "ili.h"
56 #include "expand.h"
57 #include "regutil.h"
58 #include "machreg.h"
59 #include "machar.h"
60
61 #define RATA_ALL RATA_KR
62
63 static char *atype_names[] = {"nme ", "cons", "ili ", "temp",
64 "ind ", "arr ", "rpl "};
65 static char *get_msize(int);
66
67 /* NOTE: init. is dependent on defines in regutil.h */
68 int il_rtype_df[RATA_RTYPES_TOTAL] = {
69 IL_IRDF, IL_SPDF, /* RATA_IR , RATA_SP */
70 IL_DPDF, IL_ARDF, /* RATA_DP , RATA_AR */
71 IL_KRDF, 0, /* RATA_KR , RATA_VECT */
72 0, 0, /* RATA_QP , RATA_CSP */
73 0, 0, /* RATA_CDP , RATA_CQP */
74 0, 0, /* RATA_X87 , RATA_CX87*/
75 };
76 int il_mv_rtype[RATA_RTYPES_TOTAL] = {
77 IL_MVIR, IL_MVSP, /* RATA_IR , RATA_SP */
78 IL_MVDP, IL_MVAR, /* RATA_DP , RATA_AR */
79 IL_MVKR, 0, /* RATA_KR , RATA_VECT */
80 0, 0, /* RATA_QP , RATA_CSP */
81 0, 0, /* RATA_CDP , RATA_CQP */
82 0, 0, /* RATA_X87 , RATA_CX87*/
83 };
84
85 void
reg_init(int entr)86 reg_init(int entr)
87 {
88 mr_init();
89 rcandb.static_cnt = rcandb.const_cnt = 0;
90 aux.curr_entry->arasgn = NULL;
91 }
92
93 /**
94 \brief Add a potential candidate, an ILI, to the appropriate candidate list.
95 */
96 void
addrcand(int ilix)97 addrcand(int ilix)
98 {
99 int atype, /* type of the candidate */
100 rtype, /* register type of the ili */
101 msize, /* memory size of the ili */
102 nme, /* names entry of the ili */
103 rcand; /* RCAND for the ili */
104
105 switch (ILI_OPC(ilix)) { /* case according to the ILI opcode */
106
107 case IL_ACEXT:
108 /* these are never seen by optimizer in c , for now, just return */
109 assert(STYPEG(CONVAL1G(ILI_OPND(ilix, 1))) == ST_LABEL,
110 "unexpected acext in addrcand", ilix, ERR_Severe);
111 return;
112 case IL_LD: /* load data register */
113 rtype = RATA_IR;
114 msize = ILI_OPND(ilix, 3);
115 goto ac_load;
116
117 case IL_LDKR:
118 rtype = RATA_KR;
119 msize = MSZ_I8;
120 goto ac_load;
121
122 case IL_VCON:
123 case IL_VLD:
124 case IL_VLDU:
125 case IL_VST:
126 case IL_VSTU:
127 /* ignore these */
128 return;
129
130 case IL_LDA: /* load address register */
131 rtype = RATA_AR;
132 msize = MSZ_PTR;
133 goto ac_load;
134 case IL_LDQ: /* load m128*/
135 rtype = RATA_DP;
136 msize = MSZ_F16;
137 goto ac_load;
138 case IL_LD256: /* load m256*/
139 rtype = RATA_DP;
140 msize = MSZ_F32;
141 goto ac_load;
142 case IL_LD256A: /* load m256*/
143 rtype = RATA_DP;
144 msize = MSZ_F32;
145 goto ac_load;
146 case IL_LDSCMPLX:
147 rtype = RATA_CSP;
148 msize = MSZ_F8;
149 goto ac_load;
150 case IL_LDDCMPLX:
151 rtype = RATA_CDP;
152 msize = MSZ_F16;
153 goto ac_load;
154
155 case IL_LDSP: /* load single precision */
156 rtype = RATA_SP;
157 msize = MSZ_F4;
158 goto ac_load;
159
160 case IL_LDDP: /* load double precision */
161 rtype = RATA_DP;
162 msize = MSZ_F8;
163
164 ac_load: /* common entry for the loads */
165
166 /*
167 * check if the ili is already a candidate; if so, just increment its
168 * (the candidate entry for the ili) count
169 */
170 if ((rcand = ILI_RAT(ilix)) != 0) {
171 RCAND_COUNT(rcand) += rcandb.weight;
172 if (RCAND_ATYPE(rcand) == RATA_ILI && RCAND_VAL(rcand) != ilix) {
173 RCAND_OLOAD(rcand) = ilix;
174 }
175 } else if ((rcand = NME_RAT(nme = ILI_OPND(ilix, 2))) != 0) {
176 if (RCAND_MSIZE(rcand) != msize) {
177 /*
178 * the nme was entered by a store and then another type of
179 * load ILI followed, or just another type of load ILI
180 * occurred. This occurs when type casting the & of a
181 * variable and then using the lvalue in a context which is
182 * inconsistent with its data type.
183 */
184 RCAND_CONFL(rcand) = 1;
185 } else {
186 /*
187 * the store for this load has already been processed. enter
188 * the load ili into the candidate list and back fill the ili
189 */
190 ILI_RAT(ilix) = rcand;
191 if (RCAND_ATYPE(rcand) == RATA_ILI && RCAND_VAL(rcand) != ilix) {
192 RCAND_OLOAD(rcand) = ilix;
193 } else {
194 RCAND_VAL(rcand) = ilix;
195 RCAND_ATYPE(rcand) = RATA_ILI;
196 }
197 RCAND_COUNT(rcand) += rcandb.weight;
198 }
199 } else {
200
201 /*
202 * the ili is a new entry; enter it into the appropriate
203 * candidate list and back fill the ili and its names entry
204 */
205 atype = RATA_ILI;
206 goto add_entry;
207 }
208 break;
209
210 add_entry: /* add an entry to the candidate table; there
211 * are three variables -- rtype, atype, and
212 * ilix
213 */
214 GET_RCAND(rcand);
215 RCAND_NEXT(rcand) = reg[rtype].rcand;
216 reg[rtype].rcand = rcand;
217 RCAND_RTYPE(rcand) = rtype;
218 RCAND_ATYPE(rcand) = atype;
219 RCAND_MSIZE(rcand) = msize;
220 RCAND_OLOAD(rcand) = 0;
221
222 if (atype != RATA_NME) { /* for loads, back fill the ili */
223 ILI_RAT(ilix) = rcand;
224 RCAND_STORE(rcand) = 0;
225 } else /* for RATA_NME (stores) don't back fill the
226 * store ILI */
227 RCAND_STORE(rcand) = 1;
228
229 RCAND_VAL(rcand) = ilix;
230 NME_RAT(nme) = rcand;
231 RCAND_COUNT(rcand) = rcandb.weight;
232 break;
233
234 case IL_ST: /* store data register */
235 rtype = RATA_IR;
236 msize = ILI_OPND(ilix, 4);
237 goto ac_store;
238
239 case IL_STKR:
240 rtype = RATA_KR;
241 msize = MSZ_I8;
242 goto ac_store;
243
244 case IL_STA: /* store address register */
245 rtype = RATA_AR;
246 msize = MSZ_PTR;
247 goto ac_store;
248 case IL_STQ: /* store m128 */
249 rtype = RATA_DP;
250 msize = MSZ_F16;
251 goto ac_store;
252 case IL_ST256: /* store m256 */
253 rtype = RATA_DP;
254 msize = MSZ_F32;
255 goto ac_store;
256
257 case IL_STSP: /* store single precision */
258 case IL_SSTS_SCALAR:
259 rtype = RATA_SP;
260 msize = MSZ_F4;
261 goto ac_store;
262 case IL_STSCMPLX:
263 rtype = RATA_CSP;
264 msize = MSZ_F8;
265 goto ac_store;
266 case IL_STDCMPLX:
267 rtype = RATA_CDP;
268 msize = MSZ_F16;
269 goto ac_store;
270 case IL_STDP: /* store double precision */
271 case IL_DSTS_SCALAR:
272 rtype = RATA_DP;
273 msize = MSZ_F8;
274 ac_store: /* common entry for the stores */
275 if ((rcand = NME_RAT(nme = ILI_OPND(ilix, 3))) != 0)
276 if (RCAND_MSIZE(rcand) != msize) {
277 /* this store conflicts with the existing candidate */
278 RCAND_CONFL(rcand) = 1;
279 } else {
280 /*
281 * the store has already been added to the candidate list
282 * (denoted by the rat field of its names entry)
283 */
284 RCAND_COUNT(rcand) += rcandb.weight;
285 RCAND_STORE(rcand) = 1;
286 }
287 else {
288
289 /*
290 * the store is a new entry; enter the names entry into the
291 * candidate list (the candidate type is names) and back fill the
292 * name entry
293 */
294 atype = RATA_NME;
295 goto add_entry;
296 }
297 break;
298 case IL_ACON:
299 rtype = RATA_AR;
300 msize = MSZ_PTR;
301 goto add_constant;
302 case IL_ICON:
303 rtype = RATA_IR;
304 msize = MSZ_WORD;
305 goto add_constant;
306 case IL_KCON:
307 rtype = RATA_KR;
308 msize = MSZ_I8;
309 goto add_constant;
310 case IL_FCON:
311 rtype = RATA_SP;
312 msize = MSZ_F4;
313 goto add_constant;
314 case IL_SCMPLXCON:
315 rtype = RATA_CSP;
316 msize = MSZ_F8;
317 goto add_constant;
318 case IL_DCMPLXCON:
319 rtype = RATA_CDP;
320 msize = MSZ_F16;
321 goto add_constant;
322 case IL_DCON:
323 rtype = RATA_DP;
324 msize = MSZ_F8;
325 add_constant:
326 rcand = ILI_RAT(ilix);
327 if (rcand) {
328 RCAND_COUNT(rcand) += rcandb.weight;
329 } else {
330 GET_RCAND(rcand); /* RCAND_OK = 0; prove it's ok to assn reg */
331 RCAND_RTYPE(rcand) = rtype;
332 RCAND_ATYPE(rcand) = RATA_CONST;
333 RCAND_MSIZE(rcand) = msize;
334 RCAND_VAL(rcand) = ilix;
335 RCAND_COUNT(rcand) = rcandb.weight;
336 ILI_RAT(ilix) = rcand;
337 RCAND_NEXT(rcand) = reg[rtype].rcand;
338 reg[rtype].rcand = rcand;
339 }
340 break;
341
342 #ifdef LONG_DOUBLE_FLOAT128
343 case IL_FLOAT128CON:
344 case IL_FLOAT128LD:
345 case IL_FLOAT128ST:
346 /* float128 values are not register candidates. */
347 return;
348 #endif /* LONG_DOUBLE_FLOAT128 */
349
350 default:
351 if (ILI_RAT(ilix) == 0) {
352 assert(ILI_RAT(ilix) != 0, "addrcand: no cand for ili", ilix, ERR_Severe);
353 return;
354 }
355 RCAND_COUNT(ILI_RAT(ilix)) += rcandb.weight;
356 break;
357 }
358 }
359
360 static void
dump_cand(int candl)361 dump_cand(int candl)
362 {
363 int temp, val, sym, i;
364 fprintf(gbl.dbgfil, "Type Value Count\n");
365 do {
366 val = RCAND_VAL(candl);
367 fprintf(gbl.dbgfil, "%4s ", atype_names[temp = RCAND_ATYPE(candl)]);
368 fprintf(gbl.dbgfil, "%-5u %4d", val, (int)RCAND_COUNT(candl));
369 sym = 0;
370 switch (temp) {
371 case RATA_NME:
372 fprintf(gbl.dbgfil, " - %-9s", ilis[temp = ILI_OPC(val)].name);
373 if (IL_TYPE(temp) == ILTY_STORE) {
374 fprintf(gbl.dbgfil, "\"");
375 sym = print_nme((int)ILI_OPND(val, 3));
376 fprintf(gbl.dbgfil, "\"");
377 }
378 break;
379 case RATA_IND:
380 fprintf(gbl.dbgfil, " - \"");
381 sym = print_nme((int)ILI_OPND(val, 2));
382 fprintf(gbl.dbgfil, "\"");
383 for (i = RCAND_TEMP(candl); i; i = RCAND_NEXT(i))
384 fprintf(gbl.dbgfil, ", %u^", RCAND_VAL(i));
385 break;
386 case RATA_ARR:
387 fprintf(gbl.dbgfil, " - \"");
388 sym = print_nme((int)ILI_OPND(val, 2));
389 fprintf(gbl.dbgfil, "\"");
390 i = RCAND_TEMP(candl);
391 fprintf(gbl.dbgfil, ", %u^ %u^", RCAND_VAL(i), RCAND_TEMP(i));
392 break;
393 case RATA_ILI:
394 fprintf(gbl.dbgfil, " - %-9s", ilis[temp = ILI_OPC(val)].name);
395 if (IL_TYPE(temp) == ILTY_LOAD) {
396 fprintf(gbl.dbgfil, "\"");
397 sym = print_nme((int)ILI_OPND(val, 2));
398 fprintf(gbl.dbgfil, "\"");
399 }
400 break;
401 case RATA_TEMP:
402 fprintf(gbl.dbgfil, " - %-9s", ilis[ILI_OPC(val)].name);
403 fprintf(gbl.dbgfil, " \"%s\"", getprint((int)RCAND_TEMP(candl)));
404 break;
405 case RATA_RPL:
406 fprintf(gbl.dbgfil, " - %-9s", ilis[ILI_OPC(val)].name);
407 fprintf(gbl.dbgfil, " %u^", RCAND_TEMP(candl));
408 break;
409 case RATA_CONST:
410 fprintf(gbl.dbgfil, " - %-9s", ilis[ILI_OPC(val)].name);
411 temp = ILI_OPND(val, 1);
412 if (ILI_OPC(val) != IL_ACON)
413 fprintf(gbl.dbgfil, " \"%s\"", getprint(temp));
414 else {
415 if (CONVAL1G(temp))
416 fprintf(gbl.dbgfil, " \"%s", getprint((int)CONVAL1G(temp)));
417 else
418 fprintf(gbl.dbgfil, " \"%d", CONVAL1G(temp));
419 fprintf(gbl.dbgfil, ",%" ISZ_PF "d\"", ACONOFFG(temp));
420 }
421 break;
422 }
423 if (RCAND_RTYPE(candl) != RATA_VECT)
424 fprintf(gbl.dbgfil, " <%s>", get_msize(RCAND_MSIZE(candl)));
425 else
426 fprintf(gbl.dbgfil, " <DT %d>", RCAND_MSIZE(candl));
427 if (RCAND_CONFL(candl))
428 fprintf(gbl.dbgfil, "<confl>");
429 if (sym) {
430 if (ADDRTKNG(sym))
431 fprintf(gbl.dbgfil, "<&>");
432 if (RCAND_STORE(candl))
433 fprintf(gbl.dbgfil, "<stored>");
434 }
435 if (RCAND_OK(candl))
436 fprintf(gbl.dbgfil, "<cnst ok>");
437 if (RCAND_NOREG(candl))
438 fprintf(gbl.dbgfil, "<noreg>");
439 if (RCAND_CSE(candl))
440 fprintf(gbl.dbgfil, "<cse>");
441 if (RCAND_IGNORE(candl))
442 fprintf(gbl.dbgfil, "<ignore>");
443 if (RCAND_INV(candl))
444 fprintf(gbl.dbgfil, "<inv>");
445 fprintf(gbl.dbgfil, "\n");
446 candl = RCAND_NEXT(candl);
447 } while (candl != 0);
448 fflush(gbl.dbgfil);
449 }
450
451 void
dmprcand(void)452 dmprcand(void)
453 {
454 int candl;
455
456 candl = reg[RATA_IR].rcand;
457 if (candl != 0) {
458 fprintf(gbl.dbgfil, "\n***** IR Candidates *****\n");
459 dump_cand(candl);
460 }
461 candl = reg[RATA_AR].rcand;
462 if (candl != 0) {
463 fprintf(gbl.dbgfil, "\n***** AR Candidates *****\n");
464 dump_cand(candl);
465 }
466 candl = reg[RATA_SP].rcand;
467 if (candl != 0) {
468 fprintf(gbl.dbgfil, "\n***** SP Candidates *****\n");
469 dump_cand(candl);
470 }
471 candl = reg[RATA_DP].rcand;
472 if (candl != 0) {
473 fprintf(gbl.dbgfil, "\n***** DP Candidates *****\n");
474 dump_cand(candl);
475 }
476 candl = reg[RATA_KR].rcand;
477 if (candl != 0) {
478 fprintf(gbl.dbgfil, "\n***** KR Candidates *****\n");
479 dump_cand(candl);
480 }
481 candl = reg[RATA_VECT].rcand;
482 if (candl != 0) {
483 fprintf(gbl.dbgfil, "\n***** VECT Candidates *****\n");
484 dump_cand(candl);
485 }
486 candl = reg[RATA_CSP].rcand;
487 if (candl != 0) {
488 fprintf(gbl.dbgfil, "\n***** CSP Candidates *****\n");
489 dump_cand(candl);
490 }
491 candl = reg[RATA_CDP].rcand;
492 if (candl != 0) {
493 fprintf(gbl.dbgfil, "\n***** CDP Candidates *****\n");
494 dump_cand(candl);
495 }
496 }
497
498 void
dmp_rat(int rat)499 dmp_rat(int rat)
500 {
501 int val;
502
503 switch (RAT_ATYPE(rat)) {
504 case RATA_TEMP:
505 case RATA_RPL:
506 fprintf(gbl.dbgfil, "%-7d ", RAT_REG(rat));
507 break;
508 default:
509 switch (RAT_RTYPE(rat)) {
510 case RATA_IR:
511 fprintf(gbl.dbgfil, "ir(%2d) ", (int)ILI_OPND(RAT_REG(rat), 1));
512 break;
513 case RATA_AR:
514 fprintf(gbl.dbgfil, "ar(%2d) ", (int)ILI_OPND(RAT_REG(rat), 1));
515 break;
516 case RATA_SP:
517 fprintf(gbl.dbgfil, "sp(%2d) ", (int)ILI_OPND(RAT_REG(rat), 1));
518 break;
519 case RATA_DP:
520 fprintf(gbl.dbgfil, "dp(%3d) ", (int)ILI_OPND(RAT_REG(rat), 1));
521 break;
522 #ifdef RATA_CSP
523 case RATA_CSP:
524 fprintf(gbl.dbgfil, "csp(%3d) ", (int)ILI_OPND(RAT_REG(rat), 1));
525 break;
526 case RATA_CDP:
527 fprintf(gbl.dbgfil, "cdp(%3d) ", (int)ILI_OPND(RAT_REG(rat), 1));
528 break;
529 case RATA_CQP:
530 fprintf(gbl.dbgfil, "cqp(%3d) ", (int)ILI_OPND(RAT_REG(rat), 1));
531 break;
532 #endif
533 case RATA_KR:
534 fprintf(gbl.dbgfil, "kr(%2d,%2d) ", KR_MSH(ILI_OPND(RAT_REG(rat), 1)),
535 KR_LSH(ILI_OPND(RAT_REG(rat), 1)));
536 break;
537 }
538 }
539 fprintf(gbl.dbgfil, " %4s", atype_names[RAT_ATYPE(rat)]);
540 val = RAT_VAL(rat);
541 fprintf(gbl.dbgfil, " %-5u", val);
542 switch (RAT_ATYPE(rat)) {
543 case RATA_NME:
544 fprintf(gbl.dbgfil, " \"");
545 (void)print_nme(val);
546 fprintf(gbl.dbgfil, "\"");
547 break;
548 case RATA_TEMP:
549 case RATA_ILI:
550 case RATA_RPL:
551 fprintf(gbl.dbgfil, " - %-9s", ilis[ILI_OPC(val)].name);
552 break;
553 }
554 if (RAT_RTYPE(rat) != RATA_VECT)
555 fprintf(gbl.dbgfil, " <%s>", get_msize(RAT_MSIZE(rat)));
556 else
557 fprintf(gbl.dbgfil, " <DT %d>", RAT_MSIZE(rat));
558
559 if (RAT_CONFL(rat))
560 fprintf(gbl.dbgfil, " <confl>");
561 if (RAT_ATYPE(rat) == RATA_NME && RAT_STORE(rat))
562 fprintf(gbl.dbgfil, " <stored>");
563 fprintf(gbl.dbgfil, " addr: %u", RAT_ADDR(rat));
564 fprintf(gbl.dbgfil, "\n");
565 }
566
567 static char *
get_msize(int msz)568 get_msize(int msz)
569 {
570 char *p;
571
572 switch (msz) {
573 case MSZ_SBYTE:
574 p = "sb";
575 break;
576 case MSZ_SHWORD:
577 p = "sh";
578 break;
579 case MSZ_SWORD:
580 p = "wd";
581 break;
582 case MSZ_SLWORD:
583 p = "wd";
584 break;
585 case MSZ_UBYTE:
586 p = "ub";
587 break;
588 case MSZ_UHWORD:
589 p = "uh";
590 break;
591 case MSZ_PTR:
592 p = "pt";
593 break;
594 case MSZ_ULWORD:
595 p = "uw";
596 break;
597 case MSZ_F4:
598 p = "fl";
599 break;
600 case MSZ_F8:
601 p = "db";
602 break; /* this can get confused with csp */
603 case MSZ_F16:
604 p = "cdp";
605 break;
606 case MSZ_I8:
607 p = "i8";
608 break;
609 default:
610 interr("get_msize: unknown msize", msz, ERR_Warning);
611 p = "??";
612 }
613 return p;
614 }
615
616 void
dmprat(int rat)617 dmprat(int rat)
618 {
619 int nregs;
620
621 if (rat != 0) {
622 fprintf(gbl.dbgfil, "\n***** Register Assigned Table (%d) ", rat);
623 nregs = RAT_VAL(rat);
624 fprintf(gbl.dbgfil, "nregs: %d *****\n", nregs);
625 fprintf(gbl.dbgfil, "Register Type Value\n");
626 while (nregs > 0) {
627 rat++;
628 dmp_rat(rat);
629 nregs--;
630 }
631 }
632 }
633
634 /**
635 \brief Get a candidate from the candidate list, candl.
636 */
637 int
getrcand(int candl)638 getrcand(int candl)
639 {
640 int cand, count;
641
642 cand = 0; /* value of getrcand if a candidate is not
643 * found
644 */
645 count = GR_THRESHOLD; /* a candidate must have a count greater than
646 * this value (defined in machreg.h)
647 */
648
649 /*
650 * scan through the candidate list to find a the candidate with the
651 * maximum count
652 */
653 for (; candl; candl = RCAND_NEXT(candl))
654 if (RCAND_COUNT(candl) > count) {
655
656 /*
657 * if the candidate variable was used in contexts which conflicts
658 * with its true register type, get the next candidate
659 */
660 if (RCAND_CONFL(candl)) {
661 RCAND_COUNT(candl) = 0;
662 continue;
663 }
664 cand = candl; /* potential candidate */
665 count = RCAND_COUNT(cand); /* new maximum count */
666 }
667 rcandb.count = RCAND_COUNT(cand);
668 RCAND_COUNT(cand) = 0; /* clear the candidate's count. this
669 * "removes" the candidate from the list
670 */
671 return (cand);
672 }
673
674 /**
675 \brief Go through all of the candidate lists to reinitialize the back
676 pointers of the names entries and ILI.
677
678 The regs' rcand fields are set to null, and the register candidate list is
679 reset.
680 */
681 void
endrcand(void)682 endrcand(void)
683 {
684 int rtype, cand, val, i;
685
686 for (rtype = 0; rtype <= RATA_ALL; rtype++) {
687 for (cand = reg[rtype].rcand; cand; cand = RCAND_NEXT(cand)) {
688 val = RCAND_VAL(cand);
689 switch (RCAND_ATYPE(cand)) {
690 case RATA_NME:
691 NME_RAT(ILI_OPND(val, 3)) = 0;
692 break;
693
694 #ifdef RATA_UPLV
695 case RATA_UPLV:
696 #endif
697 case RATA_ILI:
698 NME_RAT(ILI_OPND(val, 2)) = 0;
699 if (RCAND_OLOAD(cand))
700 ILI_RAT(RCAND_OLOAD(cand)) = 0;
701 case RATA_TEMP:
702 case RATA_CONST:
703 case RATA_RPL:
704 ILI_RAT(val) = 0;
705 break;
706
707 case RATA_IND:
708 ILI_RAT(val) = 0;
709 NME_RAT(ILI_OPND(val, 2)) = 0;
710 for (i = RCAND_TEMP(cand); i; i = RCAND_NEXT(i))
711 ILI_RAT(RCAND_VAL(i)) = 0;
712 break;
713
714 case RATA_ARR:
715 ILI_RAT(val) = 0;
716 NME_RAT(ILI_OPND(val, 2)) = 0;
717 break;
718 }
719 }
720 reg[rtype].rcand = 0;
721 }
722
723 rtype = RATA_VECT;
724 {
725 for (cand = reg[rtype].rcand; cand; cand = RCAND_NEXT(cand)) {
726 val = RCAND_VAL(cand);
727 switch (RCAND_ATYPE(cand)) {
728 case RATA_TEMP:
729 ILI_RAT(val) = 0;
730 break;
731 default:
732 interr("endrcand: unexpected atype for RATA_VECT", RCAND_ATYPE(cand),
733 ERR_Severe);
734 }
735 }
736 reg[rtype].rcand = 0;
737 }
738 for (rtype = RATA_CSP; rtype <= RATA_CDP; rtype++) {
739 for (cand = reg[rtype].rcand; cand; cand = RCAND_NEXT(cand)) {
740 val = RCAND_VAL(cand);
741 switch (RCAND_ATYPE(cand)) {
742 case RATA_NME:
743 NME_RAT(ILI_OPND(val, 3)) = 0;
744 break;
745
746 case RATA_ILI:
747 NME_RAT(ILI_OPND(val, 2)) = 0;
748 if (RCAND_OLOAD(cand))
749 ILI_RAT(RCAND_OLOAD(cand)) = 0;
750 case RATA_TEMP:
751 case RATA_CONST:
752 case RATA_RPL:
753 ILI_RAT(val) = 0;
754 break;
755
756 case RATA_IND:
757 ILI_RAT(val) = 0;
758 NME_RAT(ILI_OPND(val, 2)) = 0;
759 for (i = RCAND_TEMP(cand); i; i = RCAND_NEXT(i))
760 ILI_RAT(RCAND_VAL(i)) = 0;
761 break;
762
763 case RATA_ARR:
764 ILI_RAT(val) = 0;
765 NME_RAT(ILI_OPND(val, 2)) = 0;
766 break;
767 }
768 }
769 reg[rtype].rcand = 0;
770 }
771
772 rcandb.stg_avail = 1; /* reset the register candidate area */
773 }
774
775 /**
776 \brief For ftn, all dummies which are assigned to registers and are stored
777 into must have their values stored back into memory. These stores are added
778 to the beginning of the exit block.
779 */
780 void
storedums(int exitbih,int first_rat)781 storedums(int exitbih, int first_rat)
782 {
783 int rat, i, nme, cnt;
784 int addr;
785
786 rdilts(exitbih); /* read in the exit block */
787 rat = first_rat; /* first rat entry */
788 for (cnt = RAT_VAL(rat++); cnt--; rat++) {
789 i = basesym_of(nme = RAT_VAL(rat));
790 if (!IS_DUM(i))
791 continue;
792 if (!RAT_STORE(rat))
793 continue;
794 /*
795 * For a language like PASCAL
796 * if (OUT(i)) continue;
797 */
798 addr = RAT_ADDR(rat);
799 i = RAT_REG(rat);
800 switch (RAT_RTYPE(rat)) {
801 case RATA_AR:
802 (void)addilt(0, ad3ili(IL_STA, i, addr, nme));
803 break;
804 case RATA_IR:
805 (void)addilt(0, ad4ili(IL_ST, i, addr, nme, RAT_MSIZE(rat)));
806 break;
807 case RATA_KR:
808 (void)addilt(0, ad4ili(IL_STKR, i, addr, nme, MSZ_I8));
809 break;
810 case RATA_SP:
811 (void)addilt(0, ad4ili(IL_STSP, i, addr, nme, MSZ_F4));
812 break;
813 case RATA_DP:
814 (void)addilt(0, ad4ili(IL_STDP, i, addr, nme, MSZ_F8));
815 break;
816 case RATA_CSP:
817 (void)addilt(0, ad4ili(IL_STSCMPLX, i, addr, nme, MSZ_F8));
818 break;
819 case RATA_CDP:
820 (void)addilt(0, ad4ili(IL_STDCMPLX, i, addr, nme, MSZ_F16));
821 break;
822 }
823 }
824 BIH_SMOVE(exitbih) = 1; /* (temp) mark block so sched limits scratch set */
825 wrilts(exitbih); /* write out the exit block */
826 }
827
828 /* Register Temporary Section -
829 These routines provide a mechanism to create temporaries during
830 the expansion of ILM blocks which can be re-used for different
831 ILM blocks and are unique across functions. The scenario (at
832 opt 0 or 1) is:
833 1. At the beginning of an ILM block, initialize (mkrtemp_init).
834 2. Create temporaries during expansion by calling mkrtemp.
835 3. At the end of a function, ensure that the temporaries created
836 for the function are unique from those created in the next
837 function (mkrtemp_end).
838
839 For opt 2, the scenario for the loops in a function is:
840 0. At the beginning of a function, mkrtemp_copy
841 1. For innermost loops, mkrtemp_init. Otherwise, use
842 mkrtemp_reinit (this gets the values created from calls to
843 mkrtemp_update of all contained loops).
844 2. During optimizations, use mkrtemp.
845 3. At the end of optimizing a loop, mkrtemp_update for the
846 parent of the loop. This will keep track of the rtemps used
847 in contained loops.
848 4. At the end of a function, mkrtemp_end();
849
850 NOTE: any change in the number of elements in the rtemp array
851 must also be applied to the macro RTEMPS which is defined in
852 regutil.h.
853 */
854
855 static struct { /* Register temporary information */
856 char prefix; /* beginning char of name */
857 char *arg1pfx; /* ARG1PTR Q&D - SEE f13720 */
858 DTYPE dt; /* data type chosen for the temp */
859 int current; /* current index to be used in name */
860 int start; /* start value of index for a function */
861 int max; /* maximum index used for the file */
862 } rtemps[] = {
863 {'D', "Da", DT_INT, 0, 0, -1}, /* 0: data register temps */
864 {'G', "Ga", DT_CPTR, 0, 0, -1}, /* 1: address register temps */
865 {'H', "Ha", DT_FLOAT, 0, 0, -1}, /* 2: single register temps */
866 {'K', "Ka", DT_DBLE, 0, 0, -1}, /* 3: double register temps */
867 {'g', "ga", DT_INT8, 0, 0, -1}, /* 4: integer*8 temps */
868 {'h', "ha", DT_CMPLX, 0, 0, -1}, /* 5: complex temps */
869 {'k', "ka", DT_DCMPLX, 0, 0, -1}, /* 6: double complex temps */
870 {'h', "ha", DT_NONE, 0, 0, -1}, /* 7: filler */
871 {'v', "va", DT_NONE, 0, 0, -1}, /* 8: vector temps */
872 #if defined LONG_DOUBLE_FLOAT128
873 {'X', "Xa", DT_FLOAT128, 0, 0, -1}, /* 9: float128 temps */
874 {'x', "xa", DT_CMPLX128, 0, 0, -1}, /*10: float complex temps */
875 #else
876 {'X', "Xa", DT_NONE, 0, 0, -1}, /* 9 and 10: filler */
877 {'x', "xa", DT_NONE, 0, 0, -1}, /* 9 and 10: filler */
878 #endif
879 };
880
881 static int select_rtemp(int);
882
883 /**
884 \brief This routine initializes for temporaries created during an ILM block.
885 This guarantees that the temps used will be unique for a given block.
886 */
887 void
mkrtemp_init(void)888 mkrtemp_init(void)
889 {
890 int i;
891 /* Both DOUBLE_DOUBLE && LONG_DOUBLE_FLOAT128 may be defined. In that
892 * case the mapping of "long doulbe" is determined by xbit.
893 */
894
895 assert(sizeof rtemps == RTEMPS * sizeof *rtemps,
896 "mkrtemp_init: rtemps[] size inconsistent with RTEMPS value", RTEMPS,
897 ERR_Severe);
898 for (i = 0; i < RTEMPS; i++) {
899 rtemps[i].current = rtemps[i].start;
900 }
901 }
902
903 /**
904 \brief This routine makes a temporary and returns its symbol table index. The
905 rtemp entry which is used is determined by the type of the ILI which needs a
906 temporary to store its value
907 */
908 SPTR
mkrtemp(int ilix)909 mkrtemp(int ilix)
910 {
911 return mkrtemp_sc(ilix, SC_AUTO);
912 }
913
914 /**
915 \brief This routine makes a temporary and returns its symbol table index. The
916 rtemp entry which is used is determined by the type of the ILI which needs a
917 temporary to store its value
918 */
919 SPTR
mkrtemp_sc(int ilix,SC_KIND sc)920 mkrtemp_sc(int ilix, SC_KIND sc)
921 {
922 int index, type;
923 SPTR sym;
924
925 type = select_rtemp(ilix);
926 if ((index = rtemps[type].current++) > rtemps[type].max)
927 rtemps[type].max = index;
928
929 sym = getccsym_sc(rtemps[type].prefix, index, ST_VAR, sc);
930 DTYPEP(sym, rtemps[type].dt);
931 #ifdef NOCONFLICTP
932 NOCONFLICTP(sym, 1);
933 #endif
934 #ifdef PTRSAFEP
935 PTRSAFEP(sym, 1);
936 #endif
937
938 return sym;
939 }
940
941 /**
942 \brief This routine makes a complex temporary and returns its symbol table
943 index. The rtemp entry which is used is determined by the dtype.
944
945 Also used for INTEGER*8 support to allocate 64-bit temporaries for 64-bit
946 int argument expressions.
947 */
948 SPTR
mkrtemp_cpx(DTYPE dtype)949 mkrtemp_cpx(DTYPE dtype)
950 {
951 SPTR sym;
952 sym = mkrtemp_cpx_sc(dtype, SC_AUTO);
953 #ifdef NOCONFLICTP
954 NOCONFLICTP(sym, 1);
955 #endif
956 #ifdef PTRSAFEP
957 PTRSAFEP(sym, 1);
958 #endif
959 return sym;
960 }
961
962 SPTR
mkrtemp_cpx_sc(DTYPE dtype,SC_KIND sc)963 mkrtemp_cpx_sc(DTYPE dtype, SC_KIND sc)
964 {
965 int index, type;
966 SPTR sym;
967
968 switch (dtype) {
969 case DT_CMPLX:
970 type = 5;
971 break;
972 case DT_DCMPLX:
973 type = 6;
974 break;
975 #ifdef LONG_DOUBLE_FLOAT128
976 case DT_CMPLX128:
977 type = 10;
978 break;
979 #endif
980 case DT_INT8:
981 type = 4;
982 break;
983 default:
984 interr("mkrtemp_cpx: illegal dtype", dtype, ERR_Severe);
985 type = 6;
986 }
987
988 if ((index = rtemps[type].current++) > rtemps[type].max)
989 rtemps[type].max = index;
990
991 sym = getccsym_sc(rtemps[type].prefix, index, ST_VAR, sc);
992 DTYPEP(sym, rtemps[type].dt);
993 #ifdef NOCONFLICTP
994 NOCONFLICTP(sym, 1);
995 #endif
996 #ifdef PTRSAFEP
997 PTRSAFEP(sym, 1);
998 #endif
999
1000 return sym;
1001 }
1002
1003 SPTR
mkrtemp_arg1_sc(DTYPE dtype,SC_KIND sc)1004 mkrtemp_arg1_sc(DTYPE dtype, SC_KIND sc)
1005 {
1006 #ifndef ARG1PTRP
1007 return mkrtemp_cpx_sc(dtype, sc);
1008 #else
1009 int index, type;
1010 SPTR sym;
1011
1012 if (dtype == DT_CMPLX)
1013 type = 5;
1014 else if (dtype == DT_DCMPLX)
1015 type = 6;
1016 #ifdef LONG_DOUBLE_FLOAT128
1017 else if (dtype == DT_CMPLX128)
1018 type = 6;
1019 #endif
1020 else if (dtype == DT_INT8)
1021 type = 4;
1022 else {
1023 interr("mkrtemp_cpx: illegal dtype", dtype, ERR_Severe);
1024 type = 6;
1025 }
1026
1027 if ((index = rtemps[type].current++) > rtemps[type].max)
1028 rtemps[type].max = index;
1029
1030 sym = getccssym_sc(rtemps[type].arg1pfx, index, ST_VAR, sc);
1031 DTYPEP(sym, rtemps[type].dt);
1032 #ifdef NOCONFLICTP
1033 NOCONFLICTP(sym, 1);
1034 #endif
1035 #ifdef PTRSAFEP
1036 PTRSAFEP(sym, 1);
1037 #endif
1038 ARG1PTRP(sym, 1);
1039
1040 return sym;
1041 #endif
1042 }
1043
1044 /**
1045 \brief This routine ends the temp processing for a function. Values are
1046 updated so that temps created for the next function are unique from the
1047 temps created during the current function
1048 */
1049 void
mkrtemp_end(void)1050 mkrtemp_end(void)
1051 {
1052 int i;
1053
1054 for (i = 0; i < RTEMPS; i++) {
1055 rtemps[i].start = rtemps[i].max + 1;
1056 }
1057 }
1058
1059 /**
1060 \brief This routine copies the maximum values of the temporaries currently
1061 allocated -- this is typically used at the start of optimizing a function.
1062 */
1063 void
mkrtemp_copy(int * rt)1064 mkrtemp_copy(int *rt)
1065 {
1066 int i;
1067
1068 for (i = 0; i < RTEMPS; i++) {
1069 rt[i] = rtemps[i].max;
1070 }
1071 }
1072
1073 /**
1074 \brief This routine keeps track of the maximum values of rtemps in rt
1075 */
1076 void
mkrtemp_update(int * rt)1077 mkrtemp_update(int *rt)
1078 {
1079 int i;
1080
1081 for (i = 0; i < RTEMPS; i++) {
1082 if (rt[i] < rtemps[i].max)
1083 rt[i] = rtemps[i].max;
1084 }
1085 }
1086
1087 /**
1088 \brief This routine resets the rtemps values from rt.
1089 */
1090 void
mkrtemp_reinit(int * rt)1091 mkrtemp_reinit(int *rt)
1092 {
1093 int i;
1094
1095 for (i = 0; i < RTEMPS; i++) {
1096 rtemps[i].max = rt[i];
1097 rtemps[i].current = rtemps[i].start = rtemps[i].max + 1;
1098 }
1099 }
1100
1101 int
assn_rtemp(int ili)1102 assn_rtemp(int ili)
1103 {
1104 int temp;
1105
1106 temp = assn_rtemp_sc(ili, SC_AUTO);
1107 return (temp);
1108 }
1109
1110 static int
_assn_rtemp(int ili,int temp)1111 _assn_rtemp(int ili, int temp)
1112 {
1113 int rcand, rtype;
1114 ILI_OP opc = ILI_OPC(ili);
1115 GET_RCAND(rcand);
1116
1117 switch (opc) {
1118 default:
1119 break;
1120 case IL_STA:
1121 opc = IL_LDA;
1122 break;
1123 case IL_ST:
1124 opc = IL_LD;
1125 break;
1126 case IL_STKR:
1127 opc = IL_LDKR;
1128 break;
1129 case IL_STSP:
1130 opc = IL_LDSP;
1131 break;
1132 case IL_STDP:
1133 opc = IL_LDDP;
1134 break;
1135 case IL_VST:
1136 opc = IL_VLD;
1137 break;
1138 case IL_VSTU:
1139 opc = IL_VLDU;
1140 break;
1141 case IL_STSCMPLX:
1142 opc = IL_LDSCMPLX;
1143 break;
1144 case IL_STDCMPLX:
1145 opc = IL_LDDCMPLX;
1146 break;
1147 }
1148
1149 switch (IL_RES(opc)) {
1150 case ILIA_IR:
1151 rtype = RCAND_RTYPE(rcand) = RATA_IR;
1152 RCAND_MSIZE(rcand) = MSZ_WORD;
1153 break;
1154 case ILIA_AR:
1155 rtype = RCAND_RTYPE(rcand) = RATA_AR;
1156 RCAND_MSIZE(rcand) = MSZ_PTR;
1157 break;
1158 case ILIA_SP:
1159 rtype = RCAND_RTYPE(rcand) = RATA_SP;
1160 RCAND_MSIZE(rcand) = MSZ_F4;
1161 break;
1162 case ILIA_DP:
1163 rtype = RCAND_RTYPE(rcand) = RATA_DP;
1164 RCAND_MSIZE(rcand) = MSZ_F8;
1165 break;
1166 case ILIA_KR:
1167 rtype = RCAND_RTYPE(rcand) = RATA_KR;
1168 RCAND_MSIZE(rcand) = MSZ_I8;
1169 break;
1170 #ifdef ILIA_CS
1171 case ILIA_CS:
1172 rtype = RCAND_RTYPE(rcand) = RATA_CSP;
1173 RCAND_MSIZE(rcand) = MSZ_F8;
1174 break;
1175 #endif
1176 #ifdef ILIA_CD
1177 case ILIA_CD:
1178 rtype = RCAND_RTYPE(rcand) = RATA_CDP;
1179 RCAND_MSIZE(rcand) = MSZ_F16;
1180 break;
1181 #endif
1182 case ILIA_LNK:
1183 if (IL_VECT(ILI_OPC(ili))) {
1184 RCAND_MSIZE(rcand) = ili_get_vect_dtype(ili);
1185 rtype = RCAND_RTYPE(rcand) = RATA_VECT;
1186 break;
1187 }
1188
1189 default:
1190 interr("_assn_rtemp: illegal ili for temp assn", ili, ERR_Severe);
1191 }
1192 RCAND_NEXT(rcand) = reg[rtype].rcand;
1193 reg[rtype].rcand = rcand;
1194 RCAND_TEMP(rcand) = temp;
1195 RCAND_ATYPE(rcand) = RATA_TEMP;
1196 RCAND_COUNT(rcand) = 0;
1197 RCAND_CONFL(rcand) = 0;
1198 RCAND_VAL(rcand) = ili;
1199 ILI_RAT(ili) = rcand;
1200
1201 return temp;
1202 }
1203
1204 void
assn_input_rtemp(int ili,int temp)1205 assn_input_rtemp(int ili, int temp)
1206 {
1207 _assn_rtemp(ili, temp);
1208 }
1209
1210 int
assn_rtemp_sc(int ili,SC_KIND sc)1211 assn_rtemp_sc(int ili, SC_KIND sc)
1212 {
1213 int temp;
1214 temp = mkrtemp_sc(ili, sc);
1215 return _assn_rtemp(ili, temp);
1216 }
1217
1218 int
assn_sclrtemp(int ili,SC_KIND sc)1219 assn_sclrtemp(int ili, SC_KIND sc)
1220 {
1221 int temp;
1222 int type;
1223 DTYPE dtype;
1224 int retry;
1225 char name[16];
1226
1227 type = select_rtemp(ili);
1228 dtype = rtemps[type].dt;
1229
1230 if (sc != SC_PRIVATE)
1231 snprintf(name, sizeof(name), ".r%04d", ili); /* at least 4, could be more */
1232 else
1233 snprintf(name, sizeof(name), ".r%04dp",
1234 ili); /* at least 4, could be more */
1235 retry = 0;
1236 again:
1237 temp = getsymbol(name);
1238 if (STYPEG(temp) == ST_VAR) {
1239 if (DTYPEG(temp) != dtype) {
1240 if (sc != SC_PRIVATE)
1241 snprintf(name, sizeof(name), ".r%d%04d", retry, ili);
1242 else
1243 snprintf(name, sizeof(name), ".r%d%04dp", retry, ili);
1244 retry++;
1245 goto again;
1246 }
1247 } else {
1248 STYPEP(temp, ST_VAR);
1249 CCSYMP(temp, 1);
1250 LSCOPEP(temp, 1);
1251 #ifdef PTRSAFEP
1252 PTRSAFEP(temp, 1);
1253 #endif
1254 SCP(temp, sc);
1255 DTYPEP(temp, dtype);
1256 }
1257
1258 return _assn_rtemp(ili, temp);
1259 }
1260
1261 static int
select_rtemp(int ili)1262 select_rtemp(int ili)
1263 {
1264 int type;
1265
1266 switch (IL_RES(ILI_OPC(ili))) {
1267 case ILIA_IR:
1268 type = 0;
1269 break;
1270 case ILIA_AR:
1271 type = 1;
1272 break;
1273 case ILIA_SP:
1274 type = 2;
1275 break;
1276 case ILIA_DP:
1277 type = 3;
1278 break;
1279 case ILIA_KR:
1280 type = 4;
1281 break;
1282 case ILIA_LNK:
1283 if (IL_VECT(ILI_OPC(ili))) {
1284 DTYPE dt = ili_get_vect_dtype(ili);
1285 if (dt) {
1286 type = 8;
1287 rtemps[type].dt = dt;
1288 break;
1289 }
1290 }
1291 #ifdef ILIA_CS
1292 case ILIA_CS:
1293 type = 5;
1294 break;
1295 #endif
1296 #ifdef ILIA_CD
1297 case ILIA_CD:
1298 type = 6;
1299 break;
1300 #endif
1301 #ifdef LONG_DOUBLE_FLOAT128
1302 case ILIA_FLOAT128:
1303 type = 9;
1304 break;
1305 #endif
1306 default:
1307 interr("select_rtemp: bad ili", ili, ERR_Severe);
1308 type = 0;
1309 }
1310 return type;
1311 }
1312