forked from OSchip/llvm-project
CodeGen: Refactor SetLLVMFunctionAttributesForDefinition to use an AttrBuilder.
Adding attributes to a uniqued set has become expensive, don't do it more often than necessary. No functionality change. llvm-svn: 181662
This commit is contained in:
parent
470b077bca
commit
2960dbddbb
|
@ -598,61 +598,65 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) {
|
||||||
|
|
||||||
void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
|
||||||
llvm::Function *F) {
|
llvm::Function *F) {
|
||||||
|
llvm::AttrBuilder B;
|
||||||
|
|
||||||
if (CodeGenOpts.UnwindTables)
|
if (CodeGenOpts.UnwindTables)
|
||||||
F->setHasUWTable();
|
B.addAttribute(llvm::Attribute::UWTable);
|
||||||
|
|
||||||
if (!hasUnwindExceptions(LangOpts))
|
if (!hasUnwindExceptions(LangOpts))
|
||||||
F->addFnAttr(llvm::Attribute::NoUnwind);
|
B.addAttribute(llvm::Attribute::NoUnwind);
|
||||||
|
|
||||||
if (D->hasAttr<NakedAttr>()) {
|
if (D->hasAttr<NakedAttr>()) {
|
||||||
// Naked implies noinline: we should not be inlining such functions.
|
// Naked implies noinline: we should not be inlining such functions.
|
||||||
F->addFnAttr(llvm::Attribute::Naked);
|
B.addAttribute(llvm::Attribute::Naked);
|
||||||
F->addFnAttr(llvm::Attribute::NoInline);
|
B.addAttribute(llvm::Attribute::NoInline);
|
||||||
}
|
} else if (D->hasAttr<NoInlineAttr>()) {
|
||||||
|
B.addAttribute(llvm::Attribute::NoInline);
|
||||||
if (D->hasAttr<NoInlineAttr>())
|
} else if ((D->hasAttr<AlwaysInlineAttr>() ||
|
||||||
F->addFnAttr(llvm::Attribute::NoInline);
|
D->hasAttr<ForceInlineAttr>()) &&
|
||||||
|
|
||||||
// (noinline wins over always_inline, and we can't specify both in IR)
|
|
||||||
if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) &&
|
|
||||||
!F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex,
|
!F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex,
|
||||||
llvm::Attribute::NoInline))
|
llvm::Attribute::NoInline)) {
|
||||||
F->addFnAttr(llvm::Attribute::AlwaysInline);
|
// (noinline wins over always_inline, and we can't specify both in IR)
|
||||||
|
B.addAttribute(llvm::Attribute::AlwaysInline);
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Communicate hot and cold attributes to LLVM more directly.
|
// FIXME: Communicate hot and cold attributes to LLVM more directly.
|
||||||
if (D->hasAttr<ColdAttr>())
|
if (D->hasAttr<ColdAttr>())
|
||||||
F->addFnAttr(llvm::Attribute::OptimizeForSize);
|
B.addAttribute(llvm::Attribute::OptimizeForSize);
|
||||||
|
|
||||||
if (D->hasAttr<MinSizeAttr>())
|
if (D->hasAttr<MinSizeAttr>())
|
||||||
F->addFnAttr(llvm::Attribute::MinSize);
|
B.addAttribute(llvm::Attribute::MinSize);
|
||||||
|
|
||||||
if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
|
|
||||||
F->setUnnamedAddr(true);
|
|
||||||
|
|
||||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
|
|
||||||
if (MD->isVirtual())
|
|
||||||
F->setUnnamedAddr(true);
|
|
||||||
|
|
||||||
if (LangOpts.getStackProtector() == LangOptions::SSPOn)
|
if (LangOpts.getStackProtector() == LangOptions::SSPOn)
|
||||||
F->addFnAttr(llvm::Attribute::StackProtect);
|
B.addAttribute(llvm::Attribute::StackProtect);
|
||||||
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
|
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
|
||||||
F->addFnAttr(llvm::Attribute::StackProtectReq);
|
B.addAttribute(llvm::Attribute::StackProtectReq);
|
||||||
|
|
||||||
// Add sanitizer attributes if function is not blacklisted.
|
// Add sanitizer attributes if function is not blacklisted.
|
||||||
if (!SanitizerBlacklist.isIn(*F)) {
|
if (!SanitizerBlacklist.isIn(*F)) {
|
||||||
// When AddressSanitizer is enabled, set SanitizeAddress attribute
|
// When AddressSanitizer is enabled, set SanitizeAddress attribute
|
||||||
// unless __attribute__((no_sanitize_address)) is used.
|
// unless __attribute__((no_sanitize_address)) is used.
|
||||||
if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>())
|
if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>())
|
||||||
F->addFnAttr(llvm::Attribute::SanitizeAddress);
|
B.addAttribute(llvm::Attribute::SanitizeAddress);
|
||||||
// Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
|
// Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
|
||||||
if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
|
if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
|
||||||
F->addFnAttr(llvm::Attribute::SanitizeThread);
|
B.addAttribute(llvm::Attribute::SanitizeThread);
|
||||||
}
|
}
|
||||||
// Same for MemorySanitizer and __attribute__((no_sanitize_memory))
|
// Same for MemorySanitizer and __attribute__((no_sanitize_memory))
|
||||||
if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
|
if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
|
||||||
F->addFnAttr(llvm::Attribute::SanitizeMemory);
|
B.addAttribute(llvm::Attribute::SanitizeMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
F->addAttributes(llvm::AttributeSet::FunctionIndex,
|
||||||
|
llvm::AttributeSet::get(
|
||||||
|
F->getContext(), llvm::AttributeSet::FunctionIndex, B));
|
||||||
|
|
||||||
|
if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
|
||||||
|
F->setUnnamedAddr(true);
|
||||||
|
else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
|
||||||
|
if (MD->isVirtual())
|
||||||
|
F->setUnnamedAddr(true);
|
||||||
|
|
||||||
unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
|
unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
|
||||||
if (alignment)
|
if (alignment)
|
||||||
F->setAlignment(alignment);
|
F->setAlignment(alignment);
|
||||||
|
|
Loading…
Reference in New Issue