[flang] Add High level Fortran IR dialect
This patch adds the basic dialect definition of the HLFIR dialect that was described in https://reviews.llvm.org/D134285. It adds the definition of the hlfir.expr type and related tests so that it can be verified that the dialect is properly hooked up by the tools. Operations will be added as progress is made in the expression lowering update. Differential Revision: https://reviews.llvm.org/D136328
This commit is contained in:
parent
a0549ee2a3
commit
451b1b1ffb
|
@ -1,3 +1,4 @@
|
||||||
add_subdirectory(CodeGen)
|
add_subdirectory(CodeGen)
|
||||||
add_subdirectory(Dialect)
|
add_subdirectory(Dialect)
|
||||||
|
add_subdirectory(HLFIR)
|
||||||
add_subdirectory(Transforms)
|
add_subdirectory(Transforms)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
set(LLVM_TARGET_DEFINITIONS HLFIROpBase.td)
|
||||||
|
mlir_tablegen(HLFIRTypes.h.inc -gen-typedef-decls)
|
||||||
|
mlir_tablegen(HLFIRTypes.cpp.inc -gen-typedef-defs)
|
||||||
|
mlir_tablegen(HLFIRDialect.h.inc -gen-dialect-decls -dialect=hlfir)
|
||||||
|
mlir_tablegen(HLFIRDialect.cpp.inc -gen-dialect-defs -dialect=hlfir)
|
||||||
|
mlir_tablegen(HLFIRAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=hlfir)
|
||||||
|
mlir_tablegen(HLFIRAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=hlfir)
|
||||||
|
add_public_tablegen_target(HLFIROpsIncGen)
|
|
@ -0,0 +1,27 @@
|
||||||
|
//===- HLFIRDialect.h - High Level Fortran IR dialect -----------*- 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 defines the HLFIR dialect that models Fortran expressions and
|
||||||
|
// assignments without requiring storage allocation and manipulations.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H
|
||||||
|
#define FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H
|
||||||
|
|
||||||
|
#include "mlir/IR/Dialect.h"
|
||||||
|
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRDialect.h.inc"
|
||||||
|
|
||||||
|
#define GET_TYPEDEF_CLASSES
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRTypes.h.inc"
|
||||||
|
|
||||||
|
#define GET_ATTRDEF_CLASSES
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRAttributes.h.inc"
|
||||||
|
|
||||||
|
#endif // FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H
|
|
@ -0,0 +1,73 @@
|
||||||
|
//===-- HLFIROpBase.td - HLFIR dialect base definitions ----*- 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// Definition of the HLFIR dialect and core hlfir.expr type
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef FORTRAN_DIALECT_HLFIR_OP_BASE
|
||||||
|
#define FORTRAN_DIALECT_HLFIR_OP_BASE
|
||||||
|
|
||||||
|
include "mlir/IR/AttrTypeBase.td"
|
||||||
|
include "mlir/IR/OpBase.td"
|
||||||
|
|
||||||
|
def hlfir_Dialect : Dialect {
|
||||||
|
let name = "hlfir";
|
||||||
|
|
||||||
|
let summary = "High Level Fortran IR.";
|
||||||
|
|
||||||
|
let description = [{
|
||||||
|
This dialect models Fortran expressions and assignments without requiring
|
||||||
|
the allocation and manipulation of temporary storage.
|
||||||
|
It allows running high level optimization passes and is rather
|
||||||
|
straightforward to generate from Fortran expressions and assignments.
|
||||||
|
|
||||||
|
It is not a complete implementation of Fortran, for constructs and lower
|
||||||
|
level operations, FIR should be used directly.
|
||||||
|
|
||||||
|
A bufferization pass transforms hlfir.expr values into FIR temporary in
|
||||||
|
memory, and its translation pass to FIR translates high level operations
|
||||||
|
into sequence of lower level FIR operations operating on memory.
|
||||||
|
}];
|
||||||
|
|
||||||
|
let useDefaultTypePrinterParser = 1;
|
||||||
|
let cppNamespace = "hlfir";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def hlfir_ExprType : TypeDef<hlfir_Dialect, "Expr"> {
|
||||||
|
let mnemonic = "expr";
|
||||||
|
let summary = "The type of an array, character, or derived type Fortran expression";
|
||||||
|
|
||||||
|
let description = [{
|
||||||
|
Abstract value type for Fortran arrays, characters and derived types.
|
||||||
|
The rank cannot be assumed, and empty shape means that the expression is a scalar.
|
||||||
|
When the element type is a derived type, the polymorphic flag may be set to true
|
||||||
|
to indicate that the expression dynamic type can differ from its static type.
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
let parameters = (ins
|
||||||
|
ArrayRefParameter<"int64_t", "expression shape">:$shape,
|
||||||
|
"mlir::Type":$elementType,
|
||||||
|
"bool":$polymorphic
|
||||||
|
);
|
||||||
|
|
||||||
|
let extraClassDeclaration = [{
|
||||||
|
using Shape = llvm::SmallVector<int64_t>;
|
||||||
|
mlir::Type getEleTy() const {return getElementType();}
|
||||||
|
bool isArray() const { return !getShape().empty(); }
|
||||||
|
bool isPolymorphic() const { return getPolymorphic(); }
|
||||||
|
}];
|
||||||
|
|
||||||
|
let hasCustomAssemblyFormat = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FORTRAN_DIALECT_HLFIR_OP_BASE
|
|
@ -14,6 +14,7 @@
|
||||||
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
|
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
|
||||||
|
|
||||||
#include "flang/Optimizer/Dialect/FIRDialect.h"
|
#include "flang/Optimizer/Dialect/FIRDialect.h"
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
|
||||||
#include "mlir/Conversion/Passes.h"
|
#include "mlir/Conversion/Passes.h"
|
||||||
#include "mlir/Dialect/Affine/Passes.h"
|
#include "mlir/Dialect/Affine/Passes.h"
|
||||||
#include "mlir/InitAllDialects.h"
|
#include "mlir/InitAllDialects.h"
|
||||||
|
@ -25,11 +26,11 @@
|
||||||
namespace fir::support {
|
namespace fir::support {
|
||||||
|
|
||||||
#define FLANG_NONCODEGEN_DIALECT_LIST \
|
#define FLANG_NONCODEGEN_DIALECT_LIST \
|
||||||
mlir::AffineDialect, FIROpsDialect, mlir::acc::OpenACCDialect, \
|
mlir::AffineDialect, FIROpsDialect, hlfir::hlfirDialect, \
|
||||||
mlir::omp::OpenMPDialect, mlir::scf::SCFDialect, \
|
mlir::acc::OpenACCDialect, mlir::omp::OpenMPDialect, \
|
||||||
mlir::arith::ArithDialect, mlir::cf::ControlFlowDialect, \
|
mlir::scf::SCFDialect, mlir::arith::ArithDialect, \
|
||||||
mlir::func::FuncDialect, mlir::vector::VectorDialect, \
|
mlir::cf::ControlFlowDialect, mlir::func::FuncDialect, \
|
||||||
mlir::math::MathDialect
|
mlir::vector::VectorDialect, mlir::math::MathDialect
|
||||||
|
|
||||||
// The definitive list of dialects used by flang.
|
// The definitive list of dialects used by flang.
|
||||||
#define FLANG_DIALECT_LIST \
|
#define FLANG_DIALECT_LIST \
|
||||||
|
|
|
@ -17,6 +17,7 @@ add_flang_library(flangFrontend
|
||||||
FIRDialect
|
FIRDialect
|
||||||
FIRSupport
|
FIRSupport
|
||||||
FIROptTransformsPassIncGen
|
FIROptTransformsPassIncGen
|
||||||
|
HLFIRDialect
|
||||||
MLIRIR
|
MLIRIR
|
||||||
${dialect_libs}
|
${dialect_libs}
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ add_flang_library(flangFrontend
|
||||||
FIRBuilder
|
FIRBuilder
|
||||||
FIRCodeGen
|
FIRCodeGen
|
||||||
FIRTransforms
|
FIRTransforms
|
||||||
|
HLFIRDialect
|
||||||
MLIRTransforms
|
MLIRTransforms
|
||||||
MLIRLLVMToLLVMIRTranslation
|
MLIRLLVMToLLVMIRTranslation
|
||||||
MLIRSCFToControlFlow
|
MLIRSCFToControlFlow
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
add_subdirectory(Builder)
|
add_subdirectory(Builder)
|
||||||
add_subdirectory(CodeGen)
|
add_subdirectory(CodeGen)
|
||||||
add_subdirectory(Dialect)
|
add_subdirectory(Dialect)
|
||||||
|
add_subdirectory(HLFIR)
|
||||||
add_subdirectory(Support)
|
add_subdirectory(Support)
|
||||||
add_subdirectory(Transforms)
|
add_subdirectory(Transforms)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
|
||||||
|
|
||||||
|
add_flang_library(HLFIRDialect
|
||||||
|
HLFIRDialect.cpp
|
||||||
|
|
||||||
|
DEPENDS
|
||||||
|
FIRDialect
|
||||||
|
HLFIROpsIncGen
|
||||||
|
${dialect_libs}
|
||||||
|
|
||||||
|
LINK_LIBS
|
||||||
|
FIRDialect
|
||||||
|
MLIRIR
|
||||||
|
${dialect_libs}
|
||||||
|
|
||||||
|
LINK_COMPONENTS
|
||||||
|
AsmParser
|
||||||
|
AsmPrinter
|
||||||
|
Remarks
|
||||||
|
)
|
|
@ -0,0 +1,72 @@
|
||||||
|
//===-- HLFIRDialect.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/HLFIR/HLFIRDialect.h"
|
||||||
|
#include "mlir/IR/Builders.h"
|
||||||
|
#include "mlir/IR/BuiltinTypes.h"
|
||||||
|
#include "mlir/IR/DialectImplementation.h"
|
||||||
|
#include "mlir/IR/Matchers.h"
|
||||||
|
#include "mlir/IR/OpImplementation.h"
|
||||||
|
#include "llvm/ADT/TypeSwitch.h"
|
||||||
|
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRDialect.cpp.inc"
|
||||||
|
|
||||||
|
#define GET_TYPEDEF_CLASSES
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRTypes.cpp.inc"
|
||||||
|
|
||||||
|
#define GET_ATTRDEF_CLASSES
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRAttributes.cpp.inc"
|
||||||
|
|
||||||
|
void hlfir::hlfirDialect::initialize() {
|
||||||
|
addTypes<
|
||||||
|
#define GET_TYPEDEF_LIST
|
||||||
|
#include "flang/Optimizer/HLFIR/HLFIRTypes.cpp.inc"
|
||||||
|
>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// `expr` `<` `*` | bounds (`x` bounds)* `:` type [`?`] `>`
|
||||||
|
// bounds ::= `?` | int-lit
|
||||||
|
mlir::Type hlfir::ExprType::parse(mlir::AsmParser &parser) {
|
||||||
|
if (parser.parseLess())
|
||||||
|
return {};
|
||||||
|
ExprType::Shape shape;
|
||||||
|
if (parser.parseOptionalStar()) {
|
||||||
|
if (parser.parseDimensionList(shape, /*allowDynamic=*/true))
|
||||||
|
return {};
|
||||||
|
} else if (parser.parseColon()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
mlir::Type eleTy;
|
||||||
|
if (parser.parseType(eleTy))
|
||||||
|
return {};
|
||||||
|
const bool polymorphic = mlir::succeeded(parser.parseOptionalQuestion());
|
||||||
|
if (parser.parseGreater())
|
||||||
|
return {};
|
||||||
|
return ExprType::get(parser.getContext(), shape, eleTy, polymorphic);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hlfir::ExprType::print(mlir::AsmPrinter &printer) const {
|
||||||
|
auto shape = getShape();
|
||||||
|
printer << '<';
|
||||||
|
if (shape.size()) {
|
||||||
|
for (const auto &b : shape) {
|
||||||
|
if (b >= 0)
|
||||||
|
printer << b << 'x';
|
||||||
|
else
|
||||||
|
printer << "?x";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printer << getEleTy();
|
||||||
|
if (isPolymorphic())
|
||||||
|
printer << '?';
|
||||||
|
printer << '>';
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Test the HLFIR Expr type
|
||||||
|
// Parse types and check that we can reparse what we print.
|
||||||
|
// RUN: fir-opt --split-input-file %s | fir-opt --split-input-file | FileCheck %s
|
||||||
|
|
||||||
|
// Scalar expression types
|
||||||
|
func.func private @scalar01() -> !hlfir.expr<!fir.char<1,?>>
|
||||||
|
func.func private @scalar02() -> !hlfir.expr<!fir.char<2,10>>
|
||||||
|
func.func private @scalar03() -> !hlfir.expr<!fir.type<derived{f:f32}>>
|
||||||
|
// CHECK-LABEL: func.func private @scalar01() -> !hlfir.expr<!fir.char<1,?>>
|
||||||
|
// CHECK-LABEL: func.func private @scalar02() -> !hlfir.expr<!fir.char<2,10>>
|
||||||
|
// CHECK-LABEL: func.func private @scalar03() -> !hlfir.expr<!fir.type<derived{f:f32}>>
|
||||||
|
|
||||||
|
// Array expression types
|
||||||
|
func.func private @array01() -> !hlfir.expr<?x!fir.char<1,?>>
|
||||||
|
func.func private @array02() -> !hlfir.expr<10x!fir.char<1,20>>
|
||||||
|
func.func private @array03() -> !hlfir.expr<10x?x20x?x30x?x40x?x50x?x60xf128>
|
||||||
|
func.func private @array04() -> !hlfir.expr<10x20x!fir.type<derived{f:f32}>>
|
||||||
|
func.func private @array05() -> !hlfir.expr<10xi32>
|
||||||
|
// CHECK-LABEL: func.func private @array01() -> !hlfir.expr<?x!fir.char<1,?>>
|
||||||
|
// CHECK-LABEL: func.func private @array02() -> !hlfir.expr<10x!fir.char<1,20>>
|
||||||
|
// CHECK-LABEL: func.func private @array03() -> !hlfir.expr<10x?x20x?x30x?x40x?x50x?x60xf128>
|
||||||
|
// CHECK-LABEL: func.func private @array04() -> !hlfir.expr<10x20x!fir.type<derived{f:f32}>>
|
||||||
|
// CHECK-LABEL: func.func private @array05() -> !hlfir.expr<10xi32>
|
||||||
|
|
||||||
|
// Polymorphic expression types
|
||||||
|
func.func private @polymorph01() -> !hlfir.expr<!fir.type<derived{f:f32}>?>
|
||||||
|
func.func private @polymorph02() -> !hlfir.expr<?x!fir.type<derived{f:f32}>?>
|
||||||
|
func.func private @polymorph03() -> !hlfir.expr<10x!fir.type<derived{f:f32}>?>
|
||||||
|
// CHECK-LABEL: func.func private @polymorph01() -> !hlfir.expr<!fir.type<derived{f:f32}>?>
|
||||||
|
// CHECK-LABEL: func.func private @polymorph02() -> !hlfir.expr<?x!fir.type<derived{f:f32}>?>
|
||||||
|
// CHECK-LABEL: func.func private @polymorph03() -> !hlfir.expr<10x!fir.type<derived{f:f32}>?>
|
|
@ -11,6 +11,7 @@ FIRDialect
|
||||||
FIRSupport
|
FIRSupport
|
||||||
FIRTransforms
|
FIRTransforms
|
||||||
FIRBuilder
|
FIRBuilder
|
||||||
|
HLFIRDialect
|
||||||
${dialect_libs}
|
${dialect_libs}
|
||||||
MLIRAffineToStandard
|
MLIRAffineToStandard
|
||||||
MLIRSCFToControlFlow
|
MLIRSCFToControlFlow
|
||||||
|
|
|
@ -7,6 +7,7 @@ target_link_libraries(fir-opt PRIVATE
|
||||||
FIRSupport
|
FIRSupport
|
||||||
FIRTransforms
|
FIRTransforms
|
||||||
FIRCodeGen
|
FIRCodeGen
|
||||||
|
HLFIRDialect
|
||||||
${dialect_libs}
|
${dialect_libs}
|
||||||
|
|
||||||
# TODO: these should be transitive dependencies from a target providing
|
# TODO: these should be transitive dependencies from a target providing
|
||||||
|
|
|
@ -7,6 +7,7 @@ target_link_libraries(tco PRIVATE
|
||||||
FIRSupport
|
FIRSupport
|
||||||
FIRTransforms
|
FIRTransforms
|
||||||
FIRBuilder
|
FIRBuilder
|
||||||
|
HLFIRDialect
|
||||||
${dialect_libs}
|
${dialect_libs}
|
||||||
MLIRIR
|
MLIRIR
|
||||||
MLIRLLVMDialect
|
MLIRLLVMDialect
|
||||||
|
|
|
@ -5,6 +5,7 @@ set(LIBS
|
||||||
FIRCodeGen
|
FIRCodeGen
|
||||||
FIRDialect
|
FIRDialect
|
||||||
FIRSupport
|
FIRSupport
|
||||||
|
HLFIRDialect
|
||||||
${dialect_libs}
|
${dialect_libs}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue