@@ -91,15 +91,28 @@ static inline bool IsLstmOp(const StringRef op_name) {
9191 return op_name.take_back (6 ) == " LSTMOp" ;
9292}
9393
94+ static int HasOptions (const Record &def) {
95+ if (def.getValueAsBit (" hasOptions" )) {
96+ return 1 ;
97+ }
98+ if (def.getValueAsBit (" hasOptions2" )) {
99+ return 2 ;
100+ }
101+ return 0 ;
102+ }
103+
94104static void EmitOptionBuilders (const RecordKeeper &record_keeper,
95105 const std::vector<const Record *> &defs,
96106 raw_ostream *ostream) {
97107 raw_ostream &os = *ostream;
98108
99109 const auto attr_type = record_keeper.getClass (" Attr" );
100110 for (const auto *def : defs) {
111+ const int has_options = HasOptions (*def);
101112 // Circle ops without options are skipped over.
102- if (!def->getValueAsBit (" hasOptions" )) continue ;
113+ if (!has_options) {
114+ continue ;
115+ }
103116
104117 StringRef op_name = def->getName ().drop_front (4 ); // Strip 'CIR_' prefix
105118 std::string option_name = GetOperatorOptionName (*def);
@@ -204,7 +217,8 @@ static void EmitOperatorBuilders(const std::vector<const Record *> &defs,
204217 // Build the FlatBuffer operator
205218 os << " return circle::CreateOperator(\n "
206219 " *fbb, opcode_index, inputs, outputs,\n " ;
207- if (def->getValueAsBit (" hasOptions" )) {
220+ const int has_options = HasOptions (*def);
221+ if (has_options == 1 ) {
208222 auto option_name = GetOperatorOptionName (*def);
209223 std::string circle_option_name =
210224 option_name == " BasicLSTMOptions" ? " LSTMOptions" : option_name;
@@ -217,8 +231,26 @@ static void EmitOperatorBuilders(const std::vector<const Record *> &defs,
217231 // used by custom or flex ops and those ops are handled manually.
218232 os << " /*custom_options=*/0, "
219233 << " circle::CustomOptionsFormat_FLEXBUFFERS,\n "
220- << " /*mutating_variable_inputs=*/0"
221- << (has_intermediates ? " , intermediates" : " " ) << " );\n }\n\n " ;
234+ << " /*mutating_variable_inputs=*/0,"
235+ << (has_intermediates ? " intermediates" : " /*intermediates=*/0" );
236+
237+ if (has_options == 2 ) {
238+ os << " ,\n "
239+ << " /*large_custom_options_offset=*/0,\n "
240+ << " /*large_custom_options_size=*/0" ;
241+ os << " ,\n " ;
242+ const std::string option_name = GetOperatorOptionName (*def);
243+ os << " circle::BuiltinOptions2_" << option_name << " , "
244+ << " Create" << option_name << " (tflOp, fbb).Union()" ;
245+ } else {
246+ os << " ,\n "
247+ << " /*large_custom_options_offset=*/0,\n "
248+ << " /*large_custom_options_size=*/0" ;
249+ os << " ,\n " ;
250+ os << " circle::BuiltinOptions2_NONE, /*builtin_options2=*/0" ;
251+ }
252+
253+ os << " );\n }\n\n " ;
222254 }
223255}
224256
@@ -355,24 +387,43 @@ static void EmitBuildOperator(const std::vector<const Record *> &defs,
355387
356388// Emit a function that converts a BuiltinOptionsUnion to a vector of attributes
357389// Signature:
358- // void mlir::BuiltinOptionsToAttributes (
359- // circle::BuiltinOptionsUnion op_union,
390+ // void mlir::BuiltinOptions{id}ToAttributes (
391+ // circle::BuiltinOptions{id}Union op_union,
360392// mlir::Builder builder,
361393// llvm::SmallVectorImpl<mlir::NamedAttribute> &attributes);
362- static void EmitBuiltinOptionsToAttributes (const RecordKeeper &record_keeper,
363- const std::vector<const Record *> &defs,
364- raw_ostream *ostream) {
394+ //
395+ // where id is an empty string if builtin_options_id is 1, or builtin_options_id
396+ // otherwise.
397+ static void EmitBuiltinOptionsToAttributes (
398+ const RecordKeeper &record_keeper, const std::vector<const Record *> &defs,
399+ raw_ostream *ostream, const int builtin_options_id) {
365400 raw_ostream &os = *ostream;
366401
402+ const std::string builtin_options_suffix = [&] {
403+ switch (builtin_options_id) {
404+ case 1 :
405+ return " " ;
406+ case 2 :
407+ return " 2" ;
408+ }
409+ return " UnknownId" ;
410+ }();
411+
367412 // Signature
368- os << " void mlir::BuiltinOptionsToAttributes("
369- " circle::BuiltinOptionsUnion op_union, "
413+ os << " void mlir::BuiltinOptions" << builtin_options_suffix
414+ << " ToAttributes("
415+ " circle::BuiltinOptions"
416+ << builtin_options_suffix
417+ << " Union op_union, "
370418 " mlir::Builder builder, "
371419 " llvm::SmallVectorImpl<mlir::NamedAttribute> &attributes) {\n " ;
372420
373421 const auto attr_type = record_keeper.getClass (" Attr" );
374422 for (const auto *def : defs) {
375- if (!def->getValueAsBit (" hasOptions" )) continue ;
423+ const int has_options = HasOptions (*def);
424+ if (has_options != builtin_options_id) {
425+ continue ;
426+ }
376427 auto option_name = GetOperatorOptionName (*def);
377428 // Basic LSTM and LSTM ops share the same option to attribute converter.
378429 if (option_name == " BasicLSTMOptions" ) {
@@ -405,9 +456,14 @@ static void EmitBuiltinOptionsToAttributes(const RecordKeeper &record_keeper,
405456 os << " return;\n " ;
406457 os << " }\n " ;
407458 }
459+ if (builtin_options_id == 2 ) {
460+ os << " BuiltinOptions2ToAttributesManual(op_union, builder, "
461+ " attributes);\n " ;
462+ }
408463 // Fallthrough case is no attributes
409464 os << " }" ;
410465}
466+
411467// The function below has a non-constant reference as that is required by LLVM's
412468// TableGenMain.
413469// NOLINTNEXTLINE
@@ -440,8 +496,11 @@ static bool OperatorWritersMain(raw_ostream &os, const RecordKeeper &records) {
440496 os << " \n\n " ;
441497 EmitBuildOperator (defs, &os);
442498 os << " \n\n " ;
443- EmitBuiltinOptionsToAttributes (records, defs, &os);
499+ EmitBuiltinOptionsToAttributes (records, defs, &os, /* builtin_options_id= */ 1 );
444500 os << " \n\n " ;
501+ // TODO support options2
502+ // EmitBuiltinOptionsToAttributes(records, defs, &os, /*builtin_options_id=*/2);
503+ // os << "\n\n";
445504 EmitOperandNumbers (records, defs, &os);
446505
447506 return false ;
0 commit comments