@@ -3574,6 +3574,39 @@ def DeleteArrayOp : CIR_Op<"delete.array">,
35743574// CallOp and TryCallOp
35753575//===----------------------------------------------------------------------===//
35763576
3577+ def SE_All : I32EnumAttrCase<"All", 1, "all">;
3578+ def SE_Pure : I32EnumAttrCase<"Pure", 2, "pure">;
3579+ def SE_Const : I32EnumAttrCase<"Const", 3, "const">;
3580+
3581+ def SideEffect : I32EnumAttr<
3582+ "SideEffect", "allowed side effects of a function",
3583+ [SE_All, SE_Pure, SE_Const]> {
3584+ let description = [{
3585+ The side effect attribute specifies the possible side effects of the callee
3586+ of a call operation. This is an enumeration attribute and all possible
3587+ enumerators are:
3588+
3589+ - all: The callee can have any side effects. This is the default if no side
3590+ effects are explicitly listed.
3591+ - pure: The callee may read data from memory, but it cannot write data to
3592+ memory. This has the same effect as the GNU C/C++ attribute
3593+ `__attribute__((pure))`.
3594+ - const: The callee may not read or write data from memory. This has the
3595+ same effect as the GNU C/C++ attribute `__attribute__((const))`.
3596+
3597+ Examples:
3598+
3599+ ```mlir
3600+ %0 = cir.const #cir.int<0> : !s32i
3601+ %1 = cir.const #cir.int<1> : !s32i
3602+ %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(all)
3603+ %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(pure)
3604+ %2 = cir.call @add(%0, %1) : (!s32i, !s32i) -> !s32i side_effect(const)
3605+ ```
3606+ }];
3607+ let cppNamespace = "::cir";
3608+ }
3609+
35773610class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []> :
35783611 Op<CIR_Dialect, mnemonic,
35793612 !listconcat(extra_traits,
@@ -3633,6 +3666,7 @@ class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []> :
36333666 OptionalAttr<FlatSymbolRefAttr>:$callee,
36343667 Variadic<CIR_AnyType>:$arg_ops,
36353668 DefaultValuedAttr<CallingConv, "CallingConv::C">:$calling_conv,
3669+ DefaultValuedAttr<SideEffect, "SideEffect::All">:$side_effect,
36363670 ExtraFuncAttr:$extra_attrs,
36373671 OptionalAttr<ASTCallExprInterface>:$ast
36383672 );
@@ -3685,12 +3719,15 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
36853719 OpBuilder<(ins "mlir::SymbolRefAttr":$callee, "mlir::Type":$resType,
36863720 CArg<"mlir::ValueRange", "{}">:$operands,
36873721 CArg<"CallingConv", "CallingConv::C">:$callingConv,
3722+ CArg<"SideEffect", "SideEffect::All">:$sideEffect,
36883723 CArg<"mlir::UnitAttr", "{}">:$exception), [{
36893724 $_state.addOperands(operands);
36903725 if (callee)
36913726 $_state.addAttribute("callee", callee);
36923727 $_state.addAttribute("calling_conv",
36933728 CallingConvAttr::get($_builder.getContext(), callingConv));
3729+ $_state.addAttribute("side_effect",
3730+ SideEffectAttr::get($_builder.getContext(), sideEffect));
36943731 if (exception)
36953732 $_state.addAttribute("exception", exception);
36963733 if (resType && !isa<VoidType>(resType))
@@ -3702,13 +3739,16 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
37023739 "FuncType":$fn_type,
37033740 CArg<"mlir::ValueRange", "{}">:$operands,
37043741 CArg<"CallingConv", "CallingConv::C">:$callingConv,
3742+ CArg<"SideEffect", "SideEffect::All">:$sideEffect,
37053743 CArg<"mlir::UnitAttr", "{}">:$exception), [{
37063744 $_state.addOperands(ValueRange{ind_target});
37073745 $_state.addOperands(operands);
37083746 if (!fn_type.isVoid())
37093747 $_state.addTypes(fn_type.getReturnType());
37103748 $_state.addAttribute("calling_conv",
37113749 CallingConvAttr::get($_builder.getContext(), callingConv));
3750+ $_state.addAttribute("side_effect",
3751+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37123752 if (exception)
37133753 $_state.addAttribute("exception", exception);
37143754 // Create region placeholder for potential cleanups.
@@ -3751,7 +3791,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37513791 CArg<"mlir::ValueRange", "{}">:$operands,
37523792 CArg<"mlir::ValueRange", "{}">:$contOperands,
37533793 CArg<"mlir::ValueRange", "{}">:$landingPadOperands,
3754- CArg<"CallingConv", "CallingConv::C">:$callingConv), [{
3794+ CArg<"CallingConv", "CallingConv::C">:$callingConv,
3795+ CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
37553796 $_state.addOperands(operands);
37563797 if (callee)
37573798 $_state.addAttribute("callee", callee);
@@ -3760,6 +3801,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37603801
37613802 $_state.addAttribute("calling_conv",
37623803 CallingConvAttr::get($_builder.getContext(), callingConv));
3804+ $_state.addAttribute("side_effect",
3805+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37633806
37643807 // Handle branches
37653808 $_state.addOperands(contOperands);
@@ -3780,7 +3823,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37803823 CArg<"mlir::ValueRange", "{}">:$operands,
37813824 CArg<"mlir::ValueRange", "{}">:$contOperands,
37823825 CArg<"mlir::ValueRange", "{}">:$landingPadOperands,
3783- CArg<"CallingConv", "CallingConv::C">:$callingConv), [{
3826+ CArg<"CallingConv", "CallingConv::C">:$callingConv,
3827+ CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
37843828 ::llvm::SmallVector<mlir::Value, 4> finalCallOperands({ind_target});
37853829 finalCallOperands.append(operands.begin(), operands.end());
37863830 $_state.addOperands(finalCallOperands);
@@ -3790,6 +3834,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37903834
37913835 $_state.addAttribute("calling_conv",
37923836 CallingConvAttr::get($_builder.getContext(), callingConv));
3837+ $_state.addAttribute("side_effect",
3838+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37933839
37943840 // Handle branches
37953841 $_state.addOperands(contOperands);
@@ -4196,7 +4242,7 @@ def MemCpyInlineOp : CIR_MemOp<"memcpy_inline"> {
41964242 Given two CIR pointers, `src` and `dst`, `memcpy_inline` will copy `len`
41974243 bytes from the memory pointed by `src` to the memory pointed by `dst`.
41984244
4199- Unlike `cir.libc.memcpy`, this Op guarantees that no external functions
4245+ Unlike `cir.libc.memcpy`, this Op guarantees that no external functions
42004246 are called, and length of copied bytes is a constant.
42014247
42024248 Examples:
0 commit comments