47 #define DEBUG_NAME "compiler2/SSAConstruction"
50 STAT_REGISTER_GROUP_VAR(std::
size_t,num_trivial_phis,0,"
# trivial phis","number of trivial phis",compiler2_stat)
52 "ICMD instructions processed (by the compiler2)",compiler2_stat)
64 std::size_t in_var_index;
65 SSAConstructionPass *
parent;
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) {}
73 void fill_operands() {
78 s4 pred_nr = pred->
nr;
81 phi->append_op(parent->read_variable(var,pred_nr));
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;
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];
99 v = read_variable_recursive(varindex, bb);
101 LOG2(
"Value: " << v <<
nl);
105 Value* SSAConstructionPass::read_variable_recursive(
size_t varindex,
size_t bb) {
107 if(
BB[bb]->pred_size() == 0) {
108 ABORT_MSG(
"no predecessor ",
"basic block " << bb <<
" var index " << varindex);
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);
116 }
else if (
BB[bb]->pred_size() == 1) {
118 BeginInst *pred = *(
BB[bb]->pred_begin());
119 val = read_variable(varindex, beginToIndex[pred]);
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);
126 assert(val->to_Instruction());
128 write_variable(varindex, bb, val);
132 Value* SSAConstructionPass::add_phi_operands(
size_t varindex, PHIInst *phi) {
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]));
139 return try_remove_trivial_phi(phi);
142 Value* SSAConstructionPass::try_remove_trivial_phi(PHIInst *phi) {
144 for(Instruction::OperandListTy::const_iterator
i = phi->op_begin(),
145 e = phi->op_end();
i !=
e; ++
i) {
147 if ( (op == same) || (op == (
Value*)phi) ) {
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);
169 alloc::list<Instruction*>::type users(phi->user_begin(),phi->user_end());
171 phi->replace_value(same);
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;
182 M->remove_Instruction(phi);
184 for(alloc::list<Instruction*>::type::iterator
i = users.begin(), e = users.end();
187 PHIInst *p = (*i)->to_PHIInst();
189 try_remove_trivial_phi(p);
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];
202 add_phi_operands(
i,phi);
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;
212 bool SSAConstructionPass::try_seal_block(
basicblock *bb) {
213 if (sealed_blocks[bb->
nr])
216 LOG(
"try sealing basic block: " << bb->
nr <<
nl);
219 if (!filled_blocks[pred_bbindex] && !skipped_blocks[pred_bbindex]) {
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) {
240 }
else if ( (I = v->to_Instruction()) ) {
241 out() <<
setw(max) << I->get_name();
250 void SSAConstructionPass::install_javalocal_dependencies(
251 SourceStateInst *source_state,
256 s4 varindex = javalocals[
i];
262 Value *v = read_variable(
263 static_cast<size_t>(varindex),
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);
278 void SSAConstructionPass::install_stackvar_dependencies(
279 SourceStateInst *source_state,
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),
291 if (stack_index < paramcount) {
292 source_state->append_param(v);
293 LOG(
"register param " << varindex <<
" " << v
294 <<
" at " << source_state <<
nl);
296 source_state->append_stackvar(v);
297 LOG(
"register stackvar " << varindex <<
" " << v
298 <<
" at " << source_state <<
nl);
303 SourceStateInst *SSAConstructionPass::record_source_state(
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);
319 void SSAConstructionPass::deoptimize(
int 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;
327 bool SSAConstructionPass::skipped_all_predecessors(
basicblock *bb) {
330 if (visited_blocks[pred->
nr] && !skipped_blocks[pred->
nr]) {
337 void SSAConstructionPass::remove_unreachable_blocks() {
338 alloc::vector<BeginInst*>::type unreachable_blocks;
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);
348 while (!unreachable_blocks.empty()) {
349 BeginInst *begin = unreachable_blocks.back();
350 unreachable_blocks.pop_back();
352 LOG(
"Remove unreachable block " << begin <<
nl);
353 EndInst *end = begin->get_EndInst();
355 M->remove_Instruction(end);
360 CONSTInst *SSAConstructionPass::parse_s2_constant(
instruction *iptr, Type::TypeID type) {
364 case Type::IntTypeID:
365 konst =
new CONSTInst(static_cast<int32_t>(iptr->
sx.
s23.s2.constval),
368 case Type::LongTypeID:
369 konst =
new CONSTInst(static_cast<int64_t>(iptr->
sx.
s23.s2.constval),
380 bool SSAConstructionPass::run(JITData &JD) {
382 LOG(
"SSAConstructionPass: " << *
M <<
nl);
385 jd = JD.get_jitdata();
406 unsigned int num_basicblocks = jd->basicblockcount;
407 unsigned int init_basicblock = 0;
413 visited_blocks.clear();
414 visited_blocks.resize(num_basicblocks,
false);
416 skipped_blocks.clear();
417 skipped_blocks.resize(num_basicblocks,
false);
419 assert(jd->basicblockcount);
424 init_basicblock = jd->basicblockcount;
425 LOG(
"Extra basic block added (index = " << init_basicblock <<
")" <<
nl);
429 beginToIndex.clear();
431 BB.resize(num_basicblocks, NULL);
432 for(std::size_t
i = 0;
i < num_basicblocks; ++
i) {
433 BeginInst *bi =
new BeginInst();
435 beginToIndex.insert(std::make_pair(bi,
i));
439 std::size_t global_state = jd->vartop;
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);
449 current_def.resize(global_state+1,alloc::vector<Value*>::type(num_basicblocks,NULL));
451 sealed_blocks.clear();
452 sealed_blocks.resize(num_basicblocks,
false);
454 filled_blocks.clear();
455 filled_blocks.resize(num_basicblocks,
false);
457 var_type_tbl.clear();
458 var_type_tbl.resize(global_state+1,Type::VoidTypeID);
461 for(
size_t i = 0,
e = jd->vartop;
i !=
e ; ++
i) {
466 var_type_tbl[global_state] = Type::GlobalStateTypeID;
474 M->add_bb(
BB[init_basicblock]);
479 int varindex = jd->local_map[
slot * 5 + type];
485 write_variable(varindex,init_basicblock,I);
486 M->add_Instruction(I);
499 BeginInst *targetBlock =
BB[0];
500 Instruction *result =
new GOTOInst(
BB[init_basicblock], targetBlock);
501 M->add_Instruction(result);
503 filled_blocks[init_basicblock] =
true;
504 sealed_blocks[init_basicblock] =
true;
508 M->set_init_bb(
BB[init_basicblock]);
510 current_def[global_state][init_basicblock] =
BB[init_basicblock];
514 #if defined(ENABLE_LOGGING)
516 for(alloc::vector<BeginInst*>::type::iterator
i =
BB.begin(),
e =
BB.end();
519 LOG(
"BB: " << (
void*)v <<
nl);
522 for(
size_t i = 0,
e = jd->vartop;
i !=
e ; ++
i) {
527 LOG(
"# variables: " << jd->vartop <<
nl);
528 LOG(
"# javalocals: " << jd->localcount <<
nl);
535 <<
" (index " <<
i <<
")"
536 <<
" (var_local " << jd->local_map[
i * 5 + type] <<
")" <<
nl);
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];
556 visited_blocks[bb->
nr] =
true;
560 assert(bb->
nr == jd->basicblockcount);
568 skipped_blocks[bb->
nr] =
true;
569 DeoptimizeInst *deopt =
new DeoptimizeInst(
BB[bb->
nr]);
570 M->add_Instruction(deopt);
573 std::size_t bbindex = (std::size_t)bb->
nr;
575 LOG(
"basicblock: " << bbindex <<
nl);
577 if (!skipped_blocks[bbindex]) {
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));
587 InVarPhis invar(phi, jd, bbindex,
i,
this);
588 invar.fill_operands();
590 M->add_Instruction(phi);
596 M->add_bb(
BB[bbindex]);
600 current_def[global_state][bbindex] =
BB[bbindex];
603 assert((jd->maxlocals > 0) == (bb->
javalocals != NULL));
606 if (!skipped_blocks[bbindex]) {
609 SourceStateInst *source_state = record_source_state(
BB[bbindex],
612 #if defined(ENABLE_COUNTDOWN_TRAPS)
617 ReplacementEntryInst *rplentry =
new ReplacementEntryInst(
BB[bbindex], source_state);
618 M->add_Instruction(rplentry);
625 if (skipped_blocks[bb->
nr]) {
634 Instruction *old_global_state = read_variable(global_state,bbindex)->to_Instruction();
635 Instruction *new_global_state = NULL;
658 type = Type::IntTypeID;
661 type = Type::LongTypeID;
664 type = Type::FloatTypeID;
667 type = Type::DoubleTypeID;
671 type = Type::VoidTypeID;
673 Instruction *result =
new NEGInst(type,s1);
675 M->add_Instruction(result);
682 Instruction *array_length =
new ARRAYLENGTHInst(arrayref);
683 M->add_Instruction(array_length);
684 write_variable(iptr->
dst.
varindex, bbindex, array_length);
704 Type::TypeID type_to;
707 type_to = Type::ShortTypeID;
710 type_to = Type::CharTypeID;
713 type_to = Type::ByteTypeID;
716 type_to = Type::LongTypeID;
719 type_to = Type::FloatTypeID;
722 type_to = Type::DoubleTypeID;
725 type_to = Type::IntTypeID;
728 type_to = Type::FloatTypeID;
731 type_to = Type::DoubleTypeID;
734 type_to = Type::IntTypeID;
737 type_to = Type::LongTypeID;
740 type_to = Type::DoubleTypeID;
743 type_to = Type::IntTypeID;
746 type_to = Type::LongTypeID;
749 type_to = Type::FloatTypeID;
753 type_to = Type::VoidTypeID;
755 Instruction *result =
new CASTInst(type_to, s1);
757 M->add_Instruction(result);
766 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
770 type = Type::IntTypeID;
773 type = Type::LongTypeID;
776 type = Type::FloatTypeID;
779 type = Type::DoubleTypeID;
782 type = Type::VoidTypeID;
784 Instruction *result =
new ADDInst(type, s1, s2);
786 M->add_Instruction(result);
795 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
799 type = Type::IntTypeID;
802 type = Type::LongTypeID;
805 type = Type::FloatTypeID;
808 type = Type::DoubleTypeID;
811 type = Type::VoidTypeID;
813 Instruction *result =
new SUBInst(type, s1, s2);
815 M->add_Instruction(result);
824 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
828 type = Type::IntTypeID;
831 type = Type::LongTypeID;
834 type = Type::FloatTypeID;
837 type = Type::DoubleTypeID;
840 type = Type::VoidTypeID;
842 Instruction *result =
new MULInst(type, s1, s2);
844 M->add_Instruction(result);
853 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
857 type = Type::IntTypeID;
860 type = Type::LongTypeID;
863 type = Type::FloatTypeID;
866 type = Type::DoubleTypeID;
869 type = Type::VoidTypeID;
871 Instruction *result =
new DIVInst(type, s1, s2);
873 M->add_Instruction(result);
882 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
886 type = Type::IntTypeID;
889 type = Type::LongTypeID;
892 type = Type::FloatTypeID;
895 type = Type::DoubleTypeID;
898 type = Type::VoidTypeID;
900 Instruction *result =
new REMInst(type, s1, s2);
902 M->add_Instruction(result);
923 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
931 type = Type::IntTypeID;
936 type = Type::LongTypeID;
939 type = Type::VoidTypeID;
945 result =
new ANDInst(type, s1, s2);
949 result =
new ORInst(type, s1, s2);
953 result =
new XORInst(type, s1, s2);
959 M->add_Instruction(result);
969 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
970 CMPInst::FloatHandling handling;
974 handling = CMPInst::L;
978 handling = CMPInst::G;
981 handling = CMPInst::DontCare;
983 Instruction *result =
new CMPInst(s1, s2, handling);
985 M->add_Instruction(result);
994 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
i,Type::IntType());
998 result =
new ADDInst(Type::IntTypeID, s1, konst);
1001 result =
new SUBInst(Type::IntTypeID, s1, konst);
1006 M->add_Instruction(konst);
1007 write_variable(iptr->
dst.
varindex,bbindex,result);
1008 M->add_Instruction(result);
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);
1023 deoptimize(bbindex);
1031 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
i,Type::IntType());
1032 Instruction *result;
1033 switch (iptr->
opc) {
1035 result =
new ANDInst(Type::IntTypeID, s1, konst);
1038 result =
new DIVInst(Type::IntTypeID, s1, konst);
1041 result =
new REMInst(Type::IntTypeID, s1, konst);
1046 M->add_Instruction(konst);
1047 write_variable(iptr->
dst.
varindex,bbindex,result);
1048 M->add_Instruction(result);
1067 deoptimize(bbindex);
1077 switch (iptr->
opc) {
1079 type = Type::IntTypeID;
1080 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::IntType());
1085 type = Type::ByteTypeID;
1086 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::ByteType());
1089 type = Type::CharTypeID;
1090 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::CharType());
1093 type = Type::ShortTypeID;
1094 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::ShortType());
1097 type = Type::ReferenceTypeID;
1098 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::ReferenceType());
1102 type = Type::LongTypeID;
1103 konst =
new CONSTInst(iptr->
sx.
s23.s3.constval,Type::LongType());
1107 type = Type::VoidTypeID;
1110 M->add_Instruction(konst);
1112 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1113 assert(state_change);
1115 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(arrayref, index);
1116 M->add_Instruction(boundscheck);
1118 Instruction *ref =
new AREFInst(type, arrayref, index,
BB[bbindex]);
1119 ref->append_dep(boundscheck);
1120 M->add_Instruction(ref);
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);
1133 switch (iptr->
opc) {
1135 I =
new CONSTInst(iptr->
sx.
val.
i,Type::IntType());
1138 I =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
1141 I =
new CONSTInst(iptr->
sx.
val.
f,Type::FloatType());
1144 I =
new CONSTInst(iptr->
sx.
val.
d,Type::DoubleType());
1151 M->add_Instruction(I);
1158 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
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);
1168 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
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);
1178 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
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);
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);
1198 deoptimize(bbindex);
1204 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
1205 Instruction *result;
1206 switch (iptr->
opc) {
1209 result =
new SUBInst(Type::LongTypeID, s1, konst);
1214 M->add_Instruction(konst);
1215 write_variable(iptr->
dst.
varindex,bbindex,result);
1216 M->add_Instruction(result);
1227 deoptimize(bbindex);
1231 Instruction *I =
new CONSTInst(iptr->
sx.
val.
anyptr, Type::ReferenceType());
1233 M->add_Instruction(I);
1239 deoptimize(bbindex);
1247 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1248 assert(state_change);
1253 Instruction *getfield =
new GETFIELDInst(type, objectref, field,
BB[bbindex],
1255 M->add_Instruction(getfield);
1256 write_variable(iptr->
dst.
varindex, bbindex, getfield);
1257 write_variable(global_state, bbindex, getfield);
1264 deoptimize(bbindex);
1272 Instruction *state_change = read_variable(global_state, bbindex)->to_Instruction();
1273 assert(state_change);
1280 CONSTInst *konst = parse_s2_constant(iptr, type);
1282 M->add_Instruction(konst);
1284 value = read_variable(iptr->
sx.
s23.s2.varindex, bbindex);
1287 Instruction *putfield =
new PUTFIELDInst(objectref, value, field,
BB[bbindex],
1289 M->add_Instruction(putfield);
1290 write_variable(global_state, bbindex, putfield);
1296 deoptimize(bbindex);
1305 deoptimize(bbindex);
1309 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1310 assert(state_change);
1313 Instruction *getstatic =
new GETSTATICInst(type, field,
1314 BB[bbindex], state_change);
1316 write_variable(iptr->
dst.
varindex, bbindex, getstatic);
1317 write_variable(global_state, bbindex, getstatic);
1319 M->add_Instruction(getstatic);
1326 deoptimize(bbindex);
1335 deoptimize(bbindex);
1339 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1340 assert(state_change);
1346 CONSTInst *konst = parse_s2_constant(iptr, type);
1348 M->add_Instruction(konst);
1350 value = read_variable(iptr->
s1.
varindex,bbindex);
1353 Instruction *putstatic =
new PUTSTATICInst(value, field,
1354 BB[bbindex], state_change);
1356 write_variable(global_state, bbindex, putstatic);
1358 M->add_Instruction(putstatic);
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);
1382 Value *value = read_variable(iptr->
sx.
s23.s3.varindex,bbindex);
1385 switch (iptr->
opc) {
1387 type = Type::ByteTypeID;
1390 type = Type::CharTypeID;
1393 type = Type::ShortTypeID;
1396 type = Type::IntTypeID;
1399 type = Type::LongTypeID;
1402 type = Type::ReferenceTypeID;
1405 type = Type::FloatTypeID;
1408 type = Type::DoubleTypeID;
1412 type = Type::VoidTypeID;
1415 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1416 assert(state_change);
1418 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(arrayref, index);
1419 M->add_Instruction(boundscheck);
1421 Instruction *ref =
new AREFInst(value->get_type(), arrayref,
index,
BB[bbindex]);
1422 ref->append_dep(boundscheck);
1423 M->add_Instruction(ref);
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);
1442 switch (iptr->
opc) {
1444 type = Type::ByteTypeID;
1447 type = Type::CharTypeID;
1450 type = Type::ShortTypeID;
1453 type = Type::IntTypeID;
1456 type = Type::LongTypeID;
1459 type = Type::ReferenceTypeID;
1462 type = Type::FloatTypeID;
1465 type = Type::DoubleTypeID;
1469 type = Type::VoidTypeID;
1472 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1473 assert(state_change);
1475 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(arrayref, index);
1476 M->add_Instruction(boundscheck);
1478 Instruction *ref =
new AREFInst(type, arrayref, index,
BB[bbindex]);
1479 ref->append_dep(boundscheck);
1480 M->add_Instruction(ref);
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);
1490 deoptimize(bbindex);
1517 deoptimize(bbindex);
1526 deoptimize(bbindex);
1534 md = iptr->
sx.
s23.s3.bte->md;
1544 type = Type::IntTypeID;
1547 type = Type::LongTypeID;
1550 type = Type::FloatTypeID;
1553 type = Type::DoubleTypeID;
1556 type = Type::VoidTypeID;
1559 type = Type::ReferenceTypeID;
1564 type = Type::VoidTypeID;
1567 <<
" not yet supported! (see vm/global.h)" <<
nl;
1571 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1572 assert(state_change);
1574 SourceStateInst *source_state = record_source_state(
BB[bbindex],
1578 INVOKEInst *invoke = NULL;
1580 switch (iptr->
opc) {
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);
1590 invoke =
new INVOKESPECIALInst(type,argcount,fmiref,
BB[bbindex],state_change,source_state);
1591 invoke->append_dep(null_check);
1596 invoke =
new INVOKEVIRTUALInst(type,argcount,fmiref,
BB[bbindex],state_change,source_state);
1601 invoke =
new INVOKESTATICInst(type,argcount,fmiref,
BB[bbindex],state_change,source_state);
1606 invoke =
new INVOKEINTERFACEInst(type,argcount,fmiref,
BB[bbindex],state_change,source_state);
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);
1622 s4 *args = iptr->
sx.
s23.s2.args;
1623 for (
int i = 0;
i < argcount;
i++) {
1627 invoke->append_parameter(read_variable(args[
i],bbindex));
1630 if (type != Type::VoidTypeID) {
1631 write_variable(iptr->
dst.
varindex,bbindex,invoke);
1634 write_variable(global_state,bbindex,invoke);
1635 M->add_Instruction(invoke);
1637 LOG3(
"INVOKEInst: " << invoke <<
" dep = " << state_change <<
nl);
1647 Conditional::CondID cond;
1648 switch (iptr->
opc) {
1650 cond = Conditional::LT;
1653 cond = Conditional::GT;
1656 cond = Conditional::EQ;
1659 cond = Conditional::NE;
1662 cond = Conditional::LE;
1665 cond = Conditional::GE;
1669 cond = Conditional::NoCond;
1671 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
i,Type::IntType());
1675 if (s1->get_type() != konst->get_type()) {
1676 deoptimize(bbindex);
1681 BeginInst *trueBlock =
BB[iptr->
dst.
block->
nr]->to_BeginInst();
1683 assert(
BB[bbindex+1]);
1684 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
1686 Instruction *result =
new IFInst(
BB[bbindex], s1, konst, cond,
1687 trueBlock, falseBlock);
1688 M->add_Instruction(konst);
1689 M->add_Instruction(result);
1699 Conditional::CondID cond;
1700 switch (iptr->
opc) {
1702 cond = Conditional::LT;
1705 cond = Conditional::GT;
1708 cond = Conditional::LE;
1711 cond = Conditional::EQ;
1714 cond = Conditional::NE;
1717 cond = Conditional::GE;
1721 cond = Conditional::NoCond;
1723 Instruction *konst =
new CONSTInst(iptr->
sx.
val.
l,Type::LongType());
1727 if (s1->get_type() != konst->get_type()) {
1728 deoptimize(bbindex);
1733 BeginInst *trueBlock =
BB[iptr->
dst.
block->
nr]->to_BeginInst();
1735 assert(
BB[bbindex+1]);
1736 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
1738 Instruction *result =
new IFInst(
BB[bbindex], s1, konst, cond,
1739 trueBlock, falseBlock);
1740 M->add_Instruction(konst);
1741 M->add_Instruction(result);
1748 Instruction *result =
new GOTOInst(
BB[bbindex], targetBlock);
1749 M->add_Instruction(result);
1756 deoptimize(bbindex);
1766 Conditional::CondID cond;
1767 switch (iptr->
opc) {
1769 cond = Conditional::LE;
1772 cond = Conditional::EQ;
1775 cond = Conditional::NE;
1778 cond = Conditional::LT;
1781 cond = Conditional::GE;
1784 cond = Conditional::GT;
1788 cond = Conditional::NoCond;
1791 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
1795 if (s1->get_type() != s2->get_type()) {
1796 deoptimize(bbindex);
1801 BeginInst *trueBlock =
BB[iptr->
dst.
block->
nr]->to_BeginInst();
1803 assert(
BB[bbindex+1]);
1804 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
1806 Instruction *result =
new IFInst(
BB[bbindex], s1, s2, cond,
1807 trueBlock, falseBlock);
1808 M->add_Instruction(result);
1818 Conditional::CondID cond;
1819 switch (iptr->
opc) {
1821 cond = Conditional::EQ;
1824 cond = Conditional::NE;
1827 cond = Conditional::LT;
1830 cond = Conditional::GT;
1833 cond = Conditional::GE;
1836 cond = Conditional::LE;
1839 cond = Conditional::NoCond;
1843 Value *
s2 = read_variable(iptr->
sx.
s23.s2.varindex,bbindex);
1847 if (s1->get_type() != s2->get_type()) {
1848 deoptimize(bbindex);
1853 BeginInst *trueBlock =
BB[iptr->
dst.
block->
nr]->to_BeginInst();
1855 assert(
BB[bbindex+1]);
1856 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
1858 Instruction *result =
new IFInst(
BB[bbindex], s1, s2, cond,
1859 trueBlock, falseBlock);
1860 M->add_Instruction(result);
1866 deoptimize(bbindex);
1871 s4 tablehigh = iptr->
sx.
s23.s3.tablehigh;
1872 s4 tablelow = iptr->
sx.
s23.s2.tablelow;
1875 TABLESWITCHInst *result =
new TABLESWITCHInst(
BB[bbindex], s1,
1876 TABLESWITCHInst::LOW(tablelow),
1877 TABLESWITCHInst::HIGH(tablehigh));
1879 s4 count = tablehigh - tablelow + 1;
1880 LOG(
"tableswitch high=" << tablehigh <<
" low=" << tablelow <<
" count=" << count <<
nl);
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);
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]);
1891 result->append_succ(def);
1892 M->add_Instruction(result);
1897 s4 lookupcount = iptr->
sx.
s23.s2.lookupcount;
1900 LOOKUPSWITCHInst *result =
new LOOKUPSWITCHInst(
BB[bbindex], s1, lookupcount);
1904 for (
s4 i = 0;
i < lookupcount; ++
i) {
1907 result->set_match(
i, LOOKUPSWITCHInst::MATCH(lookup->
value));
1911 BeginInst *defaultBlock =
BB[iptr->
sx.
s23.s3.lookupdefault.block->nr];
1912 assert(defaultBlock);
1913 result->append_succ(defaultBlock);
1915 M->add_Instruction(result);
1925 Instruction *result =
new RETURNInst(
BB[bbindex], s1);
1926 M->add_Instruction(result);
1931 Instruction *result =
new RETURNInst(
BB[bbindex]);
1932 M->add_Instruction(result);
1937 deoptimize(bbindex);
1949 deoptimize(bbindex);
1953 #if !defined(NDEBUG)
1955 "Operation not yet supported!");
1958 "Operation not yet supported!");
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()) {
1967 record_source_state(new_global_state, iptr, bb, live_javalocals,
1968 iptr->stack_after, iptr->stackdepth_after);
1972 if (!
BB[bbindex]->get_EndInst()) {
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);
1981 filled_blocks[bbindex] =
true;
1991 for(
size_t i = 0;
i< num_basicblocks; ++
i) {
1992 if (!sealed_blocks[
i]) {
1994 << i <<
" (" <<
BB[
i] <<
")"
1996 assert(0 &&
"There is an unsealed basic block");
2001 remove_unreachable_blocks();
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;
2014 PassUsage& SSAConstructionPass::get_PassUsage(PassUsage &PU)
const {
2015 PU.add_requires<CFGConstructionPass>();
2020 static PassRegistry<SSAConstructionPass>
X(
"SSAConstructionPass");
jlong jlong jlong jlong jint jmethodID jint slot
static bool instruction_has_side_effects(const instruction *iptr)
JNIEnv jthread jmethodID jlocation jclass jobject jfieldID field
#define STATISTICS(x)
Wrapper for statistics only code.
static SetWidth setw(size_t w)
union constant_FMIref::@26 p
#define DEBUG_COND_N(VERBOSE)
JNIEnv jthread jobject jclass jlong size
#define MCOPY(dest, src, type, num)
basicblock ** predecessors
alloc::list< PassInfo::IDTy >::type & stack
This file contains the statistics framework.
#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.
Type::TypeID convert_to_typeid(int type)
Convert a Type to a Type::TypeID.
Fieldref, Methodref and InterfaceMethodref.
#define FOR_EACH_BASICBLOCK(jd, it)
union instruction::@12 sx
void stack_javalocals_store(instruction *iptr, s4 *javalocals)
icmdtable_entry_t icmd_table[256]
#define LOG(STMT)
Analogous to DEBUG.
Represents the result of the addition of a certain IR-variable with a certain constant.
const char * get_type_name(int type)
Get the printable name of the type.
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
static void * allocate(size_t size)
#define FOR_EACH_INSTRUCTION(bptr, it)
static void shouldnotreach()
static bool class_is_or_almost_initialized(classinfo *c)
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
const parseddesc_t parseddesc
#define INSTRUCTION_IS_RESOLVED(iptr)
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
#define INSTRUCTION_GET_METHODREF(iptr, mref)
#define INSTRUCTION_MUST_CHECK(iptr)
#define INS_FLAG_ID_SHIFT