src/share/vm/opto/loopnode.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/loopnode.hpp Thu Apr 28 15:53:52 2011
--- new/src/share/vm/opto/loopnode.hpp Thu Apr 28 15:53:52 2011
*** 287,296 ****
--- 287,318 ----
inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; }
inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; }
inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : NULL; }
+ //------------------------------LoopLimitNode-----------------------------
+ // Counted Loop limit node which represents exact final iterator value:
+ // trip_count = (limit - init_trip + stride - 1)/stride
+ // final_value= trip_count * stride + init_trip.
+ // Use HW instructions to calculate it when it can overflow in integer.
+ // Note, final_value should fit into integer since counted loop has
+ // limit check: limit <= max_int-stride.
+ class LoopLimitNode : public Node {
+ enum { Normal=0, Init=1, Limit=2, Stride=3 };
+ public:
+ LoopLimitNode( Compile* C, Node *init, Node *limit, Node *stride ) : Node(0,init,limit,stride) {
+ // Put it on the Macro nodes list to optimize during macro nodes expansion.
+ init_flags(Flag_is_macro);
+ C->add_macro_node(this);
+ }
+ virtual int Opcode() const;
+ virtual const Type *bottom_type() const { return TypeInt::INT; }
+ virtual uint ideal_reg() const { return Op_RegI; }
+ virtual const Type *Value( PhaseTransform *phase ) const;
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual Node *Identity( PhaseTransform *phase );
+ };
// -----------------------------IdealLoopTree----------------------------------
class IdealLoopTree : public ResourceObj {
public:
IdealLoopTree *_parent; // Parent in loop tree
*** 773,782 ****
--- 795,806 ----
// Per-Node transform
virtual Node *transform( Node *a_node ) { return 0; }
bool is_counted_loop( Node *x, IdealLoopTree *loop );
+ Node* exact_limit( IdealLoopTree *loop );
+
// Return a post-walked LoopNode
IdealLoopTree *get_loop( Node *n ) const {
// Dead nodes have no loop, so return the top level loop instead
if (!has_node(n)) return _ltree_root;
assert(!has_ctrl(n), "");
*** 835,845 ****
--- 859,868 ----
// Return true if exp is a scaled induction var plus (or minus) constant
bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0);
// Return true if proj is for "proj->[region->..]call_uct"
// Return true if proj is for "proj->[region->..]call_uct"
static bool is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason);
// Return true for "if(test)-> proj -> ...
// |
// V
// other_proj->[region->..]call_uct"
*** 858,881 ****
--- 881,905 ----
Deoptimization::DeoptReason reason,
PhaseIdealLoop* loop_phase,
PhaseIterGVN* igvn);
static Node* clone_loop_predicates(Node* old_entry, Node* new_entry,
bool move_predicates,
+ bool clone_limit_check,
PhaseIdealLoop* loop_phase,
PhaseIterGVN* igvn);
! Node* clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check);
! Node* move_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check);
void eliminate_loop_predicates(Node* entry);
static Node* skip_loop_predicates(Node* entry);
// Find a good location to insert a predicate
static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason);
// Find a predicate
static Node* find_predicate(Node* entry);
// Construct a range check for a predicate if
! BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
int scale, Node* offset,
Node* init, Node* limit, Node* stride,
Node* range, bool upper);
// Implementation of the loop predication to promote checks outside the loop
*** 901,915 ****
--- 925,939 ----
// Find candidate "if" for unswitching
IfNode* find_unswitching_candidate(const IdealLoopTree *loop) const;
// Range Check Elimination uses this function!
// Constrain the main loop iterations so the affine function:
! // low_limit <= scale_con * I + offset < upper_limit
// always holds true. That is, either increase the number of iterations in
// the pre-loop or the post-loop until the condition holds true in the main
// loop. Scale_con, offset and limit are all loop invariant.
! void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit );
// Partially peel loop up through last_peel node.
bool partial_peel( IdealLoopTree *loop, Node_List &old_new );
// Create a scheduled list of nodes control dependent on ctrl set.
src/share/vm/opto/loopnode.hpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File