// Memory SSA operations
//===----------------------------------------------------------------------===//
-def fir_AllocaOp :
- fir_AllocatableOp<"alloca", AutomaticAllocationScopeResource> {
+def fir_AllocaOp : fir_Op<"alloca", [AttrSizedOperandSegments,
+ MemoryEffects<[MemAlloc<AutomaticAllocationScopeResource>]>]> {
let summary = "allocate storage for a temporary on the stack given a type";
let description = [{
This primitive operation is used to allocate an object on the stack. A
whether the procedure is recursive or not.
}];
+ let arguments = (ins
+ TypeAttr:$in_type,
+ OptionalAttr<StrAttr>:$uniq_name,
+ OptionalAttr<StrAttr>:$bindc_name,
+ Variadic<AnyIntegerType>:$typeparams,
+ Variadic<AnyIntegerType>:$shape
+ );
+
let results = (outs fir_ReferenceType);
- let verifier = allocVerify#[{
- mlir::Type outType = getType();
- if (!outType.isa<fir::ReferenceType>())
- return emitOpError("must be a !fir.ref type");
- if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
- return emitOpError("cannot allocate !fir.box of unknown rank or type");
- return mlir::success();
- }];
+ let parser =
+ "return parseAllocatableOp(wrapAllocaResultType, parser, result);";
+ let printer = "printAllocatableOp(p, (*this));";
+
+ let builders = [
+ OpBuilder<(ins "mlir::Type":$inType, "llvm::StringRef":$uniqName,
+ "llvm::StringRef":$bindcName, CArg<"mlir::ValueRange", "{}">:$typeparams,
+ CArg<"mlir::ValueRange", "{}">:$shape,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>,
+ OpBuilder<(ins "mlir::Type":$inType, "llvm::StringRef":$uniqName,
+ CArg<"mlir::ValueRange", "{}">:$typeparams,
+ CArg<"mlir::ValueRange", "{}">:$shape,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>,
+ OpBuilder<(ins "mlir::Type":$in_type,
+ CArg<"mlir::ValueRange", "{}">:$typeparams,
+ CArg<"mlir::ValueRange", "{}">:$shape,
+ CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>];
- let extraClassDeclaration = extraAllocClassDeclaration#[{
- static mlir::Type wrapResultType(mlir::Type intype);
+ let verifier = [{ return ::verify(*this); }];
+
+ let extraClassDeclaration = [{
+ mlir::Type getAllocatedType();
+ bool hasLenParams() { return !typeparams().empty(); }
+ bool hasShapeOperands() { return !shape().empty(); }
+ unsigned numLenParams() { return typeparams().size(); }
+ operand_range getLenParams() { return typeparams(); }
+ unsigned numShapeOperands() { return shape().size(); }
+ operand_range getShapeOperands() { return shape(); }
+ static mlir::Type getRefTy(mlir::Type ty);
+ mlir::Type getInType() { return in_type(); }
}];
}
}
/// The semantic type of the global
- mlir::Type resultType() {
- return fir::AllocaOp::wrapResultType(getType());
- }
+ mlir::Type resultType();
/// Return the initializer attribute if it exists, or a null attribute.
Attribute getValueOrNull() { return initVal().getValueOr(Attribute()); }
return false;
}
-static bool verifyRecordLenParams(mlir::Type inType, unsigned numLenParams) {
- if (numLenParams > 0) {
- if (auto rt = inType.dyn_cast<fir::RecordType>())
- return numLenParams != rt.getNumLenParams();
- return true;
- }
- return false;
-}
-
static bool verifyTypeParamCount(mlir::Type inType, unsigned numParams) {
auto ty = fir::unwrapSequenceType(inType);
if (numParams > 0) {
// AllocaOp
//===----------------------------------------------------------------------===//
-mlir::Type fir::AllocaOp::getAllocatedType() {
- return getType().cast<ReferenceType>().getEleTy();
-}
-
/// Create a legal memory reference as return type
-mlir::Type fir::AllocaOp::wrapResultType(mlir::Type intype) {
+static mlir::Type wrapAllocaResultType(mlir::Type intype) {
// FIR semantics: memory references to memory references are disallowed
if (intype.isa<ReferenceType>())
return {};
return ReferenceType::get(intype);
}
+mlir::Type fir::AllocaOp::getAllocatedType() {
+ return getType().cast<ReferenceType>().getEleTy();
+}
+
mlir::Type fir::AllocaOp::getRefTy(mlir::Type ty) {
return ReferenceType::get(ty);
}
+void fir::AllocaOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Type inType,
+ llvm::StringRef uniqName, mlir::ValueRange typeparams,
+ mlir::ValueRange shape,
+ llvm::ArrayRef<mlir::NamedAttribute> attributes) {
+ auto nameAttr = builder.getStringAttr(uniqName);
+ build(builder, result, wrapAllocaResultType(inType), inType, nameAttr, {},
+ typeparams, shape);
+ result.addAttributes(attributes);
+}
+
+void fir::AllocaOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Type inType,
+ llvm::StringRef uniqName, llvm::StringRef bindcName,
+ mlir::ValueRange typeparams, mlir::ValueRange shape,
+ llvm::ArrayRef<mlir::NamedAttribute> attributes) {
+ auto nameAttr =
+ uniqName.empty() ? mlir::StringAttr{} : builder.getStringAttr(uniqName);
+ auto bindcAttr =
+ bindcName.empty() ? mlir::StringAttr{} : builder.getStringAttr(bindcName);
+ build(builder, result, wrapAllocaResultType(inType), inType, nameAttr,
+ bindcAttr, typeparams, shape);
+ result.addAttributes(attributes);
+}
+
+void fir::AllocaOp::build(mlir::OpBuilder &builder,
+ mlir::OperationState &result, mlir::Type inType,
+ mlir::ValueRange typeparams, mlir::ValueRange shape,
+ llvm::ArrayRef<mlir::NamedAttribute> attributes) {
+ build(builder, result, wrapAllocaResultType(inType), inType, {}, {},
+ typeparams, shape);
+ result.addAttributes(attributes);
+}
+
+static mlir::LogicalResult verify(fir::AllocaOp &op) {
+ llvm::SmallVector<llvm::StringRef> visited;
+ if (verifyInType(op.getInType(), visited, op.numShapeOperands()))
+ return op.emitOpError("invalid type for allocation");
+ if (verifyTypeParamCount(op.getInType(), op.numLenParams()))
+ return op.emitOpError("LEN params do not correspond to type");
+ mlir::Type outType = op.getType();
+ if (!outType.isa<fir::ReferenceType>())
+ return op.emitOpError("must be a !fir.ref type");
+ if (fir::isa_unknown_size_box(fir::dyn_cast_ptrEleTy(outType)))
+ return op.emitOpError("cannot allocate !fir.box of unknown rank or type");
+ return mlir::success();
+}
+
//===----------------------------------------------------------------------===//
// AllocMemOp
//===----------------------------------------------------------------------===//