750 {
751 Definition* upper_bound =
752 ConstructUpperBound(
check->index()->definition(),
check);
754
756 THR_Print(
"Failed to construct upper bound for %s index\n",
758 }
759 return;
760 }
761
762
763
764
765 if (!Simplify(&upper_bound, nullptr)) {
767 THR_Print(
"Failed to simplify upper bound for %s index\n",
769 }
770 return;
771 }
772 upper_bound = ApplyConstraints(upper_bound,
check);
774
775
776
777
778
779 GrowableArray<Definition*> non_positive_symbols;
780 if (!FindNonPositiveSymbols(&non_positive_symbols, upper_bound)) {
781#ifndef PRODUCT
784 "Failed to generalize %s index to %s"
785 " (can't ensure positivity)\n",
786 check->ToCString(), IndexBoundToCString(upper_bound));
787 }
788#endif
789 return;
790 }
791
792
793
794
795 GrowableArray<ConstraintInstr*> positive_constraints(
796 non_positive_symbols.length());
797 Range* positive_range =
800 for (intptr_t
i = 0;
i < non_positive_symbols.length();
i++) {
801 Definition* symbol = non_positive_symbols[
i];
802 positive_constraints.Add(
803 new ConstraintInstr(
new Value(symbol), positive_range));
804 }
805
806 Definition* lower_bound =
807 ConstructLowerBound(
check->index()->definition(),
check);
808
809
810 lower_bound = ApplyConstraints(lower_bound,
check, &positive_constraints);
812
814
815
816#ifndef PRODUCT
819 "Failed to generalize %s index to %s"
820 " (lower bound is not positive)\n",
821 check->ToCString(), IndexBoundToCString(upper_bound));
822 }
823#endif
824 return;
825 }
826
827#ifndef PRODUCT
829 THR_Print(
"For %s computed index bounds [%s, %s]\n",
check->ToCString(),
830 IndexBoundToCString(lower_bound),
831 IndexBoundToCString(upper_bound));
832 }
833#endif
834
835
836
838
839
841
844 for (intptr_t
i = 0;
i < non_positive_symbols.length();
i++) {
845 CheckArrayBoundInstr* precondition = new CheckArrayBoundInstr(
846 new Value(max_smi),
new Value(non_positive_symbols[
i]),
848 precondition->mark_generalized();
849 precondition = scheduler_.
Emit(precondition,
check);
850 if (precondition == nullptr) {
851 if (FLAG_trace_range_analysis) {
852 THR_Print(
" => failed to insert positivity constraint\n");
853 }
855 return;
856 }
857 }
858
859 CheckArrayBoundInstr* new_check = new CheckArrayBoundInstr(
862 new_check->mark_generalized();
863 if (new_check->IsRedundant()) {
864 if (FLAG_trace_range_analysis) {
865 THR_Print(
" => generalized check is redundant\n");
866 }
868 return;
869 }
870
871 new_check = scheduler_.
Emit(new_check,
check);
872 if (new_check != nullptr) {
873 if (FLAG_trace_range_analysis) {
874 THR_Print(
" => generalized check was hoisted into B%" Pd "\n",
875 new_check->GetBlock()->block_id());
876 }
878 } else {
879 if (FLAG_trace_range_analysis) {
880 THR_Print(
" => generalized check can't be hoisted\n");
881 }
883 }
884 }
static void RemoveGeneralizedCheck(CheckArrayBoundInstr *check)
static CompilerState & Current()
static constexpr intptr_t kNone
ConstantInstr * GetConstant(const Object &object, Representation representation=kTagged)
void AssignRangesRecursively(Definition *defn)
static RangeBoundary MaxConstant(RangeSize size)
static RangeBoundary FromConstant(int64_t val)
static bool IsPositive(Range *range)
T * Emit(T *instruction, Instruction *post_dominator)
static SmiPtr New(intptr_t value)
#define THR_Print(format,...)
constexpr bool FLAG_support_il_printer
static Definition * UnwrapConstraint(Definition *defn)