r196753 - Avoid adding some decls to DeferredDeclsToEmit.
Rafael Espindola
rafael.espindola at gmail.com
Sun Dec 8 20:29:47 PST 2013
Author: rafael
Date: Sun Dec 8 22:29:47 2013
New Revision: 196753
URL: http://llvm.org/viewvc/llvm-project?rev=196753&view=rev
Log:
Avoid adding some decls to DeferredDeclsToEmit.
Before this patch GetOrCreateLLVMFunction would add a decl to
DeferredDeclsToEmit even when it was being called by the function trying to
emit that decl.
Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=196753&r1=196752&r2=196753&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sun Dec 8 22:29:47 2013
@@ -205,8 +205,8 @@ void CodeGenModule::EmitCXXConstructor(c
const CGFunctionInfo &fnInfo =
getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);
- llvm::Function *fn =
- cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo));
+ llvm::Function *fn = cast<llvm::Function>(
+ GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo, true));
setFunctionLinkage(GlobalDecl(ctor, ctorType), fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo);
@@ -218,7 +218,8 @@ void CodeGenModule::EmitCXXConstructor(c
llvm::GlobalValue *
CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
CXXCtorType ctorType,
- const CGFunctionInfo *fnInfo) {
+ const CGFunctionInfo *fnInfo,
+ bool DontDefer) {
GlobalDecl GD(ctor, ctorType);
StringRef name = getMangledName(GD);
@@ -230,7 +231,8 @@ CodeGenModule::GetAddrOfCXXConstructor(c
llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo);
return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
- /*ForVTable=*/false));
+ /*ForVTable=*/false,
+ DontDefer));
}
void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
@@ -260,8 +262,8 @@ void CodeGenModule::EmitCXXDestructor(co
const CGFunctionInfo &fnInfo =
getTypes().arrangeCXXDestructor(dtor, dtorType);
- llvm::Function *fn =
- cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo));
+ llvm::Function *fn = cast<llvm::Function>(
+ GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo, 0, true));
setFunctionLinkage(GlobalDecl(dtor, dtorType), fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo);
@@ -274,7 +276,8 @@ llvm::GlobalValue *
CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
const CGFunctionInfo *fnInfo,
- llvm::FunctionType *fnType) {
+ llvm::FunctionType *fnType,
+ bool DontDefer) {
GlobalDecl GD(dtor, dtorType);
StringRef name = getMangledName(GD);
@@ -286,7 +289,8 @@ CodeGenModule::GetAddrOfCXXDestructor(co
fnType = getTypes().GetFunctionType(*fnInfo);
}
return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
- /*ForVTable=*/false));
+ /*ForVTable=*/false,
+ DontDefer));
}
static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=196753&r1=196752&r2=196753&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Sun Dec 8 22:29:47 2013
@@ -54,7 +54,8 @@ llvm::Constant *CodeGenModule::GetAddrOf
Out.flush();
llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD);
- return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true);
+ return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true,
+ /*DontDefer*/ true);
}
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=196753&r1=196752&r2=196753&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Dec 8 22:29:47 2013
@@ -1374,6 +1374,7 @@ llvm::Constant *
CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
llvm::Type *Ty,
GlobalDecl GD, bool ForVTable,
+ bool DontDefer,
llvm::AttributeSet ExtraAttrs) {
const Decl *D = GD.getDecl();
@@ -1393,14 +1394,6 @@ CodeGenModule::GetOrCreateLLVMFunction(S
return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo());
}
- // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
- // each other bottoming out with the base dtor. Therefore we emit non-base
- // dtors on usage, even if there is no dtor definition in the TU.
- if (D && isa<CXXDestructorDecl>(D) &&
- getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
- GD.getDtorType()))
- DeferredDeclsToEmit.push_back(GD);
-
// This function doesn't have a complete type (for example, the return
// type is an incomplete struct). Use a fake type instead, and make
// sure not to try to set attributes.
@@ -1428,50 +1421,64 @@ CodeGenModule::GetOrCreateLLVMFunction(S
B));
}
- // This is the first use or definition of a mangled name. If there is a
- // deferred decl with this name, remember that we need to emit it at the end
- // of the file.
- llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
- if (DDI != DeferredDecls.end()) {
- // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
- // list, and remove it from DeferredDecls (since we don't need it anymore).
- DeferredDeclsToEmit.push_back(DDI->second);
- DeferredDecls.erase(DDI);
-
- // Otherwise, if this is a sized deallocation function, emit a weak definition
- // for it at the end of the translation unit.
- } else if (D && cast<FunctionDecl>(D)
- ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
- DeferredDeclsToEmit.push_back(GD);
-
- // Otherwise, there are cases we have to worry about where we're
- // using a declaration for which we must emit a definition but where
- // we might not find a top-level definition:
- // - member functions defined inline in their classes
- // - friend functions defined inline in some class
- // - special member functions with implicit definitions
- // If we ever change our AST traversal to walk into class methods,
- // this will be unnecessary.
- //
- // We also don't emit a definition for a function if it's going to be an entry
- // in a vtable, unless it's already marked as used.
- } else if (getLangOpts().CPlusPlus && D) {
- // Look for a declaration that's lexically in a record.
- const FunctionDecl *FD = cast<FunctionDecl>(D);
- FD = FD->getMostRecentDecl();
- do {
- if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
- if (FD->isImplicit() && !ForVTable) {
- assert(FD->isUsed() && "Sema didn't mark implicit function as used!");
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
- break;
- } else if (FD->doesThisDeclarationHaveABody()) {
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
- break;
+ if (!DontDefer) {
+ // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
+ // each other bottoming out with the base dtor. Therefore we emit non-base
+ // dtors on usage, even if there is no dtor definition in the TU.
+ if (D && isa<CXXDestructorDecl>(D) &&
+ getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
+ GD.getDtorType()))
+ DeferredDeclsToEmit.push_back(GD);
+
+ // This is the first use or definition of a mangled name. If there is a
+ // deferred decl with this name, remember that we need to emit it at the end
+ // of the file.
+ llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+ if (DDI != DeferredDecls.end()) {
+ // Move the potentially referenced deferred decl to the
+ // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
+ // don't need it anymore).
+ DeferredDeclsToEmit.push_back(DDI->second);
+ DeferredDecls.erase(DDI);
+
+ // Otherwise, if this is a sized deallocation function, emit a weak
+ // definition
+ // for it at the end of the translation unit.
+ } else if (D && cast<FunctionDecl>(D)
+ ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
+ DeferredDeclsToEmit.push_back(GD);
+
+ // Otherwise, there are cases we have to worry about where we're
+ // using a declaration for which we must emit a definition but where
+ // we might not find a top-level definition:
+ // - member functions defined inline in their classes
+ // - friend functions defined inline in some class
+ // - special member functions with implicit definitions
+ // If we ever change our AST traversal to walk into class methods,
+ // this will be unnecessary.
+ //
+ // We also don't emit a definition for a function if it's going to be an
+ // entry
+ // in a vtable, unless it's already marked as used.
+ } else if (getLangOpts().CPlusPlus && D) {
+ // Look for a declaration that's lexically in a record.
+ const FunctionDecl *FD = cast<FunctionDecl>(D);
+ FD = FD->getMostRecentDecl();
+ do {
+ if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
+ if (FD->isImplicit() && !ForVTable) {
+ assert(FD->isUsed() &&
+ "Sema didn't mark implicit function as used!");
+ DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ break;
+ } else if (FD->doesThisDeclarationHaveABody()) {
+ DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ break;
+ }
}
- }
- FD = FD->getPreviousDecl();
- } while (FD);
+ FD = FD->getPreviousDecl();
+ } while (FD);
+ }
}
// Make sure the result is of the requested type.
@@ -1489,13 +1496,14 @@ CodeGenModule::GetOrCreateLLVMFunction(S
/// create it (this occurs when we see a definition of the function).
llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
llvm::Type *Ty,
- bool ForVTable) {
+ bool ForVTable,
+ bool DontDefer) {
// If there was no specific requested type, just convert it now.
if (!Ty)
Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
StringRef MangledName = getMangledName(GD);
- return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable);
+ return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer);
}
/// CreateRuntimeFunction - Create a new runtime function with the specified
@@ -1504,9 +1512,9 @@ llvm::Constant *
CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy,
StringRef Name,
llvm::AttributeSet ExtraAttrs) {
- llvm::Constant *C
- = GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
- ExtraAttrs);
+ llvm::Constant *C =
+ GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
+ /*DontDefer=*/false, ExtraAttrs);
if (llvm::Function *F = dyn_cast<llvm::Function>(C))
if (F->empty())
F->setCallingConv(getRuntimeCC());
@@ -2090,7 +2098,8 @@ void CodeGenModule::EmitGlobalFunctionDe
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
// Get or create the prototype for the function.
- llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
+ llvm::Constant *Entry =
+ GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/ true);
// Strip off a bitcast if we got one back.
if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=196753&r1=196752&r2=196753&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sun Dec 8 22:29:47 2013
@@ -639,9 +639,9 @@ public:
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it.
- llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
- llvm::Type *Ty = 0,
- bool ForVTable = false);
+ llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = 0,
+ bool ForVTable = false,
+ bool DontDefer = false);
/// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor
/// for the given type.
@@ -769,14 +769,16 @@ public:
/// given type.
llvm::GlobalValue *GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
CXXCtorType ctorType,
- const CGFunctionInfo *fnInfo = 0);
+ const CGFunctionInfo *fnInfo = 0,
+ bool DontDefer = false);
/// GetAddrOfCXXDestructor - Return the address of the constructor of the
/// given type.
llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
const CGFunctionInfo *fnInfo = 0,
- llvm::FunctionType *fnType = 0);
+ llvm::FunctionType *fnType = 0,
+ bool DontDefer = false);
/// getBuiltinLibFunction - Given a builtin id for a function like
/// "__builtin_fabsf", return a Function* for "fabsf".
@@ -1009,12 +1011,11 @@ public:
private:
llvm::GlobalValue *GetGlobalValue(StringRef Ref);
- llvm::Constant *GetOrCreateLLVMFunction(StringRef MangledName,
- llvm::Type *Ty,
- GlobalDecl D,
- bool ForVTable,
- llvm::AttributeSet ExtraAttrs =
- llvm::AttributeSet());
+ llvm::Constant *
+ GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
+ bool ForVTable, bool DontDefer = false,
+ llvm::AttributeSet ExtraAttrs = llvm::AttributeSet());
+
llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName,
llvm::PointerType *PTy,
const VarDecl *D,
More information about the cfe-commits
mailing list