mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
8024070: C2 needs some form of type speculation
Record unused type profile information with type system, propagate and use it. Reviewed-by: kvn, twisti
This commit is contained in:
parent
ceb177b16f
commit
1b5bd82335
22 changed files with 1429 additions and 144 deletions
|
@ -1360,7 +1360,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
|
|||
// During the 2nd round of IterGVN, NotNull castings are removed.
|
||||
// Make sure the Bottom and NotNull variants alias the same.
|
||||
// Also, make sure exact and non-exact variants alias the same.
|
||||
if( ptr == TypePtr::NotNull || ta->klass_is_exact() ) {
|
||||
if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != NULL) {
|
||||
tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset);
|
||||
}
|
||||
}
|
||||
|
@ -1385,6 +1385,9 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
|
|||
// Also, make sure exact and non-exact variants alias the same.
|
||||
tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
|
||||
}
|
||||
if (to->speculative() != NULL) {
|
||||
tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),to->offset(), to->instance_id());
|
||||
}
|
||||
// Canonicalize the holder of this field
|
||||
if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
|
||||
// First handle header references such as a LoadKlassNode, even if the
|
||||
|
@ -2013,6 +2016,12 @@ void Compile::Optimize() {
|
|||
if (failing()) return;
|
||||
}
|
||||
|
||||
// Remove the speculative part of types and clean up the graph from
|
||||
// the extra CastPP nodes whose only purpose is to carry them. Do
|
||||
// that early so that optimizations are not disrupted by the extra
|
||||
// CastPP nodes.
|
||||
remove_speculative_types(igvn);
|
||||
|
||||
// No more new expensive nodes will be added to the list from here
|
||||
// so keep only the actual candidates for optimizations.
|
||||
cleanup_expensive_nodes(igvn);
|
||||
|
@ -3799,6 +3808,45 @@ void Compile::add_expensive_node(Node * n) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the speculative part of types and clean up the graph
|
||||
*/
|
||||
void Compile::remove_speculative_types(PhaseIterGVN &igvn) {
|
||||
if (UseTypeSpeculation) {
|
||||
Unique_Node_List worklist;
|
||||
worklist.push(root());
|
||||
int modified = 0;
|
||||
// Go over all type nodes that carry a speculative type, drop the
|
||||
// speculative part of the type and enqueue the node for an igvn
|
||||
// which may optimize it out.
|
||||
for (uint next = 0; next < worklist.size(); ++next) {
|
||||
Node *n = worklist.at(next);
|
||||
if (n->is_Type() && n->as_Type()->type()->isa_oopptr() != NULL &&
|
||||
n->as_Type()->type()->is_oopptr()->speculative() != NULL) {
|
||||
TypeNode* tn = n->as_Type();
|
||||
const TypeOopPtr* t = tn->type()->is_oopptr();
|
||||
bool in_hash = igvn.hash_delete(n);
|
||||
assert(in_hash, "node should be in igvn hash table");
|
||||
tn->set_type(t->remove_speculative());
|
||||
igvn.hash_insert(n);
|
||||
igvn._worklist.push(n); // give it a chance to go away
|
||||
modified++;
|
||||
}
|
||||
uint max = n->len();
|
||||
for( uint i = 0; i < max; ++i ) {
|
||||
Node *m = n->in(i);
|
||||
if (not_a_node(m)) continue;
|
||||
worklist.push(m);
|
||||
}
|
||||
}
|
||||
// Drop the speculative part of all types in the igvn's type table
|
||||
igvn.remove_speculative_types();
|
||||
if (modified > 0) {
|
||||
igvn.optimize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Auxiliary method to support randomized stressing/fuzzing.
|
||||
//
|
||||
// This method can be called the arbitrary number of times, with current count
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue