@@ -85,11 +85,26 @@ pub trait TypeBuilder {
8585
8686 /// Return whether the type is a builtin.
8787 fn is_builtin ( & self ) -> bool ;
88- /// Return whether the type requires a return pointer when returning.
88+ /// Return whether the type requires a return pointer when returning,
89+ /// instead of using the CPU registers.
90+ ///
91+ /// This attribute does not modify the compilation, and it only reflects
92+ /// what the ABI of the target architecture already specifies.
93+ /// - For x86-64: https://gitlab.com/x86-psABIs/x86-64-ABI.
94+ /// - For AArch64: https://github.com/ARM-software/abi-aa.
95+ ///
96+ /// We can validate this empirically, by building a Cairo program that
97+ /// returns a particular type, and seeing how it is lowered to machine code.
98+ ///
99+ /// ```bash
100+ /// llc a.llvmir -o - --mtriple "aarch64"
101+ /// llc a.llvmir -o - --mtriple "x86_64"
102+ /// ```
89103 fn is_complex (
90104 & self ,
91105 registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
92106 ) -> Result < bool , Self :: Error > ;
107+
93108 /// Return whether the Sierra type resolves to a zero-sized type.
94109 fn is_zst (
95110 & self ,
@@ -104,8 +119,21 @@ pub trait TypeBuilder {
104119 registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
105120 ) -> Result < Layout , Self :: Error > ;
106121
107- /// Whether the layout should be allocated in memory (either the stack or the heap) when used as
108- /// a function invocation argument or return value.
122+ /// Whether the layout should be allocated in memory (either the stack or
123+ /// the heap) when used as a function invocation argument or return value.
124+ ///
125+ /// Unlike `is_complex`, this attribute alters the compilation:
126+ ///
127+ /// - When passing a memory allocated value to a function, we allocate that
128+ /// value on the stack, and pass a pointer to it.
129+ ///
130+ /// - If a function returns a memory allocated value, we receive a return
131+ /// pointer as its first argument, and write the return value there
132+ /// instead.
133+ ///
134+ /// The rationale behind allocating a value in memory, rather than
135+ /// registers, is to avoid putting too much pressure on the register
136+ /// allocation pass for really complex types, like enums.
109137 fn is_memory_allocated (
110138 & self ,
111139 registry : & ProgramRegistry < CoreType , CoreLibfunc > ,
0 commit comments