comparison src/share/vm/opto/loopnode.hpp @ 3345:bad7ecd0b6ed

5091921: Sign flip issues in loop optimizer Summary: Fix integer overflow problem in the code generated by loop optimizer. Reviewed-by: never
author kvn
date Wed, 04 May 2011 13:12:42 -0700
parents 3af54845df98
children 38569792a45a
comparison
equal deleted inserted replaced
3344:0139aac70fb5 3345:bad7ecd0b6ed
287 inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); } 287 inline bool CountedLoopNode::stride_is_con() const { return loopexit() && loopexit()->stride_is_con(); }
288 inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; } 288 inline Node *CountedLoopNode::limit() const { return loopexit() ? loopexit()->limit() : NULL; }
289 inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; } 289 inline Node *CountedLoopNode::incr() const { return loopexit() ? loopexit()->incr() : NULL; }
290 inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : NULL; } 290 inline Node *CountedLoopNode::phi() const { return loopexit() ? loopexit()->phi() : NULL; }
291 291
292 //------------------------------LoopLimitNode-----------------------------
293 // Counted Loop limit node which represents exact final iterator value:
294 // trip_count = (limit - init_trip + stride - 1)/stride
295 // final_value= trip_count * stride + init_trip.
296 // Use HW instructions to calculate it when it can overflow in integer.
297 // Note, final_value should fit into integer since counted loop has
298 // limit check: limit <= max_int-stride.
299 class LoopLimitNode : public Node {
300 enum { Init=1, Limit=2, Stride=3 };
301 public:
302 LoopLimitNode( Compile* C, Node *init, Node *limit, Node *stride ) : Node(0,init,limit,stride) {
303 // Put it on the Macro nodes list to optimize during macro nodes expansion.
304 init_flags(Flag_is_macro);
305 C->add_macro_node(this);
306 }
307 virtual int Opcode() const;
308 virtual const Type *bottom_type() const { return TypeInt::INT; }
309 virtual uint ideal_reg() const { return Op_RegI; }
310 virtual const Type *Value( PhaseTransform *phase ) const;
311 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
312 virtual Node *Identity( PhaseTransform *phase );
313 };
292 314
293 // -----------------------------IdealLoopTree---------------------------------- 315 // -----------------------------IdealLoopTree----------------------------------
294 class IdealLoopTree : public ResourceObj { 316 class IdealLoopTree : public ResourceObj {
295 public: 317 public:
296 IdealLoopTree *_parent; // Parent in loop tree 318 IdealLoopTree *_parent; // Parent in loop tree
772 794
773 // Per-Node transform 795 // Per-Node transform
774 virtual Node *transform( Node *a_node ) { return 0; } 796 virtual Node *transform( Node *a_node ) { return 0; }
775 797
776 bool is_counted_loop( Node *x, IdealLoopTree *loop ); 798 bool is_counted_loop( Node *x, IdealLoopTree *loop );
799
800 Node* exact_limit( IdealLoopTree *loop );
777 801
778 // Return a post-walked LoopNode 802 // Return a post-walked LoopNode
779 IdealLoopTree *get_loop( Node *n ) const { 803 IdealLoopTree *get_loop( Node *n ) const {
780 // Dead nodes have no loop, so return the top level loop instead 804 // Dead nodes have no loop, so return the top level loop instead
781 if (!has_node(n)) return _ltree_root; 805 if (!has_node(n)) return _ltree_root;
835 859
836 // Return true if exp is a scaled induction var plus (or minus) constant 860 // Return true if exp is a scaled induction var plus (or minus) constant
837 bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0); 861 bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0);
838 862
839 // Return true if proj is for "proj->[region->..]call_uct" 863 // Return true if proj is for "proj->[region->..]call_uct"
840 // Return true if proj is for "proj->[region->..]call_uct"
841 static bool is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason); 864 static bool is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason);
842 // Return true for "if(test)-> proj -> ... 865 // Return true for "if(test)-> proj -> ...
843 // | 866 // |
844 // V 867 // V
845 // other_proj->[region->..]call_uct" 868 // other_proj->[region->..]call_uct"
858 Deoptimization::DeoptReason reason, 881 Deoptimization::DeoptReason reason,
859 PhaseIdealLoop* loop_phase, 882 PhaseIdealLoop* loop_phase,
860 PhaseIterGVN* igvn); 883 PhaseIterGVN* igvn);
861 static Node* clone_loop_predicates(Node* old_entry, Node* new_entry, 884 static Node* clone_loop_predicates(Node* old_entry, Node* new_entry,
862 bool move_predicates, 885 bool move_predicates,
886 bool clone_limit_check,
863 PhaseIdealLoop* loop_phase, 887 PhaseIdealLoop* loop_phase,
864 PhaseIterGVN* igvn); 888 PhaseIterGVN* igvn);
865 Node* clone_loop_predicates(Node* old_entry, Node* new_entry); 889 Node* clone_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check);
866 Node* move_loop_predicates(Node* old_entry, Node* new_entry); 890 Node* move_loop_predicates(Node* old_entry, Node* new_entry, bool clone_limit_check);
867 891
868 void eliminate_loop_predicates(Node* entry); 892 void eliminate_loop_predicates(Node* entry);
869 static Node* skip_loop_predicates(Node* entry); 893 static Node* skip_loop_predicates(Node* entry);
870 894
871 // Find a good location to insert a predicate 895 // Find a good location to insert a predicate
872 static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason); 896 static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason);
873 // Find a predicate 897 // Find a predicate
874 static Node* find_predicate(Node* entry); 898 static Node* find_predicate(Node* entry);
875 // Construct a range check for a predicate if 899 // Construct a range check for a predicate if
876 BoolNode* rc_predicate(Node* ctrl, 900 BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
877 int scale, Node* offset, 901 int scale, Node* offset,
878 Node* init, Node* limit, Node* stride, 902 Node* init, Node* limit, Node* stride,
879 Node* range, bool upper); 903 Node* range, bool upper);
880 904
881 // Implementation of the loop predication to promote checks outside the loop 905 // Implementation of the loop predication to promote checks outside the loop
901 // Find candidate "if" for unswitching 925 // Find candidate "if" for unswitching
902 IfNode* find_unswitching_candidate(const IdealLoopTree *loop) const; 926 IfNode* find_unswitching_candidate(const IdealLoopTree *loop) const;
903 927
904 // Range Check Elimination uses this function! 928 // Range Check Elimination uses this function!
905 // Constrain the main loop iterations so the affine function: 929 // Constrain the main loop iterations so the affine function:
906 // scale_con * I + offset < limit 930 // low_limit <= scale_con * I + offset < upper_limit
907 // always holds true. That is, either increase the number of iterations in 931 // always holds true. That is, either increase the number of iterations in
908 // the pre-loop or the post-loop until the condition holds true in the main 932 // the pre-loop or the post-loop until the condition holds true in the main
909 // loop. Scale_con, offset and limit are all loop invariant. 933 // loop. Scale_con, offset and limit are all loop invariant.
910 void add_constraint( int stride_con, int scale_con, Node *offset, Node *limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ); 934 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 );
911 935
912 // Partially peel loop up through last_peel node. 936 // Partially peel loop up through last_peel node.
913 bool partial_peel( IdealLoopTree *loop, Node_List &old_new ); 937 bool partial_peel( IdealLoopTree *loop, Node_List &old_new );
914 938
915 // Create a scheduled list of nodes control dependent on ctrl set. 939 // Create a scheduled list of nodes control dependent on ctrl set.