CACAO
simplereg.cpp
Go to the documentation of this file.
1 /* src/vm/jit/allocator/simplereg.cpp - register allocator
2 
3  Copyright (C) 1996-2014
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2009 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22  02111-1307, USA.
23 
24 */
25 
26 
27 #include "config.h"
28 
29 #include <cassert>
30 #include <stdint.h>
31 
32 #include "vm/types.hpp"
33 
34 #include "arch.hpp"
35 #include "md-abi.hpp"
36 
37 #include "mm/memory.hpp"
38 #include "mm/dumpmemory.hpp"
39 
40 #include "vm/descriptor.hpp" // for typedesc, methoddesc, etc
41 #include "vm/exceptions.hpp"
42 #include "vm/method.hpp"
43 #include "vm/options.hpp"
44 #include "vm/resolve.hpp"
45 
47 #include "vm/jit/abi.hpp"
48 #include "vm/jit/builtin.hpp"
49 #include "vm/jit/code.hpp"
50 #include "vm/jit/reg.hpp"
51 #include "vm/jit/show.hpp"
52 
54 
55 #define DEBUG_NAME "simplereg"
56 
57 
58 STAT_DECLARE_VAR(int,count_locals_spilled,0)
59 STAT_DECLARE_VAR(int,count_locals_register,0)
60 // currently not used!
61 STAT_DECLARE_VAR(int,count_ss_spilled,0)
62 // currently not used!
63 STAT_DECLARE_VAR(int,count_ss_register,0)
64 STAT_DECLARE_VAR(int,count_interface_size,0)
65 // currently not used!
66 STAT_DECLARE_VAR(int,count_argument_reg_ss,0)
67 // currently not used!
68 STAT_DECLARE_VAR(int,count_argument_mem_ss,0)
69 STAT_REGISTER_VAR(int,count_method_in_register,0,"methods in register","Number of Methods kept in registers")
70 
71 /* function prototypes for this file ******************************************/
72 
73 static void simplereg_allocate_interfaces(jitdata *jd);
74 static void simplereg_allocate_locals(jitdata *jd);
76 
77 
78 /* size of a stackslot used by the internal ABI */
79 
80 #define SIZE_OF_STACKSLOT 8
81 
82 
83 /* total number of registers */
84 
85 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
86 
87 
88 /* macros for handling register stacks ****************************************/
89 
90 #if !defined(NDEBUG)
91 # define AVAIL_FRONT(cnt, limit) (!opt_RegallocSpillAll && ((cnt) < (limit)))
92 # define AVAIL_BACK(cnt) (!opt_RegallocSpillAll && ((cnt) > 0))
93 #else
94 # define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
95 # define AVAIL_BACK(cnt) ((cnt) > 0)
96 #endif
97 
98 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
99 # if !defined(NDEBUG)
100 # define AVAIL_FRONT_INT(cnt, limit) (!opt_RegallocSpillAll && ((cnt) < (limit) - intregsneeded))
101 # define AVAIL_BACK_INT(cnt) (!opt_RegallocSpillAll && ((cnt) > intregsneeded))
102 # else
103 # define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
104 # define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
105 # endif
106 #else
107 # define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
108 # define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
109 #endif
110 
111 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
112 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
113 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
114 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
115 
116 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
117 #define POP_FRONT_INT(stk, cnt, reg) \
118  do { \
119  if (intregsneeded) { \
120  reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
121  cnt += 2; \
122  } \
123  else \
124  POP_FRONT(stk, cnt, reg); \
125  } while (0)
126 #else
127 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
128 #endif
129 
130 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
131 #define POP_BACK_INT(stk, cnt, reg) \
132  do { \
133  if (intregsneeded) { \
134  cnt -= 2; \
135  reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
136  } \
137  else \
138  POP_BACK(stk, cnt, reg); \
139  } while (0)
140 #else
141 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
142 #endif
143 
144 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
145 #define PUSH_BACK_INT(stk, cnt, reg) \
146  do { \
147  if (intregsneeded) { \
148  stk[cnt] = GET_LOW_REG(reg); \
149  stk[cnt + 1] = GET_HIGH_REG(reg); \
150  cnt += 2; \
151  } \
152  else \
153  PUSH_BACK(stk, cnt, reg); \
154  } while (0)
155 #else
156 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
157 #endif
158 
159 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
160 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
161 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
162 
163 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
164 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
165 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
166 
167 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
168 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
169 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
170 
171 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
172 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
173 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
174 
175 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
176 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
177 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
178 
179 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
180 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
181 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
182 
183 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
184 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
185 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
186 
187 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
188 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
189 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
190 
191 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
192 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
193 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
194 
195 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
196 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
197 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
198 
199 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
200 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
201 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
202 
203 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
204 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
205 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
206 
207 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
208 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
209 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
210 
211 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
212 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
213 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
214 
215 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
216 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
217 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
218 
219 
220 /* macros for allocating memory slots ****************************************/
221 
222 #define NEW_MEM_SLOT(r) \
223  do { \
224  (r) = rd->memuse * SIZE_OF_STACKSLOT; \
225  rd->memuse += 1; \
226  } while (0)
227 
228 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
229 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
230 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
231 
232 
233 /* macros for creating/freeing temporary variables ***************************/
234 
235 #define NEW_TEMP_REG(index) \
236  if ( ((index) >= jd->localcount) \
237  && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
238  simplereg_new_temp(jd, (index))
239 
240 
241 #define FREE_TEMP_REG(index) \
242  if (((index) > jd->localcount) \
243  && (!(VAR(index)->flags & (PREALLOC)))) \
244  simplereg_free_temp(jd, (index))
245 
246 
247 /* macro for getting a unique register index *********************************/
248 
249 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
250 #define REG_INDEX(regoff, type) (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
251 #else
252 #define REG_INDEX(regoff, type) (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
253 #endif
254 
255 
256 /* regalloc ********************************************************************
257 
258  Does a simple register allocation.
259 
260 *******************************************************************************/
261 
262 bool regalloc(jitdata *jd)
263 {
264  /* There is a problem with the use of unused float argument
265  registers in leafmethods for stackslots on c7 (2 * Dual Core
266  AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
267  benchmark is heaviliy increased. This could be prevented by
268  setting rd->argfltreguse to FLT_ARG_CNT before calling
269  simplereg_allocate_temporaries and setting it back to the original
270  value before calling simplereg_allocate_locals. */
271 
275 
276  /* everthing's ok */
277 
278  return true;
279 }
280 
281 
282 /* simplereg_allocate_interfaces ***********************************************
283 
284  Allocates registers for all interface variables.
285 
286 *******************************************************************************/
287 
289 {
290  methodinfo *m;
291  codeinfo *code;
292  //codegendata *cd;
293  registerdata *rd;
294 
295  int s, t, tt, saved;
296  int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
297  /* in case more vars are packed into this interface slot */
298  /* Allocate LNG and DBL types first to ensure 2 registers */
299  /* on some architectures. */
300  int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
301  int flags, regoff;
302 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
303  int intregsneeded;
304 #endif
305 
306  /* get required compiler data */
307 
308  m = jd->m;
309  code = jd->code;
310  //cd = jd->cd;
311  rd = jd->rd;
312 
313  /* rd->memuse was already set in stack.c to allocate stack space
314  for passing arguments to called methods. */
315 
316 #if defined(__I386__)
317  if (checksync && code_is_synchronized(code)) {
318  /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
319  if (rd->memuse < 1)
320  rd->memuse = 1;
321  }
322 #endif
323 
324  if (code_is_leafmethod(code)) {
325  /* Reserve argument register, which will be used for Locals acting */
326  /* as Parameters */
327  if (rd->argintreguse < m->parseddesc->argintreguse)
329  if (rd->argfltreguse < m->parseddesc->argfltreguse)
331  }
332 
333  for (s = 0; s < jd->maxinterfaces; s++) {
334  intalloc = -1; fltalloc = -1;
335 
336  /* check if the interface at this stack depth must be a SAVEDVAR */
337 
338  saved = 0;
339 
340  for (tt = 0; tt <=4; tt++) {
341  if ((t = jd->interface_map[s * 5 + tt].flags) != jitdata::UNUSED) {
342  saved |= t & SAVEDVAR;
343  }
344  }
345 
346  /* allocate reg/mem for each type the interface is used as */
347 
348  for (tt = 0; tt <= 4; tt++) {
349  t = typeloop[tt];
350  if (jd->interface_map[s * 5 + t].flags == jitdata::UNUSED)
351  continue;
352 
353  flags = saved;
354  regoff = -1; /* initialize to invalid value */
355 
356 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
357  intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
358 #endif
359 
360  if (!saved) {
361  if (IS_FLT_DBL_TYPE(t)) {
362  if (fltalloc >= 0) {
363  /* Reuse memory slot(s)/register(s) for shared interface slots */
364  flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
365  regoff = jd->interface_map[fltalloc].regoff;
366  }
367  else if (AVAIL_ARG_FLT) {
368  flags |= ARGREG;
369  TAKE_ARG_FLT(regoff);
370  }
371  else if (AVAIL_TMP_FLT) {
372  TAKE_TMP_FLT(regoff);
373  }
374  else if (AVAIL_SAV_FLT) {
375  flags |= SAVREG;
376  TAKE_SAV_FLT(regoff);
377  }
378  else {
379  flags |= INMEMORY;
380  NEW_MEM_SLOT_FLT_DBL(regoff);
381  }
382  fltalloc = s * 5 + t;
383  }
384  else { /* !IS_FLT_DBL_TYPE(t) */
385 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
386  /*
387  * for i386 put all longs in memory
388  */
389  if (IS_2_WORD_TYPE(t)) {
390  flags |= INMEMORY;
391  NEW_MEM_SLOT_INT_LNG(regoff);
392  }
393  else
394 #endif
395  if (intalloc >= 0) {
396  /* Reuse memory slot(s)/register(s) for shared interface slots */
397  flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
398  regoff = jd->interface_map[intalloc].regoff;
399 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
400  /* reuse lower half */
401  if (!(flags & INMEMORY) && IS_2_WORD_TYPE(intalloc % 5))
402  regoff = GET_LOW_REG(regoff);
403 #endif
404  }
405  else {
406  if (AVAIL_ARG_INT) {
407  flags |= ARGREG;
408  TAKE_ARG_INT(regoff);
409  }
410  else if (AVAIL_TMP_INT) {
411  TAKE_TMP_INT(regoff);
412  }
413  else if (AVAIL_SAV_INT) {
414  flags |= SAVREG;
415  TAKE_SAV_INT(regoff);
416  }
417  else {
418  flags |= INMEMORY;
419  NEW_MEM_SLOT_INT_LNG(regoff);
420  }
421  }
422 
423  intalloc = s * 5 + t;
424  } /* if (IS_FLT_DBL_TYPE(t)) */
425  }
426  else { /* (saved) */
427  /* now the same like above, but without a chance to take a temporary register */
428  if (IS_FLT_DBL_TYPE(t)) {
429  if (fltalloc >= 0) {
430  flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
431  regoff = jd->interface_map[fltalloc].regoff;
432  }
433  else {
434  if (AVAIL_SAV_FLT) {
435  TAKE_SAV_FLT(regoff);
436  }
437  else {
438  flags |= INMEMORY;
439  NEW_MEM_SLOT_FLT_DBL(regoff);
440  }
441  }
442  fltalloc = s * 5 + t;
443  }
444  else { /* IS_INT_LNG */
445 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
446  /*
447  * for i386 put all longs in memory
448  */
449  if (IS_2_WORD_TYPE(t)) {
450  flags |= INMEMORY;
451  NEW_MEM_SLOT_INT_LNG(regoff);
452  }
453  else
454 #endif
455  {
456  if (intalloc >= 0) {
457  flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
458  regoff = jd->interface_map[intalloc].regoff;
459 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
460  /* reuse lower half */
461  if (!(flags & INMEMORY) && IS_2_WORD_TYPE(intalloc % 5))
462  regoff = GET_LOW_REG(regoff);
463 #endif
464  }
465  else {
466  if (AVAIL_SAV_INT) {
467  TAKE_SAV_INT(regoff);
468  }
469  else {
470  flags |= INMEMORY;
471  NEW_MEM_SLOT_INT_LNG(regoff);
472  }
473  }
474 
475  intalloc = s*5 + t;
476  } /* if (IS_FLT_DBL_TYPE(t) else */
477  } /* if (IS_ADR_TYPE(t)) else */
478  } /* if (saved) else */
479  /* if (type >= 0) */
480 
481  assert(regoff >= 0);
482  jd->interface_map[5*s + t].flags = flags | INOUT;
483  jd->interface_map[5*s + t].regoff = regoff;
484  } /* for t */
485  } /* for s */
486 }
487 
488 
489 /* simplereg_allocate_locals_leafmethod ****************************************
490 
491  Allocates registers for all local variables of a leafmethod.
492 
493 *******************************************************************************/
494 
496 {
497  methodinfo *m;
498  //codegendata *cd;
499  registerdata *rd;
500  methoddesc *md;
501 
502  int p, s, t, tt, varindex;
503  int intalloc, fltalloc;
504  varinfo *v;
505  int intregsneeded = 0;
506  int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
507  int fargcnt, iargcnt;
508 
509  /* get required compiler data */
510 
511  m = jd->m;
512  //cd = jd->cd;
513  rd = jd->rd;
514 
515  md = m->parseddesc;
516 
517  iargcnt = rd->argintreguse;
518  fargcnt = rd->argfltreguse;
519 
520  for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
521  intalloc = -1; fltalloc = -1;
522  for (tt = 0; tt <= 4; tt++) {
523  t = typeloop[tt];
524  varindex = jd->local_map[s * 5 + t];
525  if (varindex == jitdata::UNUSED)
526  continue;
527 
528  v = VAR(varindex);
529 
530 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
531  intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
532 #endif
533  if (IS_FLT_DBL_TYPE(t)) {
534  if (fltalloc >= 0) {
535  v->flags = VAR(fltalloc)->flags;
536  v->vv.regoff = VAR(fltalloc)->vv.regoff;
537  }
538 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
539  /* We can only use float arguments as local variables,
540  * if we do not pass them in integer registers. */
541  else if ((p < md->paramcount) && !md->params[p].inmemory) {
542  v->flags = 0;
543  v->vv.regoff = md->params[p].regoff;
544  }
545 #endif
546  else if (AVAIL_TMP_FLT) {
547  v->flags = 0;
548  TAKE_TMP_FLT(v->vv.regoff);
549  }
550  /* use unused argument registers as local registers */
551  else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
552  v->flags = 0;
554  fargcnt, v->vv.regoff);
555  }
556  else if (AVAIL_SAV_FLT) {
557  v->flags = 0;
558  TAKE_SAV_FLT(v->vv.regoff);
559  }
560  else {
561  v->flags = INMEMORY;
563  }
564  fltalloc = jd->local_map[s * 5 + t];
565 
566  }
567  else {
568 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
569  /*
570  * for i386 put all longs in memory
571  */
572  if (IS_2_WORD_TYPE(t)) {
573  v->flags = INMEMORY;
575  }
576  else
577 #endif
578  {
579  if (intalloc >= 0) {
580  v->flags = VAR(intalloc)->flags;
581 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
582  if (!(v->flags & INMEMORY) && IS_2_WORD_TYPE(VAR(intalloc)->type))
583  v->vv.regoff = GET_LOW_REG(VAR(intalloc)->vv.regoff);
584  else
585 #endif
586  v->vv.regoff = VAR(intalloc)->vv.regoff;
587  }
588  else if ((p < md->paramcount) &&
589  !md->params[p].inmemory)
590  {
591  v->flags = 0;
592 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
593  if (IS_2_WORD_TYPE(t))
594  v->vv.regoff =
596  GET_HIGH_REG(md->params[p].regoff));
597  else
598 #endif
599  v->vv.regoff = md->params[p].regoff;
600  }
601  else if (AVAIL_TMP_INT) {
602  v->flags = 0;
603  TAKE_TMP_INT(v->vv.regoff);
604  }
605  /*
606  * use unused argument registers as local registers
607  */
608  else if ((p >= m->parseddesc->paramcount) &&
609  (iargcnt + intregsneeded < INT_ARG_CNT))
610  {
611  v->flags = 0;
613  iargcnt, v->vv.regoff);
614  }
615  else if (AVAIL_SAV_INT) {
616  v->flags = 0;
617  TAKE_SAV_INT(v->vv.regoff);
618  }
619  else {
620  v->flags = INMEMORY;
622  }
623  }
624  intalloc = jd->local_map[s * 5 + t];
625  }
626  } /* for (tt=0;...) */
627 
628  /* If the current parameter is a 2-word type, the next local slot */
629  /* is skipped. */
630 
631  if (p < md->paramcount)
632  if (IS_2_WORD_TYPE(md->paramtypes[p].type))
633  s++;
634  }
635 }
636 
637 /* simplereg_allocate_locals ***************************************************
638 
639  Allocates registers for all local variables.
640 
641 *******************************************************************************/
642 
644 {
645  codeinfo *code;
646  //codegendata *cd;
647  registerdata *rd;
648 
649  int s, t, tt, varindex;
650  int intalloc, fltalloc;
651  varinfo *v;
652  int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
653 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
654  s4 intregsneeded;
655 #endif
656 
657  /* get required compiler data */
658 
659  code = jd->code;
660  //cd = jd->cd;
661  rd = jd->rd;
662 
663  if (code_is_leafmethod(code)) {
665  return;
666  }
667 
668  for (s = 0; s < jd->maxlocals; s++) {
669  intalloc = -1; fltalloc = -1;
670  for (tt=0; tt<=4; tt++) {
671  t = typeloop[tt];
672 
673  varindex = jd->local_map[s * 5 + t];
674  if (varindex == jitdata::UNUSED)
675  continue;
676 
677  v = VAR(varindex);
678 
679 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
680  intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
681 #endif
682 
683  if (IS_FLT_DBL_TYPE(t)) {
684  if (fltalloc >= 0) {
685  v->flags = VAR(fltalloc)->flags;
686  v->vv.regoff = VAR(fltalloc)->vv.regoff;
687  }
688  else if (AVAIL_SAV_FLT) {
689  v->flags = 0;
690  TAKE_SAV_FLT(v->vv.regoff);
691  }
692  else {
693  v->flags = INMEMORY;
695  }
696  fltalloc = jd->local_map[s * 5 + t];
697  }
698  else {
699 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
700  /*
701  * for i386 put all longs in memory
702  */
703  if (IS_2_WORD_TYPE(t)) {
704  v->flags = INMEMORY;
706  }
707  else {
708 #endif
709  if (intalloc >= 0) {
710  v->flags = VAR(intalloc)->flags;
711 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
712  if (!(v->flags & INMEMORY) && IS_2_WORD_TYPE(VAR(intalloc)->type))
713  v->vv.regoff = GET_LOW_REG(VAR(intalloc)->vv.regoff);
714  else
715 #endif
716  v->vv.regoff = VAR(intalloc)->vv.regoff;
717  }
718  else if (AVAIL_SAV_INT) {
719  v->flags = 0;
720  TAKE_SAV_INT(v->vv.regoff);
721  }
722  else {
723  v->flags = INMEMORY;
725  }
726 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
727  }
728 #endif
729  intalloc = jd->local_map[s * 5 + t];
730  }
731  }
732  }
733 }
734 
735 
736 static void simplereg_init(jitdata *jd, registerdata *rd)
737 {
738  int i;
739 
740  rd->freememtop = 0;
741 
742  rd->freetmpinttop = 0;
743  rd->freesavinttop = 0;
744  rd->freetmpflttop = 0;
745  rd->freesavflttop = 0;
746 
747  rd->freearginttop = 0;
748  rd->freeargflttop = 0;
749 
750  rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
751  rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
752  MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
753 
754  /* memcopycount is dynamically allocated when needed */
755 
756  rd->memcopycount = NULL;
757  rd->memcopycountsize = 0;
758 
759  rd->intusedinout = DMNEW(int, INT_REG_CNT);
760  MZERO(rd->intusedinout, int, INT_REG_CNT);
761  rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
762  MZERO(rd->fltusedinout, int, FLT_REG_CNT);
763 
764  /* record the interface registers as used */
765 
766  for (i=0; i<rd->argintreguse; ++i)
768  for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
769  rd->intusedinout[rd->tmpintregs[i]] = 1;
770  for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
771  rd->intusedinout[rd->savintregs[i]] = 1;
772 
773  for (i=0; i<rd->argfltreguse; ++i)
775  for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
776  rd->fltusedinout[rd->tmpfltregs[i]] = 1;
777  for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
778  rd->fltusedinout[rd->savfltregs[i]] = 1;
779 }
780 
781 
783 {
784  int i;
785 
786  /* remove all interface registers from the free lists */
787 
788  for (i=0; i<rd->freearginttop; ++i)
789  if (rd->intusedinout[rd->freeargintregs[i]]) {
790  rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
791  }
792  for (i=0; i<rd->freetmpinttop; ++i)
793  if (rd->intusedinout[rd->freetmpintregs[i]]) {
794  rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
795  }
796  for (i=0; i<rd->freesavinttop; ++i)
797  if (rd->intusedinout[rd->freesavintregs[i]]) {
798  rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
799  }
800 
801  for (i=0; i<rd->freeargflttop; ++i)
802  if (rd->fltusedinout[rd->freeargfltregs[i]]) {
803  rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
804  }
805  for (i=0; i<rd->freetmpflttop; ++i)
806  if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
807  rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
808  }
809  for (i=0; i<rd->freesavflttop; ++i)
810  if (rd->fltusedinout[rd->freesavfltregs[i]]) {
811  rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
812  }
813 }
814 
815 
817 {
818 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
819  s4 intregsneeded;
820 #endif
821  s4 tryagain;
822  registerdata *rd;
823  varinfo *v;
824 
825  rd = jd->rd;
826  v = VAR(index);
827 
828  /* assert that constants are not allocated */
829 
830  assert(v->type != TYPE_RET);
831 
832  /* Try to allocate a saved register if there is no temporary one */
833  /* available. This is what happens during the second run. */
834  tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
835 
836 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
837  intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
838 #endif
839 
840  for(; tryagain; --tryagain) {
841  if (tryagain == 1) {
842  if (!(v->flags & SAVEDVAR))
843  v->flags |= SAVREG;
844 
845  if (IS_FLT_DBL_TYPE(v->type)) {
846  if (AVAIL_FREE_SAV_FLT) {
848  return;
849  }
850  else if (AVAIL_SAV_FLT) {
851  TAKE_SAV_FLT(v->vv.regoff);
852  return;
853  }
854  }
855  else {
856 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
857  /*
858  * for i386 put all longs in memory
859  */
860  if (!IS_2_WORD_TYPE(v->type))
861 #endif
862  {
863  if (AVAIL_FREE_SAV_INT) {
865  return;
866  }
867  else if (AVAIL_SAV_INT) {
868  TAKE_SAV_INT(v->vv.regoff);
869  return;
870  }
871  }
872  }
873  }
874  else { /* tryagain == 2 */
875  if (IS_FLT_DBL_TYPE(v->type)) {
876  if (AVAIL_FREE_ARG_FLT) {
877  v->flags |= ARGREG;
879  return;
880  }
881  else if (AVAIL_ARG_FLT) {
882  v->flags |= ARGREG;
883  TAKE_ARG_FLT(v->vv.regoff);
884  return;
885  }
886  else if (AVAIL_FREE_TMP_FLT) {
888  return;
889  }
890  else if (AVAIL_TMP_FLT) {
891  TAKE_TMP_FLT(v->vv.regoff);
892  return;
893  }
894  }
895  else {
896 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
897  /*
898  * for i386 put all longs in memory
899  */
900  if (!IS_2_WORD_TYPE(v->type))
901 #endif
902  {
903  if (AVAIL_FREE_ARG_INT) {
904  v->flags |= ARGREG;
906  return;
907  }
908  else if (AVAIL_ARG_INT) {
909  v->flags |= ARGREG;
910  TAKE_ARG_INT(v->vv.regoff);
911  return;
912  }
913  else if (AVAIL_FREE_TMP_INT) {
915  return;
916  }
917  else if (AVAIL_TMP_INT) {
918  TAKE_TMP_INT(v->vv.regoff);
919  return;
920  }
921  } /* if (!IS_2_WORD_TYPE(s->type)) */
922  } /* if (IS_FLT_DBL_TYPE(s->type)) */
923  } /* if (tryagain == 1) else */
924  } /* for(; tryagain; --tryagain) */
925 
926  /* spill to memory */
927 
928  v->flags |= INMEMORY;
929 
930  if (rd->freememtop > 0)
931  POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
932  else
934 }
935 
936 
937 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
938 {
939  /* assert that constants are not freed */
940 
941  assert(type != TYPE_RET);
942 
943  /* if this is a copy of another variable, just decrement the copy counter */
944 
945  if (flags & INMEMORY) {
946  int32_t memindex;
947 
948  if (flags & INOUT)
949  return;
950 
951  memindex = regoff / SIZE_OF_STACKSLOT;
952 
953  if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
954  rd->memcopycount[memindex]--;
955  return;
956  }
957  }
958  else {
959  s4 regindex;
960 
961  regindex = REG_INDEX(regoff, type);
962 
963  /* do not free interface registers that are needed as outvars */
964 
965  if (flags & INOUT) {
966  if (rd->regisoutvar[regindex]) {
967  LOG("DONT FREE f=" << cacao::hex << cacao::setw(2)
968  << cacao::fillzero << flags << cacao::dec
969  << " r=" << regoff << " t=" << type << cacao::nl);
970  return;
971  }
972 
973  LOG("FREEING INVAR f=" << cacao::hex << cacao::setw(2)
974  << cacao::fillzero << flags << cacao::dec
975  << " r=" << regoff << " t=" << type << cacao::nl);
976  }
977 
978  if (rd->regcopycount[regindex]) {
979  rd->regcopycount[regindex]--;
980  return;
981  }
982  }
983 
984  if (flags & INMEMORY) {
985  PUSH_BACK(rd->freemem, rd->freememtop, regoff);
986  return;
987  }
988 
989  /* freeing a register */
990 
991  else if (IS_FLT_DBL_TYPE(type)) {
992  if (flags & (SAVEDVAR | SAVREG))
993  PUSH_FREE_SAV_FLT(regoff);
994  else if (flags & ARGREG)
995  PUSH_FREE_ARG_FLT(regoff);
996  else
997  PUSH_FREE_TMP_FLT(regoff);
998  }
999  else { /* IS_INT_LNG_TYPE */
1000 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1001  s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1002 #endif
1003 
1004  if (flags & (SAVEDVAR | SAVREG))
1005  PUSH_FREE_SAV_INT(regoff);
1006  else if (flags & ARGREG)
1007  PUSH_FREE_ARG_INT(regoff);
1008  else
1009  PUSH_FREE_TMP_INT(regoff);
1010  }
1011 }
1012 
1013 
1014 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1015 {
1016  varinfo *v;
1017 
1018  v = VAR(index);
1019 
1020  simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1021 }
1022 
1023 
1024 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1025 {
1026  varinfo *sv;
1027  varinfo *dv;
1028 
1029  /* do not coalesce local variables here */
1030 
1031  if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1032  return false;
1033 
1034  sv = VAR(srcindex);
1035  dv = VAR(dstindex);
1036 
1037  /* do not coalesce in/out vars or preallocated variables here */
1038 
1039  if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1040  return false;
1041 
1042  /* if the source is in memory, we can coalesce in any case */
1043 
1044  if (sv->flags & INMEMORY) {
1045  dv->flags |= INMEMORY;
1046  dv->vv.regoff = sv->vv.regoff;
1047  return true;
1048  }
1049 
1050  /* we do not allocate a REG_TMP to a REG_SAV variable */
1051 
1052  if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1053  return false;
1054 
1055  /* coalesce */
1056  dv->vv.regoff = sv->vv.regoff;
1057  dv->flags |= sv->flags & (SAVREG | ARGREG);
1058 
1059  return true;
1060 }
1061 
1062 
1063 /* simplereg_allocate_temporaries **********************************************
1064 
1065  Allocate temporary (non-interface, non-local) registers.
1066 
1067 *******************************************************************************/
1068 
1070 {
1071  //methodinfo *m;
1072  registerdata *rd;
1073  s4 i;
1074  s4 len;
1075  instruction *iptr;
1076  basicblock *bptr;
1077  builtintable_entry *bte;
1078  methoddesc *md;
1079  s4 *argp;
1080  varinfo *v;
1081  s4 flags;
1082  s4 regoff;
1083  s4 type;
1084  s4 regindex;
1085 
1086  /* get required compiler data */
1087 
1088  //m = jd->m;
1089  rd = jd->rd;
1090 
1091  /* initialize temp registers */
1092 
1093  simplereg_init(jd, rd);
1094 
1095  bptr = jd->basicblocks;
1096 
1097  while (bptr != NULL) {
1098  if (bptr->state >= basicblock::REACHED) {
1099 
1100  LOG(cacao::nl << "allocating block L" << cacao::setw(3)
1101  << cacao::fillzero << bptr->nr << cacao::nl);
1102 
1104 
1105  /* assert that all copy counts are zero */
1106 
1107 #if !defined(NDEBUG) && !defined(ENABLE_SSA)
1108  for (i=0; i < TOTAL_REG_CNT; ++i)
1109  assert(rd->regcopycount[i] == 0);
1110 #endif
1111 
1112  /* reset outvar flags */
1113 
1114  MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1115 
1116  /* set allocation of invars */
1117 
1118  for (i=0; i<bptr->indepth; ++i)
1119  {
1120  v = VAR(bptr->invars[i]);
1121  if (v->type == TYPE_RET)
1122  continue;
1123 
1124  v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1125  v->flags = jd->interface_map[5*i + v->type].flags;
1126 
1127  if (!(v->flags & INMEMORY))
1128  rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1129  }
1130 
1131  /* set allocation of outvars */
1132 
1133  for (i=0; i<bptr->outdepth; ++i)
1134  {
1135  v = VAR(bptr->outvars[i]);
1136  if (v->type == TYPE_RET)
1137  continue;
1138 
1139  v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1140  v->flags = jd->interface_map[5*i + v->type].flags;
1141 
1142  if (!(v->flags & INMEMORY)) {
1143  regindex = REG_INDEX(v->vv.regoff, v->type);
1144  rd->regcopycount[regindex] = 1;
1145  rd->regisoutvar[regindex] = 1;
1146  }
1147  }
1148 
1149  /* free interface registers not used in this block */
1150 
1151  for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1152  type = i%5;
1153  regoff = jd->interface_map[i].regoff;
1154  flags = jd->interface_map[i].flags;
1155 
1156  if (!(flags & INMEMORY)) {
1157  if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1158  LOG("MAY REUSE interface register f="
1160  << flags << cacao::dec
1161  << " r=" << regoff << " t=" << type << cacao::nl);
1162  simplereg_free(rd, flags, regoff, type);
1163 
1164  /* mark it, so it is not freed again */
1165  rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1166  }
1167  }
1168  }
1169 
1170  /* reset copy counts */
1171 
1172  MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1173 
1174  /* iterate over ICMDS to allocate temporary variables */
1175 
1176  iptr = bptr->iinstr;
1177  len = bptr->icount;
1178 
1179  while (--len >= 0) {
1180 
1181  switch (iptr->opc) {
1182 
1183  /* pop 0 push 0 */
1184 
1185  case ICMD_JSR:
1186  case ICMD_NOP:
1187  case ICMD_CHECKNULL:
1188  case ICMD_IINC:
1189  case ICMD_RET:
1190  case ICMD_RETURN:
1191  case ICMD_GOTO:
1192  case ICMD_BREAKPOINT:
1193  case ICMD_PUTSTATICCONST:
1194  case ICMD_INLINE_START:
1195  case ICMD_INLINE_END:
1196  case ICMD_INLINE_BODY:
1197  break;
1198 
1199  /* pop 0 push 1 const */
1200 
1201  case ICMD_ICONST:
1202  case ICMD_LCONST:
1203  case ICMD_FCONST:
1204  case ICMD_DCONST:
1205  case ICMD_ACONST:
1206  case ICMD_GETEXCEPTION:
1207 
1208  /* pop 0 push 1 load */
1209 
1210  case ICMD_ILOAD:
1211  case ICMD_LLOAD:
1212  case ICMD_FLOAD:
1213  case ICMD_DLOAD:
1214  case ICMD_ALOAD:
1215  NEW_TEMP_REG(iptr->dst.varindex);
1216  break;
1217 
1218  /* pop 2 push 1 */
1219 
1220  case ICMD_IALOAD:
1221  case ICMD_LALOAD:
1222  case ICMD_FALOAD:
1223  case ICMD_DALOAD:
1224  case ICMD_AALOAD:
1225 
1226  case ICMD_BALOAD:
1227  case ICMD_CALOAD:
1228  case ICMD_SALOAD:
1229  FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1230  FREE_TEMP_REG(iptr->s1.varindex);
1231  NEW_TEMP_REG(iptr->dst.varindex);
1232  break;
1233 
1234  /* pop 3 push 0 */
1235 
1236  case ICMD_IASTORE:
1237  case ICMD_LASTORE:
1238  case ICMD_FASTORE:
1239  case ICMD_DASTORE:
1240  case ICMD_AASTORE:
1241 
1242  case ICMD_BASTORE:
1243  case ICMD_CASTORE:
1244  case ICMD_SASTORE:
1245  FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1246  FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1247  FREE_TEMP_REG(iptr->s1.varindex);
1248  break;
1249 
1250  /* pop 1 push 0 store */
1251 
1252  case ICMD_ISTORE:
1253  case ICMD_LSTORE:
1254  case ICMD_FSTORE:
1255  case ICMD_DSTORE:
1256  case ICMD_ASTORE:
1257 
1258  /* pop 1 push 0 */
1259 
1260  case ICMD_POP:
1261 
1262  case ICMD_IRETURN:
1263  case ICMD_LRETURN:
1264  case ICMD_FRETURN:
1265  case ICMD_DRETURN:
1266  case ICMD_ARETURN:
1267 
1268  case ICMD_ATHROW:
1269 
1270  case ICMD_PUTSTATIC:
1271  case ICMD_PUTFIELDCONST:
1272 
1273  /* pop 1 push 0 branch */
1274 
1275  case ICMD_IFNULL:
1276  case ICMD_IFNONNULL:
1277 
1278  case ICMD_IFEQ:
1279  case ICMD_IFNE:
1280  case ICMD_IFLT:
1281  case ICMD_IFGE:
1282  case ICMD_IFGT:
1283  case ICMD_IFLE:
1284 
1285  case ICMD_IF_LEQ:
1286  case ICMD_IF_LNE:
1287  case ICMD_IF_LLT:
1288  case ICMD_IF_LGE:
1289  case ICMD_IF_LGT:
1290  case ICMD_IF_LLE:
1291 
1292  /* pop 1 push 0 table branch */
1293 
1294  case ICMD_TABLESWITCH:
1295  case ICMD_LOOKUPSWITCH:
1296 
1297  case ICMD_MONITORENTER:
1298  case ICMD_MONITOREXIT:
1299  FREE_TEMP_REG(iptr->s1.varindex);
1300  break;
1301 
1302  /* pop 2 push 0 branch */
1303 
1304  case ICMD_IF_ICMPEQ:
1305  case ICMD_IF_ICMPNE:
1306  case ICMD_IF_ICMPLT:
1307  case ICMD_IF_ICMPGE:
1308  case ICMD_IF_ICMPGT:
1309  case ICMD_IF_ICMPLE:
1310 
1311  case ICMD_IF_LCMPEQ:
1312  case ICMD_IF_LCMPNE:
1313  case ICMD_IF_LCMPLT:
1314  case ICMD_IF_LCMPGE:
1315  case ICMD_IF_LCMPGT:
1316  case ICMD_IF_LCMPLE:
1317 
1318  case ICMD_IF_ACMPEQ:
1319  case ICMD_IF_ACMPNE:
1320 
1321  /* pop 2 push 0 */
1322 
1323  case ICMD_POP2:
1324 
1325  case ICMD_PUTFIELD:
1326 
1327  case ICMD_IASTORECONST:
1328  case ICMD_LASTORECONST:
1329  case ICMD_AASTORECONST:
1330  case ICMD_BASTORECONST:
1331  case ICMD_CASTORECONST:
1332  case ICMD_SASTORECONST:
1333  FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1334  FREE_TEMP_REG(iptr->s1.varindex);
1335  break;
1336 
1337  /* pop 0 push 1 copy */
1338 
1339  case ICMD_COPY:
1340  /* src === dst->prev (identical Stackslot Element) */
1341  /* src --> dst (copied value, take same reg/mem) */
1342 
1343  if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1344  NEW_TEMP_REG(iptr->dst.varindex);
1345  }
1346  else {
1347  v = VAROP(iptr->dst);
1348 
1349  if (v->flags & INMEMORY) {
1350  int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
1351  if (memindex >= rd->memcopycountsize) {
1352  int newsize = (memindex + 1) * 2;
1353  i = rd->memcopycountsize;
1354  rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1355  MZERO(rd->memcopycount + i, int, newsize - i);
1356  rd->memcopycountsize = newsize;
1357  }
1358  rd->memcopycount[memindex]++;
1359  }
1360  else {
1361  /* XXX split reg/mem variables on arm may need special handling here */
1362 
1363  s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1364 
1365  rd->regcopycount[regindex]++;
1366  }
1367  }
1368  break;
1369 
1370  /* pop 1 push 1 move */
1371 
1372  case ICMD_MOVE:
1373  if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1374  NEW_TEMP_REG(iptr->dst.varindex);
1375  FREE_TEMP_REG(iptr->s1.varindex);
1376  }
1377  break;
1378 
1379  /* pop 2 push 1 */
1380 
1381  case ICMD_IADD:
1382  case ICMD_ISUB:
1383  case ICMD_IMUL:
1384  case ICMD_IDIV:
1385  case ICMD_IREM:
1386 
1387  case ICMD_ISHL:
1388  case ICMD_ISHR:
1389  case ICMD_IUSHR:
1390  case ICMD_IAND:
1391  case ICMD_IOR:
1392  case ICMD_IXOR:
1393 
1394  case ICMD_LADD:
1395  case ICMD_LSUB:
1396  case ICMD_LMUL:
1397  case ICMD_LDIV:
1398  case ICMD_LREM:
1399 
1400  case ICMD_LOR:
1401  case ICMD_LAND:
1402  case ICMD_LXOR:
1403 
1404  case ICMD_LSHL:
1405  case ICMD_LSHR:
1406  case ICMD_LUSHR:
1407 
1408  case ICMD_FADD:
1409  case ICMD_FSUB:
1410  case ICMD_FMUL:
1411  case ICMD_FDIV:
1412  case ICMD_FREM:
1413 
1414  case ICMD_DADD:
1415  case ICMD_DSUB:
1416  case ICMD_DMUL:
1417  case ICMD_DDIV:
1418  case ICMD_DREM:
1419 
1420  case ICMD_LCMP:
1421  case ICMD_FCMPL:
1422  case ICMD_FCMPG:
1423  case ICMD_DCMPL:
1424  case ICMD_DCMPG:
1425  FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1426  FREE_TEMP_REG(iptr->s1.varindex);
1427  NEW_TEMP_REG(iptr->dst.varindex);
1428  break;
1429 
1430  /* pop 1 push 1 */
1431 
1432  case ICMD_IADDCONST:
1433  case ICMD_ISUBCONST:
1434  case ICMD_IMULCONST:
1435  case ICMD_IMULPOW2:
1436  case ICMD_IDIVPOW2:
1437  case ICMD_IREMPOW2:
1438  case ICMD_IANDCONST:
1439  case ICMD_IORCONST:
1440  case ICMD_IXORCONST:
1441  case ICMD_ISHLCONST:
1442  case ICMD_ISHRCONST:
1443  case ICMD_IUSHRCONST:
1444 
1445  case ICMD_LADDCONST:
1446  case ICMD_LSUBCONST:
1447  case ICMD_LMULCONST:
1448  case ICMD_LMULPOW2:
1449  case ICMD_LDIVPOW2:
1450  case ICMD_LREMPOW2:
1451  case ICMD_LANDCONST:
1452  case ICMD_LORCONST:
1453  case ICMD_LXORCONST:
1454  case ICMD_LSHLCONST:
1455  case ICMD_LSHRCONST:
1456  case ICMD_LUSHRCONST:
1457 
1458  case ICMD_INEG:
1459  case ICMD_INT2BYTE:
1460  case ICMD_INT2CHAR:
1461  case ICMD_INT2SHORT:
1462  case ICMD_LNEG:
1463  case ICMD_FNEG:
1464  case ICMD_DNEG:
1465 
1466  case ICMD_I2L:
1467  case ICMD_I2F:
1468  case ICMD_I2D:
1469  case ICMD_L2I:
1470  case ICMD_L2F:
1471  case ICMD_L2D:
1472  case ICMD_F2I:
1473  case ICMD_F2L:
1474  case ICMD_F2D:
1475  case ICMD_D2I:
1476  case ICMD_D2L:
1477  case ICMD_D2F:
1478 
1479  case ICMD_CHECKCAST:
1480 
1481  case ICMD_ARRAYLENGTH:
1482  case ICMD_INSTANCEOF:
1483 
1484  case ICMD_NEWARRAY:
1485  case ICMD_ANEWARRAY:
1486 
1487  case ICMD_GETFIELD:
1488  FREE_TEMP_REG(iptr->s1.varindex);
1489  NEW_TEMP_REG(iptr->dst.varindex);
1490  break;
1491 
1492  /* pop 0 push 1 */
1493 
1494  case ICMD_GETSTATIC:
1495 
1496  case ICMD_NEW:
1497  NEW_TEMP_REG(iptr->dst.varindex);
1498  break;
1499 
1500  /* pop many push any */
1501 
1502  case ICMD_INVOKESTATIC:
1503  case ICMD_INVOKESPECIAL:
1504  case ICMD_INVOKEVIRTUAL:
1505  case ICMD_INVOKEINTERFACE:
1506  INSTRUCTION_GET_METHODDESC(iptr,md);
1507  i = md->paramcount;
1508  argp = iptr->sx.s23.s2.args;
1509  while (--i >= 0) {
1510  FREE_TEMP_REG(*argp);
1511  argp++;
1512  }
1513  if (md->returntype.type != TYPE_VOID)
1514  NEW_TEMP_REG(iptr->dst.varindex);
1515  break;
1516 
1517  case ICMD_BUILTIN:
1518  bte = iptr->sx.s23.s3.bte;
1519  md = bte->md;
1520  i = md->paramcount;
1521  argp = iptr->sx.s23.s2.args;
1522  while (--i >= 0) {
1523  FREE_TEMP_REG(*argp);
1524  argp++;
1525  }
1526  if (md->returntype.type != TYPE_VOID)
1527  NEW_TEMP_REG(iptr->dst.varindex);
1528  break;
1529 
1530  case ICMD_MULTIANEWARRAY:
1531  i = iptr->s1.argcount;
1532  argp = iptr->sx.s23.s2.args;
1533  while (--i >= 0) {
1534  FREE_TEMP_REG(*argp);
1535  argp++;
1536  }
1537  NEW_TEMP_REG(iptr->dst.varindex);
1538  break;
1539 
1540  default:
1541  exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1542  iptr->opc);
1543  return;
1544  } /* switch */
1545  iptr++;
1546  } /* while instructions */
1547  } /* if */
1548  bptr = bptr->next;
1549  } /* while blocks */
1550 }
1551 
1552 
1553 #if defined(ENABLE_STATISTICS)
1554 void simplereg_make_statistics(jitdata *jd)
1555 {
1556  //methodinfo *m;
1557  //codegendata *cd;
1558  //registerdata *rd;
1559  int i;
1560  s4 len;
1561 #if 0
1562  stackelement_t* src, src_old;
1563  stackelement_t* dst;
1564  instruction *iptr;
1565 #endif
1566  basicblock *bptr;
1567  int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1568  bool in_register;
1569  //varinfo *var;
1570 
1571  /* get required compiler data */
1572 
1573  //m = jd->m;
1574  //cd = jd->cd;
1575  //rd = jd->rd;
1576 
1577  in_register = true;
1578 
1579  size_interface = 0;
1580 
1581  /* count how many local variables are held in memory or register */
1582  for(i=0; i < jd->localcount; i++) {
1583  if (VAR(i)->flags & INMEMORY) {
1584  STATISTICS(count_locals_spilled++);
1585  in_register=false;
1586  }
1587  else {
1588  STATISTICS(count_locals_register++);
1589  }
1590  }
1591 
1592  /* count how many stack slots are held in memory or register */
1593 
1594  bptr = jd->basicblocks;
1595 
1596  while (bptr != NULL) {
1597  if (bptr->state >= basicblock::REACHED) {
1598 
1599 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1600  if (!opt_lsra) {
1601 #endif
1602  /* check for memory moves from interface to BB instack */
1603  len = bptr->indepth;
1604 
1605  if (len > size_interface) size_interface = len;
1606 
1607  while (len) {
1608  len--;
1609  //var = VAR(bptr->invars[len]);
1610 
1611  /* invars statistics (currently none) */
1612  }
1613 
1614  /* check for memory moves from BB outstack to interface */
1615  len = bptr->outdepth;
1616  if (len > size_interface) size_interface = len;
1617 
1618  while (len) {
1619  len--;
1620  //var = VAR(bptr->outvars[len]);
1621 
1622  /* outvars statistics (currently none) */
1623  }
1624 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1625  }
1626 #endif
1627 
1628 
1629 #if 0
1630  dst = bptr->instack;
1631  iptr = bptr->iinstr;
1632  len = bptr->icount;
1633  src_old = NULL;
1634 
1635  while (--len >= 0) {
1636  src = dst;
1637  dst = iptr->dst.var;
1638 
1639  if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1640  switch (src->varkind) {
1641  case TEMPVAR:
1642  case STACKVAR:
1643  if (!(src->flags & INMEMORY))
1644  STATISTICS(count_ss_register++);
1645  else {
1646  STATISTICS(count_ss_spilled++);
1647  in_register=false;
1648  }
1649  break;
1650  /* case LOCALVAR: */
1651  /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1652  /* STATISTICS(count_ss_register++); */
1653  /* else */
1654  /* STATISTICS(count_ss_spilled++); */
1655  /* break; */
1656  case ARGVAR:
1657  if (!(src->flags & INMEMORY))
1658  STATISTICS(count_argument_mem_ss++);
1659  else
1660  STATISTICS(count_argument_reg_ss++);
1661  break;
1662 
1663 
1664  /* if (IS_FLT_DBL_TYPE(src->type)) { */
1665  /* if (src->varnum < FLT_ARG_CNT) { */
1666  /* STATISTICS(count_ss_register++); */
1667  /* break; */
1668  /* } */
1669  /* } else { */
1670  /* #if defined(__POWERPC__) */
1671  /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1672  /* #else */
1673  /* if (src->varnum < INT_ARG_CNT) { */
1674  /* #endif */
1675  /* STATISTICS(count_ss_register++); */
1676  /* break; */
1677  /* } */
1678  /* } */
1679  /* STATISTICS(count_ss_spilled++); */
1680  /* break; */
1681  }
1682  }
1683  src_old = src;
1684 
1685  iptr++;
1686  } /* while instructions */
1687 #endif
1688  } /* if */
1689 
1690  bptr = bptr->next;
1691  } /* while blocks */
1692 
1693  STATISTICS(count_interface_size += size_interface); /* accummulate the size of the interface (between bb boundaries) */
1694  if (in_register) {
1695  STATISTICS(count_method_in_register++);
1696 /* printf("INREGISTER: %s%s%s\n",UTF_TEXT(m->class->name), UTF_TEXT(m->name), UTF_TEXT(m->descriptor)); */
1697  }
1698 }
1699 #endif /* defined(ENABLE_STATISTICS) */
1700 
1701 
1702 /*
1703  * These are local overrides for various environment variables in Emacs.
1704  * Please do not remove this and leave it at the end of the file, where
1705  * Emacs will automagically detect them.
1706  * ---------------------------------------------------------------------
1707  * Local variables:
1708  * mode: c++
1709  * indent-tabs-mode: t
1710  * c-basic-offset: 4
1711  * tab-width: 4
1712  * End:
1713  * vim:noexpandtab:sw=4:ts=4:
1714  */
const s4 abi_registers_float_argument[]
Definition: md-abi.cpp:107
#define GET_HIGH_REG(a)
static void simplereg_new_temp(jitdata *jd, s4 index)
Definition: simplereg.cpp:816
std::size_t index
union varinfo::@19 vv
int argintreguse
Definition: reg.hpp:86
#define NEW_TEMP_REG(index)
Definition: simplereg.cpp:235
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
#define AVAIL_FREE_ARG_INT
Definition: simplereg.cpp:179
static SetWidth setw(size_t w)
Definition: OStream.hpp:395
basicblock * basicblocks
Definition: jit.hpp:141
int freesavflttop
Definition: reg.hpp:98
Definition: stack.hpp:41
static void simplereg_allocate_locals(jitdata *jd)
Definition: simplereg.cpp:643
Definition: jit.hpp:126
int * freemem
Definition: reg.hpp:81
Definition: stack.hpp:46
paramdesc * params
Definition: descriptor.hpp:164
#define AVAIL_ARG_INT
Definition: simplereg.cpp:167
#define TAKE_FREE_ARG_FLT(r)
Definition: simplereg.cpp:195
methoddesc * md
Definition: builtin.hpp:71
s4 localcount
Definition: jit.hpp:152
int * savintregs
Definition: reg.hpp:71
#define TAKE_TMP_FLT(r)
Definition: simplereg.cpp:184
State state
Definition: jit.hpp:313
int * freeargfltregs
Definition: reg.hpp:77
#define DMREALLOC(ptr, type, num1, num2)
Definition: dumpmemory.hpp:372
int * freetmpfltregs
Definition: reg.hpp:78
Definition: stack.hpp:42
s4 maxlocals
Definition: jit.hpp:162
s4 * invars
Definition: jit.hpp:323
basicblock * next
Definition: jit.hpp:337
const s4 abi_registers_integer_argument[]
Definition: md-abi.cpp:64
codeinfo * code
Definition: jit.hpp:128
s4 outdepth
Definition: jit.hpp:326
int32_t argcount
Definition: instruction.hpp:64
static void simplereg_free_temp(jitdata *jd, s4 index)
Definition: simplereg.cpp:1014
int memcopycountsize
Definition: reg.hpp:105
int32_t varindex
Definition: instruction.hpp:63
static void simplereg_allocate_temporaries(jitdata *jd)
Definition: simplereg.cpp:1069
int32_t flags
Definition: stack.hpp:67
Definition: stack.hpp:59
#define INT_REG_CNT
Definition: md-abi.hpp:72
#define FREE_TEMP_REG(index)
Definition: simplereg.cpp:241
#define AVAIL_TMP_INT
Definition: simplereg.cpp:168
#define PUSH_BACK(stk, cnt, reg)
Definition: simplereg.cpp:114
int * tmpfltregs
Definition: reg.hpp:72
int * freesavfltregs
Definition: reg.hpp:79
int savintreguse
Definition: reg.hpp:88
#define NEW_MEM_SLOT_INT_LNG(r)
Definition: simplereg.cpp:228
static void simplereg_init(jitdata *jd, registerdata *rd)
Definition: simplereg.cpp:736
#define POP_FRONT_INT(stk, cnt, reg)
Definition: simplereg.cpp:127
Type type
Definition: reg.hpp:44
int freememtop
Definition: reg.hpp:82
Hex hex
Definition: OStream.cpp:50
#define POP_BACK(stk, cnt, reg)
Definition: simplereg.cpp:112
int * fltusedinout
Definition: reg.hpp:101
FillZero fillzero
Definition: OStream.cpp:45
#define TAKE_FREE_TMP_INT(r)
Definition: simplereg.cpp:204
instruction * iinstr
Definition: jit.hpp:319
int * freetmpintregs
Definition: reg.hpp:75
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
s4 icount
Definition: jit.hpp:318
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:151
#define MZERO(ptr, type, num)
Definition: memory.hpp:105
#define TAKE_SAV_INT(r)
Definition: simplereg.cpp:193
#define TAKE_FREE_ARG_INT(r)
Definition: simplereg.cpp:203
s4 regoff
Definition: reg.hpp:47
int * regcopycount
Definition: reg.hpp:103
#define POP_FRONT(stk, cnt, reg)
Definition: simplereg.cpp:111
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define TAKE_ARG_INT(r)
Definition: simplereg.cpp:191
int * intusedinout
Definition: reg.hpp:100
#define INT_SAV_CNT
Definition: md-abi.hpp:73
#define PUSH_FREE_ARG_INT(r)
Definition: simplereg.cpp:215
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
int * freesavintregs
Definition: reg.hpp:76
#define PUSH_FREE_SAV_INT(r)
Definition: simplereg.cpp:217
#define NEW_MEM_SLOT_FLT_DBL(r)
Definition: simplereg.cpp:229
#define GET_LOW_REG(a)
#define AVAIL_FREE_SAV_INT
Definition: simplereg.cpp:181
#define PUSH_FREE_TMP_INT(r)
Definition: simplereg.cpp:216
#define PUSH_FREE_TMP_FLT(r)
Definition: simplereg.cpp:208
#define REG_INDEX(regoff, type)
Definition: simplereg.cpp:252
#define FLT_TMP_CNT
Definition: md-abi.hpp:82
int freetmpinttop
Definition: reg.hpp:95
static void simplereg_allocate_locals_leafmethod(jitdata *jd)
Definition: simplereg.cpp:495
dst_operand_t dst
static void simplereg_init_block(registerdata *rd)
Definition: simplereg.cpp:782
#define AVAIL_TMP_FLT
Definition: simplereg.cpp:160
#define TAKE_FREE_SAV_INT(r)
Definition: simplereg.cpp:205
static JNINativeMethod methods[]
int tmpintreguse
Definition: reg.hpp:87
bool checksync
Definition: options.cpp:90
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
Definition: simplereg.cpp:1024
void exceptions_throw_internalerror(const char *message,...)
Definition: exceptions.cpp:805
#define INT_ARG_CNT
Definition: md-abi.hpp:74
#define TOTAL_REG_CNT
Definition: simplereg.cpp:85
s4 indepth
Definition: jit.hpp:325
#define AVAIL_FREE_TMP_FLT
Definition: simplereg.cpp:172
int tmpfltreguse
Definition: reg.hpp:90
s4 * local_map
Definition: jit.hpp:153
MIIterator i
typedesc returntype
Definition: descriptor.hpp:166
#define SIZE_OF_STACKSLOT
Definition: simplereg.cpp:80
int freetmpflttop
Definition: reg.hpp:97
int32_t s4
Definition: types.hpp:45
int argfltreguse
Definition: reg.hpp:89
int * savfltregs
Definition: reg.hpp:73
VariableKind varkind
Definition: stack.hpp:68
#define TAKE_FREE_SAV_FLT(r)
Definition: simplereg.cpp:197
registerdata * rd
Definition: jit.hpp:130
#define AVAIL_ARG_FLT
Definition: simplereg.cpp:159
s4 * outvars
Definition: jit.hpp:324
static void simplereg_allocate_interfaces(jitdata *jd)
Definition: simplereg.cpp:288
int freesavinttop
Definition: reg.hpp:96
union instruction::@12 sx
int * regisoutvar
Definition: reg.hpp:102
#define AVAIL_SAV_FLT
Definition: simplereg.cpp:161
#define PACK_REGS(low, high)
int savfltreguse
Definition: reg.hpp:91
int32_t varindex
bool inmemory
Definition: descriptor.hpp:151
#define INSTRUCTION_GET_METHODDESC(iptr, md)
s1_operand_t s1
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
bool regalloc(jitdata *jd)
Definition: simplereg.cpp:262
#define INT_TMP_CNT
Definition: md-abi.hpp:75
#define FLT_SAV_CNT
Definition: md-abi.hpp:80
#define AVAIL_SAV_INT
Definition: simplereg.cpp:169
methoddesc * parseddesc
Definition: method.hpp:78
int memuse
Definition: reg.hpp:84
#define VAROP(v)
Definition: jit.hpp:251
int * tmpintregs
Definition: reg.hpp:70
Definition: builtin.hpp:60
methodinfo * m
Definition: jit.hpp:127
s4 maxinterfaces
Definition: jit.hpp:165
interface_info * interface_map
Definition: jit.hpp:164
int * memcopycount
Definition: reg.hpp:104
static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
Definition: simplereg.cpp:937
#define FLT_ARG_CNT
Definition: md-abi.hpp:81
s4 flags
Definition: reg.hpp:45
s4 nr
Definition: jit.hpp:312
#define DMNEW(type, num)
Definition: dumpmemory.hpp:371
static int code_is_synchronized(codeinfo *code)
Definition: code.hpp:173
#define AVAIL_FREE_ARG_FLT
Definition: simplereg.cpp:171
struct instruction::@12::@13 s23
#define TAKE_TMP_INT(r)
Definition: simplereg.cpp:192
#define PUSH_FREE_SAV_FLT(r)
Definition: simplereg.cpp:209
#define AVAIL_FREE_TMP_INT
Definition: simplereg.cpp:180
#define TAKE_SAV_FLT(r)
Definition: simplereg.cpp:185
#define AVAIL_FREE_SAV_FLT
Definition: simplereg.cpp:173
int freearginttop
Definition: reg.hpp:93
Nl nl
Definition: OStream.cpp:56
#define STAT_REGISTER_VAR(type, var, init, name, description)
Register an external statistics variable.
Definition: statistics.hpp:966
#define STAT_DECLARE_VAR(type, var, init)
Declare an external statistics variable.
Definition: statistics.hpp:963
uint32_t regoff
Definition: descriptor.hpp:153
#define NEW_MEM_SLOT_REUSE_PADDING(r)
Definition: simplereg.cpp:230
Dec dec
Definition: OStream.cpp:48
#define PUSH_FREE_ARG_FLT(r)
Definition: simplereg.cpp:207
#define FLT_REG_CNT
Definition: md-abi.hpp:79
#define TAKE_FREE_TMP_FLT(r)
Definition: simplereg.cpp:196
int * freeargintregs
Definition: reg.hpp:74
int freeargflttop
Definition: reg.hpp:94
#define TAKE_ARG_FLT(r)
Definition: simplereg.cpp:183