提交 571459e9 编写于 作者: K kvn

6684714: Optimize EA Connection Graph build performance

Summary: switch on EA by default, optimize Connection Graph construction
Reviewed-by: rasbold, never
上级 cb80591f
......@@ -188,10 +188,6 @@ void OopMap::set_derived_oop(VMReg reg, VMReg derived_from_local_register ) {
}
}
void OopMap::set_stack_obj(VMReg reg) {
set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad());
}
// OopMapSet
OopMapSet::OopMapSet() {
......@@ -399,8 +395,7 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
if ( loc != NULL ) {
if ( omv.type() == OopMapValue::oop_value ) {
#ifdef ASSERT
if (COMPILER2_PRESENT(!DoEscapeAnalysis &&)
(((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
!Universe::heap()->is_in_or_null(*loc)) {
tty->print_cr("# Found non oop pointer. Dumping state at failure");
// try to dump out some helpful debugging information
......@@ -431,17 +426,6 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
}
}
}
#ifdef COMPILER2
if (DoEscapeAnalysis) {
for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) {
omv = oms.current();
assert(omv.is_stack_loc(), "should refer to stack location");
oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map);
oop_fn->do_oop(&loc);
}
}
#endif // COMPILER2
}
......@@ -540,9 +524,6 @@ void print_register_type(OopMapValue::oop_types x, VMReg optional,
st->print("Derived_oop_" );
optional->print_on(st);
break;
case OopMapValue::stack_obj:
st->print("Stack");
break;
default:
ShouldNotReachHere();
}
......
......@@ -46,7 +46,7 @@ private:
public:
// Constants
enum { type_bits = 6,
enum { type_bits = 5,
register_bits = BitsPerShort - type_bits };
enum { type_shift = 0,
......@@ -63,8 +63,7 @@ public:
value_value = 2,
narrowoop_value = 4,
callee_saved_value = 8,
derived_oop_value= 16,
stack_obj = 32 };
derived_oop_value= 16 };
// Constructors
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
......@@ -93,14 +92,12 @@ public:
bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; }
void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
void set_value() { set_value((value() & register_mask_in_place) | value_value); }
void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); }
VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
......@@ -180,7 +177,6 @@ class OopMap: public ResourceObj {
void set_dead ( VMReg local);
void set_callee_saved( VMReg local, VMReg caller_machine_register );
void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
void set_stack_obj( VMReg local);
void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
int heap_size() const;
......
......@@ -83,7 +83,7 @@ static bool is_init_with_ea(ciMethod* callee_method,
ciMethod* caller_method, Compile* C) {
// True when EA is ON and a java constructor is called or
// a super constructor is called from an inlined java constructor.
return DoEscapeAnalysis && EliminateAllocations &&
return C->do_escape_analysis() && EliminateAllocations &&
( callee_method->is_initializer() ||
(caller_method->is_initializer() &&
caller_method != C->method() &&
......
......@@ -373,7 +373,7 @@
product(intx, AutoBoxCacheMax, 128, \
"Sets max value cached by the java.lang.Integer autobox cache") \
\
product(bool, DoEscapeAnalysis, false, \
product(bool, DoEscapeAnalysis, true, \
"Perform escape analysis") \
\
notproduct(bool, PrintEscapeAnalysis, false, \
......
......@@ -583,18 +583,22 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
NOT_PRODUCT( verify_graph_edges(); )
// Perform escape analysis
if (_do_escape_analysis)
_congraph = new ConnectionGraph(this);
if (_congraph != NULL) {
NOT_PRODUCT( TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, TimeCompiler); )
_congraph->compute_escape();
if (failing()) return;
if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
_congraph = new(comp_arena()) ConnectionGraph(this);
bool has_non_escaping_obj = _congraph->compute_escape();
#ifndef PRODUCT
if (PrintEscapeAnalysis) {
_congraph->dump();
}
#endif
if (!has_non_escaping_obj) {
_congraph = NULL;
}
if (failing()) return;
}
// Now optimize
Optimize();
......
此差异已折叠。
......@@ -178,14 +178,24 @@ public:
// count of outgoing edges
uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
// node index of target of outgoing edge "e"
uint edge_target(uint e) const;
uint edge_target(uint e) const {
assert(_edges != NULL, "valid edge index");
return (_edges->at(e) >> EdgeShift);
}
// type of outgoing edge "e"
EdgeType edge_type(uint e) const;
EdgeType edge_type(uint e) const {
assert(_edges != NULL, "valid edge index");
return (EdgeType) (_edges->at(e) & EdgeMask);
}
// add a edge of the specified type pointing to the specified target
void add_edge(uint targIdx, EdgeType et);
// remove an edge of the specified type pointing to the specified target
void remove_edge(uint targIdx, EdgeType et);
#ifndef PRODUCT
void dump() const;
#endif
......@@ -194,7 +204,7 @@ public:
class ConnectionGraph: public ResourceObj {
private:
GrowableArray<PointsToNode>* _nodes; // Connection graph nodes indexed
GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed
// by ideal node index.
Unique_Node_List _delayed_worklist; // Nodes to be processed before
......@@ -207,9 +217,6 @@ private:
// is still being collected. If false,
// no new nodes will be processed.
bool _has_allocations; // Indicates whether method has any
// non-escaping allocations.
uint _phantom_object; // Index of globally escaping object
// that pointer values loaded from
// a field which has not been set
......@@ -217,14 +224,13 @@ private:
Compile * _compile; // Compile object for current compilation
// address of an element in _nodes. Used when the element is to be modified
PointsToNode *ptnode_adr(uint idx) {
if ((uint)_nodes->length() <= idx) {
// expand _nodes array
PointsToNode dummy = _nodes->at_grow(idx);
}
return _nodes->adr_at(idx);
// Address of an element in _nodes. Used when the element is to be modified
PointsToNode *ptnode_adr(uint idx) const {
// There should be no new ideal nodes during ConnectionGraph build,
// growableArray::adr_at() will throw assert otherwise.
return _nodes.adr_at(idx);
}
uint nodes_size() const { return _nodes.length(); }
// Add node to ConnectionGraph.
void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
......@@ -307,30 +313,30 @@ private:
// Set the escape state of a node
void set_escape_state(uint ni, PointsToNode::EscapeState es);
// Get Compile object for current compilation.
Compile *C() const { return _compile; }
public:
ConnectionGraph(Compile *C);
// Check for non-escaping candidates
static bool has_candidates(Compile *C);
// Compute the escape information
void compute_escape();
bool compute_escape();
// escape state of a node
PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase);
// other information we have collected
bool is_scalar_replaceable(Node *n) {
if (_collecting)
if (_collecting || (n->_idx >= nodes_size()))
return false;
PointsToNode ptn = _nodes->at_grow(n->_idx);
return ptn.escape_state() == PointsToNode::NoEscape && ptn._scalar_replaceable;
PointsToNode* ptn = ptnode_adr(n->_idx);
return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable;
}
bool hidden_alias(Node *n) {
if (_collecting)
if (_collecting || (n->_idx >= nodes_size()))
return true;
PointsToNode ptn = _nodes->at_grow(n->_idx);
return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias;
PointsToNode* ptn = ptnode_adr(n->_idx);
return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias;
}
#ifndef PRODUCT
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册