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