aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Schweitz <eschweitz@nvidia.com>2021-09-30 11:04:02 +0200
committerValentin Clement <clementval@gmail.com>2021-09-30 11:05:13 +0200
commit8014b28dcfa17532bdff31358c1c5aa00e76452e (patch)
tree2f3729c5929df4ed0154677d96bfdc41c5567773
parent1f69dc08454725d95e9dbf6e299afc91e44506f5 (diff)
downloadllvm-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.td55
-rw-r--r--flang/lib/Optimizer/Dialect/FIROps.cpp67
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
//===----------------------------------------------------------------------===//