diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-01-17 23:58:17 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-01-17 23:58:17 +0000 |
commit | 436c42ec3dc9f93ecce02ee9d47da6cf7be9aa7d (patch) | |
tree | 83823f837567e7c11b9997293ceb9b48af3b555d /llvm/lib | |
parent | 2b164bd98d2123b0e30a285a3295c839e76b06f2 (diff) | |
download | llvm-436c42ec3dc9f93ecce02ee9d47da6cf7be9aa7d.zip llvm-436c42ec3dc9f93ecce02ee9d47da6cf7be9aa7d.tar.gz llvm-436c42ec3dc9f93ecce02ee9d47da6cf7be9aa7d.tar.bz2 |
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
llvm-svn: 199525
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 1 | ||||
-rw-r--r-- | llvm/lib/IR/Function.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 5 |
4 files changed, 32 insertions, 12 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index a1b5f99..ab4b48b 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4069,31 +4069,42 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, //===----------------------------------------------------------------------===// /// ParseAlloc -/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)? +/// ::= 'alloca' Type (',' 'inalloca')? (',' TypeAndValue)? (',' OptionalInfo)? int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { Value *Size = 0; LocTy SizeLoc; unsigned Alignment = 0; + bool IsInAlloca = false; Type *Ty = 0; if (ParseType(Ty)) return true; bool AteExtraComma = false; if (EatIfPresent(lltok::comma)) { - if (Lex.getKind() == lltok::kw_align) { - if (ParseOptionalAlignment(Alignment)) return true; - } else if (Lex.getKind() == lltok::MetadataVar) { - AteExtraComma = true; - } else { - if (ParseTypeAndValue(Size, SizeLoc, PFS) || - ParseOptionalCommaAlign(Alignment, AteExtraComma)) - return true; + bool HaveComma = true; + if (EatIfPresent(lltok::kw_inalloca)) { + IsInAlloca = true; + HaveComma = EatIfPresent(lltok::comma); + } + + if (HaveComma) { + if (Lex.getKind() == lltok::kw_align) { + if (ParseOptionalAlignment(Alignment)) return true; + } else if (Lex.getKind() == lltok::MetadataVar) { + AteExtraComma = true; + } else { + if (ParseTypeAndValue(Size, SizeLoc, PFS) || + ParseOptionalCommaAlign(Alignment, AteExtraComma)) + return true; + } } } if (Size && !Size->getType()->isIntegerTy()) return Error(SizeLoc, "element count must have integer type"); - Inst = new AllocaInst(Ty, Size, Alignment); + AllocaInst *AI = new AllocaInst(Ty, Size, Alignment); + AI->setUsedWithInAlloca(IsInAlloca); + Inst = AI; return AteExtraComma ? InstExtraComma : InstNormal; } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index c62979e..d25374f 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -211,6 +211,7 @@ namespace llvm { AtomicOrdering &Ordering); bool ParseOptionalStackAlignment(unsigned &Alignment); bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma); + bool ParseOptionalCommaInAlloca(bool &IsInAlloca); bool ParseIndexList(SmallVectorImpl<unsigned> &Indices,bool &AteExtraComma); bool ParseIndexList(SmallVectorImpl<unsigned> &Indices) { bool AteExtraComma; diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index bb6bef7..c1fa372 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -92,6 +92,13 @@ bool Argument::hasInAllocaAttr() const { hasAttribute(getArgNo()+1, Attribute::InAlloca); } +bool Argument::hasByValOrInAllocaAttr() const { + if (!getType()->isPointerTy()) return false; + AttributeSet Attrs = getParent()->getAttributes(); + return Attrs.hasAttribute(getArgNo() + 1, Attribute::ByVal) || + Attrs.hasAttribute(getArgNo() + 1, Attribute::InAlloca); +} + unsigned Argument::getParamAlignment() const { assert(getType()->isPointerTy() && "Only pointers have alignments"); return getParent()->getParamAlignment(getArgNo()+1); diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 761f600..5a50b73 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -893,7 +893,8 @@ void AllocaInst::setAlignment(unsigned Align) { assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!"); assert(Align <= MaximumAlignment && "Alignment is greater than MaximumAlignment!"); - setInstructionSubclassData(Log2_32(Align) + 1); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~31) | + (Log2_32(Align) + 1)); assert(getAlignment() == Align && "Alignment representation error!"); } @@ -916,7 +917,7 @@ bool AllocaInst::isStaticAlloca() const { // Must be in the entry block. const BasicBlock *Parent = getParent(); - return Parent == &Parent->getParent()->front(); + return Parent == &Parent->getParent()->front() && !isUsedWithInAlloca(); } //===----------------------------------------------------------------------===// |