47 //
48 // Idealized loops are the set of loops I perform more interesting
49 // transformations on, beyond simple hoisting.
50
51 //------------------------------LoopNode---------------------------------------
52 // Simple loop header. Fall in path on left, loop-back path on right.
53 class LoopNode : public RegionNode {
54 // Size is bigger to hold the flags. However, the flags do not change
55 // the semantics so it does not appear in the hash & cmp functions.
56 virtual uint size_of() const { return sizeof(*this); }
57 protected:
58 short _loop_flags;
59 // Names for flag bitfields
60 enum { Normal=0, Pre=1, Main=2, Post=3, PreMainPostFlagsMask=3,
61 MainHasNoPreLoop=4,
62 HasExactTripCount=8,
63 InnerLoop=16,
64 PartialPeelLoop=32,
65 PartialPeelFailed=64,
66 HasReductions=128,
67 PassedSlpAnalysis=256 };
68 char _unswitch_count;
69 enum { _unswitch_max=3 };
70
71 public:
72 // Names for edge indices
73 enum { Self=0, EntryControl, LoopBackControl };
74
75 int is_inner_loop() const { return _loop_flags & InnerLoop; }
76 void set_inner_loop() { _loop_flags |= InnerLoop; }
77
78 int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; }
79 void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; }
80 int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
81 void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
82 void mark_has_reductions() { _loop_flags |= HasReductions; }
83 void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
84
85 int unswitch_max() { return _unswitch_max; }
86 int unswitch_count() { return _unswitch_count; }
87 void set_unswitch_count(int val) {
88 assert (val <= unswitch_max(), "too many unswitches");
89 _unswitch_count = val;
90 }
91
92 LoopNode( Node *entry, Node *backedge ) : RegionNode(3), _loop_flags(0), _unswitch_count(0) {
93 init_class_id(Class_Loop);
94 init_req(EntryControl, entry);
95 init_req(LoopBackControl, backedge);
96 }
97
98 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
99 virtual int Opcode() const;
100 bool can_be_counted_loop(PhaseTransform* phase) const {
101 return req() == 3 && in(0) != NULL &&
102 in(1) != NULL && phase->type(in(1)) != Type::TOP &&
103 in(2) != NULL && phase->type(in(2)) != Type::TOP;
195 // It will be RCE'd and unrolled and aligned.
196
197 // A following 'post' loop will run any remaining iterations. Used
198 // during Range Check Elimination, the 'post' loop will do any final
199 // iterations with full checks. Also used by Loop Unrolling, where
200 // the 'post' loop will do any epilog iterations needed. Basically,
201 // a 'post' loop can not profitably be further unrolled or RCE'd.
202
203 // A preceding 'pre' loop will run at least 1 iteration (to do peeling),
204 // it may do under-flow checks for RCE and may do alignment iterations
205 // so the following main loop 'knows' that it is striding down cache
206 // lines.
207
208 // A 'main' loop that is ONLY unrolled or peeled, never RCE'd or
209 // Aligned, may be missing it's pre-loop.
210 int is_normal_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Normal; }
211 int is_pre_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Pre; }
212 int is_main_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Main; }
213 int is_post_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Post; }
214 int is_reduction_loop() const { return (_loop_flags&HasReductions) == HasReductions; }
215 int has_passed_slp () const { return (_loop_flags&PassedSlpAnalysis) == PassedSlpAnalysis; }
216 int is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; }
217 void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; }
218
219 int main_idx() const { return _main_idx; }
220
221
222 void set_pre_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Pre ; _main_idx = main->_idx; }
223 void set_main_loop ( ) { assert(is_normal_loop(),""); _loop_flags |= Main; }
224 void set_post_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Post; _main_idx = main->_idx; }
225 void set_normal_loop( ) { _loop_flags &= ~PreMainPostFlagsMask; }
226
227 void set_trip_count(uint tc) { _trip_count = tc; }
228 uint trip_count() { return _trip_count; }
229
230 bool has_exact_trip_count() const { return (_loop_flags & HasExactTripCount) != 0; }
231 void set_exact_trip_count(uint tc) {
232 _trip_count = tc;
233 _loop_flags |= HasExactTripCount;
234 }
235 void set_nonexact_trip_count() {
236 _loop_flags &= ~HasExactTripCount;
237 }
238
239 void set_profile_trip_cnt(float ptc) { _profile_trip_cnt = ptc; }
240 float profile_trip_cnt() { return _profile_trip_cnt; }
241
242 void double_unrolled_count() { _unrolled_count_log2++; }
243 int unrolled_count() { return 1 << MIN2(_unrolled_count_log2, BitsPerInt-3); }
244
245 void set_node_count_before_unroll(int ct) { _node_count_before_unroll = ct; }
246 int node_count_before_unroll() { return _node_count_before_unroll; }
247 void set_slp_max_unroll(int unroll_factor) { _slp_maximum_unroll_factor = unroll_factor; }
248 int slp_max_unroll() const { return _slp_maximum_unroll_factor; }
249
250 #ifndef PRODUCT
251 virtual void dump_spec(outputStream *st) const;
252 #endif
253 };
254
255 //------------------------------CountedLoopEndNode-----------------------------
256 // CountedLoopEndNodes end simple trip counted loops. They act much like
|
47 //
48 // Idealized loops are the set of loops I perform more interesting
49 // transformations on, beyond simple hoisting.
50
51 //------------------------------LoopNode---------------------------------------
52 // Simple loop header. Fall in path on left, loop-back path on right.
53 class LoopNode : public RegionNode {
54 // Size is bigger to hold the flags. However, the flags do not change
55 // the semantics so it does not appear in the hash & cmp functions.
56 virtual uint size_of() const { return sizeof(*this); }
57 protected:
58 short _loop_flags;
59 // Names for flag bitfields
60 enum { Normal=0, Pre=1, Main=2, Post=3, PreMainPostFlagsMask=3,
61 MainHasNoPreLoop=4,
62 HasExactTripCount=8,
63 InnerLoop=16,
64 PartialPeelLoop=32,
65 PartialPeelFailed=64,
66 HasReductions=128,
67 WasSlpAnalyzed=256,
68 PassedSlpAnalysis=512,
69 NoMoreSlp=1024 };
70 char _unswitch_count;
71 enum { _unswitch_max=3 };
72
73 public:
74 // Names for edge indices
75 enum { Self=0, EntryControl, LoopBackControl };
76
77 int is_inner_loop() const { return _loop_flags & InnerLoop; }
78 void set_inner_loop() { _loop_flags |= InnerLoop; }
79
80 int is_partial_peel_loop() const { return _loop_flags & PartialPeelLoop; }
81 void set_partial_peel_loop() { _loop_flags |= PartialPeelLoop; }
82 int partial_peel_has_failed() const { return _loop_flags & PartialPeelFailed; }
83 void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
84 void mark_has_reductions() { _loop_flags |= HasReductions; }
85 void mark_was_slp() { _loop_flags |= WasSlpAnalyzed; }
86 void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
87 void mark_no_slp() { _loop_flags |= NoMoreSlp; }
88
89 int unswitch_max() { return _unswitch_max; }
90 int unswitch_count() { return _unswitch_count; }
91 void set_unswitch_count(int val) {
92 assert (val <= unswitch_max(), "too many unswitches");
93 _unswitch_count = val;
94 }
95
96 LoopNode( Node *entry, Node *backedge ) : RegionNode(3), _loop_flags(0), _unswitch_count(0) {
97 init_class_id(Class_Loop);
98 init_req(EntryControl, entry);
99 init_req(LoopBackControl, backedge);
100 }
101
102 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
103 virtual int Opcode() const;
104 bool can_be_counted_loop(PhaseTransform* phase) const {
105 return req() == 3 && in(0) != NULL &&
106 in(1) != NULL && phase->type(in(1)) != Type::TOP &&
107 in(2) != NULL && phase->type(in(2)) != Type::TOP;
199 // It will be RCE'd and unrolled and aligned.
200
201 // A following 'post' loop will run any remaining iterations. Used
202 // during Range Check Elimination, the 'post' loop will do any final
203 // iterations with full checks. Also used by Loop Unrolling, where
204 // the 'post' loop will do any epilog iterations needed. Basically,
205 // a 'post' loop can not profitably be further unrolled or RCE'd.
206
207 // A preceding 'pre' loop will run at least 1 iteration (to do peeling),
208 // it may do under-flow checks for RCE and may do alignment iterations
209 // so the following main loop 'knows' that it is striding down cache
210 // lines.
211
212 // A 'main' loop that is ONLY unrolled or peeled, never RCE'd or
213 // Aligned, may be missing it's pre-loop.
214 int is_normal_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Normal; }
215 int is_pre_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Pre; }
216 int is_main_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Main; }
217 int is_post_loop () const { return (_loop_flags&PreMainPostFlagsMask) == Post; }
218 int is_reduction_loop() const { return (_loop_flags&HasReductions) == HasReductions; }
219 int was_slp_analyzed () const { return (_loop_flags&WasSlpAnalyzed) == WasSlpAnalyzed; }
220 int has_passed_slp () const { return (_loop_flags&PassedSlpAnalysis) == PassedSlpAnalysis; }
221 int ignore_slp () const { return (_loop_flags&NoMoreSlp) == NoMoreSlp; }
222 int is_main_no_pre_loop() const { return _loop_flags & MainHasNoPreLoop; }
223 void set_main_no_pre_loop() { _loop_flags |= MainHasNoPreLoop; }
224
225 int main_idx() const { return _main_idx; }
226
227
228 void set_pre_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Pre ; _main_idx = main->_idx; }
229 void set_main_loop ( ) { assert(is_normal_loop(),""); _loop_flags |= Main; }
230 void set_post_loop (CountedLoopNode *main) { assert(is_normal_loop(),""); _loop_flags |= Post; _main_idx = main->_idx; }
231 void set_normal_loop( ) { _loop_flags &= ~PreMainPostFlagsMask; }
232
233 void set_trip_count(uint tc) { _trip_count = tc; }
234 uint trip_count() { return _trip_count; }
235
236 bool has_exact_trip_count() const { return (_loop_flags & HasExactTripCount) != 0; }
237 void set_exact_trip_count(uint tc) {
238 _trip_count = tc;
239 _loop_flags |= HasExactTripCount;
240 }
241 void set_nonexact_trip_count() {
242 _loop_flags &= ~HasExactTripCount;
243 }
244 void set_notpassed_slp() {
245 _loop_flags &= ~PassedSlpAnalysis;
246 }
247
248 void set_profile_trip_cnt(float ptc) { _profile_trip_cnt = ptc; }
249 float profile_trip_cnt() { return _profile_trip_cnt; }
250
251 void double_unrolled_count() { _unrolled_count_log2++; }
252 int unrolled_count() { return 1 << MIN2(_unrolled_count_log2, BitsPerInt-3); }
253
254 void set_node_count_before_unroll(int ct) { _node_count_before_unroll = ct; }
255 int node_count_before_unroll() { return _node_count_before_unroll; }
256 void set_slp_max_unroll(int unroll_factor) { _slp_maximum_unroll_factor = unroll_factor; }
257 int slp_max_unroll() const { return _slp_maximum_unroll_factor; }
258
259 #ifndef PRODUCT
260 virtual void dump_spec(outputStream *st) const;
261 #endif
262 };
263
264 //------------------------------CountedLoopEndNode-----------------------------
265 // CountedLoopEndNodes end simple trip counted loops. They act much like
|