Addfinal specifier to the classop (#145977)
In some use cases of the `ClassOp`, eg MLGO, we would like to be able to declare the class as final. This specifier allows for that.
This commit is contained in:
@@ -1618,10 +1618,20 @@ def EmitC_ClassOp
|
||||
return
|
||||
}
|
||||
}
|
||||
// Class with a final speciferAdd commentMore actions
|
||||
emitc.class final @modelClass {
|
||||
emitc.field @fieldName0 : !emitc.array<1xf32> = {emitc.opaque = "input_tensor"}
|
||||
emitc.func @execute() {
|
||||
%0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
|
||||
%1 = get_field @fieldName0 : !emitc.array<1xf32>
|
||||
%2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
|
||||
return
|
||||
}
|
||||
}
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins SymbolNameAttr:$sym_name);
|
||||
let arguments = (ins SymbolNameAttr:$sym_name, UnitAttr:$final_specifier);
|
||||
|
||||
let regions = (region AnyRegion:$body);
|
||||
|
||||
@@ -1632,7 +1642,8 @@ def EmitC_ClassOp
|
||||
|
||||
let hasCustomAssemblyFormat = 1;
|
||||
|
||||
let assemblyFormat = [{ $sym_name attr-dict-with-keyword $body }];
|
||||
let assemblyFormat =
|
||||
[{ (`final` $final_specifier^)? $sym_name attr-dict-with-keyword $body }];
|
||||
}
|
||||
|
||||
def EmitC_FieldOp : EmitC_Op<"field", [Symbol]> {
|
||||
|
||||
@@ -1000,8 +1000,10 @@ static LogicalResult printOperation(CppEmitter &emitter, ModuleOp moduleOp) {
|
||||
static LogicalResult printOperation(CppEmitter &emitter, ClassOp classOp) {
|
||||
CppEmitter::Scope classScope(emitter);
|
||||
raw_indented_ostream &os = emitter.ostream();
|
||||
os << "class " << classOp.getSymName() << " {\n";
|
||||
os << "public:\n";
|
||||
os << "class " << classOp.getSymName();
|
||||
if (classOp.getFinalSpecifier())
|
||||
os << " final";
|
||||
os << " {\n public:\n";
|
||||
os.indent();
|
||||
|
||||
for (Operation &op : classOp) {
|
||||
|
||||
@@ -12,7 +12,32 @@ emitc.class @modelClass {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: class modelClass {
|
||||
// CHECK-LABEL: class modelClass {
|
||||
// CHECK-NEXT: public:
|
||||
// CHECK-NEXT: float[1] fieldName0;
|
||||
// CHECK-NEXT: float[1] fieldName1;
|
||||
// CHECK-NEXT: void execute() {
|
||||
// CHECK-NEXT: size_t v1 = 0;
|
||||
// CHECK-NEXT: float[1] v2 = fieldName0;
|
||||
// CHECK-NEXT: float[1] v3 = fieldName1;
|
||||
// CHECK-NEXT: return;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-EMPTY:
|
||||
// CHECK-NEXT: };
|
||||
|
||||
emitc.class final @finalClass {
|
||||
emitc.field @fieldName0 : !emitc.array<1xf32>
|
||||
emitc.field @fieldName1 : !emitc.array<1xf32>
|
||||
emitc.func @execute() {
|
||||
%0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
|
||||
%1 = get_field @fieldName0 : !emitc.array<1xf32>
|
||||
%2 = get_field @fieldName1 : !emitc.array<1xf32>
|
||||
%3 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue<f32>
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: class finalClass final {
|
||||
// CHECK-NEXT: public:
|
||||
// CHECK-NEXT: float[1] fieldName0;
|
||||
// CHECK-NEXT: float[1] fieldName1;
|
||||
|
||||
Reference in New Issue
Block a user