diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 99 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 3 |
6 files changed, 11 insertions, 117 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 07eb91582af..ad303649867 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -109,9 +109,6 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) { D->getType()->getAs<FunctionType>()->getCallConv()) return true; - if (BaseD->hasAttr<AlwaysInlineAttr>()) - return true; - return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base), GlobalDecl(BaseD, Dtor_Base), false); @@ -164,7 +161,14 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl, // Instead of creating as alias to a linkonce_odr, replace all of the uses // of the aliasee. - if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) { + if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) && + (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage || + !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) { + // FIXME: An extern template instantiation will create functions with + // linkage "AvailableExternally". In libc++, some classes also define + // members with attribute "AlwaysInline" and expect no reference to + // be generated. It is desirable to reenable this optimisation after + // corresponding LLVM changes. Replacements[MangledName] = Aliasee; return false; } diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b0916ed3dcb..b11814f21e1 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1557,7 +1557,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) { // -fapple-kext must inline any call to this dtor into // the caller's body. if (getLangOpts().AppleKext) - CGM.AddAlwaysInlineFunction(CurFn); + CurFn->addFnAttr(llvm::Attribute::AlwaysInline); break; } diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index f85f66bd134..a9e7a9c5552 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2114,7 +2114,7 @@ emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc, ".omp_task_privates_map.", &CGM.getModule()); CGM.SetLLVMFunctionAttributes(/*D=*/nullptr, TaskPrivatesMapFnInfo, TaskPrivatesMap); - CGM.AddAlwaysInlineFunction(TaskPrivatesMap); + TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline); CodeGenFunction CGF(CGM); CGF.disableDebugInfo(); CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ef1dcec1f89..bbc01cba633 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -448,103 +448,6 @@ void CodeGenModule::Release() { EmitVersionIdentMetadata(); EmitTargetMetadata(); - - RewriteAlwaysInlineFunctions(); -} - -void CodeGenModule::AddAlwaysInlineFunction(llvm::Function *Fn) { - AlwaysInlineFunctions.push_back(Fn); -} - -/// Find all uses of GV that are not direct calls or invokes. -static void FindNonDirectCallUses(llvm::GlobalValue *GV, - llvm::SmallVectorImpl<llvm::Use *> *Uses) { - llvm::GlobalValue::use_iterator UI = GV->use_begin(), E = GV->use_end(); - for (; UI != E;) { - llvm::Use &U = *UI; - ++UI; - - llvm::CallSite CS(U.getUser()); - bool isDirectCall = (CS.isCall() || CS.isInvoke()) && CS.isCallee(&U); - if (!isDirectCall) - Uses->push_back(&U); - } -} - -/// Replace a list of uses. -static void ReplaceUsesWith(const llvm::SmallVectorImpl<llvm::Use *> &Uses, - llvm::GlobalValue *V, - llvm::GlobalValue *Replacement) { - for (llvm::Use *U : Uses) { - auto *C = dyn_cast<llvm::Constant>(U->getUser()); - if (C && !isa<llvm::GlobalValue>(C)) - C->handleOperandChange(V, Replacement, U); - else - U->set(Replacement); - } -} - -void CodeGenModule::RewriteAlwaysInlineFunction(llvm::Function *Fn) { - std::string Name = Fn->getName(); - std::string InlineName = Name + ".alwaysinline"; - Fn->setName(InlineName); - - llvm::SmallVector<llvm::Use *, 8> NonDirectCallUses; - Fn->removeDeadConstantUsers(); - FindNonDirectCallUses(Fn, &NonDirectCallUses); - // Do not create the wrapper if there are no non-direct call uses, and we are - // not required to emit an external definition. - if (NonDirectCallUses.empty() && Fn->isDiscardableIfUnused()) - return; - - llvm::FunctionType *FT = Fn->getFunctionType(); - llvm::LLVMContext &Ctx = getModule().getContext(); - llvm::Function *StubFn = - llvm::Function::Create(FT, Fn->getLinkage(), Name, &getModule()); - assert(StubFn->getName() == Name && "name was uniqued!"); - - // Insert the stub immediately after the original function. Helps with the - // fragile tests, among other things. - StubFn->removeFromParent(); - TheModule.getFunctionList().insertAfter(Fn, StubFn); - - StubFn->copyAttributesFrom(Fn); - StubFn->setPersonalityFn(nullptr); - - // AvailableExternally functions are replaced with a declaration. - // Everyone else gets a wrapper that musttail-calls the original function. - if (Fn->hasAvailableExternallyLinkage()) { - StubFn->setLinkage(llvm::GlobalValue::ExternalLinkage); - } else { - llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", StubFn); - std::vector<llvm::Value *> Args; - for (llvm::Function::arg_iterator ai = StubFn->arg_begin(); - ai != StubFn->arg_end(); ++ai) - Args.push_back(&*ai); - llvm::CallInst *CI = llvm::CallInst::Create(Fn, Args, "", BB); - CI->setCallingConv(Fn->getCallingConv()); - CI->setTailCallKind(llvm::CallInst::TCK_MustTail); - CI->setAttributes(Fn->getAttributes()); - if (FT->getReturnType()->isVoidTy()) - llvm::ReturnInst::Create(Ctx, BB); - else - llvm::ReturnInst::Create(Ctx, CI, BB); - } - - if (Fn->hasComdat()) - StubFn->setComdat(Fn->getComdat()); - - ReplaceUsesWith(NonDirectCallUses, Fn, StubFn); -} - -void CodeGenModule::RewriteAlwaysInlineFunctions() { - for (llvm::Function *Fn : AlwaysInlineFunctions) { - RewriteAlwaysInlineFunction(Fn); - Fn->setLinkage(llvm::GlobalValue::InternalLinkage); - Fn->addFnAttr(llvm::Attribute::AlwaysInline); - Fn->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass); - Fn->setVisibility(llvm::GlobalValue::DefaultVisibility); - } } void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { @@ -869,7 +772,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex, llvm::Attribute::NoInline)) { // (noinline wins over always_inline, and we can't specify both in IR) - AddAlwaysInlineFunction(F); + B.addAttribute(llvm::Attribute::AlwaysInline); } if (D->hasAttr<ColdAttr>()) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index e579f8bd5ec..754e3d1d29f 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -489,8 +489,6 @@ private: /// MDNodes. llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap; - llvm::SmallVector<llvm::Function*, 8> AlwaysInlineFunctions; - public: CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts, const PreprocessorOptions &ppopts, @@ -1133,8 +1131,6 @@ public: /// \breif Get the declaration of std::terminate for the platform. llvm::Constant *getTerminateFn(); - void AddAlwaysInlineFunction(llvm::Function *Fn); - private: llvm::Constant * GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D, @@ -1230,12 +1226,6 @@ private: /// Emits target specific Metadata for global declarations. void EmitTargetMetadata(); - /// Replaces alwaysinline functions with a pair of internal xxx.inlinefunction - /// for direct calls, and a stub for indirect calls, and rewrites all uses of - /// those. - void RewriteAlwaysInlineFunctions(); - void RewriteAlwaysInlineFunction(llvm::Function *Fn); - /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and /// .gcda files in a way that persists in .bc files. void EmitCoverageFile(); diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index fa714d7ddc7..0c6a6d751c7 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3311,9 +3311,6 @@ static StructorCodegen getCodegenToUse(CodeGenModule &CGM, if (MD->getParent()->getNumVBases()) return StructorCodegen::Emit; - if (MD->hasAttr<AlwaysInlineAttr>()) - return StructorCodegen::Emit; - GlobalDecl AliasDecl; if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) { AliasDecl = GlobalDecl(DD, Dtor_Complete); |