Avoid redundant predicate checking in type matching.

Expand type matcher template generator to consider a set of predicates that are known to
hold. This avoids inserting redundant checking for trivially true predicates
(for example predicate that hold according to the op definition). This only targets predicates that trivially holds and does not attempt any logic equivalence proof.

PiperOrigin-RevId: 228880468
This commit is contained in:
Jacques Pienaar 2019-01-11 07:41:12 -08:00 committed by jpienaar
parent ac5a50e1e4
commit 4c0faef943
4 changed files with 23 additions and 5 deletions

View File

@ -60,7 +60,7 @@ public:
// Returns the template string to construct the matcher corresponding to this
// predicate CNF. The string uses '{0}' to represent the type.
std::string createTypeMatcherTemplate() const;
std::string createTypeMatcherTemplate(PredCNF predsKnownToHold) const;
private:
// The TableGen definition of this predicate CNF. nullptr means an empty

View File

@ -163,5 +163,6 @@ bool tblgen::Operator::Operand::hasMatcher() const {
}
std::string tblgen::Operator::Operand::createTypeMatcherTemplate() const {
return tblgen::Type(defInit).getPredicate().createTypeMatcherTemplate();
return tblgen::Type(defInit).getPredicate().createTypeMatcherTemplate(
PredCNF());
}

View File

@ -20,6 +20,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/TableGen/Predicate.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/TableGen/Error.h"
@ -42,15 +43,29 @@ const llvm::ListInit *tblgen::PredCNF::getConditions() const {
return def->getValueAsListInit("conditions");
}
std::string tblgen::PredCNF::createTypeMatcherTemplate() const {
std::string
tblgen::PredCNF::createTypeMatcherTemplate(PredCNF predsKnownToHold) const {
const auto *conjunctiveList = getConditions();
if (!conjunctiveList)
return "true";
// Create a set of all the disjunctive conditions that hold. This is taking
// advantage of uniquieing of lists to discard based on the pointer
// below. This is not perfect but this will also be moved to FSM matching in
// future and gets rid of trivial redundant checking.
llvm::SmallSetVector<const llvm::Init *, 4> existingConditions;
auto existingList = predsKnownToHold.getConditions();
if (existingList) {
for (auto disjunctiveInit : *existingList)
existingConditions.insert(disjunctiveInit);
}
std::string outString;
llvm::raw_string_ostream ss(outString);
bool firstDisjunctive = true;
for (auto disjunctiveInit : *conjunctiveList) {
if (existingConditions.count(disjunctiveInit) != 0)
continue;
ss << (firstDisjunctive ? "(" : " && (");
firstDisjunctive = false;
bool firstConjunctive = true;
@ -63,6 +78,8 @@ std::string tblgen::PredCNF::createTypeMatcherTemplate() const {
}
ss << ")";
}
if (firstDisjunctive)
return "true";
ss.flush();
return outString;
}

View File

@ -175,10 +175,10 @@ static void matchOp(Record *pattern, DagInit *tree, int depth,
"type argument required for operand");
auto pred = tblgen::Type(defInit).getPredicate();
auto opPred = tblgen::Type(operand->defInit).getPredicate();
os.indent(indent)
<< "if (!("
<< formatv(pred.createTypeMatcherTemplate().c_str(),
<< formatv(pred.createTypeMatcherTemplate(opPred).c_str(),
formatv("op{0}->getOperand({1})->getType()", depth, i))
<< ")) return matchFailure();\n";
}