Adding region to an op

Hi Folks:

How does one add a region with content to an Op using state once op has been constructed?

My problem is, I need to build an op that has a region with blocks in it. ODS is like this -

def MyOp : MyDialect<"myOp"> {
  let arguments = (ins I32Attr:$count);
  let regions = (region SizedRegion<1>:$body);
  let assemblyFormat = [{
    $count `times` $body attr-dict
  }];
}

I am able to construct the op using

auto op = builder.create<mlir::MyDialect::MyOp>(location, llvm::None, (unsigned)count);

This uses the following auto-generated .inc below:

void MyOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, uint32_t count) {
  odsState.addAttribute(countAttrName(odsState.name), odsBuilder.getIntegerAttr(odsBuilder.getIntegerType(32), count));
  (void)odsState.addRegion();
}

However, as you see above it has added an empty region. My question is : how do I add my own constructed region to the op ? None of the auto-generated builders give the ‘region’ as parameter.

Thanks in advance.

OK, I was able to figure out myself. Probably it is documented somewhere but i couldn’t find it.

The builder one writes in ODS e.g.

let builders =  [
    OpBuilder<(ins "uint32_t":$count, "::mlir::Block *":$block),
     [{ 
        $_state.addAttribute("count",$_builder.getI32IntegerAttr(count));
        auto *region = $_state.addRegion();
        region->push_back(block);
     }] >];

…will get included in .cpp.inc BUT as

void MyOp::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, uint32_t count, ::mlir::Block *block) {
   odsState.addAttribute("count",odsBuilder.getI32IntegerAttr(count));
   auto *region = odsState.addRegion();
   region->push_back(block);
}

and then this builder can be invoked by user as

builder.create<mlir::MyDialect::MyOp>(location, count, block);