[flang-commits] [flang] 241cb29 - [flang] add hlfir.null to implement NULL()

Jean Perier via flang-commits flang-commits at lists.llvm.org
Fri Jan 6 00:57:43 PST 2023


Author: Jean Perier
Date: 2023-01-06T09:57:15+01:00
New Revision: 241cb29187569274bbf327478e1665ff76528878

URL: https://github.com/llvm/llvm-project/commit/241cb29187569274bbf327478e1665ff76528878
DIFF: https://github.com/llvm/llvm-project/commit/241cb29187569274bbf327478e1665ff76528878.diff

LOG: [flang] add hlfir.null to implement NULL()

In HLFIR, the address of a Fortran entity in lowering must be defined
by an operation that has the FortranVariableOpInterface (it is a sanity
requirement to ensure that the mlir::Value propagated in certain places
of lowering can be reasoned about).
fir.zero_bits does not have this interface and it makes little sense to
add it since it can "zero initialize" more types than just addresses.

Creating an hlfir.declare for null addresses is a bit too much (what
would be the name), and it would be noisy in the IR.

Instead add a small hlfir.null operation whose codegen is simply a
replacement by fir.zero_bits.

It may also later help dealing with the NULL(MOLD) cases in a nicer
way (the current lowering of this uses special handling it).

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

Added: 
    flang/test/HLFIR/null-codegen.fir
    flang/test/HLFIR/null.fir

Modified: 
    flang/include/flang/Optimizer/HLFIR/HLFIROps.td
    flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
    flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index b5e2a4493dcbf..88acf78bf61a1 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -457,4 +457,29 @@ def hlfir_ApplyOp : hlfir_Op<"apply", [NoMemoryEffect, AttrSizedOperandSegments]
   ];
 }
 
+def hlfir_NullOp : hlfir_Op<"null", [NoMemoryEffect, fir_FortranVariableOpInterface]> {
+  let summary = "create a NULL() address";
+
+  let description = [{
+    Create a NULL() address.
+    So far is not intended to represent NULL(MOLD).
+  }];
+
+  let results = (outs AnyFortranVariable);
+  let builders = [OpBuilder<(ins)>];
+
+  let assemblyFormat = "type(results) attr-dict";
+  let extraClassDeclaration = [{
+    // Implement FortranVariableInterface interface.
+    std::optional<fir::FortranVariableFlagsEnum> getFortranAttrs() const {
+      return std::nullopt;
+    }
+    mlir::Value getShape() const {return mlir::Value{};}
+    mlir::OperandRange getExplicitTypeParams() const {
+      // Return an empty range.
+      return {(*this)->getOperands().begin(), (*this)->getOperands().begin()};
+    }
+  }];
+}
+
 #endif // FORTRAN_DIALECT_HLFIR_OPS

diff  --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 654414ac8603f..ba62f511e5348 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -503,5 +503,15 @@ void hlfir::ApplyOp::build(mlir::OpBuilder &builder,
   build(builder, odsState, resultType, expr, indices, typeparams);
 }
 
+//===----------------------------------------------------------------------===//
+// NullOp
+//===----------------------------------------------------------------------===//
+
+void hlfir::NullOp::build(mlir::OpBuilder &builder,
+                          mlir::OperationState &odsState) {
+  return build(builder, odsState,
+               fir::ReferenceType::get(builder.getNoneType()));
+}
+
 #define GET_OP_CLASSES
 #include "flang/Optimizer/HLFIR/HLFIROps.cpp.inc"

diff  --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index a5c31b3e09395..561f3e3c07b6d 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -291,6 +291,18 @@ class NoReassocOpConversion
   }
 };
 
+class NullOpConversion : public mlir::OpRewritePattern<hlfir::NullOp> {
+public:
+  explicit NullOpConversion(mlir::MLIRContext *ctx) : OpRewritePattern{ctx} {}
+
+  mlir::LogicalResult
+  matchAndRewrite(hlfir::NullOp nullop,
+                  mlir::PatternRewriter &rewriter) const override {
+    rewriter.replaceOpWithNewOp<fir::ZeroOp>(nullop, nullop.getType());
+    return mlir::success();
+  }
+};
+
 class ConvertHLFIRtoFIR
     : public hlfir::impl::ConvertHLFIRtoFIRBase<ConvertHLFIRtoFIR> {
 public:
@@ -302,8 +314,9 @@ class ConvertHLFIRtoFIR
     auto module = this->getOperation();
     auto *context = &getContext();
     mlir::RewritePatternSet patterns(context);
-    patterns.insert<AssignOpConversion, DeclareOpConversion,
-                    DesignateOpConversion, NoReassocOpConversion>(context);
+    patterns
+        .insert<AssignOpConversion, DeclareOpConversion, DesignateOpConversion,
+                NoReassocOpConversion, NullOpConversion>(context);
     mlir::ConversionTarget target(*context);
     target.addIllegalDialect<hlfir::hlfirDialect>();
     target.markUnknownOpDynamicallyLegal(

diff  --git a/flang/test/HLFIR/null-codegen.fir b/flang/test/HLFIR/null-codegen.fir
new file mode 100644
index 0000000000000..4568c45e92270
--- /dev/null
+++ b/flang/test/HLFIR/null-codegen.fir
@@ -0,0 +1,9 @@
+// Test hlfir.null code generation to FIR
+
+// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
+
+func.func @test() {
+  // CHECK: fir.zero_bits !fir.ref<none>
+  %0 = hlfir.null !fir.ref<none>
+  return
+}

diff  --git a/flang/test/HLFIR/null.fir b/flang/test/HLFIR/null.fir
new file mode 100644
index 0000000000000..4614f2bc25e5d
--- /dev/null
+++ b/flang/test/HLFIR/null.fir
@@ -0,0 +1,9 @@
+// Test hlfir.null operation parse, verify (no errors), and unparse.
+
+// RUN: fir-opt %s | fir-opt | FileCheck %s
+
+func.func @test() {
+  // CHECK: hlfir.null !fir.ref<none>
+  %0 = hlfir.null !fir.ref<none>
+  return
+}


        


More information about the flang-commits mailing list