1 //===-- Optimizer/Support/KindMapping.h -- support kind mapping -*- 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_SUPPORT_KINDMAPPING_H 14 #define FORTRAN_OPTIMIZER_SUPPORT_KINDMAPPING_H 15 16 #include "mlir/IR/OpDefinition.h" 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/IR/Type.h" 19 20 namespace llvm { 21 struct fltSemantics; 22 } // namespace llvm 23 24 namespace fir { 25 26 /// The kind mapping is an encoded string that informs FIR how the Fortran KIND 27 /// values from the front-end should be converted to LLVM IR types. This 28 /// encoding allows the mapping from front-end KIND values to backend LLVM IR 29 /// types to be customized by the front-end. 30 /// 31 /// The provided string uses the following syntax. 32 /// 33 /// intrinsic-key `:` kind-value (`,` intrinsic-key `:` kind-value)* 34 /// 35 /// intrinsic-key is a single character for the intrinsic type. 36 /// 'i' : INTEGER (size in bits) 37 /// 'l' : LOGICAL (size in bits) 38 /// 'a' : CHARACTER (size in bits) 39 /// 'r' : REAL (encoding value) 40 /// 'c' : COMPLEX (encoding value) 41 /// 42 /// kind-value is either an unsigned integer (for 'i', 'l', and 'a') or one of 43 /// 'Half', 'BFloat', 'Float', 'Double', 'X86_FP80', or 'FP128' (for 'r' and 44 /// 'c'). 45 /// 46 /// If LLVM adds support for new floating-point types, the final list should be 47 /// extended. 48 class KindMapping { 49 public: 50 using KindTy = unsigned; 51 using Bitsize = unsigned; 52 using LLVMTypeID = llvm::Type::TypeID; 53 using MatchResult = mlir::ParseResult; 54 55 /// KindMapping constructor with both the kind map and default kinds read from 56 /// command-line options. 57 explicit KindMapping(mlir::MLIRContext *context); 58 /// KindMapping constructor taking a `defs` argument to specify the default 59 /// kinds for intrinsic types. To set the default kinds, an ArrayRef of 6 60 /// KindTy must be passed. The kinds must be the given in the following order: 61 /// CHARACTER, COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL, and REAL. The 62 /// kind map is read from command-line options, if given. 63 explicit KindMapping(mlir::MLIRContext *context, llvm::ArrayRef<KindTy> defs); 64 /// KindMapping constructor taking an optional `defs` argument to specify the 65 /// default kinds for intrinsic types. To set the default kinds, an ArrayRef 66 /// of 6 KindTy must be passed. The kinds must be the given in the following 67 /// order: CHARACTER, COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL, and REAL. 68 explicit KindMapping(mlir::MLIRContext *context, llvm::StringRef map, 69 llvm::ArrayRef<KindTy> defs = llvm::None); KindMapping(mlir::MLIRContext * context,llvm::StringRef map,llvm::StringRef defs)70 explicit KindMapping(mlir::MLIRContext *context, llvm::StringRef map, 71 llvm::StringRef defs) 72 : KindMapping{context, map, toDefaultKinds(defs)} {} 73 74 /// Get the size in bits of !fir.char<kind> 75 Bitsize getCharacterBitsize(KindTy kind) const; 76 77 /// Get the size in bits of !fir.int<kind> 78 Bitsize getIntegerBitsize(KindTy kind) const; 79 80 /// Get the size in bits of !fir.logical<kind> 81 Bitsize getLogicalBitsize(KindTy kind) const; 82 83 /// Get the size in bits of !fir.real<kind> 84 Bitsize getRealBitsize(KindTy kind) const; 85 86 /// Get the LLVM Type::TypeID of !fir.real<kind> 87 LLVMTypeID getRealTypeID(KindTy kind) const; 88 89 /// Get the LLVM Type::TypeID of !fir.complex<kind> 90 LLVMTypeID getComplexTypeID(KindTy kind) const; 91 getContext()92 mlir::MLIRContext *getContext() const { return context; } 93 94 /// Get the float semantics of !fir.real<kind> 95 const llvm::fltSemantics &getFloatSemantics(KindTy kind) const; 96 97 /// Get the default kind map as a string. getDefaultMap()98 static constexpr const char *getDefaultMap() { return ""; } 99 100 /// Convert the current kind map to a string. 101 std::string mapToString() const; 102 103 //===--------------------------------------------------------------------===// 104 // Default kinds of intrinsic types 105 //===--------------------------------------------------------------------===// 106 107 KindTy defaultCharacterKind() const; 108 KindTy defaultComplexKind() const; 109 KindTy defaultDoubleKind() const; 110 KindTy defaultIntegerKind() const; 111 KindTy defaultLogicalKind() const; 112 KindTy defaultRealKind() const; 113 114 /// Get the default kinds as a string. getDefaultKinds()115 static constexpr const char *getDefaultKinds() { return "a1c4d8i4l4r4"; } 116 117 /// Convert the current default kinds to a string. 118 std::string defaultsToString() const; 119 120 /// Translate a default kinds string into a default kind vector. This vector 121 /// can be passed to the KindMapping ctor. 122 static std::vector<KindTy> toDefaultKinds(llvm::StringRef defs); 123 124 private: 125 MatchResult badMapString(const llvm::Twine &ptr); 126 MatchResult parse(llvm::StringRef kindMap); 127 mlir::LogicalResult setDefaultKinds(llvm::ArrayRef<KindTy> defs); 128 129 mlir::MLIRContext *context; 130 llvm::DenseMap<std::pair<char, KindTy>, Bitsize> intMap; 131 llvm::DenseMap<std::pair<char, KindTy>, LLVMTypeID> floatMap; 132 llvm::DenseMap<char, KindTy> defaultMap; 133 }; 134 135 } // namespace fir 136 137 #endif // FORTRAN_OPTIMIZER_SUPPORT_KINDMAPPING_H 138