llvm.org GIT mirror llvm / 3cbfa16
Add an inalloca flag to allocas Summary: The only current use of this flag is to mark the alloca as dynamic, even if its in the entry block. The stack adjustment for the alloca can never be folded into the prologue because the call may clear it and it has to be allocated at the top of the stack. Reviewers: majnemer CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2571 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199525 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 6 years ago
10 changed file(s) with 100 addition(s) and 30 deletion(s). Raw diff Collapse all Expand all
777777 .. Warning:: This feature is unstable and not fully implemented.
778778
779779 The ``inalloca`` argument attribute allows the caller to take the
780 address of all stack-allocated arguments to a ``call`` or ``invoke``
781 before it executes. It is similar to ``byval`` in that it is used
782 to pass arguments by value, but it guarantees that the argument will
783 not be copied.
784
785 To be :ref:`well formed `, an alloca may be used as an
786 ``inalloca`` argument at most once. The attribute can only be
787 applied to the last parameter, and it guarantees that they are
788 passed in memory. The ``inalloca`` attribute cannot be used in
789 conjunction with other attributes that affect argument storage, like
790 ``inreg``, ``nest``, ``sret``, or ``byval``. The ``inalloca`` stack
791 space is considered to be clobbered by any call that uses it, so any
792 ``inalloca`` parameters cannot be marked ``readonly``.
780 address of outgoing stack arguments. An ``inalloca`` argument must
781 be a pointer to stack memory produced by an ``alloca`` instruction.
782 The alloca, or argument allocation, must also be tagged with the
783 inalloca keyword. Only the past argument may have the ``inalloca``
784 attribute, and that argument is guaranteed to be passed in memory.
785
786 An argument allocation may be used by a call at most once because
787 the call may deallocate it. The ``inalloca`` attribute cannot be
788 used in conjunction with other attributes that affect argument
789 storage, like ``inreg``, ``nest``, ``sret``, or ``byval``.
793790
794791 When the call site is reached, the argument allocation must have
795792 been the most recent stack allocation that is still live, or the
46924689
46934690 ::
46944691
4695 = alloca [, ][, align ] ; yields {type*}:result
4692 = alloca [, inalloca][, ][, align ] ; yields {type*}:result
46964693
46974694 Overview:
46984695 """""""""
5858 /// containing function.
5959 bool hasByValAttr() const;
6060
61 /// \brief Return true if this argument has the byval attribute or inalloca
62 /// attribute on it in its containing function. These attributes both
63 /// represent arguments being passed by value.
64 bool hasByValOrInAllocaAttr() const;
65
6166 /// \brief If this is a byval or inalloca argument, return its alignment.
6267 unsigned getParamAlignment() const;
6368
100100 /// by the instruction.
101101 ///
102102 unsigned getAlignment() const {
103 return (1u << getSubclassDataFromInstruction()) >> 1;
103 return (1u << (getSubclassDataFromInstruction() & 31)) >> 1;
104104 }
105105 void setAlignment(unsigned Align);
106106
108108 /// function and is a constant size. If so, the code generator will fold it
109109 /// into the prolog/epilog code, so it is basically free.
110110 bool isStaticAlloca() const;
111
112 /// \brief Return true if this alloca is used as an inalloca argument to a
113 /// call. Such allocas are never considered static even if they are in the
114 /// entry block.
115 bool isUsedWithInAlloca() const {
116 return getSubclassDataFromInstruction() & 32;
117 }
118
119 /// \brief Specify whether this alloca is used to represent a the arguments to
120 /// a call.
121 void setUsedWithInAlloca(bool V) {
122 setInstructionSubclassData((getSubclassDataFromInstruction() & ~32) |
123 (V ? 32 : 0));
124 }
111125
112126 // Methods for support type inquiry through isa, cast, and dyn_cast:
113127 static inline bool classof(const Instruction *I) {
40684068 //===----------------------------------------------------------------------===//
40694069
40704070 /// ParseAlloc
4071 /// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
4071 /// ::= 'alloca' Type (',' 'inalloca')? (',' TypeAndValue)? (',' OptionalInfo)?
40724072 int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
40734073 Value *Size = 0;
40744074 LocTy SizeLoc;
40754075 unsigned Alignment = 0;
4076 bool IsInAlloca = false;
40764077 Type *Ty = 0;
40774078 if (ParseType(Ty)) return true;
40784079
40794080 bool AteExtraComma = false;
40804081 if (EatIfPresent(lltok::comma)) {
4081 if (Lex.getKind() == lltok::kw_align) {
4082 if (ParseOptionalAlignment(Alignment)) return true;
4083 } else if (Lex.getKind() == lltok::MetadataVar) {
4084 AteExtraComma = true;
4085 } else {
4086 if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
4087 ParseOptionalCommaAlign(Alignment, AteExtraComma))
4088 return true;
4082 bool HaveComma = true;
4083 if (EatIfPresent(lltok::kw_inalloca)) {
4084 IsInAlloca = true;
4085 HaveComma = EatIfPresent(lltok::comma);
4086 }
4087
4088 if (HaveComma) {
4089 if (Lex.getKind() == lltok::kw_align) {
4090 if (ParseOptionalAlignment(Alignment)) return true;
4091 } else if (Lex.getKind() == lltok::MetadataVar) {
4092 AteExtraComma = true;
4093 } else {
4094 if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
4095 ParseOptionalCommaAlign(Alignment, AteExtraComma))
4096 return true;
4097 }
40894098 }
40904099 }
40914100
40924101 if (Size && !Size->getType()->isIntegerTy())
40934102 return Error(SizeLoc, "element count must have integer type");
40944103
4095 Inst = new AllocaInst(Ty, Size, Alignment);
4104 AllocaInst *AI = new AllocaInst(Ty, Size, Alignment);
4105 AI->setUsedWithInAlloca(IsInAlloca);
4106 Inst = AI;
40964107 return AteExtraComma ? InstExtraComma : InstNormal;
40974108 }
40984109
210210 AtomicOrdering &Ordering);
211211 bool ParseOptionalStackAlignment(unsigned &Alignment);
212212 bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma);
213 bool ParseOptionalCommaInAlloca(bool &IsInAlloca);
213214 bool ParseIndexList(SmallVectorImpl &Indices,bool &AteExtraComma);
214215 bool ParseIndexList(SmallVectorImpl &Indices) {
215216 bool AteExtraComma;
8989 if (!getType()->isPointerTy()) return false;
9090 return getParent()->getAttributes().
9191 hasAttribute(getArgNo()+1, Attribute::InAlloca);
92 }
93
94 bool Argument::hasByValOrInAllocaAttr() const {
95 if (!getType()->isPointerTy()) return false;
96 AttributeSet Attrs = getParent()->getAttributes();
97 return Attrs.hasAttribute(getArgNo() + 1, Attribute::ByVal) ||
98 Attrs.hasAttribute(getArgNo() + 1, Attribute::InAlloca);
9299 }
93100
94101 unsigned Argument::getParamAlignment() const {
892892 assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
893893 assert(Align <= MaximumAlignment &&
894894 "Alignment is greater than MaximumAlignment!");
895 setInstructionSubclassData(Log2_32(Align) + 1);
895 setInstructionSubclassData((getSubclassDataFromInstruction() & ~31) |
896 (Log2_32(Align) + 1));
896897 assert(getAlignment() == Align && "Alignment representation error!");
897898 }
898899
915916
916917 // Must be in the entry block.
917918 const BasicBlock *Parent = getParent();
918 return Parent == &Parent->getParent()->front();
919 return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca();
919920 }
920921
921922 //===----------------------------------------------------------------------===//
0 ; RUN: llvm-as %s -o /dev/null
1
2 define void @a() {
3 entry:
4 %0 = alloca i32, inalloca
5 %1 = alloca [2 x i32], inalloca
6 %2 = alloca i32, inalloca, i32 2
7 %3 = alloca i32, inalloca, i32 2, align 16
8 %4 = alloca i32, inalloca, i32 2, align 16, !foo !0
9 %5 = alloca i32, i32 2, align 16, !foo !0
10 %6 = alloca i32, i32 2, align 16
11 ret void
12 }
13
14 !0 = metadata !{i32 662302, null}
15 !foo = !{ !0 }
11
22 declare void @h(i32, ...)
33 define void @i() {
4 %args = alloca i32
4 %args = alloca i32, inalloca
55 call void (i32, ...)* @h(i32 1, i32* inalloca %args, i32 3)
66 ; CHECK: inalloca isn't on the last argument!
77 ret void
55
66 define void @a() {
77 entry:
8 %a = alloca [2 x i32]
8 %a = alloca [2 x i32], inalloca
99 %b = bitcast [2 x i32]* %a to i64*
1010 call void @doit(i64* inalloca %b)
1111 ret void
1313
1414 define void @b() {
1515 entry:
16 %a = alloca i64
16 %a = alloca i64, inalloca
1717 call void @doit(i64* inalloca %a)
1818 call void @doit(i64* inalloca %a)
1919 ret void
2020 }
21
22 define void @c(i1 %cond) {
23 entry:
24 br i1 %cond, label %if, label %else
25
26 if:
27 %a = alloca i64, inalloca
28 br label %call
29
30 else:
31 %b = alloca i64, inalloca
32 br label %call
33
34 call:
35 %args = phi i64* [ %a, %if ], [ %b, %else ]
36 call void @doit(i64* inalloca %args)
37 ret void
38 }