[flang][NFC] Refactor to remove .inc file containing shared code (#109874)

Remove flang/include/flang/Tools/CLOptions.inc - which was included as
is in - several places. Move the code in it to header and source files
which are used used in the "standard" way. Some minor cleanup such as
removing trailing whitespace and excessive newlines and reordering
entries alphabetically for files that were modified along the way.
Update the documentation that referenced CLOptions.inc.
This commit is contained in:
Tarun Prabhu
2024-09-25 14:04:38 -06:00
committed by GitHub
parent eb48aac7d4
commit c3201ddaea
15 changed files with 671 additions and 473 deletions

View File

@@ -521,7 +521,7 @@ e.g. during the semantic checks.
## FIR Optimizer Pass Pipeline Extension Points
The default FIR optimizer pass pipeline `createDefaultFIROptimizerPassPipeline`
in `flang/include/flang/Tools/CLOptions.inc` contains extension point callback
in `flang/lib/Optimizer/Passes/Pipelines.cpp` contains extension point callback
invocations `invokeFIROptEarlyEPCallbacks`, `invokeFIRInlinerCallback`, and
`invokeFIROptLastEPCallbacks` for Flang drivers to be able to insert additonal
passes at different points of the default pass pipeline. An example use of these

View File

@@ -0,0 +1,60 @@
//===-- CommandLineOpts.h -- shared 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 declares some shared command-line options that can be used when
/// debugging the test tools.
#ifndef FORTRAN_OPTIMIZER_PASSES_COMMANDLINEOPTS_H
#define FORTRAN_OPTIMIZER_PASSES_COMMANDLINEOPTS_H
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/CommandLine.h"
/// Shared option in tools to control whether dynamically sized array
/// allocations should always be on the heap.
extern llvm::cl::opt<bool> dynamicArrayStackToHeapAllocation;
/// 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.
extern llvm::cl::opt<std::size_t> arrayStackAllocationThreshold;
/// Shared option in tools to ignore missing runtime type descriptor objects
/// when translating FIR to LLVM. The resulting program will crash if the
/// runtime needs the derived type descriptors, this is only a debug option to
/// allow compiling manually written FIR programs involving derived types
/// without having to write the derived type descriptors which are normally
/// generated by the frontend.
extern llvm::cl::opt<bool> ignoreMissingTypeDescriptors;
/// Default optimization level used to create Flang pass pipeline is O0.
extern llvm::OptimizationLevel defaultOptLevel;
extern llvm::codegenoptions::DebugInfoKind noDebugInfo;
/// Optimizer Passes
extern llvm::cl::opt<bool> disableCfgConversion;
extern llvm::cl::opt<bool> disableFirAvc;
extern llvm::cl::opt<bool> disableFirMao;
extern llvm::cl::opt<bool> disableFirAliasTags;
extern llvm::cl::opt<bool> useOldAliasTags;
/// CodeGen Passes
extern llvm::cl::opt<bool> disableCodeGenRewrite;
extern llvm::cl::opt<bool> disableTargetRewrite;
extern llvm::cl::opt<bool> disableDebugInfo;
extern llvm::cl::opt<bool> disableFirToLlvmIr;
extern llvm::cl::opt<bool> disableLlvmIrToLlvm;
extern llvm::cl::opt<bool> disableBoxedProcedureRewrite;
extern llvm::cl::opt<bool> disableExternalNameConversion;
extern llvm::cl::opt<bool> enableConstantArgumentGlobalisation;
extern llvm::cl::opt<bool> disableCompilerGeneratedNamesConversion;
#endif // FORTRAN_OPTIMIZER_PASSES_COMMANDLINE_OPTS_H

View File

@@ -0,0 +1,162 @@
//===-- Pipelines.h -- FIR pass pipelines -----------------------*- 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 declares some utilties to setup FIR pass pipelines. These are
/// common to flang and the test tools.
#ifndef FORTRAN_OPTIMIZER_PASSES_PIPELINES_H
#define FORTRAN_OPTIMIZER_PASSES_PIPELINES_H
#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/Passes/CommandLineOpts.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "flang/Tools/CrossToolHelpers.h"
#include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "mlir/Transforms/Passes.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/CommandLine.h"
namespace fir {
using PassConstructor = std::unique_ptr<mlir::Pass>();
template <typename OP>
void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) {
pm.addNestedPass<OP>(ctor());
}
template <typename OP, typename... OPS,
typename = std::enable_if_t<sizeof...(OPS) != 0>>
void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) {
addNestedPassToOps<OP>(pm, ctor);
addNestedPassToOps<OPS...>(pm, ctor);
}
/// 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());
}
void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm,
PassConstructor ctor);
void addNestedPassToAllTopLevelOperationsConditionally(
mlir::PassManager &pm, llvm::cl::opt<bool> &disabled, PassConstructor ctor);
/// Add MLIR Canonicalizer pass with region simplification disabled.
/// FIR does not support the promotion of some SSA value to block arguments (or
/// into arith.select operands) that may be done by mlir block merging in the
/// region simplification (e.g., !fir.shape<> SSA values are not supported as
/// block arguments).
/// Aside from the fir.shape issue, moving some abstract SSA value into block
/// arguments may have a heavy cost since it forces their code generation that
/// may be expensive (array temporary). The MLIR pass does not take these
/// extra costs into account when doing block merging.
void addCanonicalizerPassWithoutRegionSimplification(mlir::OpPassManager &pm);
void addCfgConversionPass(mlir::PassManager &pm,
const MLIRToLLVMPassPipelineConfig &config);
void addAVC(mlir::PassManager &pm, const llvm::OptimizationLevel &optLevel);
void addMemoryAllocationOpt(mlir::PassManager &pm);
void addCodeGenRewritePass(mlir::PassManager &pm, bool preserveDeclare);
void addTargetRewritePass(mlir::PassManager &pm);
mlir::LLVM::DIEmissionKind
getEmissionKind(llvm::codegenoptions::DebugInfoKind kind);
void addBoxedProcedurePass(mlir::PassManager &pm);
void addExternalNameConversionPass(mlir::PassManager &pm,
bool appendUnderscore = true);
void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm);
void addDebugInfoPass(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel optLevel,
llvm::StringRef inputFilename);
void addFIRToLLVMPass(mlir::PassManager &pm,
const MLIRToLLVMPassPipelineConfig &config);
void addLLVMDialectToLLVMPass(mlir::PassManager &pm, llvm::raw_ostream &output);
/// Use inliner extension point callback to register the default inliner pass.
void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config);
/// 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
void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig &pc);
/// Create a pass pipeline for lowering from HLFIR to FIR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
void createHLFIRToFIRPassPipeline(
mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel);
/// Create a pass pipeline for handling certain OpenMP transformations needed
/// prior to FIR lowering.
///
/// WARNING: These passes must be run immediately after the lowering to ensure
/// that the FIR is correct with respect to OpenMP operations/attributes.
///
/// \param pm - MLIR pass manager that will hold the pipeline definition.
/// \param isTargetDevice - Whether code is being generated for a target device
/// rather than the host device.
void createOpenMPFIRPassPipeline(mlir::PassManager &pm, bool isTargetDevice);
#if !defined(FLANG_EXCLUDE_CODEGEN)
void createDebugPasses(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel OptLevel,
llvm::StringRef inputFilename);
void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig config,
llvm::StringRef inputFilename = {});
/// Create a pass pipeline for lowering from MLIR to LLVM IR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig &config,
llvm::StringRef inputFilename = {});
#undef FLANG_EXCLUDE_CODEGEN
#endif
} // namespace fir
#endif // FORTRAN_OPTIMIZER_PASSES_PIPELINES_H

View File

@@ -1,438 +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/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.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/HLFIR/Passes.h"
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/Transforms/Passes.h"
#include "llvm/Passes/OptimizationLevel.h"
#include "llvm/Support/CommandLine.h"
#include <type_traits>
#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)
#define EnableOption(EOName, EOOption, EODescription) \
static llvm::cl::opt<bool> enable##EOName("enable-" EOOption, \
llvm::cl::desc("enable " EODescription " 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);
/// Shared option in tools to ignore missing runtime type descriptor objects
/// when translating FIR to LLVM. The resulting program will crash if the
/// runtime needs the derived type descriptors, this is only a debug option to
/// allow compiling manually written FIR programs involving derived types
/// without having to write the derived type descriptors which are normally
/// generated by the frontend.
static llvm::cl::opt<bool> ignoreMissingTypeDescriptors(
"ignore-missing-type-desc",
llvm::cl::desc("ignore failures to find derived type descriptors when "
"translating FIR to LLVM"),
llvm::cl::init(false), llvm::cl::Hidden);
namespace {
/// Default optimization level used to create Flang pass pipeline is O0.
const static llvm::OptimizationLevel &defaultOptLevel{
llvm::OptimizationLevel::O0};
const static llvm::codegenoptions::DebugInfoKind &NoDebugInfo{
llvm::codegenoptions::NoDebugInfo};
/// 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");
DisableOption(FirAliasTags, "fir-alias-tags", "fir alias analysis");
static llvm::cl::opt<bool> useOldAliasTags("use-old-alias-tags",
llvm::cl::desc("Use a single TBAA tree for all functions and do not use "
"the FIR alias tags pass"),
llvm::cl::init(false), llvm::cl::Hidden);
/// CodeGen Passes
#if !defined(FLANG_EXCLUDE_CODEGEN)
DisableOption(CodeGenRewrite, "codegen-rewrite", "rewrite FIR for codegen");
DisableOption(TargetRewrite, "target-rewrite", "rewrite FIR for target");
DisableOption(DebugInfo, "debug-info", "Add debug info");
DisableOption(FirToLlvmIr, "fir-to-llvmir", "FIR to LLVM-IR dialect");
DisableOption(LlvmIrToLlvm, "llvm", "conversion to LLVM");
DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite",
"rewrite boxed procedures");
#endif
DisableOption(ExternalNameConversion, "external-name-interop",
"convert names with external convention");
EnableOption(ConstantArgumentGlobalisation, "constant-argument-globalisation",
"the local constant argument to global constant conversion");
DisableOption(CompilerGeneratedNamesConversion, "compiler-generated-names",
"replace special symbols in compiler generated names");
using PassConstructor = std::unique_ptr<mlir::Pass>();
template <typename OP>
void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) {
pm.addNestedPass<OP>(ctor());
}
template <typename OP, typename... OPS,
typename = std::enable_if_t<sizeof...(OPS) != 0>>
void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) {
addNestedPassToOps<OP>(pm, ctor);
addNestedPassToOps<OPS...>(pm, ctor);
}
void addNestedPassToAllTopLevelOperations(
mlir::PassManager &pm, PassConstructor ctor) {
addNestedPassToOps<mlir::func::FuncOp, mlir::omp::DeclareReductionOp,
mlir::omp::PrivateClauseOp, fir::GlobalOp>(pm, ctor);
}
void addNestedPassToAllTopLevelOperationsConditionally(mlir::PassManager &pm,
llvm::cl::opt<bool> &disabled, PassConstructor ctor) {
if (!disabled)
addNestedPassToAllTopLevelOperations(pm, ctor);
}
/// 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 {
/// Add MLIR Canonicalizer pass with region simplification disabled.
/// FIR does not support the promotion of some SSA value to block arguments (or
/// into arith.select operands) that may be done by mlir block merging in the
/// region simplification (e.g., !fir.shape<> SSA values are not supported as
/// block arguments).
/// Aside from the fir.shape issue, moving some abstract SSA value into block
/// arguments may have a heavy cost since it forces their code generation that
/// may be expensive (array temporary). The MLIR pass does not take these
/// extra costs into account when doing block merging.
static void addCanonicalizerPassWithoutRegionSimplification(
mlir::OpPassManager &pm) {
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCanonicalizerPass(config));
}
inline void addCfgConversionPass(
mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &config) {
if (config.NSWOnLoopVarInc)
addNestedPassToAllTopLevelOperationsConditionally(
pm, disableCfgConversion, fir::createCFGConversionPassWithNSW);
else
addNestedPassToAllTopLevelOperationsConditionally(
pm, disableCfgConversion, fir::createCFGConversion);
}
inline void addAVC(
mlir::PassManager &pm, const llvm::OptimizationLevel &optLevel) {
ArrayValueCopyOptions options;
options.optimizeConflicts = optLevel.isOptimizingForSpeed();
addNestedPassConditionally<mlir::func::FuncOp>(
pm, disableFirAvc, [&]() { return createArrayValueCopyPass(options); });
}
inline void addMemoryAllocationOpt(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::func::FuncOp>(pm, disableFirMao, [&]() {
return fir::createMemoryAllocationOpt(
{dynamicArrayStackToHeapAllocation, arrayStackAllocationThreshold});
});
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
inline void addCodeGenRewritePass(mlir::PassManager &pm, bool preserveDeclare) {
fir::CodeGenRewriteOptions options;
options.preserveDeclare = preserveDeclare;
addPassConditionally(pm, disableCodeGenRewrite,
[&]() { return fir::createCodeGenRewrite(options); });
}
inline void addTargetRewritePass(mlir::PassManager &pm) {
addPassConditionally(pm, disableTargetRewrite,
[]() { return fir::createTargetRewritePass(); });
}
inline mlir::LLVM::DIEmissionKind getEmissionKind(
llvm::codegenoptions::DebugInfoKind kind) {
switch (kind) {
case llvm::codegenoptions::DebugInfoKind::FullDebugInfo:
return mlir::LLVM::DIEmissionKind::Full;
case llvm::codegenoptions::DebugInfoKind::DebugLineTablesOnly:
return mlir::LLVM::DIEmissionKind::LineTablesOnly;
default:
return mlir::LLVM::DIEmissionKind::None;
}
}
inline void addDebugInfoPass(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel optLevel, llvm::StringRef inputFilename) {
fir::AddDebugInfoOptions options;
options.debugLevel = getEmissionKind(debugLevel);
options.isOptimized = optLevel != llvm::OptimizationLevel::O0;
options.inputFilename = inputFilename;
addPassConditionally(pm, disableDebugInfo,
[&]() { return fir::createAddDebugInfoPass(options); });
}
inline void addFIRToLLVMPass(
mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &config) {
fir::FIRToLLVMPassOptions options;
options.ignoreMissingTypeDescriptors = ignoreMissingTypeDescriptors;
options.applyTBAA = config.AliasAnalysis;
options.forceUnifiedTBAATree = useOldAliasTags;
options.typeDescriptorsRenamedForAssembly =
!disableCompilerGeneratedNamesConversion;
addPassConditionally(pm, disableFirToLlvmIr,
[&]() { return fir::createFIRToLLVMPass(options); });
// The dialect conversion framework may leave dead unrealized_conversion_cast
// ops behind, so run reconcile-unrealized-casts to clean them up.
addPassConditionally(pm, disableFirToLlvmIr,
[&]() { return mlir::createReconcileUnrealizedCastsPass(); });
}
inline void addLLVMDialectToLLVMPass(
mlir::PassManager &pm, llvm::raw_ostream &output) {
addPassConditionally(pm, disableLlvmIrToLlvm,
[&]() { return fir::createLLVMDialectToLLVMPass(output); });
}
inline void addBoxedProcedurePass(mlir::PassManager &pm) {
addPassConditionally(pm, disableBoxedProcedureRewrite,
[&]() { return fir::createBoxedProcedurePass(); });
}
#endif
inline void addExternalNameConversionPass(
mlir::PassManager &pm, bool appendUnderscore = true) {
addPassConditionally(pm, disableExternalNameConversion,
[&]() { return fir::createExternalNameConversion({appendUnderscore}); });
}
inline void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm) {
addPassConditionally(pm, disableCompilerGeneratedNamesConversion,
[&]() { return fir::createCompilerGeneratedNamesConversion(); });
}
// Use inliner extension point callback to register the default inliner pass.
inline void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config) {
config.registerFIRInlinerCallback(
[](mlir::PassManager &pm, llvm::OptimizationLevel level) {
llvm::StringMap<mlir::OpPassManager> pipelines;
// The default inliner pass adds the canonicalizer pass with the default
// configuration.
pm.addPass(mlir::createInlinerPass(
pipelines, addCanonicalizerPassWithoutRegionSimplification));
});
}
/// 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, MLIRToLLVMPassPipelineConfig &pc) {
// Early Optimizer EP Callback
pc.invokeFIROptEarlyEPCallbacks(pm, pc.OptLevel);
// simplify the IR
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCSEPass());
fir::addAVC(pm, pc.OptLevel);
addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion);
pm.addPass(mlir::createCanonicalizerPass(config));
pm.addPass(fir::createSimplifyRegionLite());
if (pc.OptLevel.isOptimizingForSpeed()) {
// These passes may increase code size.
pm.addPass(fir::createSimplifyIntrinsics());
pm.addPass(fir::createAlgebraicSimplificationPass(config));
if (enableConstantArgumentGlobalisation)
pm.addPass(fir::createConstantArgumentGlobalisationOpt());
}
if (pc.LoopVersioning)
pm.addPass(fir::createLoopVersioning());
pm.addPass(mlir::createCSEPass());
if (pc.StackArrays)
pm.addPass(fir::createStackArrays());
else
fir::addMemoryAllocationOpt(pm);
// FIR Inliner Callback
pc.invokeFIRInlinerCallback(pm, pc.OptLevel);
pm.addPass(fir::createSimplifyRegionLite());
pm.addPass(mlir::createCSEPass());
// Polymorphic types
pm.addPass(fir::createPolymorphicOpConversion());
pm.addPass(fir::createAssumedRankOpConversion());
if (pc.AliasAnalysis && !disableFirAliasTags && !useOldAliasTags)
pm.addPass(fir::createAddAliasTags());
addNestedPassToAllTopLevelOperations(pm, fir::createStackReclaim);
// convert control flow to CFG form
fir::addCfgConversionPass(pm, pc);
pm.addPass(mlir::createConvertSCFToCFPass());
pm.addPass(mlir::createCanonicalizerPass(config));
pm.addPass(fir::createSimplifyRegionLite());
pm.addPass(mlir::createCSEPass());
// Last Optimizer EP Callback
pc.invokeFIROptLastEPCallbacks(pm, pc.OptLevel);
}
/// Create a pass pipeline for lowering from HLFIR to FIR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
inline void createHLFIRToFIRPassPipeline(
mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
if (optLevel.isOptimizingForSpeed()) {
addCanonicalizerPassWithoutRegionSimplification(pm);
addNestedPassToAllTopLevelOperations(
pm, hlfir::createSimplifyHLFIRIntrinsics);
}
addNestedPassToAllTopLevelOperations(pm, hlfir::createInlineElementals);
if (optLevel.isOptimizingForSpeed()) {
addCanonicalizerPassWithoutRegionSimplification(pm);
pm.addPass(mlir::createCSEPass());
addNestedPassToAllTopLevelOperations(
pm, hlfir::createOptimizedBufferization);
}
pm.addPass(hlfir::createLowerHLFIROrderedAssignments());
pm.addPass(hlfir::createLowerHLFIRIntrinsics());
pm.addPass(hlfir::createBufferizeHLFIR());
pm.addPass(hlfir::createConvertHLFIRtoFIR());
}
/// Create a pass pipeline for handling certain OpenMP transformations needed
/// prior to FIR lowering.
///
/// WARNING: These passes must be run immediately after the lowering to ensure
/// that the FIR is correct with respect to OpenMP operations/attributes.
///
/// \param pm - MLIR pass manager that will hold the pipeline definition.
/// \param isTargetDevice - Whether code is being generated for a target device
/// rather than the host device.
inline void createOpenMPFIRPassPipeline(
mlir::PassManager &pm, bool isTargetDevice) {
pm.addPass(flangomp::createMapInfoFinalizationPass());
pm.addPass(flangomp::createMarkDeclareTargetPass());
if (isTargetDevice)
pm.addPass(flangomp::createFunctionFilteringPass());
}
#if !defined(FLANG_EXCLUDE_CODEGEN)
inline void createDebugPasses(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel OptLevel, llvm::StringRef inputFilename) {
if (debugLevel != llvm::codegenoptions::NoDebugInfo)
addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename);
}
inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig config, llvm::StringRef inputFilename = {}) {
fir::addBoxedProcedurePass(pm);
addNestedPassToAllTopLevelOperations(pm, fir::createAbstractResultOpt);
fir::addCodeGenRewritePass(
pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo));
fir::addTargetRewritePass(pm);
fir::addCompilerGeneratedNamesConversionPass(pm);
fir::addExternalNameConversionPass(pm, config.Underscoring);
fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename);
if (config.VScaleMin != 0)
pm.addPass(fir::createVScaleAttr({{config.VScaleMin, config.VScaleMax}}));
// Add function attributes
mlir::LLVM::framePointerKind::FramePointerKind framePointerKind;
if (config.FramePointerKind != llvm::FramePointerKind::None ||
config.NoInfsFPMath || config.NoNaNsFPMath || config.ApproxFuncFPMath ||
config.NoSignedZerosFPMath || config.UnsafeFPMath) {
if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf)
framePointerKind =
mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf;
else if (config.FramePointerKind == llvm::FramePointerKind::All)
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All;
else
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
pm.addPass(fir::createFunctionAttr({framePointerKind, config.NoInfsFPMath,
config.NoNaNsFPMath, config.ApproxFuncFPMath,
config.NoSignedZerosFPMath, config.UnsafeFPMath}));
}
fir::addFIRToLLVMPass(pm, config);
}
/// Create a pass pipeline for lowering from MLIR to LLVM IR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig &config, llvm::StringRef inputFilename = {}) {
fir::createHLFIRToFIRPassPipeline(pm, config.OptLevel);
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm, config);
// Add codegen pass pipeline.
fir::createDefaultFIRCodeGenPassPipeline(pm, config, inputFilename);
}
#undef FLANG_EXCLUDE_CODEGEN
#endif
} // namespace fir

View File

@@ -12,7 +12,7 @@ endif()
if(flang_vc AND LLVM_APPEND_VC_REV)
set(flang_source_dir ${FLANG_SOURCE_DIR})
endif()
# Create custom target to generate the VC revision include.
add_custom_command(OUTPUT "${version_inc}"
DEPENDS "${llvm_vc}" "${flang_vc}" "${generate_vcs_version_script}"
@@ -34,7 +34,6 @@ if(FLANG_VENDOR)
PROPERTIES COMPILE_DEFINITIONS "FLANG_VENDOR=\"${FLANG_VENDOR} \"")
endif()
add_flang_library(FortranCommon
Fortran.cpp
Fortran-features.cpp

View File

@@ -38,6 +38,7 @@ add_flang_library(flangFrontend
FIRTransforms
HLFIRDialect
HLFIRTransforms
flangPasses
FlangOpenMPTransforms
MLIRTransforms
MLIRBuiltinToLLVMIRTranslation

View File

@@ -21,6 +21,7 @@
#include "flang/Lower/Support/Verifier.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/Dialect/Support/KindMapping.h"
#include "flang/Optimizer/Passes/Pipelines.h"
#include "flang/Optimizer/Support/DataLayout.h"
#include "flang/Optimizer/Support/InitFIR.h"
#include "flang/Optimizer/Support/Utils.h"
@@ -77,8 +78,6 @@
#include <memory>
#include <system_error>
#include "flang/Tools/CLOptions.inc"
namespace llvm {
extern cl::opt<bool> PrintPipelinePasses;
} // namespace llvm

View File

@@ -1,8 +1,9 @@
add_subdirectory(Analysis)
add_subdirectory(Builder)
add_subdirectory(CodeGen)
add_subdirectory(Dialect)
add_subdirectory(HLFIR)
add_subdirectory(OpenMP)
add_subdirectory(Passes)
add_subdirectory(Support)
add_subdirectory(Transforms)
add_subdirectory(Analysis)
add_subdirectory(OpenMP)

View File

@@ -0,0 +1,22 @@
add_flang_library(flangPasses
CommandLineOpts.cpp
Pipelines.cpp
DEPENDS
FortranCommon
LINK_LIBS
FIRCodeGen
FIRTransforms
FlangOpenMPTransforms
FortranCommon
HLFIRTransforms
MLIRPass
MLIRReconcileUnrealizedCasts
MLIRSCFToControlFlow
MLIRSupport
MLIRTransforms
LINK_COMPONENTS
Passes
)

View File

@@ -0,0 +1,73 @@
//===-- CommandLineOpts.cpp -- shared 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.
#include "flang/Optimizer/Passes/CommandLineOpts.h"
using namespace llvm;
#define DisableOption(DOName, DOOption, DODescription) \
cl::opt<bool> disable##DOName("disable-" DOOption, \
cl::desc("disable " DODescription " pass"), \
cl::init(false), cl::Hidden)
#define EnableOption(EOName, EOOption, EODescription) \
cl::opt<bool> enable##EOName("enable-" EOOption, \
cl::desc("enable " EODescription " pass"), \
cl::init(false), cl::Hidden)
cl::opt<bool> dynamicArrayStackToHeapAllocation(
"fdynamic-heap-array",
cl::desc("place all array allocations of dynamic size on the heap"),
cl::init(false), cl::Hidden);
cl::opt<std::size_t> arrayStackAllocationThreshold(
"fstack-array-size",
cl::desc(
"place all array allocations more than <size> elements on the heap"),
cl::init(~static_cast<std::size_t>(0)), cl::Hidden);
cl::opt<bool> ignoreMissingTypeDescriptors(
"ignore-missing-type-desc",
cl::desc("ignore failures to find derived type descriptors when "
"translating FIR to LLVM"),
cl::init(false), cl::Hidden);
OptimizationLevel defaultOptLevel{OptimizationLevel::O0};
codegenoptions::DebugInfoKind noDebugInfo{codegenoptions::NoDebugInfo};
/// 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");
DisableOption(FirAliasTags, "fir-alias-tags", "fir alias analysis");
cl::opt<bool> useOldAliasTags(
"use-old-alias-tags",
cl::desc("Use a single TBAA tree for all functions and do not use "
"the FIR alias tags pass"),
cl::init(false), cl::Hidden);
/// CodeGen Passes
DisableOption(CodeGenRewrite, "codegen-rewrite", "rewrite FIR for codegen");
DisableOption(TargetRewrite, "target-rewrite", "rewrite FIR for target");
DisableOption(DebugInfo, "debug-info", "Add debug info");
DisableOption(FirToLlvmIr, "fir-to-llvmir", "FIR to LLVM-IR dialect");
DisableOption(LlvmIrToLlvm, "llvm", "conversion to LLVM");
DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite",
"rewrite boxed procedures");
DisableOption(ExternalNameConversion, "external-name-interop",
"convert names with external convention");
EnableOption(ConstantArgumentGlobalisation, "constant-argument-globalisation",
"the local constant argument to global constant conversion");
DisableOption(CompilerGeneratedNamesConversion, "compiler-generated-names",
"replace special symbols in compiler generated names");

View File

@@ -0,0 +1,314 @@
//===-- Pipelines.cpp -- FIR pass pipelines ---------------------*- 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 utilties to setup FIR pass pipelines. These are
/// common to flang and the test tools.
#include "flang/Optimizer/Passes/Pipelines.h"
namespace fir {
void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm,
PassConstructor ctor) {
addNestedPassToOps<mlir::func::FuncOp, mlir::omp::DeclareReductionOp,
mlir::omp::PrivateClauseOp, fir::GlobalOp>(pm, ctor);
}
void addNestedPassToAllTopLevelOperationsConditionally(
mlir::PassManager &pm, llvm::cl::opt<bool> &disabled,
PassConstructor ctor) {
if (!disabled)
addNestedPassToAllTopLevelOperations(pm, ctor);
}
void addCanonicalizerPassWithoutRegionSimplification(mlir::OpPassManager &pm) {
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCanonicalizerPass(config));
}
void addCfgConversionPass(mlir::PassManager &pm,
const MLIRToLLVMPassPipelineConfig &config) {
if (config.NSWOnLoopVarInc)
addNestedPassToAllTopLevelOperationsConditionally(
pm, disableCfgConversion, fir::createCFGConversionPassWithNSW);
else
addNestedPassToAllTopLevelOperationsConditionally(pm, disableCfgConversion,
fir::createCFGConversion);
}
void addAVC(mlir::PassManager &pm, const llvm::OptimizationLevel &optLevel) {
ArrayValueCopyOptions options;
options.optimizeConflicts = optLevel.isOptimizingForSpeed();
addNestedPassConditionally<mlir::func::FuncOp>(
pm, disableFirAvc, [&]() { return createArrayValueCopyPass(options); });
}
void addMemoryAllocationOpt(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::func::FuncOp>(pm, disableFirMao, [&]() {
return fir::createMemoryAllocationOpt(
{dynamicArrayStackToHeapAllocation, arrayStackAllocationThreshold});
});
}
void addCodeGenRewritePass(mlir::PassManager &pm, bool preserveDeclare) {
fir::CodeGenRewriteOptions options;
options.preserveDeclare = preserveDeclare;
addPassConditionally(pm, disableCodeGenRewrite,
[&]() { return fir::createCodeGenRewrite(options); });
}
void addTargetRewritePass(mlir::PassManager &pm) {
addPassConditionally(pm, disableTargetRewrite,
[]() { return fir::createTargetRewritePass(); });
}
mlir::LLVM::DIEmissionKind
getEmissionKind(llvm::codegenoptions::DebugInfoKind kind) {
switch (kind) {
case llvm::codegenoptions::DebugInfoKind::FullDebugInfo:
return mlir::LLVM::DIEmissionKind::Full;
case llvm::codegenoptions::DebugInfoKind::DebugLineTablesOnly:
return mlir::LLVM::DIEmissionKind::LineTablesOnly;
default:
return mlir::LLVM::DIEmissionKind::None;
}
}
void addDebugInfoPass(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel optLevel,
llvm::StringRef inputFilename) {
fir::AddDebugInfoOptions options;
options.debugLevel = getEmissionKind(debugLevel);
options.isOptimized = optLevel != llvm::OptimizationLevel::O0;
options.inputFilename = inputFilename;
addPassConditionally(pm, disableDebugInfo,
[&]() { return fir::createAddDebugInfoPass(options); });
}
void addFIRToLLVMPass(mlir::PassManager &pm,
const MLIRToLLVMPassPipelineConfig &config) {
fir::FIRToLLVMPassOptions options;
options.ignoreMissingTypeDescriptors = ignoreMissingTypeDescriptors;
options.applyTBAA = config.AliasAnalysis;
options.forceUnifiedTBAATree = useOldAliasTags;
options.typeDescriptorsRenamedForAssembly =
!disableCompilerGeneratedNamesConversion;
addPassConditionally(pm, disableFirToLlvmIr,
[&]() { return fir::createFIRToLLVMPass(options); });
// The dialect conversion framework may leave dead unrealized_conversion_cast
// ops behind, so run reconcile-unrealized-casts to clean them up.
addPassConditionally(pm, disableFirToLlvmIr, [&]() {
return mlir::createReconcileUnrealizedCastsPass();
});
}
void addLLVMDialectToLLVMPass(mlir::PassManager &pm,
llvm::raw_ostream &output) {
addPassConditionally(pm, disableLlvmIrToLlvm, [&]() {
return fir::createLLVMDialectToLLVMPass(output);
});
}
void addBoxedProcedurePass(mlir::PassManager &pm) {
addPassConditionally(pm, disableBoxedProcedureRewrite,
[&]() { return fir::createBoxedProcedurePass(); });
}
void addExternalNameConversionPass(mlir::PassManager &pm,
bool appendUnderscore) {
addPassConditionally(pm, disableExternalNameConversion, [&]() {
return fir::createExternalNameConversion({appendUnderscore});
});
}
void addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm) {
addPassConditionally(pm, disableCompilerGeneratedNamesConversion, [&]() {
return fir::createCompilerGeneratedNamesConversion();
});
}
// Use inliner extension point callback to register the default inliner pass.
void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config) {
config.registerFIRInlinerCallback(
[](mlir::PassManager &pm, llvm::OptimizationLevel level) {
llvm::StringMap<mlir::OpPassManager> pipelines;
// The default inliner pass adds the canonicalizer pass with the default
// configuration.
pm.addPass(mlir::createInlinerPass(
pipelines, addCanonicalizerPassWithoutRegionSimplification));
});
}
/// 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
void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig &pc) {
// Early Optimizer EP Callback
pc.invokeFIROptEarlyEPCallbacks(pm, pc.OptLevel);
// simplify the IR
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled;
pm.addPass(mlir::createCSEPass());
fir::addAVC(pm, pc.OptLevel);
addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion);
pm.addPass(mlir::createCanonicalizerPass(config));
pm.addPass(fir::createSimplifyRegionLite());
if (pc.OptLevel.isOptimizingForSpeed()) {
// These passes may increase code size.
pm.addPass(fir::createSimplifyIntrinsics());
pm.addPass(fir::createAlgebraicSimplificationPass(config));
if (enableConstantArgumentGlobalisation)
pm.addPass(fir::createConstantArgumentGlobalisationOpt());
}
if (pc.LoopVersioning)
pm.addPass(fir::createLoopVersioning());
pm.addPass(mlir::createCSEPass());
if (pc.StackArrays)
pm.addPass(fir::createStackArrays());
else
fir::addMemoryAllocationOpt(pm);
// FIR Inliner Callback
pc.invokeFIRInlinerCallback(pm, pc.OptLevel);
pm.addPass(fir::createSimplifyRegionLite());
pm.addPass(mlir::createCSEPass());
// Polymorphic types
pm.addPass(fir::createPolymorphicOpConversion());
pm.addPass(fir::createAssumedRankOpConversion());
if (pc.AliasAnalysis && !disableFirAliasTags && !useOldAliasTags)
pm.addPass(fir::createAddAliasTags());
addNestedPassToAllTopLevelOperations(pm, fir::createStackReclaim);
// convert control flow to CFG form
fir::addCfgConversionPass(pm, pc);
pm.addPass(mlir::createConvertSCFToCFPass());
pm.addPass(mlir::createCanonicalizerPass(config));
pm.addPass(fir::createSimplifyRegionLite());
pm.addPass(mlir::createCSEPass());
// Last Optimizer EP Callback
pc.invokeFIROptLastEPCallbacks(pm, pc.OptLevel);
}
/// Create a pass pipeline for lowering from HLFIR to FIR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
void createHLFIRToFIRPassPipeline(mlir::PassManager &pm,
llvm::OptimizationLevel optLevel) {
if (optLevel.isOptimizingForSpeed()) {
addCanonicalizerPassWithoutRegionSimplification(pm);
addNestedPassToAllTopLevelOperations(pm,
hlfir::createSimplifyHLFIRIntrinsics);
}
addNestedPassToAllTopLevelOperations(pm, hlfir::createInlineElementals);
if (optLevel.isOptimizingForSpeed()) {
addCanonicalizerPassWithoutRegionSimplification(pm);
pm.addPass(mlir::createCSEPass());
addNestedPassToAllTopLevelOperations(pm,
hlfir::createOptimizedBufferization);
}
pm.addPass(hlfir::createLowerHLFIROrderedAssignments());
pm.addPass(hlfir::createLowerHLFIRIntrinsics());
pm.addPass(hlfir::createBufferizeHLFIR());
pm.addPass(hlfir::createConvertHLFIRtoFIR());
}
/// Create a pass pipeline for handling certain OpenMP transformations needed
/// prior to FIR lowering.
///
/// WARNING: These passes must be run immediately after the lowering to ensure
/// that the FIR is correct with respect to OpenMP operations/attributes.
///
/// \param pm - MLIR pass manager that will hold the pipeline definition.
/// \param isTargetDevice - Whether code is being generated for a target device
/// rather than the host device.
void createOpenMPFIRPassPipeline(mlir::PassManager &pm, bool isTargetDevice) {
pm.addPass(flangomp::createMapInfoFinalizationPass());
pm.addPass(flangomp::createMarkDeclareTargetPass());
if (isTargetDevice)
pm.addPass(flangomp::createFunctionFilteringPass());
}
void createDebugPasses(mlir::PassManager &pm,
llvm::codegenoptions::DebugInfoKind debugLevel,
llvm::OptimizationLevel OptLevel,
llvm::StringRef inputFilename) {
if (debugLevel != llvm::codegenoptions::NoDebugInfo)
addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename);
}
void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig config,
llvm::StringRef inputFilename) {
fir::addBoxedProcedurePass(pm);
addNestedPassToAllTopLevelOperations(pm, fir::createAbstractResultOpt);
fir::addCodeGenRewritePass(
pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo));
fir::addTargetRewritePass(pm);
fir::addCompilerGeneratedNamesConversionPass(pm);
fir::addExternalNameConversionPass(pm, config.Underscoring);
fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename);
if (config.VScaleMin != 0)
pm.addPass(fir::createVScaleAttr({{config.VScaleMin, config.VScaleMax}}));
// Add function attributes
mlir::LLVM::framePointerKind::FramePointerKind framePointerKind;
if (config.FramePointerKind != llvm::FramePointerKind::None ||
config.NoInfsFPMath || config.NoNaNsFPMath || config.ApproxFuncFPMath ||
config.NoSignedZerosFPMath || config.UnsafeFPMath) {
if (config.FramePointerKind == llvm::FramePointerKind::NonLeaf)
framePointerKind =
mlir::LLVM::framePointerKind::FramePointerKind::NonLeaf;
else if (config.FramePointerKind == llvm::FramePointerKind::All)
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::All;
else
framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
pm.addPass(fir::createFunctionAttr(
{framePointerKind, config.NoInfsFPMath, config.NoNaNsFPMath,
config.ApproxFuncFPMath, config.NoSignedZerosFPMath,
config.UnsafeFPMath}));
}
fir::addFIRToLLVMPass(pm, config);
}
/// Create a pass pipeline for lowering from MLIR to LLVM IR
///
/// \param pm - MLIR pass manager that will hold the pipeline definition
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
MLIRToLLVMPassPipelineConfig &config,
llvm::StringRef inputFilename) {
fir::createHLFIRToFIRPassPipeline(pm, config.OptLevel);
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm, config);
// Add codegen pass pipeline.
fir::createDefaultFIRCodeGenPassPipeline(pm, config, inputFilename);
}
} // namespace fir

View File

@@ -1,14 +1,14 @@
set(LLVM_LINK_COMPONENTS
Passes
AllTargetsCodeGens
AllTargetsDescs
AllTargetsInfos
TargetParser
Passes
AllTargetsCodeGens
AllTargetsDescs
AllTargetsInfos
TargetParser
)
add_flang_tool(bbc bbc.cpp
DEPENDS
FIROptCodeGenPassIncGen
DEPENDS
FIROptCodeGenPassIncGen
)
llvm_update_compile_flags(bbc)
@@ -16,23 +16,24 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
get_property(extension_libs GLOBAL PROPERTY MLIR_EXTENSION_LIBS)
target_link_libraries(bbc PRIVATE
CUFAttrs
CUFDialect
FIRDialect
FIRDialectSupport
FIRSupport
FIRTransforms
FIRBuilder
HLFIRDialect
HLFIRTransforms
FlangOpenMPTransforms
${dialect_libs}
${extension_libs}
MLIRAffineToStandard
MLIRSCFToControlFlow
FortranCommon
FortranParser
FortranEvaluate
FortranSemantics
FortranLower
CUFAttrs
CUFDialect
FIRDialect
FIRDialectSupport
FIRSupport
FIRTransforms
FIRBuilder
HLFIRDialect
HLFIRTransforms
flangPasses
FlangOpenMPTransforms
${dialect_libs}
${extension_libs}
MLIRAffineToStandard
MLIRSCFToControlFlow
FortranCommon
FortranParser
FortranEvaluate
FortranSemantics
FortranLower
)

View File

@@ -233,7 +233,8 @@ static llvm::cl::opt<bool>
llvm::cl::init(false));
#define FLANG_EXCLUDE_CODEGEN
#include "flang/Tools/CLOptions.inc"
#include "flang/Optimizer/Passes/CommandLineOpts.h"
#include "flang/Optimizer/Passes/Pipelines.h"
//===----------------------------------------------------------------------===//

View File

@@ -17,7 +17,9 @@ target_link_libraries(tco PRIVATE
FIRBuilder
HLFIRDialect
HLFIRTransforms
flangPasses
FlangOpenMPTransforms
FortranCommon
${dialect_libs}
${extension_libs}
MLIRIR

View File

@@ -70,7 +70,8 @@ static cl::opt<bool> codeGenLLVM(
cl::desc("Run only CodeGen passes and translate FIR to LLVM IR"),
cl::init(false));
#include "flang/Tools/CLOptions.inc"
#include "flang/Optimizer/Passes/CommandLineOpts.h"
#include "flang/Optimizer/Passes/Pipelines.h"
static void printModule(mlir::ModuleOp mod, raw_ostream &output) {
output << mod << '\n';