1 | //===- Parser.h - Parser for Presburger library -----------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines functions to parse strings into Presburger library |
10 | // constructs. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef MLIR_UNITTESTS_ANALYSIS_PRESBURGER_PARSER_H |
15 | #define MLIR_UNITTESTS_ANALYSIS_PRESBURGER_PARSER_H |
16 | |
17 | #include "mlir/Analysis/Presburger/IntegerRelation.h" |
18 | #include "mlir/Analysis/Presburger/PWMAFunction.h" |
19 | #include "mlir/Analysis/Presburger/PresburgerRelation.h" |
20 | #include "mlir/AsmParser/AsmParser.h" |
21 | #include "mlir/Dialect/Affine/Analysis/AffineStructures.h" |
22 | #include "mlir/IR/AffineExpr.h" |
23 | #include "mlir/IR/AffineMap.h" |
24 | #include "mlir/IR/IntegerSet.h" |
25 | |
26 | namespace mlir { |
27 | namespace presburger { |
28 | |
29 | /// Parses an IntegerPolyhedron from a StringRef. It is expected that the string |
30 | /// represents a valid IntegerSet. |
31 | inline IntegerPolyhedron parseIntegerPolyhedron(StringRef str) { |
32 | MLIRContext context(MLIRContext::Threading::DISABLED); |
33 | return affine::FlatAffineValueConstraints(parseIntegerSet(str, context: &context)); |
34 | } |
35 | |
36 | /// Parse a list of StringRefs to IntegerRelation and combine them into a |
37 | /// PresburgerSet by using the union operation. It is expected that the strings |
38 | /// are all valid IntegerSet representation and that all of them have compatible |
39 | /// spaces. |
40 | inline PresburgerSet parsePresburgerSet(ArrayRef<StringRef> strs) { |
41 | assert(!strs.empty() && "strs should not be empty" ); |
42 | |
43 | IntegerPolyhedron initPoly = parseIntegerPolyhedron(str: strs[0]); |
44 | PresburgerSet result(initPoly); |
45 | for (unsigned i = 1, e = strs.size(); i < e; ++i) |
46 | result.unionInPlace(disjunct: parseIntegerPolyhedron(str: strs[i])); |
47 | return result; |
48 | } |
49 | |
50 | inline MultiAffineFunction parseMultiAffineFunction(StringRef str) { |
51 | MLIRContext context(MLIRContext::Threading::DISABLED); |
52 | |
53 | // TODO: Add default constructor for MultiAffineFunction. |
54 | MultiAffineFunction multiAff(PresburgerSpace::getRelationSpace(), |
55 | IntMatrix(0, 1)); |
56 | if (getMultiAffineFunctionFromMap(map: parseAffineMap(str, context: &context), multiAff) |
57 | .failed()) |
58 | llvm_unreachable( |
59 | "Failed to parse MultiAffineFunction because of semi-affinity" ); |
60 | return multiAff; |
61 | } |
62 | |
63 | inline PWMAFunction |
64 | parsePWMAF(ArrayRef<std::pair<StringRef, StringRef>> pieces) { |
65 | assert(!pieces.empty() && "At least one piece should be present." ); |
66 | |
67 | MLIRContext context(MLIRContext::Threading::DISABLED); |
68 | |
69 | IntegerPolyhedron initDomain = parseIntegerPolyhedron(str: pieces[0].first); |
70 | MultiAffineFunction initMultiAff = parseMultiAffineFunction(str: pieces[0].second); |
71 | |
72 | PWMAFunction func(PresburgerSpace::getRelationSpace( |
73 | numDomain: initMultiAff.getNumDomainVars(), numRange: initMultiAff.getNumOutputs(), |
74 | numSymbols: initMultiAff.getNumSymbolVars())); |
75 | |
76 | func.addPiece(piece: {.domain: PresburgerSet(initDomain), .output: initMultiAff}); |
77 | for (unsigned i = 1, e = pieces.size(); i < e; ++i) |
78 | func.addPiece(piece: {.domain: PresburgerSet(parseIntegerPolyhedron(str: pieces[i].first)), |
79 | .output: parseMultiAffineFunction(str: pieces[i].second)}); |
80 | return func; |
81 | } |
82 | |
83 | inline IntegerRelation parseRelationFromSet(StringRef set, unsigned numDomain) { |
84 | IntegerRelation rel = parseIntegerPolyhedron(str: set); |
85 | |
86 | rel.convertVarKind(srcKind: VarKind::SetDim, varStart: 0, varLimit: numDomain, dstKind: VarKind::Domain); |
87 | |
88 | return rel; |
89 | } |
90 | |
91 | inline PresburgerRelation |
92 | parsePresburgerRelationFromPresburgerSet(ArrayRef<StringRef> strs, |
93 | unsigned numDomain) { |
94 | assert(!strs.empty() && "strs should not be empty" ); |
95 | |
96 | IntegerRelation rel = parseIntegerPolyhedron(str: strs[0]); |
97 | PresburgerRelation result(rel); |
98 | for (unsigned i = 1, e = strs.size(); i < e; ++i) |
99 | result.unionInPlace(disjunct: parseIntegerPolyhedron(str: strs[i])); |
100 | result.convertVarKind(srcKind: VarKind::SetDim, srcPos: 0, num: numDomain, dstKind: VarKind::Domain, dstPos: 0); |
101 | return result; |
102 | } |
103 | |
104 | } // namespace presburger |
105 | } // namespace mlir |
106 | |
107 | #endif // MLIR_UNITTESTS_ANALYSIS_PRESBURGER_PARSER_H |
108 | |