forked from OSchip/llvm-project
Revert "[flang] Update tco tool pipline and add translation to LLVM IR"
This reverts commit 68db0e25df
.
This commit is contained in:
parent
fd0c6f5391
commit
3c90ae5d0b
|
@ -12,8 +12,6 @@
|
|||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/Pass/Pass.h"
|
||||
#include "mlir/Pass/PassRegistry.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <memory>
|
||||
|
||||
namespace fir {
|
||||
|
@ -38,13 +36,9 @@ std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>> createFirTargetRewritePass(
|
|||
/// Convert FIR to the LLVM IR dialect
|
||||
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
|
||||
std::unique_ptr<mlir::Pass> createLLVMDialectToLLVMPass(
|
||||
llvm::raw_ostream &output,
|
||||
LLVMIRLoweringPrinter printer =
|
||||
[](llvm::Module &m, llvm::raw_ostream &out) { m.print(out, nullptr); });
|
||||
std::unique_ptr<mlir::Pass>
|
||||
createLLVMDialectToLLVMPass(llvm::raw_ostream &output);
|
||||
|
||||
// declarative passes
|
||||
#define GEN_PASS_REGISTRATION
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
|
||||
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
|
||||
|
||||
#include "flang/Optimizer/CodeGen/CodeGen.h"
|
||||
#include "flang/Optimizer/Dialect/FIRDialect.h"
|
||||
#include "mlir/Conversion/Passes.h"
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
|
@ -34,19 +35,11 @@ namespace fir::support {
|
|||
#define FLANG_DIALECT_LIST \
|
||||
FLANG_NONCODEGEN_DIALECT_LIST, FIRCodeGenDialect, mlir::LLVM::LLVMDialect
|
||||
|
||||
inline void registerNonCodegenDialects(mlir::DialectRegistry ®istry) {
|
||||
registry.insert<FLANG_NONCODEGEN_DIALECT_LIST>();
|
||||
}
|
||||
|
||||
/// Register all the dialects used by flang.
|
||||
inline void registerDialects(mlir::DialectRegistry ®istry) {
|
||||
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
|
||||
/// 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.
|
||||
|
@ -82,9 +75,6 @@ inline void registerMLIRPassesForFortranTools() {
|
|||
mlir::registerConvertAffineToStandardPass();
|
||||
}
|
||||
|
||||
/// Register the interfaces needed to lower to LLVM IR.
|
||||
void registerLLVMTranslation(mlir::MLIRContext &context);
|
||||
|
||||
} // namespace fir::support
|
||||
|
||||
#endif // FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
|
||||
|
|
|
@ -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
|
|
@ -23,7 +23,6 @@
|
|||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/Matchers.h"
|
||||
#include "mlir/Pass/Pass.h"
|
||||
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
|
||||
#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
|
||||
|
||||
std::unique_ptr<mlir::Pass> fir::createFIRToLLVMPass() {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
|
|||
|
||||
add_flang_library(FIRSupport
|
||||
FIRContext.cpp
|
||||
InitFIR.cpp
|
||||
InternalNames.cpp
|
||||
KindMapping.cpp
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
target_link_libraries(tco PRIVATE
|
||||
|
||||
set(LIBS
|
||||
FIRCodeGen
|
||||
FIRDialect
|
||||
FIRSupport
|
||||
FIRTransforms
|
||||
FIRBuilder
|
||||
${dialect_libs}
|
||||
MLIRIR
|
||||
MLIRLLVMIR
|
||||
MLIRLLVMToLLVMIRTranslation
|
||||
MLIRTargetLLVMIRExport
|
||||
MLIRPass
|
||||
MLIRStandardToLLVM
|
||||
MLIRTransforms
|
||||
|
@ -30,5 +18,7 @@ target_link_libraries(tco PRIVATE
|
|||
MLIRStandardToLLVM
|
||||
MLIRSupport
|
||||
MLIRVectorToLLVM
|
||||
${llvm_libs}
|
||||
)
|
||||
|
||||
add_flang_tool(tco tco.cpp)
|
||||
target_link_libraries(tco PRIVATE ${LIBS})
|
||||
|
|
|
@ -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/InternalNames.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/MLIRContext.h"
|
||||
#include "mlir/Parser.h"
|
||||
|
@ -31,13 +25,11 @@
|
|||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/ToolOutputFile.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
/// list of program return codes
|
||||
static cl::opt<std::string>
|
||||
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::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) {
|
||||
for (auto &op : *mod.getBody())
|
||||
for (auto &op : mod.getBody()->without_terminator())
|
||||
output << op << '\n';
|
||||
}
|
||||
|
||||
|
@ -79,8 +65,6 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
|
|||
mlir::DialectRegistry registry;
|
||||
fir::support::registerDialects(registry);
|
||||
mlir::MLIRContext context(registry);
|
||||
fir::support::loadDialects(context);
|
||||
fir::support::registerLLVMTranslation(context);
|
||||
auto owningRef = mlir::parseSourceFile(sourceMgr, &context);
|
||||
|
||||
if (!owningRef) {
|
||||
|
@ -96,31 +80,21 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
|
|||
ToolOutputFile out(outputFilename, ec, sys::fs::OF_None);
|
||||
|
||||
// run passes
|
||||
fir::KindMapping kindMap{&context};
|
||||
fir::setTargetTriple(*owningRef, targetTriple);
|
||||
fir::setKindMapping(*owningRef, kindMap);
|
||||
mlir::PassManager pm(&context, mlir::OpPassManager::Nesting::Implicit);
|
||||
pm.enableVerifier(/*verifyPasses=*/true);
|
||||
mlir::PassManager pm{&context};
|
||||
mlir::applyPassManagerCLOptions(pm);
|
||||
if (emitFir) {
|
||||
// parse the input and pretty-print it back out
|
||||
// -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 {
|
||||
fir::createMLIRToLLVMPassPipeline(pm);
|
||||
fir::addLLVMDialectToLLVMPass(pm, out.os());
|
||||
// TODO: Actually add passes when added to FIR code base
|
||||
// add all the passes
|
||||
// the user can disable them individually
|
||||
}
|
||||
|
||||
// run the pass manager
|
||||
if (mlir::succeeded(pm.run(*owningRef))) {
|
||||
// passes ran successfully, so keep the output
|
||||
if (emitFir || passPipeline.hasAnyOccurrences())
|
||||
if (emitFir)
|
||||
printModuleBody(*owningRef, out.os());
|
||||
out.keep();
|
||||
return mlir::success();
|
||||
|
@ -133,13 +107,8 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
[[maybe_unused]] InitLLVM y(argc, argv);
|
||||
fir::support::registerMLIRPassesForFortranTools();
|
||||
fir::registerOptCodeGenPasses();
|
||||
fir::registerOptTransformPasses();
|
||||
InitializeAllTargets();
|
||||
mlir::registerAsmPrinterCLOptions();
|
||||
mlir::registerMLIRContextCLOptions();
|
||||
[[maybe_unused]] InitLLVM y(argc, argv);
|
||||
mlir::registerPassManagerCLOptions();
|
||||
mlir::PassPipelineCLParser passPipe("", "Compiler passes to run");
|
||||
cl::ParseCommandLineOptions(argc, argv, "Tilikum Crossing Optimizer\n");
|
||||
|
|
Loading…
Reference in New Issue