How to create a FuncOp with parameter list from scratch?

I use the following code snippet to create a module containing a FuncOp with parameter list:

mlir::OpBuilder builder(context); // Line 1
mlir::OwningModuleRef module_ref; // Line 2
module_ref = mlir::ModuleOp::create(mlir::UnknownLoc::get(context)); // Line 3
llvm::SmallVector<mlir::Type, 4> operandTypes; // Line 4
operandTypes.push_back(builder.getF32Type()); // Line 5
mlir::FuncOp myFunc = mlir::FuncOp::create(mlir::UnknownLoc::get(context), /*name=*/"myfunc", /*type=*/builder.getFunctionType(operandTypes, {}), /*attrs=*/{}); // Line 6
module_ref->push_back(myFunc); // Line 7
myFunc.getBody().push_back(new mlir::Block); // Line 8
module_ref->dump(); // Line 9

the expected mlir is:

module {
  func @myfunc(%arg0: f32) {

But, when I run the above snippet, my program core dump at Line 9.
After some debug, I realized that when creating a FuncOp, I should create an operands list corresponding to operandTypes, but I didn’t find such an FuncOp::build API to bind operands to operandTypes.

My question is how to create a FuncOp correctly? Is there any demo code?

1 Like

The problem is likely at line 8. The entry block of the functions body should have arguments corresponding to the function arguments.

For this purpose the FunctionLike trait, which FuncOp implements, actually has a convenience function [1].
Simply replace line 8 with myFunc.addEntryBlock(); That should create the entry block for you and set it up correctly as well.


Great! Problem solved. Thanks!

Another question: the default names of BlockArgument are arg0, arg1 etc. How to change the name of BlockArgument.

The names aren’t meaningful and aren’t retained internally, it’s just a convenience when printing to print entry block ones with arg prefix.