< prev index next >

src/share/vm/opto/callnode.cpp

Print this page
rev 8739 : 8004073: Implement C2 Ideal node specific dump() method
Summary: add Node::dump_rel() to dump a node and its related nodes (the notion of "related" depends on the node at hand); add Node::dump_comp() to dump a node in compact representation; add Node::dump_rel_comp() to dump a node and its related nodes in compact representation; add the required machinery; extend some C2 IR nodes with compact and related dumping
Reviewed-by:

@@ -50,10 +50,11 @@
 { return _domain == ((StartNode&)n)._domain; }
 const Type *StartNode::bottom_type() const { return _domain; }
 const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; }
 #ifndef PRODUCT
 void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);}
+void StartNode::dump_comp_spec(outputStream *st) const { /* empty */ }
 #endif
 
 //------------------------------Ideal------------------------------------------
 Node *StartNode::Ideal(PhaseGVN *phase, bool can_reshape){
   return remove_dead_region(phase, can_reshape) ? this : NULL;

@@ -119,10 +120,27 @@
     st->print("Parm%d: ",_con-TypeFunc::Parms);
     // Verbose and WizardMode dump bottom_type for all nodes
     if( !Verbose && !WizardMode )   bottom_type()->dump_on(st);
   }
 }
+
+void ParmNode::dump_comp_spec(outputStream *st) const {
+  if (_con < TypeFunc::Parms) {
+    st->print("%s", names[_con]);
+  } else {
+    st->print("%d:", _con-TypeFunc::Parms);
+    // unconditionally dump bottom_type
+    bottom_type()->dump_on(st);
+  }
+}
+
+// For a ParmNode, all immediate inputs and outputs are considered relevant
+// both in compact and standard representation.
+void ParmNode::rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
+  this->collect_nodes(in_rel, 1, false, false);
+  this->collect_nodes(out_rel, -1, false, false);
+}
 #endif
 
 uint ParmNode::ideal_reg() const {
   switch( _con ) {
   case TypeFunc::Control  : // fall through

@@ -946,10 +964,18 @@
 #ifndef PRODUCT
 void CallJavaNode::dump_spec(outputStream *st) const {
   if( _method ) _method->print_short_name(st);
   CallNode::dump_spec(st);
 }
+
+void CallJavaNode::dump_comp_spec(outputStream* st) const {
+  if (_method) {
+    _method->print_short_name(st);
+  } else {
+    st->print("<?>");
+  }
+}
 #endif
 
 //=============================================================================
 uint CallStaticJavaNode::size_of() const { return sizeof(*this); }
 uint CallStaticJavaNode::cmp( const Node &n ) const {

@@ -993,10 +1019,20 @@
     }
     st->print(" ");
   }
   CallJavaNode::dump_spec(st);
 }
+
+void CallStaticJavaNode::dump_comp_spec(outputStream* st) const {
+  if (_method) {
+    _method->print_short_name(st);
+  } else if (_name) {
+    st->print("%s", _name);
+  } else {
+    st->print("<?>");
+  }
+}
 #endif
 
 //=============================================================================
 uint CallDynamicJavaNode::size_of() const { return sizeof(*this); }
 uint CallDynamicJavaNode::cmp( const Node &n ) const {

@@ -1128,10 +1164,23 @@
 #ifndef PRODUCT
 void SafePointNode::dump_spec(outputStream *st) const {
   st->print(" SafePoint ");
   _replaced_nodes.dump(st);
 }
+
+// The related nodes of a SafepointNode are all data inputs, excluding the
+// control boundary, as well as all outputs till level 2 (to include projection
+// nodes and targets). In compact mode, just include inputs till level 1 and
+// outputs as before.
+void SafePointNode::rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
+  if (compact) {
+    this->collect_nodes(in_rel, 1, false, false);
+  } else {
+    this->collect_nodes_in_all_data(in_rel, false);
+  }
+  this->collect_nodes(out_rel, -2, false, false);
+}
 #endif
 
 const RegMask &SafePointNode::in_RegMask(uint idx) const {
   if( idx < TypeFunc::Parms ) return RegMask::Empty;
   // Values outside the domain represent debug info

@@ -1674,10 +1723,31 @@
     // The counter update code will stay around even though the
     // optimizer will eliminate the lock operation itself.
     _counter->set_tag(NamedCounter::EliminatedLockCounter);
   }
 }
+
+const char* AbstractLockNode::_kind_names[] = {"Regular", "NonEscObj", "Coarsened", "Nested"};
+
+void AbstractLockNode::dump_spec(outputStream* st) const {
+  st->print("%s ", _kind_names[_kind]);
+  CallNode::dump_spec(st);
+}
+
+void AbstractLockNode::dump_comp_spec(outputStream* st) const {
+  st->print("%s", _kind_names[_kind]);
+}
+
+// The related set of lock nodes includes the control boundary.
+void AbstractLockNode::rel(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
+  if (compact) {
+      this->collect_nodes(in_rel, 1, false, false);
+    } else {
+      this->collect_nodes_in_all_data(in_rel, true);
+    }
+    this->collect_nodes(out_rel, -2, false, false);
+}
 #endif
 
 //=============================================================================
 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
 
< prev index next >