Skip to content

Commit

Permalink
[FSM]New builders for StateOp and TransitionOp. (#6991)
Browse files Browse the repository at this point in the history
* [FSM]New Builders for StateOp and TransitionOp

1. Create an OutputOp inside a StateOp with the output values instead of an empty OutputOp, which needs to be erased after all.

2. Accept two functions as arguments to create the TransitionOp, which is similar to the creation of sv::IfOp. This would be helpful because one doesn't have to create the blocks and set the insertion point manually, which may cause errors sometime.
  • Loading branch information
HahaLan97 authored Jul 8, 2024
1 parent 792f1fe commit 499d1e9
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 10 deletions.
10 changes: 7 additions & 3 deletions include/circt/Dialect/FSM/FSMOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ def StateOp : FSMOp<"state", [HasParent<"MachineOp">, Symbol, NoTerminator]> {
}];

let builders = [
OpBuilder<(ins "StringRef":$stateName)>
OpBuilder<(ins "StringRef":$stateName)>,
OpBuilder<(ins "StringRef":$stateName, "ValueRange":$outputs)>
];

let skipDefaultBuilders = 1;
Expand Down Expand Up @@ -301,8 +302,11 @@ def TransitionOp : FSMOp<"transition", [HasParent<"StateOp">, NoTerminator]> {
}];

let builders = [
OpBuilder<(ins "StringRef":$nextState)>,
OpBuilder<(ins "fsm::StateOp":$nextState)>
// OpBuilder<(ins "StringRef":$nextState)>,
OpBuilder<(ins "fsm::StateOp":$nextState)>,
OpBuilder<(ins "StringRef":$nextState,
CArg<"llvm::function_ref<void()>", "{}">:$guardCtor,
CArg<"llvm::function_ref<void()>", "{}">:$actionCtor)>
];

let skipDefaultBuilders = 1;
Expand Down
39 changes: 32 additions & 7 deletions lib/Dialect/FSM/FSMOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,18 @@ void StateOp::build(OpBuilder &builder, OperationState &state,
state.addAttribute("sym_name", builder.getStringAttr(stateName));
}

void StateOp::build(OpBuilder &builder, OperationState &state,
StringRef stateName, ValueRange outputs) {
OpBuilder::InsertionGuard guard(builder);
Region *output = state.addRegion();
output->push_back(new Block());
builder.setInsertionPointToEnd(&output->back());
builder.create<fsm::OutputOp>(state.location, outputs);
Region *transitions = state.addRegion();
transitions->push_back(new Block());
state.addAttribute("sym_name", builder.getStringAttr(stateName));
}

SetVector<StateOp> StateOp::getNextStates() {
SmallVector<StateOp> nextStates;
llvm::transform(
Expand Down Expand Up @@ -402,16 +414,29 @@ LogicalResult OutputOp::verify() {
//===----------------------------------------------------------------------===//

void TransitionOp::build(OpBuilder &builder, OperationState &state,
StringRef nextState) {
state.addRegion(); // guard
state.addRegion(); // action
state.addAttribute("nextState",
FlatSymbolRefAttr::get(builder.getStringAttr(nextState)));
StateOp nextState) {
build(builder, state, nextState.getName());
}

void TransitionOp::build(OpBuilder &builder, OperationState &state,
StateOp nextState) {
build(builder, state, nextState.getName());
StringRef nextState,
llvm::function_ref<void()> guardCtor,
llvm::function_ref<void()> actionCtor) {
state.addAttribute("nextState",
FlatSymbolRefAttr::get(builder.getStringAttr(nextState)));
OpBuilder::InsertionGuard guard(builder);

Region *guardRegion = state.addRegion(); // guard
if (guardCtor) {
builder.createBlock(guardRegion);
guardCtor();
}

Region *actionRegion = state.addRegion(); // action
if (actionCtor) {
builder.createBlock(actionRegion);
actionCtor();
}
}

Block *TransitionOp::ensureGuard(OpBuilder &builder) {
Expand Down

0 comments on commit 499d1e9

Please sign in to comment.