================ @@ -0,0 +1,241 @@ +//===---- ABITypeMapper.cpp - Maps LLVM ABI Types to LLVM IR Types ------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Maps LLVM ABI type representations back to corresponding LLVM IR types. +/// This reverse mapper translates low-level ABI-specific types back into +/// LLVM IR types suitable for code generation and optimization passes. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/ABI/ABITypeMapper.h" +#include "llvm/ABI/Types.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +Type *ABITypeMapper::convertType(const abi::Type *ABIType) { + if (!ABIType) + return nullptr; + + auto It = TypeCache.find(ABIType); + if (It != TypeCache.end()) + return It->second; + + Type *Result = nullptr; + + switch (ABIType->getKind()) { + case abi::TypeKind::Integer: + Result = convertIntegerType(cast<abi::IntegerType>(ABIType)); + break; + case abi::TypeKind::Float: + Result = convertFloatType(cast<abi::FloatType>(ABIType)); + break; + case abi::TypeKind::Pointer: + Result = convertPointerType(cast<abi::PointerType>(ABIType)); + break; + case abi::TypeKind::Array: + Result = convertArrayType(cast<abi::ArrayType>(ABIType)); + break; + case abi::TypeKind::Vector: + Result = convertVectorType(cast<abi::VectorType>(ABIType)); + break; + case abi::TypeKind::Struct: + Result = convertStructType(cast<abi::StructType>(ABIType)); + break; + case abi::TypeKind::Union: + Result = convertUnionType(cast<abi::UnionType>(ABIType)); + break; + case abi::TypeKind::Void: + Result = convertVoidType(cast<abi::VoidType>(ABIType)); + break; + default: + llvm_unreachable("Unknown ABI type kind"); + } + + if (Result) + TypeCache[ABIType] = Result; + + return Result; +} + +Type *ABITypeMapper::convertIntegerType(const abi::IntegerType *IT) { + unsigned BitWidth = IT->getSizeInBits(); + return IntegerType::get(Context, BitWidth); +} + +Type *ABITypeMapper::convertFloatType(const abi::FloatType *FT) { + const fltSemantics *Semantics = + const_cast<abi::FloatType *>(FT)->getSemantics(); + return getFloatTypeForSemantics(*Semantics); +} + +Type *ABITypeMapper::convertPointerType(const abi::PointerType *PT) { + return PointerType::get(Context, 0); +} + +Type *ABITypeMapper::convertArrayType(const abi::ArrayType *AT) { + Type *ElementType = convertType(AT->getElementType()); + if (!ElementType) + return nullptr; + + uint64_t NumElements = AT->getNumElements(); + + return ArrayType::get(ElementType, NumElements); +} + +Type *ABITypeMapper::convertVectorType(const abi::VectorType *VT) { + Type *ElementType = convertType(VT->getElementType()); + if (!ElementType) + return nullptr; + + ElementCount EC = VT->getNumElements(); + + if (EC.isScalable()) + return ScalableVectorType::get(ElementType, EC.getKnownMinValue()); + return FixedVectorType::get(ElementType, EC.getFixedValue()); +} + +Type *ABITypeMapper::convertStructType(const abi::StructType *ST) { + return createStructFromFields(*ST->getFields(), ST->getNumFields(), + ST->getSizeInBits(), ST->getAlignment(), false); +} + +Type *ABITypeMapper::convertUnionType(const abi::UnionType *UT) { + return createStructFromFields(*UT->getFields(), UT->getNumFields(), + UT->getSizeInBits(), UT->getAlignment(), true); +} + +Type *ABITypeMapper::convertVoidType(const abi::VoidType *VT) { + return Type::getVoidTy(Context); +} + +Type *ABITypeMapper::getFloatTypeForSemantics(const fltSemantics &Semantics) { + if (&Semantics == &APFloat::IEEEhalf()) + return Type::getHalfTy(Context); + if (&Semantics == &APFloat::BFloat()) + return Type::getBFloatTy(Context); + if (&Semantics == &APFloat::IEEEsingle()) + return Type::getFloatTy(Context); + if (&Semantics == &APFloat::IEEEdouble()) + return Type::getDoubleTy(Context); + if (&Semantics == &APFloat::x87DoubleExtended()) + return Type::getX86_FP80Ty(Context); + if (&Semantics == &APFloat::IEEEquad()) + return Type::getFP128Ty(Context); + if (&Semantics == &APFloat::PPCDoubleDouble()) + return Type::getPPC_FP128Ty(Context); + + // Fallback + return Type::getDoubleTy(Context); +} + +StructType * +ABITypeMapper::createStructFromFields(ArrayRef<abi::FieldInfo> Fields, + uint32_t NumFields, TypeSize Size, + Align Alignment, bool IsUnion) { + SmallVector<Type *, 16> FieldTypes; + + if (IsUnion) { + Type *LargestFieldType = nullptr; + uint64_t LargestFieldSize = 0; + + for (const auto &Field : Fields) { + Type *FieldType = convertType(Field.FieldType); + if (!FieldType) + continue; + + uint64_t FieldSize = 0; + if (auto *IntTy = dyn_cast<IntegerType>(FieldType)) { + FieldSize = IntTy->getBitWidth(); + } else if (FieldType->isFloatingPointTy()) { + FieldSize = FieldType->getPrimitiveSizeInBits(); + } else if (FieldType->isPointerTy()) { + FieldSize = 64; // Assume 64-bit pointers + } ---------------- nikic wrote:
Use the SizeInBits stored in the type instead? https://github.com/llvm/llvm-project/pull/140112 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits