Revert "PR14569: Omit debug info for thunks"

This reverts commit r189320.

Alexey Samsonov and Dmitry Vyukov presented some arguments for keeping
these around - though it still seems like those tasks could be solved by
a tool just using the symbol table. In a very small number of cases,
thunks may be inlined & debug info might be able to save profilers &
similar tools from misclassifying those cases as part of the caller.

The extra changes here plumb through the VarDecl for various cases to
CodeGenFunction - this provides better fidelity through a few APIs but
generally just causes the CGF::StartFunction to fallback to using the
name of the IR function as the name in the debug info.

The changes to debug-info-global-ctor-dtor.cpp seem like goodness. The
two names that go missing (in favor of only emitting those names as
linkage names) are names that can be demangled - emitting them only as
the linkage name should encourage tools to do just that.

Again, thanks to Dinesh Dwivedi for investigation/work on this issue.

llvm-svn: 189421
This commit is contained in:
David Blaikie 2013-08-27 23:57:18 +00:00
parent 7ca1d30e49
commit ebe87e1cfa
9 changed files with 27 additions and 28 deletions

View File

@ -227,7 +227,7 @@ void CGCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
// The default behavior is to use atexit.
CGF.registerGlobalDtorWithAtExit(dtor, addr);
CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
}
/// Returns the adjustment, in bytes, required for the given

View File

@ -2450,7 +2450,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
llvm::DIArray TParamsArray;
if (!HasDecl) {
// Use llvm function name.
Name = Fn->getName();
LinkageName = Fn->getName();
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// If there is a DISubprogram for this function available then use it.
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator

View File

@ -100,9 +100,9 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
// Otherwise, the standard logic requires a helper function.
} else {
function = CodeGenFunction(CGM).generateDestroyHelper(addr, type,
CGF.getDestroyer(dtorKind),
CGF.needsEHCleanup(dtorKind));
function = CodeGenFunction(CGM)
.generateDestroyHelper(addr, type, CGF.getDestroyer(dtorKind),
CGF.needsEHCleanup(dtorKind), &D);
argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);
}
@ -161,7 +161,7 @@ CreateGlobalInitOrDestructFunction(CodeGenModule &CGM,
/// Create a stub function, suitable for being passed to atexit,
/// which passes the given address to the given destructor function.
static llvm::Constant *createAtExitStub(CodeGenModule &CGM,
static llvm::Constant *createAtExitStub(CodeGenModule &CGM, const VarDecl &VD,
llvm::Constant *dtor,
llvm::Constant *addr) {
// Get the destructor function type, void(*)(void).
@ -172,9 +172,9 @@ static llvm::Constant *createAtExitStub(CodeGenModule &CGM,
CodeGenFunction CGF(CGM);
CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, fn,
CGM.getTypes().arrangeNullaryFunction(),
FunctionArgList(), SourceLocation());
CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn,
CGM.getTypes().arrangeNullaryFunction(), FunctionArgList(),
SourceLocation());
llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
@ -189,10 +189,11 @@ static llvm::Constant *createAtExitStub(CodeGenModule &CGM,
}
/// Register a global destructor using the C atexit runtime function.
void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtor,
void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
llvm::Constant *dtor,
llvm::Constant *addr) {
// Create a function which calls the destructor.
llvm::Constant *dtorStub = createAtExitStub(CGM, dtor, addr);
llvm::Constant *dtorStub = createAtExitStub(CGM, VD, dtor, addr);
// extern "C" int atexit(void (*f)(void));
llvm::FunctionType *atexitTy =
@ -485,11 +486,9 @@ void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn,
/// generateDestroyHelper - Generates a helper function which, when
/// invoked, destroys the given object.
llvm::Function *
CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
QualType type,
Destroyer *destroyer,
bool useEHCleanupForArray) {
llvm::Function *CodeGenFunction::generateDestroyHelper(
llvm::Constant *addr, QualType type, Destroyer *destroyer,
bool useEHCleanupForArray, const VarDecl *VD) {
FunctionArgList args;
ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
args.push_back(&dst);
@ -502,8 +501,7 @@ CodeGenFunction::generateDestroyHelper(llvm::Constant *addr,
llvm::Function *fn =
CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
StartFunction(GlobalDecl(), getContext().VoidTy, fn, FI, args,
SourceLocation());
StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation());
emitDestroy(addr, type, destroyer, useEHCleanupForArray);

View File

@ -261,7 +261,8 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
if (E->getType()->isArrayType()) {
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
cast<llvm::Constant>(ReferenceTemporary), E->getType(),
CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions);
CodeGenFunction::destroyCXXObject, CGF.getLangOpts().Exceptions,
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
} else {
CleanupFn =

View File

@ -292,7 +292,6 @@ void CodeGenFunction::GenerateVarArgsThunk(
void CodeGenFunction::GenerateThunk(llvm::Function *Fn,
const CGFunctionInfo &FnInfo,
GlobalDecl GD, const ThunkInfo &Thunk) {
DebugInfo = NULL; // debug info for thunks is not required or desired
const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
QualType ThisType = MD->getThisType(getContext());

View File

@ -1021,10 +1021,10 @@ public:
bool useEHCleanupForArray);
void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer,
bool useEHCleanupForArray);
llvm::Function *generateDestroyHelper(llvm::Constant *addr,
QualType type,
llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type,
Destroyer *destroyer,
bool useEHCleanupForArray);
bool useEHCleanupForArray,
const VarDecl *VD);
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
QualType type, Destroyer *destroyer,
bool checkZeroLength, bool useEHCleanup);
@ -2305,7 +2305,8 @@ public:
/// Call atexit() with a function that passes the given argument to
/// the given function.
void registerGlobalDtorWithAtExit(llvm::Constant *fn, llvm::Constant *addr);
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn,
llvm::Constant *addr);
/// Emit code in this function to perform a guarded variable
/// initialization. Guarded initializations are used when it's not

View File

@ -1310,7 +1310,7 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
return CGM.AddCXXDtorEntry(dtor, addr);
}
CGF.registerGlobalDtorWithAtExit(dtor, addr);
CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
}
/// Get the appropriate linkage for the wrapper function. This is essentially

View File

@ -22,6 +22,6 @@ void foo() {
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_array_dtor]
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__dtor_]
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 16] [local] [def] [__dtor__ZZ3foovE4stat]
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__I_a]
// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}}
// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def] [_GLOBAL__D_a]
// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}}

View File

@ -14,4 +14,4 @@ struct C : A, B {
void C::f() { }
// CHECK-NOT: [ DW_TAG_subprogram ] [line 15] [def] [_ZThn{{4|8}}_N1C1fEv]
// CHECK: metadata !"_ZThn{{4|8}}_N1C1fEv", i32 15, {{.*}} ; [ DW_TAG_subprogram ] [line 15] [def]{{$}}