mlir.dialects.emitc =================== .. py:module:: mlir.dialects.emitc Classes ------- .. autoapisummary:: mlir.dialects.emitc.AddAssignOp mlir.dialects.emitc.AddAssignOpAdaptor mlir.dialects.emitc.AddOp mlir.dialects.emitc.AddOpAdaptor mlir.dialects.emitc.AddressOfOp mlir.dialects.emitc.AddressOfOpAdaptor mlir.dialects.emitc.AssignOp mlir.dialects.emitc.AssignOpAdaptor mlir.dialects.emitc.BitwiseAndOp mlir.dialects.emitc.BitwiseAndOpAdaptor mlir.dialects.emitc.BitwiseLeftShiftOp mlir.dialects.emitc.BitwiseLeftShiftOpAdaptor mlir.dialects.emitc.BitwiseNotOp mlir.dialects.emitc.BitwiseNotOpAdaptor mlir.dialects.emitc.BitwiseOrOp mlir.dialects.emitc.BitwiseOrOpAdaptor mlir.dialects.emitc.BitwiseRightShiftOp mlir.dialects.emitc.BitwiseRightShiftOpAdaptor mlir.dialects.emitc.BitwiseXorOp mlir.dialects.emitc.BitwiseXorOpAdaptor mlir.dialects.emitc.CallOp mlir.dialects.emitc.CallOpAdaptor mlir.dialects.emitc.CallOpaqueOp mlir.dialects.emitc.CallOpaqueOpAdaptor mlir.dialects.emitc.CastOp mlir.dialects.emitc.CastOpAdaptor mlir.dialects.emitc.ClassOp mlir.dialects.emitc.ClassOpAdaptor mlir.dialects.emitc.CmpOp mlir.dialects.emitc.CmpOpAdaptor mlir.dialects.emitc.ConditionalOp mlir.dialects.emitc.ConditionalOpAdaptor mlir.dialects.emitc.ConstantOp mlir.dialects.emitc.ConstantOpAdaptor mlir.dialects.emitc.DeclareFuncOp mlir.dialects.emitc.DeclareFuncOpAdaptor mlir.dialects.emitc.DereferenceOp mlir.dialects.emitc.DereferenceOpAdaptor mlir.dialects.emitc.DivAssignOp mlir.dialects.emitc.DivAssignOpAdaptor mlir.dialects.emitc.DivOp mlir.dialects.emitc.DivOpAdaptor mlir.dialects.emitc.DoOp mlir.dialects.emitc.DoOpAdaptor mlir.dialects.emitc.ExpressionOp mlir.dialects.emitc.ExpressionOpAdaptor mlir.dialects.emitc.FieldOp mlir.dialects.emitc.FieldOpAdaptor mlir.dialects.emitc.FileOp mlir.dialects.emitc.FileOpAdaptor mlir.dialects.emitc.ForOp mlir.dialects.emitc.ForOpAdaptor mlir.dialects.emitc.FuncOp mlir.dialects.emitc.FuncOpAdaptor mlir.dialects.emitc.GetFieldOp mlir.dialects.emitc.GetFieldOpAdaptor mlir.dialects.emitc.GetGlobalOp mlir.dialects.emitc.GetGlobalOpAdaptor mlir.dialects.emitc.GlobalOp mlir.dialects.emitc.GlobalOpAdaptor mlir.dialects.emitc.IfOp mlir.dialects.emitc.IfOpAdaptor mlir.dialects.emitc.IncludeOp mlir.dialects.emitc.IncludeOpAdaptor mlir.dialects.emitc.LiteralOp mlir.dialects.emitc.LiteralOpAdaptor mlir.dialects.emitc.LoadOp mlir.dialects.emitc.LoadOpAdaptor mlir.dialects.emitc.LogicalAndOp mlir.dialects.emitc.LogicalAndOpAdaptor mlir.dialects.emitc.LogicalNotOp mlir.dialects.emitc.LogicalNotOpAdaptor mlir.dialects.emitc.LogicalOrOp mlir.dialects.emitc.LogicalOrOpAdaptor mlir.dialects.emitc.MemberCallOpaqueOp mlir.dialects.emitc.MemberCallOpaqueOpAdaptor mlir.dialects.emitc.MemberOfPtrOp mlir.dialects.emitc.MemberOfPtrOpAdaptor mlir.dialects.emitc.MemberOp mlir.dialects.emitc.MemberOpAdaptor mlir.dialects.emitc.MulAssignOp mlir.dialects.emitc.MulAssignOpAdaptor mlir.dialects.emitc.MulOp mlir.dialects.emitc.MulOpAdaptor mlir.dialects.emitc.PostDecrementOp mlir.dialects.emitc.PostDecrementOpAdaptor mlir.dialects.emitc.PostIncrementOp mlir.dialects.emitc.PostIncrementOpAdaptor mlir.dialects.emitc.PreDecrementOp mlir.dialects.emitc.PreDecrementOpAdaptor mlir.dialects.emitc.PreIncrementOp mlir.dialects.emitc.PreIncrementOpAdaptor mlir.dialects.emitc.RemAssignOp mlir.dialects.emitc.RemAssignOpAdaptor mlir.dialects.emitc.RemOp mlir.dialects.emitc.RemOpAdaptor mlir.dialects.emitc.ReturnOp mlir.dialects.emitc.ReturnOpAdaptor mlir.dialects.emitc.SubAssignOp mlir.dialects.emitc.SubAssignOpAdaptor mlir.dialects.emitc.SubOp mlir.dialects.emitc.SubOpAdaptor mlir.dialects.emitc.SubscriptOp mlir.dialects.emitc.SubscriptOpAdaptor mlir.dialects.emitc.SwitchOp mlir.dialects.emitc.SwitchOpAdaptor mlir.dialects.emitc.UnaryMinusOp mlir.dialects.emitc.UnaryMinusOpAdaptor mlir.dialects.emitc.UnaryPlusOp mlir.dialects.emitc.UnaryPlusOpAdaptor mlir.dialects.emitc.VariableOp mlir.dialects.emitc.VariableOpAdaptor mlir.dialects.emitc.VerbatimOp mlir.dialects.emitc.VerbatimOpAdaptor mlir.dialects.emitc.YieldOp mlir.dialects.emitc.YieldOpAdaptor Functions --------- .. autoapisummary:: mlir.dialects.emitc.add_assign mlir.dialects.emitc.add mlir.dialects.emitc.address_of mlir.dialects.emitc.assign mlir.dialects.emitc.bitwise_and mlir.dialects.emitc.bitwise_left_shift mlir.dialects.emitc.bitwise_not mlir.dialects.emitc.bitwise_or mlir.dialects.emitc.bitwise_right_shift mlir.dialects.emitc.bitwise_xor mlir.dialects.emitc.call mlir.dialects.emitc.call_opaque mlir.dialects.emitc.cast mlir.dialects.emitc.class_ mlir.dialects.emitc.cmp mlir.dialects.emitc.conditional mlir.dialects.emitc.constant mlir.dialects.emitc.declare_func mlir.dialects.emitc.dereference mlir.dialects.emitc.div_assign mlir.dialects.emitc.div mlir.dialects.emitc.do mlir.dialects.emitc.expression mlir.dialects.emitc.field mlir.dialects.emitc.file mlir.dialects.emitc.for_ mlir.dialects.emitc.func mlir.dialects.emitc.get_field mlir.dialects.emitc.get_global mlir.dialects.emitc.global_ mlir.dialects.emitc.if_ mlir.dialects.emitc.include mlir.dialects.emitc.literal mlir.dialects.emitc.load mlir.dialects.emitc.logical_and mlir.dialects.emitc.logical_not mlir.dialects.emitc.logical_or mlir.dialects.emitc.member_call_opaque mlir.dialects.emitc.member_of_ptr mlir.dialects.emitc.member mlir.dialects.emitc.mul_assign mlir.dialects.emitc.mul mlir.dialects.emitc.post_decrement mlir.dialects.emitc.post_increment mlir.dialects.emitc.pre_decrement mlir.dialects.emitc.pre_increment mlir.dialects.emitc.rem_assign mlir.dialects.emitc.rem mlir.dialects.emitc.return_ mlir.dialects.emitc.sub_assign mlir.dialects.emitc.sub mlir.dialects.emitc.subscript mlir.dialects.emitc.switch mlir.dialects.emitc.unary_minus mlir.dialects.emitc.unary_plus mlir.dialects.emitc.variable mlir.dialects.emitc.verbatim mlir.dialects.emitc.yield_ Module Contents --------------- .. py:class:: AddAssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.add_assign`` operation applies the C/C++ ``+=`` operator to an lvalue. Example: .. code:: mlir emitc.add_assign %value : i32 to %var : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.add_assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: AddAssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) AddAssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.add_assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: add_assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> AddAssignOp .. py:class:: AddOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.add`` operation the arithmetic operator + (addition) can be applied. Example: .. code:: mlir // Custom form of the addition operation. %0 = emitc.add %arg0, %arg1 : (i32, i32) -> i32 %1 = emitc.add %arg2, %arg3 : (!emitc.ptr, i32) -> !emitc.ptr .. code:: c++ // Code emitted for the operations above. int32_t v5 = v1 + v2; float* v6 = v3 + v4; .. py:attribute:: OPERATION_NAME :value: 'emitc.add' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: AddOpAdaptor(operands: list[Value], attributes: OpAttributeMap) AddOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.add' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: add(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: AddressOfOp(result: _ods_ir, reference: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C & (address of) operator for a single operand, which must be an emitc.lvalue, and returns an emitc pointer to its location. Example: .. code:: mlir // Custom form of applying the & operator. %0 = emitc.address_of %arg0 : (!emitc.lvalue) -> !emitc.ptr .. py:attribute:: OPERATION_NAME :value: 'emitc.address_of' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: reference() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: AddressOfOpAdaptor(operands: list[Value], attributes: OpAttributeMap) AddressOfOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.address_of' .. py:method:: reference() -> _ods_ir .. py:function:: address_of(result: _ods_ir, reference: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: AssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.assign`` operation stores an SSA value to the location designated by an EmitC variable. This operation doesn't return any value. The assigned value must be of the same type as the variable being assigned. The operation is emitted as a C/C++ '=' operator. Example: .. code:: mlir // Integer variable %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue %1 = emitc.call_opaque "foo"() : () -> (i32) // Assign emitted as `... = ...;` "emitc.assign"(%0, %1) : (!emitc.lvalue, i32) -> () .. py:attribute:: OPERATION_NAME :value: 'emitc.assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: AssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) AssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> AssignOp .. py:class:: BitwiseAndOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_and`` operation the bitwise operator & (and) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_and %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v3 = v1 & v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_and' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: BitwiseAndOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseAndOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_and' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: bitwise_and(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: BitwiseLeftShiftOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_left_shift`` operation the bitwise operator << (left shift) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_left_shift %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v3 = v1 << v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_left_shift' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: BitwiseLeftShiftOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseLeftShiftOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_left_shift' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: bitwise_left_shift(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: BitwiseNotOp(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_not`` operation the bitwise operator ~ (not) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_not %arg0 : (i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v2 = ~v1; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_not' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: BitwiseNotOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseNotOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_not' .. py:function:: bitwise_not(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: BitwiseOrOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_or`` operation the bitwise operator | (or) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_or %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v3 = v1 | v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_or' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: BitwiseOrOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseOrOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_or' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: bitwise_or(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: BitwiseRightShiftOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_right_shift`` operation the bitwise operator >> (right shift) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_right_shift %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v3 = v1 >> v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_right_shift' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: BitwiseRightShiftOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseRightShiftOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_right_shift' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: bitwise_right_shift(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: BitwiseXorOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.bitwise_xor`` operation the bitwise operator ^ (xor) can be applied. Example: .. code:: mlir %0 = emitc.bitwise_xor %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v3 = v1 ^ v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_xor' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: BitwiseXorOpAdaptor(operands: list[Value], attributes: OpAttributeMap) BitwiseXorOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.bitwise_xor' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: bitwise_xor(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: CallOp(result: Sequence[_ods_ir], callee: Union[str, _ods_ir], operands_: Sequence[_ods_ir], *, arg_attrs: Optional[Union[Any, _ods_ir]] = None, res_attrs: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.call`` operation represents a direct call to an ``emitc.func`` that is within the same symbol scope as the call. The operands and result type of the call must match the specified function type. The callee is encoded as a symbol reference attribute named "callee". Example: .. code:: mlir %2 = emitc.call @my_add(%0, %1) : (f32, f32) -> f32 .. py:attribute:: OPERATION_NAME :value: 'emitc.call' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operands_() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: arg_attrs() -> Optional[_ods_ir] .. py:method:: res_attrs() -> Optional[_ods_ir] .. py:class:: CallOpAdaptor(operands: list[Value], attributes: OpAttributeMap) CallOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.call' .. py:method:: operands_() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: arg_attrs() -> Optional[_ods_ir] .. py:method:: res_attrs() -> Optional[_ods_ir] .. py:function:: call(result: Sequence[_ods_ir], callee: Union[str, _ods_ir], operands_: Sequence[_ods_ir], *, arg_attrs: Optional[Union[Any, _ods_ir]] = None, res_attrs: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> Union[_ods_ir, _ods_ir, CallOp] .. py:class:: CallOpaqueOp(result: Sequence[_ods_ir], callee: Union[str, _ods_ir], arg_operands: Sequence[_ods_ir], *, args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, template_args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.call_opaque`` operation represents a C++ function call. The callee can be an arbitrary non-empty string. The call allows specifying order of operands and attributes in the call as follows: * integer value of index type refers to an operand; * attribute which will get lowered to constant value in call; Example: .. code:: mlir // Custom form defining a call to `foo()`. %0 = emitc.call_opaque "foo" () : () -> i32 // Generic form of the same operation. %0 = "emitc.call_opaque"() {callee = "foo"} : () -> i32 .. py:attribute:: OPERATION_NAME :value: 'emitc.call_opaque' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: arg_operands() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: args() -> Optional[_ods_ir] .. py:method:: template_args() -> Optional[_ods_ir] .. py:class:: CallOpaqueOpAdaptor(operands: list[Value], attributes: OpAttributeMap) CallOpaqueOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.call_opaque' .. py:method:: arg_operands() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: args() -> Optional[_ods_ir] .. py:method:: template_args() -> Optional[_ods_ir] .. py:function:: call_opaque(result: Sequence[_ods_ir], callee: Union[str, _ods_ir], arg_operands: Sequence[_ods_ir], *, args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, template_args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> Union[_ods_ir, _ods_ir, CallOpaqueOp] .. py:class:: CastOp(dest: _ods_ir, source: _ods_ir, *, pure: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.cast`` operation performs an explicit type conversion and is emitted as a C-style cast expression. It can be applied to integer, float, index and EmitC types. Example: .. code:: mlir // Cast from `int32_t` to `float` %0 = emitc.cast %arg0: i32 to f32 // Cast from `void` to `int32_t` pointer %1 = emitc.cast %arg1 : !emitc.ptr> to !emitc.ptr In general, C++ cast expressions cannot always be assumed to be pure: they may invoke user-defined conversions or be affected by floating-point environment settings. However, in many practical cases, such as integer casts without operator overloading, the cast is pure and can be treated as speculatable and side-effect-free. For such cases, the ``pure`` attribute may be used. When ``pure`` attribute is set, ``getSpeculatability()`` returns ``Speculatable`` and ``getEffects()`` reports no effects. It is UB if the ``pure`` attribute is set and the actual conversion is not pure, e.g. when the user-defined conversion has memory effects. .. py:attribute:: OPERATION_NAME :value: 'emitc.cast' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: source() -> _ods_ir .. py:method:: pure() -> bool .. py:method:: dest() -> _ods_ir .. py:class:: CastOpAdaptor(operands: list[Value], attributes: OpAttributeMap) CastOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.cast' .. py:method:: source() -> _ods_ir .. py:method:: pure() -> bool .. py:function:: cast(dest: _ods_ir, source: _ods_ir, *, pure: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: ClassOp(sym_name: Union[str, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, final_specifier: Optional[bool] = None, class_type: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.class`` operation defines a C++ class, acting as a container for its data fields (``emitc.field``) and methods (``emitc.func``). It creates a distinct scope, isolating its contents from the surrounding MLIR region, similar to how C++ classes encapsulate their internals. Example: .. code:: mlir emitc.class @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 return } } // Class with a final specifer 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 return } } .. py:attribute:: OPERATION_NAME :value: 'emitc.class' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: final_specifier() -> bool .. py:method:: class_type() -> _ods_ir .. py:method:: body() -> _ods_ir .. py:class:: ClassOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ClassOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.class' .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: final_specifier() -> bool .. py:method:: class_type() -> _ods_ir .. py:function:: class_(sym_name: Union[str, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, final_specifier: Optional[bool] = None, class_type: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> ClassOp .. py:class:: CmpOp(result: _ods_ir, predicate: Union[Any, _ods_ir], lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.cmp`` operation the comparison operators ==, !=, <, <=, >, >=, <=> can be applied. Its first argument is an attribute that defines the comparison operator: * equal to (mnemonic: ``"eq"``; integer value: ``0``) * not equal to (mnemonic: ``"ne"``; integer value: ``1``) * less than (mnemonic: ``"lt"``; integer value: ``2``) * less than or equal to (mnemonic: ``"le"``; integer value: ``3``) * greater than (mnemonic: ``"gt"``; integer value: ``4``) * greater than or equal to (mnemonic: ``"ge"``; integer value: ``5``) * three-way-comparison (mnemonic: ``"three_way"``; integer value: ``6``) Example: .. code:: mlir // Custom form of the cmp operation. %0 = emitc.cmp eq, %arg0, %arg1 : (i32, i32) -> i1 %1 = emitc.cmp lt, %arg2, %arg3 : ( !emitc.opaque<"std::valarray">, !emitc.opaque<"std::valarray"> ) -> !emitc.opaque<"std::valarray"> .. code:: c++ // Code emitted for the operations above. bool v5 = v1 == v2; std::valarray v6 = v3 < v4; .. py:attribute:: OPERATION_NAME :value: 'emitc.cmp' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: predicate() -> _ods_ir .. py:class:: CmpOpAdaptor(operands: list[Value], attributes: OpAttributeMap) CmpOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.cmp' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:method:: predicate() -> _ods_ir .. py:function:: cmp(result: _ods_ir, predicate: Union[Any, _ods_ir], lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: ConditionalOp(result: _ods_ir, condition: _ods_ir[_ods_ir], true_value: _ods_ir, false_value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.conditional`` operation the ternary conditional operator can be applied. Example: .. code:: mlir %0 = emitc.cmp gt, %arg0, %arg1 : (i32, i32) -> i1 %c0 = "emitc.constant"() {value = 10 : i32} : () -> i32 %c1 = "emitc.constant"() {value = 11 : i32} : () -> i32 %1 = emitc.conditional %0, %c0, %c1 : i32 .. code:: c++ // Code emitted for the operations above. bool v3 = v1 > v2; int32_t v4 = 10; int32_t v5 = 11; int32_t v6 = v3 ? v4 : v5; .. py:attribute:: OPERATION_NAME :value: 'emitc.conditional' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: condition() -> _ods_ir[_ods_ir] .. py:method:: true_value() -> _ods_ir .. py:method:: false_value() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: ConditionalOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ConditionalOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.conditional' .. py:method:: condition() -> _ods_ir[_ods_ir] .. py:method:: true_value() -> _ods_ir .. py:method:: false_value() -> _ods_ir .. py:function:: conditional(result: _ods_ir, condition: _ods_ir[_ods_ir], true_value: _ods_ir, false_value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: ConstantOp(result: _ods_ir, value: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.constant`` operation produces an SSA value equal to some constant specified by an attribute. This can be used to form simple integer and floating point constants, as well as more exotic things like tensor constants. The ``emitc.constant`` operation also supports the EmitC opaque attribute and the EmitC opaque type. Since folding is supported, it should not be used with pointers. Example: .. code:: mlir // Integer constant %0 = "emitc.constant"(){value = 42 : i32} : () -> i32 // Constant emitted as `char = CHAR_MIN;` %1 = "emitc.constant"() {value = #emitc.opaque<"CHAR_MIN">} : () -> !emitc.opaque<"char"> .. py:attribute:: OPERATION_NAME :value: 'emitc.constant' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:class:: ConstantOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ConstantOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.constant' .. py:method:: value() -> _ods_ir .. py:function:: constant(result: _ods_ir, value: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: DeclareFuncOp(sym_name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.declare_func`` operation allows to insert a function declaration for an ``emitc.func`` at a specific position. The operation only requires the "callee" of the ``emitc.func`` to be specified as an attribute. Example: .. code:: mlir emitc.declare_func @bar emitc.func @foo(%arg0: i32) -> i32 { %0 = emitc.call @bar(%arg0) : (i32) -> (i32) emitc.return %0 : i32 } emitc.func @bar(%arg0: i32) -> i32 { emitc.return %arg0 : i32 } .. code:: c++ // Code emitted for the operations above. int32_t bar(int32_t v1); int32_t foo(int32_t v1) { int32_t v2 = bar(v1); return v2; } int32_t bar(int32_t v1) { return v1; } .. py:attribute:: OPERATION_NAME :value: 'emitc.declare_func' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: sym_name() -> _ods_ir .. py:class:: DeclareFuncOpAdaptor(operands: list[Value], attributes: OpAttributeMap) DeclareFuncOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.declare_func' .. py:method:: sym_name() -> _ods_ir .. py:function:: declare_func(sym_name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> DeclareFuncOp .. py:class:: DereferenceOp(result: _ods_ir, pointer: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C * (dereference) operator, which must be of !emitc.ptr<> type, returning an !emitc.lvalue<> the value pointed to by the pointer. Example: .. code:: mlir // Custom form of the dereference operator. %0 = emitc.dereference %arg0 : (!emitc.ptr) -> !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.dereference' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: pointer() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: DereferenceOpAdaptor(operands: list[Value], attributes: OpAttributeMap) DereferenceOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.dereference' .. py:method:: pointer() -> _ods_ir .. py:function:: dereference(result: _ods_ir, pointer: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: DivAssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.div_assign`` operation applies the C/C++ ``/=`` operator to an lvalue. Example: .. code:: mlir emitc.div_assign %value : i32 to %var : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.div_assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: DivAssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) DivAssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.div_assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: div_assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> DivAssignOp .. py:class:: DivOp(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.div`` operation the arithmetic operator / (division) can be applied. Example: .. code:: mlir // Custom form of the division operation. %0 = emitc.div %arg0, %arg1 : (i32, i32) -> i32 %1 = emitc.div %arg2, %arg3 : (f32, f32) -> f32 .. code:: c++ // Code emitted for the operations above. int32_t v5 = v1 / v2; float v6 = v3 / v4; .. py:attribute:: OPERATION_NAME :value: 'emitc.div' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: DivOpAdaptor(operands: list[Value], attributes: OpAttributeMap) DivOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.div' .. py:function:: div(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: DoOp(*, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.do`` operation represents a C/C++ do-while loop construct that repeatedly executes a body region as long as a condition region evaluates to true. The operation has two regions: #. A body region that contains the loop body #. A condition region that must yield a boolean value (i1) The condition is evaluated before each iteration as follows: * The condition region must contain exactly one block with: #. An ``emitc.expression`` operation producing an i1 value #. An ``emitc.yield`` passing through the expression result * The expression's body contains the actual condition logic The body region is executed before the first evaluation of the condition. Thus, there is a guarantee that the loop will be executed at least once. The loop terminates when the condition yields false. The canonical structure of ``emitc.do`` is: .. code:: mlir emitc.do { // Body region (no terminator required). // Loop body operations... } while { // Condition region (must yield i1) %condition = emitc.expression : () -> i1 { // Condition computation... %result = ... : i1 // Last operation must produce i1 emitc.yield %result : i1 } // Forward expression result emitc.yield %condition : i1 } Example: .. code:: mlir emitc.func @do_example() { %counter = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue %end = emitc.literal "10" : i32 %step = emitc.literal "1" : i32 emitc.do { // Print current value %val = emitc.load %counter : !emitc.lvalue emitc.verbatim "printf(\"%d\\n\", {});" args %val : i32 // Increment counter %new_val = emitc.add %val, %step : (i32, i32) -> i32 "emitc.assign"(%counter, %new_val) : (!emitc.lvalue, i32) -> () } while { %condition = emitc.expression %counter, %end : (!emitc.lvalue, i32) -> i1 { %current = emitc.load %counter : !emitc.lvalue %cmp_res = emitc.cmp lt, %current, %end : (i32, i32) -> i1 emitc.yield %cmp_res : i1 } emitc.yield %condition : i1 } return } .. code:: c++ // Code emitted for the operation above. void do_example() { int32_t v1 = 0; do { int32_t v2 = v1; printf("%d\n", v2); int32_t v3 = v2 + 1; v1 = v3; } while (v1 < 10); return; } .. py:attribute:: OPERATION_NAME :value: 'emitc.do' .. py:attribute:: _ODS_REGIONS :value: (2, True) .. py:method:: bodyRegion() -> _ods_ir .. py:method:: conditionRegion() -> _ods_ir .. py:class:: DoOpAdaptor(operands: list[Value], attributes: OpAttributeMap) DoOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.do' .. py:function:: do(*, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> DoOp .. py:class:: ExpressionOp(result: _ods_ir, defs: Sequence[_ods_ir], *, do_not_inline: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.expression`` operation returns a single SSA value which is yielded by its single-basic-block region. The operation takes zero or more input operands that are passed as block arguments to the region. As the operation is to be emitted as a C expression, the operations within its body must form a single Def-Use tree, or a DAG trivially expandable to one, i.e. a DAG where each operation with side effects is only reachable once from the expression root. Input operands can be of both value types (``EmitCType``) and lvalue types (``EmitC_LValueType``). Example: .. code:: mlir %r = emitc.expression %a, %b, %c : (i32, i32, i32) -> i32 { %0 = emitc.call_opaque "foo"(%a) : (i32) -> i32 %1 = emitc.add %b, %c : (i32, i32) -> i32 %2 = emitc.mul %0, %1 : (i32, i32) -> i32 emitc.yield %2 : i32 } May be emitted as: .. code:: c++ int32_t v4 = foo(v1) * (v2 + v3); When specified, the optional ``noinline`` indicates that the expression is to be emitted as seen above, i.e. as the rhs of an EmitC SSA value definition. Otherwise, the expression may be emitted inline, i.e. directly at its use. .. py:attribute:: OPERATION_NAME :value: 'emitc.expression' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: defs() -> _ods_ir .. py:method:: do_not_inline() -> bool .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:method:: region() -> _ods_ir .. py:class:: ExpressionOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ExpressionOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.expression' .. py:method:: defs() -> _ods_ir .. py:method:: do_not_inline() -> bool .. py:function:: expression(result: _ods_ir, defs: Sequence[_ods_ir], *, do_not_inline: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: FieldOp(sym_name: Union[str, _ods_ir], type_: Union[_ods_ir, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, initial_value: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.field`` operation declares a named field within an ``emitc.class`` operation. The field's type must be an EmitC type. Example: .. code:: mlir // Example with an attribute: emitc.field @fieldName0 : !emitc.array<1xf32> {emitc.opaque = "another_feature"} // Example with no attribute: emitc.field @fieldName0 : !emitc.array<1xf32> // Example with an initial value: emitc.field @fieldName0 : !emitc.array<1xf32> = dense<0.0> // Example with an initial value and attributes: emitc.field @fieldName0 : !emitc.array<1xf32> = dense<0.0> { emitc.opaque = "input_tensor"} .. py:attribute:: OPERATION_NAME :value: 'emitc.field' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: type_() -> _ods_ir .. py:method:: initial_value() -> Optional[_ods_ir] .. py:class:: FieldOpAdaptor(operands: list[Value], attributes: OpAttributeMap) FieldOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.field' .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: type_() -> _ods_ir .. py:method:: initial_value() -> Optional[_ods_ir] .. py:function:: field(sym_name: Union[str, _ods_ir], type_: Union[_ods_ir, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, initial_value: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> FieldOp .. py:class:: FileOp(id: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` A ``file`` represents a single C/C++ file. ``mlir-translate`` ignores the body of all ``emitc.file`` ops unless the ``-file-id=id`` flag is used. With that flag, all ``emitc.file`` ops with matching id are emitted. Example: .. code:: mlir emitc.file "main" { emitc.func @func_one() { emitc.return } } .. py:attribute:: OPERATION_NAME :value: 'emitc.file' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: id() -> _ods_ir .. py:method:: bodyRegion() -> _ods_ir .. py:class:: FileOpAdaptor(operands: list[Value], attributes: OpAttributeMap) FileOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.file' .. py:method:: id() -> _ods_ir .. py:function:: file(id: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> FileOp .. py:class:: ForOp(lowerBound: _ods_ir, upperBound: _ods_ir, step: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.for`` operation represents a C loop of the following form: .. code:: c++ for (T i = lb; i < ub; i += step) { /* ... */ } // where T is typeof(lb) The operation takes 3 SSA values as operands that represent the lower bound, upper bound and step respectively, and defines an SSA value for its induction variable. It has one region capturing the loop body. The induction variable is represented as an argument of this region. This SSA value is a signless integer, or an index. The step is a value of same type. This operation has no result. The body region must contain exactly one block that terminates with ``emitc.yield``. Calling ForOp::build will create such a region and insert the terminator implicitly if none is defined, so will the parsing even in cases when it is absent from the custom format. For example: .. code:: mlir // Index case. emitc.for %iv = %lb to %ub step %step { ... // body } ... // Integer case. emitc.for %iv_32 = %lb_32 to %ub_32 step %step_32 : i32 { ... // body } .. py:attribute:: OPERATION_NAME :value: 'emitc.for' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: lowerBound() -> _ods_ir .. py:method:: upperBound() -> _ods_ir .. py:method:: step() -> _ods_ir .. py:method:: region() -> _ods_ir .. py:class:: ForOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ForOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.for' .. py:method:: lowerBound() -> _ods_ir .. py:method:: upperBound() -> _ods_ir .. py:method:: step() -> _ods_ir .. py:function:: for_(lower_bound: _ods_ir, upper_bound: _ods_ir, step: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> ForOp .. py:class:: FuncOp(sym_name: Union[str, _ods_ir], function_type: Union[Any, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, specifiers: Optional[Union[Sequence[str], _ods_ir]] = None, arg_attrs: Optional[Union[Any, _ods_ir]] = None, res_attrs: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` Operations within the function cannot implicitly capture values defined outside of the function, i.e. Functions are ``IsolatedFromAbove``. All external references must use function arguments or attributes that establish a symbolic connection (e.g. symbols referenced by name via a string attribute like SymbolRefAttr). While the MLIR textual form provides a nice inline syntax for function arguments, they are internally represented as “block arguments” to the first block in the region. Only dialect attribute names may be specified in the attribute dictionaries for function arguments, results, or the function itself. Example: .. code:: mlir // A function with no results: emitc.func @foo(%arg0 : i32) { emitc.call_opaque "bar" (%arg0) : (i32) -> () emitc.return } // A function with its argument as single result: emitc.func @foo(%arg0 : i32) -> i32 { emitc.return %arg0 : i32 } // A function with specifiers attribute: emitc.func @example_specifiers_fn_attr() -> i32 attributes {specifiers = ["static","inline"]} { %0 = emitc.call_opaque "foo" (): () -> i32 emitc.return %0 : i32 } // An external function definition: emitc.func private @extern_func(i32) attributes {specifiers = ["extern"]} .. py:attribute:: OPERATION_NAME :value: 'emitc.func' .. py:attribute:: _ODS_REGIONS :value: (1, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: function_type() -> _ods_ir .. py:method:: specifiers() -> Optional[_ods_ir] .. py:method:: arg_attrs() -> Optional[_ods_ir] .. py:method:: res_attrs() -> Optional[_ods_ir] .. py:method:: body() -> _ods_ir .. py:class:: FuncOpAdaptor(operands: list[Value], attributes: OpAttributeMap) FuncOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.func' .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: function_type() -> _ods_ir .. py:method:: specifiers() -> Optional[_ods_ir] .. py:method:: arg_attrs() -> Optional[_ods_ir] .. py:method:: res_attrs() -> Optional[_ods_ir] .. py:function:: func(sym_name: Union[str, _ods_ir], function_type: Union[Any, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, specifiers: Optional[Union[Sequence[str], _ods_ir]] = None, arg_attrs: Optional[Union[Any, _ods_ir]] = None, res_attrs: Optional[Union[Any, _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> FuncOp .. py:class:: GetFieldOp(result: _ods_ir, field_name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.get_field`` operation retrieves the lvalue of a named field from a given class instance. Example: .. code:: mlir %0 = get_field @fieldName0 : !emitc.array<1xf32> .. py:attribute:: OPERATION_NAME :value: 'emitc.get_field' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: field_name() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: GetFieldOpAdaptor(operands: list[Value], attributes: OpAttributeMap) GetFieldOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.get_field' .. py:method:: field_name() -> _ods_ir .. py:function:: get_field(result: _ods_ir, field_name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: GetGlobalOp(result: _ods_ir, name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.get_global`` operation retrieves the lvalue of a named global variable. If the global variable is marked constant, assigning to that lvalue is undefined. Example: .. code:: mlir %x = emitc.get_global @foo : !emitc.array<2xf32> %y = emitc.get_global @bar : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.get_global' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: name() -> _ods_ir Returns the fully qualified name of the operation. .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: GetGlobalOpAdaptor(operands: list[Value], attributes: OpAttributeMap) GetGlobalOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.get_global' .. py:method:: name() -> _ods_ir .. py:function:: get_global(result: _ods_ir, name: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: GlobalOp(sym_name: Union[str, _ods_ir], type_: Union[_ods_ir, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, initial_value: Optional[Union[Any, _ods_ir]] = None, extern_specifier: Optional[bool] = None, static_specifier: Optional[bool] = None, const_specifier: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.global`` operation declares or defines a named global variable. The backing memory for the variable is allocated statically and described by the variable's type, which must be an EmitC type. Optionally, an ``initial_value`` can be provided. Internal linkage can be specified using the ``static_specifier`` unit attribute and external linkage can be specified using the ``extern_specifier`` unit attribute. Note that the default linkage without those two keywords depends on whether the target is C or C++ and whether the global variable is ``const``. The global variable can also be marked constant using the ``const_specifier`` unit attribute. Writing to such constant global variables is undefined. The global variable can be accessed by using the ``emitc.get_global`` to retrieve the value for the global variable. Example: .. code:: mlir // Global variable with an initial value. emitc.global @x : !emitc.array<2xf32> = dense<0.0> // Global variable with an initial values. emitc.global @x : !emitc.array<3xi32> = dense<[0, 1, 2]> // Global variable with an opaque initial value. emitc.global @x : !emitc.opaque<"char"> = #emitc.opaque<"CHAR_MIN"> // External global variable emitc.global extern @x : !emitc.array<2xf32> // Constant global variable with internal linkage emitc.global static const @x : i32 = 0 .. py:attribute:: OPERATION_NAME :value: 'emitc.global' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: type_() -> _ods_ir .. py:method:: initial_value() -> Optional[_ods_ir] .. py:method:: extern_specifier() -> bool .. py:method:: static_specifier() -> bool .. py:method:: const_specifier() -> bool .. py:class:: GlobalOpAdaptor(operands: list[Value], attributes: OpAttributeMap) GlobalOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.global' .. py:method:: sym_name() -> _ods_ir .. py:method:: sym_visibility() -> Optional[_ods_ir] .. py:method:: type_() -> _ods_ir .. py:method:: initial_value() -> Optional[_ods_ir] .. py:method:: extern_specifier() -> bool .. py:method:: static_specifier() -> bool .. py:method:: const_specifier() -> bool .. py:function:: global_(sym_name: Union[str, _ods_ir], type_: Union[_ods_ir, _ods_ir], *, sym_visibility: Optional[Union[str, _ods_ir]] = None, initial_value: Optional[Union[Any, _ods_ir]] = None, extern_specifier: Optional[bool] = None, static_specifier: Optional[bool] = None, const_specifier: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> GlobalOp .. py:class:: IfOp(condition: _ods_ir[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.if`` operation represents an if-then-else construct for conditionally executing two regions of code. The operand to an if operation is a boolean value. For example: .. code:: mlir emitc.if %b { ... } else { ... } The "then" region has exactly 1 block. The "else" region may have 0 or 1 blocks. The blocks are always terminated with ``emitc.yield``, which can be left out to be inserted implicitly. This operation doesn't produce any results. .. py:attribute:: OPERATION_NAME :value: 'emitc.if' .. py:attribute:: _ODS_REGIONS :value: (2, True) .. py:method:: condition() -> _ods_ir[_ods_ir] .. py:method:: thenRegion() -> _ods_ir .. py:method:: elseRegion() -> _ods_ir .. py:class:: IfOpAdaptor(operands: list[Value], attributes: OpAttributeMap) IfOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.if' .. py:method:: condition() -> _ods_ir[_ods_ir] .. py:function:: if_(condition: _ods_ir[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> IfOp .. py:class:: IncludeOp(include: Union[str, _ods_ir], *, is_standard_include: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.include`` operation allows to define a source file inclusion via the ``#include`` directive. Example: .. code:: mlir // Custom form defining the inclusion of ``. emitc.include <"myheader.h"> // Generic form of the same operation. "emitc.include" (){include = "myheader.h", is_standard_include} : () -> () // Custom form defining the inclusion of `"myheader"`. emitc.include "myheader.h" // Generic form of the same operation. "emitc.include" (){include = "myheader.h"} : () -> () .. py:attribute:: OPERATION_NAME :value: 'emitc.include' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: include() -> _ods_ir .. py:method:: is_standard_include() -> bool .. py:class:: IncludeOpAdaptor(operands: list[Value], attributes: OpAttributeMap) IncludeOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.include' .. py:method:: include() -> _ods_ir .. py:method:: is_standard_include() -> bool .. py:function:: include(include: Union[str, _ods_ir], *, is_standard_include: Optional[bool] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> IncludeOp .. py:class:: LiteralOp(result: _ods_ir, value: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.literal`` operation produces an SSA value equal to some constant specified by an attribute. Example: .. code:: mlir %p0 = emitc.literal "M_PI" : f32 %1 = "emitc.add" (%arg0, %p0) : (f32, f32) -> f32 .. code:: c++ // Code emitted for the operation above. float v2 = v1 + M_PI; .. py:attribute:: OPERATION_NAME :value: 'emitc.literal' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: LiteralOpAdaptor(operands: list[Value], attributes: OpAttributeMap) LiteralOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.literal' .. py:method:: value() -> _ods_ir .. py:function:: literal(result: _ods_ir, value: Union[str, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: LoadOp(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation loads the content of a modifiable lvalue into an SSA value. Modifications of the lvalue executed after the load are not observable on the produced value. Example: .. code:: mlir %1 = emitc.load %0 : !emitc.lvalue .. code:: c++ // Code emitted for the operation above. int32_t v2 = v1; .. py:attribute:: OPERATION_NAME :value: 'emitc.load' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: LoadOpAdaptor(operands: list[Value], attributes: OpAttributeMap) LoadOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.load' .. py:method:: operand() -> _ods_ir .. py:function:: load(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: LogicalAndOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.logical_and`` operation the logical operator && (and) can be applied. Example: .. code:: mlir %0 = emitc.logical_and %arg0, %arg1 : i32, i32 .. code:: c++ // Code emitted for the operation above. bool v3 = v1 && v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_and' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: LogicalAndOpAdaptor(operands: list[Value], attributes: OpAttributeMap) LogicalAndOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_and' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: logical_and(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir[_ods_ir] .. py:class:: LogicalNotOp(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.logical_not`` operation the logical operator ! (negation) can be applied. Example: .. code:: mlir %0 = emitc.logical_not %arg0 : i32 .. code:: c++ // Code emitted for the operation above. bool v2 = !v1; .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_not' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: LogicalNotOpAdaptor(operands: list[Value], attributes: OpAttributeMap) LogicalNotOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_not' .. py:function:: logical_not(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir[_ods_ir] .. py:class:: LogicalOrOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.logical_or`` operation the logical operator || (inclusive or) can be applied. Example: .. code:: mlir %0 = emitc.logical_or %arg0, %arg1 : i32, i32 .. code:: c++ // Code emitted for the operation above. bool v3 = v1 || v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_or' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: LogicalOrOpAdaptor(operands: list[Value], attributes: OpAttributeMap) LogicalOrOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.logical_or' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: logical_or(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir[_ods_ir] .. py:class:: MemberCallOpaqueOp(result: Sequence[_ods_ir], receiver: _ods_ir, callee: Union[str, _ods_ir], arg_operands: Sequence[_ods_ir], *, args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, template_args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.member_call_opaque`` operation represents a C++ member function call. It takes a receiver operand, a callee string attribute (the method name), and variadic operands for arguments. The call allows specifying order of operands and attributes in the call as follows: * integer value of index type refers to an argument operand; * attribute which will get lowered to constant value in call; Example: .. code:: mlir %0 = emitc.member_call_opaque %receiver "method" (%arg0, %arg1) : !emitc.opaque<"MyClass">, (i32, i32) -> i32 .. py:attribute:: OPERATION_NAME :value: 'emitc.member_call_opaque' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: receiver() -> _ods_ir .. py:method:: arg_operands() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: args() -> Optional[_ods_ir] .. py:method:: template_args() -> Optional[_ods_ir] .. py:class:: MemberCallOpaqueOpAdaptor(operands: list[Value], attributes: OpAttributeMap) MemberCallOpaqueOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.member_call_opaque' .. py:method:: receiver() -> _ods_ir .. py:method:: arg_operands() -> _ods_ir .. py:method:: callee() -> _ods_ir .. py:method:: args() -> Optional[_ods_ir] .. py:method:: template_args() -> Optional[_ods_ir] .. py:function:: member_call_opaque(result: Sequence[_ods_ir], receiver: _ods_ir, callee: Union[str, _ods_ir], arg_operands: Sequence[_ods_ir], *, args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, template_args: Optional[Union[Sequence[_ods_ir], _ods_ir]] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> Union[_ods_ir, _ods_ir, MemberCallOpaqueOp] .. py:class:: MemberOfPtrOp(result: _ods_ir, member: Union[str, _ods_ir], operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.member_of_ptr`` operation the member access operator ``->`` can be applied. Example: .. code:: mlir %0 = "emitc.member_of_ptr" (%arg0) {member = "a"} : (!emitc.lvalue>>) -> !emitc.lvalue %1 = "emitc.member_of_ptr" (%arg0) {member = "b"} : (!emitc.lvalue>>) -> !emitc.array<2xi32> .. py:attribute:: OPERATION_NAME :value: 'emitc.member_of_ptr' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: member() -> _ods_ir .. py:class:: MemberOfPtrOpAdaptor(operands: list[Value], attributes: OpAttributeMap) MemberOfPtrOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.member_of_ptr' .. py:method:: operand() -> _ods_ir .. py:method:: member() -> _ods_ir .. py:function:: member_of_ptr(result: _ods_ir, member: Union[str, _ods_ir], operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: MemberOp(result: _ods_ir, member: Union[str, _ods_ir], operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.member`` operation the member access operator ``.`` can be applied. Example: .. code:: mlir %0 = "emitc.member" (%arg0) {member = "a"} : (!emitc.opaque<"mystruct">) -> i32 %0 = "emitc.member" (%arg0) {member = "a"} : (!emitc.lvalue>) -> !emitc.lvalue %1 = "emitc.member" (%arg0) {member = "b"} : (!emitc.lvalue>) -> !emitc.array<2xi32> .. py:attribute:: OPERATION_NAME :value: 'emitc.member' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: member() -> _ods_ir .. py:class:: MemberOpAdaptor(operands: list[Value], attributes: OpAttributeMap) MemberOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.member' .. py:method:: operand() -> _ods_ir .. py:method:: member() -> _ods_ir .. py:function:: member(result: _ods_ir, member: Union[str, _ods_ir], operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: MulAssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.mul_assign`` operation applies the C/C++ ``*=`` operator to an lvalue. Example: .. code:: mlir emitc.mul_assign %value : i32 to %var : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.mul_assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: MulAssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) MulAssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.mul_assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: mul_assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> MulAssignOp .. py:class:: MulOp(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.mul`` operation the arithmetic operator * (multiplication) can be applied. Example: .. code:: mlir // Custom form of the multiplication operation. %0 = emitc.mul %arg0, %arg1 : (i32, i32) -> i32 %1 = emitc.mul %arg2, %arg3 : (f32, f32) -> f32 .. code:: c++ // Code emitted for the operations above. int32_t v5 = v1 * v2; float v6 = v3 * v4; .. py:attribute:: OPERATION_NAME :value: 'emitc.mul' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: MulOpAdaptor(operands: list[Value], attributes: OpAttributeMap) MulOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.mul' .. py:function:: mul(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: PostDecrementOp(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C/C++ post-decrement operator on an lvalue. Example: .. code:: mlir %0 = emitc.post_decrement %arg0 : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.post_decrement' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: PostDecrementOpAdaptor(operands: list[Value], attributes: OpAttributeMap) PostDecrementOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.post_decrement' .. py:method:: operand() -> _ods_ir .. py:function:: post_decrement(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: PostIncrementOp(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C/C++ post-increment operator on an lvalue. Example: .. code:: mlir %0 = emitc.post_increment %arg0 : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.post_increment' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: PostIncrementOpAdaptor(operands: list[Value], attributes: OpAttributeMap) PostIncrementOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.post_increment' .. py:method:: operand() -> _ods_ir .. py:function:: post_increment(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: PreDecrementOp(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C/C++ pre-decrement operator on an lvalue. Example: .. code:: mlir %0 = emitc.pre_decrement %arg0 : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.pre_decrement' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: PreDecrementOpAdaptor(operands: list[Value], attributes: OpAttributeMap) PreDecrementOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.pre_decrement' .. py:method:: operand() -> _ods_ir .. py:function:: pre_decrement(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: PreIncrementOp(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` This operation models the C/C++ pre-increment operator on an lvalue. Example: .. code:: mlir %0 = emitc.pre_increment %arg0 : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.pre_increment' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: PreIncrementOpAdaptor(operands: list[Value], attributes: OpAttributeMap) PreIncrementOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.pre_increment' .. py:method:: operand() -> _ods_ir .. py:function:: pre_increment(result: _ods_ir, operand: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: RemAssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.rem_assign`` operation applies the C/C++ ``%=`` operator to an lvalue. Example: .. code:: mlir emitc.rem_assign %value : i32 to %var : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.rem_assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: RemAssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) RemAssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.rem_assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: rem_assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> RemAssignOp .. py:class:: RemOp(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.rem`` operation the arithmetic operator % (remainder) can be applied. Example: .. code:: mlir // Custom form of the remainder operation. %0 = emitc.rem %arg0, %arg1 : (i32, i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v5 = v1 % v2; .. py:attribute:: OPERATION_NAME :value: 'emitc.rem' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: RemOpAdaptor(operands: list[Value], attributes: OpAttributeMap) RemOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.rem' .. py:function:: rem(result: _ods_ir, _gen_arg_0: _ods_ir, _gen_arg_1: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: ReturnOp(*, operand: Optional[_ods_ir] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.return`` operation represents a return operation within a function. The operation takes zero or exactly one operand and produces no results. The operand number and type must match the signature of the function that contains the operation. Example: .. code:: mlir emitc.func @foo() -> (i32) { ... emitc.return %0 : i32 } .. py:attribute:: OPERATION_NAME :value: 'emitc.return' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: operand() -> Optional[_ods_ir] .. py:class:: ReturnOpAdaptor(operands: list[Value], attributes: OpAttributeMap) ReturnOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.return' .. py:method:: operand() -> Optional[_ods_ir] .. py:function:: return_(*, operand: Optional[_ods_ir] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> ReturnOp .. py:class:: SubAssignOp(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.sub_assign`` operation applies the C/C++ ``-=`` operator to an lvalue. Example: .. code:: mlir emitc.sub_assign %value : i32 to %var : !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.sub_assign' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: SubAssignOpAdaptor(operands: list[Value], attributes: OpAttributeMap) SubAssignOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.sub_assign' .. py:method:: var() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: sub_assign(var: _ods_ir, value: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> SubAssignOp .. py:class:: SubOp(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.sub`` operation the arithmetic operator - (subtraction) can be applied. Example: .. code:: mlir // Custom form of the substraction operation. %0 = emitc.sub %arg0, %arg1 : (i32, i32) -> i32 %1 = emitc.sub %arg2, %arg3 : (!emitc.ptr, i32) -> !emitc.ptr %2 = emitc.sub %arg4, %arg5 : (!emitc.ptr, !emitc.ptr) -> !emitc.ptrdiff_t .. code:: c++ // Code emitted for the operations above. int32_t v7 = v1 - v2; float* v8 = v3 - v4; ptrdiff_t v9 = v5 - v6; .. py:attribute:: OPERATION_NAME :value: 'emitc.sub' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:class:: SubOpAdaptor(operands: list[Value], attributes: OpAttributeMap) SubOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.sub' .. py:method:: lhs() -> _ods_ir .. py:method:: rhs() -> _ods_ir .. py:function:: sub(result: _ods_ir, lhs: _ods_ir, rhs: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: SubscriptOp(result: _ods_ir, value: _ods_ir, indices: Sequence[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.subscript`` operation the subscript operator ``[]`` can be applied to variables or arguments of array, pointer and opaque type. Example: .. code:: mlir %i = index.constant 1 %j = index.constant 7 %0 = emitc.subscript %arg0[%i, %j] : (!emitc.array<4x8xf32>, index, index) -> !emitc.lvalue %1 = emitc.subscript %arg1[%i] : (!emitc.ptr, index) -> !emitc.lvalue .. py:attribute:: OPERATION_NAME :value: 'emitc.subscript' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:method:: indices() -> _ods_ir .. py:method:: result() -> _ods_ir Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: SubscriptOpAdaptor(operands: list[Value], attributes: OpAttributeMap) SubscriptOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.subscript' .. py:method:: value() -> _ods_ir .. py:method:: indices() -> _ods_ir .. py:function:: subscript(result: _ods_ir, value: _ods_ir, indices: Sequence[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: SwitchOp(arg: _ods_ir, cases: Union[Sequence[int], _ods_ir], num_caseRegions: int, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.switch`` is a control-flow operation that branches to one of the given regions based on the values of the argument and the cases. The operand to a switch operation is a opaque, integral or pointer wide types. The operation always has a "default" region and any number of case regions denoted by integer constants. Control-flow transfers to the case region whose constant value equals the value of the argument. If the argument does not equal any of the case values, control-flow transfer to the "default" region. The operation does not return any value. Moreover, case regions must be explicitly terminated using the ``emitc.yield`` operation. Default region is yielded implicitly. Example: .. code:: mlir // Example: emitc.switch %0 : i32 case 2 { %1 = emitc.call_opaque "func_b" () : () -> i32 emitc.yield } case 5 { %2 = emitc.call_opaque "func_a" () : () -> i32 emitc.yield } default { %3 = "emitc.constant"(){value = 42.0 : f32} : () -> f32 emitc.call_opaque "func2" (%3) : (f32) -> () } .. code:: c++ // Code emitted for the operations above. switch (v1) { case 2: { int32_t v2 = func_b(); break; } case 5: { int32_t v3 = func_a(); break; } default: { float v4 = 4.200000000e+01f; func2(v4); break; } } .. py:attribute:: OPERATION_NAME :value: 'emitc.switch' .. py:attribute:: _ODS_REGIONS :value: (1, False) .. py:method:: arg() -> _ods_ir .. py:method:: cases() -> _ods_ir .. py:method:: defaultRegion() -> _ods_ir .. py:method:: caseRegions() -> _ods_ir .. py:class:: SwitchOpAdaptor(operands: list[Value], attributes: OpAttributeMap) SwitchOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.switch' .. py:method:: arg() -> _ods_ir .. py:method:: cases() -> _ods_ir .. py:function:: switch(arg: _ods_ir, cases: Union[Sequence[int], _ods_ir], num_case_regions: int, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> SwitchOp .. py:class:: UnaryMinusOp(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.unary_minus`` operation the unary operator - (minus) can be applied. Example: .. code:: mlir %0 = emitc.unary_minus %arg0 : (i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v2 = -v1; .. py:attribute:: OPERATION_NAME :value: 'emitc.unary_minus' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: UnaryMinusOpAdaptor(operands: list[Value], attributes: OpAttributeMap) UnaryMinusOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.unary_minus' .. py:function:: unary_minus(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: UnaryPlusOp(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` With the ``emitc.unary_plus`` operation the unary operator + (plus) can be applied. Example: .. code:: mlir %0 = emitc.unary_plus %arg0 : (i32) -> i32 .. code:: c++ // Code emitted for the operation above. int32_t v2 = +v1; .. py:attribute:: OPERATION_NAME :value: 'emitc.unary_plus' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:class:: UnaryPlusOpAdaptor(operands: list[Value], attributes: OpAttributeMap) UnaryPlusOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.unary_plus' .. py:function:: unary_plus(result: _ods_ir, _gen_arg_0: _ods_ir, *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: VariableOp(result: _ods_ir, value: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.variable`` operation produces an SSA value equal to some value specified by an attribute. This can be used to form simple integer and floating point variables, as well as more exotic things like tensor variables. The ``emitc.variable`` operation also supports the EmitC opaque attribute and the EmitC opaque type. If further supports the EmitC pointer type, whereas folding is not supported. The ``emitc.variable`` is emitted as a C/C++ local variable. Example: .. code:: mlir // Integer variable %0 = "emitc.variable"(){value = 42 : i32} : () -> !emitc.lvalue // Variable emitted as `int32_t* = NULL;` %1 = "emitc.variable"() {value = #emitc.opaque<"NULL">} : () -> !emitc.lvalue>> Since folding is not supported, it can be used with pointers. As an example, it is valid to create pointers to ``variable`` operations by using ``address_of`` operations and pass these to a ``call`` operation. .. code:: mlir %0 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue %1 = "emitc.variable"() {value = 0 : i32} : () -> !emitc.lvalue %2 = emitc.address_of %0 : !emitc.lvalue %3 = emitc.address_of %1 : !emitc.lvalue emitc.call_opaque "write"(%2, %3) : (!emitc.ptr, !emitc.ptr) -> () .. py:attribute:: OPERATION_NAME :value: 'emitc.variable' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: value() -> _ods_ir .. py:class:: VariableOpAdaptor(operands: list[Value], attributes: OpAttributeMap) VariableOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.variable' .. py:method:: value() -> _ods_ir .. py:function:: variable(result: _ods_ir, value: Union[Any, _ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> _ods_ir .. py:class:: VerbatimOp(value: Union[str, _ods_ir], fmtArgs: Sequence[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.verbatim`` operation produces no results and the value is emitted as is followed by a line break ('\n' character) during translation. Note: Use with caution. This operation can have arbitrary effects on the semantics of the emitted code. Use semantically more meaningful operations whenever possible. Additionally this op is *NOT* intended to be used to inject large snippets of code. This operation can be used in situations where a more suitable operation is not yet implemented in the dialect or where preprocessor directives interfere with the structure of the code. One example of this is to declare the linkage of external symbols to make the generated code usable in both C and C++ contexts: .. code:: c++ #ifdef __cplusplus extern "C" { #endif ... #ifdef __cplusplus } #endif If the ``emitc.verbatim`` op has operands, then the ``value`` is interpreted as format string, where ``{}`` is a placeholder for an operand in their order. For example, ``emitc.verbatim "#pragma my src={} dst={}" %src, %dest : i32, i32`` would be emitted as ``#pragma my src=a dst=b`` if ``%src`` became ``a`` and ``%dest`` became ``b`` in the C code. ``{{`` in the format string is interpreted as a single ``{`` and doesn't introduce a placeholder. Example: .. code:: mlir emitc.verbatim "typedef float f32;" emitc.verbatim "#pragma my var={} property" args %arg : f32 .. code:: c++ // Code emitted for the operation above. typedef float f32; #pragma my var=v1 property .. py:attribute:: OPERATION_NAME :value: 'emitc.verbatim' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: fmtArgs() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:class:: VerbatimOpAdaptor(operands: list[Value], attributes: OpAttributeMap) VerbatimOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.verbatim' .. py:method:: fmtArgs() -> _ods_ir .. py:method:: value() -> _ods_ir .. py:function:: verbatim(value: Union[str, _ods_ir], fmt_args: Sequence[_ods_ir], *, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> VerbatimOp .. py:class:: YieldOp(*, result: Optional[_ods_ir] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) Bases: :py:obj:`_ods_ir` The ``emitc.yield`` terminates its parent EmitC op's region, optionally yielding an SSA value. The semantics of how the values are yielded is defined by the parent operation. If ``emitc.yield`` has an operand, the operand must match the parent operation's result. If the parent operation defines no values, then the ``emitc.yield`` may be left out in the custom syntax and the builders will insert one implicitly. Otherwise, it has to be present in the syntax to indicate which value is yielded. .. py:attribute:: OPERATION_NAME :value: 'emitc.yield' .. py:attribute:: _ODS_REGIONS :value: (0, True) .. py:method:: result() -> Optional[_ods_ir] Shortcut to get an op result if it has only one (throws an error otherwise). .. py:class:: YieldOpAdaptor(operands: list[Value], attributes: OpAttributeMap) YieldOpAdaptor(operands: list[Value], opview: OpView) Bases: :py:obj:`_ods_ir` .. py:attribute:: OPERATION_NAME :value: 'emitc.yield' .. py:method:: result() -> Optional[_ods_ir] .. py:function:: yield_(*, result: Optional[_ods_ir] = None, loc: Optional[_ods_ir] = None, ip: Optional[_ods_ir] = None) -> YieldOp