8282024: add EscapeAnalysis statistics under PrintOptoStatistics
Reviewed-by: xliu, kvn
This commit is contained in:
parent
cdb476888a
commit
2f19144249
@ -254,6 +254,8 @@ void Compile::print_statistics() {
|
||||
PhaseOutput::print_statistics();
|
||||
PhasePeephole::print_statistics();
|
||||
PhaseIdealLoop::print_statistics();
|
||||
ConnectionGraph::print_statistics();
|
||||
PhaseMacroExpand::print_statistics();
|
||||
if (xtty != NULL) xtty->tail("statistics");
|
||||
}
|
||||
if (_intrinsic_hist_flags[as_int(vmIntrinsics::_none)] != 0) {
|
||||
|
@ -233,6 +233,7 @@ bool ConnectionGraph::compute_escape() {
|
||||
|
||||
if (non_escaped_allocs_worklist.length() == 0) {
|
||||
_collecting = false;
|
||||
NOT_PRODUCT(escape_state_statistics(java_objects_worklist);)
|
||||
return false; // Nothing to do.
|
||||
}
|
||||
// Add final simple edges to graph.
|
||||
@ -262,7 +263,10 @@ bool ConnectionGraph::compute_escape() {
|
||||
// processing, calls to CI to resolve symbols (types, fields, methods)
|
||||
// referenced in bytecode. During symbol resolution VM may throw
|
||||
// an exception which CI cleans and converts to compilation failure.
|
||||
if (C->failing()) return false;
|
||||
if (C->failing()) {
|
||||
NOT_PRODUCT(escape_state_statistics(java_objects_worklist);)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Finish Graph construction by propagating references to all
|
||||
// java objects through graph.
|
||||
@ -270,6 +274,7 @@ bool ConnectionGraph::compute_escape() {
|
||||
java_objects_worklist, oop_fields_worklist)) {
|
||||
// All objects escaped or hit time or iterations limits.
|
||||
_collecting = false;
|
||||
NOT_PRODUCT(escape_state_statistics(java_objects_worklist);)
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -339,7 +344,10 @@ bool ConnectionGraph::compute_escape() {
|
||||
// Now use the escape information to create unique types for
|
||||
// scalar replaceable objects.
|
||||
split_unique_types(alloc_worklist, arraycopy_worklist, mergemem_worklist);
|
||||
if (C->failing()) return false;
|
||||
if (C->failing()) {
|
||||
NOT_PRODUCT(escape_state_statistics(java_objects_worklist);)
|
||||
return false;
|
||||
}
|
||||
C->print_method(PHASE_AFTER_EA, 2);
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -375,6 +383,7 @@ bool ConnectionGraph::compute_escape() {
|
||||
}
|
||||
}
|
||||
|
||||
NOT_PRODUCT(escape_state_statistics(java_objects_worklist);)
|
||||
return has_non_escaping_obj;
|
||||
}
|
||||
|
||||
@ -3673,6 +3682,10 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
int ConnectionGraph::_no_escape_counter = 0;
|
||||
int ConnectionGraph::_arg_escape_counter = 0;
|
||||
int ConnectionGraph::_global_escape_counter = 0;
|
||||
|
||||
static const char *node_type_names[] = {
|
||||
"UnknownType",
|
||||
"JavaObject",
|
||||
@ -3781,6 +3794,30 @@ void ConnectionGraph::dump(GrowableArray<PointsToNode*>& ptnodes_worklist) {
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionGraph::print_statistics() {
|
||||
tty->print_cr("No escape = %d, Arg escape = %d, Global escape = %d", Atomic::load(&_no_escape_counter), Atomic::load(&_arg_escape_counter), Atomic::load(&_global_escape_counter));
|
||||
}
|
||||
|
||||
void ConnectionGraph::escape_state_statistics(GrowableArray<JavaObjectNode*>& java_objects_worklist) {
|
||||
if (!PrintOptoStatistics || (_invocation > 0)) { // Collect data only for the first invocation
|
||||
return;
|
||||
}
|
||||
for (int next = 0; next < java_objects_worklist.length(); ++next) {
|
||||
JavaObjectNode* ptn = java_objects_worklist.at(next);
|
||||
if (ptn->ideal_node()->is_Allocate()) {
|
||||
if (ptn->escape_state() == PointsToNode::NoEscape) {
|
||||
Atomic::inc(&ConnectionGraph::_no_escape_counter);
|
||||
} else if (ptn->escape_state() == PointsToNode::ArgEscape) {
|
||||
Atomic::inc(&ConnectionGraph::_arg_escape_counter);
|
||||
} else if (ptn->escape_state() == PointsToNode::GlobalEscape) {
|
||||
Atomic::inc(&ConnectionGraph::_global_escape_counter);
|
||||
} else {
|
||||
assert(false, "Unexpected Escape State");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectionGraph::trace_es_update_helper(PointsToNode* ptn, PointsToNode::EscapeState es, bool fields, const char* reason) const {
|
||||
if (_compile->directive()->TraceEscapeAnalysisOption) {
|
||||
assert(ptn != nullptr, "should not be null");
|
||||
|
@ -636,7 +636,12 @@ public:
|
||||
bool add_final_edges_unsafe_access(Node* n, uint opcode);
|
||||
|
||||
#ifndef PRODUCT
|
||||
static int _no_escape_counter;
|
||||
static int _arg_escape_counter;
|
||||
static int _global_escape_counter;
|
||||
void dump(GrowableArray<PointsToNode*>& ptnodes_worklist);
|
||||
static void print_statistics();
|
||||
void escape_state_statistics(GrowableArray<JavaObjectNode*>& java_objects_worklist);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -160,6 +160,11 @@ CallNode* PhaseMacroExpand::make_slow_call(CallNode *oldcall, const TypeFunc* sl
|
||||
void PhaseMacroExpand::eliminate_gc_barrier(Node* p2x) {
|
||||
BarrierSetC2 *bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
bs->eliminate_gc_barrier(this, p2x);
|
||||
#ifndef PRODUCT
|
||||
if (PrintOptoStatistics) {
|
||||
Atomic::inc(&PhaseMacroExpand::_GC_barriers_removed_counter);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Search for a memory operation for the specified memory slice.
|
||||
@ -2339,6 +2344,7 @@ void PhaseMacroExpand::expand_subtypecheck_node(SubTypeCheckNode *check) {
|
||||
void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||
if (C->macro_count() == 0)
|
||||
return;
|
||||
NOT_PRODUCT(int membar_before = count_MemBar(C);)
|
||||
|
||||
// Before elimination may re-mark (change to Nested or NonEscObj)
|
||||
// all associated (same box and obj) lock and unlock nodes.
|
||||
@ -2364,6 +2370,11 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||
DEBUG_ONLY(int old_macro_count = C->macro_count();)
|
||||
if (n->is_AbstractLock()) {
|
||||
success = eliminate_locking_node(n->as_AbstractLock());
|
||||
#ifndef PRODUCT
|
||||
if (success && PrintOptoStatistics) {
|
||||
Atomic::inc(&PhaseMacroExpand::_monitor_objects_removed_counter);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
|
||||
progress = progress || success;
|
||||
@ -2382,6 +2393,11 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||
case Node::Class_Allocate:
|
||||
case Node::Class_AllocateArray:
|
||||
success = eliminate_allocate_node(n->as_Allocate());
|
||||
#ifndef PRODUCT
|
||||
if (success && PrintOptoStatistics) {
|
||||
Atomic::inc(&PhaseMacroExpand::_objs_scalar_replaced_counter);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case Node::Class_CallStaticJava:
|
||||
success = eliminate_boxing_node(n->as_CallStaticJava());
|
||||
@ -2411,6 +2427,12 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
|
||||
progress = progress || success;
|
||||
}
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
if (PrintOptoStatistics) {
|
||||
int membar_after = count_MemBar(C);
|
||||
Atomic::add(&PhaseMacroExpand::_memory_barriers_removed_counter, membar_before - membar_after);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//------------------------------expand_macro_nodes----------------------
|
||||
@ -2599,3 +2621,38 @@ bool PhaseMacroExpand::expand_macro_nodes() {
|
||||
_igvn.set_delay_transform(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
int PhaseMacroExpand::_objs_scalar_replaced_counter = 0;
|
||||
int PhaseMacroExpand::_monitor_objects_removed_counter = 0;
|
||||
int PhaseMacroExpand::_GC_barriers_removed_counter = 0;
|
||||
int PhaseMacroExpand::_memory_barriers_removed_counter = 0;
|
||||
|
||||
void PhaseMacroExpand::print_statistics() {
|
||||
tty->print("Objects scalar replaced = %d, ", Atomic::load(&_objs_scalar_replaced_counter));
|
||||
tty->print("Monitor objects removed = %d, ", Atomic::load(&_monitor_objects_removed_counter));
|
||||
tty->print("GC barriers removed = %d, ", Atomic::load(&_GC_barriers_removed_counter));
|
||||
tty->print_cr("Memory barriers removed = %d", Atomic::load(&_memory_barriers_removed_counter));
|
||||
}
|
||||
|
||||
int PhaseMacroExpand::count_MemBar(Compile *C) {
|
||||
if (!PrintOptoStatistics) {
|
||||
return 0;
|
||||
}
|
||||
Unique_Node_List ideal_nodes;
|
||||
int total = 0;
|
||||
ideal_nodes.map(C->live_nodes(), NULL);
|
||||
ideal_nodes.push(C->root());
|
||||
for (uint next = 0; next < ideal_nodes.size(); ++next) {
|
||||
Node* n = ideal_nodes.at(next);
|
||||
if (n->is_MemBar()) {
|
||||
total++;
|
||||
}
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
Node* m = n->fast_out(i);
|
||||
ideal_nodes.push(m);
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
#endif
|
||||
|
@ -208,6 +208,15 @@ public:
|
||||
|
||||
PhaseIterGVN &igvn() const { return _igvn; }
|
||||
|
||||
#ifndef PRODUCT
|
||||
static int _objs_scalar_replaced_counter;
|
||||
static int _monitor_objects_removed_counter;
|
||||
static int _GC_barriers_removed_counter;
|
||||
static int _memory_barriers_removed_counter;
|
||||
static void print_statistics();
|
||||
static int count_MemBar(Compile *C);
|
||||
#endif
|
||||
|
||||
// Members accessed from BarrierSetC2
|
||||
void replace_node(Node* source, Node* target) { _igvn.replace_node(source, target); }
|
||||
Node* intcon(jint con) const { return _igvn.intcon(con); }
|
||||
|
Loading…
Reference in New Issue
Block a user