llvm.org GIT mirror llvm / 4b70bfc
Begin adding docs and IR-level support for the inalloca attribute The inalloca attribute is designed to support passing C++ objects by value in the Microsoft C++ ABI. It behaves the same as byval, except that it always implies that the argument is in memory and that the bytes are never copied. This attribute allows the caller to take the address of an outgoing argument's memory and execute arbitrary code to store into it. This patch adds basic IR support, docs, and verification. It does not attempt to implement any lowering or fix any possibly broken transforms. When this patch lands, a complete description of this feature should appear at http://llvm.org/docs/InAlloca.html . Differential Revision: http://llvm-reviews.chandlerc.com/D2173 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197645 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 5 years ago
20 changed file(s) with 330 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
0 ==========================================
1 Design and Usage of the InAlloca Attribute
2 ==========================================
3
4 Introduction
5 ============
6
7 .. Warning:: This feature is unstable and not fully implemented.
8
9 The :ref:`attr_inalloca` attribute is designed to allow taking the
10 address of an aggregate argument that is being passed by value through
11 memory. Primarily, this feature is required for compatibility with the
12 Microsoft C++ ABI. Under that ABI, class instances that are passed by
13 value are constructed directly into argument stack memory. Prior to the
14 addition of inalloca, calls in LLVM were indivisible instructions.
15 There was no way to perform intermediate work, such as object
16 construction, between the first stack adjustment and the final control
17 transfer. With inalloca, each argument is modelled as an alloca, which
18 can be stored to independently of the call. Unfortunately, this
19 complicated feature comes with a large set of restrictions designed to
20 bound the lifetime of the argument memory around the call, which are
21 explained in this document.
22
23 For now, it is recommended that frontends and optimizers avoid producing
24 this construct, primarily because it forces the use of a base pointer.
25 This feature may grow in the future to allow general mid-level
26 optimization, but for now, it should be regarded as less efficient than
27 passing by value with a copy.
28
29 Intended Usage
30 ==============
31
32 In the example below, ``f`` is attempting to pass a default-constructed
33 ``Foo`` object to ``g`` by value.
34
35 .. code-block:: llvm
36
37 %Foo = type { i32, i32 }
38 declare void @Foo_ctor(%Foo* %this)
39 declare void @g(%Foo* inalloca %arg)
40
41 define void @f() {
42 ...
43
44 bb1:
45 %base = call i8* @llvm.stacksave()
46 %arg = alloca %Foo
47 invoke void @Foo_ctor(%Foo* %arg)
48 to label %invoke.cont unwind %invoke.unwind
49
50 invoke.cont:
51 call void @g(%Foo* inalloca %arg)
52 call void @llvm.stackrestore(i8* %base)
53 ...
54
55 invoke.unwind:
56 call void @llvm.stackrestore(i8* %base)
57 ...
58 }
59
60 The alloca in this example is dynamic, meaning it is not in the entry
61 block, and it can be executed more than once. Due to the restrictions
62 against allocas between an alloca used with inalloca and its associated
63 call site, all allocas used with inalloca are considered dynamic.
64
65 To avoid any stack leakage, the frontend saves the current stack pointer
66 with a call to :ref:`llvm.stacksave `. Then, it
67 allocates the argument stack space with alloca and calls the default
68 constructor. One important consideration is that the default
69 constructor could throw an exception, so the frontend has to create a
70 landing pad. At this point, if there were any other inalloca arguments,
71 the frontend would have to destruct them before restoring the stack
72 pointer. If the constructor does not unwind, ``g`` is called, and then
73 the stack is restored.
74
75 Design Considerations
76 =====================
77
78 Lifetime
79 --------
80
81 The biggest design consideration for this feature is object lifetime.
82 We cannot model the arguments as static allocas in the entry block,
83 because all calls need to use the memory that is at the end of the call
84 frame to pass arguments. We cannot vend pointers to that memory at
85 function entry because after code generation they will alias. In the
86 current design, the rule against allocas between the inalloca alloca
87 values and the call site avoids this problem, but it creates a cleanup
88 problem. Cleanup and lifetime is handled explicitly with stack save and
89 restore calls. In the future, we may be able to avoid this by using
90 :ref:`llvm.lifetime.start ` and :ref:`llvm.lifetime.end
91 ` instead.
92
93 Nested Calls and Copy Elision
94 -----------------------------
95
96 The next consideration is the ability for the frontend to perform copy
97 elision in the face of nested calls. Consider the evaluation of
98 ``foo(foo(Bar()))``, where ``foo`` takes and returns a ``Bar`` object by
99 value and ``Bar`` has non-trivial constructors. In this case, we want
100 to be able to elide copies into ``foo``'s argument slots. That means we
101 need to have more than one set of argument frames active at the same
102 time. First, we need to allocate the frame for the outer call so we can
103 pass it in as the hidden struct return pointer to the middle call. Then
104 we do the same for the middle call, allocating a frame and passing its
105 address to ``Bar``'s default constructor. By wrapping the evaluation of
106 the inner ``foo`` with stack save and restore, we can have multiple
107 overlapping active call frames.
108
109 Callee-cleanup Calling Conventions
110 ----------------------------------
111
112 Another wrinkle is the existence of callee-cleanup conventions. On
113 Windows, all methods and many other functions adjust the stack to clear
114 the memory used to pass their arguments. In some sense, this means that
115 the allocas are automatically cleared by the call. However, LLVM
116 instead models this as a write of undef to all of the inalloca values
117 passed to the call instead of a stack adjustment. Frontends should
118 still restore the stack pointer to avoid a stack leak.
119
120 Exceptions
121 ----------
122
123 There is also the possibility of an exception. If argument evaluation
124 or copy construction throws an exception, the landing pad must do
125 cleanup, which includes adjusting the stack pointer to avoid a stack
126 leak. This means the cleanup of the stack memory cannot be tied to the
127 call itself. There needs to be a separate IR-level instruction that can
128 perform independent cleanup of arguments.
129
130 Efficiency
131 ----------
132
133 Eventually, it should be possible to generate efficient code for this
134 construct. In particular, using inalloca should not require a base
135 pointer. If the backend can prove that all points in the CFG only have
136 one possible stack level, then it can address the stack directly from
137 the stack pointer. While this is not yet implemented, the plan is that
138 the inalloca attribute should not change much, but the frontend IR
139 generation recommendations may change.
695695 form and the known alignment of the pointer specified to the call
696696 site. If the alignment is not specified, then the code generator
697697 makes a target-specific assumption.
698
699 .. _attr_inalloca:
700
701 ``inalloca``
702
703 .. Warning:: This feature is unstable and not fully implemented.
704
705 The ``inalloca`` argument attribute allows the caller to get the
706 address of an outgoing argument to a ``call`` or ``invoke`` before
707 it executes. It is similar to ``byval`` in that it is used to pass
708 arguments by value, but it guarantees that the argument will not be
709 copied.
710
711 To be :ref:`well formed `, the caller must pass in an
712 alloca value into an ``inalloca`` parameter, and an alloca may be
713 used as an ``inalloca`` argument at most once. The attribute can
714 only be applied to parameters that would be passed in memory and not
715 registers. The ``inalloca`` attribute cannot be used in conjunction
716 with other attributes that affect argument storage, like ``inreg``,
717 ``nest``, ``sret``, or ``byval``. The ``inalloca`` stack space is
718 considered to be clobbered by any call that uses it, so any
719 ``inalloca`` parameters cannot be marked ``readonly``.
720
721 Allocas passed with ``inalloca`` to a call must be in the opposite
722 order of the parameter list, meaning that the rightmost argument
723 must be allocated first. If a call has inalloca arguments, no other
724 allocas can occur between the first alloca used by the call and the
725 call site, unless they are are cleared by calls to
726 :ref:`llvm.stackrestore `. Violating these rules
727 results in undefined behavior at runtime.
728
729 See :doc:`InAlloca` for more information on how to use this
730 attribute.
698731
699732 ``sret``
700733 This indicates that the pointer parameter specifies the address of a
84188451 This class of intrinsics exists to information about the lifetime of
84198452 memory objects and ranges where variables are immutable.
84208453
8454 .. _int_lifestart:
8455
84218456 '``llvm.lifetime.start``' Intrinsic
84228457 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84238458
84488483 of the memory pointed to by ``ptr`` is dead. This means that it is known
84498484 to never be used and has an undefined value. A load from the pointer
84508485 that precedes this intrinsic can be replaced with ``'undef'``.
8486
8487 .. _int_lifeend:
84518488
84528489 '``llvm.lifetime.end``' Intrinsic
84538490 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
369369 ATTR_KIND_Z_EXT = 34,
370370 ATTR_KIND_BUILTIN = 35,
371371 ATTR_KIND_COLD = 36,
372 ATTR_KIND_OPTIMIZE_NONE = 37
372 ATTR_KIND_OPTIMIZE_NONE = 37,
373 ATTR_KIND_IN_ALLOCA = 38
373374 };
374375
375376 } // End bitc namespace
5858 /// containing function.
5959 bool hasByValAttr() const;
6060
61 /// \brief If this is a byval argument, return its alignment.
61 /// \brief If this is a byval or inalloca argument, return its alignment.
6262 unsigned getParamAlignment() const;
6363
6464 /// \brief Return true if this argument has the nest attribute on it in its
8585 /// on it in its containing function.
8686 bool onlyReadsMemory() const;
8787
88 /// \brief Return true if this argument has the inalloca attribute on it in
89 /// its containing function.
90 bool hasInAllocaAttr() const;
8891
8992 /// \brief Add a Attribute to an argument.
9093 void addAttr(AttributeSet AS);
7070 Builtin, ///< Callee is recognized as a builtin, despite
7171 ///< nobuiltin attribute on its declaration.
7272 ByVal, ///< Pass structure by value
73 InAlloca, ///< Pass structure in an alloca
7374 Cold, ///< Marks function as being in a cold path.
7475 InlineHint, ///< Source said inlining was desirable
7576 InReg, ///< Force argument to be passed in register
256256 return paramHasAttr(ArgNo + 1, Attribute::ByVal);
257257 }
258258
259 /// @brief Determine whether this argument is passed in an alloca.
260 bool isInAllocaArgument(unsigned ArgNo) const {
261 return paramHasAttr(ArgNo + 1, Attribute::InAlloca);
262 }
263
264 /// @brief Determine whether this argument is passed by value or in an alloca.
265 bool isByValOrInAllocaArgument(unsigned ArgNo) const {
266 return paramHasAttr(ArgNo + 1, Attribute::ByVal) ||
267 paramHasAttr(ArgNo + 1, Attribute::InAlloca);
268 }
269
270 /// @brief Determine if there are any inalloca arguments.
271 bool hasInAllocaArgument() const {
272 return getAttributes().hasAttrSomewhere(Attribute::InAlloca);
273 }
274
259275 bool doesNotAccessMemory(unsigned ArgNo) const {
260276 return paramHasAttr(ArgNo + 1, Attribute::ReadNone);
261277 }
166166 LLVMAddressSafety = 1ULL << 32,
167167 LLVMStackProtectStrongAttribute = 1ULL<<33,
168168 LLVMCold = 1ULL << 34,
169 LLVMOptimizeNone = 1ULL << 35
169 LLVMOptimizeNone = 1ULL << 35,
170 LLVMInAllocaAttribute = 1ULL << 36
170171 */
171172 } LLVMAttribute;
172173
571571 KEYWORD(alwaysinline);
572572 KEYWORD(builtin);
573573 KEYWORD(byval);
574 KEYWORD(inalloca);
574575 KEYWORD(cold);
575576 KEYWORD(inlinehint);
576577 KEYWORD(inreg);
943943 "invalid use of attribute on a function");
944944 break;
945945 case lltok::kw_byval:
946 case lltok::kw_inalloca:
946947 case lltok::kw_nest:
947948 case lltok::kw_noalias:
948949 case lltok::kw_nocapture:
11551156 continue;
11561157 }
11571158 case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
1159 case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break;
11581160 case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
11591161 case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
11601162 case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
12171219 // Error handling.
12181220 case lltok::kw_align:
12191221 case lltok::kw_byval:
1222 case lltok::kw_inalloca:
12201223 case lltok::kw_nest:
12211224 case lltok::kw_nocapture:
12221225 case lltok::kw_returned:
9898 kw_sanitize_address,
9999 kw_builtin,
100100 kw_byval,
101 kw_inalloca,
101102 kw_cold,
102103 kw_inlinehint,
103104 kw_inreg,
521521 return Attribute::Builtin;
522522 case bitc::ATTR_KIND_BY_VAL:
523523 return Attribute::ByVal;
524 case bitc::ATTR_KIND_IN_ALLOCA:
525 return Attribute::InAlloca;
524526 case bitc::ATTR_KIND_COLD:
525527 return Attribute::Cold;
526528 case bitc::ATTR_KIND_INLINE_HINT:
168168 return bitc::ATTR_KIND_BUILTIN;
169169 case Attribute::ByVal:
170170 return bitc::ATTR_KIND_BY_VAL;
171 case Attribute::InAlloca:
172 return bitc::ATTR_KIND_IN_ALLOCA;
171173 case Attribute::Cold:
172174 return bitc::ATTR_KIND_COLD;
173175 case Attribute::InlineHint:
165165 return "builtin";
166166 if (hasAttribute(Attribute::ByVal))
167167 return "byval";
168 if (hasAttribute(Attribute::InAlloca))
169 return "inalloca";
168170 if (hasAttribute(Attribute::InlineHint))
169171 return "inlinehint";
170172 if (hasAttribute(Attribute::InReg))
387389 case Attribute::Cold: return 1ULL << 40;
388390 case Attribute::Builtin: return 1ULL << 41;
389391 case Attribute::OptimizeNone: return 1ULL << 42;
392 case Attribute::InAlloca: return 1ULL << 43;
390393 }
391394 llvm_unreachable("Unsupported attribute type");
392395 }
11731176 .addAttribute(Attribute::NoCapture)
11741177 .addAttribute(Attribute::ReadNone)
11751178 .addAttribute(Attribute::ReadOnly)
1176 .addAttribute(Attribute::StructRet);
1179 .addAttribute(Attribute::StructRet)
1180 .addAttribute(Attribute::InAlloca);
11771181
11781182 return AttributeSet::get(Ty->getContext(), Index, Incompatible);
11791183 }
8181 if (!getType()->isPointerTy()) return false;
8282 return getParent()->getAttributes().
8383 hasAttribute(getArgNo()+1, Attribute::ByVal);
84 }
85
86 /// \brief Return true if this argument has the inalloca attribute on it in
87 /// its containing function.
88 bool Argument::hasInAllocaAttr() const {
89 if (!getType()->isPointerTy()) return false;
90 return getParent()->getAttributes().
91 hasAttribute(getArgNo()+1, Attribute::InAlloca);
8492 }
8593
8694 unsigned Argument::getParamAlignment() const {
812812 !Attrs.hasAttribute(Idx, Attribute::Nest) &&
813813 !Attrs.hasAttribute(Idx, Attribute::StructRet) &&
814814 !Attrs.hasAttribute(Idx, Attribute::NoCapture) &&
815 !Attrs.hasAttribute(Idx, Attribute::Returned),
816 "Attribute 'byval', 'nest', 'sret', 'nocapture', and 'returned' "
817 "do not apply to return values!", V);
818
819 // Check for mutually incompatible attributes.
820 Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) &&
821 Attrs.hasAttribute(Idx, Attribute::Nest)) ||
822 (Attrs.hasAttribute(Idx, Attribute::ByVal) &&
823 Attrs.hasAttribute(Idx, Attribute::StructRet)) ||
824 (Attrs.hasAttribute(Idx, Attribute::Nest) &&
825 Attrs.hasAttribute(Idx, Attribute::StructRet))), "Attributes "
826 "'byval, nest, and sret' are incompatible!", V);
827
828 Assert1(!((Attrs.hasAttribute(Idx, Attribute::ByVal) &&
829 Attrs.hasAttribute(Idx, Attribute::Nest)) ||
830 (Attrs.hasAttribute(Idx, Attribute::ByVal) &&
831 Attrs.hasAttribute(Idx, Attribute::InReg)) ||
832 (Attrs.hasAttribute(Idx, Attribute::Nest) &&
833 Attrs.hasAttribute(Idx, Attribute::InReg))), "Attributes "
834 "'byval, nest, and inreg' are incompatible!", V);
815 !Attrs.hasAttribute(Idx, Attribute::Returned) &&
816 !Attrs.hasAttribute(Idx, Attribute::InAlloca),
817 "Attributes 'byval', 'inalloca', 'nest', 'sret', 'nocapture', and "
818 "'returned' do not apply to return values!", V);
819
820 // Check for mutually incompatible attributes. Only inreg is compatible with
821 // sret.
822 unsigned AttrCount = 0;
823 AttrCount += Attrs.hasAttribute(Idx, Attribute::ByVal);
824 AttrCount += Attrs.hasAttribute(Idx, Attribute::InAlloca);
825 AttrCount += Attrs.hasAttribute(Idx, Attribute::StructRet) ||
826 Attrs.hasAttribute(Idx, Attribute::InReg);
827 AttrCount += Attrs.hasAttribute(Idx, Attribute::Nest);
828 Assert1(AttrCount <= 1, "Attributes 'byval', 'inalloca', 'inreg', 'nest', "
829 "and 'sret' are incompatible!", V);
830
831 Assert1(!(Attrs.hasAttribute(Idx, Attribute::InAlloca) &&
832 Attrs.hasAttribute(Idx, Attribute::ReadOnly)), "Attributes "
833 "'inalloca and readonly' are incompatible!", V);
835834
836835 Assert1(!(Attrs.hasAttribute(Idx, Attribute::StructRet) &&
837836 Attrs.hasAttribute(Idx, Attribute::Returned)), "Attributes "
854853 "Wrong types for attribute: " +
855854 AttributeFuncs::typeIncompatible(Ty, Idx).getAsString(Idx), V);
856855
857 if (PointerType *PTy = dyn_cast(Ty))
858 Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) ||
859 PTy->getElementType()->isSized(),
860 "Attribute 'byval' does not support unsized types!", V);
861 else
856 if (PointerType *PTy = dyn_cast(Ty)) {
857 if (!PTy->getElementType()->isSized()) {
858 Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal) &&
859 !Attrs.hasAttribute(Idx, Attribute::InAlloca),
860 "Attributes 'byval' and 'inalloca' do not support unsized types!",
861 V);
862 }
863 } else {
862864 Assert1(!Attrs.hasAttribute(Idx, Attribute::ByVal),
863865 "Attribute 'byval' only applies to parameters with pointer type!",
864866 V);
867 }
865868 }
866869
867870 // VerifyFunctionAttrs - Check parameter attributes against a function type.
15311534
15321535 // Verify call attributes.
15331536 VerifyFunctionAttrs(FTy, Attrs, I);
1537
1538 // Verify that values used for inalloca parameters are in fact allocas.
1539 for (unsigned i = 0, e = CS.arg_size(); i != e; ++i) {
1540 if (!Attrs.hasAttribute(1 + i, Attribute::InAlloca))
1541 continue;
1542 Value *Arg = CS.getArgument(i);
1543 Assert2(isa(Arg), "Inalloca argument is not an alloca!", I,
1544 Arg);
1545 }
15341546
15351547 if (FTy->isVarArg()) {
15361548 // FIXME? is 'nest' even legal here?
18691881 &AI);
18701882 Assert1(AI.getArraySize()->getType()->isIntegerTy(),
18711883 "Alloca array size must have integer type", &AI);
1884
1885 // Verify that an alloca instruction is not used with inalloca more than once.
1886 unsigned InAllocaUses = 0;
1887 for (User::use_iterator UI = AI.use_begin(), UE = AI.use_end(); UI != UE;
1888 ++UI) {
1889 CallSite CS(*UI);
1890 if (!CS)
1891 continue;
1892 unsigned ArgNo = CS.getArgumentNo(UI);
1893 if (CS.isInAllocaArgument(ArgNo)) {
1894 InAllocaUses++;
1895 Assert1(InAllocaUses <= 1,
1896 "Allocas can be used at most once with inalloca!", &AI);
1897 }
1898 }
1899
18721900 visitInstruction(AI);
18731901 }
18741902
490490 HANDLE_ATTR(NoUnwind);
491491 HANDLE_ATTR(NoAlias);
492492 HANDLE_ATTR(ByVal);
493 HANDLE_ATTR(InAlloca);
493494 HANDLE_ATTR(Nest);
494495 HANDLE_ATTR(ReadNone);
495496 HANDLE_ATTR(ReadOnly);
210210 ; CHECK: define void @f35() #23
211211 {
212212 ret void;
213 }
214
215 define void @f36(i8* inalloca) {
216 ; CHECK: define void @f36(i8* inalloca) {
217 ret void
213218 }
214219
215220 ; CHECK: attributes #0 = { noreturn }
0 ; RUN: llc < %s -march=cpp | FileCheck %s
1
2 define void @f1(i8* byval, i8* inalloca) {
3 ; CHECK: ByVal
4 ; CHECK: InAlloca
5 ret void
6 }
0 ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 declare void @a(i64* byval inalloca %p)
3 ; CHECK: Attributes {{.*}} are incompatible
4
5 declare void @b(i64* inreg inalloca %p)
6 ; CHECK: Attributes {{.*}} are incompatible
7
8 declare void @c(i64* sret inalloca %p)
9 ; CHECK: Attributes {{.*}} are incompatible
10
11 declare void @d(i64* nest inalloca %p)
12 ; CHECK: Attributes {{.*}} are incompatible
13
14 declare void @e(i64* readonly inalloca %p)
15 ; CHECK: Attributes {{.*}} are incompatible
16
17 declare void @f(void ()* inalloca %p)
18 ; CHECK: do not support unsized types
0 ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
1
2 declare void @doit(i64* inalloca %a)
3
4 define void @a() {
5 entry:
6 %a = alloca [2 x i32]
7 %b = bitcast [2 x i32]* %a to i64*
8 call void @doit(i64* inalloca %b)
9 ; CHECK: Inalloca argument is not an alloca!
10 ret void
11 }
12
13 define void @b() {
14 entry:
15 %a = alloca i64
16 call void @doit(i64* inalloca %a)
17 call void @doit(i64* inalloca %a)
18 ; CHECK: Allocas can be used at most once with inalloca!
19 ret void
20 }