FLANG
Target.h
1//===- Target.h - target specific details -----------------------*- 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//
9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef FORTRAN_OPTMIZER_CODEGEN_TARGET_H
14#define FORTRAN_OPTMIZER_CODEGEN_TARGET_H
15
16#include "flang/Optimizer/Dialect/FIRType.h"
17#include "flang/Optimizer/Dialect/Support/KindMapping.h"
18#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
19#include "mlir/IR/BuiltinTypes.h"
20#include "llvm/TargetParser/Triple.h"
21#include <memory>
22#include <tuple>
23#include <vector>
24
25namespace mlir {
26class DataLayout;
27}
28
29namespace fir {
30
31namespace details {
36class Attributes {
37public:
38 enum class IntegerExtension { None, Zero, Sign };
39
40 Attributes(unsigned short alignment = 0, bool byval = false,
41 bool sret = false, bool append = false,
42 IntegerExtension intExt = IntegerExtension::None,
43 bool indirect = false)
44 : alignment{alignment}, byval{byval}, sret{sret}, append{append},
45 indirect{indirect}, intExt{intExt} {}
46
47 unsigned getAlignment() const { return alignment; }
48 bool hasAlignment() const { return alignment != 0; }
49 bool isByVal() const { return byval; }
50 bool isSRet() const { return sret; }
58 bool isIndirect() const { return indirect; }
59 bool isAppend() const { return append; }
60 bool isZeroExt() const { return intExt == IntegerExtension::Zero; }
61 bool isSignExt() const { return intExt == IntegerExtension::Sign; }
62 llvm::StringRef getIntExtensionAttrName() const;
63
64private:
65 unsigned short alignment{};
66 bool byval : 1;
67 bool sret : 1;
68 bool append : 1;
69 bool indirect : 1;
70 IntegerExtension intExt;
71};
72
73} // namespace details
74
78class CodeGenSpecifics {
79public:
80 using Attributes = details::Attributes;
81 using TypeAndAttr = std::tuple<mlir::Type, Attributes>;
82 using Marshalling = std::vector<TypeAndAttr>;
83
84 static std::unique_ptr<CodeGenSpecifics>
85 get(mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
86 llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
87 llvm::StringRef targetABI, const mlir::DataLayout &dl);
88
89 static std::unique_ptr<CodeGenSpecifics>
90 get(mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap,
91 llvm::StringRef targetCPU, mlir::LLVM::TargetFeaturesAttr targetFeatures,
92 llvm::StringRef targetABI, const mlir::DataLayout &dl,
93 llvm::StringRef tuneCPU);
94
95 static TypeAndAttr getTypeAndAttr(mlir::Type t) { return TypeAndAttr{t, {}}; }
96
97 CodeGenSpecifics(mlir::MLIRContext *ctx, llvm::Triple &&trp,
98 KindMapping &&kindMap, llvm::StringRef targetCPU,
99 mlir::LLVM::TargetFeaturesAttr targetFeatures,
100 llvm::StringRef targetABI, const mlir::DataLayout &dl)
101 : context{*ctx}, triple{std::move(trp)}, kindMap{std::move(kindMap)},
102 targetCPU{targetCPU}, targetFeatures{targetFeatures},
103 targetABI{targetABI}, dataLayout{&dl}, tuneCPU{""} {}
104
105 CodeGenSpecifics(mlir::MLIRContext *ctx, llvm::Triple &&trp,
106 KindMapping &&kindMap, llvm::StringRef targetCPU,
107 mlir::LLVM::TargetFeaturesAttr targetFeatures,
108 llvm::StringRef targetABI, const mlir::DataLayout &dl,
109 llvm::StringRef tuneCPU)
110 : context{*ctx}, triple{std::move(trp)}, kindMap{std::move(kindMap)},
111 targetCPU{targetCPU}, targetFeatures{targetFeatures},
112 targetABI{targetABI}, dataLayout{&dl}, tuneCPU{tuneCPU} {}
113
114 CodeGenSpecifics() = delete;
115 virtual ~CodeGenSpecifics() {}
116
118 virtual mlir::Type complexMemoryType(mlir::Type eleTy) const = 0;
119
123 virtual Marshalling complexArgumentType(mlir::Location loc,
124 mlir::Type eleTy) const = 0;
125
128 virtual Marshalling complexReturnType(mlir::Location loc,
129 mlir::Type eleTy) const = 0;
130
132 virtual mlir::Type boxcharMemoryType(mlir::Type eleTy) const = 0;
133
137 virtual Marshalling
138 structArgumentType(mlir::Location loc, fir::RecordType recTy,
139 const Marshalling &previousArguments) const = 0;
140
143 virtual Marshalling structReturnType(mlir::Location loc,
144 fir::RecordType eleTy) const = 0;
145
148 virtual Marshalling boxcharArgumentType(mlir::Type eleTy) const = 0;
149
150 // Compute ABI rules for an integer argument of the given mlir::IntegerType
151 // \p argTy. Note that this methods is supposed to be called for
152 // arguments passed by value not via reference, e.g. the 'i1' argument here:
153 // declare i1 @_FortranAioOutputLogical(ptr, i1)
154 //
155 // \p loc is the location of the operation using/specifying the argument.
156 //
157 // Currently, the only supported marshalling is whether the argument
158 // should be zero or sign extended.
159 //
160 // The zero/sign extension is especially important to comply with the ABI
161 // used by C/C++ compiler that builds Fortran runtime. As in the above
162 // example the callee will expect the caller to zero extend the second
163 // argument up to the size of the C/C++'s 'int' type.
164 // The corresponding handling in clang is done in
165 // DefaultABIInfo::classifyArgumentType(), and the logic may brielfy
166 // be explained as some sort of extension is required if the integer
167 // type is shorter than the size of 'int' for the target.
168 // The related code is located in ASTContext::isPromotableIntegerType()
169 // and ABIInfo::isPromotableIntegerTypeForABI().
170 // In particular, the latter returns 'true' for 'bool', several kinds
171 // of 'char', 'short', 'wchar' and enumerated types.
172 // The type of the extensions (zero or sign) depends on the signedness
173 // of the original language type.
174 //
175 // It is not clear how to handle signless integer types.
176 // From the point of Fortran-C interface all supported integer types
177 // seem to be signed except for CFI_type_Bool/bool that is supported
178 // via signless 'i1', but that is treated as unsigned type by clang
179 // (e.g. 'bool' arguments are using 'zeroext' ABI).
180 virtual Marshalling integerArgumentType(mlir::Location loc,
181 mlir::IntegerType argTy) const = 0;
182
183 // By default, integer argument and return values use the same
184 // zero/sign extension rules.
185 virtual Marshalling integerReturnType(mlir::Location loc,
186 mlir::IntegerType argTy) const = 0;
187
188 // Returns width in bits of C/C++ 'int' type size.
189 virtual unsigned char getCIntTypeWidth() const = 0;
190
191 llvm::StringRef getTargetCPU() const { return targetCPU; }
192 llvm::StringRef getTuneCPU() const { return tuneCPU; }
193
194 mlir::LLVM::TargetFeaturesAttr getTargetFeatures() const {
195 return targetFeatures;
196 }
197
198 llvm::StringRef getTargetABI() const { return targetABI; }
199
200 const mlir::DataLayout &getDataLayout() const {
201 assert(dataLayout && "dataLayout must be set");
202 return *dataLayout;
203 }
204
205protected:
206 mlir::MLIRContext &context;
207 llvm::Triple triple;
208 KindMapping kindMap;
209 llvm::StringRef targetCPU;
210 mlir::LLVM::TargetFeaturesAttr targetFeatures;
211 llvm::StringRef targetABI;
212 const mlir::DataLayout *dataLayout = nullptr;
213 llvm::StringRef tuneCPU;
214};
215
216} // namespace fir
217
218#endif // FORTRAN_OPTMIZER_CODEGEN_TARGET_H
virtual Marshalling complexArgumentType(mlir::Location loc, mlir::Type eleTy) const =0
virtual mlir::Type complexMemoryType(mlir::Type eleTy) const =0
Type presentation of a complex<ele> type value in memory.
virtual mlir::Type boxcharMemoryType(mlir::Type eleTy) const =0
Type presentation of a boxchar<n> type value in memory.
virtual Marshalling structArgumentType(mlir::Location loc, fir::RecordType recTy, const Marshalling &previousArguments) const =0
virtual Marshalling boxcharArgumentType(mlir::Type eleTy) const =0
virtual Marshalling structReturnType(mlir::Location loc, fir::RecordType eleTy) const =0
virtual Marshalling complexReturnType(mlir::Location loc, mlir::Type eleTy) const =0
Definition KindMapping.h:48
Definition Target.h:36
bool isIndirect() const
Definition Target.h:58
Definition AbstractConverter.h:37
llvm::StringRef getTuneCPU(mlir::ModuleOp mod)
Get the tune CPU string from the Module or return a null reference.
Definition FIRContext.cpp:142
Definition AbstractConverter.h:32