FLANG
CrossToolHelpers.h
1//===-- Tools/CrossToolHelpers.h --------------------------------- *-C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// A header file for containing functionallity that is used across Flang tools,
9// such as helper functions which apply or generate information needed accross
10// tools like bbc and flang.
11//===----------------------------------------------------------------------===//
12
13#ifndef FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
14#define FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
15
16#include "flang/Frontend/CodeGenOptions.h"
17#include "flang/Support/LangOptions.h"
19#include <cstdint>
20
21#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
22#include "mlir/IR/BuiltinOps.h"
23#include "mlir/Pass/PassRegistry.h"
24#include "llvm/ADT/SmallVector.h"
25#include "llvm/Frontend/Debug/Options.h"
26#include "llvm/Passes/OptimizationLevel.h"
27
28// Flang Extension Point Callbacks
30public:
31 void registerFIROptEarlyEPCallbacks(
32 const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
33 &C) {
34 FIROptEarlyEPCallbacks.push_back(C);
35 }
36
37 void registerFIRInlinerCallback(
38 const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
39 &C) {
40 FIRInlinerCallback.push_back(C);
41 }
42
43 void registerFIROptLastEPCallbacks(
44 const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
45 &C) {
46 FIROptLastEPCallbacks.push_back(C);
47 }
48
49 void invokeFIROptEarlyEPCallbacks(
50 mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
51 for (auto &C : FIROptEarlyEPCallbacks)
52 C(pm, optLevel);
53 };
54
55 void invokeFIRInlinerCallback(
56 mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
57 for (auto &C : FIRInlinerCallback)
58 C(pm, optLevel);
59 };
60
61 void invokeFIROptLastEPCallbacks(
62 mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
63 for (auto &C : FIROptLastEPCallbacks)
64 C(pm, optLevel);
65 };
66
67private:
69 std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
70 FIROptEarlyEPCallbacks;
71
73 std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
74 FIRInlinerCallback;
75
77 std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
78 FIROptLastEPCallbacks;
79};
80
82struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
83 explicit MLIRToLLVMPassPipelineConfig(llvm::OptimizationLevel level) {
84 OptLevel = level;
85 }
86 explicit MLIRToLLVMPassPipelineConfig(llvm::OptimizationLevel level,
88 const Fortran::common::MathOptionsBase &mathOpts) {
89 OptLevel = level;
90 StackArrays = opts.StackArrays;
91 Underscoring = opts.Underscoring;
92 LoopVersioning = opts.LoopVersioning;
93 DebugInfo = opts.getDebugInfo();
94 AliasAnalysis = opts.AliasAnalysis;
95 FramePointerKind = opts.getFramePointer();
96 // The logic for setting these attributes is intended to match the logic
97 // used in Clang.
98 NoInfsFPMath = mathOpts.getNoHonorInfs();
99 NoNaNsFPMath = mathOpts.getNoHonorNaNs();
100 ApproxFuncFPMath = mathOpts.getApproxFunc();
101 NoSignedZerosFPMath = mathOpts.getNoSignedZeros();
102 UnsafeFPMath = mathOpts.getAssociativeMath() &&
103 mathOpts.getReciprocalMath() && NoSignedZerosFPMath &&
104 ApproxFuncFPMath && mathOpts.getFPContractEnabled();
107 if (opts.InstrumentFunctions) {
108 InstrumentFunctionEntry = "__cyg_profile_func_enter";
109 InstrumentFunctionExit = "__cyg_profile_func_exit";
110 }
111 DwarfVersion = opts.DwarfVersion;
113 }
114
115 llvm::OptimizationLevel OptLevel;
116 bool StackArrays = false;
117 bool Underscoring = true;
118 bool LoopVersioning = false;
119 bool AliasAnalysis = false;
120 llvm::codegenoptions::DebugInfoKind DebugInfo =
121 llvm::codegenoptions::NoDebugInfo;
122 llvm::FramePointerKind FramePointerKind =
123 llvm::FramePointerKind::None;
124 unsigned VScaleMin = 0;
125 unsigned VScaleMax = 0;
126 bool NoInfsFPMath = false;
127 bool NoNaNsFPMath = false;
128 bool ApproxFuncFPMath = false;
130 false;
131 bool UnsafeFPMath = false;
132 std::string Reciprocals = "";
134 std::string PreferVectorWidth = "";
136 bool NSWOnLoopVarInc = true;
137 bool EnableOpenMP = false;
138 bool EnableOpenMPSimd = false;
141 "";
144 "";
147 Fortran::frontend::CodeGenOptions::ComplexRangeKind::
148 CX_Full;
149 int32_t DwarfVersion = 0;
150 std::string SplitDwarfFile = "";
151};
152
153struct OffloadModuleOpts {
154 OffloadModuleOpts() {}
155 OffloadModuleOpts(uint32_t OpenMPTargetDebug, bool OpenMPTeamSubscription,
156 bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
157 bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
158 bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
159 std::string OMPHostIRFile = {},
160 const std::vector<llvm::Triple> &OMPTargetTriples = {},
161 bool NoGPULib = false)
162 : OpenMPTargetDebug(OpenMPTargetDebug),
163 OpenMPTeamSubscription(OpenMPTeamSubscription),
164 OpenMPThreadSubscription(OpenMPThreadSubscription),
165 OpenMPNoThreadState(OpenMPNoThreadState),
166 OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
167 OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
168 OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
169 OMPHostIRFile(OMPHostIRFile),
170 OMPTargetTriples(OMPTargetTriples.begin(), OMPTargetTriples.end()),
171 NoGPULib(NoGPULib) {}
172
173 OffloadModuleOpts(Fortran::common::LangOptions &Opts)
174 : OpenMPTargetDebug(Opts.OpenMPTargetDebug),
175 OpenMPTeamSubscription(Opts.OpenMPTeamSubscription),
176 OpenMPThreadSubscription(Opts.OpenMPThreadSubscription),
177 OpenMPNoThreadState(Opts.OpenMPNoThreadState),
178 OpenMPNoNestedParallelism(Opts.OpenMPNoNestedParallelism),
179 OpenMPIsTargetDevice(Opts.OpenMPIsTargetDevice),
180 OpenMPIsGPU(Opts.OpenMPIsGPU), OpenMPForceUSM(Opts.OpenMPForceUSM),
181 OpenMPVersion(Opts.OpenMPVersion), OMPHostIRFile(Opts.OMPHostIRFile),
182 OMPTargetTriples(Opts.OMPTargetTriples), NoGPULib(Opts.NoGPULib) {}
183
184 uint32_t OpenMPTargetDebug = 0;
185 bool OpenMPTeamSubscription = false;
186 bool OpenMPThreadSubscription = false;
187 bool OpenMPNoThreadState = false;
188 bool OpenMPNoNestedParallelism = false;
189 bool OpenMPIsTargetDevice = false;
190 bool OpenMPIsGPU = false;
191 bool OpenMPForceUSM = false;
192 uint32_t OpenMPVersion = 31;
193 std::string OMPHostIRFile = {};
194 std::vector<llvm::Triple> OMPTargetTriples = {};
195 bool NoGPULib = false;
196};
197
198// Shares assinging of the OpenMP OffloadModuleInterface and its assorted
199// attributes accross Flang tools (bbc/flang)
200[[maybe_unused]] static void setOffloadModuleInterfaceAttributes(
201 mlir::ModuleOp module, OffloadModuleOpts Opts) {
202 // Should be registered by the OpenMPDialect
203 if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
204 module.getOperation())) {
205 offloadMod.setIsTargetDevice(Opts.OpenMPIsTargetDevice);
206 offloadMod.setIsGPU(Opts.OpenMPIsGPU);
207 if (Opts.OpenMPForceUSM) {
208 offloadMod.setRequires(mlir::omp::ClauseRequires::unified_shared_memory);
209 }
210 if (Opts.OpenMPIsTargetDevice) {
211 offloadMod.setFlags(Opts.OpenMPTargetDebug, Opts.OpenMPTeamSubscription,
212 Opts.OpenMPThreadSubscription, Opts.OpenMPNoThreadState,
213 Opts.OpenMPNoNestedParallelism, Opts.OpenMPVersion, Opts.NoGPULib);
214
215 if (!Opts.OMPHostIRFile.empty())
216 offloadMod.setHostIRFilePath(Opts.OMPHostIRFile);
217 }
218 auto strTriples = llvm::to_vector(llvm::map_range(Opts.OMPTargetTriples,
219 [](llvm::Triple triple) { return triple.normalize(); }));
220 offloadMod.setTargetTriples(strTriples);
221 }
222}
223
224[[maybe_unused]] static void setOpenMPVersionAttribute(
225 mlir::ModuleOp module, int64_t version) {
226 module.getOperation()->setAttr(
227 mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
228 mlir::omp::VersionAttr::get(module.getContext(), version));
229}
230
231[[maybe_unused]] static int64_t getOpenMPVersionAttribute(
232 mlir::ModuleOp module, int64_t fallback = -1) {
233 if (mlir::Attribute verAttr = module->getAttr("omp.version"))
234 return llvm::cast<mlir::omp::VersionAttr>(verAttr).getVersion();
235 return fallback;
236}
237
238#endif // FORTRAN_TOOLS_CROSS_TOOL_HELPERS_H
Definition CrossToolHelpers.h:29
Definition LangOptions.h:58
std::vector< llvm::Triple > OMPTargetTriples
List of triples passed in using -fopenmp-targets.
Definition LangOptions.h:76
std::string OMPHostIRFile
signed integer overflow handling
Definition LangOptions.h:73
Definition MathOptionsBase.h:22
Definition CodeGenOptions.h:50
std::string PreferVectorWidth
The prefered vector width, if requested by -mprefer-vector-width.
Definition CodeGenOptions.h:57
std::string SplitDwarfFile
Definition CodeGenOptions.h:173
std::string Reciprocals
List of reciprocal estimate sub-options.
Definition CodeGenOptions.h:60
ComplexRangeKind
Controls the various implementations for complex division.
Definition CodeGenOptions.h:203
Definition OpenACC.h:20
llvm::codegenoptions::DebugInfoKind DebugInfo
Debug info generation.
Definition CrossToolHelpers.h:120
bool NoSignedZerosFPMath
Set no-signed-zeros-fp-math attribute for functions.
Definition CrossToolHelpers.h:129
bool LoopVersioning
Run the version loop pass.
Definition CrossToolHelpers.h:118
unsigned VScaleMin
SVE vector range minimum.
Definition CrossToolHelpers.h:124
std::string Reciprocals
Definition CrossToolHelpers.h:132
llvm::FramePointerKind FramePointerKind
Add frame pointer to functions.
Definition CrossToolHelpers.h:122
bool NoNaNsFPMath
Set no-nans-fp-math attribute for functions.
Definition CrossToolHelpers.h:127
std::string SplitDwarfFile
File name for the split debug info.
Definition CrossToolHelpers.h:150
bool Underscoring
add underscores to function names.
Definition CrossToolHelpers.h:117
std::string PreferVectorWidth
Definition CrossToolHelpers.h:134
bool ApproxFuncFPMath
Set afn flag for instructions.
Definition CrossToolHelpers.h:128
unsigned VScaleMax
SVE vector range maximum.
Definition CrossToolHelpers.h:125
bool NoInfsFPMath
Set no-infs-fp-math attribute for functions.
Definition CrossToolHelpers.h:126
llvm::OptimizationLevel OptLevel
optimisation level
Definition CrossToolHelpers.h:115
bool EnableOpenMPSimd
Enable OpenMP simd-only mode.
Definition CrossToolHelpers.h:138
bool NSWOnLoopVarInc
Add nsw flag to loop variable increments.
Definition CrossToolHelpers.h:136
bool AliasAnalysis
Add TBAA tags to generated LLVMIR.
Definition CrossToolHelpers.h:119
Fortran::frontend::CodeGenOptions::ComplexRangeKind ComplexRange
Method for calculating complex number division.
Definition CrossToolHelpers.h:146
bool SkipConvertComplexPow
Do not run complex pow conversion.
Definition CrossToolHelpers.h:139
bool UnsafeFPMath
Set unsafe-fp-math attribute for functions.
Definition CrossToolHelpers.h:131
std::string InstrumentFunctionEntry
Definition CrossToolHelpers.h:140
bool StackArrays
convert memory allocations to alloca.
Definition CrossToolHelpers.h:116
int32_t DwarfVersion
Version of DWARF debug info to generate.
Definition CrossToolHelpers.h:149
bool EnableOpenMP
Enable OpenMP lowering.
Definition CrossToolHelpers.h:137
std::string InstrumentFunctionExit
Definition CrossToolHelpers.h:143
Definition CrossToolHelpers.h:153