diff options
author | Igor Laevsky <igmyrj@gmail.com> | 2015-07-11 10:30:36 +0000 |
---|---|---|
committer | Igor Laevsky <igmyrj@gmail.com> | 2015-07-11 10:30:36 +0000 |
commit | 39d662f7ba0aa80799a2c6ea2ca84b0c0727db66 (patch) | |
tree | 1486500f54fd10e5c5b7b147dffcaf5a7c6b9bac /llvm/lib | |
parent | 15f5d9731123d31af0baf935fbcc07a001d11ebd (diff) | |
download | bcm5719-llvm-39d662f7ba0aa80799a2c6ea2ca84b0c0727db66.tar.gz bcm5719-llvm-39d662f7ba0aa80799a2c6ea2ca84b0c0727db66.zip |
Add argmemonly attribute.
This change adds new attribute called "argmemonly". Function marked with this attribute can only access memory through it's argument pointers. This attribute directly corresponds to the "OnlyAccessesArgumentPointees" ModRef behaviour in alias analysis.
Differential Revision: http://reviews.llvm.org/D10398
llvm-svn: 241979
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/BasicAliasAnalysis.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 67 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 8 |
8 files changed, 62 insertions, 33 deletions
diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 8e812252fdf..68f766edb30 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -685,6 +685,9 @@ BasicAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) { if (CS.onlyReadsMemory()) Min = OnlyReadsMemory; + if (CS.onlyAccessesArgMemory()) + Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees); + // The AliasAnalysis base class has some smarts, lets use them. return ModRefBehavior(AliasAnalysis::getModRefBehavior(CS) & Min); } @@ -710,6 +713,9 @@ BasicAliasAnalysis::getModRefBehavior(const Function *F) { if (F->onlyReadsMemory()) Min = OnlyReadsMemory; + if (F->onlyAccessesArgMemory()) + Min = ModRefBehavior(Min & OnlyAccessesArgumentPointees); + const TargetLibraryInfo &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); if (isMemsetPattern16(F, TLI)) diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 88f359d4fd5..5c4bab734b2 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -593,6 +593,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(attributes); KEYWORD(alwaysinline); + KEYWORD(argmemonly); KEYWORD(builtin); KEYWORD(byval); KEYWORD(inalloca); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index aa96d60ca0d..1c6e7bd18d0 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -946,35 +946,42 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, B.addStackAlignmentAttr(Alignment); continue; } - case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; - case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break; - case lltok::kw_cold: B.addAttribute(Attribute::Cold); break; - case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break; - case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; - case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break; - case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; - case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; - case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; - case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; - case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break; - case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; - case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; - case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; - case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; - case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; - case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; - case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; - case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; - case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; - case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break; - case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; - case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; - case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; - case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break; - case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; - case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; - case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break; - case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; + case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; + case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break; + case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break; + case lltok::kw_cold: B.addAttribute(Attribute::Cold); break; + case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break; + case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break; + case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; + case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; + case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; + case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; + case lltok::kw_noimplicitfloat: + B.addAttribute(Attribute::NoImplicitFloat); break; + case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; + case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; + case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; + case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; + case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returns_twice: + B.addAttribute(Attribute::ReturnsTwice); break; + case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; + case lltok::kw_sspstrong: + B.addAttribute(Attribute::StackProtectStrong); break; + case lltok::kw_safestack: B.addAttribute(Attribute::SafeStack); break; + case lltok::kw_sanitize_address: + B.addAttribute(Attribute::SanitizeAddress); break; + case lltok::kw_sanitize_thread: + B.addAttribute(Attribute::SanitizeThread); break; + case lltok::kw_sanitize_memory: + B.addAttribute(Attribute::SanitizeMemory); break; + case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; // Error handling. case lltok::kw_inreg: @@ -1258,6 +1265,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_alignstack: case lltok::kw_alwaysinline: + case lltok::kw_argmemonly: case lltok::kw_builtin: case lltok::kw_inlinehint: case lltok::kw_jumptable: @@ -1334,6 +1342,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_alignstack: case lltok::kw_alwaysinline: + case lltok::kw_argmemonly: case lltok::kw_builtin: case lltok::kw_cold: case lltok::kw_inlinehint: diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 2487d120813..691f085f0c9 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -100,6 +100,7 @@ namespace lltok { // Attributes: kw_attributes, kw_alwaysinline, + kw_argmemonly, kw_sanitize_address, kw_builtin, kw_byval, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 4695078303a..c04e8b9f1f3 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1090,6 +1090,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::Alignment; case bitc::ATTR_KIND_ALWAYS_INLINE: return Attribute::AlwaysInline; + case bitc::ATTR_KIND_ARGMEMONLY: + return Attribute::ArgMemOnly; case bitc::ATTR_KIND_BUILTIN: return Attribute::Builtin; case bitc::ATTR_KIND_BY_VAL: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 8a3ed18ffeb..1a70ba5ac12 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -162,6 +162,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_ALIGNMENT; case Attribute::AlwaysInline: return bitc::ATTR_KIND_ALWAYS_INLINE; + case Attribute::ArgMemOnly: + return bitc::ATTR_KIND_ARGMEMONLY; case Attribute::Builtin: return bitc::ATTR_KIND_BUILTIN; case Attribute::ByVal: diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index c3032f4ffc7..546a98670a2 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -190,6 +190,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "sanitize_address"; if (hasAttribute(Attribute::AlwaysInline)) return "alwaysinline"; + if (hasAttribute(Attribute::ArgMemOnly)) + return "argmemonly"; if (hasAttribute(Attribute::Builtin)) return "builtin"; if (hasAttribute(Attribute::ByVal)) @@ -447,6 +449,9 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { llvm_unreachable("dereferenceable_or_null attribute not supported in raw " "format"); break; + case Attribute::ArgMemOnly: + llvm_unreachable("argmemonly attribute not supported in raw format"); + break; } llvm_unreachable("Unsupported attribute type"); } @@ -1356,7 +1361,8 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; I = Attribute::AttrKind(I + 1)) { if (I == Attribute::Dereferenceable || - I == Attribute::DereferenceableOrNull) + I == Attribute::DereferenceableOrNull || + I == Attribute::ArgMemOnly) continue; if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { Attrs[I] = true; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 647920f23da..2a0a4ff393e 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1273,7 +1273,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, I->getKindAsEnum() == Attribute::Cold || I->getKindAsEnum() == Attribute::OptimizeNone || I->getKindAsEnum() == Attribute::JumpTable || - I->getKindAsEnum() == Attribute::Convergent) { + I->getKindAsEnum() == Attribute::Convergent || + I->getKindAsEnum() == Attribute::ArgMemOnly) { if (!isFunction) { CheckFailed("Attribute '" + I->getAsString() + "' only applies to functions!", V); @@ -1531,8 +1532,9 @@ void Verifier::VerifyStatepoint(ImmutableCallSite CS) { const Instruction &CI = *CS.getInstruction(); - Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory(), - "gc.statepoint must read and write memory to preserve " + Assert(!CS.doesNotAccessMemory() && !CS.onlyReadsMemory() && + !CS.onlyAccessesArgMemory(), + "gc.statepoint must read and write all memory to preserve " "reordering restrictions required by safepoint semantics", &CI); |