comparison src/share/vm/opto/compile.cpp @ 12966:b2ee5dc63353

8024070: C2 needs some form of type speculation Summary: record unused type profile information with type system, propagate and use it. Reviewed-by: kvn, twisti
author roland
date Wed, 23 Oct 2013 12:40:23 +0200
parents 435c7b4577cd
children e428d5e768e3 94a83e0f9ce1 2b8e28fdf503
comparison
equal deleted inserted replaced
12965:8b4bbba322d3 12966:b2ee5dc63353
1358 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset); 1358 tj = ta = TypeAryPtr::make(ptr,ta->const_oop(),tary,aklass,false,offset);
1359 } 1359 }
1360 // During the 2nd round of IterGVN, NotNull castings are removed. 1360 // During the 2nd round of IterGVN, NotNull castings are removed.
1361 // Make sure the Bottom and NotNull variants alias the same. 1361 // Make sure the Bottom and NotNull variants alias the same.
1362 // Also, make sure exact and non-exact variants alias the same. 1362 // Also, make sure exact and non-exact variants alias the same.
1363 if( ptr == TypePtr::NotNull || ta->klass_is_exact() ) { 1363 if (ptr == TypePtr::NotNull || ta->klass_is_exact() || ta->speculative() != NULL) {
1364 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset); 1364 tj = ta = TypeAryPtr::make(TypePtr::BotPTR,ta->ary(),ta->klass(),false,offset);
1365 } 1365 }
1366 } 1366 }
1367 1367
1368 // Oop pointers need some flattening 1368 // Oop pointers need some flattening
1382 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) { 1382 } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
1383 // During the 2nd round of IterGVN, NotNull castings are removed. 1383 // During the 2nd round of IterGVN, NotNull castings are removed.
1384 // Make sure the Bottom and NotNull variants alias the same. 1384 // Make sure the Bottom and NotNull variants alias the same.
1385 // Also, make sure exact and non-exact variants alias the same. 1385 // Also, make sure exact and non-exact variants alias the same.
1386 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset); 1386 tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
1387 }
1388 if (to->speculative() != NULL) {
1389 tj = to = TypeInstPtr::make(to->ptr(),to->klass(),to->klass_is_exact(),to->const_oop(),to->offset(), to->instance_id());
1387 } 1390 }
1388 // Canonicalize the holder of this field 1391 // Canonicalize the holder of this field
1389 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) { 1392 if (offset >= 0 && offset < instanceOopDesc::base_offset_in_bytes()) {
1390 // First handle header references such as a LoadKlassNode, even if the 1393 // First handle header references such as a LoadKlassNode, even if the
1391 // object's klass is unloaded at compile time (4965979). 1394 // object's klass is unloaded at compile time (4965979).
2010 2013
2011 print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2); 2014 print_method(PHASE_INCREMENTAL_BOXING_INLINE, 2);
2012 2015
2013 if (failing()) return; 2016 if (failing()) return;
2014 } 2017 }
2018
2019 // Remove the speculative part of types and clean up the graph from
2020 // the extra CastPP nodes whose only purpose is to carry them. Do
2021 // that early so that optimizations are not disrupted by the extra
2022 // CastPP nodes.
2023 remove_speculative_types(igvn);
2015 2024
2016 // No more new expensive nodes will be added to the list from here 2025 // No more new expensive nodes will be added to the list from here
2017 // so keep only the actual candidates for optimizations. 2026 // so keep only the actual candidates for optimizations.
2018 cleanup_expensive_nodes(igvn); 2027 cleanup_expensive_nodes(igvn);
2019 2028
3797 // OptimizeExpensiveOps is off. 3806 // OptimizeExpensiveOps is off.
3798 n->set_req(0, NULL); 3807 n->set_req(0, NULL);
3799 } 3808 }
3800 } 3809 }
3801 3810
3811 /**
3812 * Remove the speculative part of types and clean up the graph
3813 */
3814 void Compile::remove_speculative_types(PhaseIterGVN &igvn) {
3815 if (UseTypeSpeculation) {
3816 Unique_Node_List worklist;
3817 worklist.push(root());
3818 int modified = 0;
3819 // Go over all type nodes that carry a speculative type, drop the
3820 // speculative part of the type and enqueue the node for an igvn
3821 // which may optimize it out.
3822 for (uint next = 0; next < worklist.size(); ++next) {
3823 Node *n = worklist.at(next);
3824 if (n->is_Type() && n->as_Type()->type()->isa_oopptr() != NULL &&
3825 n->as_Type()->type()->is_oopptr()->speculative() != NULL) {
3826 TypeNode* tn = n->as_Type();
3827 const TypeOopPtr* t = tn->type()->is_oopptr();
3828 bool in_hash = igvn.hash_delete(n);
3829 assert(in_hash, "node should be in igvn hash table");
3830 tn->set_type(t->remove_speculative());
3831 igvn.hash_insert(n);
3832 igvn._worklist.push(n); // give it a chance to go away
3833 modified++;
3834 }
3835 uint max = n->len();
3836 for( uint i = 0; i < max; ++i ) {
3837 Node *m = n->in(i);
3838 if (not_a_node(m)) continue;
3839 worklist.push(m);
3840 }
3841 }
3842 // Drop the speculative part of all types in the igvn's type table
3843 igvn.remove_speculative_types();
3844 if (modified > 0) {
3845 igvn.optimize();
3846 }
3847 }
3848 }
3849
3802 // Auxiliary method to support randomized stressing/fuzzing. 3850 // Auxiliary method to support randomized stressing/fuzzing.
3803 // 3851 //
3804 // This method can be called the arbitrary number of times, with current count 3852 // This method can be called the arbitrary number of times, with current count
3805 // as the argument. The logic allows selecting a single candidate from the 3853 // as the argument. The logic allows selecting a single candidate from the
3806 // running list of candidates as follows: 3854 // running list of candidates as follows: