================ @@ -115,6 +115,149 @@ def ConstantOp : CIR_Op<"const", let hasFolder = 1; } +//===----------------------------------------------------------------------===// +// AllocaOp +//===----------------------------------------------------------------------===// + +class AllocaTypesMatchWith<string summary, string lhsArg, string rhsArg, + string transform, string comparator = "std::equal_to<>()"> + : PredOpTrait<summary, CPred< + comparator # "(" # + !subst("$_self", "$" # lhsArg # ".getType()", transform) # + ", $" # rhsArg # ")">> { + string lhs = lhsArg; + string rhs = rhsArg; + string transformer = transform; +} + +def AllocaOp : CIR_Op<"alloca", [ + AllocaTypesMatchWith<"'allocaType' matches pointee type of 'addr'", + "addr", "allocaType", + "cast<PointerType>($_self).getPointee()">, + DeclareOpInterfaceMethods<PromotableAllocationOpInterface>]> { + let summary = "Defines a scope-local variable"; + let description = [{ + The `cir.alloca` operation defines a scope-local variable. + + The presence `init` attribute indicates that the local variable represented + by this alloca was originally initialized in C/C++ source code. In such + cases, the first use contains the initialization (a cir.store, a cir.call + to a ctor, etc). + + The presence of the `const` attribute indicates that the local variable is + declared with C/C++ `const` keyword. + + The `dynAllocSize` specifies the size to dynamically allocate on the stack + and ignores the allocation size based on the original type. This is useful + when handling VLAs and is omitted when declaring regular local variables. + + The result type is a pointer to the input's type. + + Example: + + ```mlir + // int count = 3; + %0 = cir.alloca i32, !cir.ptr<i32>, ["count", init] {alignment = 4 : i64} + + // int *ptr; + %1 = cir.alloca !cir.ptr<i32>, !cir.ptr<!cir.ptr<i32>>, ["ptr"] {alignment = 8 : i64} + ... + ``` + }]; + + let arguments = (ins + Optional<PrimitiveInt>:$dynAllocSize, + TypeAttr:$allocaType, + StrAttr:$name, + UnitAttr:$init, + UnitAttr:$constant, + ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$alignment, + OptionalAttr<ArrayAttr>:$annotations + ); + + let results = (outs Res<CIR_PointerType, "", + [MemAlloc<AutomaticAllocationScopeResource>]>:$addr); + + let skipDefaultBuilders = 1; + let builders = [ + OpBuilder<(ins "mlir::Type":$addr, "mlir::Type":$allocaType, + "llvm::StringRef":$name, + "mlir::IntegerAttr":$alignment)>, + + OpBuilder<(ins "mlir::Type":$addr, + "mlir::Type":$allocaType, + "llvm::StringRef":$name, + "mlir::IntegerAttr":$alignment, + "mlir::Value":$dynAllocSize), + [{ + if (dynAllocSize) + $_state.addOperands(dynAllocSize); + build($_builder, $_state, addr, allocaType, name, alignment); + }]> + ]; + + let extraClassDeclaration = [{ + // Whether the alloca input type is a pointer. + bool isPointerType() { return ::mlir::isa<::cir::PointerType>(getAllocaType()); } + + bool isDynamic() { return (bool)getDynAllocSize(); } + }]; + + let assemblyFormat = [{ + $allocaType `,` qualified(type($addr)) `,` + ($dynAllocSize^ `:` type($dynAllocSize) `,`)? + `[` $name + (`,` `init` $init^)? + (`,` `const` $constant^)? + `]` + ($annotations^)? attr-dict + }]; + + let hasVerifier = 0; +} + +//===----------------------------------------------------------------------===// +// LoadOp +//===----------------------------------------------------------------------===// + +def LoadOp : CIR_Op<"load", [ + TypesMatchWith<"type of 'result' matches pointee type of 'addr'", + "addr", "result", + "cast<PointerType>($_self).getPointee()">, + DeclareOpInterfaceMethods<PromotableMemOpInterface>]> { + + let summary = "Load value from memory adddress"; + let description = [{ + `cir.load` reads a value (lvalue to rvalue conversion) given an address + backed up by a `cir.ptr` type. A unit attribute `deref` can be used to + mark the resulting value as used by another operation to dereference + a pointer. A unit attribute `volatile` can be used to indicate a volatile + loading. Load can be marked atomic by using `atomic(<mem_order>)`. + + `align` can be used to specify an alignment that's different from the + default, which is computed from `result`'s type ABI data layout. + + Example: + + ```mlir + + // Read from local variable, address in %0. + %1 = cir.load %0 : !cir.ptr<i32>, i32 + ``` + }]; + + let arguments = (ins Arg<CIR_PointerType, "the address to load from", + [MemRead]>:$addr + ); ---------------- bcardosolopes wrote:
The closing paren probably belongs in the line above? https://github.com/llvm/llvm-project/pull/128792 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits