[flang] Introduce FortranVariableOpInterface for ops creating variable
authorJean Perier <jperier@nvidia.com>
Wed, 19 Oct 2022 06:55:02 +0000 (08:55 +0200)
committerJean Perier <jperier@nvidia.com>
Wed, 19 Oct 2022 06:56:47 +0000 (08:56 +0200)
HLFIR will rely on certain operations to create SSA memory values
that correspond to a Fortran variable. They will hold bounds and type
parameters information as well as metadata (like Fortran attributes).

This patch adds an interface that for such operations so that Fortran
variable can be stored, manipulated, and queried regardless of what
created them. This is so far intended for fir.declare, hlfir.designate
and hlfir.associate operations.
It is added to FIR and not HLFIR because fir.declare needs it and it
does not itself needs any HLFIR concepts.

Unit tests for the interface methods will be added alongside
fir.declare in the next patch.

Differential Revision: https://reviews.llvm.org/D136151

flang/include/flang/Optimizer/Dialect/CMakeLists.txt
flang/include/flang/Optimizer/Dialect/FortranVariableInterface.h [new file with mode: 0644]
flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td [new file with mode: 0644]
flang/lib/Optimizer/Dialect/CMakeLists.txt
flang/lib/Optimizer/Dialect/FortranVariableInterface.cpp [new file with mode: 0644]

index 8946856..00d06cd 100644 (file)
@@ -12,6 +12,7 @@ mlir_tablegen(FIROps.h.inc -gen-op-decls)
 mlir_tablegen(FIROps.cpp.inc -gen-op-defs)
 mlir_tablegen(FIROpsTypes.h.inc --gen-typedef-decls)
 mlir_tablegen(FIROpsTypes.cpp.inc --gen-typedef-defs)
+add_mlir_interface(FortranVariableInterface)
 add_public_tablegen_target(FIROpsIncGen)
 
 set(LLVM_TARGET_DEFINITIONS CanonicalizationPatterns.td)
diff --git a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.h b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.h
new file mode 100644 (file)
index 0000000..0e0783a
--- /dev/null
@@ -0,0 +1,26 @@
+//===- FortranVariableInterface.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a set of interfaces for operations defining Fortran
+// variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_DIALECT_FORTRANVARIABLEINTERFACE_H
+#define FORTRAN_OPTIMIZER_DIALECT_FORTRANVARIABLEINTERFACE_H
+
+#include "flang/Optimizer/Dialect/FIRAttr.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/OpDefinition.h"
+
+namespace fir {
+#include "flang/Optimizer/Dialect/FortranVariableInterface.h.inc"
+} // namespace fir
+
+#endif // FORTRAN_OPTIMIZER_DIALECT_FORTRANVARIABLEINTERFACE_H
diff --git a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td
new file mode 100644 (file)
index 0000000..39e8c9a
--- /dev/null
@@ -0,0 +1,124 @@
+//===- FortranVariableInterface.td -------------------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an interface for operations defining Fortran variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRANVARIABLEINTERFACE
+#define FORTRANVARIABLEINTERFACE
+
+include "mlir/IR/OpBase.td"
+
+
+def FortranVariableOpInterface : OpInterface<"FortranVariableOpInterface"> {
+  let description = [{
+    Interface for operations that create Fortran like variables in order to
+    query about all their Fortran properties.
+  }];
+
+  let methods = [
+    InterfaceMethod<
+      /*desc=*/"Get the address produced by the definition",
+      /*retTy=*/"mlir::Value",
+      /*methodName=*/"getBase",
+      /*args=*/(ins),
+      /*methodBody=*/[{}],
+      /*defaultImplementation=*/[{
+        ConcreteOp op = mlir::cast<ConcreteOp>(this->getOperation());
+        return op.getResult();
+      }]
+    >,
+    InterfaceMethod<
+      /*desc=*/"Get Fortran attributes",
+      /*retTy=*/"llvm::Optional<fir::FortranVariableFlagsEnum>",
+      /*methodName=*/"getFortranAttrs",
+      /*args=*/(ins),
+      /*methodBody=*/[{}],
+      /*defaultImplementation=*/[{
+        ConcreteOp op = mlir::cast<ConcreteOp>(this->getOperation());
+        return op.getFortran_attrs();
+      }]
+    >,
+    InterfaceMethod<
+      /*desc=*/"Get the shape of the variable",
+      /*retTy=*/"llvm::Optional<mlir::Value>",
+      /*methodName=*/"getShape",
+      /*args=*/(ins),
+      /*methodBody=*/[{}],
+      /*defaultImplementation=*/[{
+        ConcreteOp op = mlir::cast<ConcreteOp>(this->getOperation());
+        return op.getShape();
+      }]
+    >,
+    InterfaceMethod<
+      /*desc=*/"Get explicit type parameters of the variable",
+      /*retTy=*/"mlir::OperandRange",
+      /*methodName=*/"getExplicitTypeParams",
+      /*args=*/(ins),
+      /*methodBody=*/[{}],
+      /*defaultImplementation=*/[{
+        ConcreteOp op = mlir::cast<ConcreteOp>(this->getOperation());
+        return op.getTypeparams();
+      }]
+    >,
+  ];
+
+  let extraClassDeclaration = [{
+
+    /// Get the sequence type or scalar value type corresponding to this
+    /// variable.
+    mlir::Type getElementOrSequenceType() {
+      return fir::unwrapPassByRefType(getBase().getType());
+    }
+
+    /// Get the scalar value type corresponding to this variable.
+    mlir::Type getElementType() {
+      return fir::unwrapSequenceType(getElementOrSequenceType());
+    }
+
+    /// Is the variable an array ?
+    bool isArray() {
+      return getElementOrSequenceType().isa<fir::SequenceType>();
+    }
+
+    /// Is this variable a Fortran pointer ?
+    bool isPointer() {
+      auto attrs = getFortranAttrs();
+      return attrs && bitEnumContainsAny(*attrs,
+                        fir::FortranVariableFlagsEnum::pointer);
+    }
+
+    /// Is this variable a Fortran allocatable ?
+    bool isAllocatable() {
+      auto attrs = getFortranAttrs();
+      return attrs && bitEnumContainsAny(*attrs,
+                        fir::FortranVariableFlagsEnum::allocatable);
+    }
+
+    /// Is this a Fortran character variable ?
+    bool isCharacter() {
+      return getElementType().isa<fir::CharacterType>();
+    }
+
+    /// Is this a Fortran character variable with an explicit length ?
+    bool hasExplicitCharLen() {
+      return isCharacter() && !getExplicitTypeParams().empty();
+    }
+
+    /// Return the length of explicit length character variable.
+    mlir::Value getExplicitCharLen() {
+      assert(hasExplicitCharLen() && "must be an explicit length character");
+      return getExplicitTypeParams()[0];
+    }
+
+  }];
+
+}
+
+#endif  // FORTRANVARIABLEINTERFACE
index 829a119..8f82e92 100644 (file)
@@ -3,6 +3,7 @@ add_flang_library(FIRDialect
   FIRDialect.cpp
   FIROps.cpp
   FIRType.cpp
+  FortranVariableInterface.cpp
   Inliner.cpp
 
   DEPENDS
diff --git a/flang/lib/Optimizer/Dialect/FortranVariableInterface.cpp b/flang/lib/Optimizer/Dialect/FortranVariableInterface.cpp
new file mode 100644 (file)
index 0000000..0091a50
--- /dev/null
@@ -0,0 +1,17 @@
+//===-- FortranVariableInterface.cpp.cpp ----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
+
+namespace fir {
+#include "flang/Optimizer/Dialect/FortranVariableInterface.cpp.inc"
+}