1 //===- Predicate.cpp - Predicate class ------------------------------------===//
2 //
3 // Copyright 2019 The MLIR Authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // =============================================================================
17 //
18 // Wrapper around predicates defined in TableGen.
19 //
20 //===----------------------------------------------------------------------===//
21 
22 #include "mlir/TableGen/Predicate.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/Support/FormatVariadic.h"
25 #include "llvm/TableGen/Error.h"
26 #include "llvm/TableGen/Record.h"
27 
28 using namespace mlir;
29 
30 tblgen::PredCNF::PredCNF(const llvm::Init *init) : def(nullptr) {
31   if (const auto *defInit = dyn_cast<llvm::DefInit>(init)) {
32     def = defInit->getDef();
33     assert(def->isSubClassOf("PredCNF") &&
34            "must be subclass of TableGen 'PredCNF' class");
35   }
36 }
37 
38 const llvm::ListInit *tblgen::PredCNF::getConditions() const {
39   if (!def)
40     return nullptr;
41 
42   return def->getValueAsListInit("conditions");
43 }
44 
45 std::string tblgen::PredCNF::createTypeMatcherTemplate() const {
46   const auto *conjunctiveList = getConditions();
47   if (!conjunctiveList)
48     return "true";
49 
50   std::string outString;
51   llvm::raw_string_ostream ss(outString);
52   bool firstDisjunctive = true;
53   for (auto disjunctiveInit : *conjunctiveList) {
54     ss << (firstDisjunctive ? "(" : " && (");
55     firstDisjunctive = false;
56     bool firstConjunctive = true;
57     for (auto atom : *cast<llvm::ListInit>(disjunctiveInit)) {
58       auto predAtom = cast<llvm::DefInit>(atom)->getDef();
59       ss << (firstConjunctive ? "" : " || ")
60          << (predAtom->getValueAsBit("negated") ? "!" : "")
61          << predAtom->getValueAsString("predCall");
62       firstConjunctive = false;
63     }
64     ss << ")";
65   }
66   ss.flush();
67   return outString;
68 }
69