Use dag instead of list for operands to allow named operands.

Named operands allow generating builders with more meaningful names + lay the groundwork for allowing the specification of attributes as part of the inputs pattern of an op (which allows the declarative pattern rewrite generator to define ops with attributs). This is a minimal change that just changes how input operands are represented, changes to attributes in follow up and returnTypes later.

PiperOrigin-RevId: 225509805
This commit is contained in:
Jacques Pienaar 2018-12-14 02:08:55 -08:00 committed by jpienaar
parent 45a0f52519
commit 7a62e35644
2 changed files with 17 additions and 12 deletions

View File

@ -119,6 +119,9 @@ def NoSideEffect : OpProperty; // op has no side effect
// Ops
//===----------------------------------------------------------------------===//
// Marker used to identify the operand list for an op.
def ins;
// Base class for all ops.
class Op<string mnemonic, list<OpProperty> props = []> {
// The mnemonic of the op.
@ -130,8 +133,8 @@ class Op<string mnemonic, list<OpProperty> props = []> {
// Additional, longer human-readable description of what the op does.
string description = ?;
// The list of operands of the op. Default 0 operands.
list<Type> operandTypes = [];
// Dag containting the operands of the op. Default 0 operands.
dag operands = (ins);
// The list of return types of the op. Default no return type set.
list<Type> returnTypes = [];
@ -181,7 +184,8 @@ class Op<string mnemonic, list<OpProperty> props = []> {
// The operand types of an op.
class Operands<list<Type> types> {
list<Type> operandTypes = types;
// TODO(jpienaar): Switch operands to use named operand instead of using list.
dag operands = !dag(ins, types, ?);
}
// The result types of an op.

View File

@ -247,7 +247,7 @@ void OpEmitter::emitBuilder() {
// 1. Stand-alone parameters
std::vector<Record *> returnTypes = def.getValueAsListOfDefs("returnTypes");
std::vector<Record *> operandTypes = def.getValueAsListOfDefs("operandTypes");
DagInit *operands = def.getValueAsDag("operands");
os << " static void build(Builder* builder, OperationState* result";
@ -256,7 +256,7 @@ void OpEmitter::emitBuilder() {
os << ", Type returnType" << i;
// Emit parameters for all operands
for (unsigned i = 0, e = operandTypes.size(); i != e; ++i)
for (unsigned i = 0, e = operands->getNumArgs(); i != e; ++i)
os << ", SSAValue* arg" << i;
// Emit parameters for all attributes
@ -278,9 +278,9 @@ void OpEmitter::emitBuilder() {
}
// Push all operands to the result
if (!operandTypes.empty()) {
if (operands->getNumArgs() != 0) {
os << " result->addOperands({arg0";
for (unsigned i = 1, e = operandTypes.size(); i != e; ++i)
for (unsigned i = 1, e = operands->getNumArgs(); i != e; ++i)
os << ", arg" << i;
os << "});\n";
}
@ -306,7 +306,7 @@ void OpEmitter::emitBuilder() {
<< " result->addTypes(resultTypes);\n";
// Operands
os << " assert(args.size() == " << operandTypes.size()
os << " assert(args.size() == " << operands->getNumArgs()
<< "u && \"mismatched number of parameters\");\n"
<< " result->addOperands(args);\n\n";
@ -385,7 +385,7 @@ void OpEmitter::emitVerifier() {
void OpEmitter::emitTraits() {
std::vector<Record *> returnTypes = def.getValueAsListOfDefs("returnTypes");
std::vector<Record *> operandTypes = def.getValueAsListOfDefs("operandTypes");
auto operands = def.getValueAsDag("operands");
// Add return size trait.
switch (returnTypes.size()) {
@ -417,13 +417,14 @@ void OpEmitter::emitTraits() {
}
}
if ((hasVariadicOperands || hasAtLeastNOperands) && !operandTypes.empty()) {
if ((hasVariadicOperands || hasAtLeastNOperands) &&
operands->getNumArgs() != 0) {
PrintFatalError(def.getLoc(),
"Operands number definition is not consistent.");
}
// Add operand size trait if defined explicitly.
switch (operandTypes.size()) {
switch (operands->getNumArgs()) {
case 0:
if (!hasVariadicOperands && !hasAtLeastNOperands)
os << ", OpTrait::ZeroOperands";
@ -432,7 +433,7 @@ void OpEmitter::emitTraits() {
os << ", OpTrait::OneOperand";
break;
default:
os << ", OpTrait::NOperands<" << operandTypes.size() << ">::Impl";
os << ", OpTrait::NOperands<" << operands->getNumArgs() << ">::Impl";
break;
}