@@ -2939,6 +2939,67 @@ def ExtractMemberOp : CIR_Op<"extract_member", [Pure]> {
2939
2939
let hasVerifier = 1;
2940
2940
}
2941
2941
2942
+ //===----------------------------------------------------------------------===//
2943
+ // InsertMemberOp
2944
+ //===----------------------------------------------------------------------===//
2945
+
2946
+ def InsertMemberOp : CIR_Op<"insert_member",
2947
+ [Pure, AllTypesMatch<["record", "result"]>]> {
2948
+ let summary = "Overwrite the value of a member of a struct value";
2949
+ let description = [{
2950
+ The `cir.insert_member` operation overwrites the value of a particular
2951
+ member in the input struct value, and returns the modified struct value. The
2952
+ result of this operation is equal to the input struct value, except for the
2953
+ member specified by `index_attr` whose value is equal to the given value.
2954
+
2955
+ This operation is named after the LLVM instruction `insertvalue`.
2956
+
2957
+ Currently `cir.insert_member` does not work on unions.
2958
+
2959
+ Example:
2960
+
2961
+ ```mlir
2962
+ // Suppose we have a struct with multiple members.
2963
+ !s32i = !cir.int<s, 32>
2964
+ !s8i = !cir.int<s, 32>
2965
+ !struct_ty = !cir.struct<"struct.Bar" {!s32i, !s8i}>
2966
+
2967
+ // And suppose we have a value of the struct type.
2968
+ %0 = cir.const #cir.const_struct<{#cir.int<1> : !s32i, #cir.int<2> : !s8i}> : !struct_ty
2969
+ // %0 is {1, 2}
2970
+
2971
+ // Overwrite the second member of the struct value.
2972
+ %1 = cir.const #cir.int<3> : !s8i
2973
+ %2 = cir.insert_member %0[1], %1 : !struct_ty, !s8i
2974
+ // %2 is {1, 3}
2975
+ ```
2976
+ }];
2977
+
2978
+ let arguments = (ins CIR_StructType:$record, IndexAttr:$index_attr,
2979
+ CIR_AnyType:$value);
2980
+ let results = (outs CIR_StructType:$result);
2981
+
2982
+ let builders = [
2983
+ OpBuilder<(ins "mlir::Value":$record, "uint64_t":$index,
2984
+ "mlir::Value":$value), [{
2985
+ mlir::APInt fieldIdx(64, index);
2986
+ build($_builder, $_state, record, fieldIdx, value);
2987
+ }]>
2988
+ ];
2989
+
2990
+ let extraClassDeclaration = [{
2991
+ /// Get the index of the struct member being accessed.
2992
+ uint64_t getIndex() { return getIndexAttr().getZExtValue(); }
2993
+ }];
2994
+
2995
+ let assemblyFormat = [{
2996
+ $record `[` $index_attr `]` `,` $value attr-dict
2997
+ `:` qualified(type($record)) `,` qualified(type($value))
2998
+ }];
2999
+
3000
+ let hasVerifier = 1;
3001
+ }
3002
+
2942
3003
//===----------------------------------------------------------------------===//
2943
3004
// GetRuntimeMemberOp
2944
3005
//===----------------------------------------------------------------------===//
@@ -3430,6 +3491,74 @@ def DerivedDataMemberOp : CIR_Op<"derived_data_member", [Pure]> {
3430
3491
let hasVerifier = 1;
3431
3492
}
3432
3493
3494
+ //===----------------------------------------------------------------------===//
3495
+ // BaseMethodOp & DerivedMethodOp
3496
+ //===----------------------------------------------------------------------===//
3497
+
3498
+ def BaseMethodOp : CIR_Op<"base_method", [Pure]> {
3499
+ let summary = [{
3500
+ Cast a derived class pointer-to-member-function to a base class
3501
+ pointer-to-member-function
3502
+ }];
3503
+ let description = [{
3504
+ The `cir.base_method` operation casts a pointer-to-member-function of type
3505
+ `Ret (Derived::*)(Args)` to a pointer-to-member-function of type
3506
+ `Ret (Base::*)(Args)`, where `Base` is a non-virtual base class of
3507
+ `Derived`.
3508
+
3509
+ The `offset` parameter gives the offset in bytes of the `Base` base class
3510
+ subobject within a `Derived` object.
3511
+
3512
+ Example:
3513
+
3514
+ ```mlir
3515
+ %1 = cir.base_method(%0 : !cir.method<!cir.func<(!s32i)> in !ty_Derived>) [16] -> !cir.method<!cir.func<(!s32i)> in !ty_Base>
3516
+ ```
3517
+ }];
3518
+
3519
+ let arguments = (ins CIR_MethodType:$src, IndexAttr:$offset);
3520
+ let results = (outs CIR_MethodType:$result);
3521
+
3522
+ let assemblyFormat = [{
3523
+ `(` $src `:` qualified(type($src)) `)`
3524
+ `[` $offset `]` `->` qualified(type($result)) attr-dict
3525
+ }];
3526
+
3527
+ let hasVerifier = 1;
3528
+ }
3529
+
3530
+ def DerivedMethodOp : CIR_Op<"derived_method", [Pure]> {
3531
+ let summary = [{
3532
+ Cast a base class pointer-to-member-function to a derived class
3533
+ pointer-to-member-function
3534
+ }];
3535
+ let description = [{
3536
+ The `cir.derived_method` operation casts a pointer-to-member-function of
3537
+ type `Ret (Base::*)(Args)` to a pointer-to-member-function of type
3538
+ `Ret (Derived::*)(Args)`, where `Base` is a non-virtual base class of
3539
+ `Derived`.
3540
+
3541
+ The `offset` parameter gives the offset in bytes of the `Base` base class
3542
+ subobject within a `Derived` object.
3543
+
3544
+ Example:
3545
+
3546
+ ```mlir
3547
+ %1 = cir.derived_method(%0 : !cir.method<!cir.func<(!s32i)> in !ty_Base>) [16] -> !cir.method<!cir.func<(!s32i)> in !ty_Derived>
3548
+ ```
3549
+ }];
3550
+
3551
+ let arguments = (ins CIR_MethodType:$src, IndexAttr:$offset);
3552
+ let results = (outs CIR_MethodType:$result);
3553
+
3554
+ let assemblyFormat = [{
3555
+ `(` $src `:` qualified(type($src)) `)`
3556
+ `[` $offset `]` `->` qualified(type($result)) attr-dict
3557
+ }];
3558
+
3559
+ let hasVerifier = 1;
3560
+ }
3561
+
3433
3562
//===----------------------------------------------------------------------===//
3434
3563
// FuncOp
3435
3564
//===----------------------------------------------------------------------===//
0 commit comments