llvm.org GIT mirror llvm / 4dd162f
Cleanup stdcall / fastcall name mangling. This should fix alot of problems we saw so far, e.g. PRs 5851 & 2936 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95980 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 10 years ago
9 changed file(s) with 64 addition(s) and 154 deletion(s). Raw diff Collapse all Expand all
307307
308308 /// GetGlobalValueSymbol - Return the MCSymbol for the specified global
309309 /// value.
310 MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
310 virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
311311
312312 /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
313313 /// global value name as its base, with the specified suffix, and where the
3535 #include "llvm/Support/ErrorHandling.h"
3636 #include "llvm/Support/FormattedStream.h"
3737 #include "llvm/MC/MCAsmInfo.h"
38 #include "llvm/Target/Mangler.h"
3839 #include "llvm/Target/TargetLoweringObjectFile.h"
3940 #include "llvm/Target/TargetOptions.h"
4041 #include "llvm/Target/TargetRegistry.h"
5152 OutContext);
5253 }
5354
55 MCSymbol *X86AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const {
56 SmallString<60> NameStr;
57 Mang->getNameWithPrefix(NameStr, GV, false);
58 MCSymbol *Symb = OutContext.GetOrCreateSymbol(NameStr.str());
59
60 if (Subtarget->isTargetCygMing()) {
61 X86COFFMachineModuleInfo &COFFMMI =
62 MMI->getObjFileInfo();
63 COFFMMI.DecorateCygMingName(Symb, OutContext, GV, *TM.getTargetData());
64
65 // Save function name for later type emission.
66 if (const Function *F = dyn_cast(GV))
67 if (F->isDeclaration())
68 COFFMMI.addExternalFunction(Symb->getName());
69
70 }
71
72 return Symb;
73 }
74
5475 /// runOnMachineFunction - Emit the function body.
5576 ///
5677 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
5778 SetupMachineFunction(MF);
58
59 // COFF and Cygwin specific mangling stuff. This should be moved out to the
60 // mangler or handled some other way?
79
6180 if (Subtarget->isTargetCOFF()) {
62 X86COFFMachineModuleInfo &COFFMMI =
63 MMI->getObjFileInfo();
64
65 // Populate function information map. Don't want to populate
66 // non-stdcall or non-fastcall functions' information right now.
6781 const Function *F = MF.getFunction();
68 CallingConv::ID CC = F->getCallingConv();
69 if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall)
70 COFFMMI.AddFunctionInfo(F, *MF.getInfo());
71 }
72 if (Subtarget->isTargetCygMing()) {
73 const Function *F = MF.getFunction();
74 X86COFFMachineModuleInfo &COFFMMI =
75 MMI->getObjFileInfo();
76 COFFMMI.DecorateCygMingName(CurrentFnSym, OutContext,F,*TM.getTargetData());
77
78 O << "\t.def\t " << *CurrentFnSym;
79 O << ";\t.scl\t" <<
82 O << "\t.def\t " << *CurrentFnSym << ";\t.scl\t" <<
8083 (F->hasInternalLinkage() ? COFF::C_STAT : COFF::C_EXT)
8184 << ";\t.type\t" << (COFF::DT_FCN << COFF::N_BTSHFT)
8285 << ";\t.endef\n";
8386 }
84
87
8588 // Have common code print out the function header with linkage info etc.
8689 EmitFunctionHeader();
87
90
8891 // Emit the rest of the function body.
8992 EmitFunctionBody();
9093
118121 else
119122 GVSym = GetGlobalValueSymbol(GV);
120123
121 if (Subtarget->isTargetCygMing()) {
122 X86COFFMachineModuleInfo &COFFMMI =
123 MMI->getObjFileInfo();
124 COFFMMI.DecorateCygMingName(GVSym, OutContext, GV, *TM.getTargetData());
125 }
126
127124 // Handle dllimport linkage.
128125 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
129126 GVSym = OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName());
584581 for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I)
585582 if (I->hasDLLExportLinkage()) {
586583 MCSymbol *Sym = GetGlobalValueSymbol(I);
587 COFFMMI.DecorateCygMingName(Sym, OutContext, I, *TM.getTargetData());
588584 DLLExportedFns.push_back(Sym);
589585 }
590586
6060 virtual void EmitInstruction(const MachineInstr *MI);
6161
6262 void printSymbolOperand(const MachineOperand &MO);
63
64
63 virtual MCSymbol *GetGlobalValueSymbol(const GlobalValue *GV) const;
6564
6665 // These methods are used by the tablegen'erated instruction printer.
6766 void printOperand(const MachineInstr *MI, unsigned OpNo,
2626 X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
2727 }
2828
29 void X86COFFMachineModuleInfo::AddFunctionInfo(const Function *F,
30 const X86MachineFunctionInfo &Val) {
31 FunctionInfoMap[F] = Val;
29 void X86COFFMachineModuleInfo::addExternalFunction(const StringRef& Name) {
30 CygMingStubs.insert(Name);
3231 }
3332
34
35
36 static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
37 const TargetData &TD) {
38 X86MachineFunctionInfo Info;
39 uint64_t Size = 0;
40
41 switch (F->getCallingConv()) {
42 case CallingConv::X86_StdCall:
43 Info.setDecorationStyle(StdCall);
44 break;
45 case CallingConv::X86_FastCall:
46 Info.setDecorationStyle(FastCall);
47 break;
48 default:
49 return Info;
50 }
51
52 unsigned argNum = 1;
53 for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
54 AI != AE; ++AI, ++argNum) {
55 const Type* Ty = AI->getType();
56
57 // 'Dereference' type in case of byval parameter attribute
58 if (F->paramHasAttr(argNum, Attribute::ByVal))
59 Ty = cast(Ty)->getElementType();
60
61 // Size should be aligned to DWORD boundary
62 Size += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
63 }
64
65 // We're not supporting tooooo huge arguments :)
66 Info.setBytesToPopOnReturn((unsigned int)Size);
67 return Info;
68 }
69
70
71 /// DecorateCygMingName - Query FunctionInfoMap and use this information for
72 /// various name decorations for Cygwin and MingW.
33 /// DecorateCygMingName - Apply various name decorations if the function uses
34 /// stdcall or fastcall calling convention.
7335 void X86COFFMachineModuleInfo::DecorateCygMingName(SmallVectorImpl &Name,
7436 const GlobalValue *GV,
7537 const TargetData &TD) {
7638 const Function *F = dyn_cast(GV);
7739 if (!F) return;
78
79 // Save function name for later type emission.
80 if (F->isDeclaration())
81 CygMingStubs.insert(StringRef(Name.data(), Name.size()));
82
40
8341 // We don't want to decorate non-stdcall or non-fastcall functions right now
8442 CallingConv::ID CC = F->getCallingConv();
8543 if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
8644 return;
87
88 const X86MachineFunctionInfo *Info;
89
90 FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
91 if (info_item == FunctionInfoMap.end()) {
92 // Calculate apropriate function info and populate map
93 FunctionInfoMap[F] = calculateFunctionInfo(F, TD);
94 Info = &FunctionInfoMap[F];
95 } else {
96 Info = &info_item->second;
97 }
98
99 if (Info->getDecorationStyle() == None) return;
45
46 unsigned ArgWords = 0;
47 DenseMap::const_iterator item = FnArgWords.find(F);
48 if (item == FnArgWords.end()) {
49 // Calculate arguments sizes
50 for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
51 AI != AE; ++AI) {
52 const Type* Ty = AI->getType();
53
54 // 'Dereference' type in case of byval parameter attribute
55 if (AI->hasByValAttr())
56 Ty = cast(Ty)->getElementType();
57
58 // Size should be aligned to DWORD boundary
59 ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
60 }
61
62 FnArgWords[F] = ArgWords;
63 } else
64 ArgWords = item->second;
65
10066 const FunctionType *FT = F->getFunctionType();
101
10267 // "Pure" variadic functions do not receive @0 suffix.
10368 if (!FT->isVarArg() || FT->getNumParams() == 0 ||
10469 (FT->getNumParams() == 1 && F->hasStructRetAttr()))
105 raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
106
107 if (Info->getDecorationStyle() == FastCall) {
70 raw_svector_ostream(Name) << '@' << ArgWords;
71
72 if (CC == CallingConv::X86_FastCall) {
10873 if (Name[0] == '_')
10974 Name[0] = '@';
11075 else
11176 Name.insert(Name.begin(), '@');
112 }
77 }
11378 }
11479
11580 /// DecorateCygMingName - Query FunctionInfoMap and use this information for
12085 const TargetData &TD) {
12186 SmallString<128> NameStr(Name->getName().begin(), Name->getName().end());
12287 DecorateCygMingName(NameStr, GV, TD);
123
88
12489 Name = Ctx.GetOrCreateSymbol(NameStr.str());
12590 }
2020 namespace llvm {
2121 class X86MachineFunctionInfo;
2222 class TargetData;
23
23
2424 /// X86COFFMachineModuleInfo - This is a MachineModuleInfoImpl implementation
2525 /// for X86 COFF targets.
2626 class X86COFFMachineModuleInfo : public MachineModuleInfoImpl {
2727 StringSet<> CygMingStubs;
28
29 // We have to propagate some information about MachineFunction to
30 // AsmPrinter. It's ok, when we're printing the function, since we have
31 // access to MachineFunction and can get the appropriate MachineFunctionInfo.
32 // Unfortunately, this is not possible when we're printing reference to
33 // Function (e.g. calling it and so on). Even more, there is no way to get the
34 // corresponding MachineFunctions: it can even be not created at all. That's
35 // why we should use additional structure, when we're collecting all necessary
36 // information.
37 //
38 // This structure is using e.g. for name decoration for stdcall & fastcall'ed
39 // function, since we have to use arguments' size for decoration.
40 typedef std::map FMFInfoMap;
41 FMFInfoMap FunctionInfoMap;
42
28 DenseMap FnArgWords;
4329 public:
4430 X86COFFMachineModuleInfo(const MachineModuleInfo &);
4531 ~X86COFFMachineModuleInfo();
46
47
32
4833 void DecorateCygMingName(MCSymbol* &Name, MCContext &Ctx,
4934 const GlobalValue *GV, const TargetData &TD);
5035 void DecorateCygMingName(SmallVectorImpl &Name, const GlobalValue *GV,
5136 const TargetData &TD);
52
53 void AddFunctionInfo(const Function *F, const X86MachineFunctionInfo &Val);
54
5537
38 void addExternalFunction(const StringRef& Name);
5639 typedef StringSet<>::const_iterator stub_iterator;
5740 stub_iterator stub_begin() const { return CygMingStubs.begin(); }
5841 stub_iterator stub_end() const { return CygMingStubs.end(); }
59
60
6142 };
6243
6344
13971397 return CC_X86_32_C;
13981398 }
13991399
1400 /// NameDecorationForCallConv - Selects the appropriate decoration to
1401 /// apply to a MachineFunction containing a given calling convention.
1402 NameDecorationStyle
1403 X86TargetLowering::NameDecorationForCallConv(CallingConv::ID CallConv) {
1404 if (CallConv == CallingConv::X86_FastCall)
1405 return FastCall;
1406 else if (CallConv == CallingConv::X86_StdCall)
1407 return StdCall;
1408 return None;
1409 }
1410
1411
14121400 /// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
14131401 /// by "Src" to address "Dst" with size and alignment information specified by
14141402 /// the specific parameter attribute. The copy will be passed as a byval
14831471 Subtarget->isTargetCygMing() &&
14841472 Fn->getName() == "main")
14851473 FuncInfo->setForceFramePointer(true);
1486
1487 // Decorate the function name.
1488 FuncInfo->setDecorationStyle(NameDecorationForCallConv(CallConv));
14891474
14901475 MachineFrameInfo *MFI = MF.getFrameInfo();
14911476 bool Is64Bit = Subtarget->is64Bit();
638638 int FPDiff, DebugLoc dl);
639639
640640 CCAssignFn *CCAssignFnForNode(CallingConv::ID CallConv) const;
641 NameDecorationStyle NameDecorationForCallConv(CallingConv::ID CallConv);
642641 unsigned GetAlignedArgumentStackSize(unsigned StackSize, SelectionDAG &DAG);
643642
644643 std::pair FP_TO_INTHelper(SDValue Op, SelectionDAG &DAG,
1717
1818 namespace llvm {
1919
20 enum NameDecorationStyle {
21 None,
22 StdCall,
23 FastCall
24 };
25
2620 /// X86MachineFunctionInfo - This class is derived from MachineFunction and
2721 /// contains private X86 target-specific information for each MachineFunction.
2822 class X86MachineFunctionInfo : public MachineFunctionInfo {
3933 /// BytesToPopOnReturn - Number of bytes function pops on return.
4034 /// Used on windows platform for stdcall & fastcall name decoration
4135 unsigned BytesToPopOnReturn;
42
43 /// DecorationStyle - If the function requires additional name decoration,
44 /// DecorationStyle holds the right way to do so.
45 NameDecorationStyle DecorationStyle;
4636
4737 /// ReturnAddrIndex - FrameIndex for return slot.
4838 int ReturnAddrIndex;
6555 X86MachineFunctionInfo() : ForceFramePointer(false),
6656 CalleeSavedFrameSize(0),
6757 BytesToPopOnReturn(0),
68 DecorationStyle(None),
6958 ReturnAddrIndex(0),
7059 TailCallReturnAddrDelta(0),
7160 SRetReturnReg(0),
7564 : ForceFramePointer(false),
7665 CalleeSavedFrameSize(0),
7766 BytesToPopOnReturn(0),
78 DecorationStyle(None),
7967 ReturnAddrIndex(0),
8068 TailCallReturnAddrDelta(0),
8169 SRetReturnReg(0),
8977
9078 unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
9179 void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;}
92
93 NameDecorationStyle getDecorationStyle() const { return DecorationStyle; }
94 void setDecorationStyle(NameDecorationStyle style) { DecorationStyle = style;}
9580
9681 int getRAIndex() const { return ReturnAddrIndex; }
9782 void setRAIndex(int Index) { ReturnAddrIndex = Index; }
None ; RUN: llc < %s -mtriple=i386-unknown-mingw32 | \
1 ; RUN: grep {@12}
0 ; RUN: llc < %s -mtriple=i386-unknown-mingw32 | FileCheck %s
21
32 ; Check that a fastcall function gets correct mangling
43
54 define x86_fastcallcc void @func(i64 %X, i8 %Y, i8 %G, i16 %Z) {
5 ; CHECK: @func@20:
66 ret void
77 }
88