<p>The LLVM-IR Reference Manual's section on <a href="https://llvm.org/docs/LangRef.html#calling-conventions" rel="noreferrer">Calling Conventions</a> lists as many as 15 supported calling conventions. These vary in ways including whether they support tail call optimization, how many and which registers they preserve, what existing languages use them, and so on.</p>
<p>There seems to be an overwhelming variety, even if you know what you want to focus on, such as speed or TCO support (e.g., should I use <code>fastcc</code>, <code>tailcc</code>, <code>cc 10</code>, or <code>cc 11</code>?).</p>
<p>When designing a compiler, using LLVM-IR or otherwise, how should one choose what calling convention(s) to use?</p>

<functions><optimization><compilers><calling-conventions><tail-call-optimization>
Which calling convention should my compiler use?
<p>Any externally-accessible function (such as for libraries) should 100% use the standardized calling convention for the operating environment (what LLVM calls &quot;ccc&quot; I suppose). I believe on Windows there's not exactly a standardized convention since lots of legacy code still uses Pascal convention, so it would be optimum to allow some sort of decoration or attribute to specify the expected calling convention.</p>

CC BY-SA 4.0
2023-05-17T00:03:30.700Z
2023-05-17T00:03:30.700Z
kouta-kun
CC BY-SA 4.0
2023-05-17T01:48:22.493Z
It's worth noting that the move to 64-bit consolidated most of the older Windows calling conventions.
Pseudonym
<p>I would split the 14 (I'm not including <code>cc &lt;n&gt;</code> here) calling conventions listed in three categories:</p>
<ul>
<li>generic (those that would make sense for any function to have)</li>
<li>specific (those that some functions could benefit from)</li>
<li>targeted (those that were designed for specifically targeted situations)
Each group requires a different analysis, so I think it is best to just consider them separately.</li>
</ul>
<h2>Generic</h2>
<p>I include the following CCs in this category:</p>
<ul>
<li><code>ccc</code> - The C calling convention</li>
<li><code>fastcc</code> - The fast calling convention</li>
<li><code>tailcc</code> - Tail callable calling convention</li>
</ul>
<p>The choice here is very dependent on what your language is like. If your language is designed imperatively and has little need for tail calls (or doesn't support them at all), or needs strict C compatibility <code>ccc</code> is probably best. If your language has no vararg support (or you compile varargs to something different than LLVM IR varargs), <code>fastcc</code> and <code>tailcc</code> are both very good (and, as far as I can tell, <code>tailcc</code> should generally be best), and you can probably always use them. I can't recommend either choice unless I know what the language is like, though from experience I can say that unless you really want c/llvm-style varargs, <code>fastcc</code> and <code>tailcc</code> are the better choice. Choosing between the two is probably about choosing whether you want tail calling to be idiomatic code, or just something that is supported. If the first, <code>tailcc</code> ensures that optimization happens.
However, note <a href="https://llvm.org/docs/CodeGenerator.html#tail-call-optimization" rel="noreferrer">this</a>:</p>
<blockquote>
<p>To support tail call optimization in situations where the callee has more arguments than the caller a ‘callee pops arguments’ convention is used. This currently causes each <code>fastcc</code> call that is not tail call optimized (because one or more of above constraints are not met) to be followed by a readjustment of the stack. So performance might be worse in such cases.</p>
</blockquote>
<p>I have not found this to ever be a problem, but if you are very concerned about performance, you might want to statically decide where tail calls can happen (or let the user decide) and switch conventions based on that.</p>
<h2>Specific</h2>
<ul>
<li><code>coldcc</code> - The cold calling convention</li>
<li><code>preserve_mostcc</code> - The <em>PreserveMost</em> calling convention</li>
<li><code>preserve_allcc</code> - The <em>PreserveAll</em> calling convention</li>
</ul>
<p>There is pretty much no way to decide that a function can benefit from <code>coldcc</code> (which marks it as unlikely to be called and is optimized for that), unless you let users mark/annotate a function as such. <code>preserve_mostcc</code> is useful, for example, when you have memoized functions, which generally just load a value and return it (the <em>hot path</em> mentioned on the page), but once need to do computation (the <em>cold path</em>). <em>PreserveMost</em> removes all register saving-and-loading instructions when you load the saved value, which is almost every time the function is called. <code>preserve_allcc</code> is, quoting the page, <em>to support calls to runtime functions that don’t need to call out to any other functions</em>, and tries to be as little damaging as possible to the caller's registers. I have never used <code>preserve_allcc</code>, so I can't really give an example here.</p>
<h2>Targeted</h2>
<p>Everything else, so <code>cc 10</code>, <code>cc 11</code>, <code>webkit_jscc</code>, <code>anyregcc</code>, <code>cxx_fast_tlscc</code>, <code>swiftcc</code>, <code>swifttailcc</code>, <code>cfguard_checkcc</code>.</p>
<p>You don't need these. There isn't much more to be said, you just won't need these 99.99% of the time. (the remaining 0.01% is, for example, if you want close Swift interop, in which case you might want <code>swift[tail]cc</code>)</p>

CC BY-SA 4.0
2023-06-20T20:31:15.983Z
2023-06-20T20:31:15.983Z
RubenVerg
CC BY-SA 4.0
2023-06-20T20:32:41.717Z
I just realized I basically rephrased the linked page and added like one example. this is probably a somewhat bad answer, looking for opinions for deleting.
RubenVerg
CC BY-SA 4.0
2023-06-20T21:19:01.240Z
I found this a useful way of organizing the information, definitely no reason to delete it IMO
rydwolf
CC BY-SA 4.0
2023-07-21T19:22:08.557Z
Another reason to not use `swiftcc`: If you use it while compiling for RISC-V, [LLVM segfaults](https://godbolt.org/z/c635x15Mb).
Bbrk24
CC BY-SA 4.0
2023-07-21T20:14:59.313Z
@Bbrk24 lmao I suppose that is *a* reason
RubenVerg
# Which calling convention should my compiler use?
Posted by: username_0 on 2023-05-17
The LLVM-IR Reference Manual's section on [Calling Conventions](https://llvm.org/docs/LangRef.html#calling-conventions) lists as many as 15 supported calling conventions. These vary in ways including whether they support tail call optimization, how many and which registers they preserve, what existing languages use them, and so on.

There seems to be an overwhelming variety, even if you know what you want to focus on, such as speed or TCO support (e.g., should I use `fastcc`, `tailcc`, `cc 10`, or `cc 11`?).

When designing a compiler, using LLVM-IR or otherwise, how should one choose what calling convention(s) to use?
**Tags:** functions optimization compilers calling-conventions tail-call-optimization
---
## 2 answers
### Answer by username_1 on 2023-05-17. Score: 7
Any externally-accessible function (such as for libraries) should 100% use the standardized calling convention for the operating environment (what LLVM calls "ccc" I suppose). I believe on Windows there's not exactly a standardized convention since lots of legacy code still uses Pascal convention, so it would be optimum to allow some sort of decoration or attribute to specify the expected calling convention.
> **Comments:**
> **username_2** (2023-05-17): It's worth noting that the move to 64-bit consolidated most of the older Windows calling conventions.  
---
### Answer by username_3 on 2023-06-20. Score: 7
I would split the 14 (I'm not including `cc`  here) calling conventions listed in three categories:

* generic (those that would make sense for any function to have)
* specific (those that some functions could benefit from)
* targeted (those that were designed for specifically targeted situations)
  Each group requires a different analysis, so I think it is best to just consider them separately.

## Generic

I include the following CCs in this category:

* `ccc` - The C calling convention
* `fastcc` - The fast calling convention
* `tailcc` - Tail callable calling convention

The choice here is very dependent on what your language is like. If your language is designed imperatively and has little need for tail calls (or doesn't support them at all), or needs strict C compatibility `ccc` is probably best. If your language has no vararg support (or you compile varargs to something different than LLVM IR varargs), `fastcc` and `tailcc` are both very good (and, as far as I can tell, `tailcc` should generally be best), and you can probably always use them. I can't recommend either choice unless I know what the language is like, though from experience I can say that unless you really want c/llvm-style varargs, `fastcc` and `tailcc` are the better choice. Choosing between the two is probably about choosing whether you want tail calling to be idiomatic code, or just something that is supported. If the first, `tailcc` ensures that optimization happens.
However, note [this](https://llvm.org/docs/CodeGenerator.html#tail-call-optimization):

> To support tail call optimization in situations where the callee has more arguments than the caller a ‘callee pops arguments’ convention is used. This currently causes each `fastcc` call that is not tail call optimized (because one or more of above constraints are not met) to be followed by a readjustment of the stack. So performance might be worse in such cases.

I have not found this to ever be a problem, but if you are very concerned about performance, you might want to statically decide where tail calls can happen (or let the user decide) and switch conventions based on that.

## Specific

* `coldcc` - The cold calling convention
* `preserve_mostcc` - The *PreserveMost* calling convention
* `preserve_allcc` - The *PreserveAll* calling convention

There is pretty much no way to decide that a function can benefit from `coldcc` (which marks it as unlikely to be called and is optimized for that), unless you let users mark/annotate a function as such. `preserve_mostcc` is useful, for example, when you have memoized functions, which generally just load a value and return it (the *hot path* mentioned on the page), but once need to do computation (the *cold path*). *PreserveMost* removes all register saving-and-loading instructions when you load the saved value, which is almost every time the function is called. `preserve_allcc` is, quoting the page, *to support calls to runtime functions that don’t need to call out to any other functions*, and tries to be as little damaging as possible to the caller's registers. I have never used `preserve_allcc`, so I can't really give an example here.

## Targeted

Everything else, so `cc 10`, `cc 11`, `webkit_jscc`, `anyregcc`, `cxx_fast_tlscc`, `swiftcc`, `swifttailcc`, `cfguard_checkcc`.

You don't need these. There isn't much more to be said, you just won't need these 99.99% of the time. (the remaining 0.01% is, for example, if you want close Swift interop, in which case you might want `swift[tail]cc`)
> **Comments:**
> **username_3** (2023-06-20): I just realized I basically rephrased the linked page and added like one example. this is probably a somewhat bad answer, looking for opinions for deleting.  
> **username_0** (2023-06-20): I found this a useful way of organizing the information, definitely no reason to delete it IMO  
> **username_4** (2023-07-21): Another reason to not use `swiftcc`: If you use it while compiling for RISC-V, [LLVM segfaults](https://godbolt.org/z/c635x15Mb).  
> **username_3** (2023-07-21): @Bbrk24 lmao I suppose that is *a* reason  
---
