| 846 | } |
| 847 | |
| 848 | bool LoopDependenceAnalysis::WeakZeroDestinationSIVTest( |
| 849 | SERecurrentNode* source, SENode* destination, SENode* coefficient, |
| 850 | DistanceEntry* distance_entry) { |
| 851 | PrintDebug("Performing WeakZeroDestinationSIVTest."); |
| 852 | // Build an SENode for distance. |
| 853 | std::pair<SENode*, SENode*> subscript_pair = |
| 854 | std::make_pair(source, destination); |
| 855 | const Loop* subscript_loop = GetLoopForSubscriptPair(subscript_pair); |
| 856 | SENode* source_constant_term = GetConstantTerm(subscript_loop, source); |
| 857 | SENode* delta = scalar_evolution_.SimplifyExpression( |
| 858 | scalar_evolution_.CreateSubtraction(destination, source_constant_term)); |
| 859 | |
| 860 | // Scalar evolution doesn't perform division, so we must fold to constants and |
| 861 | // do it manually. |
| 862 | int64_t distance = 0; |
| 863 | SEConstantNode* delta_constant = delta->AsSEConstantNode(); |
| 864 | SEConstantNode* coefficient_constant = coefficient->AsSEConstantNode(); |
| 865 | if (delta_constant && coefficient_constant) { |
| 866 | PrintDebug( |
| 867 | "WeakZeroDestinationSIVTest folding delta and coefficient to " |
| 868 | "constants."); |
| 869 | int64_t delta_value = delta_constant->FoldToSingleValue(); |
| 870 | int64_t coefficient_value = coefficient_constant->FoldToSingleValue(); |
| 871 | // Check if the distance is not integral. |
| 872 | if (delta_value % coefficient_value != 0) { |
| 873 | PrintDebug( |
| 874 | "WeakZeroDestinationSIVTest proved independence through distance not " |
| 875 | "being an integer."); |
| 876 | distance_entry->dependence_information = |
| 877 | DistanceEntry::DependenceInformation::DIRECTION; |
| 878 | distance_entry->direction = DistanceEntry::Directions::NONE; |
| 879 | return true; |
| 880 | } else { |
| 881 | distance = delta_value / coefficient_value; |
| 882 | PrintDebug( |
| 883 | "WeakZeroDestinationSIVTest calculated distance with the following " |
| 884 | "values\n" |
| 885 | "\tdelta value: " + |
| 886 | ToString(delta_value) + |
| 887 | "\n\tcoefficient value: " + ToString(coefficient_value) + |
| 888 | "\n\tdistance: " + ToString(distance) + "\n"); |
| 889 | } |
| 890 | } else { |
| 891 | PrintDebug( |
| 892 | "WeakZeroDestinationSIVTest was unable to fold delta and coefficient " |
| 893 | "to constants."); |
| 894 | } |
| 895 | |
| 896 | // If we can prove the distance is outside the bounds we prove independence. |
| 897 | SEConstantNode* lower_bound = |
| 898 | GetLowerBound(subscript_loop)->AsSEConstantNode(); |
| 899 | SEConstantNode* upper_bound = |
| 900 | GetUpperBound(subscript_loop)->AsSEConstantNode(); |
| 901 | if (lower_bound && upper_bound) { |
| 902 | PrintDebug("WeakZeroDestinationSIVTest found bounds as SEConstantNodes."); |
| 903 | int64_t lower_bound_value = lower_bound->FoldToSingleValue(); |
| 904 | int64_t upper_bound_value = upper_bound->FoldToSingleValue(); |
| 905 | if (!IsWithinBounds(llabs(distance), lower_bound_value, |
nothing calls this directly
no test coverage detected