@@ -426,6 +426,10 @@ class FlatAffineConstraints {
426
426
// / O(VC) time.
427
427
void removeRedundantConstraints ();
428
428
429
+ // / Converts identifiers in the column range [idStart, idLimit) to local
430
+ // / variables.
431
+ void convertDimToLocal (unsigned dimStart, unsigned dimLimit);
432
+
429
433
// / Merge local ids of `this` and `other`. This is done by appending local ids
430
434
// / of `other` to `this` and inserting local ids of `this` to `other` at start
431
435
// / of its local ids.
@@ -581,6 +585,16 @@ class FlatAffineValueConstraints : public FlatAffineConstraints {
581
585
numLocals + 1 ,
582
586
numDims, numSymbols, numLocals, valArgs) {}
583
587
588
+ FlatAffineValueConstraints (const FlatAffineConstraints &fac,
589
+ ArrayRef<Optional<Value>> valArgs = {})
590
+ : FlatAffineConstraints(fac) {
591
+ assert (valArgs.empty () || valArgs.size () == numIds);
592
+ if (valArgs.empty ())
593
+ values.resize (numIds, None);
594
+ else
595
+ values.append (valArgs.begin (), valArgs.end ());
596
+ }
597
+
584
598
// / Create a flat affine constraint system from an AffineValueMap or a list of
585
599
// / these. The constructed system will only include equalities.
586
600
explicit FlatAffineValueConstraints (const AffineValueMap &avm);
@@ -721,7 +735,8 @@ class FlatAffineValueConstraints : public FlatAffineConstraints {
721
735
using FlatAffineConstraints::insertDimId;
722
736
unsigned insertSymbolId (unsigned pos, ValueRange vals);
723
737
using FlatAffineConstraints::insertSymbolId;
724
- unsigned insertId (IdKind kind, unsigned pos, unsigned num = 1 ) override ;
738
+ virtual unsigned insertId (IdKind kind, unsigned pos,
739
+ unsigned num = 1 ) override ;
725
740
unsigned insertId (IdKind kind, unsigned pos, ValueRange vals);
726
741
727
742
// / Append identifiers of the specified kind after the last identifier of that
@@ -882,7 +897,7 @@ class FlatAffineValueConstraints : public FlatAffineConstraints {
882
897
// / Removes identifiers in the column range [idStart, idLimit), and copies any
883
898
// / remaining valid data into place, updates member variables, and resizes
884
899
// / arrays as needed.
885
- void removeIdRange (unsigned idStart, unsigned idLimit) override ;
900
+ virtual void removeIdRange (unsigned idStart, unsigned idLimit) override ;
886
901
887
902
// / Eliminates the identifier at the specified position using Fourier-Motzkin
888
903
// / variable elimination, but uses Gaussian elimination if there is an
@@ -901,6 +916,83 @@ class FlatAffineValueConstraints : public FlatAffineConstraints {
901
916
SmallVector<Optional<Value>, 8 > values;
902
917
};
903
918
919
+ // / A FlatAffineRelation represents a set of ordered pairs (domain -> range)
920
+ // / where "domain" and "range" are tuples of identifiers. The relation is
921
+ // / represented as a FlatAffineValueConstraints with separation of dimension
922
+ // / identifiers into domain and range. The identifiers are stored as:
923
+ // / [domainIds, rangeIds, symbolIds, localIds, constant].
924
+ class FlatAffineRelation : public FlatAffineValueConstraints {
925
+ public:
926
+ FlatAffineRelation (unsigned numReservedInequalities,
927
+ unsigned numReservedEqualities, unsigned numReservedCols,
928
+ unsigned numDomainDims, unsigned numRangeDims,
929
+ unsigned numSymbols, unsigned numLocals,
930
+ ArrayRef<Optional<Value>> valArgs = {})
931
+ : FlatAffineValueConstraints(
932
+ numReservedInequalities, numReservedEqualities, numReservedCols,
933
+ numDomainDims + numRangeDims, numSymbols, numLocals, valArgs),
934
+ numDomainDims (numDomainDims), numRangeDims(numRangeDims) {}
935
+
936
+ FlatAffineRelation (unsigned numDomainDims = 0 , unsigned numRangeDims = 0 ,
937
+ unsigned numSymbols = 0 , unsigned numLocals = 0 )
938
+ : FlatAffineValueConstraints(numDomainDims + numRangeDims, numSymbols,
939
+ numLocals),
940
+ numDomainDims(numDomainDims), numRangeDims(numRangeDims) {}
941
+
942
+ FlatAffineRelation (unsigned numDomainDims, unsigned numRangeDims,
943
+ FlatAffineValueConstraints &fac)
944
+ : FlatAffineValueConstraints(fac), numDomainDims(numDomainDims),
945
+ numRangeDims(numRangeDims) {}
946
+
947
+ FlatAffineRelation (unsigned numDomainDims, unsigned numRangeDims,
948
+ FlatAffineConstraints &fac)
949
+ : FlatAffineValueConstraints(fac), numDomainDims(numDomainDims),
950
+ numRangeDims(numRangeDims) {}
951
+
952
+ // / Returns a set corresponding to the domain/range of the affine relation.
953
+ FlatAffineValueConstraints getDomainSet () const ;
954
+ FlatAffineValueConstraints getRangeSet () const ;
955
+
956
+ // / Returns the number of identifiers corresponding to domain/range of
957
+ // / relation.
958
+ inline unsigned getNumDomainDims () const { return numDomainDims; }
959
+ inline unsigned getNumRangeDims () const { return numRangeDims; }
960
+
961
+ // / Given affine relation `other: (domainOther -> rangeOther)`, this operation
962
+ // / takes the composition of `other` on `this: (domainThis -> rangeThis)`.
963
+ // / The resulting relation represents tuples of the form: `domainOther ->
964
+ // / rangeThis`.
965
+ void compose (const FlatAffineRelation &other);
966
+
967
+ // / Swap domain and range of the relation.
968
+ // / `(domain -> range)` is converted to `(range -> domain)`.
969
+ void inverse ();
970
+
971
+ // / Insert `num` identifiers of the specified kind after the `pos` identifier
972
+ // / of that kind. The coefficient columns corresponding to the added
973
+ // / identifiers are initialized to zero.
974
+ void insertDomainId (unsigned pos, unsigned num = 1 );
975
+ void insertRangeId (unsigned pos, unsigned num = 1 );
976
+
977
+ // / Append `num` identifiers of the specified kind after the last identifier
978
+ // / of that kind. The coefficient columns corresponding to the added
979
+ // / identifiers are initialized to zero.
980
+ void appendDomainId (unsigned num = 1 );
981
+ void appendRangeId (unsigned num = 1 );
982
+
983
+ protected:
984
+ // Number of dimension identifers corresponding to domain identifers.
985
+ unsigned numDomainDims;
986
+
987
+ // Number of dimension identifers corresponding to range identifers.
988
+ unsigned numRangeDims;
989
+
990
+ // / Removes identifiers in the column range [idStart, idLimit), and copies any
991
+ // / remaining valid data into place, updates member variables, and resizes
992
+ // / arrays as needed.
993
+ void removeIdRange (unsigned idStart, unsigned idLimit) override ;
994
+ };
995
+
904
996
// / Flattens 'expr' into 'flattenedExpr', which contains the coefficients of the
905
997
// / dimensions, symbols, and additional variables that represent floor divisions
906
998
// / of dimensions, symbols, and in turn other floor divisions. Returns failure
@@ -957,6 +1049,26 @@ AffineMap alignAffineMapWithValues(AffineMap map, ValueRange operands,
957
1049
ValueRange dims, ValueRange syms,
958
1050
SmallVector<Value> *newSyms = nullptr );
959
1051
1052
+ // / Builds a relation from the given AffineMap/AffineValueMap `map`, containing
1053
+ // / all pairs of the form `operands -> result` that satisfy `map`. `rel` is set
1054
+ // / to the relation built. For example, give the AffineMap:
1055
+ // /
1056
+ // / (d0, d1)[s0] -> (d0 + s0, d0 - s0)
1057
+ // /
1058
+ // / the resulting relation formed is:
1059
+ // /
1060
+ // / (d0, d1) -> (r1, r2)
1061
+ // / [d0 d1 r1 r2 s0 const]
1062
+ // / 1 0 -1 0 1 0 = 0
1063
+ // / 0 1 0 -1 -1 0 = 0
1064
+ // /
1065
+ // / For AffineValueMap, the domain and symbols have Value set corresponding to
1066
+ // / the Value in `map`. Returns failure if the AffineMap could not be flattened
1067
+ // / (i.e., semi-affine is not yet handled).
1068
+ LogicalResult getRelationFromMap (AffineMap &map, FlatAffineRelation &rel);
1069
+ LogicalResult getRelationFromMap (const AffineValueMap &map,
1070
+ FlatAffineRelation &rel);
1071
+
960
1072
} // end namespace mlir.
961
1073
962
1074
#endif // MLIR_ANALYSIS_AFFINESTRUCTURES_H
0 commit comments