src/share/vm/opto/callnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/callnode.cpp

Print this page
rev 6447 : 8026796: Make replace_in_map() on parent maps generic
Summary: propagate node replacements along control flow edges to callers
Reviewed-by:
rev 6448 : [mq]: replaceinmap-8026796-reviews


1073     }
1074     if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
1075       // Useless Safepoint, so remove it
1076       return in(TypeFunc::Control);
1077     }
1078   }
1079 
1080   return this;
1081 }
1082 
1083 //------------------------------Value------------------------------------------
1084 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
1085   if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
1086   if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
1087   return Type::CONTROL;
1088 }
1089 
1090 #ifndef PRODUCT
1091 void SafePointNode::dump_spec(outputStream *st) const {
1092   st->print(" SafePoint ");

1093 }
1094 #endif
1095 
1096 const RegMask &SafePointNode::in_RegMask(uint idx) const {
1097   if( idx < TypeFunc::Parms ) return RegMask::Empty;
1098   // Values outside the domain represent debug info
1099   return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
1100 }
1101 const RegMask &SafePointNode::out_RegMask() const {
1102   return RegMask::Empty;
1103 }
1104 
1105 
1106 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
1107   assert((int)grow_by > 0, "sanity");
1108   int monoff = jvms->monoff();
1109   int scloff = jvms->scloff();
1110   int endoff = jvms->endoff();
1111   assert(endoff == (int)req(), "no other states or debug info after me");
1112   Node* top = Compile::current()->top();


1153 }
1154 
1155 Node *SafePointNode::peek_monitor_box() const {
1156   int mon = jvms()->nof_monitors() - 1;
1157   assert(mon >= 0, "most have a monitor");
1158   return monitor_box(jvms(), mon);
1159 }
1160 
1161 Node *SafePointNode::peek_monitor_obj() const {
1162   int mon = jvms()->nof_monitors() - 1;
1163   assert(mon >= 0, "most have a monitor");
1164   return monitor_obj(jvms(), mon);
1165 }
1166 
1167 // Do we Match on this edge index or not?  Match no edges
1168 uint SafePointNode::match_edge(uint idx) const {
1169   if( !needs_polling_address_input() )
1170     return 0;
1171 
1172   return (TypeFunc::Parms == idx);































































































































































































1173 }
1174 
1175 //==============  SafePointScalarObjectNode  ==============
1176 
1177 SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
1178 #ifdef ASSERT
1179                                                      AllocateNode* alloc,
1180 #endif
1181                                                      uint first_index,
1182                                                      uint n_fields) :
1183   TypeNode(tp, 1), // 1 control input -- seems required.  Get from root.
1184 #ifdef ASSERT
1185   _alloc(alloc),
1186 #endif
1187   _first_index(first_index),
1188   _n_fields(n_fields)
1189 {
1190   init_class_id(Class_SafePointScalarObject);
1191 }
1192 




1073     }
1074     if( n0->is_Call() && n0->as_Call()->guaranteed_safepoint() ) {
1075       // Useless Safepoint, so remove it
1076       return in(TypeFunc::Control);
1077     }
1078   }
1079 
1080   return this;
1081 }
1082 
1083 //------------------------------Value------------------------------------------
1084 const Type *SafePointNode::Value( PhaseTransform *phase ) const {
1085   if( phase->type(in(0)) == Type::TOP ) return Type::TOP;
1086   if( phase->eqv( in(0), this ) ) return Type::TOP; // Dead infinite loop
1087   return Type::CONTROL;
1088 }
1089 
1090 #ifndef PRODUCT
1091 void SafePointNode::dump_spec(outputStream *st) const {
1092   st->print(" SafePoint ");
1093   _replaced_nodes.dump(st);
1094 }
1095 #endif
1096 
1097 const RegMask &SafePointNode::in_RegMask(uint idx) const {
1098   if( idx < TypeFunc::Parms ) return RegMask::Empty;
1099   // Values outside the domain represent debug info
1100   return *(Compile::current()->matcher()->idealreg2debugmask[in(idx)->ideal_reg()]);
1101 }
1102 const RegMask &SafePointNode::out_RegMask() const {
1103   return RegMask::Empty;
1104 }
1105 
1106 
1107 void SafePointNode::grow_stack(JVMState* jvms, uint grow_by) {
1108   assert((int)grow_by > 0, "sanity");
1109   int monoff = jvms->monoff();
1110   int scloff = jvms->scloff();
1111   int endoff = jvms->endoff();
1112   assert(endoff == (int)req(), "no other states or debug info after me");
1113   Node* top = Compile::current()->top();


1154 }
1155 
1156 Node *SafePointNode::peek_monitor_box() const {
1157   int mon = jvms()->nof_monitors() - 1;
1158   assert(mon >= 0, "most have a monitor");
1159   return monitor_box(jvms(), mon);
1160 }
1161 
1162 Node *SafePointNode::peek_monitor_obj() const {
1163   int mon = jvms()->nof_monitors() - 1;
1164   assert(mon >= 0, "most have a monitor");
1165   return monitor_obj(jvms(), mon);
1166 }
1167 
1168 // Do we Match on this edge index or not?  Match no edges
1169 uint SafePointNode::match_edge(uint idx) const {
1170   if( !needs_polling_address_input() )
1171     return 0;
1172 
1173   return (TypeFunc::Parms == idx);
1174 }
1175 
1176 void ReplacedNodes::allocate_if_necessary() {
1177   if (_replaced_nodes == NULL) {
1178     _replaced_nodes = new GrowableArray<ReplacedNode>();
1179   }
1180 }
1181 
1182 bool ReplacedNodes::is_empty() const {
1183   return _replaced_nodes == NULL || _replaced_nodes->length() == 0;
1184 }
1185 
1186 bool ReplacedNodes::has_node(ReplacedNode r) const {
1187   return _replaced_nodes->find(r) != -1;
1188 }
1189 
1190 bool ReplacedNodes::has_target_node(Node* n) const {
1191   for (int i = 0; i < _replaced_nodes->length(); i++) {
1192     if (_replaced_nodes->at(i).improved() == n) {
1193       return true;
1194     }
1195   }
1196   return false;
1197 }
1198 
1199 // Record replaced node if not seen before
1200 void ReplacedNodes::record(Node* initial, Node* improved) {
1201   allocate_if_necessary();
1202   ReplacedNode r(initial, improved);
1203   if (!has_node(r)) {
1204     _replaced_nodes->push(r);
1205   }
1206 }
1207 
1208 // Copy replaced nodes from one map to another. idx is used to
1209 // identify nodes that are too new to be of interest in the target
1210 // node list.
1211 void ReplacedNodes::transfer_from(ReplacedNodes other, uint idx) {
1212   if (other.is_empty()) {
1213     return;
1214   }
1215   allocate_if_necessary();
1216   for (int i = 0; i < other._replaced_nodes->length(); i++) {
1217     ReplacedNode replaced = other._replaced_nodes->at(i);
1218     // Only transfer the nodes that can actually be useful
1219     if (!has_node(replaced) && (replaced.initial()->_idx < idx || has_target_node(replaced.initial()))) {
1220       _replaced_nodes->push(replaced);
1221     }
1222   }
1223 }
1224 
1225 void ReplacedNodes::clone() {
1226   if (_replaced_nodes != NULL) {
1227     GrowableArray<ReplacedNode>* replaced_nodes_clone = new GrowableArray<ReplacedNode>();
1228     replaced_nodes_clone->appendAll(_replaced_nodes);
1229     _replaced_nodes = replaced_nodes_clone;
1230   }
1231 }
1232 
1233 void ReplacedNodes::reset() {
1234   if (_replaced_nodes != NULL) {
1235     _replaced_nodes->clear();
1236   }
1237 }
1238 
1239 // Perfom node replacement (used when returning to caller)
1240 void ReplacedNodes::apply(Node* n) {
1241   if (is_empty()) {
1242     return;
1243   }
1244   for (int i = 0; i < _replaced_nodes->length(); i++) {
1245     ReplacedNode replaced = _replaced_nodes->at(i);
1246     n->replace_edge(replaced.initial(), replaced.improved());
1247   }
1248 }
1249 
1250 static void enqueue_use(Node* n, Node* use, Unique_Node_List& work) {
1251   if (use->is_Phi()) {
1252     Node* r = use->in(0);
1253     assert(r->is_Region(), "Phi should have Region");
1254     for (uint i = 1; i < use->req(); i++) {
1255       if (use->in(i) == n) {
1256         work.push(r->in(i));
1257       }
1258     }
1259   } else {
1260     work.push(use);
1261   }
1262 }
1263 
1264 // Perfom node replacement following late inlining
1265 void ReplacedNodes::apply(Compile* C, Node* ctl) {
1266   // ctl is the control on exit of the method that was late inlined
1267   if (is_empty()) {
1268     return;
1269   }
1270   for (int i = 0; i < _replaced_nodes->length(); i++) {
1271     ReplacedNode replaced = _replaced_nodes->at(i);
1272     Node* initial = replaced.initial();
1273     Node* improved = replaced.improved();
1274     assert (ctl != NULL && !ctl->is_top(), "replaced node should have actual control");
1275     
1276     ResourceMark rm;
1277     Unique_Node_List work;
1278     // Go over all the uses of the node that is considered for replacement...
1279     for (DUIterator j = initial->outs(); initial->has_out(j); j++) {
1280       Node* use = initial->out(j);
1281 
1282       if (use == improved || use->outcnt() == 0) {
1283         continue;
1284       }
1285       work.clear();
1286       enqueue_use(initial, use, work);
1287       bool replace = true;
1288       // Check that this use is dominated by ctl. Go ahead with the
1289       // replacement if it is.
1290       while (work.size() != 0 && replace) {
1291         Node* n = work.pop();
1292         if (use->outcnt() == 0) {
1293           continue;
1294         }
1295         if (n->is_CFG() || (n->in(0) != NULL && !n->in(0)->is_top())) {
1296           int depth = 0;
1297           Node *m = n;
1298           if (!n->is_CFG()) {
1299             n = n->in(0);
1300           }
1301           assert(n->is_CFG(), "should be CFG now");
1302           while(n != ctl) {
1303             n = IfNode::up_one_dom(n);
1304             depth++;
1305             // limit search depth
1306             if (depth >= 100 || n == NULL) {
1307               replace = false;
1308               break;
1309             }
1310           }
1311         } else {
1312           for (DUIterator k = n->outs(); n->has_out(k); k++) {
1313             enqueue_use(n, n->out(k), work);
1314           }
1315         }
1316       }
1317       if (replace) {
1318         bool is_in_table = C->initial_gvn()->hash_delete(use);
1319         int replaced = use->replace_edge(initial, improved);
1320         if (is_in_table) {
1321           C->initial_gvn()->hash_find_insert(use);
1322         }
1323         C->record_for_igvn(use);
1324 
1325         assert(replaced > 0, "inconsistent");
1326         --j;
1327       }
1328     }
1329   }
1330 }
1331 
1332 void ReplacedNodes::dump(outputStream *st) const {
1333   if (!is_empty()) {
1334     tty->print("replaced nodes: ");
1335     for (int i = 0; i < _replaced_nodes->length(); i++) {
1336       tty->print("%d->%d", _replaced_nodes->at(i).initial()->_idx, _replaced_nodes->at(i).improved()->_idx);
1337       if (i < _replaced_nodes->length()-1) {
1338         tty->print(",");
1339       }
1340     }
1341   }
1342 }
1343 
1344 // Merge 2 list of replaced node at a point where control flow paths merge
1345 void ReplacedNodes::merge_with(ReplacedNodes other) {
1346   if (is_empty()) {
1347     return;
1348   }
1349   if (other.is_empty()) {
1350     reset();
1351     return;
1352   }
1353   int shift = 0;
1354   int len = _replaced_nodes->length();
1355   for (int i = 0; i < len; i++) {
1356     if (!other.has_node(_replaced_nodes->at(i))) {
1357       shift++;
1358     } else if (shift > 0) {
1359       _replaced_nodes->at_put(i-shift, _replaced_nodes->at(i));
1360     }
1361   }
1362   if (shift > 0) {
1363     _replaced_nodes->trunc_to(len - shift);
1364   }
1365 }
1366 
1367 //==============  SafePointScalarObjectNode  ==============
1368 
1369 SafePointScalarObjectNode::SafePointScalarObjectNode(const TypeOopPtr* tp,
1370 #ifdef ASSERT
1371                                                      AllocateNode* alloc,
1372 #endif
1373                                                      uint first_index,
1374                                                      uint n_fields) :
1375   TypeNode(tp, 1), // 1 control input -- seems required.  Get from root.
1376 #ifdef ASSERT
1377   _alloc(alloc),
1378 #endif
1379   _first_index(first_index),
1380   _n_fields(n_fields)
1381 {
1382   init_class_id(Class_SafePointScalarObject);
1383 }
1384 


src/share/vm/opto/callnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File