blob: b079076852909f88ecec631c278ad1d9470a4ecf [file] [log] [blame]
Aart Bikd14c5952015-09-08 15:25:15 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_OPTIMIZING_INDUCTION_VAR_RANGE_H_
18#define ART_COMPILER_OPTIMIZING_INDUCTION_VAR_RANGE_H_
19
20#include "induction_var_analysis.h"
21
22namespace art {
23
24/**
25 * This class implements induction variable based range analysis on expressions within loops.
26 * It takes the results of induction variable analysis in the constructor and provides a public
27 * API to obtain a conservative lower and upper bound value on each instruction in the HIR.
28 *
29 * For example, given a linear induction 2 * i + x where 0 <= i <= 10, range analysis yields lower
30 * bound value x and upper bound value x + 20 for the expression, thus, the range [0, x + 20].
31 */
32class InductionVarRange {
33 public:
34 /*
35 * A value that can be represented as "a * instruction + b" for 32-bit constants, where
36 * Value(INT_MIN) and Value(INT_MAX) denote an unknown lower and upper bound, respectively.
37 * Although range analysis could yield more complex values, the format is sufficiently powerful
38 * to represent useful cases and feeds directly into optimizations like bounds check elimination.
39 */
40 struct Value {
41 Value(HInstruction* i, int32_t a, int32_t b)
42 : instruction(a ? i : nullptr),
43 a_constant(a),
44 b_constant(b) {}
45 explicit Value(int32_t b) : Value(nullptr, 0, b) {}
46 HInstruction* instruction;
47 int32_t a_constant;
48 int32_t b_constant;
49 };
50
51 explicit InductionVarRange(HInductionVarAnalysis* induction);
52
53 /**
54 * Given a context denoted by the first instruction, returns a,
55 * possibly conservative, lower bound on the instruction's value.
56 */
57 Value GetMinInduction(HInstruction* context, HInstruction* instruction);
58
59 /**
60 * Given a context denoted by the first instruction, returns a,
61 * possibly conservative, upper bound on the instruction's value.
62 */
63 Value GetMaxInduction(HInstruction* context, HInstruction* instruction);
64
65 private:
66 //
67 // Private helper methods.
68 //
69
70 HInductionVarAnalysis::InductionInfo* GetTripCount(HLoopInformation* loop,
71 HInstruction* context);
72
73 static Value GetFetch(HInstruction* instruction, int32_t fail_value);
74
75 static Value GetMin(HInductionVarAnalysis::InductionInfo* info,
76 HInductionVarAnalysis::InductionInfo* trip);
77 static Value GetMax(HInductionVarAnalysis::InductionInfo* info,
78 HInductionVarAnalysis::InductionInfo* trip);
79 static Value GetMul(HInductionVarAnalysis::InductionInfo* info1,
80 HInductionVarAnalysis::InductionInfo* info2,
81 HInductionVarAnalysis::InductionInfo* trip, int32_t fail_value);
82 static Value GetDiv(HInductionVarAnalysis::InductionInfo* info1,
83 HInductionVarAnalysis::InductionInfo* info2,
84 HInductionVarAnalysis::InductionInfo* trip, int32_t fail_value);
85
86 static Value AddValue(Value v1, Value v2, int32_t fail_value);
87 static Value SubValue(Value v1, Value v2, int32_t fail_value);
88 static Value MulValue(Value v1, Value v2, int32_t fail_value);
89 static Value DivValue(Value v1, Value v2, int32_t fail_value);
90 static Value MinValue(Value v1, Value v2);
91 static Value MaxValue(Value v1, Value v2);
92
93 /** Results of prior induction variable analysis. */
94 HInductionVarAnalysis *induction_analysis_;
95
96 friend class InductionVarRangeTest;
97
98 DISALLOW_COPY_AND_ASSIGN(InductionVarRange);
99};
100
101} // namespace art
102
103#endif // ART_COMPILER_OPTIMIZING_INDUCTION_VAR_RANGE_H_