< prev index next >

src/share/vm/opto/loopTransform.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 68,80 **** _phase->_igvn._worklist.push(n); } } //------------------------------compute_exact_trip_count----------------------- ! // Compute loop exact trip count if possible. Do not recalculate trip count for // split loops (pre-main-post) which have their limits and inits behind Opaque node. ! void IdealLoopTree::compute_exact_trip_count( PhaseIdealLoop *phase ) { if (!_head->as_Loop()->is_valid_counted_loop()) { return; } CountedLoopNode* cl = _head->as_CountedLoop(); // Trip count may become nonexact for iteration split loops since --- 68,80 ---- _phase->_igvn._worklist.push(n); } } //------------------------------compute_exact_trip_count----------------------- ! // Compute loop trip count if possible. Do not recalculate trip count for // split loops (pre-main-post) which have their limits and inits behind Opaque node. ! void IdealLoopTree::compute_trip_count(PhaseIdealLoop* phase) { if (!_head->as_Loop()->is_valid_counted_loop()) { return; } CountedLoopNode* cl = _head->as_CountedLoop(); // Trip count may become nonexact for iteration split loops since
*** 92,112 **** bt == BoolTest::ne, "canonical test is expected"); #endif Node* init_n = cl->init_trip(); Node* limit_n = cl->limit(); ! if (init_n != NULL && init_n->is_Con() && ! limit_n != NULL && limit_n->is_Con()) { // Use longs to avoid integer overflow. int stride_con = cl->stride_con(); ! jlong init_con = cl->init_trip()->get_int(); ! jlong limit_con = cl->limit()->get_int(); int stride_m = stride_con - (stride_con > 0 ? 1 : -1); jlong trip_count = (limit_con - init_con + stride_m)/stride_con; if (trip_count > 0 && (julong)trip_count < (julong)max_juint) { // Set exact trip count. cl->set_exact_trip_count((uint)trip_count); } } } //------------------------------compute_profile_trip_cnt---------------------------- --- 92,116 ---- bt == BoolTest::ne, "canonical test is expected"); #endif Node* init_n = cl->init_trip(); Node* limit_n = cl->limit(); ! if (init_n != NULL && limit_n != NULL) { // Use longs to avoid integer overflow. int stride_con = cl->stride_con(); ! jlong init_con = phase->_igvn.type(init_n)->is_int()->_lo; ! jlong limit_con = phase->_igvn.type(limit_n)->is_int()->_hi; int stride_m = stride_con - (stride_con > 0 ? 1 : -1); jlong trip_count = (limit_con - init_con + stride_m)/stride_con; if (trip_count > 0 && (julong)trip_count < (julong)max_juint) { + if (init_n->is_Con() && limit_n->is_Con()) { // Set exact trip count. cl->set_exact_trip_count((uint)trip_count); + } else if (cl->is_normal_loop() && cl->unrolled_count() == 1) { + // Set maximum trip count before unrolling. + cl->set_trip_count((uint)trip_count); + } } } } //------------------------------compute_profile_trip_cnt----------------------------
*** 1303,1313 **** // Step A: Create a new post-Loop. Node* main_exit = main_end->proj_out(false); assert(main_exit->Opcode() == Op_IfFalse, ""); int dd_main_exit = dom_depth(main_exit); ! // Step A1: Clone the loop body of main. The clone becomes the vector post-loop. // The main loop pre-header illegally has 2 control users (old & new loops). clone_loop(loop, old_new, dd_main_exit); assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, ""); post_head = old_new[main_head->_idx]->as_CountedLoop(); post_head->set_normal_loop(); --- 1307,1317 ---- // Step A: Create a new post-Loop. Node* main_exit = main_end->proj_out(false); assert(main_exit->Opcode() == Op_IfFalse, ""); int dd_main_exit = dom_depth(main_exit); ! // Step A1: Clone the loop body of main. The clone becomes the post-loop. // The main loop pre-header illegally has 2 control users (old & new loops). clone_loop(loop, old_new, dd_main_exit); assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, ""); post_head = old_new[main_head->_idx]->as_CountedLoop(); post_head->set_normal_loop();
*** 2093,2104 **** // Count number of range checks and reduce by load range limits, if zero, // the loop is in canonical form to multiversion. closed_range_checks = 0; ! // Check loop body for tests of trip-counter plus loop-invariant vs ! // loop-invariant. for( uint i = 0; i < loop->_body.size(); i++ ) { Node *iff = loop->_body[i]; if (iff->Opcode() == Op_If || iff->Opcode() == Op_RangeCheck) { // Test? // Test is an IfNode, has 2 projections. If BOTH are in the loop --- 2097,2107 ---- // Count number of range checks and reduce by load range limits, if zero, // the loop is in canonical form to multiversion. closed_range_checks = 0; ! // Check loop body for tests of trip-counter plus loop-invariant vs loop-variant. for( uint i = 0; i < loop->_body.size(); i++ ) { Node *iff = loop->_body[i]; if (iff->Opcode() == Op_If || iff->Opcode() == Op_RangeCheck) { // Test? // Test is an IfNode, has 2 projections. If BOTH are in the loop
*** 2296,2306 **** CountedLoopNode *cl = loop->_head->as_CountedLoop(); // skip this loop if it is already checked if (cl->has_been_range_checked()) return; ! // Now check for existance of range checks for (uint i = 0; i < loop->_body.size(); i++) { Node *iff = loop->_body[i]; int iff_opc = iff->Opcode(); if (iff_opc == Op_If || iff_opc == Op_RangeCheck) { cl->mark_has_range_checks(); --- 2299,2309 ---- CountedLoopNode *cl = loop->_head->as_CountedLoop(); // skip this loop if it is already checked if (cl->has_been_range_checked()) return; ! // Now check for existence of range checks for (uint i = 0; i < loop->_body.size(); i++) { Node *iff = loop->_body[i]; int iff_opc = iff->Opcode(); if (iff_opc == Op_If || iff_opc == Op_RangeCheck) { cl->mark_has_range_checks();
*** 2317,2327 **** bool multi_version_succeeded = false; assert(RangeCheckElimination, ""); CountedLoopNode *legacy_cl = legacy_loop->_head->as_CountedLoop(); assert(legacy_cl->is_post_loop(), ""); ! // Check for existance of range checks using the unique instance to make a guard with Unique_Node_List worklist; for (uint i = 0; i < legacy_loop->_body.size(); i++) { Node *iff = legacy_loop->_body[i]; int iff_opc = iff->Opcode(); if (iff_opc == Op_If || iff_opc == Op_RangeCheck) { --- 2320,2330 ---- bool multi_version_succeeded = false; assert(RangeCheckElimination, ""); CountedLoopNode *legacy_cl = legacy_loop->_head->as_CountedLoop(); assert(legacy_cl->is_post_loop(), ""); ! // Check for existence of range checks using the unique instance to make a guard with Unique_Node_List worklist; for (uint i = 0; i < legacy_loop->_body.size(); i++) { Node *iff = legacy_loop->_body[i]; int iff_opc = iff->Opcode(); if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
*** 2420,2430 **** return multi_version_succeeded; } //-------------------------poison_rce_post_loop-------------------------------- ! // Causes the rce'd post loop to be optimized away if multiverioning fails void PhaseIdealLoop::poison_rce_post_loop(IdealLoopTree *rce_loop) { CountedLoopNode *rce_cl = rce_loop->_head->as_CountedLoop(); Node* ctrl = rce_cl->in(LoopNode::EntryControl); if (ctrl->is_IfTrue() || ctrl->is_IfFalse()) { Node* iffm = ctrl->in(0); --- 2423,2433 ---- return multi_version_succeeded; } //-------------------------poison_rce_post_loop-------------------------------- ! // Causes the rce'd post loop to be optimized away if multiversioning fails void PhaseIdealLoop::poison_rce_post_loop(IdealLoopTree *rce_loop) { CountedLoopNode *rce_cl = rce_loop->_head->as_CountedLoop(); Node* ctrl = rce_cl->in(LoopNode::EntryControl); if (ctrl->is_IfTrue() || ctrl->is_IfFalse()) { Node* iffm = ctrl->in(0);
*** 2708,2719 **** } //============================================================================= //------------------------------iteration_split_impl--------------------------- bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { ! // Compute exact loop trip count if possible. ! compute_exact_trip_count(phase); // Convert one iteration loop into normal code. if (policy_do_one_iteration_loop(phase)) return true; --- 2711,2722 ---- } //============================================================================= //------------------------------iteration_split_impl--------------------------- bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { ! // Compute loop trip count if possible. ! compute_trip_count(phase); // Convert one iteration loop into normal code. if (policy_do_one_iteration_loop(phase)) return true;
< prev index next >