1 /*
2  * Copyright (c) 1993-2018, 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 performed by the expander at opt level 1
20  */
21 
22 #include "expreg.h"
23 #include "gbldefs.h"
24 #include "error.h"
25 #include "global.h"
26 #include "symtab.h"
27 #include "ili.h"
28 #include "expand.h"
29 #include "regutil.h"
30 #include "machreg.h"
31 #include "machar.h"
32 
33 static int ilt;
34 
35 static LST *list; /* linked list of ili added to entry blk */
36 
37 static void assign1(int rtype);
38 
39 /** \brief Add register candidate
40  *
41  * routine to add candidates to the register candidate lists of
42  * the register module.  This routine is valid for opt 1 only.
43  * This routine is called only for load and store ILI and will
44  * eliminate a candidate which depend on their types, storage
45  * class, etc.
46  */
47 void
exp_rcand(int ilix,int nmex)48 exp_rcand(int ilix, int nmex)
49 {
50   register int sym;
51 
52   if (NME_TYPE(nmex) == NT_VAR                         /* var names only */
53       && TY_ISSCALAR(DTY(DTYPEG(sym = NME_SYM(nmex)))) /* scalars only */
54       && IS_LCL_OR_DUM(sym)                            /* autos, args or regs */
55       && !VOLG(sym)                                    /* not volatile */
56       && SOCPTRG(sym) == 0 /* not equivalenced */
57       ) {
58     addrcand(ilix);
59     /* If a variable is loaded or stored in a critical section or a
60      * parallel section, set the candidate's IGNORE flag.  This prevents
61      * a register from being assigned.
62      * Tprs 2077 & 2127 - can't assign registers to variables in a
63      * parallel region (could restrict this to shared variables).
64      */
65     if (NME_RAT(nmex) &&
66         (bihb.csfg || bihb.parsectfg || bihb.parfg || bihb.taskfg))
67       RCAND_IGNORE(NME_RAT(nmex)) = 1;
68   }
69 }
70 
71 /***********************************************************************/
72 
73 /** \brief Control the assignment of the registers at opt level 1
74  */
75 void
reg_assign1(void)76 reg_assign1(void)
77 {
78   register int first_rat, /* first entry of the block's RAT  */
79       ilix,               /* ili index of the candidate */
80       entr,               /* entry symbol of the function */
81       rtype,              /* register type */
82       cand;               /* register candidate */
83   int null_rat;
84   int funcbih;
85   int iltt; /* local tmp for ilt */
86   int sym;
87   LST *save;
88   int tbih;
89 
90   funcbih = BIHNUMG(gbl.currsub);
91   rdilts(funcbih);           /* fetch the entry block */
92   entr = BIH_LABEL(funcbih); /* get the entry symbol */
93   list = 0;
94   ilt = ILT_PREV(0); /* locate the last ilt in the block */
95 
96 #if DEBUG
97   if (EXPDBG(8, 12))
98     fprintf(gbl.dbgfil,
99             "\n***** Register Information for Function \"%s\" *****\n",
100             getprint(entr));
101   if (EXPDBG(8, 4))
102     dmprcand();
103 #endif
104 
105   GET_RAT(first_rat); /* fetch a RAT item which will be
106                        * the header of the table
107                        */
108   /*
109    * assign the data registers from the allowed register set.
110    */
111   assign1(RATA_IR);
112   /*
113    * assign the address registers from the allowed set.
114    */
115   assign1(RATA_AR);
116   /*
117    * assign the single precision registers from the allowed set.
118    */
119   assign1(RATA_SP);
120   /*
121    * assign the double precision registers from the allowed set.
122    */
123   assign1(RATA_DP);
124   /*
125    * assign the double integer registers from the allowed set.
126    */
127   assign1(RATA_KR);
128   /*
129    * communicate to the scheduler the first global register assigned
130    * for each register class -- note that this will be the physical register
131    * number; it reflects the number of registers assigned from the physical
132    * set mapped from the generic register set. Because two or more generic
133    * register sets can map to a single register set, this information
134    * can only be computed after all of the assignments are done.
135    *
136    */
137   mr_end();
138   /*
139    * fill in the VAL field of the header entry for this RAT with
140    * the number of assignments.
141    */
142   RAT_VAL(first_rat) = ratb.stg_avail - first_rat - 1;
143 
144 #if DEBUG
145   if (EXPDBG(8, 8)) {
146     dmprat(first_rat);
147     fprintf(gbl.dbgfil,
148             "   first_dr:%3d, first_ar:%3d, first_sp:%3d, first_dp:%3d\n",
149             aux.curr_entry->first_dr, aux.curr_entry->first_ar,
150             aux.curr_entry->first_sp, aux.curr_entry->first_dp);
151   }
152 #endif
153 /*
154  * link the BIH of the entry block to the RAT.  this block is written
155  * out.
156  */
157   BIH_ASSN(BIH_NEXT(funcbih)) = first_rat;
158   wrilts(funcbih);
159   /*
160    * add ilis that were added to the main entry to any other entries
161    */
162   if (list) {
163     save = list;
164     for (sym = SYMLKG(gbl.entries); sym != NOSYM; sym = SYMLKG(sym)) {
165       rdilts(tbih = BIHNUMG(sym));
166       GET_RAT(null_rat);
167       RAT_VAL(null_rat) = 0;
168       BIH_ASSN(tbih) = null_rat;
169       /*
170        * if we copied params, we do this mvxx stuff in block after the
171        * entry block, so scheduler loads up dummies after copy to temp
172        * param list has been done
173        */
174       if (COPYPRMSG(sym)) {
175         wrilts(tbih);
176         tbih = exp_addbih(tbih);
177         rdilts(tbih);
178         BIH_ASSN(tbih) = null_rat;
179       }
180       iltt = ILT_PREV(0);
181       list = save;
182       while (list) {
183         iltt = addilt(iltt, list->item);
184         list = list->next;
185       }
186       BIH_ASSN(BIH_NEXT(tbih)) = first_rat;
187       wrilts(tbih);
188     }
189     freearea(LST_AREA);
190   }
191   /*
192    * dummies that have stores into  and that are assigned registers , must
193    * be stored back at exit
194    */
195   storedums(expb.curbih, first_rat);
196 
197   /* for the routine's exit block, assign a null rat table  */
198   GET_RAT(null_rat);
199   RAT_VAL(null_rat) = 0;
200   BIH_ASSN(expb.curbih) = null_rat;
201 
202   /*
203    * go through the candidate lists to clean up the back pointers.
204    * also, reset the register candidate store area.
205    */
206   endrcand();
207 
208 }
209 
210 /** \brief Assign registers for opt level 1.
211  *
212  * The possible set of registers to use satisfies the relation first_global <=
213  * reg <= last_global, where the bounds are found in the mach_reg structure of
214  * the reg structure for the given register type.  The registers are assigned
215  * beginning at last_global and continues down to first_global.  The value
216  * returned by the function is the number of registers assigned.
217  *
218  * \param rtype type of registers
219  */
220 static void
assign1(int rtype)221 assign1(int rtype)
222 {
223   register int cand, /* candidate for a register */
224       rat,           /* RAT for each assigned reg */
225       ilix,          /* ili for the candidate */
226       areg;          /* assigned register */
227 
228   int candl,  /* candidate list */
229       nme,    /* NME for the candidate */
230       sym,    /* ST for the candidate  */
231       addr,   /* address ili for the candidate */
232       ilitmp; /* ili temporary */
233 
234   /*
235    * loop while there are candidates and registers available
236    */
237   candl = reg[rtype].rcand;
238   for (;;) {
239     /*
240      * get a candidate; if one does not exist, exit the loop
241      */
242     if ((cand = getrcand(candl)) == 0)
243       break;
244     if (RCAND_IGNORE(cand))
245       continue;
246     if (!RCAND_ISILI(cand)) {
247 /*
248  * if the candidate is not type ILI (implies that just stores
249  * occurred, get the next candidate if it's not a regarg.
250  * NOTE: C only.
251  */
252       continue;
253     } else {
254       /*
255        * for the candidate, locate the load ili (ilix), the names entry
256        * (nme), and the symbol (sym)
257        */
258       ilix = RCAND_VAL(cand);
259       sym = NME_SYM(nme = ILI_OPND(ilix, 2));
260       addr = ILI_OPND(ilix, 1);
261     }
262     /*
263      * if the symbol has had its address taken, it cannot be assigned a
264      * register
265      */
266     if (ADDRTKNG(sym))
267       continue;
268     if (gbl.internal > 1 && sym == aux.curr_entry->display) {
269       /* printf("display temp %s cannot be assigned register\n",
270              SYMNAME(sym));
271        */
272       continue;
273     }
274 /*
275  * if symbol is declared in an 'outer' scope, it cannot be assigned a
276  * register - happens in a language with nested procedures (c++)
277  */
278     if (GSCOPEG(sym))
279       continue;
280     if (UPLEVELG(sym))
281       continue;
282 
283     /*
284      *for now, dissallow dummies if there are multiple entries
285      */
286     if (IS_DUM(sym)) {
287       if (SYMLKG(gbl.entries) != NOSYM)
288         continue;
289     } else if (SCG(sym) == SC_LOCAL && DINITG(sym) &&
290                (ADDRTKNG(sym) || RCAND_STORE(cand)) && gbl.rutype != RU_PROG)
291       /*
292        * if a local variable is data initialized, disallow it if it
293        * has been stored; the thinking is that it falls into the
294        * same category of a saved variable -- someday, may want
295        * to override this if XBIT(124,0x80) is set (also optutil.c)
296        */
297       continue;
298     /*
299      * for C regargs, use arg register saved in address field;
300      * for ftn use arg register saved in address field if it's the
301      * symbol which represents the arg's address.  Otherwise, get a
302      * register from the "global" set.
303      */
304     if (IS_REGARG(sym))
305       areg = ADDRESSG(sym);
306     else {
307       /*
308        * get a register from the global set
309        */
310       if ((areg = mr_getreg(rtype)) == NO_REG)
311         break;
312     }
313 
314     GET_RAT(rat) /* locate a rat entry */
315 
316     RAT_REG(rat) = ad1ili(RTYPE_DF(rtype), areg);
317 
318     RAT_RTYPE(rat) = rtype;             /* don't forget its rtype */
319     RAT_ATYPE(rat) = RATA_NME;          /* opt 1 assigns nme's only */
320     RAT_ADDR(rat) = addr;               /* locate addr ili of ref   */
321     RAT_CONFL(rat) = 0;                 /* no conflict for opt 1    */
322     RAT_STORE(rat) = RCAND_STORE(cand); /* copy up store flag       */
323     RAT_VAL(rat) = nme;                 /* record nme assigned      */
324     RAT_MSIZE(rat) = RCAND_MSIZE(cand); /* copy up mem size         */
325                                         /*
326                                          * if the symbol is an argument to the function, add a move ili of
327                                          * the argument to its assigned register
328                                          */
329     /* for fortran, a REGARG sym has its address in the register, not
330      * the value of the argument.  REDUC flag indicates that no extra
331      * indirection is needed.
332      */
333     if (IS_DUM(sym)) {
334       if (REGARGG(sym)) {
335         if (!REDUCG(sym)) {
336           /* we're preloading the dummy argument; we need to use
337            * the arg register that's assigned to its address as the
338            * address expression in the the load.
339            */
340           addr = ad1ili(IL_ARDF, ADDRESSG(sym));
341           if (flg.endian &&
342               (DTYPEG(sym) == DT_INT8 || DTYPEG(sym) == DT_LOG8)) {
343             if (!XBIT(124, 0x400))
344               /* 32bits of significance in 64 bits */
345               addr = ad3ili(IL_AADD, addr, ad_aconi(4), 0);
346           }
347           RAT_ADDR(rat) = addr; /* switch addr expr */
348           ilix = ad3ili(ILI_OPC(ilix), addr, ILI_OPND(ilix, 2),
349                         ILI_OPND(ilix, 3));
350           ilt = addilt(ilt, ilitmp = ad2ili(MV_RTYPE(rtype), ilix, areg));
351           ADDNODE(list, ilitmp);
352         }
353       } else {
354         ilt = addilt(ilt, ilitmp = ad2ili(MV_RTYPE(rtype), ilix, areg));
355         ADDNODE(list, ilitmp);
356       }
357     } else {
358       /*
359        * FORTRAN only - if the symbol is local to the function and has
360        * been data initialized, add a move ili of the argument to its
361        * assigned register
362        */
363       if (DINITG(sym)) {
364         ilt = addilt(ilt, ilitmp = ad2ili(MV_RTYPE(rtype), ilix, areg));
365         ADDNODE(list, ilitmp);
366       }
367     }
368   }
369 }
370