================
@@ -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) {
----------------
nikic wrote:

Hmm... this is tricky. I'm not entirely sure what to do here. For the purpose 
of mapping ABIArgInfo, we should never encounter unions. For the struct case, 
things are tricky. Mostly, I believe we just want LLVM structs as a means of 
holding multiple values. E.g. a StructType for Direct arguments will normally 
get unpacked into individual arguments. In this case, we really don't want any 
kind of padding fillers in it. I think the only case that cares about that is 
CoerceAndExpand, which has two struct types, one just with the elements (which 
will be passed as separate arguments) and one that has the actual layout (with 
correct alignment etc).

This kind of makes me wonder whether it would make sense to start by storing 
llvm types in ABIArgInfo to match what clang currently does. abi::Type is 
conceptually nicer, but also not quite the right representation for everything 
(e.g. because it can't really represent the "struct without layout" case well).

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

Reply via email to