diff --git a/flang/lib/Lower/RTBuilder.h b/flang/lib/Lower/RTBuilder.h deleted file mode 100644 --- a/flang/lib/Lower/RTBuilder.h +++ /dev/null @@ -1,287 +0,0 @@ -//===-- RTBuilder.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 -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// This file defines some C++17 template classes that are used to convert the -/// signatures of plain old C functions into a model that can be used to -/// generate MLIR calls to those functions. This can be used to autogenerate -/// tables at compiler compile-time to call runtime support code. -/// -//===----------------------------------------------------------------------===// - -#ifndef FORTRAN_LOWER_RTBUILDER_H -#define FORTRAN_LOWER_RTBUILDER_H - -#include "flang/Lower/ConvertType.h" -#include "flang/Optimizer/Dialect/FIRType.h" -#include "mlir/IR/BuiltinTypes.h" -#include "mlir/IR/MLIRContext.h" -#include "llvm/ADT/SmallVector.h" -#include - -// List the runtime headers we want to be able to dissect -#include "flang/Runtime/io-api.h" - -// Incomplete type indicating C99 complex ABI in interfaces. Beware, _Complex -// and std::complex are layout compatible, but not compatible in all ABI call -// interface (e.g. X86 32 bits). _Complex is not standard C++, so do not use -// it here. -struct c_float_complex_t; -struct c_double_complex_t; - -namespace Fortran::lower { - -using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *); -using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *); - -//===----------------------------------------------------------------------===// -// Type builder models -//===----------------------------------------------------------------------===// - -/// Return a function that returns the type signature model for the type `T` -/// when provided an MLIRContext*. This allows one to translate C(++) function -/// signatures from runtime header files to MLIR signatures into a static table -/// at compile-time. -/// -/// For example, when `T` is `int`, return a function that returns the MLIR -/// standard type `i32` when `sizeof(int)` is 4. -template -static constexpr TypeBuilderFunc getModel(); -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, 8 * sizeof(int)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - TypeBuilderFunc f{getModel()}; - return fir::ReferenceType::get(f(context)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, - 8 * sizeof(Fortran::runtime::io::Iostat)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get(mlir::IntegerType::get(context, 8)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return getModel(); -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get(mlir::IntegerType::get(context, 16)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get(mlir::IntegerType::get(context, 32)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ReferenceType::get( - fir::PointerType::get(mlir::IntegerType::get(context, 8))); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, 64); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - TypeBuilderFunc f{getModel()}; - return fir::ReferenceType::get(f(context)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, 8 * sizeof(std::size_t)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return getModel(); -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::FloatType::getF64(context); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - TypeBuilderFunc f{getModel()}; - return fir::ReferenceType::get(f(context)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::FloatType::getF32(context); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - TypeBuilderFunc f{getModel()}; - return fir::ReferenceType::get(f(context)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::IntegerType::get(context, 1); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - TypeBuilderFunc f{getModel()}; - return fir::ReferenceType::get(f(context)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ComplexType::get(context, sizeof(float)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::ComplexType::get(context, sizeof(double)); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return fir::BoxType::get(mlir::NoneType::get(context)); - }; -} -template <> -constexpr TypeBuilderFunc -getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - // FIXME: a namelist group must be some well-defined data structure, use a - // tuple as a proxy for the moment - return mlir::TupleType::get(context); - }; -} -template <> -constexpr TypeBuilderFunc getModel() { - return [](mlir::MLIRContext *context) -> mlir::Type { - return mlir::NoneType::get(context); - }; -} - -template -struct RuntimeTableKey; -template -struct RuntimeTableKey { - static constexpr FuncTypeBuilderFunc getTypeModel() { - return [](mlir::MLIRContext *ctxt) { - TypeBuilderFunc ret = getModel(); - std::array args = {getModel()...}; - mlir::Type retTy = ret(ctxt); - llvm::SmallVector argTys; - for (auto f : args) - argTys.push_back(f(ctxt)); - return mlir::FunctionType::get(ctxt, argTys, {retTy}); - }; - } -}; - -//===----------------------------------------------------------------------===// -// Runtime table building (constexpr folded) -//===----------------------------------------------------------------------===// - -template -using RuntimeIdentifier = std::integer_sequence; - -namespace details { -template -static constexpr std::integer_sequence -concat(std::integer_sequence, std::integer_sequence) { - return {}; -} -template -static constexpr auto concat(std::integer_sequence, - std::integer_sequence, Cs...) { - return concat(std::integer_sequence{}, Cs{}...); -} -template -static constexpr std::integer_sequence concat(std::integer_sequence) { - return {}; -} -template -static constexpr auto filterZero(std::integer_sequence) { - if constexpr (a != 0) { - return std::integer_sequence{}; - } else { - return std::integer_sequence{}; - } -} -template -static constexpr auto filter(std::integer_sequence) { - if constexpr (sizeof...(b) > 0) { - return details::concat(filterZero(std::integer_sequence{})...); - } else { - return std::integer_sequence{}; - } -} -} // namespace details - -template -struct RuntimeTableEntry; -template -struct RuntimeTableEntry, RuntimeIdentifier> { - static constexpr FuncTypeBuilderFunc getTypeModel() { - return RuntimeTableKey::getTypeModel(); - } - static constexpr const char name[sizeof...(Cs) + 1] = {Cs..., '\0'}; -}; - -#undef E -#define E(L, I) (I < sizeof(L) / sizeof(*L) ? L[I] : 0) -#define QuoteKey(X) #X -#define MacroExpandKey(X) \ - E(X, 0), E(X, 1), E(X, 2), E(X, 3), E(X, 4), E(X, 5), E(X, 6), E(X, 7), \ - E(X, 8), E(X, 9), E(X, 10), E(X, 11), E(X, 12), E(X, 13), E(X, 14), \ - E(X, 15), E(X, 16), E(X, 17), E(X, 18), E(X, 19), E(X, 20), E(X, 21), \ - E(X, 22), E(X, 23), E(X, 24), E(X, 25), E(X, 26), E(X, 27), E(X, 28), \ - E(X, 29), E(X, 30), E(X, 31), E(X, 32), E(X, 33), E(X, 34), E(X, 35), \ - E(X, 36), E(X, 37), E(X, 38), E(X, 39), E(X, 40), E(X, 41), E(X, 42), \ - E(X, 43), E(X, 44), E(X, 45), E(X, 46), E(X, 47), E(X, 48), E(X, 49) -#define ExpandKey(X) MacroExpandKey(QuoteKey(X)) -#define FullSeq(X) std::integer_sequence -#define AsSequence(X) decltype(Fortran::lower::details::filter(FullSeq(X){})) -#define mkKey(X) \ - Fortran::lower::RuntimeTableEntry< \ - Fortran::lower::RuntimeTableKey, AsSequence(X)> - -} // namespace Fortran::lower - -#endif // FORTRAN_LOWER_RTBUILDER_H diff --git a/flang/unittests/Optimizer/RTBuilder.cpp b/flang/unittests/Optimizer/RTBuilder.cpp --- a/flang/unittests/Optimizer/RTBuilder.cpp +++ b/flang/unittests/Optimizer/RTBuilder.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "../../lib/Lower/RTBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" #include "gtest/gtest.h" #include "flang/Optimizer/Support/InitFIR.h" @@ -25,7 +25,7 @@ mlir::MLIRContext ctx(registry); fir::support::loadDialects(ctx); mlir::Type c99_cacosf_signature{ - Fortran::lower::RuntimeTableKey::getTypeModel()( + fir::runtime::RuntimeTableKey::getTypeModel()( &ctx)}; auto c99_cacosf_funcTy = c99_cacosf_signature.cast(); EXPECT_EQ(c99_cacosf_funcTy.getNumInputs(), 1u);