CACAO
SSAConstructionPass.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/SSAConstructionPass.cpp - SSAConstructionPass
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
32 
33 #include "vm/descriptor.hpp"
34 #include "vm/field.hpp"
35 
36 #include "vm/jit/jit.hpp"
37 #include "vm/jit/show.hpp"
38 #include "vm/jit/ir/icmd.hpp"
40 
41 #include "mm/dumpmemory.hpp"
42 
43 #include "vm/statistics.hpp"
44 
45 #include "toolbox/logging.hpp"
46 
47 #define DEBUG_NAME "compiler2/SSAConstruction"
48 
49 STAT_DECLARE_GROUP(compiler2_stat)
50 STAT_REGISTER_GROUP_VAR(std::size_t,num_trivial_phis,0,"# trivial phis","number of trivial phis",compiler2_stat)
51 STAT_REGISTER_GROUP_VAR(std::size_t,num_icmd_inst,0,"icmd instructions",
52  "ICMD instructions processed (by the compiler2)",compiler2_stat)
53 
54 
55 namespace cacao {
56 namespace jit {
57 namespace compiler2 {
58 
59 class InVarPhis {
60 private:
61  PHIInst *phi;
62  jitdata *jd;
63  std::size_t bb_num;
64  std::size_t in_var_index;
65  SSAConstructionPass *parent;
66 public:
67  // constructs
68  InVarPhis(PHIInst *phi, jitdata *jd, std::size_t bb_num, std::size_t in_var_index,
69  SSAConstructionPass *parent)
70  : phi(phi), jd(jd), bb_num(bb_num), in_var_index(in_var_index), parent(parent) {}
71 
72  // fill phi operands
73  void fill_operands() {
74  basicblock *bb = &jd->basicblocks[bb_num];
75  for(s4 i = 0; i < bb->predecessorcount; ++i) {
76  basicblock *pred = bb->predecessors[i];
77  assert(pred->outdepth == bb->indepth);
78  s4 pred_nr = pred->nr;
79  s4 var = pred->outvars[in_var_index];
80  // append operand
81  phi->append_op(parent->read_variable(var,pred_nr));
82  }
83  }
84 };
85 
86 void SSAConstructionPass::write_variable(size_t varindex, size_t bb, Value* v) {
87  LOG2("write variable(" << varindex << "," << bb << ") = " << v << nl);
88  current_def[varindex][bb] = v;
89 }
90 
91 Value* SSAConstructionPass::read_variable(size_t varindex, size_t bb) {
92  LOG2("read variable(" << varindex << "," << bb << ")" << nl);
93  Value* v = current_def[varindex][bb];
94  if (v) {
95  // local value numbering
96  //v = v;
97  } else {
98  // global value numbering
99  v = read_variable_recursive(varindex, bb);
100  }
101  LOG2("Value: " << v << nl);
102  return v;
103 }
104 
105 Value* SSAConstructionPass::read_variable_recursive(size_t varindex, size_t bb) {
106  Value *val; // current definition
107  if(BB[bb]->pred_size() == 0) {
108  ABORT_MSG("no predecessor ","basic block " << bb << " var index " << varindex);
109  return NULL;
110  }
111  if (!sealed_blocks[bb]) {
112  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bb]);
113  incomplete_phi[bb][varindex] = phi;
114  M->add_Instruction(phi);
115  val = phi;
116  } else if (BB[bb]->pred_size() == 1) { // one predecessor
117  // get first (and only predecessor
118  BeginInst *pred = *(BB[bb]->pred_begin());
119  val = read_variable(varindex, beginToIndex[pred]);
120  } else {
121  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bb]);
122  write_variable(varindex, bb, phi);
123  M->add_Instruction(phi);
124  val = add_phi_operands(varindex, phi);
125  // might get deleted by try_remove_trivial_phi()
126  assert(val->to_Instruction());
127  }
128  write_variable(varindex, bb, val);
129  return val;
130 }
131 
132 Value* SSAConstructionPass::add_phi_operands(size_t varindex, PHIInst *phi) {
133  // determine operands from predecessors
134  BeginInst *BI = phi->get_BeginInst();
135  for (BeginInst::PredecessorListTy::const_iterator i = BI->pred_begin(),
136  e = BI->pred_end(); i != e; ++i) {
137  phi->append_op(read_variable(varindex,beginToIndex[*i]));
138  }
139  return try_remove_trivial_phi(phi);
140 }
141 
142 Value* SSAConstructionPass::try_remove_trivial_phi(PHIInst *phi) {
143  Value *same = NULL;
144  for(Instruction::OperandListTy::const_iterator i = phi->op_begin(),
145  e = phi->op_end(); i != e; ++i) {
146  Value *op = *i;
147  if ( (op == same) || (op == (Value*)phi) ) {
148  continue; // unique value or self-reference
149  }
150  if (same != NULL) {
151  return phi; // not trivial (merges at least two values)
152  }
153  same = op;
154  }
155  if (same == NULL) {
156  same = NULL; // Phi instruction not reachable
157  }
158  LOG(BoldGreen << "going to remove PHI: " << reset_color << phi << nl);
159  if (DEBUG_COND_N(2)) {
160  for (std::size_t i = 0, e = current_def.size(); i < e; ++i) {
161  for (std::size_t j = 0, e = current_def[i].size(); j < e; ++j) {
162  if (current_def[i][j] == phi) {
163  LOG2("current_def["<<i<<"]["<<j<<"] will be invalid" << nl);
164  }
165  }
166  }
167  }
168  STATISTICS(num_trivial_phis++);
169  alloc::list<Instruction*>::type users(phi->user_begin(),phi->user_end());
170  users.remove(phi);
171  phi->replace_value(same);
172  // update table
173  // XXX this should be done in a smarter way (e.g. by using value references)
174  for (std::size_t i = 0, e = current_def.size(); i < e; ++i) {
175  for (std::size_t j = 0, e = current_def[i].size(); j < e; ++j) {
176  if (current_def[i][j] == phi) {
177  current_def[i][j] = same;
178  }
179  }
180  }
181  // TODO delete phi
182  M->remove_Instruction(phi);
183 
184  for(alloc::list<Instruction*>::type::iterator i = users.begin(), e = users.end();
185  i != e; ++i) {
186  assert(*i);
187  PHIInst *p = (*i)->to_PHIInst();
188  if (p) {
189  try_remove_trivial_phi(p);
190  }
191  }
192 
193  return same;
194 }
195 
196 void SSAConstructionPass::seal_block(size_t bb) {
197  LOG("sealing basic block: " << bb << nl);
198  alloc::vector<PHIInst*>::type &inc_phi_bb = incomplete_phi[bb];
199  for (int i = 0, e = inc_phi_bb.size(); i != e ; ++i) {
200  PHIInst *phi = inc_phi_bb[i];
201  if (phi) {
202  add_phi_operands(i,phi);
203  }
204  }
205  alloc::list<InVarPhis*>::type &in_var_bb = incomplete_in_phi[bb];
206  std::for_each(in_var_bb.begin(),in_var_bb.end(),
207  std::mem_fun(&InVarPhis::fill_operands));
208  sealed_blocks[bb] = true;
209 }
210 
211 
212 bool SSAConstructionPass::try_seal_block(basicblock *bb) {
213  if (sealed_blocks[bb->nr])
214  return true;
215 
216  LOG("try sealing basic block: " << bb->nr << nl);
217  for(int i = 0; i < bb->predecessorcount; ++i) {
218  int pred_bbindex = bb->predecessors[i]->nr;
219  if (!filled_blocks[pred_bbindex] && !skipped_blocks[pred_bbindex]) {
220  return false;
221  }
222  }
223 
224  // seal it!
225  seal_block(bb->nr);
226 
227  return true;
228 }
229 
230 void SSAConstructionPass::print_current_def() const {
231  for(alloc::vector<alloc::vector<Value*>::type >::type::const_iterator i = current_def.begin(),
232  e = current_def.end(); i != e ; ++i) {
233  for(alloc::vector<Value*>::type::const_iterator ii = (*i).begin(),
234  ee = (*i).end(); ii != ee ; ++ii) {
235  Value *v = *ii;
236  Instruction *I;
237  int max = 20;
238  if (!v) {
239  out() << setw(max) << "NULL";
240  } else if ( (I = v->to_Instruction()) ) {
241  out() << setw(max) << I->get_name();
242  } else {
243  out() << setw(max) << "VALUE";
244  }
245  }
246  out() << nl;
247  }
248 }
249 
250 void SSAConstructionPass::install_javalocal_dependencies(
251  SourceStateInst *source_state,
252  s4 *javalocals,
253  basicblock *bb) {
254  if (javalocals) {
255  for (s4 i = 0; i < bb->method->maxlocals; ++i) {
256  s4 varindex = javalocals[i];
257  if (varindex == jitdata::UNUSED) {
258  continue;
259  }
260 
261  if (varindex >= 0) {
262  Value *v = read_variable(
263  static_cast<size_t>(varindex),
264  bb->nr);
265  SourceStateInst::Javalocal javalocal(v,
266  static_cast<size_t>(i));
267  source_state->append_javalocal(javalocal);
268  LOG("register javalocal " << varindex << " " << v
269  << " at " << source_state << nl);
270  } else {
271  assert(0);
272  // TODO
273  }
274  }
275  }
276 }
277 
278 void SSAConstructionPass::install_stackvar_dependencies(
279  SourceStateInst *source_state,
280  s4 *stack,
281  s4 stackdepth,
282  s4 paramcount,
283  basicblock *bb) {
284  LOG("register " << stackdepth << " stackvars and " << paramcount << " parameters" << nl);
285  for (s4 stack_index = 0; stack_index < stackdepth; stack_index++) {
286  s4 varindex = stack[stack_index];
287  Value *v = read_variable(
288  static_cast<size_t>(varindex),
289  bb->nr);
290 
291  if (stack_index < paramcount) {
292  source_state->append_param(v);
293  LOG("register param " << varindex << " " << v
294  << " at " << source_state << nl);
295  } else {
296  source_state->append_stackvar(v);
297  LOG("register stackvar " << varindex << " " << v
298  << " at " << source_state << nl);
299  }
300  }
301 }
302 
303 SourceStateInst *SSAConstructionPass::record_source_state(
304  Instruction *I,
305  instruction *iptr,
306  basicblock *bb,
307  s4 *javalocals,
308  s4 *stack,
309  s4 stackdepth) {
310  s4 source_id = iptr->flags.bits >> INS_FLAG_ID_SHIFT;
311  LOG("record source state after instruction " << source_id << " " << I << nl);
312  SourceStateInst *source_state = new SourceStateInst(source_id, I);
313  install_javalocal_dependencies(source_state, javalocals, bb);
314  install_stackvar_dependencies(source_state, stack, stackdepth, 0, bb);
315  M->add_Instruction(source_state);
316  return source_state;
317 }
318 
319 void SSAConstructionPass::deoptimize(int bbindex) {
320  assert(BB[bbindex]);
321  LOG("Instruction not supported, deoptimize instead" << nl);
322  DeoptimizeInst *deopt = new DeoptimizeInst(BB[bbindex]);
323  M->add_Instruction(deopt);
324  skipped_blocks[bbindex] = true;
325 }
326 
327 bool SSAConstructionPass::skipped_all_predecessors(basicblock *bb) {
328  for (int i = 0; i < bb->predecessorcount; i++) {
329  basicblock *pred = bb->predecessors[i];
330  if (visited_blocks[pred->nr] && !skipped_blocks[pred->nr]) {
331  return false;
332  }
333  }
334  return true;
335 }
336 
337 void SSAConstructionPass::remove_unreachable_blocks() {
338  alloc::vector<BeginInst*>::type unreachable_blocks;
339 
340  Method::const_bb_iterator end = M->bb_end();
341  for (Method::const_bb_iterator i = M->bb_begin(); i != end; i++) {
342  BeginInst *begin = *i;
343  if (begin->pred_size() == 0 && begin != M->get_init_bb()) {
344  unreachable_blocks.push_back(begin);
345  }
346  }
347 
348  while (!unreachable_blocks.empty()) {
349  BeginInst *begin = unreachable_blocks.back();
350  unreachable_blocks.pop_back();
351 
352  LOG("Remove unreachable block " << begin << nl);
353  EndInst *end = begin->get_EndInst();
354  assert(end);
355  M->remove_Instruction(end);
356  M->remove_bb(begin);
357  }
358 }
359 
360 CONSTInst *SSAConstructionPass::parse_s2_constant(instruction *iptr, Type::TypeID type) {
361  CONSTInst *konst;
362 
363  switch (type) {
364  case Type::IntTypeID:
365  konst = new CONSTInst(static_cast<int32_t>(iptr->sx.s23.s2.constval),
366  Type::IntType());
367  break;
368  case Type::LongTypeID:
369  konst = new CONSTInst(static_cast<int64_t>(iptr->sx.s23.s2.constval),
370  Type::LongType());
371  break;
372  default:
373  assert(false);
374  break;
375  }
376 
377  return konst;
378 }
379 
380 bool SSAConstructionPass::run(JITData &JD) {
381  M = JD.get_Method();
382  LOG("SSAConstructionPass: " << *M << nl);
383 
384  basicblock *bb;
385  jd = JD.get_jitdata();
386 
387  // **** BEGIN initializations
388 
389  /**
390  * There are two kinds of variables in the baseline ir. The javalocals as defined
391  * in the JVM specification (2.6.1.). These are used for arguments and other values
392  * not stored on the JVM stack. These variables are addressed using an index. Every
393  * 'slot' can contain values of each basic type. The type is defined by the access
394  * instruction (e.g. ILOAD, ISTORE for integer). These instructions are introduced
395  * by the java compiler (usually javac).
396  * The other group of variables are intended to replace the jvm stack and are created
397  * by the baseline parse/stackanalysis pass. In contrast to the javalocals these
398  * variables have a fixed typed. They are used as arguments and results for
399  * baseline IR instructions.
400  * For simplicity of the compiler2 IR both variables groups are treated the same way.
401  * Their current definitions are stored in a value numbering table.
402  * The number of variables is already known at this point for both types.
403  */
404  //unsigned int num_variables = jd->vartop;
405  // last block used for argument loading
406  unsigned int num_basicblocks = jd->basicblockcount;
407  unsigned int init_basicblock = 0;
408  bool extra_init_bb = jd->basicblocks[0].predecessorcount;
409 
410  // Used to track at each point the javalocals that are live.
411  s4 *live_javalocals = (s4*) DumpMemory::allocate(sizeof(s4) * jd->maxlocals);
412 
413  visited_blocks.clear();
414  visited_blocks.resize(num_basicblocks, false);
415 
416  skipped_blocks.clear();
417  skipped_blocks.resize(num_basicblocks, false);
418 
419  assert(jd->basicblockcount);
420  if (extra_init_bb) {
421  // The first basicblock is the target of a jump (e.g. loophead).
422  // We have to create a new one to load the arguments
423  ++num_basicblocks;
424  init_basicblock = jd->basicblockcount;
425  LOG("Extra basic block added (index = " << init_basicblock << ")" << nl);
426  }
427 
428  // store basicblock BeginInst
429  beginToIndex.clear();
430  BB.clear();
431  BB.resize(num_basicblocks, NULL);
432  for(std::size_t i = 0; i < num_basicblocks; ++i) {
433  BeginInst *bi = new BeginInst();
434  BB[i] = bi;
435  beginToIndex.insert(std::make_pair(bi,i));
436  }
437  //
438  // pseudo variable index for global state
439  std::size_t global_state = jd->vartop;
440 
441  // init incomplete_phi
442  incomplete_phi.clear();
443  incomplete_phi.resize(num_basicblocks,alloc::vector<PHIInst*>::type(global_state + 1,NULL));
444  incomplete_in_phi.clear();
445  incomplete_in_phi.resize(num_basicblocks);
446 
447  // (Local,Global) Value Numbering Map, size #bb times #var, initialized to NULL
448  current_def.clear();
449  current_def.resize(global_state+1,alloc::vector<Value*>::type(num_basicblocks,NULL));
450  // sealed blocks
451  sealed_blocks.clear();
452  sealed_blocks.resize(num_basicblocks,false);
453  // filled blocks
454  filled_blocks.clear();
455  filled_blocks.resize(num_basicblocks,false);
456  // initialize
457  var_type_tbl.clear();
458  var_type_tbl.resize(global_state+1,Type::VoidTypeID);
459 
460  // create variable type map
461  for(size_t i = 0, e = jd->vartop; i != e ; ++i) {
462  varinfo &v = jd->var[i];
463  var_type_tbl[i] = convert_to_typeid(v.type);
464  }
465  // set global state
466  var_type_tbl[global_state] = Type::GlobalStateTypeID;
467 
468  // initialize arguments
469  methoddesc *md = jd->m->parseddesc;
470  assert(md);
471  assert(md->paramtypes);
472 
473  if (extra_init_bb) {
474  M->add_bb(BB[init_basicblock]);
475  }
476  LOG("parameter count: i = " << md->paramcount << " slot count = " << md->paramslots << nl);
477  for (int i = 0, slot = 0; i < md->paramcount; ++i) {
478  int type = md->paramtypes[i].type;
479  int varindex = jd->local_map[slot * 5 + type];
480  LOG("parameter: i = " << i << " slot = " << slot << " type " << get_type_name(type) << nl);
481 
482  if (varindex != jitdata::UNUSED) {
483  // only load if variable is used
484  Instruction *I = new LOADInst(convert_to_typeid(type), i, BB[init_basicblock]);
485  write_variable(varindex,init_basicblock,I);
486  M->add_Instruction(I);
487  }
488 
489  switch (type) {
490  case TYPE_LNG:
491  case TYPE_DBL:
492  slot +=2;
493  break;
494  default:
495  ++slot;
496  }
497  }
498  if (extra_init_bb) {
499  BeginInst *targetBlock = BB[0];
500  Instruction *result = new GOTOInst(BB[init_basicblock], targetBlock);
501  M->add_Instruction(result);
502  // now we mark it filled and sealed
503  filled_blocks[init_basicblock] = true;
504  sealed_blocks[init_basicblock] = true;
505  }
506 
507  // set start begin inst
508  M->set_init_bb(BB[init_basicblock]);
509 
510  current_def[global_state][init_basicblock] = BB[init_basicblock];
511 
512  // **** END initializations
513 
514 #if defined(ENABLE_LOGGING)
515  // print BeginInsts
516  for(alloc::vector<BeginInst*>::type::iterator i = BB.begin(), e = BB.end();
517  i != e; ++i) {
518  Instruction *v = *i;
519  LOG("BB: " << (void*)v << nl);
520  }
521  // print variables
522  for(size_t i = 0, e = jd->vartop; i != e ; ++i) {
523  varinfo &v = jd->var[i];
524  LOG("var#" << i << " type: " << get_type_name(v.type) << nl);
525  }
526 #endif
527  LOG("# variables: " << jd->vartop << nl);
528  LOG("# javalocals: " << jd->localcount << nl);
529  // print arguments
530  LOG("# parameters: " << md->paramcount << nl);
531  LOG("# parameter slots: " << md->paramslots << nl);
532  for (int i = 0; i < md->paramslots; ++i) {
533  int type = md->paramtypes[i].type;
534  LOG("argument type: " << get_type_name(type)
535  << " (index " << i << ")"
536  << " (var_local " << jd->local_map[i * 5 + type] << ")" << nl);
537  switch (type) {
538  case TYPE_LNG:
539  case TYPE_DBL:
540  ++i;
541  break;
542  }
543  }
544  for (int i = 0; i < jd->maxlocals; ++i) {
545  LOG("localindex: " << i << nl);
546  for (int j = 0; j < 5; ++j) {
547  s4 entry = jd->local_map[i*5+j];
548  if (entry == jitdata::UNUSED)
549  LOG(" type " <<get_type_name(j) << " UNUSED" << nl);
550  else
551  LOG(" type " <<get_type_name(j) << " " << entry << nl);
552  }
553  }
554 
555  FOR_EACH_BASICBLOCK(jd,bb) {
556  visited_blocks[bb->nr] = true;
557 
558  if (bb->icount == 0 ) {
559  // this is the last (empty) basicblock
560  assert(bb->nr == jd->basicblockcount);
561  assert(bb->predecessorcount == 0);
562  assert(bb->successorcount == 0);
563  // we dont need it
564  continue;
565  }
566 
567  if ((skipped_all_predecessors(bb) && bb->predecessorcount > 0) || bb->type == basicblock::TYPE_EXH) {
568  skipped_blocks[bb->nr] = true;
569  DeoptimizeInst *deopt = new DeoptimizeInst(BB[bb->nr]);
570  M->add_Instruction(deopt);
571  }
572 
573  std::size_t bbindex = (std::size_t)bb->nr;
574  instruction *iptr;
575  LOG("basicblock: " << bbindex << nl);
576 
577  if (!skipped_blocks[bbindex]) {
578  // handle invars
579  for(s4 i = 0; i < bb->indepth; ++i) {
580  std::size_t varindex = bb->invars[i];
581  PHIInst *phi = new PHIInst(var_type_tbl[varindex], BB[bbindex]);
582  write_variable(varindex, bbindex, phi);
583  if (!sealed_blocks[bbindex]) {
584  incomplete_in_phi[bbindex].push_back(new InVarPhis(phi, jd, bbindex, i, this));
585  }
586  else {
587  InVarPhis invar(phi, jd, bbindex, i, this);
588  invar.fill_operands();
589  }
590  M->add_Instruction(phi);
591  }
592  }
593 
594  // add begin block
595  assert(BB[bbindex]);
596  M->add_bb(BB[bbindex]);
597  // every merge node is a possible statechange
598  // XXX maybe we can handle this via phi nodes but we must ensure that
599  // they do not get deleted!
600  current_def[global_state][bbindex] = BB[bbindex];
601 
602  // Get javalocals that are live at the begin of the block.
603  assert((jd->maxlocals > 0) == (bb->javalocals != NULL));
604  MCOPY(live_javalocals, bb->javalocals, s4, jd->maxlocals);
605 
606  if (!skipped_blocks[bbindex]) {
607  if (bb->predecessorcount > 1 || bb->nr == 0) {
608  // Record the source state at method entry and control-flow merges.
609  SourceStateInst *source_state = record_source_state(BB[bbindex],
610  bb->iinstr, bb, live_javalocals, bb->invars, bb->indepth);
611 
612 #if defined(ENABLE_COUNTDOWN_TRAPS)
613  // For now it is only possible to jump into optimized code at the begin
614  // of methods. Hence, we currently only place a ReplacementEntryInst at
615  // method entry.
616  if (bb->nr == 0) {
617  ReplacementEntryInst *rplentry = new ReplacementEntryInst(BB[bbindex], source_state);
618  M->add_Instruction(rplentry);
619  }
620 #endif
621  }
622  }
623 
624  FOR_EACH_INSTRUCTION(bb,iptr) {
625  if (skipped_blocks[bb->nr]) {
626  break;
627  }
628 
629  STATISTICS(++num_icmd_inst);
630  #if !defined(NDEBUG)
631  LOG("iptr: " << icmd_table[iptr->opc].name << nl);
632  #endif
633 
634  Instruction *old_global_state = read_variable(global_state,bbindex)->to_Instruction();
635  Instruction *new_global_state = NULL;
636 
637  switch (iptr->opc) {
638  case ICMD_POP:
639  case ICMD_NOP:
640  break;
641  case ICMD_CHECKNULL:
642  {
643  deoptimize(bbindex);
644  break;
645  }
646 
647  /* unary */
648 
649  case ICMD_INEG:
650  case ICMD_LNEG:
651  case ICMD_FNEG:
652  case ICMD_DNEG:
653  {
654  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
655  Type::TypeID type;
656  switch (iptr->opc) {
657  case ICMD_INEG:
658  type = Type::IntTypeID;
659  break;
660  case ICMD_LNEG:
661  type = Type::LongTypeID;
662  break;
663  case ICMD_FNEG:
664  type = Type::FloatTypeID;
665  break;
666  case ICMD_DNEG:
667  type = Type::DoubleTypeID;
668  break;
669  default:
670  assert(0);
671  type = Type::VoidTypeID;
672  }
673  Instruction *result = new NEGInst(type,s1);
674  write_variable(iptr->dst.varindex,bbindex,result);
675  M->add_Instruction(result);
676  break;
677  }
678  case ICMD_ARRAYLENGTH:
679  {
680  Value *arrayref = read_variable(iptr->s1.varindex, bbindex);
681 
682  Instruction *array_length = new ARRAYLENGTHInst(arrayref);
683  M->add_Instruction(array_length);
684  write_variable(iptr->dst.varindex, bbindex, array_length);
685  break;
686  }
687  case ICMD_I2L:
688  case ICMD_I2F:
689  case ICMD_I2D:
690  case ICMD_L2I:
691  case ICMD_L2F:
692  case ICMD_L2D:
693  case ICMD_F2I:
694  case ICMD_F2L:
695  case ICMD_F2D:
696  case ICMD_D2I:
697  case ICMD_D2L:
698  case ICMD_D2F:
699  case ICMD_INT2BYTE:
700  case ICMD_INT2CHAR:
701  case ICMD_INT2SHORT:
702  {
703  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
704  Type::TypeID type_to;
705  switch (iptr->opc) {
706  case ICMD_INT2SHORT:
707  type_to = Type::ShortTypeID;
708  break;
709  case ICMD_INT2CHAR:
710  type_to = Type::CharTypeID;
711  break;
712  case ICMD_INT2BYTE:
713  type_to = Type::ByteTypeID;
714  break;
715  case ICMD_I2L:
716  type_to = Type::LongTypeID;
717  break;
718  case ICMD_I2F:
719  type_to = Type::FloatTypeID;
720  break;
721  case ICMD_I2D:
722  type_to = Type::DoubleTypeID;
723  break;
724  case ICMD_L2I:
725  type_to = Type::IntTypeID;
726  break;
727  case ICMD_L2F:
728  type_to = Type::FloatTypeID;
729  break;
730  case ICMD_L2D:
731  type_to = Type::DoubleTypeID;
732  break;
733  case ICMD_F2I:
734  type_to = Type::IntTypeID;
735  break;
736  case ICMD_F2L:
737  type_to = Type::LongTypeID;
738  break;
739  case ICMD_F2D:
740  type_to = Type::DoubleTypeID;
741  break;
742  case ICMD_D2I:
743  type_to = Type::IntTypeID;
744  break;
745  case ICMD_D2L:
746  type_to = Type::LongTypeID;
747  break;
748  case ICMD_D2F:
749  type_to = Type::FloatTypeID;
750  break;
751  default:
752  assert(0);
753  type_to = Type::VoidTypeID;
754  }
755  Instruction *result = new CASTInst(type_to, s1);
756  write_variable(iptr->dst.varindex,bbindex,result);
757  M->add_Instruction(result);
758  break;
759  }
760  case ICMD_IADD:
761  case ICMD_LADD:
762  case ICMD_FADD:
763  case ICMD_DADD:
764  {
765  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
766  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
767  Type::TypeID type;
768  switch (iptr->opc) {
769  case ICMD_IADD:
770  type = Type::IntTypeID;
771  break;
772  case ICMD_LADD:
773  type = Type::LongTypeID;
774  break;
775  case ICMD_FADD:
776  type = Type::FloatTypeID;
777  break;
778  case ICMD_DADD:
779  type = Type::DoubleTypeID;
780  break;
781  default: assert(0);
782  type = Type::VoidTypeID;
783  }
784  Instruction *result = new ADDInst(type, s1, s2);
785  write_variable(iptr->dst.varindex,bbindex,result);
786  M->add_Instruction(result);
787  }
788  break;
789  case ICMD_ISUB:
790  case ICMD_LSUB:
791  case ICMD_FSUB:
792  case ICMD_DSUB:
793  {
794  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
795  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
796  Type::TypeID type;
797  switch (iptr->opc) {
798  case ICMD_ISUB:
799  type = Type::IntTypeID;
800  break;
801  case ICMD_LSUB:
802  type = Type::LongTypeID;
803  break;
804  case ICMD_FSUB:
805  type = Type::FloatTypeID;
806  break;
807  case ICMD_DSUB:
808  type = Type::DoubleTypeID;
809  break;
810  default: assert(0);
811  type = Type::VoidTypeID;
812  }
813  Instruction *result = new SUBInst(type, s1, s2);
814  write_variable(iptr->dst.varindex,bbindex,result);
815  M->add_Instruction(result);
816  }
817  break;
818  case ICMD_IMUL:
819  case ICMD_LMUL:
820  case ICMD_FMUL:
821  case ICMD_DMUL:
822  {
823  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
824  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
825  Type::TypeID type;
826  switch (iptr->opc) {
827  case ICMD_IMUL:
828  type = Type::IntTypeID;
829  break;
830  case ICMD_LMUL:
831  type = Type::LongTypeID;
832  break;
833  case ICMD_FMUL:
834  type = Type::FloatTypeID;
835  break;
836  case ICMD_DMUL:
837  type = Type::DoubleTypeID;
838  break;
839  default: assert(0);
840  type = Type::VoidTypeID;
841  }
842  Instruction *result = new MULInst(type, s1, s2);
843  write_variable(iptr->dst.varindex,bbindex,result);
844  M->add_Instruction(result);
845  }
846  break;
847  case ICMD_IDIV:
848  case ICMD_LDIV:
849  case ICMD_FDIV:
850  case ICMD_DDIV:
851  {
852  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
853  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
854  Type::TypeID type;
855  switch (iptr->opc) {
856  case ICMD_IDIV:
857  type = Type::IntTypeID;
858  break;
859  case ICMD_LDIV:
860  type = Type::LongTypeID;
861  break;
862  case ICMD_FDIV:
863  type = Type::FloatTypeID;
864  break;
865  case ICMD_DDIV:
866  type = Type::DoubleTypeID;
867  break;
868  default: assert(0);
869  type = Type::VoidTypeID;
870  }
871  Instruction *result = new DIVInst(type, s1, s2);
872  write_variable(iptr->dst.varindex,bbindex,result);
873  M->add_Instruction(result);
874  }
875  break;
876  case ICMD_IREM:
877  case ICMD_LREM:
878  case ICMD_FREM:
879  case ICMD_DREM:
880  {
881  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
882  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
883  Type::TypeID type;
884  switch (iptr->opc) {
885  case ICMD_IREM:
886  type = Type::IntTypeID;
887  break;
888  case ICMD_LREM:
889  type = Type::LongTypeID;
890  break;
891  case ICMD_FREM:
892  type = Type::FloatTypeID;
893  break;
894  case ICMD_DREM:
895  type = Type::DoubleTypeID;
896  break;
897  default: assert(0);
898  type = Type::VoidTypeID;
899  }
900  Instruction *result = new REMInst(type, s1, s2);
901  write_variable(iptr->dst.varindex,bbindex,result);
902  M->add_Instruction(result);
903  }
904  break;
905  case ICMD_ISHL:
906  case ICMD_LSHL:
907  case ICMD_ISHR:
908  case ICMD_LSHR:
909  case ICMD_IUSHR:
910  case ICMD_LUSHR:
911  {
912  deoptimize(bbindex);
913  break;
914  }
915  case ICMD_IOR:
916  case ICMD_LOR:
917  case ICMD_IXOR:
918  case ICMD_LXOR:
919  case ICMD_IAND:
920  case ICMD_LAND:
921  {
922  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
923  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
924  Type::TypeID type;
925  Instruction *result;
926  // type
927  switch (iptr->opc) {
928  case ICMD_IAND:
929  case ICMD_IOR:
930  case ICMD_IXOR:
931  type = Type::IntTypeID;
932  break;
933  case ICMD_LAND:
934  case ICMD_LOR:
935  case ICMD_LXOR:
936  type = Type::LongTypeID;
937  break;
938  default: assert(0);
939  type = Type::VoidTypeID;
940  }
941  // operation
942  switch (iptr->opc) {
943  case ICMD_IAND:
944  case ICMD_LAND:
945  result = new ANDInst(type, s1, s2);
946  break;
947  case ICMD_IOR:
948  case ICMD_LOR:
949  result = new ORInst(type, s1, s2);
950  break;
951  case ICMD_IXOR:
952  case ICMD_LXOR:
953  result = new XORInst(type, s1, s2);
954  break;
955  default: assert(0);
956  result = NULL;
957  }
958  write_variable(iptr->dst.varindex,bbindex,result);
959  M->add_Instruction(result);
960  }
961  break;
962  case ICMD_LCMP:
963  case ICMD_FCMPL:
964  case ICMD_FCMPG:
965  case ICMD_DCMPL:
966  case ICMD_DCMPG:
967  {
968  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
969  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
970  CMPInst::FloatHandling handling;
971  switch (iptr->opc) {
972  case ICMD_FCMPL:
973  case ICMD_DCMPL:
974  handling = CMPInst::L;
975  break;
976  case ICMD_FCMPG:
977  case ICMD_DCMPG:
978  handling = CMPInst::G;
979  break;
980  default: assert(0);
981  handling = CMPInst::DontCare;
982  }
983  Instruction *result = new CMPInst(s1, s2, handling);
984  write_variable(iptr->dst.varindex,bbindex,result);
985  M->add_Instruction(result);
986  }
987  break;
988 
989  /* binary/const INT */
990  case ICMD_IADDCONST:
991  case ICMD_ISUBCONST:
992  {
993  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
994  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
995  Instruction *result;
996  switch (iptr->opc) {
997  case ICMD_IADDCONST:
998  result = new ADDInst(Type::IntTypeID, s1, konst);
999  break;
1000  case ICMD_ISUBCONST:
1001  result = new SUBInst(Type::IntTypeID, s1, konst);
1002  break;
1003  default: assert(0);
1004  result = 0;
1005  }
1006  M->add_Instruction(konst);
1007  write_variable(iptr->dst.varindex,bbindex,result);
1008  M->add_Instruction(result);
1009  }
1010  break;
1011  case ICMD_IMULCONST:
1012  {
1013  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1014  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1015  Instruction *result = new MULInst(Type::IntTypeID, s1, konst);
1016  M->add_Instruction(konst);
1017  write_variable(iptr->dst.varindex,bbindex,result);
1018  M->add_Instruction(result);
1019  }
1020  break;
1021  case ICMD_IMULPOW2:
1022  {
1023  deoptimize(bbindex);
1024  break;
1025  }
1026  case ICMD_IREMPOW2:
1027  case ICMD_IDIVPOW2:
1028  case ICMD_IANDCONST:
1029  {
1030  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1031  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1032  Instruction *result;
1033  switch (iptr->opc) {
1034  case ICMD_IANDCONST:
1035  result = new ANDInst(Type::IntTypeID, s1, konst);
1036  break;
1037  case ICMD_IDIVPOW2:
1038  result = new DIVInst(Type::IntTypeID, s1, konst);
1039  break;
1040  case ICMD_IREMPOW2:
1041  result = new REMInst(Type::IntTypeID, s1, konst);
1042  break;
1043  default: assert(0);
1044  result = NULL;
1045  }
1046  M->add_Instruction(konst);
1047  write_variable(iptr->dst.varindex,bbindex,result);
1048  M->add_Instruction(result);
1049  }
1050  break;
1051  case ICMD_IORCONST:
1052  case ICMD_IXORCONST:
1053  case ICMD_ISHLCONST:
1054  case ICMD_ISHRCONST:
1055  case ICMD_IUSHRCONST:
1056  case ICMD_LSHLCONST:
1057  case ICMD_LSHRCONST:
1058  case ICMD_LUSHRCONST:
1059 
1060  /* ?ASTORECONST (trinary/const INT) */
1061 
1062  case ICMD_BASTORECONST:
1063  case ICMD_CASTORECONST:
1064  case ICMD_SASTORECONST:
1065  case ICMD_AASTORECONST:
1066  {
1067  deoptimize(bbindex);
1068  break;
1069  }
1070  case ICMD_IASTORECONST:
1071  case ICMD_LASTORECONST:
1072  {
1073  Value *arrayref = read_variable(iptr->s1.varindex, bbindex);
1074  Value *index = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1075  Instruction *konst;
1076  Type::TypeID type;
1077  switch (iptr->opc) {
1078  case ICMD_IASTORECONST:
1079  type = Type::IntTypeID;
1080  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::IntType());
1081  break;
1082  // TODO Investigate why the following cases are not used.
1083  #if 0
1084  case ICMD_BASTORECONST:
1085  type = Type::ByteTypeID;
1086  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ByteType());
1087  break;
1088  case ICMD_CASTORECONST:
1089  type = Type::CharTypeID;
1090  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::CharType());
1091  break;
1092  case ICMD_SASTORECONST:
1093  type = Type::ShortTypeID;
1094  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ShortType());
1095  break;
1096  case ICMD_AASTORECONST:
1097  type = Type::ReferenceTypeID;
1098  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::ReferenceType());
1099  break;
1100  #endif
1101  case ICMD_LASTORECONST:
1102  type = Type::LongTypeID;
1103  konst = new CONSTInst(iptr->sx.s23.s3.constval,Type::LongType());
1104  break;
1105  default:
1106  assert(0);
1107  type = Type::VoidTypeID;
1108  konst = NULL;
1109  }
1110  M->add_Instruction(konst);
1111 
1112  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1113  assert(state_change);
1114 
1115  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(arrayref, index);
1116  M->add_Instruction(boundscheck);
1117 
1118  Instruction *ref = new AREFInst(type, arrayref, index, BB[bbindex]);
1119  ref->append_dep(boundscheck);
1120  M->add_Instruction(ref);
1121 
1122  Instruction *array_store = new ASTOREInst(type, ref, konst, BB[bbindex], state_change);
1123  M->add_Instruction(array_store);
1124  write_variable(global_state, bbindex, array_store);
1125  }
1126  break;
1127  case ICMD_ICONST:
1128  case ICMD_LCONST:
1129  case ICMD_FCONST:
1130  case ICMD_DCONST:
1131  {
1132  Instruction *I;
1133  switch (iptr->opc) {
1134  case ICMD_ICONST:
1135  I = new CONSTInst(iptr->sx.val.i,Type::IntType());
1136  break;
1137  case ICMD_LCONST:
1138  I = new CONSTInst(iptr->sx.val.l,Type::LongType());
1139  break;
1140  case ICMD_FCONST:
1141  I = new CONSTInst(iptr->sx.val.f,Type::FloatType());
1142  break;
1143  case ICMD_DCONST:
1144  I = new CONSTInst(iptr->sx.val.d,Type::DoubleType());
1145  break;
1146  default:
1147  assert(0);
1148  I = NULL;
1149  }
1150  write_variable(iptr->dst.varindex,bbindex,I);
1151  M->add_Instruction(I);
1152  }
1153  break;
1154 
1155  /* binary/const LNG */
1156  case ICMD_LADDCONST:
1157  {
1158  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1159  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1160  Instruction *result = new ADDInst(Type::LongTypeID, s1, konst);
1161  M->add_Instruction(konst);
1162  write_variable(iptr->dst.varindex,bbindex,result);
1163  M->add_Instruction(result);
1164  }
1165  break;
1166  case ICMD_LSUBCONST:
1167  {
1168  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1169  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1170  Instruction *result = new SUBInst(Type::LongTypeID, s1, konst);
1171  M->add_Instruction(konst);
1172  write_variable(iptr->dst.varindex,bbindex,result);
1173  M->add_Instruction(result);
1174  }
1175  break;
1176  case ICMD_LMULCONST:
1177  {
1178  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1179  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1180  Instruction *result = new MULInst(Type::LongTypeID, s1, konst);
1181  M->add_Instruction(konst);
1182  write_variable(iptr->dst.varindex,bbindex,result);
1183  M->add_Instruction(result);
1184  }
1185  break;
1186  case ICMD_LANDCONST:
1187  {
1188  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1189  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1190  Instruction *result = new ANDInst(Type::LongTypeID, s1, konst);
1191  M->add_Instruction(konst);
1192  write_variable(iptr->dst.varindex,bbindex,result);
1193  M->add_Instruction(result);
1194  }
1195  break;
1196  case ICMD_LMULPOW2:
1197  {
1198  deoptimize(bbindex);
1199  break;
1200  }
1201  case ICMD_LDIVPOW2:
1202  {
1203  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1204  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1205  Instruction *result;
1206  switch (iptr->opc) {
1207  case ICMD_LDIVPOW2:
1208  // FIXME this is not right!
1209  result = new SUBInst(Type::LongTypeID, s1, konst);
1210  break;
1211  default: assert(0);
1212  result = 0;
1213  }
1214  M->add_Instruction(konst);
1215  write_variable(iptr->dst.varindex,bbindex,result);
1216  M->add_Instruction(result);
1217  }
1218  break;
1219  case ICMD_LREMPOW2:
1220  case ICMD_LORCONST:
1221  case ICMD_LXORCONST:
1222 
1223  /* const ADR */
1224  case ICMD_ACONST:
1225  {
1226  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1227  deoptimize(bbindex);
1228  break;
1229  }
1230 
1231  Instruction *I = new CONSTInst(iptr->sx.val.anyptr, Type::ReferenceType());
1232  write_variable(iptr->dst.varindex,bbindex,I);
1233  M->add_Instruction(I);
1234  }
1235  break;
1236  case ICMD_GETFIELD: /* 1 -> 1 */
1237  {
1238  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1239  deoptimize(bbindex);
1240  break;
1241  }
1242 
1243  constant_FMIref *fmiref;
1244  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1245  fieldinfo* field = fmiref->p.field;
1246 
1247  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1248  assert(state_change);
1249 
1250  Type::TypeID type = convert_to_typeid(fmiref->parseddesc.fd->type);
1251  Value *objectref = read_variable(iptr->s1.varindex,bbindex);
1252 
1253  Instruction *getfield = new GETFIELDInst(type, objectref, field, BB[bbindex],
1254  state_change);
1255  M->add_Instruction(getfield);
1256  write_variable(iptr->dst.varindex, bbindex, getfield);
1257  write_variable(global_state, bbindex, getfield);
1258  }
1259  break;
1260  case ICMD_PUTFIELD: /* 2 -> 0 */
1261  case ICMD_PUTFIELDCONST: /* 1 -> 0 */
1262  {
1263  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1264  deoptimize(bbindex);
1265  break;
1266  }
1267 
1268  constant_FMIref *fmiref;
1269  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1270  fieldinfo* field = fmiref->p.field;
1271 
1272  Instruction *state_change = read_variable(global_state, bbindex)->to_Instruction();
1273  assert(state_change);
1274 
1275  Value *objectref = read_variable(iptr->s1.varindex, bbindex);
1276  Value *value;
1277 
1278  if (iptr->opc == ICMD_PUTFIELDCONST) {
1279  Type::TypeID type = convert_to_typeid(fmiref->parseddesc.fd->type);
1280  CONSTInst *konst = parse_s2_constant(iptr, type);
1281  value = konst;
1282  M->add_Instruction(konst);
1283  } else {
1284  value = read_variable(iptr->sx.s23.s2.varindex, bbindex);
1285  }
1286 
1287  Instruction *putfield = new PUTFIELDInst(objectref, value, field, BB[bbindex],
1288  state_change);
1289  M->add_Instruction(putfield);
1290  write_variable(global_state, bbindex, putfield);
1291  }
1292  break;
1293  case ICMD_GETSTATIC: /* 0 -> 1 */
1294  {
1295  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1296  deoptimize(bbindex);
1297  break;
1298  }
1299 
1300  constant_FMIref *fmiref;
1301  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1302  fieldinfo* field = fmiref->p.field;
1303 
1304  if (!class_is_or_almost_initialized(field->clazz)) {
1305  deoptimize(bbindex);
1306  break;
1307  }
1308 
1309  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1310  assert(state_change);
1311 
1312  Type::TypeID type = convert_to_typeid(fmiref->parseddesc.fd->type);
1313  Instruction *getstatic = new GETSTATICInst(type, field,
1314  BB[bbindex], state_change);
1315 
1316  write_variable(iptr->dst.varindex, bbindex, getstatic);
1317  write_variable(global_state, bbindex, getstatic);
1318 
1319  M->add_Instruction(getstatic);
1320  }
1321  break;
1322  case ICMD_PUTSTATIC: /* 1 -> 0 */
1323  case ICMD_PUTSTATICCONST: /* 0 -> 0 */
1324  {
1325  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1326  deoptimize(bbindex);
1327  break;
1328  }
1329 
1330  constant_FMIref *fmiref;
1331  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1332  fieldinfo* field = fmiref->p.field;
1333 
1334  if (!class_is_or_almost_initialized(field->clazz)) {
1335  deoptimize(bbindex);
1336  break;
1337  }
1338 
1339  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1340  assert(state_change);
1341 
1342  Value *value;
1343 
1344  if (iptr->opc == ICMD_PUTSTATICCONST) {
1345  Type::TypeID type = convert_to_typeid(fmiref->parseddesc.fd->type);
1346  CONSTInst *konst = parse_s2_constant(iptr, type);
1347  value = konst;
1348  M->add_Instruction(konst);
1349  } else {
1350  value = read_variable(iptr->s1.varindex,bbindex);
1351  }
1352 
1353  Instruction *putstatic = new PUTSTATICInst(value, field,
1354  BB[bbindex], state_change);
1355 
1356  write_variable(global_state, bbindex, putstatic);
1357 
1358  M->add_Instruction(putstatic);
1359  }
1360  break;
1361  case ICMD_IINC:
1362  {
1363  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1364  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1365  Instruction *result = new ADDInst(Type::IntTypeID, s1, konst);
1366  M->add_Instruction(konst);
1367  write_variable(iptr->dst.varindex,bbindex,result);
1368  M->add_Instruction(result);
1369  }
1370  break;
1371  case ICMD_IASTORE:
1372  case ICMD_SASTORE:
1373  case ICMD_BASTORE:
1374  case ICMD_CASTORE:
1375  case ICMD_LASTORE:
1376  case ICMD_DASTORE:
1377  case ICMD_FASTORE:
1378  case ICMD_AASTORE:
1379  {
1380  Value *arrayref = read_variable(iptr->s1.varindex, bbindex);
1381  Value *index = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1382  Value *value = read_variable(iptr->sx.s23.s3.varindex,bbindex);
1383 
1384  Type::TypeID type;
1385  switch (iptr->opc) {
1386  case ICMD_BASTORE:
1387  type = Type::ByteTypeID;
1388  break;
1389  case ICMD_CASTORE:
1390  type = Type::CharTypeID;
1391  break;
1392  case ICMD_SASTORE:
1393  type = Type::ShortTypeID;
1394  break;
1395  case ICMD_IASTORE:
1396  type = Type::IntTypeID;
1397  break;
1398  case ICMD_LASTORE:
1399  type = Type::LongTypeID;
1400  break;
1401  case ICMD_AASTORE:
1402  type = Type::ReferenceTypeID;
1403  break;
1404  case ICMD_FASTORE:
1405  type = Type::FloatTypeID;
1406  break;
1407  case ICMD_DASTORE:
1408  type = Type::DoubleTypeID;
1409  break;
1410  default:
1411  assert(0);
1412  type = Type::VoidTypeID;
1413  }
1414 
1415  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1416  assert(state_change);
1417 
1418  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(arrayref, index);
1419  M->add_Instruction(boundscheck);
1420 
1421  Instruction *ref = new AREFInst(value->get_type(), arrayref, index, BB[bbindex]);
1422  ref->append_dep(boundscheck);
1423  M->add_Instruction(ref);
1424 
1425  Instruction *array_store = new ASTOREInst(type, ref, value, BB[bbindex], state_change);
1426  M->add_Instruction(array_store);
1427  write_variable(global_state, bbindex, array_store);
1428  }
1429  break;
1430  case ICMD_IALOAD:
1431  case ICMD_SALOAD:
1432  case ICMD_BALOAD:
1433  case ICMD_CALOAD:
1434  case ICMD_LALOAD:
1435  case ICMD_DALOAD:
1436  case ICMD_FALOAD:
1437  case ICMD_AALOAD:
1438  {
1439  Value *arrayref = read_variable(iptr->s1.varindex, bbindex);
1440  Value *index = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1441  Type::TypeID type;
1442  switch (iptr->opc) {
1443  case ICMD_BALOAD:
1444  type = Type::ByteTypeID;
1445  break;
1446  case ICMD_CALOAD:
1447  type = Type::CharTypeID;
1448  break;
1449  case ICMD_SALOAD:
1450  type = Type::ShortTypeID;
1451  break;
1452  case ICMD_IALOAD:
1453  type = Type::IntTypeID;
1454  break;
1455  case ICMD_LALOAD:
1456  type = Type::LongTypeID;
1457  break;
1458  case ICMD_AALOAD:
1459  type = Type::ReferenceTypeID;
1460  break;
1461  case ICMD_FALOAD:
1462  type = Type::FloatTypeID;
1463  break;
1464  case ICMD_DALOAD:
1465  type = Type::DoubleTypeID;
1466  break;
1467  default:
1468  assert(0);
1469  type = Type::VoidTypeID;
1470  }
1471 
1472  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1473  assert(state_change);
1474 
1475  Instruction *boundscheck = new ARRAYBOUNDSCHECKInst(arrayref, index);
1476  M->add_Instruction(boundscheck);
1477 
1478  Instruction *ref = new AREFInst(type, arrayref, index, BB[bbindex]);
1479  ref->append_dep(boundscheck);
1480  M->add_Instruction(ref);
1481 
1482  Instruction *array_load = new ALOADInst(type, ref, BB[bbindex], state_change);
1483  M->add_Instruction(array_load);
1484  write_variable(iptr->dst.varindex, bbindex, array_load);
1485  write_variable(global_state, bbindex, array_load);
1486  }
1487  break;
1488  case ICMD_RET:
1489  {
1490  deoptimize(bbindex);
1491  break;
1492  }
1493  case ICMD_ILOAD:
1494  case ICMD_LLOAD:
1495  case ICMD_FLOAD:
1496  case ICMD_DLOAD:
1497  case ICMD_ALOAD:
1498  {
1499  Value *def = read_variable(iptr->s1.varindex,bbindex);
1500  assert(def);
1501  write_variable(iptr->dst.varindex,bbindex,def);
1502  }
1503  break;
1504  case ICMD_ISTORE:
1505  case ICMD_LSTORE:
1506  case ICMD_FSTORE:
1507  case ICMD_DSTORE:
1508  case ICMD_ASTORE:
1509  {
1510  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1511  write_variable(iptr->dst.varindex,bbindex,s1);
1512  stack_javalocals_store(iptr, live_javalocals);
1513  }
1514  break;
1515  case ICMD_CHECKCAST:
1516  case ICMD_INSTANCEOF:
1517  deoptimize(bbindex);
1518  break;
1519  case ICMD_INVOKESPECIAL:
1520  case ICMD_INVOKEVIRTUAL:
1521  case ICMD_INVOKEINTERFACE:
1522  case ICMD_INVOKESTATIC:
1523  case ICMD_BUILTIN:
1524  {
1525  if (!INSTRUCTION_IS_RESOLVED(iptr)) {
1526  deoptimize(bbindex);
1527  break;
1528  }
1529 
1530  methoddesc *md;
1531  constant_FMIref *fmiref;
1532 
1533  if (iptr->opc == ICMD_BUILTIN) {
1534  md = iptr->sx.s23.s3.bte->md;
1535  } else {
1536  INSTRUCTION_GET_METHODREF(iptr, fmiref);
1537  md = fmiref->parseddesc.md;
1538  }
1539 
1540  // Determine the return type of the invocation.
1541  Type::TypeID type;
1542  switch (md->returntype.type) {
1543  case TYPE_INT:
1544  type = Type::IntTypeID;
1545  break;
1546  case TYPE_LNG:
1547  type = Type::LongTypeID;
1548  break;
1549  case TYPE_FLT:
1550  type = Type::FloatTypeID;
1551  break;
1552  case TYPE_DBL:
1553  type = Type::DoubleTypeID;
1554  break;
1555  case TYPE_VOID:
1556  type = Type::VoidTypeID;
1557  break;
1558  case TYPE_ADR:
1559  type = Type::ReferenceTypeID;
1560  break;
1561  case TYPE_RET:
1562  // TODO Implement me.
1563  default:
1564  type = Type::VoidTypeID;
1565  err() << BoldRed << "error: " << reset_color << " type " << BoldWhite
1566  << md->returntype.type << reset_color
1567  << " not yet supported! (see vm/global.h)" << nl;
1568  assert(false);
1569  }
1570 
1571  Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1572  assert(state_change);
1573 
1574  SourceStateInst *source_state = record_source_state(BB[bbindex],
1575  bb->iinstr, bb, live_javalocals, bb->invars, bb->indepth);
1576 
1577  // Create the actual instruction for the invocation.
1578  INVOKEInst *invoke = NULL;
1579  int32_t argcount = iptr->s1.argcount;
1580  switch (iptr->opc) {
1581  case ICMD_INVOKESPECIAL:
1582  {
1583  assert(INSTRUCTION_MUST_CHECK(iptr));
1584 
1585  s4 receiver_index = *(iptr->sx.s23.s2.args);
1586  Value *receiver = read_variable(receiver_index,bbindex);
1587  Instruction *null_check = new CHECKNULLInst(receiver);
1588  M->add_Instruction(null_check);
1589 
1590  invoke = new INVOKESPECIALInst(type,argcount,fmiref,BB[bbindex],state_change,source_state);
1591  invoke->append_dep(null_check);
1592  }
1593  break;
1594  case ICMD_INVOKEVIRTUAL:
1595  {
1596  invoke = new INVOKEVIRTUALInst(type,argcount,fmiref,BB[bbindex],state_change,source_state);
1597  }
1598  break;
1599  case ICMD_INVOKESTATIC:
1600  {
1601  invoke = new INVOKESTATICInst(type,argcount,fmiref,BB[bbindex],state_change,source_state);
1602  }
1603  break;
1604  case ICMD_INVOKEINTERFACE:
1605  {
1606  invoke = new INVOKEINTERFACEInst(type,argcount,fmiref,BB[bbindex],state_change,source_state);
1607  }
1608  break;
1609  case ICMD_BUILTIN:
1610  {
1611  builtintable_entry *bte = iptr->sx.s23.s3.bte;
1612  u1 *builtin_address = bte->stub == NULL ? reinterpret_cast<u1*>(bte->fp) : bte->stub;
1613  invoke = new BUILTINInst(type,builtin_address,argcount,BB[bbindex],state_change,source_state);
1614  }
1615  break;
1616  default:
1617  assert(false);
1618  break;
1619  }
1620 
1621  // Establish data dependencies to the arguments of the invocation.
1622  s4 *args = iptr->sx.s23.s2.args;
1623  for (int i = 0; i < argcount; i++) {
1624  // TODO understand
1625  //if ((iptr->s1.argcount - 1 - i) == md->paramcount)
1626  // printf(" pass-through: ");
1627  invoke->append_parameter(read_variable(args[i],bbindex));
1628  }
1629 
1630  if (type != Type::VoidTypeID) {
1631  write_variable(iptr->dst.varindex,bbindex,invoke);
1632  }
1633 
1634  write_variable(global_state,bbindex,invoke);
1635  M->add_Instruction(invoke);
1636 
1637  LOG3("INVOKEInst: " << invoke << " dep = " << state_change << nl);
1638  }
1639  break;
1640  case ICMD_IFLT:
1641  case ICMD_IFGT:
1642  case ICMD_IFGE:
1643  case ICMD_IFEQ:
1644  case ICMD_IFNE:
1645  case ICMD_IFLE:
1646  {
1647  Conditional::CondID cond;
1648  switch (iptr->opc) {
1649  case ICMD_IFLT:
1650  cond = Conditional::LT;
1651  break;
1652  case ICMD_IFGT:
1653  cond = Conditional::GT;
1654  break;
1655  case ICMD_IFEQ:
1656  cond = Conditional::EQ;
1657  break;
1658  case ICMD_IFNE:
1659  cond = Conditional::NE;
1660  break;
1661  case ICMD_IFLE:
1662  cond = Conditional::LE;
1663  break;
1664  case ICMD_IFGE:
1665  cond = Conditional::GE;
1666  break;
1667  default:
1669  cond = Conditional::NoCond;
1670  }
1671  Instruction *konst = new CONSTInst(iptr->sx.val.i,Type::IntType());
1672  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1673  assert(s1);
1674 
1675  if (s1->get_type() != konst->get_type()) {
1676  deoptimize(bbindex);
1677  break;
1678  }
1679 
1680  assert(BB[iptr->dst.block->nr]);
1681  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
1682  assert(trueBlock);
1683  assert(BB[bbindex+1]);
1684  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
1685  assert(falseBlock);
1686  Instruction *result = new IFInst(BB[bbindex], s1, konst, cond,
1687  trueBlock, falseBlock);
1688  M->add_Instruction(konst);
1689  M->add_Instruction(result);
1690  }
1691  break;
1692  case ICMD_IF_LLT:
1693  case ICMD_IF_LGT:
1694  case ICMD_IF_LLE:
1695  case ICMD_IF_LEQ:
1696  case ICMD_IF_LNE:
1697  case ICMD_IF_LGE:
1698  {
1699  Conditional::CondID cond;
1700  switch (iptr->opc) {
1701  case ICMD_IF_LLT:
1702  cond = Conditional::LT;
1703  break;
1704  case ICMD_IF_LGT:
1705  cond = Conditional::GT;
1706  break;
1707  case ICMD_IF_LLE:
1708  cond = Conditional::LE;
1709  break;
1710  case ICMD_IF_LEQ:
1711  cond = Conditional::EQ;
1712  break;
1713  case ICMD_IF_LNE:
1714  cond = Conditional::NE;
1715  break;
1716  case ICMD_IF_LGE:
1717  cond = Conditional::GE;
1718  break;
1719  default:
1721  cond = Conditional::NoCond;
1722  }
1723  Instruction *konst = new CONSTInst(iptr->sx.val.l,Type::LongType());
1724  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1725  assert(s1);
1726 
1727  if (s1->get_type() != konst->get_type()) {
1728  deoptimize(bbindex);
1729  break;
1730  }
1731 
1732  assert(BB[iptr->dst.block->nr]);
1733  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
1734  assert(trueBlock);
1735  assert(BB[bbindex+1]);
1736  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
1737  assert(falseBlock);
1738  Instruction *result = new IFInst(BB[bbindex], s1, konst, cond,
1739  trueBlock, falseBlock);
1740  M->add_Instruction(konst);
1741  M->add_Instruction(result);
1742  }
1743  break;
1744  case ICMD_GOTO:
1745  {
1746  assert(BB[iptr->dst.block->nr]);
1747  BeginInst *targetBlock = BB[iptr->dst.block->nr];
1748  Instruction *result = new GOTOInst(BB[bbindex], targetBlock);
1749  M->add_Instruction(result);
1750  }
1751  break;
1752  case ICMD_JSR:
1753  case ICMD_IFNULL:
1754  case ICMD_IFNONNULL:
1755  {
1756  deoptimize(bbindex);
1757  break;
1758  }
1759  case ICMD_IF_ICMPEQ:
1760  case ICMD_IF_ICMPNE:
1761  case ICMD_IF_ICMPLT:
1762  case ICMD_IF_ICMPGE:
1763  case ICMD_IF_ICMPGT:
1764  case ICMD_IF_ICMPLE:
1765  {
1766  Conditional::CondID cond;
1767  switch (iptr->opc) {
1768  case ICMD_IF_ICMPLE:
1769  cond = Conditional::LE;
1770  break;
1771  case ICMD_IF_ICMPEQ:
1772  cond = Conditional::EQ;
1773  break;
1774  case ICMD_IF_ICMPNE:
1775  cond = Conditional::NE;
1776  break;
1777  case ICMD_IF_ICMPLT:
1778  cond = Conditional::LT;
1779  break;
1780  case ICMD_IF_ICMPGE:
1781  cond = Conditional::GE;
1782  break;
1783  case ICMD_IF_ICMPGT:
1784  cond = Conditional::GT;
1785  break;
1786  default:
1788  cond = Conditional::NoCond;
1789  }
1790  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1791  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1792  assert(s1);
1793  assert(s2);
1794 
1795  if (s1->get_type() != s2->get_type()) {
1796  deoptimize(bbindex);
1797  break;
1798  }
1799 
1800  assert(BB[iptr->dst.block->nr]);
1801  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
1802  assert(trueBlock);
1803  assert(BB[bbindex+1]);
1804  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
1805  assert(falseBlock);
1806  Instruction *result = new IFInst(BB[bbindex], s1, s2, cond,
1807  trueBlock, falseBlock);
1808  M->add_Instruction(result);
1809  }
1810  break;
1811  case ICMD_IF_LCMPEQ:
1812  case ICMD_IF_LCMPNE:
1813  case ICMD_IF_LCMPLT:
1814  case ICMD_IF_LCMPGT:
1815  case ICMD_IF_LCMPGE:
1816  case ICMD_IF_LCMPLE:
1817  {
1818  Conditional::CondID cond;
1819  switch (iptr->opc) {
1820  case ICMD_IF_LCMPEQ:
1821  cond = Conditional::EQ;
1822  break;
1823  case ICMD_IF_LCMPNE:
1824  cond = Conditional::NE;
1825  break;
1826  case ICMD_IF_LCMPLT:
1827  cond = Conditional::LT;
1828  break;
1829  case ICMD_IF_LCMPGT:
1830  cond = Conditional::GT;
1831  break;
1832  case ICMD_IF_LCMPGE:
1833  cond = Conditional::GE;
1834  break;
1835  case ICMD_IF_LCMPLE:
1836  cond = Conditional::LE;
1837  break;
1838  default:
1839  cond = Conditional::NoCond;
1841  }
1842  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1843  Value *s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1844  assert(s1);
1845  assert(s2);
1846 
1847  if (s1->get_type() != s2->get_type()) {
1848  deoptimize(bbindex);
1849  break;
1850  }
1851 
1852  assert(BB[iptr->dst.block->nr]);
1853  BeginInst *trueBlock = BB[iptr->dst.block->nr]->to_BeginInst();
1854  assert(trueBlock);
1855  assert(BB[bbindex+1]);
1856  BeginInst *falseBlock = BB[bbindex+1]->to_BeginInst();
1857  assert(falseBlock);
1858  Instruction *result = new IFInst(BB[bbindex], s1, s2, cond,
1859  trueBlock, falseBlock);
1860  M->add_Instruction(result);
1861  }
1862  break;
1863  case ICMD_IF_ACMPEQ:
1864  case ICMD_IF_ACMPNE:
1865  {
1866  deoptimize(bbindex);
1867  break;
1868  }
1869  case ICMD_TABLESWITCH:
1870  {
1871  s4 tablehigh = iptr->sx.s23.s3.tablehigh;
1872  s4 tablelow = iptr->sx.s23.s2.tablelow;
1873 
1874  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1875  TABLESWITCHInst *result = new TABLESWITCHInst(BB[bbindex], s1,
1876  TABLESWITCHInst::LOW(tablelow),
1877  TABLESWITCHInst::HIGH(tablehigh));
1878 
1879  s4 count = tablehigh - tablelow + 1;
1880  LOG("tableswitch high=" << tablehigh << " low=" << tablelow << " count=" << count << nl);
1881  branch_target_t *table = iptr->dst.table;
1882  BeginInst* def = BB[table[0].block->nr];
1883  LOG("idx: " << 0 << " BeginInst: " << BB[table[0].block->nr]
1884  << "(block.nr=" << table[0].block->nr << ")"<< nl);
1885  ++table;
1886  for (s4 i = 0; i < count ; ++i) {
1887  LOG("idx: " << i << " BeginInst: " << BB[table[i].block->nr]
1888  << "(block.nr=" << table[i].block->nr << ")"<< nl);
1889  result->append_succ(BB[table[i].block->nr]);
1890  }
1891  result->append_succ(def);
1892  M->add_Instruction(result);
1893  }
1894  break;
1895  case ICMD_LOOKUPSWITCH:
1896  {
1897  s4 lookupcount = iptr->sx.s23.s2.lookupcount;
1898 
1899  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1900  LOOKUPSWITCHInst *result = new LOOKUPSWITCHInst(BB[bbindex], s1, lookupcount);
1901 
1902  // add case targets
1903  lookup_target_t *lookup = iptr->dst.lookup;
1904  for (s4 i = 0; i < lookupcount; ++i) {
1905  // lookup->value
1906  result->append_succ(BB[lookup->target.block->nr]);
1907  result->set_match(i, LOOKUPSWITCHInst::MATCH(lookup->value));
1908  ++lookup;
1909  }
1910  // add default target
1911  BeginInst *defaultBlock = BB[iptr->sx.s23.s3.lookupdefault.block->nr];
1912  assert(defaultBlock);
1913  result->append_succ(defaultBlock);
1914 
1915  M->add_Instruction(result);
1916  }
1917  break;
1918  case ICMD_FRETURN:
1919  case ICMD_IRETURN:
1920  case ICMD_DRETURN:
1921  case ICMD_LRETURN:
1922  case ICMD_ARETURN:
1923  {
1924  Value *s1 = read_variable(iptr->s1.varindex,bbindex);
1925  Instruction *result = new RETURNInst(BB[bbindex], s1);
1926  M->add_Instruction(result);
1927  }
1928  break;
1929  case ICMD_RETURN:
1930  {
1931  Instruction *result = new RETURNInst(BB[bbindex]);
1932  M->add_Instruction(result);
1933  }
1934  break;
1935  case ICMD_ATHROW:
1936  {
1937  deoptimize(bbindex);
1938  break;
1939  }
1940  case ICMD_COPY:
1941  case ICMD_MOVE:
1942  {
1943  Value *s1 = read_variable(iptr->s1.varindex, bbindex);
1944  write_variable(iptr->dst.varindex,bbindex,s1);
1945  }
1946  break;
1947  case ICMD_GETEXCEPTION:
1948  {
1949  deoptimize(bbindex);
1950  break;
1951  }
1952  default:
1953  #if !defined(NDEBUG)
1954  ABORT_MSG(icmd_table[iptr->opc].name << " (" << iptr->opc << ")",
1955  "Operation not yet supported!");
1956  #else
1957  ABORT_MSG("Opcode: (" << iptr->opc << ")",
1958  "Operation not yet supported!");
1959  #endif
1960  break;
1961  }
1962 
1963  // Record the source state if the last instruction was side-effecting.
1964  new_global_state = read_variable(global_state,bbindex)->to_Instruction();
1965  if (new_global_state != old_global_state && new_global_state->has_side_effects()) {
1966  assert(instruction_has_side_effects(iptr));
1967  record_source_state(new_global_state, iptr, bb, live_javalocals,
1968  iptr->stack_after, iptr->stackdepth_after);
1969  }
1970  }
1971 
1972  if (!BB[bbindex]->get_EndInst()) {
1973  // No end instruction yet. Adding GOTO
1974  assert(bbindex+1 < BB.size());
1975  BeginInst *targetBlock = BB[bbindex+1];
1976  Instruction *result = new GOTOInst(BB[bbindex], targetBlock);
1977  M->add_Instruction(result);
1978  }
1979 
1980  // block filled!
1981  filled_blocks[bbindex] = true;
1982  // try to seal block
1983  try_seal_block(bb);
1984  // try seal successors
1985  for(int i = 0; i < bb->successorcount; ++i) {
1986  try_seal_block(bb->successors[i]);
1987  }
1988  }
1989 
1990 #ifndef NDEBUG
1991  for(size_t i = 0; i< num_basicblocks; ++i) {
1992  if (!sealed_blocks[i]) {
1993  err() << BoldRed << "error: " << reset_color << "unsealed basic block: " << BoldWhite
1994  << i << " (" << BB[i] << ")"
1995  << reset_color << nl;
1996  assert(0 && "There is an unsealed basic block");
1997  }
1998  }
1999 #endif
2000 
2001  remove_unreachable_blocks();
2002 
2003  return true;
2004 }
2005 
2006 bool SSAConstructionPass::verify() const {
2007  for (Method::const_iterator i = M->begin(), e = M->end() ; i != e ; ++i) {
2008  Instruction *I = *i;
2009  if (!I->verify()) return false;
2010  }
2011  return true;
2012 }
2013 
2014 PassUsage& SSAConstructionPass::get_PassUsage(PassUsage &PU) const {
2015  PU.add_requires<CFGConstructionPass>();
2016  return PU;
2017 }
2018 
2019 // registrate Pass
2020 static PassRegistry<SSAConstructionPass> X("SSAConstructionPass");
2021 
2022 } // end namespace cacao
2023 } // end namespace jit
2024 } // end namespace compiler2
2025 
2026 
2027 /*
2028  * These are local overrides for various environment variables in Emacs.
2029  * Please do not remove this and leave it at the end of the file, where
2030  * Emacs will automagically detect them.
2031  * ---------------------------------------------------------------------
2032  * Local variables:
2033  * mode: c++
2034  * indent-tabs-mode: t
2035  * c-basic-offset: 4
2036  * tab-width: 4
2037  * End:
2038  * vim:noexpandtab:sw=4:ts=4:
2039  */
val_operand_t val
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
std::size_t index
basicblock * block
static bool instruction_has_side_effects(const instruction *iptr)
JNIEnv jthread jmethodID jlocation jclass jobject jfieldID field
Definition: jvmti.h:221
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
static SetWidth setw(size_t w)
Definition: OStream.hpp:395
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
#define max(a, b)
Definition: lsra.hpp:80
BeginInst * BI
s4 * invars
Definition: jit.hpp:330
s4 outdepth
Definition: jit.hpp:333
u2 op
Definition: disass.cpp:129
int32_t argcount
Definition: instruction.hpp:64
s4 successorcount
Definition: jit.hpp:338
int32_t varindex
Definition: instruction.hpp:63
const char * name
Definition: icmd.hpp:393
union constant_FMIref::@26 p
methoddesc * md
Definition: references.hpp:75
uint8_t u1
Definition: types.hpp:40
Type type
Definition: reg.hpp:44
MachineBasicBlock * BB
u1 * stub
Definition: builtin.hpp:64
#define DEBUG_COND_N(VERBOSE)
Definition: Debug.hpp:112
lookup_target_t * lookup
instruction * iinstr
Definition: jit.hpp:326
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
Definition: reg.hpp:43
s4 icount
Definition: jit.hpp:325
s4 * javalocals
Definition: jit.hpp:329
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define MCOPY(dest, src, type, num)
Definition: memory.hpp:103
BeginInst *& block
branch_target_t target
Definition: instruction.hpp:57
dst_operand_t dst
flags_operand_t flags
basicblock ** predecessors
Definition: jit.hpp:339
alloc::list< PassInfo::IDTy >::type & stack
This file contains the statistics framework.
s4 predecessorcount
Definition: jit.hpp:337
#define INSTRUCTION_GET_FIELDREF(iptr, fref)
#define STAT_REGISTER_GROUP_VAR(type, var, init, name, description, group)
Register an statistics variable and add it to a group.
Definition: statistics.hpp:967
s4 indepth
Definition: jit.hpp:332
typedesc * fd
Definition: references.hpp:74
MIIterator i
Type::TypeID convert_to_typeid(int type)
Convert a Type to a Type::TypeID.
Definition: Type.cpp:51
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
typedesc returntype
Definition: descriptor.hpp:166
#define LOG2(STMT)
Definition: logging.hpp:93
#define FOR_EACH_BASICBLOCK(jd, it)
Definition: jit.hpp:181
int32_t s4
Definition: types.hpp:45
classinfo * clazz
Definition: field.hpp:55
ResetColor reset_color
Definition: OStream.cpp:61
s4 maxlocals
Definition: method.hpp:84
s4 * outvars
Definition: jit.hpp:331
union instruction::@12 sx
void stack_javalocals_store(instruction *iptr, s4 *javalocals)
Definition: stack.cpp:4724
int32_t varindex
#define LOG3(STMT)
Definition: logging.hpp:94
OStream & err()
Definition: OStream.cpp:33
icmdtable_entry_t icmd_table[256]
Definition: icmd.cpp:60
MIIterator e
s1_operand_t s1
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
basicblock * block
Definition: instruction.hpp:50
#define I(value)
Definition: codegen.c:279
Definition: builtin.hpp:60
Represents the result of the addition of a certain IR-variable with a certain constant.
Definition: Value.hpp:36
methodinfo * method
Definition: jit.hpp:349
const char * get_type_name(int type)
Get the printable name of the type.
Definition: Type.cpp:37
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
Definition: statistics.hpp:970
const Method & M
static void * allocate(size_t size)
Definition: dumpmemory.hpp:251
#define FOR_EACH_INSTRUCTION(bptr, it)
Definition: jit.hpp:391
s4 nr
Definition: jit.hpp:319
static void shouldnotreach()
Definition: os.hpp:690
int8_t s1
Definition: types.hpp:39
static bool class_is_or_almost_initialized(classinfo *c)
Definition: class.hpp:433
int16_t s2
Definition: types.hpp:42
OStream & out()
Definition: OStream.cpp:39
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
basicblock ** successors
Definition: jit.hpp:340
const parseddesc_t parseddesc
Definition: references.hpp:105
#define INSTRUCTION_IS_RESOLVED(iptr)
functionptr fp
Definition: builtin.hpp:63
fieldinfo * field
Definition: references.hpp:100
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
Definition: logging.hpp:133
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
Nl nl
Definition: OStream.cpp:56
Type type
Definition: jit.hpp:322
#define INSTRUCTION_GET_METHODREF(iptr, mref)
#define INSTRUCTION_MUST_CHECK(iptr)
LoopTreeGraph * parent
branch_target_t * table
#define INS_FLAG_ID_SHIFT