8004073: Implement C2 Ideal node specific dump() method
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: kvn, roland
This commit is contained in:
parent
c030d4e363
commit
fd2f61a53f
@ -79,10 +79,15 @@ void ArrayCopyNode::connect_outputs(GraphKit* kit) {
|
||||
|
||||
#ifndef PRODUCT
|
||||
const char* ArrayCopyNode::_kind_names[] = {"arraycopy", "arraycopy, validated arguments", "clone", "oop array clone", "CopyOf", "CopyOfRange"};
|
||||
|
||||
void ArrayCopyNode::dump_spec(outputStream *st) const {
|
||||
CallNode::dump_spec(st);
|
||||
st->print(" (%s%s)", _kind_names[_kind], _alloc_tightly_coupled ? ", tightly coupled allocation" : "");
|
||||
}
|
||||
|
||||
void ArrayCopyNode::dump_compact_spec(outputStream* st) const {
|
||||
st->print("%s%s", _kind_names[_kind], _alloc_tightly_coupled ? ",tight" : "");
|
||||
}
|
||||
#endif
|
||||
|
||||
intptr_t ArrayCopyNode::get_length_if_constant(PhaseGVN *phase) const {
|
||||
|
@ -164,6 +164,7 @@ public:
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream* st) const;
|
||||
#endif
|
||||
};
|
||||
#endif // SHARE_VM_OPTO_ARRAYCOPYNODE_HPP
|
||||
|
@ -52,6 +52,7 @@ 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_compact_spec(outputStream *st) const { /* empty */ }
|
||||
#endif
|
||||
|
||||
//------------------------------Ideal------------------------------------------
|
||||
@ -121,6 +122,23 @@ void ParmNode::dump_spec(outputStream *st) const {
|
||||
if( !Verbose && !WizardMode ) bottom_type()->dump_on(st);
|
||||
}
|
||||
}
|
||||
|
||||
void ParmNode::dump_compact_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::related(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 {
|
||||
@ -948,6 +966,14 @@ void CallJavaNode::dump_spec(outputStream *st) const {
|
||||
if( _method ) _method->print_short_name(st);
|
||||
CallNode::dump_spec(st);
|
||||
}
|
||||
|
||||
void CallJavaNode::dump_compact_spec(outputStream* st) const {
|
||||
if (_method) {
|
||||
_method->print_short_name(st);
|
||||
} else {
|
||||
st->print("<?>");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
@ -995,6 +1021,16 @@ void CallStaticJavaNode::dump_spec(outputStream *st) const {
|
||||
}
|
||||
CallJavaNode::dump_spec(st);
|
||||
}
|
||||
|
||||
void CallStaticJavaNode::dump_compact_spec(outputStream* st) const {
|
||||
if (_method) {
|
||||
_method->print_short_name(st);
|
||||
} else if (_name) {
|
||||
st->print("%s", _name);
|
||||
} else {
|
||||
st->print("<?>");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
@ -1130,6 +1166,19 @@ 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::related(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 {
|
||||
@ -1676,6 +1725,27 @@ void AbstractLockNode::set_eliminated_lock_counter() {
|
||||
_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_compact_spec(outputStream* st) const {
|
||||
st->print("%s", _kind_names[_kind]);
|
||||
}
|
||||
|
||||
// The related set of lock nodes includes the control boundary.
|
||||
void AbstractLockNode::related(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
|
||||
|
||||
//=============================================================================
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
virtual uint ideal_reg() const { return 0; }
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -110,6 +111,8 @@ public:
|
||||
virtual uint ideal_reg() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -476,6 +479,7 @@ public:
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -675,6 +679,7 @@ public:
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -730,6 +735,7 @@ public:
|
||||
virtual int Opcode() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -951,6 +957,7 @@ private:
|
||||
} _kind;
|
||||
#ifndef PRODUCT
|
||||
NamedCounter* _counter;
|
||||
static const char* _kind_names[Nested+1];
|
||||
#endif
|
||||
|
||||
protected:
|
||||
@ -1005,6 +1012,9 @@ public:
|
||||
#ifndef PRODUCT
|
||||
void create_lock_counter(JVMState* s);
|
||||
NamedCounter* counter() const { return _counter; }
|
||||
virtual void dump_spec(outputStream* st) const;
|
||||
virtual void dump_compact_spec(outputStream* st) const;
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2023,6 +2023,14 @@ const RegMask &PhiNode::out_RegMask() const {
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void PhiNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
// For a PhiNode, the set of related nodes includes all inputs till level 2,
|
||||
// and all outputs till level 1. In compact mode, inputs till level 1 are
|
||||
// collected.
|
||||
this->collect_nodes(in_rel, compact ? 1 : 2, false, false);
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
}
|
||||
|
||||
void PhiNode::dump_spec(outputStream *st) const {
|
||||
TypeNode::dump_spec(st);
|
||||
if (is_tripcount()) {
|
||||
@ -2047,11 +2055,33 @@ const RegMask &GotoNode::out_RegMask() const {
|
||||
return RegMask::Empty;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//-----------------------------related-----------------------------------------
|
||||
// The related nodes of a GotoNode are all inputs at level 1, as well as the
|
||||
// outputs at level 1. This is regardless of compact mode.
|
||||
void GotoNode::related(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
|
||||
|
||||
|
||||
//=============================================================================
|
||||
const RegMask &JumpNode::out_RegMask() const {
|
||||
return RegMask::Empty;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//-----------------------------related-----------------------------------------
|
||||
// The related nodes of a JumpNode are all inputs at level 1, as well as the
|
||||
// outputs at level 2 (to include actual jump targets beyond projection nodes).
|
||||
// This is regardless of compact mode.
|
||||
void JumpNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
this->collect_nodes(in_rel, 1, false, false);
|
||||
this->collect_nodes(out_rel, -2, false, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
const RegMask &JProjNode::out_RegMask() const {
|
||||
return RegMask::Empty;
|
||||
@ -2105,7 +2135,18 @@ uint JumpProjNode::cmp( const Node &n ) const {
|
||||
#ifndef PRODUCT
|
||||
void JumpProjNode::dump_spec(outputStream *st) const {
|
||||
ProjNode::dump_spec(st);
|
||||
st->print("@bci %d ",_dest_bci);
|
||||
st->print("@bci %d ",_dest_bci);
|
||||
}
|
||||
|
||||
void JumpProjNode::dump_compact_spec(outputStream *st) const {
|
||||
ProjNode::dump_compact_spec(st);
|
||||
st->print("(%d)%d@%d", _switch_val, _proj_no, _dest_bci);
|
||||
}
|
||||
|
||||
void JumpProjNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
// The related nodes of a JumpProjNode are its inputs and outputs at level 1.
|
||||
this->collect_nodes(in_rel, 1, false, false);
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -204,6 +204,7 @@ public:
|
||||
virtual const RegMask &out_RegMask() const;
|
||||
virtual const RegMask &in_RegMask(uint) const;
|
||||
#ifndef PRODUCT
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
#endif
|
||||
#ifdef ASSERT
|
||||
@ -229,6 +230,10 @@ public:
|
||||
virtual const Type *Value( PhaseTransform *phase ) const;
|
||||
virtual Node *Identity( PhaseTransform *phase );
|
||||
virtual const RegMask &out_RegMask() const;
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------CProjNode--------------------------------------
|
||||
@ -382,6 +387,7 @@ public:
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -393,6 +399,11 @@ public:
|
||||
protected:
|
||||
// Type of If input when this branch is always taken
|
||||
virtual bool always_taken(const TypeTuple* t) const = 0;
|
||||
|
||||
#ifndef PRODUCT
|
||||
public:
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class IfTrueNode : public IfProjNode {
|
||||
@ -455,6 +466,9 @@ public:
|
||||
virtual int Opcode() const;
|
||||
virtual const RegMask& out_RegMask() const;
|
||||
virtual const Node* is_block_proj() const { return this; }
|
||||
#ifndef PRODUCT
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class JumpProjNode : public JProjNode {
|
||||
@ -479,6 +493,8 @@ class JumpProjNode : public JProjNode {
|
||||
uint proj_no() const { return _proj_no; }
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1601,11 +1601,41 @@ Node *IfProjNode::Identity(PhaseTransform *phase) {
|
||||
return this;
|
||||
}
|
||||
|
||||
//------------------------------dump_spec--------------------------------------
|
||||
#ifndef PRODUCT
|
||||
//-------------------------------related---------------------------------------
|
||||
// An IfProjNode's related node set consists of its input (an IfNode) including
|
||||
// the IfNode's condition, plus all of its outputs at level 1. In compact mode,
|
||||
// the restrictions for IfNode apply (see IfNode::rel).
|
||||
void IfProjNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
Node* ifNode = this->in(0);
|
||||
in_rel->append(ifNode);
|
||||
if (compact) {
|
||||
ifNode->collect_nodes(in_rel, 3, false, true);
|
||||
} else {
|
||||
ifNode->collect_nodes_in_all_data(in_rel, false);
|
||||
}
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
}
|
||||
|
||||
//------------------------------dump_spec--------------------------------------
|
||||
void IfNode::dump_spec(outputStream *st) const {
|
||||
st->print("P=%f, C=%f",_prob,_fcnt);
|
||||
}
|
||||
|
||||
//-------------------------------related---------------------------------------
|
||||
// For an IfNode, the set of related output nodes is just the output nodes till
|
||||
// depth 2, i.e, the IfTrue/IfFalse projection nodes plus the nodes they refer.
|
||||
// The related input nodes contain no control nodes, but all data nodes
|
||||
// pertaining to the condition. In compact mode, the input nodes are collected
|
||||
// up to a depth of 3.
|
||||
void IfNode::related(GrowableArray <Node *> *in_rel, GrowableArray <Node *> *out_rel, bool compact) const {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 3, false, true);
|
||||
} else {
|
||||
this->collect_nodes_in_all_data(in_rel, false);
|
||||
}
|
||||
this->collect_nodes(out_rel, -2, false, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------idealize_test----------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -396,3 +396,17 @@ const Type *MoveD2LNode::Value( PhaseTransform *phase ) const {
|
||||
return TypeLong::make( v.get_jlong() );
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//----------------------------BinaryNode---------------------------------------
|
||||
// The set of related nodes for a BinaryNode is all data inputs and all outputs
|
||||
// till level 2 (i.e., one beyond the associated CMoveNode). In compact mode,
|
||||
// it's the inputs till level 1 and the outputs till level 2.
|
||||
void BinaryNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 1, false, true);
|
||||
} else {
|
||||
this->collect_nodes_in_all_data(in_rel, false);
|
||||
}
|
||||
this->collect_nodes(out_rel, -2, false, false);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -145,6 +145,10 @@ class BinaryNode : public Node {
|
||||
BinaryNode( Node *n1, Node *n2 ) : Node(0,n1,n2) { }
|
||||
virtual int Opcode() const;
|
||||
virtual uint ideal_reg() const { return 0; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -118,6 +118,20 @@ const TypePtr *ProjNode::adr_type() const {
|
||||
bool ProjNode::pinned() const { return in(0)->pinned(); }
|
||||
#ifndef PRODUCT
|
||||
void ProjNode::dump_spec(outputStream *st) const { st->print("#%d",_con); if(_is_io_use) st->print(" (i_o_use)");}
|
||||
|
||||
void ProjNode::dump_compact_spec(outputStream *st) const {
|
||||
for (DUIterator i = this->outs(); this->has_out(i); i++) {
|
||||
Node* o = this->out(i);
|
||||
if (NotANode(o)) {
|
||||
st->print("[?]");
|
||||
} else if (o == NULL) {
|
||||
st->print("[_]");
|
||||
} else {
|
||||
st->print("[%d]", o->_idx);
|
||||
}
|
||||
}
|
||||
st->print("#%d", _con);
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------check_con----------------------------------------
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,6 +87,7 @@ public:
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
#endif
|
||||
|
||||
// Return uncommon trap call node if proj is for "proj->[region->..]call_uct"
|
||||
|
@ -1489,16 +1489,6 @@ jfloat Node::getf() const {
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
//----------------------------NotANode----------------------------------------
|
||||
// Used in debugging code to avoid walking across dead or uninitialized edges.
|
||||
static inline bool NotANode(const Node* n) {
|
||||
if (n == NULL) return true;
|
||||
if (((intptr_t)n & 1) != 0) return true; // uninitialized, etc.
|
||||
if (*(address*)n == badAddress) return true; // kill by Node::destruct
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------find------------------------------------------
|
||||
// Find a neighbor of this Node with the given _idx
|
||||
// If idx is negative, find its absolute value, following both _in and _out.
|
||||
@ -1636,11 +1626,11 @@ void Node::set_debug_orig(Node* orig) {
|
||||
|
||||
//------------------------------dump------------------------------------------
|
||||
// Dump a Node
|
||||
void Node::dump(const char* suffix, outputStream *st) const {
|
||||
void Node::dump(const char* suffix, bool mark, outputStream *st) const {
|
||||
Compile* C = Compile::current();
|
||||
bool is_new = C->node_arena()->contains(this);
|
||||
C->_in_dump_cnt++;
|
||||
st->print("%c%d\t%s\t=== ", is_new ? ' ' : 'o', _idx, Name());
|
||||
st->print("%c%d%s\t%s\t=== ", is_new ? ' ' : 'o', _idx, mark ? " >" : "", Name());
|
||||
|
||||
// Dump the required and precedence inputs
|
||||
dump_req(st);
|
||||
@ -1760,42 +1750,60 @@ void Node::dump_out(outputStream *st) const {
|
||||
st->print("]] ");
|
||||
}
|
||||
|
||||
//------------------------------dump_nodes-------------------------------------
|
||||
static void dump_nodes(const Node* start, int d, bool only_ctrl) {
|
||||
Node* s = (Node*)start; // remove const
|
||||
if (NotANode(s)) return;
|
||||
|
||||
uint depth = (uint)ABS(d);
|
||||
int direction = d;
|
||||
Compile* C = Compile::current();
|
||||
GrowableArray <Node *> nstack(C->unique());
|
||||
|
||||
nstack.append(s);
|
||||
//----------------------------collect_nodes_i----------------------------------
|
||||
// Collects nodes from an Ideal graph, starting from a given start node and
|
||||
// moving in a given direction until a certain depth (distance from the start
|
||||
// node) is reached. Duplicates are ignored.
|
||||
// Arguments:
|
||||
// nstack: the nodes are collected into this array.
|
||||
// start: the node at which to start collecting.
|
||||
// direction: if this is a positive number, collect input nodes; if it is
|
||||
// a negative number, collect output nodes.
|
||||
// depth: collect nodes up to this distance from the start node.
|
||||
// include_start: whether to include the start node in the result collection.
|
||||
// only_ctrl: whether to regard control edges only during traversal.
|
||||
// only_data: whether to regard data edges only during traversal.
|
||||
static void collect_nodes_i(GrowableArray<Node*> *nstack, const Node* start, int direction, uint depth, bool include_start, bool only_ctrl, bool only_data) {
|
||||
Node* s = (Node*) start; // remove const
|
||||
nstack->append(s);
|
||||
int begin = 0;
|
||||
int end = 0;
|
||||
for(uint i = 0; i < depth; i++) {
|
||||
end = nstack.length();
|
||||
end = nstack->length();
|
||||
for(int j = begin; j < end; j++) {
|
||||
Node* tp = nstack.at(j);
|
||||
Node* tp = nstack->at(j);
|
||||
uint limit = direction > 0 ? tp->len() : tp->outcnt();
|
||||
for(uint k = 0; k < limit; k++) {
|
||||
Node* n = direction > 0 ? tp->in(k) : tp->raw_out(k);
|
||||
|
||||
if (NotANode(n)) continue;
|
||||
// do not recurse through top or the root (would reach unrelated stuff)
|
||||
if (n->is_Root() || n->is_top()) continue;
|
||||
if (n->is_Root() || n->is_top()) continue;
|
||||
if (only_ctrl && !n->is_CFG()) continue;
|
||||
if (only_data && n->is_CFG()) continue;
|
||||
|
||||
bool on_stack = nstack.contains(n);
|
||||
bool on_stack = nstack->contains(n);
|
||||
if (!on_stack) {
|
||||
nstack.append(n);
|
||||
nstack->append(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
begin = end;
|
||||
}
|
||||
end = nstack.length();
|
||||
if (direction > 0) {
|
||||
if (!include_start) {
|
||||
nstack->remove(s);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------dump_nodes-------------------------------------
|
||||
static void dump_nodes(const Node* start, int d, bool only_ctrl) {
|
||||
if (NotANode(start)) return;
|
||||
|
||||
GrowableArray <Node *> nstack(Compile::current()->unique());
|
||||
collect_nodes_i(&nstack, start, d, (uint) ABS(d), true, only_ctrl, false);
|
||||
|
||||
int end = nstack.length();
|
||||
if (d > 0) {
|
||||
for(int j = end-1; j >= 0; j--) {
|
||||
nstack.at(j)->dump();
|
||||
}
|
||||
@ -1817,6 +1825,221 @@ void Node::dump_ctrl(int d) const {
|
||||
dump_nodes(this, d, true);
|
||||
}
|
||||
|
||||
//-----------------------------dump_compact------------------------------------
|
||||
void Node::dump_comp() const {
|
||||
this->dump_comp("\n");
|
||||
}
|
||||
|
||||
//-----------------------------dump_compact------------------------------------
|
||||
// Dump a Node in compact representation, i.e., just print its name and index.
|
||||
// Nodes can specify additional specifics to print in compact representation by
|
||||
// implementing dump_compact_spec.
|
||||
void Node::dump_comp(const char* suffix, outputStream *st) const {
|
||||
Compile* C = Compile::current();
|
||||
C->_in_dump_cnt++;
|
||||
st->print("%s(%d)", Name(), _idx);
|
||||
this->dump_compact_spec(st);
|
||||
if (suffix) {
|
||||
st->print("%s", suffix);
|
||||
}
|
||||
C->_in_dump_cnt--;
|
||||
}
|
||||
|
||||
//----------------------------dump_related-------------------------------------
|
||||
// Dump a Node's related nodes - the notion of "related" depends on the Node at
|
||||
// hand and is determined by the implementation of the virtual method rel.
|
||||
void Node::dump_related() const {
|
||||
Compile* C = Compile::current();
|
||||
GrowableArray <Node *> in_rel(C->unique());
|
||||
GrowableArray <Node *> out_rel(C->unique());
|
||||
this->related(&in_rel, &out_rel, false);
|
||||
for (int i = in_rel.length() - 1; i >= 0; i--) {
|
||||
in_rel.at(i)->dump();
|
||||
}
|
||||
this->dump("\n", true);
|
||||
for (int i = 0; i < out_rel.length(); i++) {
|
||||
out_rel.at(i)->dump();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------dump_related-------------------------------------
|
||||
// Dump a Node's related nodes up to a given depth (distance from the start
|
||||
// node).
|
||||
// Arguments:
|
||||
// d_in: depth for input nodes.
|
||||
// d_out: depth for output nodes (note: this also is a positive number).
|
||||
void Node::dump_related(uint d_in, uint d_out) const {
|
||||
Compile* C = Compile::current();
|
||||
GrowableArray <Node *> in_rel(C->unique());
|
||||
GrowableArray <Node *> out_rel(C->unique());
|
||||
|
||||
// call collect_nodes_i directly
|
||||
collect_nodes_i(&in_rel, this, 1, d_in, false, false, false);
|
||||
collect_nodes_i(&out_rel, this, -1, d_out, false, false, false);
|
||||
|
||||
for (int i = in_rel.length() - 1; i >= 0; i--) {
|
||||
in_rel.at(i)->dump();
|
||||
}
|
||||
this->dump("\n", true);
|
||||
for (int i = 0; i < out_rel.length(); i++) {
|
||||
out_rel.at(i)->dump();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------dump_related_compact---------------------------------
|
||||
// Dump a Node's related nodes in compact representation. The notion of
|
||||
// "related" depends on the Node at hand and is determined by the implementation
|
||||
// of the virtual method rel.
|
||||
void Node::dump_related_compact() const {
|
||||
Compile* C = Compile::current();
|
||||
GrowableArray <Node *> in_rel(C->unique());
|
||||
GrowableArray <Node *> out_rel(C->unique());
|
||||
this->related(&in_rel, &out_rel, true);
|
||||
int n_in = in_rel.length();
|
||||
int n_out = out_rel.length();
|
||||
|
||||
this->dump_comp(n_in == 0 ? "\n" : " ");
|
||||
for (int i = 0; i < n_in; i++) {
|
||||
in_rel.at(i)->dump_comp(i == n_in - 1 ? "\n" : " ");
|
||||
}
|
||||
for (int i = 0; i < n_out; i++) {
|
||||
out_rel.at(i)->dump_comp(i == n_out - 1 ? "\n" : " ");
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------related----------------------------------------
|
||||
// Collect a Node's related nodes. The default behaviour just collects the
|
||||
// inputs and outputs at depth 1, including both control and data flow edges,
|
||||
// regardless of whether the presentation is compact or not. For data nodes,
|
||||
// the default is to collect all data inputs (till level 1 if compact), and
|
||||
// outputs till level 1.
|
||||
void Node::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
if (this->is_CFG()) {
|
||||
collect_nodes_i(in_rel, this, 1, 1, false, false, false);
|
||||
collect_nodes_i(out_rel, this, -1, 1, false, false, false);
|
||||
} else {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 1, false, true);
|
||||
} else {
|
||||
this->collect_nodes_in_all_data(in_rel, false);
|
||||
}
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------collect_nodes-------------------------------------
|
||||
// An entry point to the low-level node collection facility, to start from a
|
||||
// given node in the graph. The start node is by default not included in the
|
||||
// result.
|
||||
// Arguments:
|
||||
// ns: collect the nodes into this data structure.
|
||||
// d: the depth (distance from start node) to which nodes should be
|
||||
// collected. A value >0 indicates input nodes, a value <0, output
|
||||
// nodes.
|
||||
// ctrl: include only control nodes.
|
||||
// data: include only data nodes.
|
||||
void Node::collect_nodes(GrowableArray<Node*> *ns, int d, bool ctrl, bool data) const {
|
||||
if (ctrl && data) {
|
||||
// ignore nonsensical combination
|
||||
return;
|
||||
}
|
||||
collect_nodes_i(ns, this, d, (uint) ABS(d), false, ctrl, data);
|
||||
}
|
||||
|
||||
//--------------------------collect_nodes_in-----------------------------------
|
||||
static void collect_nodes_in(Node* start, GrowableArray<Node*> *ns, bool primary_is_data, bool collect_secondary) {
|
||||
// The maximum depth is determined using a BFS that visits all primary (data
|
||||
// or control) inputs and increments the depth at each level.
|
||||
uint d_in = 0;
|
||||
GrowableArray<Node*> nodes(Compile::current()->unique());
|
||||
nodes.push(start);
|
||||
int nodes_at_current_level = 1;
|
||||
int n_idx = 0;
|
||||
while (nodes_at_current_level > 0) {
|
||||
// Add all primary inputs reachable from the current level to the list, and
|
||||
// increase the depth if there were any.
|
||||
int nodes_at_next_level = 0;
|
||||
bool nodes_added = false;
|
||||
while (nodes_at_current_level > 0) {
|
||||
nodes_at_current_level--;
|
||||
Node* current = nodes.at(n_idx++);
|
||||
for (uint i = 0; i < current->len(); i++) {
|
||||
Node* n = current->in(i);
|
||||
if (NotANode(n)) {
|
||||
continue;
|
||||
}
|
||||
if ((primary_is_data && n->is_CFG()) || (!primary_is_data && !n->is_CFG())) {
|
||||
continue;
|
||||
}
|
||||
if (!nodes.contains(n)) {
|
||||
nodes.push(n);
|
||||
nodes_added = true;
|
||||
nodes_at_next_level++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nodes_added) {
|
||||
d_in++;
|
||||
}
|
||||
nodes_at_current_level = nodes_at_next_level;
|
||||
}
|
||||
start->collect_nodes(ns, d_in, !primary_is_data, primary_is_data);
|
||||
if (collect_secondary) {
|
||||
// Now, iterate over the secondary nodes in ns and add the respective
|
||||
// boundary reachable from them.
|
||||
GrowableArray<Node*> sns(Compile::current()->unique());
|
||||
for (GrowableArrayIterator<Node*> it = ns->begin(); it != ns->end(); ++it) {
|
||||
Node* n = *it;
|
||||
n->collect_nodes(&sns, 1, primary_is_data, !primary_is_data);
|
||||
for (GrowableArrayIterator<Node*> d = sns.begin(); d != sns.end(); ++d) {
|
||||
ns->append_if_missing(*d);
|
||||
}
|
||||
sns.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------collect_nodes_in_all_data-------------------------------
|
||||
// Collect the entire data input graph. Include the control boundary if
|
||||
// requested.
|
||||
// Arguments:
|
||||
// ns: collect the nodes into this data structure.
|
||||
// ctrl: if true, include the control boundary.
|
||||
void Node::collect_nodes_in_all_data(GrowableArray<Node*> *ns, bool ctrl) const {
|
||||
collect_nodes_in((Node*) this, ns, true, ctrl);
|
||||
}
|
||||
|
||||
//--------------------------collect_nodes_in_all_ctrl--------------------------
|
||||
// Collect the entire control input graph. Include the data boundary if
|
||||
// requested.
|
||||
// ns: collect the nodes into this data structure.
|
||||
// data: if true, include the control boundary.
|
||||
void Node::collect_nodes_in_all_ctrl(GrowableArray<Node*> *ns, bool data) const {
|
||||
collect_nodes_in((Node*) this, ns, false, data);
|
||||
}
|
||||
|
||||
//------------------collect_nodes_out_all_ctrl_boundary------------------------
|
||||
// Collect the entire output graph until hitting control node boundaries, and
|
||||
// include those.
|
||||
void Node::collect_nodes_out_all_ctrl_boundary(GrowableArray<Node*> *ns) const {
|
||||
// Perform a BFS and stop at control nodes.
|
||||
GrowableArray<Node*> nodes(Compile::current()->unique());
|
||||
nodes.push((Node*) this);
|
||||
while (nodes.length() > 0) {
|
||||
Node* current = nodes.pop();
|
||||
if (NotANode(current)) {
|
||||
continue;
|
||||
}
|
||||
ns->append_if_missing(current);
|
||||
if (!current->is_CFG()) {
|
||||
for (DUIterator i = current->outs(); current->has_out(i); i++) {
|
||||
nodes.push(current->out(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
ns->remove((Node*) this);
|
||||
}
|
||||
|
||||
// VERIFICATION CODE
|
||||
// For each input edge to a node (ie - for each Use-Def edge), verify that
|
||||
// there is a corresponding Def-Use edge.
|
||||
@ -2173,6 +2396,11 @@ void TypeNode::dump_spec(outputStream *st) const {
|
||||
st->print(" #"); _type->dump_on(st);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeNode::dump_compact_spec(outputStream *st) const {
|
||||
st->print("#");
|
||||
_type->dump_on(st);
|
||||
}
|
||||
#endif
|
||||
uint TypeNode::hash() const {
|
||||
return Node::hash() + _type->hash();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1038,13 +1038,35 @@ public:
|
||||
Node* find(int idx) const; // Search the graph for the given idx.
|
||||
Node* find_ctrl(int idx) const; // Search control ancestors for the given idx.
|
||||
void dump() const { dump("\n"); } // Print this node.
|
||||
void dump(const char* suffix, outputStream *st = tty) const;// Print this node.
|
||||
void dump(const char* suffix, bool mark = false, outputStream *st = tty) const; // Print this node.
|
||||
void dump(int depth) const; // Print this node, recursively to depth d
|
||||
void dump_ctrl(int depth) const; // Print control nodes, to depth d
|
||||
virtual void dump_req(outputStream *st = tty) const; // Print required-edge info
|
||||
virtual void dump_prec(outputStream *st = tty) const; // Print precedence-edge info
|
||||
virtual void dump_out(outputStream *st = tty) const; // Print the output edge info
|
||||
virtual void dump_spec(outputStream *st) const {}; // Print per-node info
|
||||
void dump_comp() const; // Print this node in compact representation.
|
||||
// Print this node in compact representation.
|
||||
void dump_comp(const char* suffix, outputStream *st = tty) const;
|
||||
virtual void dump_req(outputStream *st = tty) const; // Print required-edge info
|
||||
virtual void dump_prec(outputStream *st = tty) const; // Print precedence-edge info
|
||||
virtual void dump_out(outputStream *st = tty) const; // Print the output edge info
|
||||
virtual void dump_spec(outputStream *st) const {}; // Print per-node info
|
||||
// Print compact per-node info
|
||||
virtual void dump_compact_spec(outputStream *st) const { dump_spec(st); }
|
||||
void dump_related() const; // Print related nodes (depends on node at hand).
|
||||
// Print related nodes up to given depths for input and output nodes.
|
||||
void dump_related(uint d_in, uint d_out) const;
|
||||
void dump_related_compact() const; // Print related nodes in compact representation.
|
||||
// Collect related nodes.
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
// Collect nodes starting from this node, explicitly including/excluding control and data links.
|
||||
void collect_nodes(GrowableArray<Node*> *ns, int d, bool ctrl, bool data) const;
|
||||
|
||||
// Node collectors, to be used in implementations of Node::rel().
|
||||
// Collect the entire data input graph. Include control inputs if requested.
|
||||
void collect_nodes_in_all_data(GrowableArray<Node*> *ns, bool ctrl) const;
|
||||
// Collect the entire control input graph. Include data inputs if requested.
|
||||
void collect_nodes_in_all_ctrl(GrowableArray<Node*> *ns, bool data) const;
|
||||
// Collect the entire output graph until hitting and including control nodes.
|
||||
void collect_nodes_out_all_ctrl_boundary(GrowableArray<Node*> *ns) const;
|
||||
|
||||
void verify_edges(Unique_Node_List &visited); // Verify bi-directional edges
|
||||
void verify() const; // Check Def-Use info for my subgraph
|
||||
static void verify_recur(const Node *n, int verify_depth, VectorSet &old_space, VectorSet &new_space);
|
||||
@ -1091,6 +1113,20 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
// Used in debugging code to avoid walking across dead or uninitialized edges.
|
||||
inline bool NotANode(const Node* n) {
|
||||
if (n == NULL) return true;
|
||||
if (((intptr_t)n & 1) != 0) return true; // uninitialized, etc.
|
||||
if (*(address*)n == badAddress) return true; // kill by Node::destruct
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Iterators over DU info, and associated Node functions.
|
||||
|
||||
@ -1618,6 +1654,7 @@ public:
|
||||
virtual uint ideal_reg() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void dump_compact_spec(outputStream *st) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -88,3 +88,18 @@ const Type *HaltNode::Value( PhaseTransform *phase ) const {
|
||||
const RegMask &HaltNode::out_RegMask() const {
|
||||
return RegMask::Empty;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//-----------------------------related-----------------------------------------
|
||||
// Include all control inputs in the related set, and also the input data
|
||||
// boundary. In compact mode, include all inputs till level 2. Also include
|
||||
// all outputs at level 1.
|
||||
void HaltNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 2, false, false);
|
||||
} else {
|
||||
this->collect_nodes_in_all_ctrl(in_rel, true);
|
||||
}
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,6 +64,10 @@ public:
|
||||
virtual const RegMask &out_RegMask() const;
|
||||
virtual uint ideal_reg() const { return NotAMachineReg; }
|
||||
virtual uint match_edge(uint idx) const { return 0; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_OPTO_ROOTNODE_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -498,6 +498,37 @@ Node *CmpNode::Identity( PhaseTransform *phase ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//----------------------------related------------------------------------------
|
||||
// Related nodes of comparison nodes include all data inputs (until hitting a
|
||||
// control boundary) as well as all outputs until and including control nodes
|
||||
// as well as their projections. In compact mode, data inputs till depth 1 and
|
||||
// all outputs till depth 1 are considered.
|
||||
void CmpNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 1, false, true);
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
} else {
|
||||
this->collect_nodes_in_all_data(in_rel, false);
|
||||
this->collect_nodes_out_all_ctrl_boundary(out_rel);
|
||||
// Now, find all control nodes in out_rel, and include their projections
|
||||
// and projection targets (if any) in the result.
|
||||
GrowableArray<Node*> proj(Compile::current()->unique());
|
||||
for (GrowableArrayIterator<Node*> it = out_rel->begin(); it != out_rel->end(); ++it) {
|
||||
Node* n = *it;
|
||||
if (n->is_CFG() && !n->is_Proj()) {
|
||||
// Assume projections and projection targets are found at levels 1 and 2.
|
||||
n->collect_nodes(&proj, -2, false, false);
|
||||
for (GrowableArrayIterator<Node*> p = proj.begin(); p != proj.end(); ++p) {
|
||||
out_rel->append_if_missing(*p);
|
||||
}
|
||||
proj.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------cmp--------------------------------------------
|
||||
// Simplify a CmpI (compare 2 integers) node, based on local information.
|
||||
@ -1396,17 +1427,31 @@ const Type *BoolNode::Value( PhaseTransform *phase ) const {
|
||||
return _test.cc2logical( phase->type( in(1) ) );
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
//------------------------------dump_spec--------------------------------------
|
||||
// Dump special per-node info
|
||||
#ifndef PRODUCT
|
||||
void BoolNode::dump_spec(outputStream *st) const {
|
||||
st->print("[");
|
||||
_test.dump_on(st);
|
||||
st->print("]");
|
||||
}
|
||||
|
||||
//-------------------------------related---------------------------------------
|
||||
// A BoolNode's related nodes are all of its data inputs, and all of its
|
||||
// outputs until control nodes are hit, which are included. In compact
|
||||
// representation, inputs till level 3 and immediate outputs are included.
|
||||
void BoolNode::related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const {
|
||||
if (compact) {
|
||||
this->collect_nodes(in_rel, 3, false, true);
|
||||
this->collect_nodes(out_rel, -1, false, false);
|
||||
} else {
|
||||
this->collect_nodes_in_all_data(in_rel, false);
|
||||
this->collect_nodes_out_all_ctrl_boundary(out_rel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------is_counted_loop_exit_test--------------------------------------
|
||||
//----------------------is_counted_loop_exit_test------------------------------
|
||||
// Returns true if node is used by a counted loop node.
|
||||
bool BoolNode::is_counted_loop_exit_test() {
|
||||
for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,7 +60,6 @@ public:
|
||||
// Supplied function to return the additive identity type.
|
||||
// This is returned whenever the subtracts inputs are the same.
|
||||
virtual const Type *add_id() const = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -140,6 +139,13 @@ public:
|
||||
const Type *add_id() const { return TypeInt::ZERO; }
|
||||
const Type *bottom_type() const { return TypeInt::CC; }
|
||||
virtual uint ideal_reg() const { return Op_RegFlags; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
// CmpNode and subclasses include all data inputs (until hitting a control
|
||||
// boundary) in their related node set, as well as all outputs until and
|
||||
// including eventual control nodes and their projections.
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
//------------------------------CmpINode---------------------------------------
|
||||
@ -311,6 +317,7 @@ public:
|
||||
bool is_counted_loop_exit_test();
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
virtual void related(GrowableArray<Node*> *in_rel, GrowableArray<Node*> *out_rel, bool compact) const;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user