RFR(M): 8004073: Implement C2 Ideal node specific dump() method

Vladimir Kozlov vladimir.kozlov at oracle.com
Tue Jul 28 17:24:30 UTC 2015


Some first observations.

Before looking to webrev, can you use whole word Node::related(), 
dump_related(), dump_related_compact(), dump_compact()? "comp" could be 
confused for "compiled". It is more typing in debugger but it is more clear.

Also from  this->dump_rel() in your example I see that you dump a lot 
more input nodes than I expect (only up to inputs of CmpU node).
But this->dump_rel_comp() produces correct set of nodes.

It would be nice if you can avoid using macro:

+#ifndef PRODUCT
+  REL_IN_DATA_OUT_1;
+#endif

"Arithmetic nodes" are most common data nodes (vs control nodes 
this->is_CFG() == true). May be instead specialized rel() method you can 
use some flags checks in Node::rel() method.

Thanks,
Vladimir

On 7/28/15 1:56 AM, Michael Haupt wrote:
> Dear all,
>
> please review and sponsor this change.
> RFE: https://bugs.openjdk.java.net/browse/JDK-8004073
> Webrev: http://cr.openjdk.java.net/~mhaupt/8004073/webrev.00
>
> This change extends the dumping facilities of the C2 IR Node hierarchy.
> Node::dump() is used in debugging sessions to print information about an
> IR node. The API is extended by these new entry points:
>
> * void Node::dump_comp()
>    -> Dump the node in compact form.
>
> * void Node::dump_rel(), void Node::dump_rel_comp()
>    -> Dump the node (in compact form) and all nodes related to it. Mark the
>       current node in the output.
>
> The notion of "related" nodes is of course a property of the node
> itself, or rather, of its class. This is configured in this virtual method:
>
> * virtual void Node::rel(GrowableArray<Node*> *in_rel,
> GrowableArray<Node*> *out_rel, bool compact)
>    -> Collect all related nodes. Store the incoming related nodes in the
> in_rel
>       array, and the outgoing related nodes in the out_rel array. In
> case compact
>       representation is desired, possibly collect less nodes.
>
> This method must be overridden by all subclasses of Node that, in their
> notion of what related nodes are, divert from the default behaviour as
> specified in the implementation of Node::rel() in the Node class itself.
> The default is to collect all inputs and outputs till depth 1, including
> both data and control nodes, ignoring compactness.
>
> There are several auxiliary methods. Node collection is chiefly
> facilitated by this method:
>
> * void Node::collect_nodes(GrowableArray<Node*> *ns, int d, bool ctrl,
> bool data)
>    -> Collect nodes till depth d (positive: inputs, negative: outputs),
> including
>       *only* control or data nodes (this is controlled by the two bool
> arguments,
>       and setting both to true is nonsensical).
>
> Furthermore, there exist pre-defined collectors for common cases:
>
> * void Node::collect_nodes_in_all_data(GrowableArray<Node*> *ns, bool ctrl)
>    -> Collect the entire data input graph. Include control nodes only if
>       requested.
>
> * void Node::collect_nodes_in_all_ctrl(GrowableArray<Node*> *ns, bool data)
>    -> Collect the entire control input graph. Include data nodes only if
>       requested.
>
> * void Node::collect_nodes_out_all_ctrl_boundary(GrowableArray<Node*> *ns)
>    -> Collect all output nodes, stopping at control nodes, including these.
>
> * void Node::collect_nodes_in_data_out_1(GrowableArray<Node*> *is,
> GrowableArray<Node*> *os, bool compact)
>    -> Collect the entire data input graph, and outputs till depth 1.
>
> Regarding compact dumping, subclasses of Node should override this
> virtual method:
>
> * virtual void dump_comp_spec(outputStream *st)
>    -> Dump the specifics of a node in compact form. This method is
> supposed to
>       operate in the fashion of Node::dump_spec().
>
> The default behaviour for compact dumping is to dump a node's name and
> index.
>
> Specific notions of "related" have been added to the following node classes:
> * AbsNode and subclasses
> * AddNode and subclasses
> * AddPNode
> * AtanDNode
> * BinaryNode
> * BoolNode
> * CosDNode
> * CountBitsNode and subclasses
> * Div{D,F,I,L}Node
> * ExpDNode
> * GotoNode
> * HaltNode
> * Log{10D,D}Node
> * LShift{I,L}Node
> * Mod{D,F,I,L}Node
> * MulHiLNode
> * Mul{D,F,I,L}Node and subclasses
> * DivModNode and subclasses
> * IfNode
> * JumpNode
> * SafePointNode and subclasses (may require more detail)
> * StartNode and subclass
> * NegNode and subclasses
> * PowDNode
> * IfProjNode and subclasses
> * JProjNode and subclass
> * ParmNode
> * ReductionNode and subclasses
> * Round{Double,Float}Node
> * RShift{I,L}Node
> * SqrtDNode
> * SubNode and subclasses
> * TanDNode
> * AddV{B,D,F,I,L,S,_}Node
> * DivV{D,F}Node
> * LShiftV{B,I,L,S}Node
> * MulV{D,F,I,S}Node
> * OrVNode
> * RShiftV{B,I,L,S}Node
> * SubV{B,D,F,I,L,S}Node
> * URShiftV{B,I,L,S}Node
> * XorVNode
> * URShift{I,L}Node
>
> Here is a sample session in LLDB, showing the different dumps for an IfNode:
>
> * thread #28: tid = 0x10d1ce3, 0x000000010353be17
> libjvm.dylib`IfNode::Ideal(this=0x0000000104888760,
> phase=0x000000011cf62368, can_reshape=<unavailable>) + 77 at
> ifnode.cpp:1297, name = 'Java: C2 CompilerThread0', stop reason =
> breakpoint 1.1
>      frame #0: 0x000000010353be17
> libjvm.dylib`IfNode::Ideal(this=0x0000000104888760,
> phase=0x000000011cf62368, can_reshape=<unavailable>) + 77 at ifnode.cpp:1297
>     1294  if (remove_dead_region(phase, can_reshape))  return this;
>     1295  // No Def-Use info?
>     1296  if (!can_reshape)  return NULL;
> -> 1297  PhaseIterGVN *igvn = phase->is_IterGVN();
>     1298
>     1299  // Don't bother trying to transform a dead if
>     1300  if (in(0)->is_top())  return NULL;
> (lldb) expr -- this->dump()
>   82If===  61  79  [[ 83  84 ]] P=0.999999, C=-1.000000 !jvms:
> String::charAt @ bci:27
> (lldb) expr -- this->dump_comp()
> If(82)P=0.999999, C=-1.000000
> (lldb) expr -- this->dump_rel()
>   10Parm===  3  [[ 38  38  65  32 ]] Parm0:
> java/lang/String:NotNull:exact *  Oop:java/lang/String:NotNull:exact *
> !jvms: String::charAt @ bci:-1
>   38AddP=== _  10  10  37  [[ 39
> ]]   Oop:java/lang/String:NotNull:exact+12 * [narrow] !jvms:
> String::charAt @ bci:6
>   39LoadN=== _  7  38  [[ 40 ]]  @java/lang/String:exact+12 * [narrow],
> name=value, idx=4; #narrowoop: char[int:>=0]:exact *
> !jvms: String::charAt @ bci:6
>   40DecodeN=== _  39  [[ 55  42 ]]  #char[int:>=0]:exact * !jvms:
> String::charAt @ bci:6
>   37ConL===  0  [[ 38  56 ]]  #long:12
>   55CastPP===  47  40  [[ 56  56  97  97  96  86
> ]]  #char[int:>=0]:NotNull:exact * !jvms: String::charAt @ bci:9
>   56AddP=== _  55  55  37  [[ 57 ]]  !jvms: String::charAt @ bci:9
>   7Parm===  3  [[ 99  98  86  65  57  32  50  39 ]] Memory  Memory:
> @BotPTR *+bot, idx=Bot; !jvms: String::charAt @ bci:-1
>   57LoadRange=== _  7  56  [[ 65  58  78 ]]  @bottom[int:>=0]+12 *
> [narrow], idx=5; #int:>=0 !jvms: String::charAt @ bci:9
>   11Parm===  3  [[ 78  93  65  32  24  32  65  58  86 ]] Parm1: int
> !jvms: String::charAt @ bci:-1
>   78CmpU=== _  11  57  [[ 79 ]]  !jvms: String::charAt @ bci:27
>   79Bool=== _  78  [[ 82 ]] [lt] !jvms: String::charAt @ bci:27
>   82 >If===  61  79  [[ 83  84 ]] P=0.999999, C=-1.000000 !jvms:
> String::charAt @ bci:27
>   83IfTrue===  82  [[ 99  98 ]] #1 !jvms: String::charAt @ bci:27
>   84IfFalse===  82  [[ 86 ]] #0 !jvms: String::charAt @ bci:27
>   99Return===  83  6  7  8  9 returns 98  [[ 0 ]]
>   98LoadUS===  83  7  96  [[ 99 ]]  @char[int:>=0]:exact+any *, idx=6;
> #char !jvms: String::charAt @ bci:27
>   86CallStaticJava===  84  6  7  8  9 ( 85  1  1  55  11 ) [[ 87 ]] #
> Static
> uncommon_trap(reason='range_check' action='make_not_entrant')  void (
> int ) C=0.000100 String::charAt @ bci:27 !jvms: String::charAt @ bci:27
> (lldb) expr -- this->dump_rel_comp()
> If(82)P=0.999999,
> C=-1.000000  Bool(79)[lt]  CmpU(78)  Parm(11)1:int  LoadRange(57)
> @bottom[int:>=0]+12 * [narrow], idx=5; #int:>=0
> IfTrue(83)[99][98]#1  IfFalse(84)[86]#0  Return(99)  LoadUS(98)
> @char[int:>=0]:exact+any *, idx=6; #char  CallStaticJava(86)uncommon_trap
>
> Best,
>
> Michael
>
> --
>
> Oracle <http://www.oracle.com/>
> Dr. Michael Haupt | Principal Member of Technical Staff
> Phone: +49 331 200 7277 | Fax: +49 331 200 7561
> OracleJava Platform Group | LangTools Team | Nashorn
> Oracle Deutschland B.V. & Co. KG, Schiffbauergasse 14 | 14467 Potsdam,
> Germany
> Green Oracle <http://www.oracle.com/commitment>	Oracle is committed to
> developing practices and products that help protect the environment
>
>


More information about the hotspot-compiler-dev mailing list