[Mlir-commits] [mlir] [llvm] [mlir][EmitC] Add func, call and return operations and conversions (PR #79612)
Marius Brehler
llvmlistbot at llvm.org
Wed Jan 31 05:40:22 PST 2024
================
@@ -346,6 +349,185 @@ LogicalResult ForOp::verifyRegions() {
return success();
}
+//===----------------------------------------------------------------------===//
+// CallOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult CallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
+ // Check that the callee attribute was specified.
+ auto fnAttr = (*this)->getAttrOfType<FlatSymbolRefAttr>("callee");
+ if (!fnAttr)
+ return emitOpError("requires a 'callee' symbol reference attribute");
+ FuncOp fn = symbolTable.lookupNearestSymbolFrom<FuncOp>(*this, fnAttr);
+ if (!fn)
+ return emitOpError() << "'" << fnAttr.getValue()
+ << "' does not reference a valid function";
+
+ // Verify that the operand and result types match the callee.
+ auto fnType = fn.getFunctionType();
+ if (fnType.getNumInputs() != getNumOperands())
+ return emitOpError("incorrect number of operands for callee");
+
+ for (unsigned i = 0, e = fnType.getNumInputs(); i != e; ++i)
+ if (getOperand(i).getType() != fnType.getInput(i))
+ return emitOpError("operand type mismatch: expected operand type ")
+ << fnType.getInput(i) << ", but provided "
+ << getOperand(i).getType() << " for operand number " << i;
+
+ if (fnType.getNumResults() != getNumResults())
+ return emitOpError("incorrect number of results for callee");
+
+ for (unsigned i = 0, e = fnType.getNumResults(); i != e; ++i)
+ if (getResult(i).getType() != fnType.getResult(i)) {
+ auto diag = emitOpError("result type mismatch at index ") << i;
+ diag.attachNote() << " op result types: " << getResultTypes();
+ diag.attachNote() << "function result types: " << fnType.getResults();
+ return diag;
+ }
+
+ return success();
+}
+
+FunctionType CallOp::getCalleeType() {
+ return FunctionType::get(getContext(), getOperandTypes(), getResultTypes());
+}
+
+//===----------------------------------------------------------------------===//
+// FuncOp
+//===----------------------------------------------------------------------===//
+
+void FuncOp::build(OpBuilder &builder, OperationState &state, StringRef name,
+ FunctionType type, ArrayRef<NamedAttribute> attrs,
+ ArrayRef<DictionaryAttr> argAttrs) {
+ state.addAttribute(SymbolTable::getSymbolAttrName(),
+ builder.getStringAttr(name));
+ state.addAttribute(getFunctionTypeAttrName(state.name), TypeAttr::get(type));
+ state.attributes.append(attrs.begin(), attrs.end());
+ state.addRegion();
+
+ if (argAttrs.empty())
+ return;
+ assert(type.getNumInputs() == argAttrs.size());
+ function_interface_impl::addArgAndResultAttrs(
+ builder, state, argAttrs, /*resultAttrs=*/std::nullopt,
+ getArgAttrsAttrName(state.name), getResAttrsAttrName(state.name));
+}
+
+ParseResult FuncOp::parse(OpAsmParser &parser, OperationState &result) {
+ auto buildFuncType =
+ [](Builder &builder, ArrayRef<Type> argTypes, ArrayRef<Type> results,
+ function_interface_impl::VariadicFlag,
+ std::string &) { return builder.getFunctionType(argTypes, results); };
+
+ return function_interface_impl::parseFunctionOp(
+ parser, result, /*allowVariadic=*/false,
+ getFunctionTypeAttrName(result.name), buildFuncType,
+ getArgAttrsAttrName(result.name), getResAttrsAttrName(result.name));
+}
+
+void FuncOp::print(OpAsmPrinter &p) {
+ function_interface_impl::printFunctionOp(
+ p, *this, /*isVariadic=*/false, getFunctionTypeAttrName(),
+ getArgAttrsAttrName(), getResAttrsAttrName());
+}
+
+/// Clone the internal blocks from this function into dest and all attributes
+/// from this function to dest.
+void FuncOp::cloneInto(FuncOp dest, IRMapping &mapper) {
+ // Add the attributes of this function to dest.
+ llvm::MapVector<StringAttr, Attribute> newAttrMap;
+ for (const auto &attr : dest->getAttrs())
+ newAttrMap.insert({attr.getName(), attr.getValue()});
+ for (const auto &attr : (*this)->getAttrs())
+ newAttrMap.insert({attr.getName(), attr.getValue()});
+
+ auto newAttrs = llvm::to_vector(llvm::map_range(
+ newAttrMap, [](std::pair<StringAttr, Attribute> attrPair) {
+ return NamedAttribute(attrPair.first, attrPair.second);
+ }));
+ dest->setAttrs(DictionaryAttr::get(getContext(), newAttrs));
+
+ // Clone the body.
+ getBody().cloneInto(&dest.getBody(), mapper);
+}
+
+/// Create a deep copy of this function and all of its blocks, remapping
+/// any operands that use values outside of the function using the map that is
+/// provided (leaving them alone if no entry is present). Replaces references
+/// to cloned sub-values with the corresponding value that is copied, and adds
+/// those mappings to the mapper.
+FuncOp FuncOp::clone(IRMapping &mapper) {
----------------
marbre wrote:
Not yet and these *were* indeed copies from the Func dialect. I removed the clone methods for now and we can implement (and test) those if wer later have a use for this functionality.
https://github.com/llvm/llvm-project/pull/79612
More information about the Mlir-commits
mailing list