-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[WIP] Clang ABI Types #133080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
easyonaadit
wants to merge
19
commits into
llvm:main
Choose a base branch
from
easyonaadit:LLVM-ABI
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
[WIP] Clang ABI Types #133080
+731
−10
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
have annotated the code with some parts of understanding.
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- llvm/lib/LLVMABI/ABICall.h llvm/lib/LLVMABI/ABIFunctionInfo.cpp llvm/lib/LLVMABI/ABIFunctionInfo.h llvm/lib/LLVMABI/Targets/x86.cpp llvm/lib/LLVMABI/Type.cpp llvm/lib/LLVMABI/Type.h clang/lib/CodeGen/CGCall.cpp View the diff from clang-format here.diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 7c950dc1d..13d9e0e16 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -11,8 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/include/llvm/LLVMABI/Type.h"
-#include "llvm/include/llvm/LLVMABI/ABIFunctionInfo.h"
#include "CGCall.h"
#include "ABIInfo.h"
#include "ABIInfoImpl.h"
@@ -44,6 +42,8 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/include/llvm/LLVMABI/ABIFunctionInfo.h"
+#include "llvm/include/llvm/LLVMABI/Type.h"
#include <optional>
using namespace clang;
using namespace CodeGen;
@@ -52,12 +52,13 @@ using namespace ABI;
/***/
ABIFunction::CallingConv ClangCallConvToABICallConv(CallingConv CC) {
switch (CC) {
- default: return ABIFunction::CallingConv::CC_C;
- case CC_X86StdCall: return ABIFunction::CallingConv::CC_X86StdCall;
+ default:
+ return ABIFunction::CallingConv::CC_C;
+ case CC_X86StdCall:
+ return ABIFunction::CallingConv::CC_X86StdCall;
}
}
-
unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
switch (CC) {
default: return llvm::CallingConv::C;
@@ -825,41 +826,43 @@ void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
}
}
-std::unique_ptr<ABI::Type> getABIType(QualType QT){
+std::unique_ptr<ABI::Type> getABIType(QualType QT) {
const clang::Type *BaseType = QT.getTypePtr();
switch (BaseType->getTypeClass()) {
- case clang::Type::Builtin: {
- // Cast to BuiltinType to access its kind
- auto *BT = llvm::cast<clang::BuiltinType>(BaseType);
-
- ABIBuiltinType::Kind ABIKind;
- switch (BT->getKind()) {
- case clang::BuiltinType::Void:
- ABIKind = ABIBuiltinType::Void;
- break;
- case clang::BuiltinType::Bool:
- ABIKind = ABIBuiltinType::Bool;
- break;
- case clang::BuiltinType::Int:
- ABIKind = ABIBuiltinType::Integer;
- break;
- case clang::BuiltinType::UInt:
- ABIKind = ABIBuiltinType::UInt128;
- break;
- case clang::BuiltinType::Float:
- ABIKind = ABIBuiltinType::Float;
- break;
- default:
- // TODO: support additional types
- return std::make_unique<ABI::Type>(ABI::ABIBuiltinType(ABIBuiltinType::Void), 0);
- }
- auto *ABIType = new ABI::ABIBuiltinType(ABIKind);
- return std::make_unique<ABI::Type>(ABIType, 0);
+ case clang::Type::Builtin: {
+ // Cast to BuiltinType to access its kind
+ auto *BT = llvm::cast<clang::BuiltinType>(BaseType);
+
+ ABIBuiltinType::Kind ABIKind;
+ switch (BT->getKind()) {
+ case clang::BuiltinType::Void:
+ ABIKind = ABIBuiltinType::Void;
+ break;
+ case clang::BuiltinType::Bool:
+ ABIKind = ABIBuiltinType::Bool;
+ break;
+ case clang::BuiltinType::Int:
+ ABIKind = ABIBuiltinType::Integer;
+ break;
+ case clang::BuiltinType::UInt:
+ ABIKind = ABIBuiltinType::UInt128;
+ break;
+ case clang::BuiltinType::Float:
+ ABIKind = ABIBuiltinType::Float;
+ break;
+ default:
+ // TODO: support additional types
+ return std::make_unique<ABI::Type>(
+ ABI::ABIBuiltinType(ABIBuiltinType::Void), 0);
}
- default :
- // TODO: support additonal types
- return std::make_unique<ABI::Type>(ABI::ABIBuiltinType(ABIBuiltinType::Void), 0);
+ auto *ABIType = new ABI::ABIBuiltinType(ABIKind);
+ return std::make_unique<ABI::Type>(ABIType, 0);
+ }
+ default:
+ // TODO: support additonal types
+ return std::make_unique<ABI::Type>(
+ ABI::ABIBuiltinType(ABIBuiltinType::Void), 0);
}
}
@@ -897,24 +900,27 @@ const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
std::unique_ptr<ABI::Type> resultTypeABI = getABIType(resultType);
std::vector<ABI::Type> abiTypes;
- abiTypes.reserve(argTypes.size());
+ abiTypes.reserve(argTypes.size());
for (CanQualType &element : argTypes) {
- abiTypes.push_back(*getABIType(element)); // Move unique_ptr into the vector
+ abiTypes.push_back(*getABIType(element)); // Move unique_ptr into the vector
}
// map the abi::Types -> abi::FunctionInfo type, done by the library
- ABIFunction::ABIFunctionInfo *ABIFI = ABIFunction::ABIFunctionInfo::create(CC, abiTypes, *(resultTypeABI.get()));
+ ABIFunction::ABIFunctionInfo *ABIFI = ABIFunction::ABIFunctionInfo::create(
+ CC, abiTypes, *(resultTypeABI.get()));
// Compute ABI information.
- if (ClangCallConvToLLVMCallConv(info.getCC()) == llvm::CallingConv::SPIR_KERNEL) {
+ if (ClangCallConvToLLVMCallConv(info.getCC()) ==
+ llvm::CallingConv::SPIR_KERNEL) {
// Force target independent argument handling for the host visible
// kernel functions.
computeSPIRKernelABIInfo(CGM, *FI);
} else if (info.getCC() == CC_Swift || info.getCC() == CC_SwiftAsync) {
swiftcall::computeABIInfo(CGM, *FI);
} else {
- // inject the required ABI information into the function. done by the library
+ // inject the required ABI information into the function. done by the
+ // library
ABI::computeFunctionInfo(CodeGenModule::getTargetCodeGenInfo(), ABIFI);
}
diff --git a/llvm/lib/LLVMABI/ABICall.h b/llvm/lib/LLVMABI/ABICall.h
index 8edb3a4b6..058aa84f6 100644
--- a/llvm/lib/LLVMABI/ABICall.h
+++ b/llvm/lib/LLVMABI/ABICall.h
@@ -1,8 +1,8 @@
#ifndef ABICALL_H
#define ABICALL_H
-#include "Type.h"
#include "ABIFunctionInfo.h"
+#include "Type.h"
using namespace ABI;
using namespace ABIFunction;
@@ -18,7 +18,6 @@ public:
ABIArgInfo classifyArgumentType(Type RetTy) const;
void computeInfo(ABIFunctionInfo &FI) const override;
-
};
#endif
diff --git a/llvm/lib/LLVMABI/ABIFunctionInfo.h b/llvm/lib/LLVMABI/ABIFunctionInfo.h
index c04d99210..56bc3e9cc 100644
--- a/llvm/lib/LLVMABI/ABIFunctionInfo.h
+++ b/llvm/lib/LLVMABI/ABIFunctionInfo.h
@@ -6,7 +6,7 @@
using namespace ABI;
-namespace ABIFunction{
+namespace ABIFunction {
/// ABIArgInfo - Helper class to encapsulate information about how a
/// specific C type should be passed to or returned from a function.
@@ -70,10 +70,10 @@ public:
private:
Kind TheKind;
-
+
public:
ABIArgInfo(Kind K = Direct) : TheKind(K) {}
-
+
Kind getKind() const { return TheKind; }
static Kind getDirect() { return Direct; }
@@ -104,38 +104,37 @@ struct ABIFunctionInfoArgInfo {
class ABIFunctionInfo {
typedef ABIFunctionInfoArgInfo ArgInfo;
- private:
+private:
CallingConv CC;
std::vector<ArgInfo> Parameters;
ArgInfo RetInfo;
-
- public:
- ABIFunctionInfo(CallingConv cc, std::vector<const Type *> parameters,
- Type ReturnInfo);
- static ABIFunctionInfo *create(CallingConv cc,
- std::vector<const Type *> parameters,
- Type ReturnInfo);
+public:
+ ABIFunctionInfo(CallingConv cc, std::vector<const Type *> parameters,
+ Type ReturnInfo);
+
+ static ABIFunctionInfo *
+ create(CallingConv cc, std::vector<const Type *> parameters, Type ReturnInfo);
- ABIArgInfo &getReturnInfo();
- const ABIArgInfo &getReturnInfo() const;
+ ABIArgInfo &getReturnInfo();
+ const ABIArgInfo &getReturnInfo() const;
- const Type *getReturnType() const;
+ const Type *getReturnType() const;
- using arg_iterator = std::vector<ArgInfo>::iterator;
- using const_arg_iterator = std::vector<ArgInfo>::const_iterator;
+ using arg_iterator = std::vector<ArgInfo>::iterator;
+ using const_arg_iterator = std::vector<ArgInfo>::const_iterator;
- arg_iterator arg_begin();
- arg_iterator arg_end();
+ arg_iterator arg_begin();
+ arg_iterator arg_end();
- const_arg_iterator arg_begin() const;
- const_arg_iterator arg_end() const;
+ const_arg_iterator arg_begin() const;
+ const_arg_iterator arg_end() const;
- void dump() const;
+ void dump() const;
- unsigned getCallingConvention() const { return CC; }
+ unsigned getCallingConvention() const { return CC; }
};
-}
+} // namespace ABIFunction
#endif
\ No newline at end of file
diff --git a/llvm/lib/LLVMABI/Type.cpp b/llvm/lib/LLVMABI/Type.cpp
index 4811c82dd..ac8950bb6 100644
--- a/llvm/lib/LLVMABI/Type.cpp
+++ b/llvm/lib/LLVMABI/Type.cpp
@@ -5,40 +5,46 @@
using namespace ABI;
void ABIBuiltinType::dump() const {
- std::cout << "BuiltinType: ";
- // Assuming you're sticking with these only:
- switch (kind) {
- case Void: std::cout << "Void\n"; break;
- case Bool: std::cout << "Bool\n"; break;
- case Integer:
- std::cout << "Integer\n";
- break;
- case Int128: std::cout << "Int128\n"; break;
- case UInt128:
- std::cout << "UInt128\n";
- break;
- case LongLong:
- std::cout << "LongLong\n";
- break;
- case Float:
- std::cout << "Float\n";
- break;
- case Double:
- std::cout << "Double\n";
- break;
- case Float16:
- std::cout << "Float16\n";
- break;
- case BFloat16:
- std::cout << "BFloat16\n";
- break;
- case Float128:
- std::cout << "Float128\n";
- break;
- case LongDouble:
- std::cout << "LongDouble\n";
- break;
- }
+ std::cout << "BuiltinType: ";
+ // Assuming you're sticking with these only:
+ switch (kind) {
+ case Void:
+ std::cout << "Void\n";
+ break;
+ case Bool:
+ std::cout << "Bool\n";
+ break;
+ case Integer:
+ std::cout << "Integer\n";
+ break;
+ case Int128:
+ std::cout << "Int128\n";
+ break;
+ case UInt128:
+ std::cout << "UInt128\n";
+ break;
+ case LongLong:
+ std::cout << "LongLong\n";
+ break;
+ case Float:
+ std::cout << "Float\n";
+ break;
+ case Double:
+ std::cout << "Double\n";
+ break;
+ case Float16:
+ std::cout << "Float16\n";
+ break;
+ case BFloat16:
+ std::cout << "BFloat16\n";
+ break;
+ case Float128:
+ std::cout << "Float128\n";
+ break;
+ case LongDouble:
+ std::cout << "LongDouble\n";
+ break;
+ }
}
void ABIRecordType::dump() const {
@@ -48,5 +54,5 @@ void ABIRecordType::dump() const {
std::cout << " Field: " << F.Name << ", Offset: " << F.OffsetInBits
<< " bits"
<< ", TypeClass: " << F.FieldType->getTypeClass() << "\n";
- }
+ }
}
diff --git a/llvm/lib/LLVMABI/Type.h b/llvm/lib/LLVMABI/Type.h
index d45371aad..d75523f5b 100644
--- a/llvm/lib/LLVMABI/Type.h
+++ b/llvm/lib/LLVMABI/Type.h
@@ -7,106 +7,104 @@
using namespace std;
-
-namespace ABI{
- class Type {
- public:
- enum TypeClass { Builtin, Record };
-
- Type(TypeClass TC) : Tc(TC) {}
+namespace ABI {
+class Type {
+public:
+ enum TypeClass { Builtin, Record };
- // getter method
- TypeClass getTypeClass() const { return Tc; }
+ Type(TypeClass TC) : Tc(TC) {}
- virtual ~Type() = default;
- bool isBuiltinType() const { return getTypeClass() == Builtin; }
- bool isAggregateType() const { return getTypeClass() == Record; }
+ // getter method
+ TypeClass getTypeClass() const { return Tc; }
- static bool classof(const Type *T) { return true; }
+ virtual ~Type() = default;
+ bool isBuiltinType() const { return getTypeClass() == Builtin; }
+ bool isAggregateType() const { return getTypeClass() == Record; }
- // debug info
- virtual void dump() const;
+ static bool classof(const Type *T) { return true; }
- private:
- //save the type class
- TypeClass Tc;
+ // debug info
+ virtual void dump() const;
+
+private:
+ // save the type class
+ TypeClass Tc;
};
class ABIBuiltinType : public Type {
- public:
- enum Kind {
- Void,
- Bool,
- Integer,
- Int128,
- UInt128,
- LongLong,
- Float,
- Double,
- Float16,
- BFloat16,
- Float128,
- LongDouble
- };
-
- private:
- Kind kind;
- uint64_t Size;
- uint64_t Alignment;
-
- public:
- ABIBuiltinType(Kind K) : Type(Builtin), kind(K) {}
-
- Kind getKind() const { return kind; }
-
- bool isInteger() const {
- return getKind() == Kind::Integer || getKind() == Kind::Int128;
- }
- bool isFloatingPoint() const { return getKind() == Kind::Float; }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
-
- void dump() const override;
+public:
+ enum Kind {
+ Void,
+ Bool,
+ Integer,
+ Int128,
+ UInt128,
+ LongLong,
+ Float,
+ Double,
+ Float16,
+ BFloat16,
+ Float128,
+ LongDouble
+ };
+
+private:
+ Kind kind;
+ uint64_t Size;
+ uint64_t Alignment;
+
+public:
+ ABIBuiltinType(Kind K) : Type(Builtin), kind(K) {}
+
+ Kind getKind() const { return kind; }
+
+ bool isInteger() const {
+ return getKind() == Kind::Integer || getKind() == Kind::Int128;
+ }
+ bool isFloatingPoint() const { return getKind() == Kind::Float; }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
+
+ void dump() const override;
};
class ABIRecordType : public Type {
- public:
- struct Field {
- std::string Name;
- const Type *FieldType;
- uint64_t OffsetInBits;
+public:
+ struct Field {
+ std::string Name;
+ const Type *FieldType;
+ uint64_t OffsetInBits;
- Field(const std::string &N, const Type *T, uint64_t Offset = 0)
- : Name(N), FieldType(T), OffsetInBits(Offset) {}
- };
+ Field(const std::string &N, const Type *T, uint64_t Offset = 0)
+ : Name(N), FieldType(T), OffsetInBits(Offset) {}
+ };
- using FieldList = std::vector<Field>;
+ using FieldList = std::vector<Field>;
- ABIRecordType(const std::string &Name, uint64_t AlignInBits = 0)
- : Type(Record), RecordName(Name), Alignment(AlignInBits) {}
+ ABIRecordType(const std::string &Name, uint64_t AlignInBits = 0)
+ : Type(Record), RecordName(Name), Alignment(AlignInBits) {}
- void addField(const std::string &Name, const Type *T, uint64_t Offset = 0) {
- Fields.emplace_back(Name, T, Offset);
- }
+ void addField(const std::string &Name, const Type *T, uint64_t Offset = 0) {
+ Fields.emplace_back(Name, T, Offset);
+ }
- const FieldList &getFields() const { return Fields; }
+ const FieldList &getFields() const { return Fields; }
- uint64_t getAlignmentInBits() const { return Alignment; }
- void setAlignmentInBits(uint64_t Align) { Alignment = Align; }
+ uint64_t getAlignmentInBits() const { return Alignment; }
+ void setAlignmentInBits(uint64_t Align) { Alignment = Align; }
- const std::string &getName() const { return RecordName; }
+ const std::string &getName() const { return RecordName; }
- static bool classof(const Type *T) { return T->getTypeClass() == Record; }
+ static bool classof(const Type *T) { return T->getTypeClass() == Record; }
- void dump() const;
+ void dump() const;
- private:
- std::string RecordName;
- FieldList Fields;
- uint64_t Alignment;
+private:
+ std::string RecordName;
+ FieldList Fields;
+ uint64_t Alignment;
};
} // namespace ABI
#endif
-
|
…ltypes to the abi types.
…l have a lot to refactor. Things to decide yet: 1. The mapping of QualTypes to ABI types is yet not crystal clear. 2. I think I am polluting the namespaces. Need to clean that up. 3. Mapping the ABIFunctionInfo to the CGFunctionInfo is yet to be done. 4. The target Call information has to be passed to the library. how does the library know which target it is lowering for.
invoke the compute info function. I will need to pass some information about the target. Also mapping from ABIFunctionInfo types back to CGFunctionInfo is still pending. Is the library going to be shipped seperately? or is it going to be a part of the LLVM repo?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a prototype for introducing an ABI lowering library in LLVM.
Initial design is focused around the x86_64 SysV ABI specifications.
The major work currently involves supporting the ABI details
related to calling conventions.
This library will feature its own completely independent type system.
Frontends which want to support a C FFI's will have to map from their
AST types to the library type system, and provide the target triple,
and based on this the library will return
ABIArgInfo
, an object whichwill have the function call coerced according to the ABI specifications.
This prototype currently supports the following:
will be a part of the result returned.