Skip to content

[Object][COFF][NFC] Introduce Arm64ECThunkType enum. #85936

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

Merged
merged 1 commit into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions llvm/include/llvm/BinaryFormat/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,12 @@ enum Feat00Flags : uint32_t {
Kernel = 0x40000000,
};

enum class Arm64ECThunkType : uint8_t {
GuestExit = 0,
Entry = 1,
Exit = 4,
};

inline bool isReservedSectionNumber(int32_t SectionNumber) {
return SectionNumber <= 0;
}
Expand Down
57 changes: 29 additions & 28 deletions llvm/lib/Target/AArch64/AArch64Arm64ECCallLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "llvm/TargetParser/Triple.h"

using namespace llvm;
using namespace llvm::COFF;
using namespace llvm::object;

using OperandBundleDef = OperandBundleDefT<Value *>;
Expand All @@ -45,8 +46,6 @@ static cl::opt<bool> GenerateThunks("arm64ec-generate-thunks", cl::Hidden,

namespace {

enum class ThunkType { GuestExit, Entry, Exit };

class AArch64Arm64ECCallLowering : public ModulePass {
public:
static char ID;
Expand All @@ -73,15 +72,15 @@ class AArch64Arm64ECCallLowering : public ModulePass {
Type *I64Ty;
Type *VoidTy;

void getThunkType(FunctionType *FT, AttributeList AttrList, ThunkType TT,
raw_ostream &Out, FunctionType *&Arm64Ty,
FunctionType *&X64Ty);
void getThunkType(FunctionType *FT, AttributeList AttrList,
Arm64ECThunkType TT, raw_ostream &Out,
FunctionType *&Arm64Ty, FunctionType *&X64Ty);
void getThunkRetType(FunctionType *FT, AttributeList AttrList,
raw_ostream &Out, Type *&Arm64RetTy, Type *&X64RetTy,
SmallVectorImpl<Type *> &Arm64ArgTypes,
SmallVectorImpl<Type *> &X64ArgTypes, bool &HasSretPtr);
void getThunkArgTypes(FunctionType *FT, AttributeList AttrList, ThunkType TT,
raw_ostream &Out,
void getThunkArgTypes(FunctionType *FT, AttributeList AttrList,
Arm64ECThunkType TT, raw_ostream &Out,
SmallVectorImpl<Type *> &Arm64ArgTypes,
SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr);
void canonicalizeThunkType(Type *T, Align Alignment, bool Ret,
Expand All @@ -91,13 +90,11 @@ class AArch64Arm64ECCallLowering : public ModulePass {

} // end anonymous namespace

void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
AttributeList AttrList,
ThunkType TT, raw_ostream &Out,
FunctionType *&Arm64Ty,
FunctionType *&X64Ty) {
Out << (TT == ThunkType::Entry ? "$ientry_thunk$cdecl$"
: "$iexit_thunk$cdecl$");
void AArch64Arm64ECCallLowering::getThunkType(
FunctionType *FT, AttributeList AttrList, Arm64ECThunkType TT,
raw_ostream &Out, FunctionType *&Arm64Ty, FunctionType *&X64Ty) {
Out << (TT == Arm64ECThunkType::Entry ? "$ientry_thunk$cdecl$"
: "$iexit_thunk$cdecl$");

Type *Arm64RetTy;
Type *X64RetTy;
Expand All @@ -108,7 +105,7 @@ void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
// The first argument to a thunk is the called function, stored in x9.
// For exit thunks, we pass the called function down to the emulator;
// for entry/guest exit thunks, we just call the Arm64 function directly.
if (TT == ThunkType::Exit)
if (TT == Arm64ECThunkType::Exit)
Arm64ArgTypes.push_back(PtrTy);
X64ArgTypes.push_back(PtrTy);

Expand All @@ -125,8 +122,8 @@ void AArch64Arm64ECCallLowering::getThunkType(FunctionType *FT,
}

void AArch64Arm64ECCallLowering::getThunkArgTypes(
FunctionType *FT, AttributeList AttrList, ThunkType TT, raw_ostream &Out,
SmallVectorImpl<Type *> &Arm64ArgTypes,
FunctionType *FT, AttributeList AttrList, Arm64ECThunkType TT,
raw_ostream &Out, SmallVectorImpl<Type *> &Arm64ArgTypes,
SmallVectorImpl<Type *> &X64ArgTypes, bool HasSretPtr) {

Out << "$";
Expand Down Expand Up @@ -163,7 +160,7 @@ void AArch64Arm64ECCallLowering::getThunkArgTypes(
X64ArgTypes.push_back(PtrTy);
// x5
Arm64ArgTypes.push_back(I64Ty);
if (TT != ThunkType::Entry) {
if (TT != Arm64ECThunkType::Entry) {
// FIXME: x5 isn't actually used by the x64 side; revisit once we
// have proper isel for varargs
X64ArgTypes.push_back(I64Ty);
Expand Down Expand Up @@ -348,7 +345,8 @@ Function *AArch64Arm64ECCallLowering::buildExitThunk(FunctionType *FT,
SmallString<256> ExitThunkName;
llvm::raw_svector_ostream ExitThunkStream(ExitThunkName);
FunctionType *Arm64Ty, *X64Ty;
getThunkType(FT, Attrs, ThunkType::Exit, ExitThunkStream, Arm64Ty, X64Ty);
getThunkType(FT, Attrs, Arm64ECThunkType::Exit, ExitThunkStream, Arm64Ty,
X64Ty);
if (Function *F = M->getFunction(ExitThunkName))
return F;

Expand Down Expand Up @@ -451,8 +449,8 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
SmallString<256> EntryThunkName;
llvm::raw_svector_ostream EntryThunkStream(EntryThunkName);
FunctionType *Arm64Ty, *X64Ty;
getThunkType(F->getFunctionType(), F->getAttributes(), ThunkType::Entry,
EntryThunkStream, Arm64Ty, X64Ty);
getThunkType(F->getFunctionType(), F->getAttributes(),
Arm64ECThunkType::Entry, EntryThunkStream, Arm64Ty, X64Ty);
if (Function *F = M->getFunction(EntryThunkName))
return F;

Expand Down Expand Up @@ -543,8 +541,8 @@ Function *AArch64Arm64ECCallLowering::buildEntryThunk(Function *F) {
Function *AArch64Arm64ECCallLowering::buildGuestExitThunk(Function *F) {
llvm::raw_null_ostream NullThunkName;
FunctionType *Arm64Ty, *X64Ty;
getThunkType(F->getFunctionType(), F->getAttributes(), ThunkType::GuestExit,
NullThunkName, Arm64Ty, X64Ty);
getThunkType(F->getFunctionType(), F->getAttributes(),
Arm64ECThunkType::GuestExit, NullThunkName, Arm64Ty, X64Ty);
auto MangledName = getArm64ECMangledFunctionName(F->getName().str());
assert(MangledName && "Can't guest exit to function that's already native");
std::string ThunkName = *MangledName;
Expand Down Expand Up @@ -679,7 +677,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
struct ThunkInfo {
Constant *Src;
Constant *Dst;
unsigned Kind;
Arm64ECThunkType Kind;
};
SmallVector<ThunkInfo> ThunkMapping;
for (Function &F : Mod) {
Expand All @@ -688,14 +686,17 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
F.getCallingConv() != CallingConv::ARM64EC_Thunk_X64) {
if (!F.hasComdat())
F.setComdat(Mod.getOrInsertComdat(F.getName()));
ThunkMapping.push_back({&F, buildEntryThunk(&F), 1});
ThunkMapping.push_back(
{&F, buildEntryThunk(&F), Arm64ECThunkType::Entry});
}
}
for (Function *F : DirectCalledFns) {
ThunkMapping.push_back(
{F, buildExitThunk(F->getFunctionType(), F->getAttributes()), 4});
{F, buildExitThunk(F->getFunctionType(), F->getAttributes()),
Arm64ECThunkType::Exit});
if (!F->hasDLLImportStorageClass())
ThunkMapping.push_back({buildGuestExitThunk(F), F, 0});
ThunkMapping.push_back(
{buildGuestExitThunk(F), F, Arm64ECThunkType::GuestExit});
}

if (!ThunkMapping.empty()) {
Expand All @@ -704,7 +705,7 @@ bool AArch64Arm64ECCallLowering::runOnModule(Module &Mod) {
ThunkMappingArrayElems.push_back(ConstantStruct::getAnon(
{ConstantExpr::getBitCast(Thunk.Src, PtrTy),
ConstantExpr::getBitCast(Thunk.Dst, PtrTy),
ConstantInt::get(M->getContext(), APInt(32, Thunk.Kind))}));
ConstantInt::get(M->getContext(), APInt(32, uint8_t(Thunk.Kind)))}));
}
Constant *ThunkMappingArray = ConstantArray::get(
llvm::ArrayType::get(ThunkMappingArrayElems[0]->getType(),
Expand Down