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