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