8255026: C2: Miscellaneous cleanups in Compile and PhaseIdealLoop code
Reviewed-by: thartmann, neliasso, redestad
This commit is contained in:
parent
c107178bcc
commit
27230fae24
@ -119,9 +119,9 @@ class IntrinsicDescPair {
|
||||
};
|
||||
int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual, bool& found) {
|
||||
#ifdef ASSERT
|
||||
for (int i = 1; i < _intrinsics->length(); i++) {
|
||||
CallGenerator* cg1 = _intrinsics->at(i-1);
|
||||
CallGenerator* cg2 = _intrinsics->at(i);
|
||||
for (int i = 1; i < _intrinsics.length(); i++) {
|
||||
CallGenerator* cg1 = _intrinsics.at(i-1);
|
||||
CallGenerator* cg2 = _intrinsics.at(i);
|
||||
assert(cg1->method() != cg2->method()
|
||||
? cg1->method() < cg2->method()
|
||||
: cg1->is_virtual() < cg2->is_virtual(),
|
||||
@ -129,28 +129,24 @@ int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual, bool& found
|
||||
}
|
||||
#endif
|
||||
IntrinsicDescPair pair(m, is_virtual);
|
||||
return _intrinsics->find_sorted<IntrinsicDescPair*, IntrinsicDescPair::compare>(&pair, found);
|
||||
return _intrinsics.find_sorted<IntrinsicDescPair*, IntrinsicDescPair::compare>(&pair, found);
|
||||
}
|
||||
|
||||
void Compile::register_intrinsic(CallGenerator* cg) {
|
||||
if (_intrinsics == NULL) {
|
||||
_intrinsics = new (comp_arena())GrowableArray<CallGenerator*>(comp_arena(), 60, 0, NULL);
|
||||
}
|
||||
int len = _intrinsics->length();
|
||||
bool found = false;
|
||||
int index = intrinsic_insertion_index(cg->method(), cg->is_virtual(), found);
|
||||
assert(!found, "registering twice");
|
||||
_intrinsics->insert_before(index, cg);
|
||||
_intrinsics.insert_before(index, cg);
|
||||
assert(find_intrinsic(cg->method(), cg->is_virtual()) == cg, "registration worked");
|
||||
}
|
||||
|
||||
CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
assert(m->is_loaded(), "don't try this on unloaded methods");
|
||||
if (_intrinsics != NULL) {
|
||||
if (_intrinsics.length() > 0) {
|
||||
bool found = false;
|
||||
int index = intrinsic_insertion_index(m, is_virtual, found);
|
||||
if (found) {
|
||||
return _intrinsics->at(index);
|
||||
return _intrinsics.at(index);
|
||||
}
|
||||
}
|
||||
// Lazily create intrinsics for intrinsic IDs well-known in the runtime.
|
||||
@ -168,9 +164,7 @@ CallGenerator* Compile::find_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Compile:: register_library_intrinsics and make_vm_intrinsic are defined
|
||||
// in library_call.cpp.
|
||||
|
||||
// Compile::make_vm_intrinsic is defined in library_call.cpp.
|
||||
|
||||
#ifndef PRODUCT
|
||||
// statistics gathering...
|
||||
@ -352,6 +346,15 @@ void Compile::remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines
|
||||
inlines->trunc_to(inlines->length()-shift);
|
||||
}
|
||||
|
||||
void Compile::remove_useless_nodes(GrowableArray<Node*>& node_list, Unique_Node_List& useful) {
|
||||
for (int i = node_list.length() - 1; i >= 0; i--) {
|
||||
Node* n = node_list.at(i);
|
||||
if (!useful.member(n)) {
|
||||
node_list.remove_if_existing(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect all useless nodes by disconnecting those at the boundary.
|
||||
void Compile::remove_useless_nodes(Unique_Node_List &useful) {
|
||||
uint next = 0;
|
||||
@ -366,7 +369,7 @@ void Compile::remove_useless_nodes(Unique_Node_List &useful) {
|
||||
int max = n->outcnt();
|
||||
for (int j = 0; j < max; ++j) {
|
||||
Node* child = n->raw_out(j);
|
||||
if (! useful.member(child)) {
|
||||
if (!useful.member(child)) {
|
||||
assert(!child->is_top() || child != top(),
|
||||
"If top is cached in Compile object it is in useful list");
|
||||
// Only need to remove this out-edge to the useless node
|
||||
@ -379,34 +382,12 @@ void Compile::remove_useless_nodes(Unique_Node_List &useful) {
|
||||
record_for_igvn(n->unique_out());
|
||||
}
|
||||
}
|
||||
// Remove useless macro and predicate opaq nodes
|
||||
for (int i = C->macro_count()-1; i >= 0; i--) {
|
||||
Node* n = C->macro_node(i);
|
||||
if (!useful.member(n)) {
|
||||
remove_macro_node(n);
|
||||
}
|
||||
}
|
||||
// Remove useless CastII nodes with range check dependency
|
||||
for (int i = range_check_cast_count() - 1; i >= 0; i--) {
|
||||
Node* cast = range_check_cast_node(i);
|
||||
if (!useful.member(cast)) {
|
||||
remove_range_check_cast(cast);
|
||||
}
|
||||
}
|
||||
// Remove useless expensive nodes
|
||||
for (int i = C->expensive_count()-1; i >= 0; i--) {
|
||||
Node* n = C->expensive_node(i);
|
||||
if (!useful.member(n)) {
|
||||
remove_expensive_node(n);
|
||||
}
|
||||
}
|
||||
// Remove useless Opaque4 nodes
|
||||
for (int i = opaque4_count() - 1; i >= 0; i--) {
|
||||
Node* opaq = opaque4_node(i);
|
||||
if (!useful.member(opaq)) {
|
||||
remove_opaque4_node(opaq);
|
||||
}
|
||||
}
|
||||
|
||||
remove_useless_nodes(_macro_nodes, useful); // remove useless macro and predicate opaq nodes
|
||||
remove_useless_nodes(_expensive_nodes, useful); // remove useless expensive nodes
|
||||
remove_useless_nodes(_range_check_casts, useful); // remove useless CastII nodes with range check dependency
|
||||
remove_useless_nodes(_opaque4_nodes, useful); // remove useless Opaque4 nodes
|
||||
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
bs->eliminate_useless_gc_barriers(useful, this);
|
||||
// clean up the late inline lists
|
||||
@ -533,6 +514,12 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci,
|
||||
_directive(directive),
|
||||
_log(ci_env->log()),
|
||||
_failure_reason(NULL),
|
||||
_intrinsics (comp_arena(), 0, 0, NULL),
|
||||
_macro_nodes (comp_arena(), 8, 0, NULL),
|
||||
_predicate_opaqs (comp_arena(), 8, 0, NULL),
|
||||
_expensive_nodes (comp_arena(), 8, 0, NULL),
|
||||
_range_check_casts (comp_arena(), 8, 0, NULL),
|
||||
_opaque4_nodes (comp_arena(), 8, 0, NULL),
|
||||
_congraph(NULL),
|
||||
NOT_PRODUCT(_printer(NULL) COMMA)
|
||||
_dead_node_list(comp_arena()),
|
||||
@ -1015,13 +1002,6 @@ void Compile::Init(int aliaslevel) {
|
||||
// A NULL adr_type hits in the cache right away. Preload the right answer.
|
||||
probe_alias_cache(NULL)->_index = AliasIdxTop;
|
||||
|
||||
_intrinsics = NULL;
|
||||
_macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||
_predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||
_expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||
_range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||
_opaque4_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||
register_library_intrinsics();
|
||||
#ifdef ASSERT
|
||||
_type_verify_symmetry = true;
|
||||
_phase_optimize_finished = false;
|
||||
@ -1794,8 +1774,8 @@ void Compile::cleanup_loop_predicates(PhaseIterGVN &igvn) {
|
||||
|
||||
void Compile::add_range_check_cast(Node* n) {
|
||||
assert(n->isa_CastII()->has_range_check(), "CastII should have range check dependency");
|
||||
assert(!_range_check_casts->contains(n), "duplicate entry in range check casts");
|
||||
_range_check_casts->append(n);
|
||||
assert(!_range_check_casts.contains(n), "duplicate entry in range check casts");
|
||||
_range_check_casts.append(n);
|
||||
}
|
||||
|
||||
// Remove all range check dependent CastIINodes.
|
||||
@ -1810,8 +1790,8 @@ void Compile::remove_range_check_casts(PhaseIterGVN &igvn) {
|
||||
|
||||
void Compile::add_opaque4_node(Node* n) {
|
||||
assert(n->Opcode() == Op_Opaque4, "Opaque4 only");
|
||||
assert(!_opaque4_nodes->contains(n), "duplicate entry in Opaque4 list");
|
||||
_opaque4_nodes->append(n);
|
||||
assert(!_opaque4_nodes.contains(n), "duplicate entry in Opaque4 list");
|
||||
_opaque4_nodes.append(n);
|
||||
}
|
||||
|
||||
// Remove all Opaque4 nodes.
|
||||
@ -1988,9 +1968,9 @@ void Compile::inline_incrementally(PhaseIterGVN& igvn) {
|
||||
|
||||
|
||||
bool Compile::optimize_loops(PhaseIterGVN& igvn, LoopOptsMode mode) {
|
||||
if(_loop_opts_cnt > 0) {
|
||||
if (_loop_opts_cnt > 0) {
|
||||
debug_only( int cnt = 0; );
|
||||
while(major_progress() && (_loop_opts_cnt > 0)) {
|
||||
while (major_progress() && (_loop_opts_cnt > 0)) {
|
||||
TracePhase tp("idealLoop", &timers[_t_idealLoop]);
|
||||
assert( cnt++ < 40, "infinite cycle in loop optimization" );
|
||||
PhaseIdealLoop::optimize(igvn, mode);
|
||||
@ -2273,6 +2253,7 @@ void Compile::Optimize() {
|
||||
}
|
||||
|
||||
DEBUG_ONLY( _modified_nodes = NULL; )
|
||||
assert(igvn._worklist.size() == 0, "not empty");
|
||||
} // (End scope of igvn; run destructor if necessary for asserts.)
|
||||
|
||||
process_print_inlining();
|
||||
@ -3683,7 +3664,7 @@ bool Compile::final_graph_reshaping() {
|
||||
// be freely moved to the least frequent code path by gcm.
|
||||
assert(OptimizeExpensiveOps || expensive_count() == 0, "optimization off but list non empty?");
|
||||
for (int i = 0; i < expensive_count(); i++) {
|
||||
_expensive_nodes->at(i)->set_req(0, NULL);
|
||||
_expensive_nodes.at(i)->set_req(0, NULL);
|
||||
}
|
||||
|
||||
Final_Reshape_Counts frc;
|
||||
@ -4335,13 +4316,13 @@ int Compile::cmp_expensive_nodes(Node** n1p, Node** n2p) {
|
||||
|
||||
void Compile::sort_expensive_nodes() {
|
||||
if (!expensive_nodes_sorted()) {
|
||||
_expensive_nodes->sort(cmp_expensive_nodes);
|
||||
_expensive_nodes.sort(cmp_expensive_nodes);
|
||||
}
|
||||
}
|
||||
|
||||
bool Compile::expensive_nodes_sorted() const {
|
||||
for (int i = 1; i < _expensive_nodes->length(); i++) {
|
||||
if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i-1)) < 0) {
|
||||
for (int i = 1; i < _expensive_nodes.length(); i++) {
|
||||
if (cmp_expensive_nodes(_expensive_nodes.adr_at(i), _expensive_nodes.adr_at(i-1)) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4349,7 +4330,7 @@ bool Compile::expensive_nodes_sorted() const {
|
||||
}
|
||||
|
||||
bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) {
|
||||
if (_expensive_nodes->length() == 0) {
|
||||
if (_expensive_nodes.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4357,23 +4338,23 @@ bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) {
|
||||
|
||||
// Take this opportunity to remove dead nodes from the list
|
||||
int j = 0;
|
||||
for (int i = 0; i < _expensive_nodes->length(); i++) {
|
||||
Node* n = _expensive_nodes->at(i);
|
||||
for (int i = 0; i < _expensive_nodes.length(); i++) {
|
||||
Node* n = _expensive_nodes.at(i);
|
||||
if (!n->is_unreachable(igvn)) {
|
||||
assert(n->is_expensive(), "should be expensive");
|
||||
_expensive_nodes->at_put(j, n);
|
||||
_expensive_nodes.at_put(j, n);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
_expensive_nodes->trunc_to(j);
|
||||
_expensive_nodes.trunc_to(j);
|
||||
|
||||
// Then sort the list so that similar nodes are next to each other
|
||||
// and check for at least two nodes of identical kind with same data
|
||||
// inputs.
|
||||
sort_expensive_nodes();
|
||||
|
||||
for (int i = 0; i < _expensive_nodes->length()-1; i++) {
|
||||
if (cmp_expensive_nodes(_expensive_nodes->adr_at(i), _expensive_nodes->adr_at(i+1)) == 0) {
|
||||
for (int i = 0; i < _expensive_nodes.length()-1; i++) {
|
||||
if (cmp_expensive_nodes(_expensive_nodes.adr_at(i), _expensive_nodes.adr_at(i+1)) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -4382,7 +4363,7 @@ bool Compile::should_optimize_expensive_nodes(PhaseIterGVN &igvn) {
|
||||
}
|
||||
|
||||
void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) {
|
||||
if (_expensive_nodes->length() == 0) {
|
||||
if (_expensive_nodes.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4396,43 +4377,43 @@ void Compile::cleanup_expensive_nodes(PhaseIterGVN &igvn) {
|
||||
int identical = 0;
|
||||
int i = 0;
|
||||
bool modified = false;
|
||||
for (; i < _expensive_nodes->length()-1; i++) {
|
||||
for (; i < _expensive_nodes.length()-1; i++) {
|
||||
assert(j <= i, "can't write beyond current index");
|
||||
if (_expensive_nodes->at(i)->Opcode() == _expensive_nodes->at(i+1)->Opcode()) {
|
||||
if (_expensive_nodes.at(i)->Opcode() == _expensive_nodes.at(i+1)->Opcode()) {
|
||||
identical++;
|
||||
_expensive_nodes->at_put(j++, _expensive_nodes->at(i));
|
||||
_expensive_nodes.at_put(j++, _expensive_nodes.at(i));
|
||||
continue;
|
||||
}
|
||||
if (identical > 0) {
|
||||
_expensive_nodes->at_put(j++, _expensive_nodes->at(i));
|
||||
_expensive_nodes.at_put(j++, _expensive_nodes.at(i));
|
||||
identical = 0;
|
||||
} else {
|
||||
Node* n = _expensive_nodes->at(i);
|
||||
Node* n = _expensive_nodes.at(i);
|
||||
igvn.replace_input_of(n, 0, NULL);
|
||||
igvn.hash_insert(n);
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (identical > 0) {
|
||||
_expensive_nodes->at_put(j++, _expensive_nodes->at(i));
|
||||
} else if (_expensive_nodes->length() >= 1) {
|
||||
Node* n = _expensive_nodes->at(i);
|
||||
_expensive_nodes.at_put(j++, _expensive_nodes.at(i));
|
||||
} else if (_expensive_nodes.length() >= 1) {
|
||||
Node* n = _expensive_nodes.at(i);
|
||||
igvn.replace_input_of(n, 0, NULL);
|
||||
igvn.hash_insert(n);
|
||||
modified = true;
|
||||
}
|
||||
_expensive_nodes->trunc_to(j);
|
||||
_expensive_nodes.trunc_to(j);
|
||||
if (modified) {
|
||||
igvn.optimize();
|
||||
}
|
||||
}
|
||||
|
||||
void Compile::add_expensive_node(Node * n) {
|
||||
assert(!_expensive_nodes->contains(n), "duplicate entry in expensive list");
|
||||
assert(!_expensive_nodes.contains(n), "duplicate entry in expensive list");
|
||||
assert(n->is_expensive(), "expensive nodes with non-null control here only");
|
||||
assert(!n->is_CFG() && !n->is_Mem(), "no cfg or memory nodes here");
|
||||
if (OptimizeExpensiveOps) {
|
||||
_expensive_nodes->append(n);
|
||||
_expensive_nodes.append(n);
|
||||
} else {
|
||||
// Clear control input and let IGVN optimize expensive nodes if
|
||||
// OptimizeExpensiveOps is off.
|
||||
@ -4610,8 +4591,8 @@ void Compile::sort_macro_nodes() {
|
||||
if (n->is_Allocate()) {
|
||||
if (i != allocates) {
|
||||
Node* tmp = macro_node(allocates);
|
||||
_macro_nodes->at_put(allocates, n);
|
||||
_macro_nodes->at_put(i, tmp);
|
||||
_macro_nodes.at_put(allocates, n);
|
||||
_macro_nodes.at_put(i, tmp);
|
||||
}
|
||||
allocates++;
|
||||
}
|
||||
|
@ -309,12 +309,12 @@ class Compile : public Phase {
|
||||
DirectiveSet* _directive; // Compiler directive
|
||||
CompileLog* _log; // from CompilerThread
|
||||
const char* _failure_reason; // for record_failure/failing pattern
|
||||
GrowableArray<CallGenerator*>* _intrinsics; // List of intrinsics.
|
||||
GrowableArray<Node*>* _macro_nodes; // List of nodes which need to be expanded before matching.
|
||||
GrowableArray<Node*>* _predicate_opaqs; // List of Opaque1 nodes for the loop predicates.
|
||||
GrowableArray<Node*>* _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
|
||||
GrowableArray<Node*>* _range_check_casts; // List of CastII nodes with a range check dependency
|
||||
GrowableArray<Node*>* _opaque4_nodes; // List of Opaque4 nodes that have a default value
|
||||
GrowableArray<CallGenerator*> _intrinsics; // List of intrinsics.
|
||||
GrowableArray<Node*> _macro_nodes; // List of nodes which need to be expanded before matching.
|
||||
GrowableArray<Node*> _predicate_opaqs; // List of Opaque1 nodes for the loop predicates.
|
||||
GrowableArray<Node*> _expensive_nodes; // List of nodes that are expensive to compute and that we'd better not let the GVN freely common
|
||||
GrowableArray<Node*> _range_check_casts; // List of CastII nodes with a range check dependency
|
||||
GrowableArray<Node*> _opaque4_nodes; // List of Opaque4 nodes that have a default value
|
||||
ConnectionGraph* _congraph;
|
||||
#ifndef PRODUCT
|
||||
IdealGraphPrinter* _printer;
|
||||
@ -376,10 +376,8 @@ class Compile : public Phase {
|
||||
Unique_Node_List* _for_igvn; // Initial work-list for next round of Iterative GVN
|
||||
WarmCallInfo* _warm_calls; // Sorted work-list for heat-based inlining.
|
||||
|
||||
GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after
|
||||
// main parsing has finished.
|
||||
GrowableArray<CallGenerator*> _late_inlines; // List of CallGenerators to be revisited after main parsing has finished.
|
||||
GrowableArray<CallGenerator*> _string_late_inlines; // same but for string operations
|
||||
|
||||
GrowableArray<CallGenerator*> _boxing_late_inlines; // same but for boxing operations
|
||||
|
||||
GrowableArray<CallGenerator*> _vector_reboxing_late_inlines; // same but for vector reboxing operations
|
||||
@ -659,54 +657,54 @@ class Compile : public Phase {
|
||||
|
||||
void end_method(int level = 1);
|
||||
|
||||
int macro_count() const { return _macro_nodes->length(); }
|
||||
int predicate_count() const { return _predicate_opaqs->length();}
|
||||
int expensive_count() const { return _expensive_nodes->length(); }
|
||||
Node* macro_node(int idx) const { return _macro_nodes->at(idx); }
|
||||
Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs->at(idx);}
|
||||
Node* expensive_node(int idx) const { return _expensive_nodes->at(idx); }
|
||||
int macro_count() const { return _macro_nodes.length(); }
|
||||
int predicate_count() const { return _predicate_opaqs.length();}
|
||||
int expensive_count() const { return _expensive_nodes.length(); }
|
||||
Node* macro_node(int idx) const { return _macro_nodes.at(idx); }
|
||||
Node* predicate_opaque1_node(int idx) const { return _predicate_opaqs.at(idx);}
|
||||
Node* expensive_node(int idx) const { return _expensive_nodes.at(idx); }
|
||||
ConnectionGraph* congraph() { return _congraph;}
|
||||
void set_congraph(ConnectionGraph* congraph) { _congraph = congraph;}
|
||||
void add_macro_node(Node * n) {
|
||||
//assert(n->is_macro(), "must be a macro node");
|
||||
assert(!_macro_nodes->contains(n), "duplicate entry in expand list");
|
||||
_macro_nodes->append(n);
|
||||
assert(!_macro_nodes.contains(n), "duplicate entry in expand list");
|
||||
_macro_nodes.append(n);
|
||||
}
|
||||
void remove_macro_node(Node* n) {
|
||||
// this function may be called twice for a node so we can only remove it
|
||||
// if it's still existing.
|
||||
_macro_nodes->remove_if_existing(n);
|
||||
_macro_nodes.remove_if_existing(n);
|
||||
// remove from _predicate_opaqs list also if it is there
|
||||
if (predicate_count() > 0) {
|
||||
_predicate_opaqs->remove_if_existing(n);
|
||||
_predicate_opaqs.remove_if_existing(n);
|
||||
}
|
||||
}
|
||||
void add_expensive_node(Node* n);
|
||||
void remove_expensive_node(Node* n) {
|
||||
_expensive_nodes->remove_if_existing(n);
|
||||
_expensive_nodes.remove_if_existing(n);
|
||||
}
|
||||
void add_predicate_opaq(Node* n) {
|
||||
assert(!_predicate_opaqs->contains(n), "duplicate entry in predicate opaque1");
|
||||
assert(_macro_nodes->contains(n), "should have already been in macro list");
|
||||
_predicate_opaqs->append(n);
|
||||
assert(!_predicate_opaqs.contains(n), "duplicate entry in predicate opaque1");
|
||||
assert(_macro_nodes.contains(n), "should have already been in macro list");
|
||||
_predicate_opaqs.append(n);
|
||||
}
|
||||
|
||||
// Range check dependent CastII nodes that can be removed after loop optimizations
|
||||
void add_range_check_cast(Node* n);
|
||||
void remove_range_check_cast(Node* n) {
|
||||
_range_check_casts->remove_if_existing(n);
|
||||
_range_check_casts.remove_if_existing(n);
|
||||
}
|
||||
Node* range_check_cast_node(int idx) const { return _range_check_casts->at(idx); }
|
||||
int range_check_cast_count() const { return _range_check_casts->length(); }
|
||||
Node* range_check_cast_node(int idx) const { return _range_check_casts.at(idx); }
|
||||
int range_check_cast_count() const { return _range_check_casts.length(); }
|
||||
// Remove all range check dependent CastIINodes.
|
||||
void remove_range_check_casts(PhaseIterGVN &igvn);
|
||||
|
||||
void add_opaque4_node(Node* n);
|
||||
void remove_opaque4_node(Node* n) {
|
||||
_opaque4_nodes->remove_if_existing(n);
|
||||
_opaque4_nodes.remove_if_existing(n);
|
||||
}
|
||||
Node* opaque4_node(int idx) const { return _opaque4_nodes->at(idx); }
|
||||
int opaque4_count() const { return _opaque4_nodes->length(); }
|
||||
Node* opaque4_node(int idx) const { return _opaque4_nodes.at(idx); }
|
||||
int opaque4_count() const { return _opaque4_nodes.length(); }
|
||||
void remove_opaque4_nodes(PhaseIterGVN &igvn);
|
||||
|
||||
void sort_macro_nodes();
|
||||
@ -714,8 +712,8 @@ class Compile : public Phase {
|
||||
// remove the opaque nodes that protect the predicates so that the unused checks and
|
||||
// uncommon traps will be eliminated from the graph.
|
||||
void cleanup_loop_predicates(PhaseIterGVN &igvn);
|
||||
bool is_predicate_opaq(Node * n) {
|
||||
return _predicate_opaqs->contains(n);
|
||||
bool is_predicate_opaq(Node* n) {
|
||||
return _predicate_opaqs.contains(n);
|
||||
}
|
||||
|
||||
// Are there candidate expensive nodes for optimization?
|
||||
@ -952,6 +950,7 @@ class Compile : public Phase {
|
||||
}
|
||||
|
||||
void remove_useless_late_inlines(GrowableArray<CallGenerator*>* inlines, Unique_Node_List &useful);
|
||||
void remove_useless_nodes (GrowableArray<Node*>& node_list, Unique_Node_List &useful);
|
||||
|
||||
void process_print_inlining();
|
||||
void dump_print_inlining();
|
||||
@ -1084,7 +1083,6 @@ class Compile : public Phase {
|
||||
void verify_top(Node*) const PRODUCT_RETURN;
|
||||
|
||||
// Intrinsic setup.
|
||||
void register_library_intrinsics(); // initializer
|
||||
CallGenerator* make_vm_intrinsic(ciMethod* m, bool is_virtual); // constructor
|
||||
int intrinsic_insertion_index(ciMethod* m, bool is_virtual, bool& found); // helper
|
||||
CallGenerator* find_intrinsic(ciMethod* m, bool is_virtual); // query fn
|
||||
|
@ -95,12 +95,6 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------register_library_intrinsics-----------------------
|
||||
// Initialize this file's data structures, for each Compile instance.
|
||||
void Compile::register_library_intrinsics() {
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
|
||||
LibraryCallKit kit(jvms, this);
|
||||
Compile* C = kit.C;
|
||||
|
@ -3486,34 +3486,39 @@ void IdealLoopTree::dump() const {
|
||||
|
||||
#endif
|
||||
|
||||
static void log_loop_tree(IdealLoopTree* root, IdealLoopTree* loop, CompileLog* log) {
|
||||
static void log_loop_tree_helper(IdealLoopTree* root, IdealLoopTree* loop, CompileLog* log) {
|
||||
if (loop == root) {
|
||||
if (loop->_child != NULL) {
|
||||
log->begin_head("loop_tree");
|
||||
log->end_head();
|
||||
if( loop->_child ) log_loop_tree(root, loop->_child, log);
|
||||
log_loop_tree_helper(root, loop->_child, log);
|
||||
log->tail("loop_tree");
|
||||
assert(loop->_next == NULL, "what?");
|
||||
}
|
||||
} else {
|
||||
} else if (loop != NULL) {
|
||||
Node* head = loop->_head;
|
||||
log->begin_head("loop");
|
||||
log->print(" idx='%d' ", head->_idx);
|
||||
if (loop->_irreducible) log->print("irreducible='1' ");
|
||||
if (head->is_Loop()) {
|
||||
if (head->as_Loop()->is_inner_loop()) log->print("inner_loop='1' ");
|
||||
if (head->as_Loop()->is_inner_loop()) log->print("inner_loop='1' ");
|
||||
if (head->as_Loop()->is_partial_peel_loop()) log->print("partial_peel_loop='1' ");
|
||||
}
|
||||
if (head->is_CountedLoop()) {
|
||||
} else if (head->is_CountedLoop()) {
|
||||
CountedLoopNode* cl = head->as_CountedLoop();
|
||||
if (cl->is_pre_loop()) log->print("pre_loop='%d' ", cl->main_idx());
|
||||
if (cl->is_main_loop()) log->print("main_loop='%d' ", cl->_idx);
|
||||
if (cl->is_post_loop()) log->print("post_loop='%d' ", cl->main_idx());
|
||||
if (cl->is_post_loop()) log->print("post_loop='%d' ", cl->main_idx());
|
||||
}
|
||||
log->end_head();
|
||||
if( loop->_child ) log_loop_tree(root, loop->_child, log);
|
||||
log_loop_tree_helper(root, loop->_child, log);
|
||||
log->tail("loop");
|
||||
if( loop->_next ) log_loop_tree(root, loop->_next, log);
|
||||
log_loop_tree_helper(root, loop->_next, log);
|
||||
}
|
||||
}
|
||||
|
||||
void PhaseIdealLoop::log_loop_tree() {
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree_helper(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3776,7 +3781,6 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
|
||||
bool strip_mined_loops_expanded = bs->strip_mined_loops_expanded(mode);
|
||||
if (stop_early && !do_expensive_nodes) {
|
||||
_igvn.optimize(); // Cleanup NeverBranches
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3886,7 +3890,6 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
// nodes again.
|
||||
C->set_major_progress();
|
||||
}
|
||||
_igvn.optimize();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3909,15 +3912,7 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
#endif
|
||||
|
||||
if (skip_loop_opts) {
|
||||
// restore major progress flag
|
||||
C->restore_major_progress(old_progress);
|
||||
|
||||
// Cleanup any modified bits
|
||||
_igvn.optimize();
|
||||
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3939,20 +3934,10 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
}
|
||||
|
||||
C->restore_major_progress(old_progress);
|
||||
|
||||
_igvn.optimize();
|
||||
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (bs->optimize_loops(this, mode, visited, nstack, worklist)) {
|
||||
_igvn.optimize();
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4091,16 +4076,9 @@ void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup any modified bits
|
||||
_igvn.optimize();
|
||||
|
||||
// disable assert until issue with split_flow_path is resolved (6742111)
|
||||
// assert(!_has_irreducible_loops || C->parsed_irreducible_loop() || C->is_osr_compilation(),
|
||||
// "shouldn't introduce irreducible loops");
|
||||
|
||||
if (C->log() != NULL) {
|
||||
log_loop_tree(_ltree_root, _ltree_root, C->log());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -812,6 +812,8 @@ private:
|
||||
bool only_has_infinite_loops();
|
||||
#endif
|
||||
|
||||
void log_loop_tree();
|
||||
|
||||
public:
|
||||
|
||||
PhaseIterGVN &igvn() const { return _igvn; }
|
||||
@ -1037,6 +1039,14 @@ public:
|
||||
static void optimize(PhaseIterGVN &igvn, LoopOptsMode mode) {
|
||||
ResourceMark rm;
|
||||
PhaseIdealLoop v(igvn, mode);
|
||||
|
||||
Compile* C = Compile::current();
|
||||
if (!C->failing()) {
|
||||
// Cleanup any modified bits
|
||||
igvn.optimize();
|
||||
|
||||
v.log_loop_tree();
|
||||
}
|
||||
}
|
||||
|
||||
// True if the method has at least 1 irreducible loop
|
||||
|
@ -791,7 +791,7 @@ public:
|
||||
return ((_class_id & ClassMask_##type) == Class_##type); \
|
||||
} \
|
||||
type##Node *as_##type() const { \
|
||||
assert(is_##type(), "invalid node class"); \
|
||||
assert(is_##type(), "invalid node class: %s", Name()); \
|
||||
return (type##Node*)this; \
|
||||
} \
|
||||
type##Node* isa_##type() const { \
|
||||
|
Loading…
Reference in New Issue
Block a user