diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp index 61aa009361f..fb3b5dba42c 100644 --- a/src/hotspot/share/opto/escape.cpp +++ b/src/hotspot/share/opto/escape.cpp @@ -114,11 +114,13 @@ void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) { invocation = C->congraph()->_invocation + 1; } ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn, invocation); + NOT_PRODUCT(if (C->should_print_igv(/* Any level */ 1)) C->igv_printer()->set_congraph(congraph);) // Perform escape analysis if (congraph->compute_escape()) { // There are non escaping objects. C->set_congraph(congraph); } + NOT_PRODUCT(if (C->should_print_igv(/* Any level */ 1)) C->igv_printer()->set_congraph(nullptr);) // Cleanup. if (oop_null->outcnt() == 0) { igvn->hash_delete(oop_null); @@ -126,6 +128,8 @@ void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) { if (noop_null->outcnt() == 0) { igvn->hash_delete(noop_null); } + + C->print_method(PHASE_AFTER_EA, 2); } bool ConnectionGraph::compute_escape() { @@ -281,6 +285,8 @@ bool ConnectionGraph::compute_escape() { return false; } + _compile->print_method(PHASE_EA_AFTER_INITIAL_CONGRAPH, 4); + // 2. Finish Graph construction by propagating references to all // java objects through graph. if (!complete_connection_graph(ptnodes_worklist, non_escaped_allocs_worklist, @@ -291,6 +297,8 @@ bool ConnectionGraph::compute_escape() { return false; } + _compile->print_method(PHASE_EA_AFTER_COMPLETE_CONGRAPH, 4); + // 3. Adjust scalar_replaceable state of nonescaping objects and push // scalar replaceable allocations on alloc_worklist for processing // in split_unique_types(). @@ -312,6 +320,7 @@ bool ConnectionGraph::compute_escape() { found_nsr_alloc = true; } } + _compile->print_method(PHASE_EA_ADJUST_SCALAR_REPLACEABLE_ITER, 6, n); } // Propagate NSR (Not Scalar Replaceable) state. @@ -350,6 +359,7 @@ bool ConnectionGraph::compute_escape() { _collecting = false; + _compile->print_method(PHASE_EA_AFTER_PROPAGATE_NSR, 4); } // TracePhase t3("connectionGraph") // 4. Optimize ideal graph based on EA information. @@ -387,6 +397,8 @@ bool ConnectionGraph::compute_escape() { } #endif + _compile->print_method(PHASE_EA_AFTER_GRAPH_OPTIMIZATION, 4); + // 5. Separate memory graph for scalar replaceable allcations. bool has_scalar_replaceable_candidates = (alloc_worklist.length() > 0); if (has_scalar_replaceable_candidates && EliminateAllocations) { @@ -398,7 +410,6 @@ bool ConnectionGraph::compute_escape() { NOT_PRODUCT(escape_state_statistics(java_objects_worklist);) return false; } - C->print_method(PHASE_AFTER_EA, 2); #ifdef ASSERT } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) { @@ -413,6 +424,8 @@ bool ConnectionGraph::compute_escape() { #endif } + _compile->print_method(PHASE_EA_AFTER_SPLIT_UNIQUE_TYPES, 4); + // 6. Reduce allocation merges used as debug information. This is done after // split_unique_types because the methods used to create SafePointScalarObject // need to traverse the memory graph to find values for object fields. We also @@ -454,6 +467,8 @@ bool ConnectionGraph::compute_escape() { } } + _compile->print_method(PHASE_EA_AFTER_REDUCE_PHI_ON_SAFEPOINTS, 4); + NOT_PRODUCT(escape_state_statistics(java_objects_worklist);) return has_non_escaping_obj; } @@ -1302,11 +1317,14 @@ void ConnectionGraph::reduce_phi(PhiNode* ophi, GrowableArray &alloc_work } } + _compile->print_method(PHASE_EA_BEFORE_PHI_REDUCTION, 5, ophi); + // CastPPs need to be processed before Cmps because during the process of // splitting CastPPs we make reference to the inputs of the Cmp that is used // by the If controlling the CastPP. for (uint i = 0; i < castpps.size(); i++) { reduce_phi_on_castpp_field_load(castpps.at(i), alloc_worklist); + _compile->print_method(PHASE_EA_AFTER_PHI_CASTPP_REDUCTION, 6, castpps.at(i)); } for (uint i = 0; i < others.size(); i++) { @@ -1314,8 +1332,10 @@ void ConnectionGraph::reduce_phi(PhiNode* ophi, GrowableArray &alloc_work if (use->is_AddP()) { reduce_phi_on_field_access(use, alloc_worklist); + _compile->print_method(PHASE_EA_AFTER_PHI_ADDP_REDUCTION, 6, use); } else if(use->is_Cmp()) { reduce_phi_on_cmp(use); + _compile->print_method(PHASE_EA_AFTER_PHI_CMP_REDUCTION, 6, use); } } @@ -2417,6 +2437,7 @@ bool ConnectionGraph::complete_connection_graph( timeout = true; break; } + _compile->print_method(PHASE_EA_COMPLETE_CONNECTION_GRAPH_ITER, 5); } if ((iterations < GRAPH_BUILD_ITER_LIMIT) && !timeout) { time.start(); @@ -2490,7 +2511,8 @@ bool ConnectionGraph::complete_connection_graph( // Propagate GlobalEscape and ArgEscape escape states to all nodes // and check that we still have non-escaping java objects. bool ConnectionGraph::find_non_escaped_objects(GrowableArray& ptnodes_worklist, - GrowableArray& non_escaped_allocs_worklist) { + GrowableArray& non_escaped_allocs_worklist, + bool print_method) { GrowableArray escape_worklist; // First, put all nodes with GlobalEscape and ArgEscape states on worklist. int ptnodes_length = ptnodes_worklist.length(); @@ -2550,6 +2572,9 @@ bool ConnectionGraph::find_non_escaped_objects(GrowableArray& ptn escape_worklist.push(e); } } + if (print_method) { + _compile->print_method(PHASE_EA_CONNECTION_GRAPH_PROPAGATE_ITER, 6, e->ideal_node()); + } } } // Remove escaped objects from non_escaped list. @@ -3137,6 +3162,7 @@ void ConnectionGraph::find_scalar_replaceable_allocs(GrowableArrayprint_method(PHASE_EA_PROPAGATE_NSR_ITER, 5, jobj->ideal_node()); } } } @@ -3159,7 +3185,7 @@ void ConnectionGraph::verify_connection_graph( assert(new_edges == 0, "graph was not complete"); // Verify that escape state is final. int length = non_escaped_allocs_worklist.length(); - find_non_escaped_objects(ptnodes_worklist, non_escaped_allocs_worklist); + find_non_escaped_objects(ptnodes_worklist, non_escaped_allocs_worklist, /*print_method=*/ false); assert((non_escaped_length == non_escaped_allocs_worklist.length()) && (non_escaped_length == length) && (_worklist.length() == 0), "escape state was not final"); @@ -4720,6 +4746,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, // New alias types were created in split_AddP(). uint new_index_end = (uint) _compile->num_alias_types(); + _compile->print_method(PHASE_EA_AFTER_SPLIT_UNIQUE_TYPES_1, 5); + // Phase 2: Process MemNode's from memnode_worklist. compute new address type and // compute new values for Memory inputs (the Memory inputs are not // actually updated until phase 4.) @@ -4920,6 +4948,8 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, record_for_optimizer(nmm); } + _compile->print_method(PHASE_EA_AFTER_SPLIT_UNIQUE_TYPES_3, 5); + // Phase 4: Update the inputs of non-instance memory Phis and // the Memory input of memnodes // First update the inputs of any non-instance Phi's from @@ -4988,6 +5018,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist, assert(old_cnt == old_mem->outcnt(), "old mem could be lost"); } #endif + _compile->print_method(PHASE_EA_AFTER_SPLIT_UNIQUE_TYPES_4, 5); } #ifndef PRODUCT @@ -5010,6 +5041,10 @@ static const char *esc_names[] = { "GlobalEscape" }; +const char* PointsToNode::esc_name() const { + return esc_names[(int)escape_state()]; +} + void PointsToNode::dump_header(bool print_state, outputStream* out) const { NodeType nt = node_type(); out->print("%s(%d) ", node_type_names[(int) nt], _pidx); diff --git a/src/hotspot/share/opto/escape.hpp b/src/hotspot/share/opto/escape.hpp index 77d14525383..eea6403acdd 100644 --- a/src/hotspot/share/opto/escape.hpp +++ b/src/hotspot/share/opto/escape.hpp @@ -26,6 +26,7 @@ #define SHARE_OPTO_ESCAPE_HPP #include "opto/addnode.hpp" +#include "opto/idealGraphPrinter.hpp" #include "opto/node.hpp" #include "utilities/growableArray.hpp" @@ -235,6 +236,7 @@ public: NodeType node_type() const { return (NodeType)_type;} void dump(bool print_state=true, outputStream* out=tty, bool newline=true) const; void dump_header(bool print_state=true, outputStream* out=tty) const; + const char* esc_name() const; #endif }; @@ -321,6 +323,7 @@ public: class ConnectionGraph: public ArenaObj { friend class PointsToNode; // to access _compile friend class FieldNode; + friend class IdealGraphPrinter; private: GrowableArray _nodes; // Map from ideal nodes to // ConnectionGraph nodes. @@ -467,7 +470,8 @@ private: // Propagate GlobalEscape and ArgEscape escape states to all nodes // and check that we still have non-escaping java objects. bool find_non_escaped_objects(GrowableArray& ptnodes_worklist, - GrowableArray& non_escaped_worklist); + GrowableArray& non_escaped_worklist, + bool print_method = true); // Adjust scalar_replaceable state after Connection Graph is built. void adjust_scalar_replaceable_state(JavaObjectNode* jobj, Unique_Node_List &reducible_merges); diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 2873c1ef9d7..6a738878a1b 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -24,6 +24,7 @@ #include "memory/resourceArea.hpp" #include "opto/chaitin.hpp" +#include "opto/escape.hpp" #include "opto/idealGraphPrinter.hpp" #include "opto/machnode.hpp" #include "opto/parse.hpp" @@ -161,6 +162,7 @@ void IdealGraphPrinter::init(const char* file_name, bool use_multiple_files, boo _current_method = nullptr; _network_stream = nullptr; _append = append; + _congraph = nullptr; _parse = nullptr; if (file_name != nullptr) { @@ -637,6 +639,29 @@ void IdealGraphPrinter::visit_node(Node* n, bool edges) { print_prop("is_block_start", "true"); } + // Dump escape analysis state for relevant nodes. + if (node->is_Allocate()) { + AllocateNode* alloc = node->as_Allocate(); + if (alloc->_is_scalar_replaceable) { + print_prop("is_scalar_replaceable", "true"); + } + if (alloc->_is_non_escaping) { + print_prop("is_non_escaping", "true"); + } + if (alloc->does_not_escape_thread()) { + print_prop("does_not_escape_thread", "true"); + } + } + if (node->is_SafePoint() && node->as_SafePoint()->has_ea_local_in_scope()) { + print_prop("has_ea_local_in_scope", "true"); + } + if (node->is_CallJava() && node->as_CallJava()->arg_escape()) { + print_prop("arg_escape", "true"); + } + if (node->is_Initialize() && node->as_Initialize()->does_not_escape()) { + print_prop("does_not_escape", "true"); + } + const char *short_name = "short_name"; if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) { int index = node->as_Proj()->_con - TypeFunc::Parms; @@ -731,6 +756,19 @@ void IdealGraphPrinter::visit_node(Node* n, bool edges) { print_prop("lrg", lrg_id); } + if (_congraph != nullptr && node->_idx < _congraph->nodes_size()) { + PointsToNode* ptn = _congraph->ptnode_adr(node->_idx); + if (ptn != nullptr) { + stringStream node_head; + ptn->dump_header(false, &node_head); + print_prop("ea_node", node_head.freeze()); + print_prop("escape_state", ptn->esc_name()); + if (ptn->scalar_replaceable()) { + print_prop("scalar_replaceable", "true"); + } + } + } + if (node->is_MachSafePoint()) { const OopMap* oopmap = node->as_MachSafePoint()->oop_map(); if (oopmap != nullptr) { diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index df1c6b254d5..2159779ddfa 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -42,6 +42,7 @@ class Node; class InlineTree; class ciMethod; class JVMState; +class ConnectionGraph; class Parse; class IdealGraphPrinter : public CHeapObj { @@ -116,6 +117,7 @@ class IdealGraphPrinter : public CHeapObj { Compile *C; double _max_freq; bool _append; + ConnectionGraph* _congraph; const Parse* _parse; // Walk the native stack and print relevant C2 frames as IGV properties (if @@ -165,6 +167,7 @@ class IdealGraphPrinter : public CHeapObj { void end_method(); void print_graph(const char* name, const frame* fr = nullptr); void print(const char* name, Node* root, GrowableArray& hidden_nodes, const frame* fr = nullptr); + void set_congraph(ConnectionGraph* congraph) { _congraph = congraph; } void set_compile(Compile* compile) {C = compile; } void update_compiled_method(ciMethod* current_method); }; diff --git a/src/hotspot/share/opto/phasetype.hpp b/src/hotspot/share/opto/phasetype.hpp index f24938b51c1..f388dc6cdc6 100644 --- a/src/hotspot/share/opto/phasetype.hpp +++ b/src/hotspot/share/opto/phasetype.hpp @@ -50,6 +50,23 @@ flags(ITER_GVN_AFTER_VECTOR, "Iter GVN after Vector Box Elimination") \ flags(BEFORE_LOOP_OPTS, "Before Loop Optimizations") \ flags(PHASEIDEAL_BEFORE_EA, "PhaseIdealLoop before EA") \ + flags(EA_AFTER_INITIAL_CONGRAPH, "EA: 1. Intial Connection Graph") \ + flags(EA_CONNECTION_GRAPH_PROPAGATE_ITER, "EA: 2. Connection Graph Propagate Iter") \ + flags(EA_COMPLETE_CONNECTION_GRAPH_ITER, "EA: 2. Complete Connection Graph Iter") \ + flags(EA_AFTER_COMPLETE_CONGRAPH, "EA: 2. Complete Connection Graph") \ + flags(EA_ADJUST_SCALAR_REPLACEABLE_ITER, "EA: 3. Adjust scalar_replaceable State Iter") \ + flags(EA_PROPAGATE_NSR_ITER, "EA: 3. Propagate NSR Iter") \ + flags(EA_AFTER_PROPAGATE_NSR, "EA: 3. Propagate NSR") \ + flags(EA_AFTER_GRAPH_OPTIMIZATION, "EA: 4. After Graph Optimization") \ + flags(EA_AFTER_SPLIT_UNIQUE_TYPES_1, "EA: 5. After split_unique_types Phase 1") \ + flags(EA_AFTER_SPLIT_UNIQUE_TYPES_3, "EA: 5. After split_unique_types Phase 3") \ + flags(EA_AFTER_SPLIT_UNIQUE_TYPES_4, "EA: 5. After split_unique_types Phase 4") \ + flags(EA_AFTER_SPLIT_UNIQUE_TYPES, "EA: 5. After split_unique_types") \ + flags(EA_AFTER_REDUCE_PHI_ON_SAFEPOINTS, "EA: 6. After reduce_phi_on_safepoints") \ + flags(EA_BEFORE_PHI_REDUCTION, "EA: 5. Before Phi Reduction") \ + flags(EA_AFTER_PHI_CASTPP_REDUCTION, "EA: 5. Phi -> CastPP Reduction") \ + flags(EA_AFTER_PHI_ADDP_REDUCTION, "EA: 5. Phi -> AddP Reduction") \ + flags(EA_AFTER_PHI_CMP_REDUCTION, "EA: 5. Phi -> Cmp Reduction") \ flags(AFTER_EA, "After Escape Analysis") \ flags(ITER_GVN_AFTER_EA, "Iter GVN after EA") \ flags(BEFORE_BEAUTIFY_LOOPS, "Before Beautify Loops") \ diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorEscapeAnalysis.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorEscapeAnalysis.filter new file mode 100644 index 00000000000..2ef14f65110 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/colorEscapeAnalysis.filter @@ -0,0 +1,51 @@ +// Color those nodes present in the escape analysis connection graph +// to indicate the result of scape analysis. +// This filter is relevant between the first EA phase and "After Macro +// Expansion". + +var bestColor = java.awt.Color.decode("#6aa84f"); // Green. +var betterColor = java.awt.Color.decode("#f1c232"); // Yellow. +var worseColor = java.awt.Color.decode("#e69138"); // Orange. +var worstColor = java.awt.Color.decode("#cc0000"); // Red. + +// Apply first colors based on persistent node attributes + +// Object does not escape compilation unit and is scalar replaceable. +colorize(and([hasProperty("is_non_escaping"), + hasProperty("is_scalar_replaceable")]), + bestColor); + +// Object does not escape compilation unit but is not scalar replaceable, +// due to of scalar replacement limitations. We can at least elide locks. +colorize(and([hasProperty("is_non_escaping"), + not(hasProperty("is_scalar_replaceable"))]), + betterColor); + +// Object may escape compilation unit but does not escape thread. +// We can at least elide locks. +colorize(and([hasProperty("does_not_escape_thread"), + not(hasProperty("is_non_escaping"))]), + worseColor); + +// Object may escape compilation unit and thread. Nothing to do. +colorize(and([matches("name", "Allocate"), + not(hasProperty("is_non_escaping")), + not(hasProperty("does_not_escape_thread"))]), + worstColor); + +// Apply colors again based on connection graph-derived attributes + +colorize(and([matches("escape_state", "NoEscape"), + hasProperty("scalar_replaceable")]), + bestColor); + +colorize(and([matches("escape_state", "NoEscape"), + not(hasProperty("scalar_replaceable"))]), + betterColor); + +colorize(and([matches("escape_state", "ArgEscape"), + not(hasProperty("scalar_replaceable"))]), + worseColor); + +colorize(matches("escape_state", "GlobalEscape"), + worstColor); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionGraphNodesOnly.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionGraphNodesOnly.filter new file mode 100644 index 00000000000..b0986db221a --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionGraphNodesOnly.filter @@ -0,0 +1,6 @@ +// This filter shows only the nodes that are present in the escape analysis +// connection graph. This can be used to approximate the connection graph inside +// IGV. +// This filter is only relevant during the escape analysis phases. + +remove(not(hasProperty("ea_node"))); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionInfo.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionInfo.filter new file mode 100644 index 00000000000..ca3509687f5 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/showConnectionInfo.filter @@ -0,0 +1,16 @@ +// This filter appends escape analysis connection graph node information to the +// (possibly already existing) extra-label line. +// This is only carried out for those nodes that are relevant to escape +// analysis (and therefore represented in the connection graph). + +// Merge a possibly existing extra label with the escape analysis node type into a +// new, single extra label. +function mergeAndAppendTypeInfo(extra_label, ea_node) { + new_extra_label = extra_label == null ? "" : (extra_label + " "); + return new_extra_label + ea_node; +} + +editProperty(hasProperty("ea_node"), + ["extra_label", "ea_node"], + "extra_label", + function(propertyValues) {return mergeAndAppendTypeInfo(propertyValues[0], propertyValues[1]);}); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml index db4682f1cab..38dfc911a44 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/layer.xml @@ -85,9 +85,21 @@ + + + + + + + + + + + + - + diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java index 06b2afa8a67..a536808d269 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java @@ -60,6 +60,23 @@ public enum CompilePhase { ITER_GVN_AFTER_VECTOR( "Iter GVN after Vector Box Elimination"), BEFORE_LOOP_OPTS( "Before Loop Optimizations"), PHASEIDEAL_BEFORE_EA( "PhaseIdealLoop before EA"), + EA_AFTER_INITIAL_CONGRAPH( "EA: 1. Intial Connection Graph"), + EA_CONNECTION_GRAPH_PROPAGATE_ITER("EA: 2. Connection Graph Propagate Iter"), + EA_COMPLETE_CONNECTION_GRAPH_ITER( "EA: 2. Complete Connection Graph Iter"), + EA_AFTER_COMPLETE_CONGRAPH( "EA: 2. Complete Connection Graph"), + EA_ADJUST_SCALAR_REPLACEABLE_ITER( "EA: 3. Adjust scalar_replaceable State Iter"), + EA_PROPAGATE_NSR_ITER( "EA: 3. Propagate NSR Iter"), + EA_AFTER_PROPAGATE_NSR( "EA: 3. Propagate NSR"), + EA_AFTER_GRAPH_OPTIMIZATION( "EA: 4. After Graph Optimization"), + EA_AFTER_SPLIT_UNIQUE_TYPES_1( "EA: 5. After split_unique_types Phase 1"), + EA_AFTER_SPLIT_UNIQUE_TYPES_3( "EA: 5. After split_unique_types Phase 3"), + EA_AFTER_SPLIT_UNIQUE_TYPES_4( "EA: 5. After split_unique_types Phase 4"), + EA_AFTER_SPLIT_UNIQUE_TYPES( "EA: 5. After split_unique_types"), + EA_AFTER_REDUCE_PHI_ON_SAFEPOINTS( "EA: 6. After reduce_phi_on_safepoints"), + EA_BEFORE_PHI_REDUCTION( "EA: 5. Before Phi Reduction"), + EA_AFTER_PHI_CASTPP_REDUCTION( "EA: 5. Phi -> CastPP Reduction"), + EA_AFTER_PHI_ADDP_REDUCTION( "EA: 5. Phi -> AddP Reduction"), + EA_AFTER_PHI_CMP_REDUCTION( "EA: 5. Phi -> Cmp Reduction"), AFTER_EA( "After Escape Analysis"), ITER_GVN_AFTER_EA( "Iter GVN after EA"), BEFORE_BEAUTIFY_LOOPS( "Before Beautify Loops"),