Integrate upstream cpp emitter changes (#6977)
Takes over upstream changes
* iml130/mlir-emitc@d2ea898
* iml130/mlir-emitc@a55966e
* iml130/mlir-emitc@45c5dc2
* iml130/mlir-emitc@9a97180
* iml130/mlir-emitc@2aef52c
* iml130/mlir-emitc@b401a08
and updates the Cpp emitter usage.
diff --git a/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp b/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
index 4bb731a..dc48c0a 100644
--- a/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
+++ b/iree/compiler/Dialect/VM/Target/C/CModuleTarget.cpp
@@ -381,8 +381,8 @@
Operation *op = funcOp.getOperation();
if (op->hasAttr("emitc.static")) output << "static ";
- if (failed(emitter.emitTypes(*funcOp.getOperation(),
- funcOp.getType().getResults())))
+ if (failed(
+ emitter.emitTypes(funcOp.getLoc(), funcOp.getType().getResults())))
return failure();
output << " " << funcOp.getName();
@@ -391,7 +391,7 @@
bool error = false;
llvm::interleaveComma(
funcOp.getArguments(), output, [&](BlockArgument arg) {
- if (failed(emitter.emitType(*funcOp.getOperation(), arg.getType())))
+ if (failed(emitter.emitType(funcOp.getLoc(), arg.getType())))
error = true;
});
if (error) return failure();
diff --git a/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h b/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
index 579b5e3..eb8c22f 100644
--- a/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
+++ b/third_party/mlir-emitc/include/emitc/Target/Cpp/CppEmitter.h
@@ -63,23 +63,23 @@
explicit CppEmitter(raw_ostream &os, bool declareVariablesAtTop);
/// Emits attribute or returns failure.
- LogicalResult emitAttribute(Operation &op, Attribute attr);
+ LogicalResult emitAttribute(Location loc, Attribute attr);
/// Emits operation 'op' with/without training semicolon or returns failure.
LogicalResult emitOperation(Operation &op, bool trailingSemicolon);
/// Emits type 'type' or returns failure.
- LogicalResult emitType(Operation &op, Type type);
+ LogicalResult emitType(Location loc, Type type);
/// Emits array of types as a std::tuple of the emitted types.
/// - emits void for an empty array;
/// - emits the type of the only element for arrays of size one;
/// - emits a std::tuple otherwise;
- LogicalResult emitTypes(Operation &op, ArrayRef<Type> types);
+ LogicalResult emitTypes(Location loc, ArrayRef<Type> types);
/// Emits array of types as a std::tuple of the emitted types independently of
/// the array size.
- LogicalResult emitTupleType(Operation &op, ArrayRef<Type> types);
+ LogicalResult emitTupleType(Location loc, ArrayRef<Type> types);
/// Emits an assignment for a variable which has been declared previously.
LogicalResult emitVariableAssignment(OpResult result);
@@ -113,8 +113,8 @@
/// Return the existing or a new label of a Block.
StringRef getOrCreateName(Block &block);
- /// Whether to map an mlir integer to a signed integer in C++.
- bool shouldMapToSigned(IntegerType::SignednessSemantics val);
+ /// Whether to map an mlir integer to a unsigned integer in C++.
+ bool shouldMapToUnsigned(IntegerType::SignednessSemantics val);
/// RAII helper function to manage entering/exiting C++ scopes.
struct Scope {
diff --git a/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp b/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
index d79814c..0596d35 100644
--- a/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/third_party/mlir-emitc/lib/Target/Cpp/TranslateToCpp.cpp
@@ -43,7 +43,7 @@
if (failed(emitter.emitVariableAssignment(result)))
return failure();
- return emitter.emitAttribute(*operation, value);
+ return emitter.emitAttribute(operation->getLoc(), value);
}
// Emit a variable declaration for an emitc.constant op without value.
@@ -57,7 +57,7 @@
// Emit a variable declaration.
if (failed(emitter.emitAssignPrefix(*operation)))
return failure();
- return emitter.emitAttribute(*operation, value);
+ return emitter.emitAttribute(operation->getLoc(), value);
}
static LogicalResult printOperation(CppEmitter &emitter,
@@ -90,7 +90,7 @@
os << "goto ";
if (!(emitter.hasBlockLabel(successor)))
- return branchOp.emitOpError() << "Unable to find label for successor block";
+ return branchOp.emitOpError("unable to find label for successor block");
os << emitter.getOrCreateName(successor);
return success();
}
@@ -115,8 +115,7 @@
os << "goto ";
if (!(emitter.hasBlockLabel(trueSuccessor))) {
- return condBranchOp.emitOpError()
- << "Unable to find label for successor block";
+ return condBranchOp.emitOpError("unable to find label for successor block");
}
os << emitter.getOrCreateName(trueSuccessor) << ";\n";
os << "} else {\n";
@@ -132,7 +131,7 @@
os << "goto ";
if (!(emitter.hasBlockLabel(falseSuccessor))) {
return condBranchOp.emitOpError()
- << "Unable to find label for successor block";
+ << "unable to find label for successor block";
}
os << emitter.getOrCreateName(falseSuccessor) << ";\n";
os << "}";
@@ -165,15 +164,15 @@
if (t.getType().isIndex()) {
int64_t idx = t.getInt();
if ((idx < 0) || (idx >= op.getNumOperands()))
- return op.emitOpError() << "invalid operand index";
+ return op.emitOpError("invalid operand index");
if (!emitter.hasValueInScope(op.getOperand(idx)))
- return op.emitOpError()
- << "operand " << idx << "'s value not defined in scope";
+ return op.emitOpError("operand ")
+ << idx << "'s value not defined in scope";
os << emitter.getOrCreateName(op.getOperand(idx));
return success();
}
}
- if (failed(emitter.emitAttribute(op, attr)))
+ if (failed(emitter.emitAttribute(op.getLoc(), attr)))
return failure();
return success();
@@ -240,8 +239,7 @@
}
for (auto pair : llvm::zip(iterArgs, operands)) {
- if (failed(emitter.emitType(*forOp.getOperation(),
- std::get<0>(pair).getType())))
+ if (failed(emitter.emitType(forOp.getLoc(), std::get<0>(pair).getType())))
return failure();
os << " " << emitter.getOrCreateName(std::get<0>(pair)) << " = ";
os << emitter.getOrCreateName(std::get<1>(pair)) << ";";
@@ -249,8 +247,8 @@
}
os << "for (";
- if (failed(emitter.emitType(*forOp.getOperation(),
- forOp.getInductionVar().getType())))
+ if (failed(
+ emitter.emitType(forOp.getLoc(), forOp.getInductionVar().getType())))
return failure();
os << " ";
os << emitter.getOrCreateName(forOp.getInductionVar());
@@ -364,7 +362,7 @@
os << emitter.getOrCreateName(result) << " = ";
if (!emitter.hasValueInScope(operand))
- return yieldOp.emitError() << "operand value not in scope";
+ return yieldOp.emitError("operand value not in scope");
os << emitter.getOrCreateName(operand);
return success();
},
@@ -406,13 +404,13 @@
// We need to declare variables at top if the function has multiple blocks.
if (!emitter.shouldDeclareVariablesAtTop() &&
functionOp.getBlocks().size() > 1) {
- return functionOp.emitOpError()
- << "with multiple blocks needs variables declared at top";
+ return functionOp.emitOpError(
+ "with multiple blocks needs variables declared at top");
}
CppEmitter::Scope scope(emitter);
raw_indented_ostream &os = emitter.ostream();
- if (failed(emitter.emitTypes(*functionOp.getOperation(),
+ if (failed(emitter.emitTypes(functionOp.getLoc(),
functionOp.getType().getResults())))
return failure();
os << " " << functionOp.getName();
@@ -421,8 +419,7 @@
if (failed(interleaveCommaWithError(
functionOp.getArguments(), os,
[&](BlockArgument arg) -> LogicalResult {
- if (failed(emitter.emitType(*functionOp.getOperation(),
- arg.getType())))
+ if (failed(emitter.emitType(functionOp.getLoc(), arg.getType())))
return failure();
os << " " << emitter.getOrCreateName(arg);
return success();
@@ -439,7 +436,7 @@
if (failed(emitter.emitVariableDeclaration(
result, /*trailingSemicolon=*/true))) {
return WalkResult(
- op->emitError("Unable to declare result variable for op"));
+ op->emitError("unable to declare result variable for op"));
}
}
return WalkResult::advance();
@@ -461,7 +458,8 @@
if (emitter.hasValueInScope(arg))
return functionOp.emitOpError(" block argument #")
<< arg.getArgNumber() << " is out of scope";
- if (failed(emitter.emitType(*block.getParentOp(), arg.getType()))) {
+ if (failed(
+ emitter.emitType(block.getParentOp()->getLoc(), arg.getType()))) {
return failure();
}
os << " " << emitter.getOrCreateName(arg) << ";\n";
@@ -475,7 +473,10 @@
return failure();
}
for (Operation &op : block.getOperations()) {
- // Don't print additional semicolons after these operations.
+ // When generating code for an scf.if or std.cond_br op no semicolon needs
+ // to be printed after the closing brace.
+ // When generating code for an scf.for op, printing a trailing semicolon
+ // is handled within the printOperation function.
bool trailingSemicolon = !isa<scf::IfOp, scf::ForOp, CondBranchOp>(op);
if (failed(emitter.emitOperation(
@@ -507,14 +508,14 @@
return *blockMapper.begin(&block);
}
-bool CppEmitter::shouldMapToSigned(IntegerType::SignednessSemantics val) {
+bool CppEmitter::shouldMapToUnsigned(IntegerType::SignednessSemantics val) {
switch (val) {
case IntegerType::Signless:
- return true;
- case IntegerType::Signed:
- return true;
- case IntegerType::Unsigned:
return false;
+ case IntegerType::Signed:
+ return false;
+ case IntegerType::Unsigned:
+ return true;
}
}
@@ -524,7 +525,7 @@
return blockMapper.count(&block);
}
-LogicalResult CppEmitter::emitAttribute(Operation &op, Attribute attr) {
+LogicalResult CppEmitter::emitAttribute(Location loc, Attribute attr) {
auto printInt = [&](APInt val, bool isSigned) {
if (val.getBitWidth() == 1) {
if (val.getBoolValue())
@@ -576,7 +577,7 @@
// Print integer attributes.
if (auto iAttr = attr.dyn_cast<IntegerAttr>()) {
if (auto iType = iAttr.getType().dyn_cast<IntegerType>()) {
- printInt(iAttr.getValue(), shouldMapToSigned(iType.getSignedness()));
+ printInt(iAttr.getValue(), shouldMapToUnsigned(iType.getSignedness()));
return success();
}
if (auto iType = iAttr.getType().dyn_cast<IndexType>()) {
@@ -591,7 +592,7 @@
.dyn_cast<IntegerType>()) {
os << '{';
interleaveComma(dense, os, [&](APInt val) {
- printInt(val, shouldMapToSigned(iType.getSignedness()));
+ printInt(val, shouldMapToUnsigned(iType.getSignedness()));
});
os << '}';
return success();
@@ -616,16 +617,16 @@
// Print symbolic reference attributes.
if (auto sAttr = attr.dyn_cast<SymbolRefAttr>()) {
if (sAttr.getNestedReferences().size() > 1)
- return op.emitError(" attribute has more than 1 nested reference");
- os << sAttr.getRootReference();
+ return emitError(loc, "attribute has more than 1 nested reference");
+ os << sAttr.getRootReference().getValue();
return success();
}
// Print type attributes.
if (auto type = attr.dyn_cast<TypeAttr>())
- return emitType(op, type.getValue());
+ return emitType(loc, type.getValue());
- return op.emitError("cannot emit attribute of type ") << attr.getType();
+ return emitError(loc, "cannot emit attribute of type ") << attr.getType();
}
LogicalResult CppEmitter::emitOperands(Operation &op) {
@@ -657,7 +658,7 @@
if (llvm::is_contained(exclude, attr.first.strref()))
return success();
os << "/* " << attr.first << " */";
- if (failed(emitAttribute(op, attr.second)))
+ if (failed(emitAttribute(op.getLoc(), attr.second)))
return failure();
return success();
};
@@ -667,7 +668,7 @@
LogicalResult CppEmitter::emitVariableAssignment(OpResult result) {
if (!hasValueInScope(result)) {
return result.getDefiningOp()->emitOpError(
- "result variable for the operation has not been declared.");
+ "result variable for the operation has not been declared");
}
os << getOrCreateName(result) << " = ";
return success();
@@ -677,9 +678,9 @@
bool trailingSemicolon) {
if (hasValueInScope(result)) {
return result.getDefiningOp()->emitError(
- "result variable for the operation already declared.");
+ "result variable for the operation already declared");
}
- if (failed(emitType(*result.getOwner(), result.getType())))
+ if (failed(emitType(result.getOwner()->getLoc(), result.getType())))
return failure();
os << " " << getOrCreateName(result);
if (trailingSemicolon)
@@ -720,7 +721,7 @@
LogicalResult CppEmitter::emitLabel(Block &block) {
if (!hasBlockLabel(block))
- return block.getParentOp()->emitError("Label for block not found.");
+ return block.getParentOp()->emitError("label for block not found");
os << getOrCreateName(block) << ":\n";
return success();
}
@@ -740,7 +741,7 @@
ModuleOp, ReturnOp>(
[&](auto op) { return printOperation(*this, op); })
.Default([&](Operation *) {
- return op.emitOpError() << "unable to find printer for op";
+ return op.emitOpError("unable to find printer for op");
});
if (failed(status))
@@ -749,7 +750,7 @@
return success();
}
-LogicalResult CppEmitter::emitType(Operation &op, Type type) {
+LogicalResult CppEmitter::emitType(Location loc, Type type) {
if (auto iType = type.dyn_cast<IntegerType>()) {
switch (iType.getWidth()) {
case 1:
@@ -758,12 +759,12 @@
case 16:
case 32:
case 64:
- if (shouldMapToSigned(iType.getSignedness()))
- return (os << "int" << iType.getWidth() << "_t"), success();
- else
+ if (shouldMapToUnsigned(iType.getSignedness()))
return (os << "uint" << iType.getWidth() << "_t"), success();
+ else
+ return (os << "int" << iType.getWidth() << "_t"), success();
default:
- return op.emitError("cannot emit integer type ") << type;
+ return emitError(loc, "cannot emit integer type ") << type;
}
}
if (auto fType = type.dyn_cast<FloatType>()) {
@@ -773,18 +774,18 @@
case 64:
return (os << "double"), success();
default:
- return op.emitError("cannot emit float type ") << type;
+ return emitError(loc, "cannot emit float type ") << type;
}
}
if (auto iType = type.dyn_cast<IndexType>())
return (os << "size_t"), success();
if (auto tType = type.dyn_cast<TensorType>()) {
if (!tType.hasRank())
- return op.emitError("cannot emit unranked tensor type");
+ return emitError(loc, "cannot emit unranked tensor type");
if (!tType.hasStaticShape())
- return op.emitError("cannot emit tensor type with non static shape");
+ return emitError(loc, "cannot emit tensor type with non static shape");
os << "Tensor<";
- if (failed(emitType(op, tType.getElementType())))
+ if (failed(emitType(loc, tType.getElementType())))
return failure();
auto shape = tType.getShape();
for (auto dimSize : shape) {
@@ -795,30 +796,30 @@
return success();
}
if (auto tType = type.dyn_cast<TupleType>())
- return emitTupleType(op, tType.getTypes());
+ return emitTupleType(loc, tType.getTypes());
if (auto oType = type.dyn_cast<emitc::OpaqueType>()) {
os << oType.getValue();
return success();
}
- return op.emitError("cannot emit type ") << type;
+ return emitError(loc, "cannot emit type ") << type;
}
-LogicalResult CppEmitter::emitTypes(Operation &op, ArrayRef<Type> types) {
+LogicalResult CppEmitter::emitTypes(Location loc, ArrayRef<Type> types) {
switch (types.size()) {
case 0:
os << "void";
return success();
case 1:
- return emitType(op, types.front());
+ return emitType(loc, types.front());
default:
- return emitTupleType(op, types);
+ return emitTupleType(loc, types);
}
}
-LogicalResult CppEmitter::emitTupleType(Operation &op, ArrayRef<Type> types) {
+LogicalResult CppEmitter::emitTupleType(Location loc, ArrayRef<Type> types) {
os << "std::tuple<";
if (failed(interleaveCommaWithError(
- types, os, [&](Type type) { return emitType(op, type); })))
+ types, os, [&](Type type) { return emitType(loc, type); })))
return failure();
os << ">";
return success();