99#ifndef LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
1010#define LLVM_ANALYSIS_CONSTRAINTSYSTEM_H
1111
12- #include " llvm/ADT/APInt.h"
13- #include " llvm/ADT/ArrayRef.h"
1412#include " llvm/ADT/DenseMap.h"
15- #include " llvm/ADT/SmallVector .h"
13+ #include " llvm/ADT/Matrix .h"
1614#include " llvm/Support/MathExtras.h"
1715
18- #include < string>
19-
2016namespace llvm {
2117
2218class Value ;
2319class ConstraintSystem {
2420 struct Entry {
25- int64_t Coefficient;
26- uint16_t Id;
21+ int64_t Coefficient = 0 ;
22+ uint16_t Id = 0 ;
2723
24+ Entry () = default ;
2825 Entry (int64_t Coefficient, uint16_t Id)
2926 : Coefficient(Coefficient), Id(Id) {}
3027 };
@@ -48,7 +45,10 @@ class ConstraintSystem {
4845 // / Current linear constraints in the system.
4946 // / An entry of the form c0, c1, ... cn represents the following constraint:
5047 // / c0 >= v0 * c1 + .... + v{n-1} * cn
51- SmallVector<SmallVector<Entry, 8 >, 4 > Constraints;
48+ MatrixStorage<Entry, 64 > Constraints;
49+
50+ // / Constraints is only ever manipulated via this View.
51+ JaggedArrayView<Entry, 16 , 64 > View;
5252
5353 // / A map of variables (IR values) to their corresponding index in the
5454 // / constraint system.
@@ -64,18 +64,40 @@ class ConstraintSystem {
6464 SmallVector<std::string> getVarNamesList () const ;
6565
6666public:
67- ConstraintSystem () {}
68- ConstraintSystem (ArrayRef<Value *> FunctionArgs) {
67+ // The Matrix Constraints should always be initialized with an upper-bound
68+ // number of columns. The default constructor hard-codes an upper-bound of 6,
69+ // as it is only used in unit tests, and not in the actual
70+ // ConstraintElimination Analysis.
71+ ConstraintSystem () : Constraints(6 ), View(Constraints) {}
72+
73+ // This constructor is used by ConstraintElimination, inside ConstraintInfo.
74+ // Unfortunately, due to calls to addFact, that adds local variables, it is
75+ // impossible to know how many local variables there are in advance.
76+ // ConstraintElimination has a fixed upper-bound on the number of columns,
77+ // configurable as a cl::opt, so use that number, and don't add the constraint
78+ // if it exceeds that number.
79+ ConstraintSystem (ArrayRef<Value *> FunctionArgs, size_t NCols)
80+ : Constraints(NCols), View(Constraints) {
6981 NumVariables += FunctionArgs.size ();
7082 for (auto *Arg : FunctionArgs) {
7183 Value2Index.insert ({Arg, Value2Index.size () + 1 });
7284 }
7385 }
74- ConstraintSystem (const DenseMap<Value *, unsigned > &Value2Index)
75- : NumVariables(Value2Index.size()), Value2Index(Value2Index) {}
86+
87+ // This constructor is only used by the dump function in
88+ // ConstraintElimination.
89+ ConstraintSystem (const DenseMap<Value *, unsigned > &Value2Index,
90+ unsigned NVars)
91+ : NumVariables(Value2Index.size()),
92+ Constraints (std::max(Value2Index.size(), NVars)), View(Constraints),
93+ Value2Index(Value2Index) {}
94+
95+ ConstraintSystem (const ConstraintSystem &Other)
96+ : NumVariables(Other.NumVariables), Constraints(Other.Constraints),
97+ View(Other.View, Constraints), Value2Index(Other.Value2Index) {}
7698
7799 bool addVariableRow (ArrayRef<int64_t > R) {
78- assert (Constraints .empty () || R.size () == NumVariables);
100+ assert (View .empty () || R.size () == NumVariables);
79101 // If all variable coefficients are 0, the constraint does not provide any
80102 // usable information.
81103 if (all_of (ArrayRef (R).drop_front (1 ), [](int64_t C) { return C == 0 ; }))
@@ -87,9 +109,10 @@ class ConstraintSystem {
87109 continue ;
88110 NewRow.emplace_back (C, Idx);
89111 }
90- if (Constraints .empty ())
112+ if (View .empty ())
91113 NumVariables = R.size ();
92- Constraints.push_back (std::move (NewRow));
114+
115+ View.addRow (std::move (NewRow));
93116 return true ;
94117 }
95118
@@ -104,6 +127,11 @@ class ConstraintSystem {
104127 if (all_of (ArrayRef (R).drop_front (1 ), [](int64_t C) { return C == 0 ; }))
105128 return false ;
106129
130+ // There is no correctness issue if we don't add a constraint, for whatever
131+ // reason.
132+ if (R.size () > Constraints.getNumCols ())
133+ return false ;
134+
107135 NumVariables = std::max (R.size (), NumVariables);
108136 return addVariableRow (R);
109137 }
@@ -145,21 +173,21 @@ class ConstraintSystem {
145173 bool isConditionImplied (SmallVector<int64_t , 8 > R) const ;
146174
147175 SmallVector<int64_t > getLastConstraint () const {
148- assert (!Constraints .empty () && " Constraint system is empty" );
176+ assert (!View .empty () && " Constraint system is empty" );
149177 SmallVector<int64_t > Result (NumVariables, 0 );
150- for (auto &Entry : Constraints. back ())
178+ for (auto &Entry : View. lastRow ())
151179 Result[Entry.Id ] = Entry.Coefficient ;
152180 return Result;
153181 }
154182
155- void popLastConstraint () { Constraints. pop_back (); }
183+ void popLastConstraint () { View. dropLastRow (); }
156184 void popLastNVariables (unsigned N) {
157185 assert (NumVariables > N);
158186 NumVariables -= N;
159187 }
160188
161189 // / Returns the number of rows in the constraint system.
162- unsigned size () const { return Constraints. size (); }
190+ unsigned size () const { return View. getRowSpan (); }
163191
164192 // / Print the constraints in the system.
165193 void dump () const ;
0 commit comments