xref: /llvm-project/flang/include/flang/Optimizer/CodeGen/TypeConverter.h (revision 79e788d02eefdacb08af365389b9055518f3fad6)
1 //===-- TypeConverter.h -- type conversion ----------------------*- 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_OPTIMIZER_CODEGEN_TYPECONVERTER_H
14 #define FORTRAN_OPTIMIZER_CODEGEN_TYPECONVERTER_H
15 
16 #include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done
17 #include "flang/Optimizer/CodeGen/TBAABuilder.h"
18 #include "flang/Optimizer/CodeGen/Target.h"
19 #include "flang/Optimizer/Dialect/FIRType.h"
20 #include "flang/Optimizer/Dialect/Support/FIRContext.h"
21 #include "flang/Optimizer/Dialect/Support/KindMapping.h"
22 #include "mlir/Conversion/LLVMCommon/TypeConverter.h"
23 #include "llvm/Support/Debug.h"
24 
25 // Position of the different values in a `fir.box`.
26 static constexpr unsigned kAddrPosInBox = 0;
27 static constexpr unsigned kElemLenPosInBox = 1;
28 static constexpr unsigned kVersionPosInBox = 2;
29 static constexpr unsigned kRankPosInBox = 3;
30 static constexpr unsigned kTypePosInBox = 4;
31 static constexpr unsigned kAttributePosInBox = 5;
32 static constexpr unsigned kExtraPosInBox = 6;
33 static constexpr unsigned kDimsPosInBox = 7;
34 static constexpr unsigned kOptTypePtrPosInBox = 8;
35 static constexpr unsigned kOptRowTypePosInBox = 9;
36 
37 // Position of the different values in [dims]
38 static constexpr unsigned kDimLowerBoundPos = 0;
39 static constexpr unsigned kDimExtentPos = 1;
40 static constexpr unsigned kDimStridePos = 2;
41 
42 namespace mlir {
43 class DataLayout;
44 }
45 
46 namespace fir {
47 
48 /// FIR type converter
49 /// This converts FIR types to LLVM types (for now)
50 class LLVMTypeConverter : public mlir::LLVMTypeConverter {
51 public:
52   LLVMTypeConverter(mlir::ModuleOp module, bool applyTBAA,
53                     bool forceUnifiedTBAATree, const mlir::DataLayout &);
54 
55   // i32 is used here because LLVM wants i32 constants when indexing into struct
56   // types. Indexing into other aggregate types is more flexible.
57   mlir::Type offsetType() const;
58 
59   // i64 can be used to index into aggregates like arrays
60   mlir::Type indexType() const;
61 
62   // fir.type<name(p : TY'...){f : TY...}>  -->  llvm<"%name = { ty... }">
63   std::optional<llvm::LogicalResult>
64   convertRecordType(fir::RecordType derived,
65                     llvm::SmallVectorImpl<mlir::Type> &results, bool isPacked);
66 
67   // Is an extended descriptor needed given the element type of a fir.box type ?
68   // Extended descriptors are required for derived types.
69   bool requiresExtendedDesc(mlir::Type boxElementType) const;
70 
71   // Magic value to indicate we do not know the rank of an entity, either
72   // because it is assumed rank or because we have not determined it yet.
73   static constexpr int unknownRank() { return -1; }
74 
75   // This corresponds to the descriptor as defined in ISO_Fortran_binding.h and
76   // the addendum defined in descriptor.h.
77   mlir::Type convertBoxType(BaseBoxType box, int rank = unknownRank()) const;
78 
79   /// Convert fir.box type to the corresponding llvm struct type instead of a
80   /// pointer to this struct type.
81   mlir::Type convertBoxTypeAsStruct(BaseBoxType box, int = unknownRank()) const;
82 
83   // fir.boxproc<any>  -->  llvm<"{ any*, i8* }">
84   mlir::Type convertBoxProcType(BoxProcType boxproc) const;
85 
86   unsigned characterBitsize(fir::CharacterType charTy) const;
87 
88   // fir.char<k,?>  -->  llvm<"ix">          where ix is scaled by kind mapping
89   // fir.char<k,n>  -->  llvm.array<n x "ix">
90   mlir::Type convertCharType(fir::CharacterType charTy) const;
91 
92   template <typename A> mlir::Type convertPointerLike(A &ty) const {
93     return mlir::LLVM::LLVMPointerType::get(ty.getContext());
94   }
95 
96   // fir.array<c ... :any>  -->  llvm<"[...[c x any]]">
97   mlir::Type convertSequenceType(SequenceType seq) const;
98 
99   // fir.tdesc<any>  -->  llvm<"i8*">
100   // TODO: For now use a void*, however pointer identity is not sufficient for
101   // the f18 object v. class distinction (F2003).
102   mlir::Type convertTypeDescType(mlir::MLIRContext *ctx) const;
103 
104   const KindMapping &getKindMap() const { return kindMapping; }
105 
106   // Relay TBAA tag attachment to TBAABuilder.
107   void attachTBAATag(mlir::LLVM::AliasAnalysisOpInterface op,
108                      mlir::Type baseFIRType, mlir::Type accessFIRType,
109                      mlir::LLVM::GEPOp gep) const;
110 
111   const mlir::DataLayout &getDataLayout() const {
112     assert(dataLayout && "must be set in ctor");
113     return *dataLayout;
114   }
115 
116 private:
117   KindMapping kindMapping;
118   std::unique_ptr<CodeGenSpecifics> specifics;
119   std::unique_ptr<TBAABuilder> tbaaBuilder;
120   const mlir::DataLayout *dataLayout;
121 };
122 
123 } // namespace fir
124 
125 #endif // FORTRAN_OPTIMIZER_CODEGEN_TYPECONVERTER_H
126