diff options
Diffstat (limited to 'lib/IR/Mangler.cpp')
-rw-r--r-- | lib/IR/Mangler.cpp | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/lib/IR/Mangler.cpp b/lib/IR/Mangler.cpp index 27d973b94f0a..5eeb7978e2f3 100644 --- a/lib/IR/Mangler.cpp +++ b/lib/IR/Mangler.cpp @@ -22,23 +22,25 @@ using namespace llvm; static void getNameWithPrefixx(raw_ostream &OS, const Twine &GVName, Mangler::ManglerPrefixTy PrefixTy, - const DataLayout &DL, bool UseAt) { + const DataLayout &DL, char Prefix) { SmallString<256> TmpData; StringRef Name = GVName.toStringRef(TmpData); assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); + // No need to do anything special if the global has the special "do not + // mangle" flag in the name. + if (Name[0] == '\1') { + OS << Name.substr(1); + return; + } + if (PrefixTy == Mangler::Private) OS << DL.getPrivateGlobalPrefix(); else if (PrefixTy == Mangler::LinkerPrivate) OS << DL.getLinkerPrivateGlobalPrefix(); - if (UseAt) { - OS << '@'; - } else { - char Prefix = DL.getGlobalPrefix(); - if (Prefix != '\0') - OS << Prefix; - } + if (Prefix != '\0') + OS << Prefix; // If this is a simple string that doesn't need escaping, just append it. OS << Name; @@ -46,7 +48,8 @@ static void getNameWithPrefixx(raw_ostream &OS, const Twine &GVName, void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName, ManglerPrefixTy PrefixTy) const { - return getNameWithPrefixx(OS, GVName, PrefixTy, *DL, false); + char Prefix = DL->getGlobalPrefix(); + return getNameWithPrefixx(OS, GVName, PrefixTy, *DL, Prefix); } void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, @@ -56,11 +59,21 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, return getNameWithPrefix(OS, GVName, PrefixTy); } -/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require -/// a suffix on their name indicating the number of words of arguments they -/// take. -static void AddFastCallStdCallSuffix(raw_ostream &OS, const Function *F, - const DataLayout &TD) { +static bool hasByteCountSuffix(CallingConv::ID CC) { + switch (CC) { + case CallingConv::X86_FastCall: + case CallingConv::X86_StdCall: + case CallingConv::X86_VectorCall: + return true; + default: + return false; + } +} + +/// Microsoft fastcall and stdcall functions require a suffix on their name +/// indicating the number of words of arguments they take. +static void addByteCountSuffix(raw_ostream &OS, const Function *F, + const DataLayout &TD) { // Calculate arguments size total. unsigned ArgWords = 0; for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); @@ -69,8 +82,9 @@ static void AddFastCallStdCallSuffix(raw_ostream &OS, const Function *F, // 'Dereference' type in case of byval or inalloca parameter attribute. if (AI->hasByValOrInAllocaAttr()) Ty = cast<PointerType>(Ty)->getElementType(); - // Size should be aligned to DWORD boundary - ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4; + // Size should be aligned to pointer size. + unsigned PtrSize = TD.getPointerSize(); + ArgWords += RoundUpToAlignment(TD.getTypeAllocSize(Ty), PtrSize); } OS << '@' << ArgWords; @@ -99,41 +113,41 @@ void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, } StringRef Name = GV->getName(); - - // No need to do anything special if the global has the special "do not - // mangle" flag in the name. - if (Name[0] == '\1') { - OS << Name.substr(1); - return; - } - - bool UseAt = false; - const Function *MSFunc = nullptr; - CallingConv::ID CC; - if (DL->hasMicrosoftFastStdCallMangling()) { - if ((MSFunc = dyn_cast<Function>(GV))) { - CC = MSFunc->getCallingConv(); - // fastcall functions need to start with @ instead of _. - if (CC == CallingConv::X86_FastCall) - UseAt = true; - } + char Prefix = DL->getGlobalPrefix(); + + // Mangle functions with Microsoft calling conventions specially. Only do + // this mangling for x86_64 vectorcall and 32-bit x86. + const Function *MSFunc = dyn_cast<Function>(GV); + if (Name.startswith("\01")) + MSFunc = nullptr; // Don't mangle when \01 is present. + CallingConv::ID CC = + MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C; + if (!DL->hasMicrosoftFastStdCallMangling() && + CC != CallingConv::X86_VectorCall) + MSFunc = nullptr; + if (MSFunc) { + if (CC == CallingConv::X86_FastCall) + Prefix = '@'; // fastcall functions have an @ prefix instead of _. + else if (CC == CallingConv::X86_VectorCall) + Prefix = '\0'; // vectorcall functions have no prefix. } - getNameWithPrefixx(OS, Name, PrefixTy, *DL, UseAt); + getNameWithPrefixx(OS, Name, PrefixTy, *DL, Prefix); if (!MSFunc) return; - // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, - // add it. - // fastcall and stdcall functions usually need @42 at the end to specify - // the argument info. + // If we are supposed to add a microsoft-style suffix for stdcall, fastcall, + // or vectorcall, add it. These functions have a suffix of @N where N is the + // cumulative byte size of all of the parameters to the function in decimal. + if (CC == CallingConv::X86_VectorCall) + OS << '@'; // vectorcall functions use a double @ suffix. FunctionType *FT = MSFunc->getFunctionType(); - if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) && + if (hasByteCountSuffix(CC) && // "Pure" variadic functions do not receive @0 suffix. (!FT->isVarArg() || FT->getNumParams() == 0 || (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr()))) - AddFastCallStdCallSuffix(OS, MSFunc, *DL); + addByteCountSuffix(OS, MSFunc, *DL); } void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, |