//===----------------------------------------------------------------------===// // Supporting multiple calling conventions in LLVM //===----------------------------------------------------------------------===// 8/17/2004 - Initial Revision 8/24/2004 - Added notes about target-indep front-ends. 8/26/2004 - Reserve 2-15 namespace for more target-independent cc's 10/7/2004 - Add a link, add note about 'infrequent call' Calling conventions are a wonderful thing, but they can also be a horrible thing. In LLVM, the code generators all use the standard C calling conventions. This allows LLVM to interoperate well with existing C compilers, and is critical for what we want to do. However, this is not enough. In particular, we want to be able to: 1. Support platforms that have multiple different calling conventions (e.g. fastcall, thiscall, stdcall, cdecl). 2. Interoperate with compilers like GCC that have a bunch of weird ABI morphing arguments (like -mregparam=N and -mfregparam=N), and related pragmas. 3. Support efficient ("correct") tail calls, which require passing arguments in "pascal order" instead of "C order". 4. Use more efficient calling conventions when we know we won't get caught (e.g. pass args in registers on X86, elide sign extensions for arg/ret value promotions, returning bools in condition codes, etc). //===----------------------------------------------------------------------===// // Proposal //===----------------------------------------------------------------------===// This proposal is very simple. Function calls (& invokes) and function definitions are augmented with a 32-bit integer calling convention number. Values 0-15 have specifically defined target-independent meanings, and values 16 -> N have target-specific meanings. If an actual callee and actual caller have mismatched calling conventions, the runtime behavior of the call is undefined. Calling convention numbers should be stable to a particular code generator (e.g. X86 or PPC32). They should not vary across subtargets like i386-linux vs i386-cygwin. Note that a target-independent front-end (such as Java or Scheme) should only generate CC#0 calling conventions. For interoperability with C compilers, they may generate simple CC#8 calls and functions, but must avoid returning multiple values in registers. Finally, without specifying a target triple, a front-end may not generate CC#16 or above calls or functions. //===------------- Calling Convention #0: 'fast' calling conventions Value #0 is defined to be whatever is most efficient for a target. In particular, if the caller and callee of a calling convention #0 call/function pair have different prototypes, the behavior of the call is undefined. In practice, this means that Value #0 calling conventions can only be used in limited circumstances: 1. Source languages that know the prototypes will always be matched up correctly can use this, if they know the callee is not going to be invoked by a non-llvm compiler. 2. Compiler optimizations can change the CC# of calls/functions if the call is not external, and if all callees are updated (this includes function pointers). Code generators have substantial freedom in their implementation of CC#0. In particular, when the code generator is young, it could just be the standard C calling conventions. When it becomes time to optimize the target implementation, defining CC#0 is important. In particular, here are some things that should be thought about: 1. If the call is not a varargs call, passing arguments in pascal order (the opposite of cdecl) allows for efficient (and trivial) tail call implementations. 2. Value should be passed in registers. 3. ... //===------------- Calling Convention #1: infrequent call Value #1 is defined to be used by functions that are not frequently called. In practice, this means that the target should choose a calling convention that clobbers as few registers as possible. Because calls to the function happen infrequently, the performance of the call is not very important, but the register reloads avoided in the caller can save a lot of space. This convention can be used, for example, by garbage collectors and other programs that have 'fast paths'. For example, you could code up something like this: inline void *allocate(unsigned Size) { if (BufPtr+Size <= BufEnd) { BufPtr += Size; // Allocate with a simple bump pointer return BufPtr-Size; } return run_gc_and_allocate(Size); // infrequent call } As with CC#0, this calling convention can be an alias for any other one and still work, though performance may not be the best. //===------------- Calling Convention #2 - 7: future expansion CC#2 - 6 are reserved for future target- and language-independent calling conventions. For now, we just reserve the namespace for future expansion. //===------------- Calling Convention #8: C calling conventions Value #8 is defined to be what we have now: C compatible calling conventions. These conventions are designed by platform providers to support stuff like this, and to make it work: --- a.c extern foo(...); int bar() { return foo(4); } --- b.c short foo(int X) { return X/17; } In this situation, the call to foo from 'a.c' has to pass arguments in a way that is compatible on the foo end. In particular, for most targets, this means that values have to be explicitly promoted to int/double (if they are smaller types), and if values are passed in registers, they also have to be passed in the stack in some cases. //===------------- Calling Convention #9 - 15 CC#9 - 15 are reserved for future target-independent language bindings, e.g. Pascal conventions. These may have restrictions placed on them (e.g. Pascal conventions do not support varargs), and may be different in other strange ways from CC#8. For now, we just reserve the namespace for future expansion. //===------------- Calling Convention #16 and above Value #16 and above are completely target specific calling conventions, and these calling conventions might have arbitrary limitations (e.g. no varargs, no vector support, etc). On X86 for example, we might have the following assignment: 2. stdcall (pascal). No varargs, passes arguments "backwards" 3. fastcall. Passes first two args in registers. 4. ... Because CC#16 can have arbitrary (weird) restrictions on it, any LLVM transformations that changes the prototypes of functions (e.g. DAE) should automatically change the calling convention to #0. If it can change the arguments passed to a function, by definition it knows all callers and callees. //===----------------------------------------------------------------------===// // Reference //===----------------------------------------------------------------------===// When to use __fastcall: http://www.cppbuilderdevjournal.com/articles/issues/0004/When_to_use___fastcall.htm Agner Fog's Calling Convention Survey: http://www.agner.org/assem/calling_conventions.pdf Cute diagrams: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_core_results_of_calling_example.asp Description of the X86 calling conventions across compilers: http://www.angelcode.com/dev/callconv/callconv.html "The history of calling conventions" articles. 8086: http://blogs.msdn.com/oldnewthing/archive/2004/01/02/47184.aspx i386: http://blogs.msdn.com/oldnewthing/archive/2004/01/08/48616.aspx IA64: http://blogs.msdn.com/oldnewthing/archive/2004/01/13/58199.aspx AMD64: http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx Other: http://blogs.msdn.com/oldnewthing/archive/2004/01/07/48303.aspx