157f536a4SjeanPerier //===-- KindMapping.cpp ---------------------------------------------------===//
257f536a4SjeanPerier //
357f536a4SjeanPerier // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457f536a4SjeanPerier // See https://llvm.org/LICENSE.txt for license information.
557f536a4SjeanPerier // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
657f536a4SjeanPerier //
757f536a4SjeanPerier //===----------------------------------------------------------------------===//
84dc87d10SEric Schweitz //
94dc87d10SEric Schweitz // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
104dc87d10SEric Schweitz //
114dc87d10SEric Schweitz //===----------------------------------------------------------------------===//
1257f536a4SjeanPerier
1357f536a4SjeanPerier #include "flang/Optimizer/Support/KindMapping.h"
1457f536a4SjeanPerier #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1557f536a4SjeanPerier #include "llvm/Support/CommandLine.h"
1657f536a4SjeanPerier
1757f536a4SjeanPerier /// Allow the user to set the FIR intrinsic type kind value to LLVM type
1857f536a4SjeanPerier /// mappings. Note that these are not mappings from kind values to any
1957f536a4SjeanPerier /// other MLIR dialect, only to LLVM IR. The default values follow the f18
2057f536a4SjeanPerier /// front-end kind mappings.
2157f536a4SjeanPerier
2257f536a4SjeanPerier using Bitsize = fir::KindMapping::Bitsize;
2357f536a4SjeanPerier using KindTy = fir::KindMapping::KindTy;
2457f536a4SjeanPerier using LLVMTypeID = fir::KindMapping::LLVMTypeID;
2557f536a4SjeanPerier using MatchResult = fir::KindMapping::MatchResult;
2657f536a4SjeanPerier
27c68d2895SEric Schweitz static llvm::cl::opt<std::string>
28c68d2895SEric Schweitz clKindMapping("kind-mapping",
29c68d2895SEric Schweitz llvm::cl::desc("kind mapping string to set kind precision"),
30c68d2895SEric Schweitz llvm::cl::value_desc("kind-mapping-string"),
31c68d2895SEric Schweitz llvm::cl::init(fir::KindMapping::getDefaultMap()));
32c68d2895SEric Schweitz
33c68d2895SEric Schweitz static llvm::cl::opt<std::string>
34c68d2895SEric Schweitz clDefaultKinds("default-kinds",
35c68d2895SEric Schweitz llvm::cl::desc("string to set default kind values"),
36c68d2895SEric Schweitz llvm::cl::value_desc("default-kind-string"),
37c68d2895SEric Schweitz llvm::cl::init(fir::KindMapping::getDefaultKinds()));
38c68d2895SEric Schweitz
39c68d2895SEric Schweitz // Keywords for the floating point types.
40c68d2895SEric Schweitz
41c68d2895SEric Schweitz static constexpr const char *kwHalf = "Half";
42c68d2895SEric Schweitz static constexpr const char *kwBFloat = "BFloat";
43c68d2895SEric Schweitz static constexpr const char *kwFloat = "Float";
44c68d2895SEric Schweitz static constexpr const char *kwDouble = "Double";
45c68d2895SEric Schweitz static constexpr const char *kwX86FP80 = "X86_FP80";
46c68d2895SEric Schweitz static constexpr const char *kwFP128 = "FP128";
47c68d2895SEric Schweitz static constexpr const char *kwPPCFP128 = "PPC_FP128";
4857f536a4SjeanPerier
4957f536a4SjeanPerier /// Integral types default to the kind value being the size of the value in
5057f536a4SjeanPerier /// bytes. The default is to scale from bytes to bits.
defaultScalingKind(KindTy kind)5157f536a4SjeanPerier static Bitsize defaultScalingKind(KindTy kind) {
521e96c4b5SValentin Clement const unsigned bitsInByte = 8;
531e96c4b5SValentin Clement return kind * bitsInByte;
5457f536a4SjeanPerier }
5557f536a4SjeanPerier
5657f536a4SjeanPerier /// Floating-point types default to the kind value being the size of the value
574dc87d10SEric Schweitz /// in bytes. The default is to translate kinds of 2, 3, 4, 8, 10, and 16 to a
5857f536a4SjeanPerier /// valid llvm::Type::TypeID value. Otherwise, the default is FloatTyID.
defaultRealKind(KindTy kind)5957f536a4SjeanPerier static LLVMTypeID defaultRealKind(KindTy kind) {
6057f536a4SjeanPerier switch (kind) {
6157f536a4SjeanPerier case 2:
6257f536a4SjeanPerier return LLVMTypeID::HalfTyID;
634dc87d10SEric Schweitz case 3:
644dc87d10SEric Schweitz return LLVMTypeID::BFloatTyID;
6557f536a4SjeanPerier case 4:
6657f536a4SjeanPerier return LLVMTypeID::FloatTyID;
6757f536a4SjeanPerier case 8:
6857f536a4SjeanPerier return LLVMTypeID::DoubleTyID;
6957f536a4SjeanPerier case 10:
7057f536a4SjeanPerier return LLVMTypeID::X86_FP80TyID;
7157f536a4SjeanPerier case 16:
7257f536a4SjeanPerier return LLVMTypeID::FP128TyID;
7357f536a4SjeanPerier default:
7457f536a4SjeanPerier return LLVMTypeID::FloatTyID;
7557f536a4SjeanPerier }
7657f536a4SjeanPerier }
7757f536a4SjeanPerier
7857f536a4SjeanPerier // lookup the kind-value given the defaults, the mappings, and a KIND key
7957f536a4SjeanPerier template <typename RT, char KEY>
doLookup(std::function<RT (KindTy)> def,const llvm::DenseMap<std::pair<char,KindTy>,RT> & map,KindTy kind)8057f536a4SjeanPerier static RT doLookup(std::function<RT(KindTy)> def,
8157f536a4SjeanPerier const llvm::DenseMap<std::pair<char, KindTy>, RT> &map,
8257f536a4SjeanPerier KindTy kind) {
8357f536a4SjeanPerier std::pair<char, KindTy> key{KEY, kind};
8457f536a4SjeanPerier auto iter = map.find(key);
8557f536a4SjeanPerier if (iter != map.end())
8657f536a4SjeanPerier return iter->second;
8757f536a4SjeanPerier return def(kind);
8857f536a4SjeanPerier }
8957f536a4SjeanPerier
90*f29f86b6SShao-Ce SUN // do a lookup for INTEGER, LOGICAL, or CHARACTER
9157f536a4SjeanPerier template <char KEY, typename MAP>
getIntegerLikeBitsize(KindTy kind,const MAP & map)9257f536a4SjeanPerier static Bitsize getIntegerLikeBitsize(KindTy kind, const MAP &map) {
9357f536a4SjeanPerier return doLookup<Bitsize, KEY>(defaultScalingKind, map, kind);
9457f536a4SjeanPerier }
9557f536a4SjeanPerier
9657f536a4SjeanPerier // do a lookup for REAL or COMPLEX
9757f536a4SjeanPerier template <char KEY, typename MAP>
getFloatLikeTypeID(KindTy kind,const MAP & map)9857f536a4SjeanPerier static LLVMTypeID getFloatLikeTypeID(KindTy kind, const MAP &map) {
9957f536a4SjeanPerier return doLookup<LLVMTypeID, KEY>(defaultRealKind, map, kind);
10057f536a4SjeanPerier }
10157f536a4SjeanPerier
10257f536a4SjeanPerier template <char KEY, typename MAP>
getFloatSemanticsOfKind(KindTy kind,const MAP & map)10357f536a4SjeanPerier static const llvm::fltSemantics &getFloatSemanticsOfKind(KindTy kind,
10457f536a4SjeanPerier const MAP &map) {
10557f536a4SjeanPerier switch (doLookup<LLVMTypeID, KEY>(defaultRealKind, map, kind)) {
10657f536a4SjeanPerier case LLVMTypeID::HalfTyID:
10757f536a4SjeanPerier return llvm::APFloat::IEEEhalf();
1084dc87d10SEric Schweitz case LLVMTypeID::BFloatTyID:
1094dc87d10SEric Schweitz return llvm::APFloat::BFloat();
11057f536a4SjeanPerier case LLVMTypeID::FloatTyID:
11157f536a4SjeanPerier return llvm::APFloat::IEEEsingle();
11257f536a4SjeanPerier case LLVMTypeID::DoubleTyID:
11357f536a4SjeanPerier return llvm::APFloat::IEEEdouble();
11457f536a4SjeanPerier case LLVMTypeID::X86_FP80TyID:
11557f536a4SjeanPerier return llvm::APFloat::x87DoubleExtended();
11657f536a4SjeanPerier case LLVMTypeID::FP128TyID:
11757f536a4SjeanPerier return llvm::APFloat::IEEEquad();
11857f536a4SjeanPerier case LLVMTypeID::PPC_FP128TyID:
11957f536a4SjeanPerier return llvm::APFloat::PPCDoubleDouble();
12057f536a4SjeanPerier default:
12157f536a4SjeanPerier llvm_unreachable("Invalid floating type");
12257f536a4SjeanPerier }
12357f536a4SjeanPerier }
12457f536a4SjeanPerier
125c68d2895SEric Schweitz /// Parse an intrinsic type code. The codes are ('a', CHARACTER), ('c',
126c68d2895SEric Schweitz /// COMPLEX), ('i', INTEGER), ('l', LOGICAL), and ('r', REAL).
parseCode(char & code,const char * & ptr,const char * endPtr)127c68d2895SEric Schweitz static MatchResult parseCode(char &code, const char *&ptr, const char *endPtr) {
128c68d2895SEric Schweitz if (ptr >= endPtr)
129c68d2895SEric Schweitz return mlir::failure();
13057f536a4SjeanPerier if (*ptr != 'a' && *ptr != 'c' && *ptr != 'i' && *ptr != 'l' && *ptr != 'r')
13157f536a4SjeanPerier return mlir::failure();
13257f536a4SjeanPerier code = *ptr++;
13357f536a4SjeanPerier return mlir::success();
13457f536a4SjeanPerier }
13557f536a4SjeanPerier
136c68d2895SEric Schweitz /// Same as `parseCode` but adds the ('d', DOUBLE PRECISION) code.
parseDefCode(char & code,const char * & ptr,const char * endPtr)137c68d2895SEric Schweitz static MatchResult parseDefCode(char &code, const char *&ptr,
138c68d2895SEric Schweitz const char *endPtr) {
139c68d2895SEric Schweitz if (ptr >= endPtr)
140c68d2895SEric Schweitz return mlir::failure();
141c68d2895SEric Schweitz if (*ptr == 'd') {
142c68d2895SEric Schweitz code = *ptr++;
143c68d2895SEric Schweitz return mlir::success();
144c68d2895SEric Schweitz }
145c68d2895SEric Schweitz return parseCode(code, ptr, endPtr);
146c68d2895SEric Schweitz }
147c68d2895SEric Schweitz
14857f536a4SjeanPerier template <char ch>
parseSingleChar(const char * & ptr,const char * endPtr)149c68d2895SEric Schweitz static MatchResult parseSingleChar(const char *&ptr, const char *endPtr) {
150c68d2895SEric Schweitz if (ptr >= endPtr || *ptr != ch)
15157f536a4SjeanPerier return mlir::failure();
15257f536a4SjeanPerier ++ptr;
15357f536a4SjeanPerier return mlir::success();
15457f536a4SjeanPerier }
15557f536a4SjeanPerier
parseColon(const char * & ptr,const char * endPtr)156c68d2895SEric Schweitz static MatchResult parseColon(const char *&ptr, const char *endPtr) {
157c68d2895SEric Schweitz return parseSingleChar<':'>(ptr, endPtr);
15857f536a4SjeanPerier }
15957f536a4SjeanPerier
parseComma(const char * & ptr,const char * endPtr)160c68d2895SEric Schweitz static MatchResult parseComma(const char *&ptr, const char *endPtr) {
161c68d2895SEric Schweitz return parseSingleChar<','>(ptr, endPtr);
16257f536a4SjeanPerier }
16357f536a4SjeanPerier
164c68d2895SEric Schweitz /// Recognize and parse an unsigned integer.
parseInt(unsigned & result,const char * & ptr,const char * endPtr)165c68d2895SEric Schweitz static MatchResult parseInt(unsigned &result, const char *&ptr,
166c68d2895SEric Schweitz const char *endPtr) {
16757f536a4SjeanPerier const char *beg = ptr;
168c68d2895SEric Schweitz while (ptr < endPtr && *ptr >= '0' && *ptr <= '9')
16957f536a4SjeanPerier ptr++;
17057f536a4SjeanPerier if (beg == ptr)
17157f536a4SjeanPerier return mlir::failure();
17257f536a4SjeanPerier llvm::StringRef ref(beg, ptr - beg);
17357f536a4SjeanPerier int temp;
17457f536a4SjeanPerier if (ref.consumeInteger(10, temp))
17557f536a4SjeanPerier return mlir::failure();
17657f536a4SjeanPerier result = temp;
17757f536a4SjeanPerier return mlir::success();
17857f536a4SjeanPerier }
17957f536a4SjeanPerier
matchString(const char * & ptr,const char * endPtr,llvm::StringRef literal)180c68d2895SEric Schweitz static mlir::LogicalResult matchString(const char *&ptr, const char *endPtr,
18157f536a4SjeanPerier llvm::StringRef literal) {
182c68d2895SEric Schweitz llvm::StringRef s(ptr, endPtr - ptr);
18357f536a4SjeanPerier if (s.startswith(literal)) {
18457f536a4SjeanPerier ptr += literal.size();
18557f536a4SjeanPerier return mlir::success();
18657f536a4SjeanPerier }
18757f536a4SjeanPerier return mlir::failure();
18857f536a4SjeanPerier }
18957f536a4SjeanPerier
190c68d2895SEric Schweitz /// Recognize and parse the various floating-point keywords. These follow the
191c68d2895SEric Schweitz /// LLVM naming convention.
parseTypeID(LLVMTypeID & result,const char * & ptr,const char * endPtr)192c68d2895SEric Schweitz static MatchResult parseTypeID(LLVMTypeID &result, const char *&ptr,
193c68d2895SEric Schweitz const char *endPtr) {
194c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwHalf))) {
19557f536a4SjeanPerier result = LLVMTypeID::HalfTyID;
19657f536a4SjeanPerier return mlir::success();
19757f536a4SjeanPerier }
198c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwBFloat))) {
1994dc87d10SEric Schweitz result = LLVMTypeID::BFloatTyID;
2004dc87d10SEric Schweitz return mlir::success();
2014dc87d10SEric Schweitz }
202c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwFloat))) {
20357f536a4SjeanPerier result = LLVMTypeID::FloatTyID;
20457f536a4SjeanPerier return mlir::success();
20557f536a4SjeanPerier }
206c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwDouble))) {
20757f536a4SjeanPerier result = LLVMTypeID::DoubleTyID;
20857f536a4SjeanPerier return mlir::success();
20957f536a4SjeanPerier }
210c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwX86FP80))) {
21157f536a4SjeanPerier result = LLVMTypeID::X86_FP80TyID;
21257f536a4SjeanPerier return mlir::success();
21357f536a4SjeanPerier }
214c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwFP128))) {
21557f536a4SjeanPerier result = LLVMTypeID::FP128TyID;
21657f536a4SjeanPerier return mlir::success();
21757f536a4SjeanPerier }
218c68d2895SEric Schweitz if (mlir::succeeded(matchString(ptr, endPtr, kwPPCFP128))) {
21957f536a4SjeanPerier result = LLVMTypeID::PPC_FP128TyID;
22057f536a4SjeanPerier return mlir::success();
22157f536a4SjeanPerier }
22257f536a4SjeanPerier return mlir::failure();
22357f536a4SjeanPerier }
22457f536a4SjeanPerier
KindMapping(mlir::MLIRContext * context,llvm::StringRef map,llvm::ArrayRef<KindTy> defs)2254dc87d10SEric Schweitz fir::KindMapping::KindMapping(mlir::MLIRContext *context, llvm::StringRef map,
2264dc87d10SEric Schweitz llvm::ArrayRef<KindTy> defs)
22757f536a4SjeanPerier : context{context} {
2284dc87d10SEric Schweitz if (mlir::failed(setDefaultKinds(defs)))
2294dc87d10SEric Schweitz llvm::report_fatal_error("bad default kinds");
2304dc87d10SEric Schweitz if (mlir::failed(parse(map)))
2314dc87d10SEric Schweitz llvm::report_fatal_error("could not parse kind map");
23257f536a4SjeanPerier }
23357f536a4SjeanPerier
KindMapping(mlir::MLIRContext * context,llvm::ArrayRef<KindTy> defs)2344dc87d10SEric Schweitz fir::KindMapping::KindMapping(mlir::MLIRContext *context,
2354dc87d10SEric Schweitz llvm::ArrayRef<KindTy> defs)
2364dc87d10SEric Schweitz : KindMapping{context, clKindMapping, defs} {}
23757f536a4SjeanPerier
KindMapping(mlir::MLIRContext * context)238c68d2895SEric Schweitz fir::KindMapping::KindMapping(mlir::MLIRContext *context)
239c68d2895SEric Schweitz : KindMapping{context, clKindMapping, clDefaultKinds} {}
240c68d2895SEric Schweitz
badMapString(const llvm::Twine & ptr)24157f536a4SjeanPerier MatchResult fir::KindMapping::badMapString(const llvm::Twine &ptr) {
24257f536a4SjeanPerier auto unknown = mlir::UnknownLoc::get(context);
24357f536a4SjeanPerier mlir::emitError(unknown, ptr);
24457f536a4SjeanPerier return mlir::failure();
24557f536a4SjeanPerier }
24657f536a4SjeanPerier
parse(llvm::StringRef kindMap)24757f536a4SjeanPerier MatchResult fir::KindMapping::parse(llvm::StringRef kindMap) {
24857f536a4SjeanPerier if (kindMap.empty())
24957f536a4SjeanPerier return mlir::success();
25057f536a4SjeanPerier const char *srcPtr = kindMap.begin();
251c68d2895SEric Schweitz const char *endPtr = kindMap.end();
25257f536a4SjeanPerier while (true) {
25357f536a4SjeanPerier char code = '\0';
25457f536a4SjeanPerier KindTy kind = 0;
255c68d2895SEric Schweitz if (parseCode(code, srcPtr, endPtr) || parseInt(kind, srcPtr, endPtr))
25657f536a4SjeanPerier return badMapString(srcPtr);
25757f536a4SjeanPerier if (code == 'a' || code == 'i' || code == 'l') {
25857f536a4SjeanPerier Bitsize bits = 0;
259c68d2895SEric Schweitz if (parseColon(srcPtr, endPtr) || parseInt(bits, srcPtr, endPtr))
26057f536a4SjeanPerier return badMapString(srcPtr);
26157f536a4SjeanPerier intMap[std::pair<char, KindTy>{code, kind}] = bits;
26257f536a4SjeanPerier } else if (code == 'r' || code == 'c') {
26357f536a4SjeanPerier LLVMTypeID id{};
264c68d2895SEric Schweitz if (parseColon(srcPtr, endPtr) || parseTypeID(id, srcPtr, endPtr))
26557f536a4SjeanPerier return badMapString(srcPtr);
26657f536a4SjeanPerier floatMap[std::pair<char, KindTy>{code, kind}] = id;
26757f536a4SjeanPerier } else {
26857f536a4SjeanPerier return badMapString(srcPtr);
26957f536a4SjeanPerier }
270c68d2895SEric Schweitz if (parseComma(srcPtr, endPtr))
27157f536a4SjeanPerier break;
27257f536a4SjeanPerier }
273c68d2895SEric Schweitz if (srcPtr > endPtr)
27457f536a4SjeanPerier return badMapString(srcPtr);
27557f536a4SjeanPerier return mlir::success();
27657f536a4SjeanPerier }
27757f536a4SjeanPerier
getCharacterBitsize(KindTy kind) const278c3477c51SEric Schweitz Bitsize fir::KindMapping::getCharacterBitsize(KindTy kind) const {
27957f536a4SjeanPerier return getIntegerLikeBitsize<'a'>(kind, intMap);
28057f536a4SjeanPerier }
28157f536a4SjeanPerier
getIntegerBitsize(KindTy kind) const282c3477c51SEric Schweitz Bitsize fir::KindMapping::getIntegerBitsize(KindTy kind) const {
28357f536a4SjeanPerier return getIntegerLikeBitsize<'i'>(kind, intMap);
28457f536a4SjeanPerier }
28557f536a4SjeanPerier
getLogicalBitsize(KindTy kind) const286c3477c51SEric Schweitz Bitsize fir::KindMapping::getLogicalBitsize(KindTy kind) const {
28757f536a4SjeanPerier return getIntegerLikeBitsize<'l'>(kind, intMap);
28857f536a4SjeanPerier }
28957f536a4SjeanPerier
getRealTypeID(KindTy kind) const290c3477c51SEric Schweitz LLVMTypeID fir::KindMapping::getRealTypeID(KindTy kind) const {
29157f536a4SjeanPerier return getFloatLikeTypeID<'r'>(kind, floatMap);
29257f536a4SjeanPerier }
29357f536a4SjeanPerier
getComplexTypeID(KindTy kind) const294c3477c51SEric Schweitz LLVMTypeID fir::KindMapping::getComplexTypeID(KindTy kind) const {
29557f536a4SjeanPerier return getFloatLikeTypeID<'c'>(kind, floatMap);
29657f536a4SjeanPerier }
29757f536a4SjeanPerier
getRealBitsize(KindTy kind) const298c3477c51SEric Schweitz Bitsize fir::KindMapping::getRealBitsize(KindTy kind) const {
299c3477c51SEric Schweitz auto typeId = getFloatLikeTypeID<'r'>(kind, floatMap);
300c3477c51SEric Schweitz llvm::LLVMContext llCtxt; // FIXME
301c3477c51SEric Schweitz return llvm::Type::getPrimitiveType(llCtxt, typeId)->getPrimitiveSizeInBits();
302c3477c51SEric Schweitz }
303c3477c51SEric Schweitz
304c3477c51SEric Schweitz const llvm::fltSemantics &
getFloatSemantics(KindTy kind) const305c3477c51SEric Schweitz fir::KindMapping::getFloatSemantics(KindTy kind) const {
30657f536a4SjeanPerier return getFloatSemanticsOfKind<'r'>(kind, floatMap);
30757f536a4SjeanPerier }
3084dc87d10SEric Schweitz
mapToString() const309c68d2895SEric Schweitz std::string fir::KindMapping::mapToString() const {
310c68d2895SEric Schweitz std::string result;
311c68d2895SEric Schweitz bool addComma = false;
312c68d2895SEric Schweitz for (auto [k, v] : intMap) {
313c68d2895SEric Schweitz if (addComma)
314c68d2895SEric Schweitz result.append(",");
315c68d2895SEric Schweitz else
316c68d2895SEric Schweitz addComma = true;
317c68d2895SEric Schweitz result += k.first + std::to_string(k.second) + ":" + std::to_string(v);
318c68d2895SEric Schweitz }
319c68d2895SEric Schweitz for (auto [k, v] : floatMap) {
320c68d2895SEric Schweitz if (addComma)
321c68d2895SEric Schweitz result.append(",");
322c68d2895SEric Schweitz else
323c68d2895SEric Schweitz addComma = true;
324c68d2895SEric Schweitz result.append(k.first + std::to_string(k.second) + ":");
325c68d2895SEric Schweitz switch (v) {
326c68d2895SEric Schweitz default:
327c68d2895SEric Schweitz llvm_unreachable("unhandled type-id");
328c68d2895SEric Schweitz case LLVMTypeID::HalfTyID:
329c68d2895SEric Schweitz result.append(kwHalf);
330c68d2895SEric Schweitz break;
331c68d2895SEric Schweitz case LLVMTypeID::BFloatTyID:
332c68d2895SEric Schweitz result.append(kwBFloat);
333c68d2895SEric Schweitz break;
334c68d2895SEric Schweitz case LLVMTypeID::FloatTyID:
335c68d2895SEric Schweitz result.append(kwFloat);
336c68d2895SEric Schweitz break;
337c68d2895SEric Schweitz case LLVMTypeID::DoubleTyID:
338c68d2895SEric Schweitz result.append(kwDouble);
339c68d2895SEric Schweitz break;
340c68d2895SEric Schweitz case LLVMTypeID::X86_FP80TyID:
341c68d2895SEric Schweitz result.append(kwX86FP80);
342c68d2895SEric Schweitz break;
343c68d2895SEric Schweitz case LLVMTypeID::FP128TyID:
344c68d2895SEric Schweitz result.append(kwFP128);
345c68d2895SEric Schweitz break;
346c68d2895SEric Schweitz case LLVMTypeID::PPC_FP128TyID:
347c68d2895SEric Schweitz result.append(kwPPCFP128);
348c68d2895SEric Schweitz break;
349c68d2895SEric Schweitz }
350c68d2895SEric Schweitz }
351c68d2895SEric Schweitz return result;
352c68d2895SEric Schweitz }
353c68d2895SEric Schweitz
3544dc87d10SEric Schweitz mlir::LogicalResult
setDefaultKinds(llvm::ArrayRef<KindTy> defs)3554dc87d10SEric Schweitz fir::KindMapping::setDefaultKinds(llvm::ArrayRef<KindTy> defs) {
3564dc87d10SEric Schweitz if (defs.empty()) {
3574dc87d10SEric Schweitz // generic front-end defaults
3584dc87d10SEric Schweitz const KindTy genericKind = 4;
3594dc87d10SEric Schweitz defaultMap.insert({'a', 1});
3604dc87d10SEric Schweitz defaultMap.insert({'c', genericKind});
3614dc87d10SEric Schweitz defaultMap.insert({'d', 2 * genericKind});
3624dc87d10SEric Schweitz defaultMap.insert({'i', genericKind});
3634dc87d10SEric Schweitz defaultMap.insert({'l', genericKind});
3644dc87d10SEric Schweitz defaultMap.insert({'r', genericKind});
3654dc87d10SEric Schweitz return mlir::success();
3664dc87d10SEric Schweitz }
3674dc87d10SEric Schweitz if (defs.size() != 6)
3684dc87d10SEric Schweitz return mlir::failure();
3694dc87d10SEric Schweitz
3704dc87d10SEric Schweitz // defaults determined after command-line processing
3714dc87d10SEric Schweitz defaultMap.insert({'a', defs[0]});
3724dc87d10SEric Schweitz defaultMap.insert({'c', defs[1]});
3734dc87d10SEric Schweitz defaultMap.insert({'d', defs[2]});
3744dc87d10SEric Schweitz defaultMap.insert({'i', defs[3]});
3754dc87d10SEric Schweitz defaultMap.insert({'l', defs[4]});
3764dc87d10SEric Schweitz defaultMap.insert({'r', defs[5]});
3774dc87d10SEric Schweitz return mlir::success();
3784dc87d10SEric Schweitz }
3794dc87d10SEric Schweitz
defaultsToString() const380c68d2895SEric Schweitz std::string fir::KindMapping::defaultsToString() const {
381c68d2895SEric Schweitz return std::string("a") + std::to_string(defaultMap.find('a')->second) +
382c68d2895SEric Schweitz std::string("c") + std::to_string(defaultMap.find('c')->second) +
383c68d2895SEric Schweitz std::string("d") + std::to_string(defaultMap.find('d')->second) +
384c68d2895SEric Schweitz std::string("i") + std::to_string(defaultMap.find('i')->second) +
385c68d2895SEric Schweitz std::string("l") + std::to_string(defaultMap.find('l')->second) +
386c68d2895SEric Schweitz std::string("r") + std::to_string(defaultMap.find('r')->second);
387c68d2895SEric Schweitz }
388c68d2895SEric Schweitz
389c68d2895SEric Schweitz /// Convert a default intrinsic code into the proper position in the array. The
390c68d2895SEric Schweitz /// default kinds have a precise ordering.
codeToIndex(char code)391c68d2895SEric Schweitz static int codeToIndex(char code) {
392c68d2895SEric Schweitz switch (code) {
393c68d2895SEric Schweitz case 'a':
394c68d2895SEric Schweitz return 0;
395c68d2895SEric Schweitz case 'c':
396c68d2895SEric Schweitz return 1;
397c68d2895SEric Schweitz case 'd':
398c68d2895SEric Schweitz return 2;
399c68d2895SEric Schweitz case 'i':
400c68d2895SEric Schweitz return 3;
401c68d2895SEric Schweitz case 'l':
402c68d2895SEric Schweitz return 4;
403c68d2895SEric Schweitz case 'r':
404c68d2895SEric Schweitz return 5;
405c68d2895SEric Schweitz }
406c68d2895SEric Schweitz llvm_unreachable("invalid default kind intrinsic code");
407c68d2895SEric Schweitz }
408c68d2895SEric Schweitz
toDefaultKinds(llvm::StringRef defs)409c68d2895SEric Schweitz std::vector<KindTy> fir::KindMapping::toDefaultKinds(llvm::StringRef defs) {
410c68d2895SEric Schweitz std::vector<KindTy> result(6);
411c68d2895SEric Schweitz char code;
412c68d2895SEric Schweitz KindTy kind;
413c68d2895SEric Schweitz if (defs.empty())
414c68d2895SEric Schweitz defs = clDefaultKinds;
415c68d2895SEric Schweitz const char *srcPtr = defs.begin();
416c68d2895SEric Schweitz const char *endPtr = defs.end();
417c68d2895SEric Schweitz while (srcPtr < endPtr) {
418c68d2895SEric Schweitz if (parseDefCode(code, srcPtr, endPtr) || parseInt(kind, srcPtr, endPtr))
419c68d2895SEric Schweitz llvm::report_fatal_error("invalid default kind code");
420c68d2895SEric Schweitz result[codeToIndex(code)] = kind;
421c68d2895SEric Schweitz }
422c68d2895SEric Schweitz assert(srcPtr == endPtr);
423c68d2895SEric Schweitz return result;
424c68d2895SEric Schweitz }
425c68d2895SEric Schweitz
defaultCharacterKind() const4264dc87d10SEric Schweitz KindTy fir::KindMapping::defaultCharacterKind() const {
4274dc87d10SEric Schweitz auto iter = defaultMap.find('a');
4284dc87d10SEric Schweitz assert(iter != defaultMap.end());
4294dc87d10SEric Schweitz return iter->second;
4304dc87d10SEric Schweitz }
4314dc87d10SEric Schweitz
defaultComplexKind() const4324dc87d10SEric Schweitz KindTy fir::KindMapping::defaultComplexKind() const {
4334dc87d10SEric Schweitz auto iter = defaultMap.find('c');
4344dc87d10SEric Schweitz assert(iter != defaultMap.end());
4354dc87d10SEric Schweitz return iter->second;
4364dc87d10SEric Schweitz }
4374dc87d10SEric Schweitz
defaultDoubleKind() const4384dc87d10SEric Schweitz KindTy fir::KindMapping::defaultDoubleKind() const {
4394dc87d10SEric Schweitz auto iter = defaultMap.find('d');
4404dc87d10SEric Schweitz assert(iter != defaultMap.end());
4414dc87d10SEric Schweitz return iter->second;
4424dc87d10SEric Schweitz }
4434dc87d10SEric Schweitz
defaultIntegerKind() const4444dc87d10SEric Schweitz KindTy fir::KindMapping::defaultIntegerKind() const {
4454dc87d10SEric Schweitz auto iter = defaultMap.find('i');
4464dc87d10SEric Schweitz assert(iter != defaultMap.end());
4474dc87d10SEric Schweitz return iter->second;
4484dc87d10SEric Schweitz }
4494dc87d10SEric Schweitz
defaultLogicalKind() const4504dc87d10SEric Schweitz KindTy fir::KindMapping::defaultLogicalKind() const {
4514dc87d10SEric Schweitz auto iter = defaultMap.find('l');
4524dc87d10SEric Schweitz assert(iter != defaultMap.end());
4534dc87d10SEric Schweitz return iter->second;
4544dc87d10SEric Schweitz }
4554dc87d10SEric Schweitz
defaultRealKind() const4564dc87d10SEric Schweitz KindTy fir::KindMapping::defaultRealKind() const {
4574dc87d10SEric Schweitz auto iter = defaultMap.find('r');
4584dc87d10SEric Schweitz assert(iter != defaultMap.end());
4594dc87d10SEric Schweitz return iter->second;
4604dc87d10SEric Schweitz }
461