@@ -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,
@@ -3624,6 +3657,7 @@ class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []> :
36243657 OptionalAttr<FlatSymbolRefAttr>:$callee,
36253658 Variadic<CIR_AnyType>:$arg_ops,
36263659 DefaultValuedAttr<CallingConv, "CallingConv::C">:$calling_conv,
3660+ DefaultValuedAttr<SideEffect, "SideEffect::All">:$side_effect,
36273661 ExtraFuncAttr:$extra_attrs,
36283662 OptionalAttr<ASTCallExprInterface>:$ast
36293663 );
@@ -3676,12 +3710,15 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
36763710 OpBuilder<(ins "mlir::SymbolRefAttr":$callee, "mlir::Type":$resType,
36773711 CArg<"mlir::ValueRange", "{}">:$operands,
36783712 CArg<"CallingConv", "CallingConv::C">:$callingConv,
3713+ CArg<"SideEffect", "SideEffect::All">:$sideEffect,
36793714 CArg<"mlir::UnitAttr", "{}">:$exception), [{
36803715 $_state.addOperands(operands);
36813716 if (callee)
36823717 $_state.addAttribute("callee", callee);
36833718 $_state.addAttribute("calling_conv",
36843719 CallingConvAttr::get($_builder.getContext(), callingConv));
3720+ $_state.addAttribute("side_effect",
3721+ SideEffectAttr::get($_builder.getContext(), sideEffect));
36853722 if (exception)
36863723 $_state.addAttribute("exception", exception);
36873724 if (resType && !isa<VoidType>(resType))
@@ -3693,13 +3730,16 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
36933730 "FuncType":$fn_type,
36943731 CArg<"mlir::ValueRange", "{}">:$operands,
36953732 CArg<"CallingConv", "CallingConv::C">:$callingConv,
3733+ CArg<"SideEffect", "SideEffect::All">:$sideEffect,
36963734 CArg<"mlir::UnitAttr", "{}">:$exception), [{
36973735 $_state.addOperands(ValueRange{ind_target});
36983736 $_state.addOperands(operands);
36993737 if (!fn_type.isVoid())
37003738 $_state.addTypes(fn_type.getReturnType());
37013739 $_state.addAttribute("calling_conv",
37023740 CallingConvAttr::get($_builder.getContext(), callingConv));
3741+ $_state.addAttribute("side_effect",
3742+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37033743 if (exception)
37043744 $_state.addAttribute("exception", exception);
37053745 // Create region placeholder for potential cleanups.
@@ -3742,7 +3782,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37423782 CArg<"mlir::ValueRange", "{}">:$operands,
37433783 CArg<"mlir::ValueRange", "{}">:$contOperands,
37443784 CArg<"mlir::ValueRange", "{}">:$landingPadOperands,
3745- CArg<"CallingConv", "CallingConv::C">:$callingConv), [{
3785+ CArg<"CallingConv", "CallingConv::C">:$callingConv,
3786+ CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
37463787 $_state.addOperands(operands);
37473788 if (callee)
37483789 $_state.addAttribute("callee", callee);
@@ -3751,6 +3792,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37513792
37523793 $_state.addAttribute("calling_conv",
37533794 CallingConvAttr::get($_builder.getContext(), callingConv));
3795+ $_state.addAttribute("side_effect",
3796+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37543797
37553798 // Handle branches
37563799 $_state.addOperands(contOperands);
@@ -3771,7 +3814,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37713814 CArg<"mlir::ValueRange", "{}">:$operands,
37723815 CArg<"mlir::ValueRange", "{}">:$contOperands,
37733816 CArg<"mlir::ValueRange", "{}">:$landingPadOperands,
3774- CArg<"CallingConv", "CallingConv::C">:$callingConv), [{
3817+ CArg<"CallingConv", "CallingConv::C">:$callingConv,
3818+ CArg<"SideEffect", "SideEffect::All">:$sideEffect), [{
37753819 ::llvm::SmallVector<mlir::Value, 4> finalCallOperands({ind_target});
37763820 finalCallOperands.append(operands.begin(), operands.end());
37773821 $_state.addOperands(finalCallOperands);
@@ -3781,6 +3825,8 @@ def TryCallOp : CIR_CallOp<"try_call",
37813825
37823826 $_state.addAttribute("calling_conv",
37833827 CallingConvAttr::get($_builder.getContext(), callingConv));
3828+ $_state.addAttribute("side_effect",
3829+ SideEffectAttr::get($_builder.getContext(), sideEffect));
37843830
37853831 // Handle branches
37863832 $_state.addOperands(contOperands);
@@ -4187,7 +4233,7 @@ def MemCpyInlineOp : CIR_MemOp<"memcpy_inline"> {
41874233 Given two CIR pointers, `src` and `dst`, `memcpy_inline` will copy `len`
41884234 bytes from the memory pointed by `src` to the memory pointed by `dst`.
41894235
4190- Unlike `cir.libc.memcpy`, this Op guarantees that no external functions
4236+ Unlike `cir.libc.memcpy`, this Op guarantees that no external functions
41914237 are called, and length of copied bytes is a constant.
41924238
41934239 Examples:
0 commit comments