@@ -667,13 +667,51 @@ class VLoopAnalyzer : StackObj {
667667// A vectorization pointer (VPointer) has information about an address for
668668// dependence checking and vector alignment. It's usually bound to a memory
669669// operation in a counted loop for vectorizable analysis.
670+ //
671+ // We parse and represent pointers of the simple form:
672+ //
673+ // pointer = adr + offset + invar + scale * ConvI2L(iv)
674+ //
675+ // Where:
676+ //
677+ // adr: the base address of an array (base = adr)
678+ // OR
679+ // some address to off-heap memory (base = TOP)
680+ //
681+ // offset: a constant offset
682+ // invar: a runtime variable, which is invariant during the loop
683+ // scale: scaling factor
684+ // iv: loop induction variable
685+ //
686+ // But more precisely, we parse the composite-long-int form:
687+ //
688+ // pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_offset + inv_invar + int_scale * iv)
689+ //
690+ // pointer = adr + long_offset + long_invar + long_scale * ConvI2L(int_index)
691+ // int_index = int_offset + int_invar + int_scale * iv
692+ //
693+ // However, for aliasing and adjacency checks (e.g. VPointer::cmp()) we always use the simple form to make
694+ // decisions. Hence, we must make sure to only create a "valid" VPointer if the optimisations based on the
695+ // simple form produce the same result as the compound-long-int form would. Intuitively, this depends on
696+ // if the int_index overflows, but the precise conditions are given in VPointer::is_safe_to_use_as_simple_form().
697+ //
698+ // ConvI2L(int_index) = ConvI2L(int_offset + int_invar + int_scale * iv)
699+ // = Convi2L(int_offset) + ConvI2L(int_invar) + ConvI2L(int_scale) * ConvI2L(iv)
700+ //
701+ // scale = long_scale * ConvI2L(int_scale)
702+ // offset = long_offset + long_scale * ConvI2L(int_offset)
703+ // invar = long_invar + long_scale * ConvI2L(int_invar)
704+ //
705+ // pointer = adr + offset + invar + scale * ConvI2L(iv)
706+ //
670707class VPointer : public ArenaObj {
671708 protected:
672709 const MemNode* _mem; // My memory reference node
673710 const VLoop& _vloop;
674711
675- Node* _base; // null if unsafe nonheap reference
676- Node* _adr; // address pointer
712+ // Components of the simple form:
713+ Node* _base; // Base address of an array OR null if some off-heap memory.
714+ Node* _adr; // Same as _base if an array pointer OR some off-heap memory pointer.
677715 int _scale; // multiplier for iv (in bytes), 0 if no loop iv
678716 int _offset; // constant offset (in bytes)
679717
@@ -684,6 +722,13 @@ class VPointer : public ArenaObj {
684722 Node* _debug_invar_scale; // multiplier for invariant
685723#endif
686724
725+ // The int_index components of the compound-long-int form. Used to decide if it is safe to use the
726+ // simple form rather than the compound-long-int form that was parsed.
727+ bool _has_int_index_after_convI2L;
728+ int _int_index_after_convI2L_offset;
729+ Node* _int_index_after_convI2L_invar;
730+ int _int_index_after_convI2L_scale;
731+
687732 Node_Stack* _nstack; // stack used to record a vpointer trace of variants
688733 bool _analyze_only; // Used in loop unrolling only for vpointer trace
689734 uint _stack_idx; // Used in loop unrolling only for vpointer trace
@@ -723,6 +768,8 @@ class VPointer : public ArenaObj {
723768 VPointer (VPointer* p);
724769 NONCOPYABLE (VPointer);
725770
771+ bool is_safe_to_use_as_simple_form (Node* base, Node* adr) const ;
772+
726773 public:
727774 bool valid () const { return _adr != nullptr ; }
728775 bool has_iv () const { return _scale != 0 ; }
@@ -748,10 +795,43 @@ class VPointer : public ArenaObj {
748795 return _invar == q._invar ;
749796 }
750797
798+ // We compute if and how two VPointers can alias at runtime, i.e. if the two addressed regions of memory can
799+ // ever overlap. There are essentially 3 relevant return states:
800+ // - NotComparable: Synonymous to "unknown aliasing".
801+ // We have no information about how the two VPointers can alias. They could overlap, refer
802+ // to another location in the same memory object, or point to a completely different object.
803+ // -> Memory edge required. Aliasing unlikely but possible.
804+ //
805+ // - Less / Greater: Synonymous to "never aliasing".
806+ // The two VPointers may point into the same memory object, but be non-aliasing (i.e. we
807+ // know both address regions inside the same memory object, but these regions are non-
808+ // overlapping), or the VPointers point to entirely different objects.
809+ // -> No memory edge required. Aliasing impossible.
810+ //
811+ // - Equal: Synonymous to "overlap, or point to different memory objects".
812+ // The two VPointers either overlap on the same memory object, or point to two different
813+ // memory objects.
814+ // -> Memory edge required. Aliasing likely.
815+ //
816+ // In a future refactoring, we can simplify to two states:
817+ // - NeverAlias: instead of Less / Greater
818+ // - MayAlias: instead of Equal / NotComparable
819+ //
820+ // Two VPointer are "comparable" (Less / Greater / Equal), iff all of these conditions apply:
821+ // 1) Both are valid, i.e. expressible in the compound-long-int or simple form.
822+ // 2) The adr are identical, or both are array bases of different arrays.
823+ // 3) They have identical scale.
824+ // 4) They have identical invar.
825+ // 5) The difference in offsets is limited: abs(offset0 - offset1) < 2^31.
751826 int cmp (const VPointer& q) const {
752827 if (valid () && q.valid () &&
753828 (_adr == q._adr || (_base == _adr && q._base == q._adr )) &&
754829 _scale == q._scale && invar_equals (q)) {
830+ jlong difference = abs (java_subtract ((jlong)_offset, (jlong)q._offset ));
831+ jlong max_diff = (jlong)1 << 31 ;
832+ if (difference >= max_diff) {
833+ return NotComparable;
834+ }
755835 bool overlap = q._offset < _offset + memory_size () &&
756836 _offset < q._offset + q.memory_size ();
757837 return overlap ? Equal : (_offset < q._offset ? Less : Greater);
@@ -851,6 +931,12 @@ class VPointer : public ArenaObj {
851931
852932 void maybe_add_to_invar (Node* new_invar, bool negate);
853933
934+ static bool try_AddI_no_overflow (int offset1, int offset2, int & result);
935+ static bool try_SubI_no_overflow (int offset1, int offset2, int & result);
936+ static bool try_AddSubI_no_overflow (int offset1, int offset2, bool is_sub, int & result);
937+ static bool try_LShiftI_no_overflow (int offset1, int offset2, int & result);
938+ static bool try_MulI_no_overflow (int offset1, int offset2, int & result);
939+
854940 Node* register_if_new (Node* n) const ;
855941};
856942
0 commit comments