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