@@ -1888,55 +1888,6 @@ void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old
18881888 loop->record_for_igvn ();
18891889}
18901890
1891-
1892- // -------------------------insert_scalar_rced_post_loop------------------------
1893- // Insert a copy of the rce'd main loop as a post loop,
1894- // We have not unrolled the main loop, so this is the right time to inject this.
1895- // Later we will examine the partner of this post loop pair which still has range checks
1896- // to see inject code which tests at runtime if the range checks are applicable.
1897- void PhaseIdealLoop::insert_scalar_rced_post_loop (IdealLoopTree *loop, Node_List &old_new) {
1898- if (!loop->_head ->is_CountedLoop ()) return ;
1899-
1900- CountedLoopNode *cl = loop->_head ->as_CountedLoop ();
1901-
1902- // only process RCE'd main loops
1903- if (!cl->is_main_loop () || loop->range_checks_present ()) return ;
1904-
1905- #ifndef PRODUCT
1906- if (TraceLoopOpts) {
1907- tty->print (" PostScalarRce " );
1908- loop->dump_head ();
1909- }
1910- #endif
1911- C->set_major_progress ();
1912-
1913- // Find common pieces of the loop being guarded with pre & post loops
1914- CountedLoopNode *main_head = loop->_head ->as_CountedLoop ();
1915- CountedLoopEndNode *main_end = main_head->loopexit ();
1916- // diagnostic to show loop end is not properly formed
1917- assert (main_end->outcnt () == 2 , " 1 true, 1 false path only" );
1918-
1919- Node *incr = main_end->incr ();
1920- Node *limit = main_end->limit ();
1921-
1922- // In this case we throw away the result as we are not using it to connect anything else.
1923- CountedLoopNode *post_head = nullptr ;
1924- insert_post_loop (loop, old_new, main_head, main_end, incr, limit, post_head);
1925- copy_assertion_predicates_to_post_loop (main_head->skip_strip_mined (), post_head, incr, main_head->stride ());
1926-
1927- // It's difficult to be precise about the trip-counts
1928- // for post loops. They are usually very short,
1929- // so guess that unit vector trips is a reasonable value.
1930- post_head->set_profile_trip_cnt (4.0 );
1931- post_head->set_is_rce_post_loop ();
1932-
1933- // Now force out all loop-invariant dominating tests. The optimizer
1934- // finds some, but we _know_ they are all useless.
1935- peeled_dom_test_elim (loop, old_new);
1936- loop->record_for_igvn ();
1937- }
1938-
1939-
19401891// ------------------------------insert_post_loop-------------------------------
19411892// Insert post loops. Add a post loop to the given loop passed.
19421893Node *PhaseIdealLoop::insert_post_loop (IdealLoopTree* loop, Node_List& old_new,
@@ -3198,143 +3149,6 @@ bool IdealLoopTree::compute_has_range_checks() const {
31983149 return false ;
31993150}
32003151
3201- // -------------------------multi_version_post_loops----------------------------
3202- // Check the range checks that remain, if simple, use the bounds to guard
3203- // which version to a post loop we execute, one with range checks or one without
3204- bool PhaseIdealLoop::multi_version_post_loops (IdealLoopTree *rce_loop, IdealLoopTree *legacy_loop) {
3205- bool multi_version_succeeded = false ;
3206- assert (RangeCheckElimination, " " );
3207- CountedLoopNode *legacy_cl = legacy_loop->_head ->as_CountedLoop ();
3208- assert (legacy_cl->is_post_loop (), " " );
3209-
3210- // Check for existence of range checks using the unique instance to make a guard with
3211- Unique_Node_List worklist;
3212- for (uint i = 0 ; i < legacy_loop->_body .size (); i++) {
3213- Node *iff = legacy_loop->_body [i];
3214- int iff_opc = iff->Opcode ();
3215- if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
3216- worklist.push (iff);
3217- }
3218- }
3219-
3220- // Find RCE'd post loop so that we can stage its guard.
3221- if (legacy_cl->is_canonical_loop_entry () == nullptr ) {
3222- return multi_version_succeeded;
3223- }
3224- Node* ctrl = legacy_cl->in (LoopNode::EntryControl);
3225- Node* iffm = ctrl->in (0 );
3226-
3227- // Now we test that both the post loops are connected
3228- Node* post_loop_region = iffm->in (0 );
3229- if (post_loop_region == nullptr ) return multi_version_succeeded;
3230- if (!post_loop_region->is_Region ()) return multi_version_succeeded;
3231- Node* covering_region = post_loop_region->in (RegionNode::Control+1 );
3232- if (covering_region == nullptr ) return multi_version_succeeded;
3233- if (!covering_region->is_Region ()) return multi_version_succeeded;
3234- Node* p_f = covering_region->in (RegionNode::Control);
3235- if (p_f == nullptr ) return multi_version_succeeded;
3236- if (!p_f->is_IfFalse ()) return multi_version_succeeded;
3237- if (!p_f->in (0 )->is_CountedLoopEnd ()) return multi_version_succeeded;
3238- CountedLoopEndNode* rce_loop_end = p_f->in (0 )->as_CountedLoopEnd ();
3239- if (rce_loop_end == nullptr ) return multi_version_succeeded;
3240- CountedLoopNode* rce_cl = rce_loop_end->loopnode ();
3241- if (rce_cl == nullptr || !rce_cl->is_post_loop ()) return multi_version_succeeded;
3242- CountedLoopNode *known_rce_cl = rce_loop->_head ->as_CountedLoop ();
3243- if (rce_cl != known_rce_cl) return multi_version_succeeded;
3244-
3245- // Then we fetch the cover entry test
3246- ctrl = rce_cl->in (LoopNode::EntryControl);
3247- if (!ctrl->is_IfTrue () && !ctrl->is_IfFalse ()) return multi_version_succeeded;
3248-
3249- #ifndef PRODUCT
3250- if (TraceLoopOpts) {
3251- tty->print (" PostMultiVersion\n " );
3252- rce_loop->dump_head ();
3253- legacy_loop->dump_head ();
3254- }
3255- #endif
3256-
3257- // Now fetch the limit we want to compare against
3258- Node *limit = rce_cl->limit ();
3259- bool first_time = true ;
3260-
3261- // If we got this far, we identified the post loop which has been RCE'd and
3262- // we have a work list. Now we will try to transform the if guard to cause
3263- // the loop pair to be multi version executed with the determination left to runtime
3264- // or the optimizer if full information is known about the given arrays at compile time.
3265- Node *last_min = nullptr ;
3266- multi_version_succeeded = true ;
3267- while (worklist.size ()) {
3268- Node* rc_iffm = worklist.pop ();
3269- if (rc_iffm->is_If ()) {
3270- Node *rc_bolzm = rc_iffm->in (1 );
3271- if (rc_bolzm->is_Bool ()) {
3272- Node *rc_cmpzm = rc_bolzm->in (1 );
3273- if (rc_cmpzm->is_Cmp ()) {
3274- Node *rc_left = rc_cmpzm->in (2 );
3275- if (rc_left->Opcode () != Op_LoadRange) {
3276- multi_version_succeeded = false ;
3277- break ;
3278- }
3279- if (first_time) {
3280- last_min = rc_left;
3281- first_time = false ;
3282- } else {
3283- Node *cur_min = new MinINode (last_min, rc_left);
3284- last_min = cur_min;
3285- _igvn.register_new_node_with_optimizer (last_min);
3286- }
3287- }
3288- }
3289- }
3290- }
3291-
3292- // All we have to do is update the limit of the rce loop
3293- // with the min of our expression and the current limit.
3294- // We will use this expression to replace the current limit.
3295- if (last_min && multi_version_succeeded) {
3296- Node *cur_min = new MinINode (last_min, limit);
3297- _igvn.register_new_node_with_optimizer (cur_min);
3298- Node *cmp_node = rce_loop_end->cmp_node ();
3299- _igvn.replace_input_of (cmp_node, 2 , cur_min);
3300- set_ctrl (cur_min, ctrl);
3301- set_loop (cur_min, rce_loop->_parent );
3302-
3303- legacy_cl->mark_is_multiversioned ();
3304- rce_cl->mark_is_multiversioned ();
3305- multi_version_succeeded = true ;
3306-
3307- C->set_major_progress ();
3308- }
3309-
3310- return multi_version_succeeded;
3311- }
3312-
3313- // -------------------------poison_rce_post_loop--------------------------------
3314- // Causes the rce'd post loop to be optimized away if multiversioning fails
3315- void PhaseIdealLoop::poison_rce_post_loop (IdealLoopTree *rce_loop) {
3316- CountedLoopNode *rce_cl = rce_loop->_head ->as_CountedLoop ();
3317- Node* ctrl = rce_cl->in (LoopNode::EntryControl);
3318- if (ctrl->is_IfTrue () || ctrl->is_IfFalse ()) {
3319- Node* iffm = ctrl->in (0 );
3320- if (iffm->is_If ()) {
3321- Node* cur_bool = iffm->in (1 );
3322- if (cur_bool->is_Bool ()) {
3323- Node* cur_cmp = cur_bool->in (1 );
3324- if (cur_cmp->is_Cmp ()) {
3325- BoolTest::mask new_test = BoolTest::gt;
3326- BoolNode *new_bool = new BoolNode (cur_cmp, new_test);
3327- _igvn.replace_node (cur_bool, new_bool);
3328- _igvn._worklist .push (new_bool);
3329- Node* left_op = cur_cmp->in (1 );
3330- _igvn.replace_input_of (cur_cmp, 2 , left_op);
3331- C->set_major_progress ();
3332- }
3333- }
3334- }
3335- }
3336- }
3337-
33383152// ------------------------------DCE_loop_body----------------------------------
33393153// Remove simplistic dead code from loop body
33403154void IdealLoopTree::DCE_loop_body () {
@@ -3864,14 +3678,6 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
38643678 phase->do_range_check (this , old_new);
38653679 }
38663680
3867- if (should_unroll && !should_peel && PostLoopMultiversioning &&
3868- Matcher::has_predicated_vectors ()) {
3869- // Try to setup multiversioning on main loops before they are unrolled
3870- if (cl->is_main_loop () && (cl->unrolled_count () == 1 )) {
3871- phase->insert_scalar_rced_post_loop (this , old_new);
3872- }
3873- }
3874-
38753681 // Double loop body for unrolling. Adjust the minimum-trip test (will do
38763682 // twice as many iterations as before) and the main body limit (only do
38773683 // an even number of trips). If we are peeling, we might enable some RCE
0 commit comments