Mercurial > hg > truffle
comparison src/share/vm/opto/loopPredicate.cpp @ 13086:096c224171c4
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 20 Nov 2013 00:10:38 +0100 |
parents | 3213ba4d3dff |
children | de6a9e811145 |
comparison
equal
deleted
inserted
replaced
12782:92b7ec34ddfa | 13086:096c224171c4 |
---|---|
38 * The condition checks are promoted from inside the loop body, and thus | 38 * The condition checks are promoted from inside the loop body, and thus |
39 * the checks inside the loop could be eliminated. Currently, loop predication | 39 * the checks inside the loop could be eliminated. Currently, loop predication |
40 * optimization has been applied to remove array range check and loop invariant | 40 * optimization has been applied to remove array range check and loop invariant |
41 * checks (such as null checks). | 41 * checks (such as null checks). |
42 */ | 42 */ |
43 | |
44 //-------------------------------is_uncommon_trap_proj---------------------------- | |
45 // Return true if proj is the form of "proj->[region->..]call_uct" | |
46 bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) { | |
47 int path_limit = 10; | |
48 assert(proj, "invalid argument"); | |
49 Node* out = proj; | |
50 for (int ct = 0; ct < path_limit; ct++) { | |
51 out = out->unique_ctrl_out(); | |
52 if (out == NULL) | |
53 return false; | |
54 if (out->is_CallStaticJava()) { | |
55 int req = out->as_CallStaticJava()->uncommon_trap_request(); | |
56 if (req != 0) { | |
57 Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req); | |
58 if (trap_reason == reason || reason == Deoptimization::Reason_none) { | |
59 return true; | |
60 } | |
61 } | |
62 return false; // don't do further after call | |
63 } | |
64 if (out->Opcode() != Op_Region) | |
65 return false; | |
66 } | |
67 return false; | |
68 } | |
69 | |
70 //-------------------------------is_uncommon_trap_if_pattern------------------------- | |
71 // Return true for "if(test)-> proj -> ... | |
72 // | | |
73 // V | |
74 // other_proj->[region->..]call_uct" | |
75 // | |
76 // "must_reason_predicate" means the uct reason must be Reason_predicate | |
77 bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) { | |
78 Node *in0 = proj->in(0); | |
79 if (!in0->is_If()) return false; | |
80 // Variation of a dead If node. | |
81 if (in0->outcnt() < 2) return false; | |
82 IfNode* iff = in0->as_If(); | |
83 | |
84 // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate | |
85 if (reason != Deoptimization::Reason_none) { | |
86 if (iff->in(1)->Opcode() != Op_Conv2B || | |
87 iff->in(1)->in(1)->Opcode() != Op_Opaque1) { | |
88 return false; | |
89 } | |
90 } | |
91 | |
92 ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj(); | |
93 if (is_uncommon_trap_proj(other_proj, reason)) { | |
94 assert(reason == Deoptimization::Reason_none || | |
95 Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list"); | |
96 return true; | |
97 } | |
98 return false; | |
99 } | |
100 | 43 |
101 //-------------------------------register_control------------------------- | 44 //-------------------------------register_control------------------------- |
102 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) { | 45 void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) { |
103 assert(n->is_CFG(), "must be control node"); | 46 assert(n->is_CFG(), "must be control node"); |
104 _igvn.register_new_node_with_optimizer(n); | 47 _igvn.register_new_node_with_optimizer(n); |
145 // We will create a region to guard the uct call if there is no one there. | 88 // We will create a region to guard the uct call if there is no one there. |
146 // The true projecttion (if_cont) of the new_iff is returned. | 89 // The true projecttion (if_cont) of the new_iff is returned. |
147 // This code is also used to clone predicates to clonned loops. | 90 // This code is also used to clone predicates to clonned loops. |
148 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, | 91 ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, |
149 Deoptimization::DeoptReason reason) { | 92 Deoptimization::DeoptReason reason) { |
150 assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); | 93 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!"); |
151 IfNode* iff = cont_proj->in(0)->as_If(); | 94 IfNode* iff = cont_proj->in(0)->as_If(); |
152 | 95 |
153 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); | 96 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); |
154 Node *rgn = uncommon_proj->unique_ctrl_out(); | 97 Node *rgn = uncommon_proj->unique_ctrl_out(); |
155 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); | 98 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); |
233 //------------------------------create_new_if_for_predicate------------------------ | 176 //------------------------------create_new_if_for_predicate------------------------ |
234 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization) | 177 // Create a new if below new_entry for the predicate to be cloned (IGVN optimization) |
235 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, | 178 ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry, |
236 Deoptimization::DeoptReason reason) { | 179 Deoptimization::DeoptReason reason) { |
237 assert(new_entry != 0, "only used for clone predicate"); | 180 assert(new_entry != 0, "only used for clone predicate"); |
238 assert(PhaseIdealLoop::is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!"); | 181 assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!"); |
239 IfNode* iff = cont_proj->in(0)->as_If(); | 182 IfNode* iff = cont_proj->in(0)->as_If(); |
240 | 183 |
241 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); | 184 ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con); |
242 Node *rgn = uncommon_proj->unique_ctrl_out(); | 185 Node *rgn = uncommon_proj->unique_ctrl_out(); |
243 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); | 186 assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct"); |
420 //--------------------------find_predicate_insertion_point------------------- | 363 //--------------------------find_predicate_insertion_point------------------- |
421 // Find a good location to insert a predicate | 364 // Find a good location to insert a predicate |
422 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) { | 365 ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) { |
423 if (start_c == NULL || !start_c->is_Proj()) | 366 if (start_c == NULL || !start_c->is_Proj()) |
424 return NULL; | 367 return NULL; |
425 if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) { | 368 if (start_c->as_Proj()->is_uncommon_trap_if_pattern(reason)) { |
426 return start_c->as_Proj(); | 369 return start_c->as_Proj(); |
427 } | 370 } |
428 return NULL; | 371 return NULL; |
429 } | 372 } |
430 | 373 |
771 ProjNode* new_predicate_proj = NULL; | 714 ProjNode* new_predicate_proj = NULL; |
772 | 715 |
773 ProjNode* proj = if_proj_list.pop()->as_Proj(); | 716 ProjNode* proj = if_proj_list.pop()->as_Proj(); |
774 IfNode* iff = proj->in(0)->as_If(); | 717 IfNode* iff = proj->in(0)->as_If(); |
775 | 718 |
776 if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) { | 719 if (!proj->is_uncommon_trap_if_pattern(Deoptimization::Reason_none)) { |
777 if (loop->is_loop_exit(iff)) { | 720 if (loop->is_loop_exit(iff)) { |
778 // stop processing the remaining projs in the list because the execution of them | 721 // stop processing the remaining projs in the list because the execution of them |
779 // depends on the condition of "iff" (iff->in(1)). | 722 // depends on the condition of "iff" (iff->in(1)). |
780 break; | 723 break; |
781 } else { | 724 } else { |