RFR(M): 8004073: Implement C2 Ideal node specific dump() method
Michael Haupt
michael.haupt at oracle.com
Tue Jul 28 08:56:05 UTC 2015
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()
82 If === 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()
10 Parm === 3 [[ 38 38 65 32 ]] Parm0: java/lang/String:NotNull:exact * Oop:java/lang/String:NotNull:exact * !jvms: String::charAt @ bci:-1
38 AddP === _ 10 10 37 [[ 39 ]] Oop:java/lang/String:NotNull:exact+12 * [narrow] !jvms: String::charAt @ bci:6
39 LoadN === _ 7 38 [[ 40 ]] @java/lang/String:exact+12 * [narrow], name=value, idx=4; #narrowoop: char[int:>=0]:exact * !jvms: String::charAt @ bci:6
40 DecodeN === _ 39 [[ 55 42 ]] #char[int:>=0]:exact * !jvms: String::charAt @ bci:6
37 ConL === 0 [[ 38 56 ]] #long:12
55 CastPP === 47 40 [[ 56 56 97 97 96 86 ]] #char[int:>=0]:NotNull:exact * !jvms: String::charAt @ bci:9
56 AddP === _ 55 55 37 [[ 57 ]] !jvms: String::charAt @ bci:9
7 Parm === 3 [[ 99 98 86 65 57 32 50 39 ]] Memory Memory: @BotPTR *+bot, idx=Bot; !jvms: String::charAt @ bci:-1
57 LoadRange === _ 7 56 [[ 65 58 78 ]] @bottom[int:>=0]+12 * [narrow], idx=5; #int:>=0 !jvms: String::charAt @ bci:9
11 Parm === 3 [[ 78 93 65 32 24 32 65 58 86 ]] Parm1: int !jvms: String::charAt @ bci:-1
78 CmpU === _ 11 57 [[ 79 ]] !jvms: String::charAt @ bci:27
79 Bool === _ 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
83 IfTrue === 82 [[ 99 98 ]] #1 !jvms: String::charAt @ bci:27
84 IfFalse === 82 [[ 86 ]] #0 !jvms: String::charAt @ bci:27
99 Return === 83 6 7 8 9 returns 98 [[ 0 ]]
98 LoadUS === 83 7 96 [[ 99 ]] @char[int:>=0]:exact+any *, idx=6; #char !jvms: String::charAt @ bci:27
86 CallStaticJava === 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
--
<http://www.oracle.com/>
Dr. Michael Haupt | Principal Member of Technical Staff
Phone: +49 331 200 7277 | Fax: +49 331 200 7561
Oracle Java Platform Group | LangTools Team | Nashorn
Oracle Deutschland B.V. & Co. KG, Schiffbauergasse 14 | 14467 Potsdam, Germany
<http://www.oracle.com/commitment> Oracle is committed to developing practices and products that help protect the environment
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20150728/a288a7a1/attachment-0001.html>
More information about the hotspot-compiler-dev
mailing list