< prev index next >
src/share/vm/opto/loopnode.hpp
Print this page
*** 67,97 ****
HasReductions=128,
WasSlpAnalyzed=256,
PassedSlpAnalysis=512,
DoUnrollOnly=1024,
VectorizedLoop=2048,
! HasAtomicPostLoop=4096 };
char _unswitch_count;
enum { _unswitch_max=3 };
public:
// Names for edge indices
enum { Self=0, EntryControl, LoopBackControl };
int is_inner_loop() const { return _loop_flags & InnerLoop; }
void set_inner_loop() { _loop_flags |= InnerLoop; }
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; }
void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
void mark_do_unroll_only() { _loop_flags |= DoUnrollOnly; }
void mark_loop_vectorized() { _loop_flags |= VectorizedLoop; }
void mark_has_atomic_post_loop() { _loop_flags |= HasAtomicPostLoop; }
int unswitch_max() { return _unswitch_max; }
int unswitch_count() { return _unswitch_count; }
void set_unswitch_count(int val) {
assert (val <= unswitch_max(), "too many unswitches");
--- 67,105 ----
HasReductions=128,
WasSlpAnalyzed=256,
PassedSlpAnalysis=512,
DoUnrollOnly=1024,
VectorizedLoop=2048,
! HasAtomicPostLoop=4096,
! HasRangeChecks=8192,
! IsMultiversioned=16384};
char _unswitch_count;
enum { _unswitch_max=3 };
public:
// Names for edge indices
enum { Self=0, EntryControl, LoopBackControl };
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; }
void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
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; }
void set_unswitch_count(int val) {
assert (val <= unswitch_max(), "too many unswitches");
*** 223,233 ****
int is_reduction_loop() const { return (_loop_flags&HasReductions) == HasReductions; }
int was_slp_analyzed () const { return (_loop_flags&WasSlpAnalyzed) == WasSlpAnalyzed; }
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; }
int main_idx() const { return _main_idx; }
--- 231,240 ----
*** 540,549 ****
--- 547,566 ----
void verify_tree(IdealLoopTree *loop, const IdealLoopTree *parent) const;
#endif
};
+ 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.
class PhaseIdealLoop : public PhaseTransform {
friend class IdealLoopTree;
*** 906,915 ****
--- 923,941 ----
void do_peeling( IdealLoopTree *loop, Node_List &old_new );
// 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
// in preheader_ctrl block and return that, otherwise return n.
Node *clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ctrl, Node *n, VectorSet &visited, Node_Stack &clones );
*** 980,989 ****
--- 1006,1025 ----
}
// 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,
Node_List &old_new,
int opcode);
< prev index next >