44 #define DEBUG_NAME "compiler2/SSAConstruction"
47 STAT_REGISTER_GROUP_VAR(std::
size_t,num_trivial_phis,0,"
# trivial phis","number of trivial phis",compiler2_stat)
49 "ICMD instructions processed (by the compiler2)",compiler2_stat)
56 OStream& show_variable_intern_OS(OStream &
OS,
const jitdata *jd,
s4 index,
int stage)
62 if (index < 0 || index >= jd->
vartop) {
63 OS <<
"<INVALID INDEX:" << index <<
">";
79 if (index < jd->localcount) {
82 OS <<
"<INVALID FLAGS!>";
92 OS <<
"<INVALID FLAGS!>";
101 printf(
"%c%c%d", kind, type, index);
102 OS << kind << type <<
index;
109 OS <<
"TODO: show_allocation(v->type, v->flags, v->vv.regoff);";
122 #define SHOW_TARGET(OS, target) \
123 if (stage >= SHOW_PARSE) { \
124 OS << "--> L" << setw(3) << (target).block->nr; \
127 OS << "--> insindex " << (target).insindex; \
130 #define SHOW_INT_CONST(OS, val) \
131 if (stage >= SHOW_PARSE) { \
132 OS << (int32_t) (val) << "0x" << hex << setw(8) << (int32_t) (val) << dec; \
138 #define SHOW_LNG_CONST(OS, val) \
139 if (stage >= SHOW_PARSE) \
140 OS << (val) << "0x" << hex << setw(16) << (val) << dec;\
144 #define SHOW_ADR_CONST(OS, val) \
145 if (stage >= SHOW_PARSE) \
146 OS << "0x" << hex << setw(8) << (ptrint) (val) << dec; \
150 #define SHOW_FLT_CONST(OS, val) \
151 if (stage >= SHOW_PARSE) { \
154 OS << (val) << hex << setw(8) << v.i << dec; \
160 #define SHOW_DBL_CONST(OS, val) \
161 if (stage >= SHOW_PARSE) { \
164 OS << (val) << hex << setw(16) << v.l << dec; \
169 #define SHOW_INDEX(OS, index) \
170 if (stage >= SHOW_PARSE) { \
177 #define SHOW_STRING(OS, val) \
178 if (stage >= SHOW_PARSE) { \
180 OS << (Utf8String)JavaString((java_handle_t*) (val)).to_utf8();\
187 #define SHOW_CLASSREF_OR_CLASSINFO(OS, c) \
188 if (stage >= SHOW_PARSE) { \
189 if (IS_CLASSREF(c)) \
190 class_classref_print(c.ref); \
192 class_print(c.cls); \
199 #define SHOW_CLASSREF_OR_CLASSINFO(OS, c) \
200 if (stage >= SHOW_PARSE) { \
201 OS << "class (TODO)"; \
208 #define SHOW_FIELD(OS, fmiref) \
209 if (stage >= SHOW_PARSE) { \
210 field_fieldref_print(fmiref); \
217 #define SHOW_FIELD(OS, fmiref) \
218 if (stage >= SHOW_PARSE) { \
219 OS << "field (TODO)"; \
226 #define SHOW_VARIABLE(OS, v) \
227 show_variable_intern_OS(OS, jd, (v), stage)
229 #define SHOW_S1(OS, iptr) \
230 if (stage >= SHOW_STACK) { \
231 SHOW_VARIABLE(OS, iptr->s1.varindex); \
234 #define SHOW_S2(OS, iptr) \
235 if (stage >= SHOW_STACK) { \
236 SHOW_VARIABLE(OS, iptr->sx.s23.s2.varindex); \
239 #define SHOW_S3(OS, iptr) \
240 if (stage >= SHOW_STACK) { \
241 SHOW_VARIABLE(OS, iptr->sx.s23.s3.varindex); \
244 #define SHOW_DST(OS, iptr) \
245 if (stage >= SHOW_STACK) { \
247 SHOW_VARIABLE(OS, iptr->dst.varindex); \
250 #define SHOW_S1_LOCAL(OS, iptr) \
251 if (stage >= SHOW_STACK) { \
252 OS << "L" << iptr->s1.varindex; \
255 OS << "JavaL" << iptr->s1.varindex << " "; \
258 #define SHOW_DST_LOCAL(OS, iptr) \
259 if (stage >= SHOW_STACK) { \
260 OS << "=> L" << iptr->dst.varindex << " "; \
263 OS << "=> JavaL" << iptr->dst.varindex << " "; \
289 OS <<
"(UNRESOLVED) ";
540 printf(
" (javaindex %d)", iptr->
sx.
s23.s3.javaindex);
560 argp = iptr->
sx.
s23.s2.args;
590 #if defined(ENABLE_INLINING)
593 show_inline_info(jd, ii, opcode, stage);
601 argp = iptr->
sx.
s23.s2.args;
604 if ((iptr->
s1.
argcount - 1 - i) == iptr->
sx.
s23.s3.bte->md->paramcount)
605 printf(
" pass-through: ");
622 argp = iptr->
sx.
s23.s2.args;
626 printf(
" pass-through: ");
700 i = iptr->
sx.
s23.s3.tablehigh - iptr->
sx.
s23.s2.tablelow + 1;
702 printf(
"high=%d low=%d count=%d\n", iptr->
sx.
s23.s3.tablehigh, iptr->
sx.
s23.s2.tablelow, i);
714 printf(
"count=%d, default=L%03d\n",
715 iptr->
sx.
s23.s2.lookupcount,
716 iptr->
sx.
s23.s3.lookupdefault.block->nr);
719 i = iptr->
sx.
s23.s2.lookupcount;
722 printf(
"\t\t%d --> L%03d\n",
755 #if defined(ENABLE_SSA)
763 if (iptr->
flags.
bits & (1 << 0)) OS <<
"used ";
764 if (iptr->
flags.
bits & (1 << 1)) OS <<
"redundantAll ";
765 if (iptr->
flags.
bits & (1 << 2)) OS <<
"redundantOne ";
776 namespace compiler2 {
783 std::size_t in_var_index;
784 SSAConstructionPass *
parent;
787 InVarPhis(PHIInst *phi,
jitdata *jd, std::size_t bb_num, std::size_t in_var_index,
788 SSAConstructionPass *
parent)
789 : phi(phi), jd(jd), bb_num(bb_num), in_var_index(in_var_index),
parent(parent) {}
792 void fill_operands() {
797 s4 pred_nr = pred->
nr;
800 phi->append_op(parent->read_variable(var,pred_nr));
805 void SSAConstructionPass::write_variable(
size_t varindex,
size_t bb,
Value* v) {
806 LOG2(
"write variable(" << varindex <<
"," << bb <<
") = " << v <<
nl);
807 current_def[varindex][bb] = v;
810 Value* SSAConstructionPass::read_variable(
size_t varindex,
size_t bb) {
811 LOG2(
"read variable(" << varindex <<
"," << bb <<
")" <<
nl);
812 Value* v = current_def[varindex][bb];
819 return read_variable_recursive(varindex, bb);
826 v = read_variable_recursive(varindex, bb);
828 LOG2(
"Value: " << v <<
nl);
832 Value* SSAConstructionPass::read_variable_recursive(
size_t varindex,
size_t bb) {
834 if(
BB[bb]->pred_size() == 0) {
842 case Type::IntTypeID:
843 konst =
new CONSTInst(0,Type::IntType());
845 case Type::LongTypeID:
846 konst =
new CONSTInst(0,Type::LongType());
848 case Type::FloatTypeID:
849 konst =
new CONSTInst(0,Type::FloatType());
851 case Type::DoubleTypeID:
852 konst =
new CONSTInst(0,Type::DoubleType());
857 ERROR_MSG(
"no predecessor ",
"basic block " << bb <<
" var index " << varindex
858 <<
" constant: " << konst );
859 M->add_Instruction(konst);
862 ABORT_MSG(
"no predecessor ",
"basic block " << bb <<
" var index " << varindex);
865 if (!sealed_blocks[bb]) {
866 PHIInst *phi =
new PHIInst(var_type_tbl[varindex],
BB[bb]);
867 incomplete_phi[bb][varindex] = phi;
868 M->add_Instruction(phi);
870 }
else if (
BB[bb]->pred_size() == 1) {
872 BeginInst *pred = *(
BB[bb]->pred_begin());
873 val = read_variable(varindex, beginToIndex[pred]);
875 PHIInst *phi =
new PHIInst(var_type_tbl[varindex],
BB[bb]);
876 write_variable(varindex, bb, phi);
877 M->add_Instruction(phi);
878 val = add_phi_operands(varindex, phi);
880 assert(val->to_Instruction());
882 write_variable(varindex, bb, val);
886 Value* SSAConstructionPass::add_phi_operands(
size_t varindex, PHIInst *phi) {
888 BeginInst *
BI = phi->get_BeginInst();
889 for (BeginInst::PredecessorListTy::const_iterator
i = BI->pred_begin(),
890 e = BI->pred_end();
i !=
e; ++
i) {
892 phi->append_op(read_variable(varindex,beginToIndex[*
i]));
894 return try_remove_trivial_phi(phi);
897 Value* SSAConstructionPass::try_remove_trivial_phi(PHIInst *phi) {
899 for(Instruction::OperandListTy::const_iterator
i = phi->op_begin(),
900 e = phi->op_end();
i !=
e; ++
i) {
902 if ( (op == same) || (op == (
Value*)phi) ) {
915 for (std::size_t
i = 0,
e = current_def.size();
i <
e; ++
i) {
916 for (std::size_t j = 0, e = current_def[
i].
size(); j <
e; ++j) {
917 if (current_def[
i][j] == phi) {
918 LOG2(
"current_def["<<
i<<
"]["<<j<<
"] will be invalid" <<
nl);
924 alloc::list<Instruction*>::type users(phi->user_begin(),phi->user_end());
926 phi->replace_value(same);
929 for (std::size_t
i = 0,
e = current_def.size();
i <
e; ++
i) {
930 for (std::size_t j = 0, e = current_def[
i].
size(); j <
e; ++j) {
931 if (current_def[
i][j] == phi) {
932 current_def[
i][j] = same;
937 M->remove_Instruction(phi);
939 for(alloc::list<Instruction*>::type::iterator
i = users.begin(), e = users.end();
942 PHIInst *p = (*i)->to_PHIInst();
944 try_remove_trivial_phi(p);
951 void SSAConstructionPass::seal_block(
size_t bb) {
952 LOG(
"sealing basic block: " << bb <<
nl);
953 alloc::vector<PHIInst*>::type &inc_phi_bb = incomplete_phi[bb];
954 for (
int i = 0,
e = inc_phi_bb.size();
i !=
e ; ++
i) {
955 PHIInst *phi = inc_phi_bb[
i];
957 add_phi_operands(
i,phi);
960 alloc::list<InVarPhis*>::type &in_var_bb = incomplete_in_phi[bb];
961 std::for_each(in_var_bb.begin(),in_var_bb.end(),
962 std::mem_fun(&InVarPhis::fill_operands));
963 sealed_blocks[bb] =
true;
967 bool SSAConstructionPass::try_seal_block(
basicblock *bb) {
968 if (sealed_blocks[bb->
nr])
971 LOG(
"try sealing basic block: " << bb->
nr <<
nl);
988 void SSAConstructionPass::print_current_def()
const {
989 for(alloc::vector<alloc::vector<Value*>::type >::type::const_iterator
i = current_def.begin(),
990 e = current_def.end();
i !=
e ; ++
i) {
991 for(alloc::vector<Value*>::type::const_iterator ii = (*i).begin(),
992 ee = (*i).end(); ii != ee ; ++ii) {
998 }
else if ( (I = v->to_Instruction()) ) {
999 out() <<
setw(max) << I->get_name();
1001 out() <<
setw(max) <<
"VALUE";
1008 bool SSAConstructionPass::run(JITData &JD) {
1009 M = JD.get_Method();
1010 LOG(
"SSAConstructionPass: " << *
M <<
nl);
1013 jd = JD.get_jitdata();
1034 unsigned int num_basicblocks = jd->basicblockcount;
1035 unsigned int init_basicblock = 0;
1038 assert(jd->basicblockcount);
1039 if (extra_init_bb) {
1043 init_basicblock = jd->basicblockcount;
1044 LOG(
"Extra basic block added (index = " << init_basicblock <<
")" <<
nl);
1048 beginToIndex.clear();
1050 BB.resize(num_basicblocks, NULL);
1051 for(std::size_t
i = 0;
i < num_basicblocks; ++
i) {
1052 BeginInst *bi =
new BeginInst();
1054 beginToIndex.insert(std::make_pair(bi,
i));
1058 std::size_t global_state = jd->vartop;
1061 incomplete_phi.clear();
1062 incomplete_phi.resize(num_basicblocks,alloc::vector<PHIInst*>::type(global_state + 1,NULL));
1063 incomplete_in_phi.clear();
1064 incomplete_in_phi.resize(num_basicblocks);
1067 current_def.clear();
1068 current_def.resize(global_state+1,alloc::vector<Value*>::type(num_basicblocks,NULL));
1070 sealed_blocks.clear();
1071 sealed_blocks.resize(num_basicblocks,
false);
1073 filled_blocks.clear();
1074 filled_blocks.resize(num_basicblocks,
false);
1076 var_type_tbl.clear();
1077 var_type_tbl.resize(global_state+1,Type::VoidTypeID);
1080 for(
size_t i = 0,
e = jd->vartop;
i !=
e ; ++
i) {
1085 var_type_tbl[global_state] = Type::GlobalStateTypeID;
1092 if (extra_init_bb) {
1093 M->add_bb(
BB[init_basicblock]);
1098 int varindex = jd->local_map[
slot * 5 + type];
1104 write_variable(varindex,init_basicblock,I);
1105 M->add_Instruction(I);
1117 if (extra_init_bb) {
1118 BeginInst *targetBlock =
BB[0];
1119 Instruction *result =
new GOTOInst(
BB[init_basicblock], targetBlock);
1120 M->add_Instruction(result);
1122 filled_blocks[init_basicblock] =
true;
1123 sealed_blocks[init_basicblock] =
true;
1127 M->set_init_bb(
BB[init_basicblock]);
1129 current_def[global_state][init_basicblock] =
BB[init_basicblock];
1133 #if defined(ENABLE_LOGGING)
1135 for(alloc::vector<BeginInst*>::type::iterator
i =
BB.begin(),
e =
BB.end();
1137 Instruction *v = *
i;
1138 LOG(
"BB: " << (
void*)v <<
nl);
1141 for(
size_t i = 0,
e = jd->vartop;
i !=
e ; ++
i) {
1146 LOG(
"# variables: " << jd->vartop <<
nl);
1147 LOG(
"# javalocals: " << jd->localcount <<
nl);
1154 <<
" (index " <<
i <<
")"
1155 <<
" (var_local " << jd->local_map[
i * 5 + type] <<
")" <<
nl);
1163 for (
int i = 0;
i < jd->maxlocals; ++
i) {
1164 LOG(
"localindex: " <<
i <<
nl);
1165 for (
int j = 0; j < 5; ++j) {
1166 s4 entry = jd->local_map[
i*5+j];
1177 assert(bb->
nr == jd->basicblockcount);
1183 std::size_t bbindex = (std::size_t)bb->
nr;
1185 LOG(
"basicblock: " << bbindex <<
nl);
1189 std::size_t varindex = bb->
invars[
i];
1190 PHIInst *phi =
new PHIInst(var_type_tbl[varindex],
BB[bbindex]);
1191 write_variable(varindex, bbindex, phi);
1192 if (!sealed_blocks[bbindex]) {
1193 incomplete_in_phi[bbindex].push_back(
new InVarPhis(phi, jd, bbindex,
i,
this));
1196 InVarPhis invar(phi, jd, bbindex,
i,
this);
1197 invar.fill_operands();
1199 M->add_Instruction(phi);
1203 assert(
BB[bbindex]);
1204 M->add_bb(
BB[bbindex]);
1208 current_def[global_state][bbindex] =
BB[bbindex];
1212 #if !defined(NDEBUG)
1215 switch (iptr->opc) {
1231 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1233 switch (iptr->opc) {
1235 type = Type::IntTypeID;
1238 type = Type::LongTypeID;
1241 type = Type::FloatTypeID;
1244 type = Type::DoubleTypeID;
1247 type = Type::VoidTypeID;
1249 Instruction *result =
new NEGInst(type,s1);
1250 write_variable(iptr->dst.varindex,bbindex,result);
1251 M->add_Instruction(result);
1256 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1257 Instruction *result =
new ARRAYLENGTHInst(s1);
1258 write_variable(iptr->dst.varindex,bbindex,result);
1259 M->add_Instruction(result);
1278 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1280 Type::TypeID type_to;
1281 switch (iptr->opc) {
1283 type_to = Type::ShortTypeID;
1286 type_to = Type::CharTypeID;
1289 type_to = Type::ByteTypeID;
1293 type_to = Type::LongTypeID;
1297 type_to = Type::FloatTypeID;
1301 type_to = Type::DoubleTypeID;
1305 type_to = Type::IntTypeID;
1309 type_to = Type::FloatTypeID;
1313 type_to = Type::DoubleTypeID;
1317 type_to = Type::IntTypeID;
1321 type_to = Type::LongTypeID;
1325 type_to = Type::DoubleTypeID;
1329 type_to = Type::IntTypeID;
1333 type_to = Type::LongTypeID;
1337 type_to = Type::FloatTypeID;
1341 type_to = Type::VoidTypeID;
1343 Instruction *result =
new CASTInst(type_to, s1);
1344 write_variable(iptr->dst.varindex,bbindex,result);
1345 M->add_Instruction(result);
1354 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1355 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1357 switch (iptr->opc) {
1359 type = Type::IntTypeID;
1362 type = Type::LongTypeID;
1365 type = Type::FloatTypeID;
1368 type = Type::DoubleTypeID;
1371 type = Type::VoidTypeID;
1373 Instruction *result =
new ADDInst(type, s1, s2);
1374 write_variable(iptr->dst.varindex,bbindex,result);
1375 M->add_Instruction(result);
1383 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1384 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1386 switch (iptr->opc) {
1388 type = Type::IntTypeID;
1391 type = Type::LongTypeID;
1394 type = Type::FloatTypeID;
1397 type = Type::DoubleTypeID;
1400 type = Type::VoidTypeID;
1402 Instruction *result =
new SUBInst(type, s1, s2);
1403 write_variable(iptr->dst.varindex,bbindex,result);
1404 M->add_Instruction(result);
1412 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1413 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1415 switch (iptr->opc) {
1417 type = Type::IntTypeID;
1420 type = Type::LongTypeID;
1423 type = Type::FloatTypeID;
1426 type = Type::DoubleTypeID;
1429 type = Type::VoidTypeID;
1431 Instruction *result =
new MULInst(type, s1, s2);
1432 write_variable(iptr->dst.varindex,bbindex,result);
1433 M->add_Instruction(result);
1441 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1442 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1444 switch (iptr->opc) {
1446 type = Type::IntTypeID;
1449 type = Type::LongTypeID;
1452 type = Type::FloatTypeID;
1455 type = Type::DoubleTypeID;
1458 type = Type::VoidTypeID;
1460 Instruction *result =
new DIVInst(type, s1, s2);
1461 write_variable(iptr->dst.varindex,bbindex,result);
1462 M->add_Instruction(result);
1470 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1471 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1473 switch (iptr->opc) {
1475 type = Type::IntTypeID;
1478 type = Type::LongTypeID;
1481 type = Type::FloatTypeID;
1484 type = Type::DoubleTypeID;
1487 type = Type::VoidTypeID;
1489 Instruction *result =
new REMInst(type, s1, s2);
1490 write_variable(iptr->dst.varindex,bbindex,result);
1491 M->add_Instruction(result);
1508 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1509 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1511 Instruction *result;
1513 switch (iptr->opc) {
1517 type = Type::IntTypeID;
1522 type = Type::LongTypeID;
1525 type = Type::VoidTypeID;
1528 switch (iptr->opc) {
1531 result =
new ANDInst(type, s1, s2);
1535 result =
new ORInst(type, s1, s2);
1539 result =
new XORInst(type, s1, s2);
1544 write_variable(iptr->dst.varindex,bbindex,result);
1545 M->add_Instruction(result);
1554 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1555 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1556 CMPInst::FloatHandling handling;
1557 switch (iptr->opc) {
1560 handling = CMPInst::L;
1564 handling = CMPInst::G;
1567 handling = CMPInst::DontCare;
1569 Instruction *result =
new CMPInst(s1, s2, handling);
1570 write_variable(iptr->dst.varindex,bbindex,result);
1571 M->add_Instruction(result);
1583 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1584 Instruction *konst =
new CONSTInst(iptr->sx.val.i,Type::IntType());
1585 Instruction *result;
1586 switch (iptr->opc) {
1588 result =
new ADDInst(Type::IntTypeID, s1, konst);
1591 result =
new SUBInst(Type::IntTypeID, s1, konst);
1596 M->add_Instruction(konst);
1597 write_variable(iptr->dst.varindex,bbindex,result);
1598 M->add_Instruction(result);
1603 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1604 Instruction *konst =
new CONSTInst(iptr->sx.val.i,Type::IntType());
1605 Instruction *result;
1606 result =
new MULInst(Type::IntTypeID, s1, konst);
1607 M->add_Instruction(konst);
1608 write_variable(iptr->dst.varindex,bbindex,result);
1609 M->add_Instruction(result);
1620 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1621 Instruction *konst =
new CONSTInst(iptr->sx.val.i,Type::IntType());
1622 Instruction *result;
1623 switch (iptr->opc) {
1625 result =
new ANDInst(Type::IntTypeID, s1, konst);
1628 result =
new DIVInst(Type::IntTypeID, s1, konst);
1631 result =
new REMInst(Type::IntTypeID, s1, konst);
1636 M->add_Instruction(konst);
1637 write_variable(iptr->dst.varindex,bbindex,result);
1638 M->add_Instruction(result);
1664 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1665 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1668 switch (iptr->opc) {
1670 type = Type::IntTypeID;
1671 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::IntType());
1675 type = Type::ByteTypeID;
1676 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::ByteType());
1679 type = Type::CharTypeID;
1680 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::CharType());
1683 type = Type::ShortTypeID;
1684 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::ShortType());
1687 type = Type::ReferenceTypeID;
1688 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::ReferenceType());
1692 type = Type::LongTypeID;
1693 konst =
new CONSTInst(iptr->sx.s23.s3.constval,Type::LongType());
1696 type = Type::VoidTypeID;
1699 M->add_Instruction(konst);
1700 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1701 assert(state_change);
1703 Instruction *ref =
new AREFInst(type, s1, s2);
1704 M->add_Instruction(ref);
1705 Instruction *result =
new ASTOREInst(type, ref, konst,
BB[bbindex], state_change);
1706 write_variable(global_state,bbindex,result);
1707 M->add_Instruction(result);
1708 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(type, s1, s2);
1709 ref->append_dep(boundscheck);
1710 M->add_Instruction(boundscheck);
1724 switch (iptr->opc) {
1726 I =
new CONSTInst(iptr->sx.val.i,Type::IntType());
1729 I =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1732 I =
new CONSTInst(iptr->sx.val.f,Type::FloatType());
1735 I =
new CONSTInst(iptr->sx.val.d,Type::DoubleType());
1740 write_variable(iptr->dst.varindex,bbindex,I);
1741 M->add_Instruction(I);
1748 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1749 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1750 Instruction *result =
new ADDInst(Type::LongTypeID, s1, konst);
1751 M->add_Instruction(konst);
1752 write_variable(iptr->dst.varindex,bbindex,result);
1753 M->add_Instruction(result);
1758 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1759 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1760 Instruction *result =
new SUBInst(Type::LongTypeID, s1, konst);
1761 M->add_Instruction(konst);
1762 write_variable(iptr->dst.varindex,bbindex,result);
1763 M->add_Instruction(result);
1768 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1769 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1770 Instruction *result =
new MULInst(Type::LongTypeID, s1, konst);
1771 M->add_Instruction(konst);
1772 write_variable(iptr->dst.varindex,bbindex,result);
1773 M->add_Instruction(result);
1778 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1779 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1780 Instruction *result;
1781 switch (iptr->opc) {
1783 result =
new ANDInst(Type::LongTypeID, s1, konst);
1788 M->add_Instruction(konst);
1789 write_variable(iptr->dst.varindex,bbindex,result);
1790 M->add_Instruction(result);
1797 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1798 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
1799 Instruction *result;
1800 switch (iptr->opc) {
1803 result =
new SUBInst(Type::LongTypeID, s1, konst);
1808 M->add_Instruction(konst);
1809 write_variable(iptr->dst.varindex,bbindex,result);
1810 M->add_Instruction(result);
1855 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1856 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1857 assert(state_change);
1859 BB[bbindex],state_change);
1860 write_variable(global_state,bbindex,putstatic);
1861 M->add_Instruction(putstatic);
1869 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1870 assert(state_change);
1872 BB[bbindex],state_change);
1873 write_variable(iptr->dst.varindex,bbindex,getstatic);
1874 write_variable(global_state,bbindex,getstatic);
1875 M->add_Instruction(getstatic);
1897 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
1898 Instruction *konst =
new CONSTInst(iptr->sx.val.i,Type::IntType());
1899 Instruction *result;
1900 switch (iptr->opc) {
1902 result =
new ADDInst(Type::IntTypeID, s1, konst);
1907 M->add_Instruction(konst);
1908 write_variable(iptr->dst.varindex,bbindex,result);
1909 M->add_Instruction(result);
1926 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1927 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1928 Value *
s3 = read_variable(iptr->sx.s23.s3.varindex,bbindex);
1930 switch (iptr->opc) {
1932 type = Type::ByteTypeID;
1935 type = Type::CharTypeID;
1938 type = Type::ShortTypeID;
1941 type = Type::IntTypeID;
1944 type = Type::LongTypeID;
1947 type = Type::ReferenceTypeID;
1950 type = Type::FloatTypeID;
1953 type = Type::DoubleTypeID;
1956 type = Type::VoidTypeID;
1958 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
1959 assert(state_change);
1960 Instruction *ref =
new AREFInst(s3->get_type(),
s1,
s2);
1961 M->add_Instruction(ref);
1962 Instruction *result =
new ASTOREInst(type, ref, s3,
BB[bbindex], state_change);
1963 write_variable(global_state,bbindex,result);
1964 M->add_Instruction(result);
1965 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(type, s1, s2);
1966 ref->append_dep(boundscheck);
1967 M->add_Instruction(boundscheck);
1979 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
1980 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
1982 switch (iptr->opc) {
1984 type = Type::ByteTypeID;
1987 type = Type::CharTypeID;
1990 type = Type::ShortTypeID;
1993 type = Type::IntTypeID;
1996 type = Type::LongTypeID;
1999 type = Type::ReferenceTypeID;
2002 type = Type::FloatTypeID;
2005 type = Type::DoubleTypeID;
2008 type = Type::VoidTypeID;
2010 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
2011 assert(state_change);
2012 Instruction *ref =
new AREFInst(type, s1, s2);
2013 M->add_Instruction(ref);
2014 Instruction *result =
new ALOADInst(type, ref,
BB[bbindex], state_change);
2015 write_variable(iptr->dst.varindex,bbindex,result);
2016 write_variable(global_state,bbindex,result);
2017 M->add_Instruction(result);
2018 Instruction *boundscheck =
new ARRAYBOUNDSCHECKInst(type, s1, s2);
2019 ref->append_dep(boundscheck);
2020 M->add_Instruction(boundscheck);
2044 switch (iptr->opc) {
2046 I =
new LOADInst(Type::IntTypeID, iptr->s1.varindex);
2049 I =
new LOADInst(Type::LongTypeID, iptr->s1.varindex);
2052 I =
new LOADInst(Type::FloatTypeID, iptr->s1.varindex);
2055 I =
new LOADInst(Type::DoubleTypeID, iptr->s1.varindex);
2060 Value *def = read_variable(iptr->s1.varindex,bbindex);
2066 switch (iptr->opc) {
2068 konst =
new CONSTInst((
int)0);
2071 konst =
new CONSTInst((
long)0);
2074 konst =
new CONSTInst((
float)0);
2077 konst =
new CONSTInst((
double)0);
2081 M->add_Instruction(konst);
2087 write_variable(iptr->dst.varindex,bbindex,def);
2096 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2097 write_variable(iptr->dst.varindex,bbindex,s1);
2153 #if defined(ENABLE_INLINING)
2156 show_inline_info(jd, ii, opcode, stage);
2192 type = Type::IntTypeID;
2195 type = Type::LongTypeID;
2198 type = Type::FloatTypeID;
2201 type = Type::DoubleTypeID;
2204 type = Type::VoidTypeID;
2213 type = Type::VoidTypeID;
2216 <<
" not yet supported! (see vm/global.h)" <<
nl;
2220 s4 *argp = iptr->sx.s23.s2.args;
2221 int32_t
i = iptr->s1.argcount;
2224 Instruction *state_change = read_variable(global_state,bbindex)->to_Instruction();
2225 assert(state_change);
2226 INVOKESTATICInst *
I =
new INVOKESTATICInst(type,i,fmiref,
2228 LOG3(
"INVOKESTATICInst: " << I <<
" dep = " << state_change <<
nl);
2233 I->append_parameter(read_variable(*(argp++),bbindex));
2235 if (type != Type::VoidTypeID) {
2236 write_variable(iptr->dst.varindex,bbindex,I);
2238 write_variable(global_state,bbindex,I);
2239 M->add_Instruction(I);
2270 Conditional::CondID cond;
2271 switch (iptr->opc) {
2273 cond = Conditional::LT;
2276 cond = Conditional::GT;
2279 cond = Conditional::EQ;
2282 cond = Conditional::NE;
2285 cond = Conditional::LE;
2288 cond = Conditional::GE;
2292 cond = Conditional::NoCond;
2294 Instruction *konst =
new CONSTInst(iptr->sx.val.i,Type::IntType());
2295 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2297 assert(
BB[iptr->dst.block->nr]);
2298 BeginInst *trueBlock =
BB[iptr->dst.block->nr]->to_BeginInst();
2300 assert(
BB[bbindex+1]);
2301 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
2303 Instruction *result =
new IFInst(
BB[bbindex], s1, konst, cond,
2304 trueBlock, falseBlock);
2305 M->add_Instruction(konst);
2306 M->add_Instruction(result);
2321 Conditional::CondID cond;
2322 switch (iptr->opc) {
2324 cond = Conditional::LT;
2327 cond = Conditional::GT;
2330 cond = Conditional::LE;
2333 cond = Conditional::EQ;
2336 cond = Conditional::NE;
2339 cond = Conditional::GE;
2343 cond = Conditional::NoCond;
2345 Instruction *konst =
new CONSTInst(iptr->sx.val.l,Type::LongType());
2346 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2348 assert(
BB[iptr->dst.block->nr]);
2349 BeginInst *trueBlock =
BB[iptr->dst.block->nr]->to_BeginInst();
2351 assert(
BB[bbindex+1]);
2352 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
2354 Instruction *result =
new IFInst(
BB[bbindex], s1, konst, cond,
2355 trueBlock, falseBlock);
2356 M->add_Instruction(konst);
2357 M->add_Instruction(result);
2362 assert(
BB[iptr->dst.block->nr]);
2363 BeginInst *targetBlock =
BB[iptr->dst.block->nr];
2364 Instruction *result =
new GOTOInst(
BB[bbindex], targetBlock);
2365 M->add_Instruction(result);
2390 Conditional::CondID cond;
2391 switch (iptr->opc) {
2393 cond = Conditional::LE;
2396 cond = Conditional::EQ;
2399 cond = Conditional::NE;
2402 cond = Conditional::LT;
2405 cond = Conditional::GE;
2408 cond = Conditional::GT;
2412 cond = Conditional::NoCond;
2414 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2415 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
2418 assert(
BB[iptr->dst.block->nr]);
2419 BeginInst *trueBlock =
BB[iptr->dst.block->nr]->to_BeginInst();
2421 assert(
BB[bbindex+1]);
2422 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
2424 Instruction *result =
new IFInst(
BB[bbindex], s1, s2, cond,
2425 trueBlock, falseBlock);
2426 M->add_Instruction(result);
2437 Conditional::CondID cond;
2438 switch (iptr->opc) {
2440 cond = Conditional::EQ;
2443 cond = Conditional::NE;
2446 cond = Conditional::LT;
2449 cond = Conditional::GT;
2452 cond = Conditional::GE;
2455 cond = Conditional::LE;
2458 cond = Conditional::NoCond;
2461 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2462 Value *
s2 = read_variable(iptr->sx.s23.s2.varindex,bbindex);
2465 assert(
BB[iptr->dst.block->nr]);
2466 BeginInst *trueBlock =
BB[iptr->dst.block->nr]->to_BeginInst();
2468 assert(
BB[bbindex+1]);
2469 BeginInst *falseBlock =
BB[bbindex+1]->to_BeginInst();
2471 Instruction *result =
new IFInst(
BB[bbindex], s1, s2, cond,
2472 trueBlock, falseBlock);
2473 M->add_Instruction(result);
2487 s4 tablehigh = iptr->sx.s23.s3.tablehigh;
2488 s4 tablelow = iptr->sx.s23.s2.tablelow;
2490 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2491 TABLESWITCHInst *result =
new TABLESWITCHInst(
BB[bbindex], s1,
2492 TABLESWITCHInst::LOW(tablelow),
2493 TABLESWITCHInst::HIGH(tablehigh));
2495 s4 count = tablehigh - tablelow + 1;
2496 LOG(
"tableswitch high=" << tablehigh <<
" low=" << tablelow <<
" count=" << count <<
nl);
2498 BeginInst* def =
BB[table[0].
block->
nr];
2499 LOG(
"idx: " << 0 <<
" BeginInst: " <<
BB[table[0].
block->nr]
2500 <<
"(block.nr=" << table[0].block->nr <<
")"<<
nl);
2502 for (
s4 i = 0;
i < count ; ++
i) {
2503 LOG(
"idx: " <<
i <<
" BeginInst: " <<
BB[table[
i].
block->nr]
2504 <<
"(block.nr=" << table[
i].block->nr <<
")"<<
nl);
2505 result->append_succ(
BB[table[
i].
block->nr]);
2507 result->append_succ(def);
2508 M->add_Instruction(result);
2514 s4 lookupcount = iptr->sx.s23.s2.lookupcount;
2516 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2517 LOOKUPSWITCHInst *result =
new LOOKUPSWITCHInst(
BB[bbindex], s1, lookupcount);
2521 for (
s4 i = 0;
i < lookupcount; ++
i) {
2524 result->set_match(
i, LOOKUPSWITCHInst::MATCH(lookup->
value));
2528 BeginInst *defaultBlock =
BB[iptr->sx.s23.s3.lookupdefault.block->nr];
2529 assert(defaultBlock);
2530 result->append_succ(defaultBlock);
2532 M->add_Instruction(result);
2557 Value *
s1 = read_variable(iptr->s1.varindex,bbindex);
2558 Instruction *result =
new RETURNInst(
BB[bbindex], s1);
2559 M->add_Instruction(result);
2567 Instruction *result =
new RETURNInst(
BB[bbindex]);
2568 M->add_Instruction(result);
2586 Value *
s1 = read_variable(iptr->s1.varindex, bbindex);
2587 write_variable(iptr->dst.varindex,bbindex,s1);
2596 #if defined(ENABLE_SSA)
2615 #if !defined(NDEBUG)
2617 "Operation not yet supported!");
2619 ABORT_MSG(
"Opcode: (" << iptr->opc <<
")",
2620 "Operation not yet supported!");
2624 if (!
BB[bbindex]->get_EndInst()) {
2626 assert(bbindex+1 <
BB.size());
2627 BeginInst *targetBlock =
BB[bbindex+1];
2628 Instruction *result =
new GOTOInst(
BB[bbindex], targetBlock);
2629 M->add_Instruction(result);
2633 filled_blocks[bbindex] =
true;
2642 for(
size_t i = 0;
i< num_basicblocks; ++
i) {
2643 if (!sealed_blocks[
i]) {
2645 << i <<
" (" <<
BB[
i] <<
")"
2647 assert(0 &&
"There is an unsealed basic block");
2654 bool SSAConstructionPass::verify()
const {
2655 for (Method::const_iterator
i =
M->begin(),
e =
M->end() ;
i !=
e ; ++
i) {
2656 Instruction *
I = *
i;
2657 if (!I->verify())
return false;
2662 PassUsage& SSAConstructionPass::get_PassUsage(PassUsage &PU)
const {
2663 PU.add_requires<CFGConstructionPass>();
2667 char SSAConstructionPass::ID = 0;
2670 static PassRegistry<SSAConstructionPass>
X(
"SSAConstructionPass");
jlong jlong jlong jlong jint jmethodID jint slot
#define STATISTICS(x)
Wrapper for statistics only code.
static SetWidth setw(size_t w)
void unresolved_class_debug_dump(unresolved_class *ref, FILE *file)
void class_classref_or_classinfo_print(classref_or_classinfo c)
#define SHOW_CLASSREF_OR_CLASSINFO(OS, c)
#define ERROR_MSG(EXPR_SHORT, EXPR_LONG)
#define SHOW_STRING(OS, val)
#define DEBUG_COND_N(VERBOSE)
JNIEnv jthread jobject jclass jlong size
#define SHOW_FIELD(OS, fmiref)
#define SHOW_INT_CONST(OS, val)
#define SHOW_S3(OS, iptr)
basicblock ** predecessors
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.
Simple stream class for formatted output.
#define RETADDR_FROM_JAVALOCAL(jl)
#define SHOW_FLT_CONST(OS, val)
#define SHOW_DBL_CONST(OS, val)
#define SHOW_S2(OS, iptr)
Fieldref, Methodref and InterfaceMethodref.
#define FOR_EACH_BASICBLOCK(jd, it)
union instruction::@12 sx
#define SHOW_LNG_CONST(OS, val)
icmdtable_entry_t icmd_table[256]
#define INSTRUCTION_GET_METHODDESC(iptr, md)
#define LOG(STMT)
Analogous to DEBUG.
#define SHOW_DST_LOCAL(OS, iptr)
#define SHOW_S1(OS, iptr)
Type::TypeID convert_var_type(int type)
Represents the result of the addition of a certain IR-variable with a certain constant.
void method_methodref_print(constant_FMIref *mr)
#define SHOW_VARIABLE(OS, v)
#define STAT_DECLARE_GROUP(var)
Declare an external group (or subgroup).
java_handle_t * stringconst
#define FOR_EACH_INSTRUCTION(bptr, it)
#define SHOW_S1_LOCAL(OS, iptr)
static void shouldnotreach()
#define INSTRUCTION_IS_UNRESOLVED(iptr)
struct instruction::@12::@13 s23
const parseddesc_t parseddesc
#define INSTRUCTION_IS_RESOLVED(iptr)
const char * get_var_type(int type)
#define ABORT_MSG(EXPR_SHORT, EXPR_LONG)
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
#define SHOW_TARGET(OS, target)
#define INSTRUCTION_GET_METHODREF(iptr, mref)
#define SHOW_DST(OS, iptr)
#define SHOW_ADR_CONST(OS, val)