diff options
| author | Eric Schweitz <eschweitz@nvidia.com> | 2021-09-30 11:04:02 +0200 |
|---|---|---|
| committer | Valentin Clement <clementval@gmail.com> | 2021-09-30 11:05:13 +0200 |
| commit | 8014b28dcfa17532bdff31358c1c5aa00e76452e (patch) | |
| tree | 2f3729c5929df4ed0154677d96bfdc41c5567773 | |
| parent | 1f69dc08454725d95e9dbf6e299afc91e44506f5 (diff) | |
| download | llvm-8014b28dcfa17532bdff31358c1c5aa00e76452e.zip llvm-8014b28dcfa17532bdff31358c1c5aa00e76452e.tar.gz llvm-8014b28dcfa17532bdff31358c1c5aa00e76452e.tar.bz2 | |
[fir] Update fir.alloca op
Update the fir.alloca operation.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D110415
Co-authored-by: Jean Perier <jperier@nvidia.com>
Co-authored-by: Valentin Clement <clementval@gmail.com>
| -rw-r--r-- | flang/include/flang/Optimizer/Dialect/FIROps.td | 55 | ||||
| -rw-r--r-- | flang/lib/Optimizer/Dialect/FIROps.cpp | 67 |
2 files changed, 93 insertions, 29 deletions
diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 8b40637..bbe8d9a 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -212,8 +212,8 @@ class fir_AllocatableOp<string mnemonic, Resource resource, // 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 @@ -275,19 +275,46 @@ def fir_AllocaOp : 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(); } }]; } @@ -3228,9 +3255,7 @@ def fir_GlobalOp : fir_Op<"global", [IsolatedFromAbove, Symbol]> { } /// 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()); } diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 4a266fe..0f2a469a 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -60,15 +60,6 @@ static bool verifyInType(mlir::Type inType, 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) { @@ -155,22 +146,70 @@ static void printAllocatableOp(mlir::OpAsmPrinter &p, OP &op) { // 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 //===----------------------------------------------------------------------===// |
