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