--- old/src/share/vm/opto/loopnode.hpp 2016-03-25 13:54:53.970969700 -0700 +++ new/src/share/vm/opto/loopnode.hpp 2016-03-25 13:54:53.492969700 -0700 @@ -69,7 +69,9 @@ PassedSlpAnalysis=512, DoUnrollOnly=1024, VectorizedLoop=2048, - HasAtomicPostLoop=4096 }; + HasAtomicPostLoop=4096, + HasRangeChecks=8192, + IsMultiversioned=16384}; char _unswitch_count; enum { _unswitch_max=3 }; @@ -80,9 +82,13 @@ int is_inner_loop() const { return _loop_flags & InnerLoop; } void set_inner_loop() { _loop_flags |= InnerLoop; } + int has_range_checks() const { return _loop_flags & HasRangeChecks; } + int is_multiversioned() const { return _loop_flags & IsMultiversioned; } + int is_vectorized_loop() const { return _loop_flags & VectorizedLoop; } int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; } void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; } int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; } + void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; } void mark_has_reductions() { _loop_flags |= HasReductions; } void mark_was_slp() { _loop_flags |= WasSlpAnalyzed; } @@ -90,6 +96,8 @@ void mark_do_unroll_only() { _loop_flags |= DoUnrollOnly; } void mark_loop_vectorized() { _loop_flags |= VectorizedLoop; } void mark_has_atomic_post_loop() { _loop_flags |= HasAtomicPostLoop; } + void mark_has_range_checks() { _loop_flags |= HasRangeChecks; } + void mark_is_multiversioned() { _loop_flags |= IsMultiversioned; } int unswitch_max() { return _unswitch_max; } int unswitch_count() { return _unswitch_count; } @@ -225,7 +233,6 @@ int has_passed_slp () const { return (_loop_flags&PassedSlpAnalysis) == PassedSlpAnalysis; } int do_unroll_only () const { return (_loop_flags&DoUnrollOnly) == DoUnrollOnly; } int is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; } - int is_vectorized_loop () const { return (_loop_flags & VectorizedLoop) == VectorizedLoop; } int has_atomic_post_loop () const { return (_loop_flags & HasAtomicPostLoop) == HasAtomicPostLoop; } void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; } @@ -542,6 +549,16 @@ }; +class PostLoopInfo { +public: + Node *new_main_exit; + CountedLoopNode *post_head; + + PostLoopInfo() { init(); } + + void init() { new_main_exit = NULL; post_head = NULL; } +}; + // -----------------------------PhaseIdealLoop--------------------------------- // Computes the mapping from Nodes to IdealLoopTrees. Organizes IdealLoopTrees into a // loop tree. Drives the loop-based transformations on the ideal graph. @@ -908,6 +925,15 @@ // Add pre and post loops around the given loop. These loops are used // during RCE, unrolling and aligning loops. void insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ); + + // Add post loop after the given loop. + void insert_post_loop( IdealLoopTree *loop, Node_List &old_new, + CountedLoopNode *main_head, CountedLoopEndNode *main_end, + Node *incr, Node *limit, PostLoopInfo &post_loop_info ); + + // Add an RCE'd post loop which we will multi-version adapt for run time test path usage + void insert_scalar_rced_post_loop( IdealLoopTree *loop, Node_List &old_new ); + // Add a vector post loop between a vector main loop and the current post loop void insert_vector_post_loop(IdealLoopTree *loop, Node_List &old_new); // If Node n lives in the back_ctrl block, we clone a private version of n @@ -982,6 +1008,16 @@ // Eliminate range-checks and other trip-counter vs loop-invariant tests. void do_range_check( IdealLoopTree *loop, Node_List &old_new ); + // Check to see if do_range_check(...) cleaned the main loop of range-checks + void has_range_checks(IdealLoopTree *loop); + + // Process post loops which have range checks and try to build a multi-version + // guard to safely determine if we can execute the post loop which was RCE'd. + bool multi_version_post_loops(IdealLoopTree *rce_loop, IdealLoopTree *legacy_loop); + + // Cause the rce'd post loop to optimized away, this happens if we cannot complete multiverioning + void poison_rce_post_loop(IdealLoopTree *rce_loop); + // Create a slow version of the loop by cloning the loop // and inserting an if to select fast-slow versions. ProjNode* create_slow_version_of_loop(IdealLoopTree *loop,