Revert "[flang] Update tco tool pipline and add translation to LLVM IR"

This reverts commit 68db0e25df.
This commit is contained in:
Valentin Clement 2022-01-21 20:34:17 +01:00
parent fd0c6f5391
commit 3c90ae5d0b
No known key found for this signature in database
GPG Key ID: 086D54783C928776
9 changed files with 15 additions and 302 deletions

View File

@ -12,8 +12,6 @@
#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/Pass.h" #include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassRegistry.h" #include "mlir/Pass/PassRegistry.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
#include <memory> #include <memory>
namespace fir { namespace fir {
@ -38,13 +36,9 @@ std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> createFirTargetRewritePass(
/// Convert FIR to the LLVM IR dialect /// Convert FIR to the LLVM IR dialect
std::unique_ptr<mlir::Pass> createFIRToLLVMPass(); std::unique_ptr<mlir::Pass> createFIRToLLVMPass();
using LLVMIRLoweringPrinter =
std::function<void(llvm::Module &, llvm::raw_ostream &)>;
/// Convert the LLVM IR dialect to LLVM-IR proper /// Convert the LLVM IR dialect to LLVM-IR proper
std::unique_ptr<mlir::Pass> createLLVMDialectToLLVMPass( std::unique_ptr<mlir::Pass>
llvm::raw_ostream &output, createLLVMDialectToLLVMPass(llvm::raw_ostream &output);
LLVMIRLoweringPrinter printer =
[](llvm::Module &m, llvm::raw_ostream &out) { m.print(out, nullptr); });
// declarative passes // declarative passes
#define GEN_PASS_REGISTRATION #define GEN_PASS_REGISTRATION

View File

@ -13,6 +13,7 @@
#ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H #ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H #define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIRDialect.h"
#include "mlir/Conversion/Passes.h" #include "mlir/Conversion/Passes.h"
#include "mlir/Dialect/Affine/Passes.h" #include "mlir/Dialect/Affine/Passes.h"
@ -34,19 +35,11 @@ namespace fir::support {
#define FLANG_DIALECT_LIST \ #define FLANG_DIALECT_LIST \
FLANG_NONCODEGEN_DIALECT_LIST, FIRCodeGenDialect, mlir::LLVM::LLVMDialect FLANG_NONCODEGEN_DIALECT_LIST, FIRCodeGenDialect, mlir::LLVM::LLVMDialect
inline void registerNonCodegenDialects(mlir::DialectRegistry &registry) {
registry.insert<FLANG_NONCODEGEN_DIALECT_LIST>();
}
/// Register all the dialects used by flang. /// Register all the dialects used by flang.
inline void registerDialects(mlir::DialectRegistry &registry) { inline void registerDialects(mlir::DialectRegistry &registry) {
registry.insert<FLANG_DIALECT_LIST>(); registry.insert<FLANG_DIALECT_LIST>();
} }
inline void loadNonCodegenDialects(mlir::MLIRContext &context) {
context.loadDialect<FLANG_NONCODEGEN_DIALECT_LIST>();
}
/// Forced load of all the dialects used by flang. Lowering is not an MLIR /// Forced load of all the dialects used by flang. Lowering is not an MLIR
/// pass, but a producer of FIR and MLIR. It is therefore a requirement that the /// pass, but a producer of FIR and MLIR. It is therefore a requirement that the
/// dialects be preloaded to be able to build the IR. /// dialects be preloaded to be able to build the IR.
@ -82,9 +75,6 @@ inline void registerMLIRPassesForFortranTools() {
mlir::registerConvertAffineToStandardPass(); mlir::registerConvertAffineToStandardPass();
} }
/// Register the interfaces needed to lower to LLVM IR.
void registerLLVMTranslation(mlir::MLIRContext &context);
} // namespace fir::support } // namespace fir::support
#endif // FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H #endif // FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H

View File

@ -1,160 +0,0 @@
//===-- CLOptions.inc -- command line options -------------------*- 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 some shared command-line options that can be used when
/// debugging the test tools. This file must be included into the tool.
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "mlir/Transforms/Passes.h"
#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "llvm/Support/CommandLine.h"
#define DisableOption(DOName, DOOption, DODescription) \
static llvm::cl::opt<bool> disable##DOName("disable-" DOOption, \
llvm::cl::desc("disable " DODescription " pass"), llvm::cl::init(false), \
llvm::cl::Hidden)
/// Shared option in tools to control whether dynamically sized array
/// allocations should always be on the heap.
static llvm::cl::opt<bool> dynamicArrayStackToHeapAllocation(
"fdynamic-heap-array",
llvm::cl::desc("place all array allocations of dynamic size on the heap"),
llvm::cl::init(false), llvm::cl::Hidden);
/// Shared option in tools to set a maximum value for the number of elements in
/// a compile-time sized array that can be allocated on the stack.
static llvm::cl::opt<std::size_t> arrayStackAllocationThreshold(
"fstack-array-size",
llvm::cl::desc(
"place all array allocations more than <size> elements on the heap"),
llvm::cl::init(~static_cast<std::size_t>(0)), llvm::cl::Hidden);
namespace {
/// Optimizer Passes
DisableOption(CfgConversion, "cfg-conversion", "disable FIR to CFG pass");
DisableOption(FirAvc, "avc", "array value copy analysis and transformation");
DisableOption(
FirMao, "memory-allocation-opt", "memory allocation optimization");
/// CodeGen Passes
#if !defined(FLANG_EXCLUDE_CODEGEN)
DisableOption(CodeGenRewrite, "codegen-rewrite", "rewrite FIR for codegen");
DisableOption(TargetRewrite, "target-rewrite", "rewrite FIR for target");
DisableOption(FirToLlvmIr, "fir-to-llvmir", "FIR to LLVM-IR dialect");
DisableOption(LlvmIrToLlvm, "llvm", "conversion to LLVM");
#endif
/// Generic for adding a pass to the pass manager if it is not disabled.
template <typename F>
void addPassConditionally(
mlir::PassManager &pm, llvm::cl::opt<bool> &disabled, F ctor) {
if (!disabled)
pm.addPass(ctor());
}
template <typename OP, typename F>
void addNestedPassConditionally(
mlir::PassManager &pm, llvm::cl::opt<bool> &disabled, F ctor) {
if (!disabled)
pm.addNestedPass<OP>(ctor());
}
} // namespace
namespace fir {
static void defaultFlangInlinerOptPipeline(mlir::OpPassManager &pm) {
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = false;
pm.addPass(mlir::createCanonicalizerPass(config));
}
inline void addCfgConversionPass(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::FuncOp>(
pm, disableCfgConversion, fir::createFirToCfgPass);
}
inline void addAVC(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::FuncOp>(
pm, disableFirAvc, fir::createArrayValueCopyPass);
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
inline void addCodeGenRewritePass(mlir::PassManager &pm) {
addPassConditionally(
pm, disableCodeGenRewrite, fir::createFirCodeGenRewritePass);
}
inline void addTargetRewritePass(mlir::PassManager &pm) {
addPassConditionally(pm, disableTargetRewrite, []() {
return fir::createFirTargetRewritePass(fir::TargetRewriteOptions{});
});
}
inline void addFIRToLLVMPass(mlir::PassManager &pm) {
addPassConditionally(pm, disableFirToLlvmIr, fir::createFIRToLLVMPass);
}
inline void addLLVMDialectToLLVMPass(
mlir::PassManager &pm, llvm::raw_ostream &output) {
addPassConditionally(pm, disableLlvmIrToLlvm,
[&]() { return fir::createLLVMDialectToLLVMPass(output); });
}
#endif
/// Create a pass pipeline for running default optimization passes for
/// incremental conversion of FIR.
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
inline void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm) {
// simplify the IR
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = false;
fir::addAVC(pm);
pm.addNestedPass<mlir::FuncOp>(fir::createCharacterConversionPass());
pm.addPass(mlir::createCanonicalizerPass(config));
// The default inliner pass adds the canonicalizer pass with the default
// configuration. Create the inliner pass with tco config.
llvm::StringMap<mlir::OpPassManager> pipelines;
pm.addPass(
mlir::createInlinerPass(pipelines, defaultFlangInlinerOptPipeline));
pm.addPass(mlir::createCSEPass());
// convert control flow to CFG form
fir::addCfgConversionPass(pm);
pm.addPass(mlir::createLowerToCFGPass());
pm.addPass(mlir::createCanonicalizerPass(config));
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm) {
pm.addNestedPass<mlir::FuncOp>(fir::createAbstractResultOptPass());
fir::addCodeGenRewritePass(pm);
fir::addTargetRewritePass(pm);
fir::addFIRToLLVMPass(pm);
}
/// Create a pass pipeline for lowering from MLIR to LLVM IR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm) {
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm);
// Add codegen pass pipeline.
fir::createDefaultFIRCodeGenPassPipeline(pm);
}
#undef FLANG_EXCLUDE_CODEGEN
#endif
} // namespace fir

View File

@ -23,7 +23,6 @@
#include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h" #include "mlir/IR/Matchers.h"
#include "mlir/Pass/Pass.h" #include "mlir/Pass/Pass.h"
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#define DEBUG_TYPE "flang-codegen" #define DEBUG_TYPE "flang-codegen"
@ -3306,44 +3305,8 @@ public:
} }
} }
}; };
/// Lower from LLVM IR dialect to proper LLVM-IR and dump the module
struct LLVMIRLoweringPass
: public mlir::PassWrapper<LLVMIRLoweringPass,
mlir::OperationPass<mlir::ModuleOp>> {
using Printer = fir::LLVMIRLoweringPrinter;
LLVMIRLoweringPass(raw_ostream &output, Printer p)
: output{output}, printer{p} {}
mlir::ModuleOp getModule() { return getOperation(); }
void runOnOperation() override final {
auto *ctx = getModule().getContext();
auto optName = getModule().getName();
llvm::LLVMContext llvmCtx;
if (auto llvmModule = mlir::translateModuleToLLVMIR(
getModule(), llvmCtx, optName ? *optName : "FIRModule")) {
printer(*llvmModule, output);
return;
}
mlir::emitError(mlir::UnknownLoc::get(ctx), "could not emit LLVM-IR\n");
signalPassFailure();
}
private:
raw_ostream &output;
Printer printer;
};
} // namespace } // namespace
std::unique_ptr<mlir::Pass> fir::createFIRToLLVMPass() { std::unique_ptr<mlir::Pass> fir::createFIRToLLVMPass() {
return std::make_unique<FIRToLLVMLowering>(); return std::make_unique<FIRToLLVMLowering>();
} }
std::unique_ptr<mlir::Pass>
fir::createLLVMDialectToLLVMPass(raw_ostream &output,
fir::LLVMIRLoweringPrinter printer) {
return std::make_unique<LLVMIRLoweringPass>(output, printer);
}

View File

@ -2,7 +2,6 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
add_flang_library(FIRSupport add_flang_library(FIRSupport
FIRContext.cpp FIRContext.cpp
InitFIR.cpp
InternalNames.cpp InternalNames.cpp
KindMapping.cpp KindMapping.cpp

View File

@ -1,20 +0,0 @@
//===-- Optimizer/Support/InitFIR.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
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Support/InitFIR.h"
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
mlir::DialectRegistry registry;
// Register OpenMP dialect interface here as well.
mlir::registerOpenMPDialectTranslation(registry);
// Register LLVM-IR dialect interface.
registerLLVMDialectTranslation(registry);
context.appendDialectRegistry(registry);
}

View File

@ -1,12 +0,0 @@
// RUN: tco %s | FileCheck %s
// REQUIRES: shell
// Check that tco is working with a basic test.
func @_QQmain() {
return
}
// CHECK: ; ModuleID = 'FIRModule'
// CHECK-LABEL: define void @_QQmain()
// CHECK: ret void

View File

@ -1,25 +1,13 @@
set(LLVM_LINK_COMPONENTS
AllTargetsAsmParsers
AllTargetsCodeGens
AllTargetsDescs
AllTargetsInfos
)
llvm_map_components_to_libnames(llvm_libs ${LLVM_LINK_COMPONENTS})
add_flang_tool(tco tco.cpp)
llvm_update_compile_flags(tco)
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
target_link_libraries(tco PRIVATE
set(LIBS
FIRCodeGen FIRCodeGen
FIRDialect FIRDialect
FIRSupport FIRSupport
FIRTransforms FIRTransforms
FIRBuilder
${dialect_libs} ${dialect_libs}
MLIRIR MLIRIR
MLIRLLVMIR MLIRLLVMIR
MLIRLLVMToLLVMIRTranslation
MLIRTargetLLVMIRExport
MLIRPass MLIRPass
MLIRStandardToLLVM MLIRStandardToLLVM
MLIRTransforms MLIRTransforms
@ -30,5 +18,7 @@ target_link_libraries(tco PRIVATE
MLIRStandardToLLVM MLIRStandardToLLVM
MLIRSupport MLIRSupport
MLIRVectorToLLVM MLIRVectorToLLVM
${llvm_libs}
) )
add_flang_tool(tco tco.cpp)
target_link_libraries(tco PRIVATE ${LIBS})

View File

@ -11,14 +11,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/Support/FIRContext.h"
#include "flang/Optimizer/Support/InitFIR.h" #include "flang/Optimizer/Support/InitFIR.h"
#include "flang/Optimizer/Support/InternalNames.h"
#include "flang/Optimizer/Support/KindMapping.h" #include "flang/Optimizer/Support/KindMapping.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h" #include "mlir/IR/MLIRContext.h"
#include "mlir/Parser.h" #include "mlir/Parser.h"
@ -31,13 +25,11 @@
#include "llvm/Support/InitLLVM.h" #include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
/// list of program return codes
static cl::opt<std::string> static cl::opt<std::string>
inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
@ -50,14 +42,8 @@ static cl::opt<bool> emitFir("emit-fir",
cl::desc("Parse and pretty-print the input"), cl::desc("Parse and pretty-print the input"),
cl::init(false)); cl::init(false));
static cl::opt<std::string> targetTriple("target",
cl::desc("specify a target triple"),
cl::init("native"));
#include "flang/Tools/CLOptions.inc"
static void printModuleBody(mlir::ModuleOp mod, raw_ostream &output) { static void printModuleBody(mlir::ModuleOp mod, raw_ostream &output) {
for (auto &op : *mod.getBody()) for (auto &op : mod.getBody()->without_terminator())
output << op << '\n'; output << op << '\n';
} }
@ -79,8 +65,6 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
mlir::DialectRegistry registry; mlir::DialectRegistry registry;
fir::support::registerDialects(registry); fir::support::registerDialects(registry);
mlir::MLIRContext context(registry); mlir::MLIRContext context(registry);
fir::support::loadDialects(context);
fir::support::registerLLVMTranslation(context);
auto owningRef = mlir::parseSourceFile(sourceMgr, &context); auto owningRef = mlir::parseSourceFile(sourceMgr, &context);
if (!owningRef) { if (!owningRef) {
@ -96,31 +80,21 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
ToolOutputFile out(outputFilename, ec, sys::fs::OF_None); ToolOutputFile out(outputFilename, ec, sys::fs::OF_None);
// run passes // run passes
fir::KindMapping kindMap{&context}; mlir::PassManager pm{&context};
fir::setTargetTriple(*owningRef, targetTriple);
fir::setKindMapping(*owningRef, kindMap);
mlir::PassManager pm(&context, mlir::OpPassManager::Nesting::Implicit);
pm.enableVerifier(/*verifyPasses=*/true);
mlir::applyPassManagerCLOptions(pm); mlir::applyPassManagerCLOptions(pm);
if (emitFir) { if (emitFir) {
// parse the input and pretty-print it back out // parse the input and pretty-print it back out
// -emit-fir intentionally disables all the passes // -emit-fir intentionally disables all the passes
} else if (passPipeline.hasAnyOccurrences()) {
auto errorHandler = [&](const Twine &msg) {
mlir::emitError(mlir::UnknownLoc::get(pm.getContext())) << msg;
return mlir::failure();
};
if (mlir::failed(passPipeline.addToPipeline(pm, errorHandler)))
return mlir::failure();
} else { } else {
fir::createMLIRToLLVMPassPipeline(pm); // TODO: Actually add passes when added to FIR code base
fir::addLLVMDialectToLLVMPass(pm, out.os()); // add all the passes
// the user can disable them individually
} }
// run the pass manager // run the pass manager
if (mlir::succeeded(pm.run(*owningRef))) { if (mlir::succeeded(pm.run(*owningRef))) {
// passes ran successfully, so keep the output // passes ran successfully, so keep the output
if (emitFir || passPipeline.hasAnyOccurrences()) if (emitFir)
printModuleBody(*owningRef, out.os()); printModuleBody(*owningRef, out.os());
out.keep(); out.keep();
return mlir::success(); return mlir::success();
@ -133,13 +107,8 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
[[maybe_unused]] InitLLVM y(argc, argv);
fir::support::registerMLIRPassesForFortranTools(); fir::support::registerMLIRPassesForFortranTools();
fir::registerOptCodeGenPasses(); [[maybe_unused]] InitLLVM y(argc, argv);
fir::registerOptTransformPasses();
InitializeAllTargets();
mlir::registerAsmPrinterCLOptions();
mlir::registerMLIRContextCLOptions();
mlir::registerPassManagerCLOptions(); mlir::registerPassManagerCLOptions();
mlir::PassPipelineCLParser passPipe("", "Compiler passes to run"); mlir::PassPipelineCLParser passPipe("", "Compiler passes to run");
cl::ParseCommandLineOptions(argc, argv, "Tilikum Crossing Optimizer\n"); cl::ParseCommandLineOptions(argc, argv, "Tilikum Crossing Optimizer\n");