[llvm-commits] [llvm-gcc-4.2] r100049 - in /llvm-gcc-4.2/trunk/gcc: llvm-backend.cpp llvm-convert.cpp llvm-debug.cpp llvm-debug.h llvm-internal.h
Stuart Hastings
stuart at apple.com
Wed Mar 31 14:12:42 PDT 2010
Author: stuart
Date: Wed Mar 31 16:12:42 2010
New Revision: 100049
URL: http://llvm.org/viewvc/llvm-project?rev=100049&view=rev
Log:
Debug info can now properly represent functions inside classes inside other functions. Partial fix for Radar 7424645.
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
llvm-gcc-4.2/trunk/gcc/llvm-debug.h
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Mar 31 16:12:42 2010
@@ -512,6 +512,8 @@
if (!flag_pch_file &&
debug_info_level > DINFO_LEVEL_NONE)
TheDebugInfo = new DebugInfo(TheModule);
+ else
+ TheDebugInfo = 0;
}
/// performLateBackendInitialization - Set backend options that may only be
@@ -533,8 +535,6 @@
}
void llvm_lang_dependent_init(const char *Name) {
- if (TheDebugInfo)
- TheDebugInfo->Initialize();
if (Name)
TheModule->setModuleIdentifier(Name);
}
@@ -1010,7 +1010,7 @@
// Convert the AST to raw/ugly LLVM code.
Function *Fn;
{
- TreeToLLVM Emitter(fndecl);
+ TreeToLLVM *Emitter = getTreeToLLVM(fndecl);
enum symbol_visibility vis = DECL_VISIBILITY (fndecl);
if (vis != VISIBILITY_DEFAULT)
@@ -1018,7 +1018,7 @@
// visibility that's not supported by the target.
targetm.asm_out.visibility(fndecl, vis);
- Fn = Emitter.EmitFunction();
+ Fn = Emitter->EmitFunction();
}
#if 0
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Mar 31 16:12:42 2010
@@ -148,7 +148,6 @@
//===----------------------------------------------------------------------===//
/// TheTreeToLLVM - Keep track of the current function being compiled.
-static TreeToLLVM *TheTreeToLLVM = 0;
const TargetData &getTargetData() {
return *TheTarget->getTargetData();
@@ -163,7 +162,7 @@
}
TreeToLLVM::TreeToLLVM(tree fndecl) :
- TD(getTargetData()), Builder(Context, *TheFolder) {
+ TD(getTargetData()), Builder(Context, *TheFolder) {
FnDecl = fndecl;
Fn = 0;
ReturnBB = UnwindBB = 0;
@@ -179,6 +178,7 @@
TheDebugInfo->setLocationFile("<unknown file>");
TheDebugInfo->setLocationLine(0);
}
+ TheDebugInfo->Initialize();
}
AllocaInsertionPoint = 0;
@@ -188,13 +188,23 @@
FuncEHException = 0;
FuncEHSelector = 0;
FuncEHGetTypeID = 0;
+}
+
+
+TreeToLLVM::~TreeToLLVM() {}
- assert(TheTreeToLLVM == 0 && "Reentering function creation?");
- TheTreeToLLVM = this;
+TreeToLLVM *getTreeToLLVM(tree fndecl) {
+ // FIXME: should this static move into the TreeToLLVM class decl?
+ static std::map<tree_node *, TreeToLLVM * > FunctionMap;
+ TreeToLLVM *newTreeToLLVM = FunctionMap[fndecl];
+ if (!newTreeToLLVM)
+ newTreeToLLVM = FunctionMap[fndecl] = new TreeToLLVM(fndecl);
+ return newTreeToLLVM;
}
-TreeToLLVM::~TreeToLLVM() {
- TheTreeToLLVM = 0;
+TreeToLLVM *getCurrentTreeToLLVM(void) {
+ assert(current_function_decl && "no current_function_decl?");
+ return getTreeToLLVM(current_function_decl);
}
/// getLabelDeclBlock - Lazily get and create a basic block for the specified
@@ -308,7 +318,8 @@
assert(TREE_CODE(TREE_TYPE(ResultDecl)) == REFERENCE_TYPE &&
"Not type match and not passing by reference?");
// Create an alloca for the ResultDecl.
- Value *Tmp = TheTreeToLLVM->CreateTemporary(AI->getType());
+ TreeToLLVM *Emitter = getCurrentTreeToLLVM();
+ Value *Tmp = Emitter->CreateTemporary(AI->getType());
Builder.CreateStore(AI, Tmp);
SET_DECL_LLVM(ResultDecl, Tmp);
@@ -451,7 +462,7 @@
}
}
-void TreeToLLVM::StartFunctionBody() {
+Function *TreeToLLVM::StartFunctionBody() {
const char *Name = "";
// Get the name of the function.
if (tree ID = DECL_ASSEMBLER_NAME(FnDecl))
@@ -610,10 +621,10 @@
// Set the BLOCK_NUMBER()s to the depth of each lexical block.
setLexicalBlockDepths(FnDecl, block_declared_vars, 1);
- SeenBlocks.clear();
-
- if (EmitDebugInfo())
- TheDebugInfo->EmitFunctionStart(FnDecl, Fn, Builder.GetInsertBlock());
+ if (TheDebugInfo) {
+ TheDebugInfo->EmitFunctionStart(FnDecl);
+ Builder.GetInsertBlock();
+ }
// Loop over all of the arguments to the function, setting Argument names and
// creating argument alloca's for the PARM_DECLs in case their address is
@@ -628,7 +639,7 @@
ABIConverter.HandleReturnType(TREE_TYPE(TREE_TYPE(FnDecl)), FnDecl,
DECL_BUILT_IN(FnDecl));
// Remember this for use by FinishFunctionBody.
- TheTreeToLLVM->ReturnOffset = Client.Offset;
+ ReturnOffset = Client.Offset;
// Prepend the static chain (if any) to the list of arguments.
tree Args = static_chain ? static_chain : DECL_ARGUMENTS(FnDecl);
@@ -709,12 +720,7 @@
block_declared_vars.count(TREE_VALUE(t)) == 0)
EmitAutomaticVariableDecl(TREE_VALUE(t));
}
-
- // Push the outermost lexical block onto the RegionStack.
- switchLexicalBlock(DECL_INITIAL(FnDecl));
-
- // Create a new block for the return node, but don't insert it yet.
- ReturnBB = BasicBlock::Create(Context, "return");
+ return Fn;
}
Function *TreeToLLVM::FinishFunctionBody() {
@@ -802,9 +808,19 @@
}
Function *TreeToLLVM::EmitFunction() {
- // Set up parameters and prepare for return, for the function.
+ // Set up parameters for the function.
StartFunctionBody();
+ // We'll remember the lexical BLOCKs we've seen here.
+ SeenBlocks.clear();
+
+ // FIXME: Should these two statements move to StartFunctionBody() ?
+ // Push the outermost lexical block onto the RegionStack.
+ switchLexicalBlock(DECL_INITIAL(FnDecl));
+
+ // Create a new block for the return node, but don't insert it yet.
+ ReturnBB = BasicBlock::Create(Context, "return");
+
// Emit the body of the function iterating over all BBs
basic_block bb;
edge e;
@@ -2610,7 +2626,7 @@
if (!Loc) {
// A value. Store to a temporary, and return the temporary's address.
// Any future access to this argument will reuse the same address.
- Loc = TheTreeToLLVM->CreateTemporary(TheValue->getType());
+ Loc = getCurrentTreeToLLVM()->CreateTemporary(TheValue->getType());
Builder.CreateStore(TheValue, Loc);
}
return Loc;
@@ -2650,7 +2666,7 @@
assert(ConvertType(type) ==
cast<PointerType>(RetBuf.Ptr->getType())->getElementType() &&
"Inconsistent result types!");
- TheTreeToLLVM->EmitAggregateCopy(*DestLoc, RetBuf, type);
+ getCurrentTreeToLLVM()->EmitAggregateCopy(*DestLoc, RetBuf, type);
return 0;
} else {
// Read out the scalar return value now.
@@ -2693,7 +2709,7 @@
if (DestLoc == 0) {
// The result is unused, but still needs to be stored somewhere.
- Value *Buf = TheTreeToLLVM->CreateTemporary(PtrArgTy->getElementType());
+ Value *Buf = getCurrentTreeToLLVM()->CreateTemporary(PtrArgTy->getElementType());
CallOperands.push_back(Buf);
} else if (useReturnSlot) {
// Letting the call write directly to the final destination is safe and
@@ -2703,7 +2719,7 @@
// Letting the call write directly to the final destination may not be
// safe (eg: if DestLoc aliases a parameter) and is not required - pass
// a buffer and copy it to DestLoc after the call.
- RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+ RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
CallOperands.push_back(RetBuf.Ptr);
}
@@ -2724,7 +2740,7 @@
"Call returns a scalar but caller expects aggregate!");
// Create a buffer to hold the result. The result will be loaded out of
// it after the call.
- RetBuf = TheTreeToLLVM->CreateTempLoc(PtrArgTy->getElementType());
+ RetBuf = getCurrentTreeToLLVM()->CreateTempLoc(PtrArgTy->getElementType());
CallOperands.push_back(RetBuf.Ptr);
// Note the use of a shadow argument.
@@ -2748,7 +2764,7 @@
if (Loc->getType() != CalledTy) {
assert(type && "Inconsistent parameter types?");
bool isSigned = !TYPE_UNSIGNED(type);
- Loc = TheTreeToLLVM->CastToAnyType(Loc, isSigned, CalledTy, false);
+ Loc = getCurrentTreeToLLVM()->CastToAnyType(Loc, isSigned, CalledTy, false);
}
}
@@ -8451,18 +8467,18 @@
/// EmitLV_LABEL_DECL - Someone took the address of a label.
Constant *TreeConstantToLLVM::EmitLV_LABEL_DECL(tree exp) {
- assert(TheTreeToLLVM &&
+ assert(getCurrentTreeToLLVM() &&
"taking the address of a label while not compiling the function!");
// Figure out which function this is for, verify it's the one we're compiling.
if (DECL_CONTEXT(exp)) {
assert(TREE_CODE(DECL_CONTEXT(exp)) == FUNCTION_DECL &&
"Address of label in nested function?");
- assert(TheTreeToLLVM->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
+ assert(getCurrentTreeToLLVM()->getFUNCTION_DECL() == DECL_CONTEXT(exp) &&
"Taking the address of a label that isn't in the current fn!?");
}
- return TheTreeToLLVM->EmitLV_LABEL_DECL(exp);
+ return getCurrentTreeToLLVM()->EmitLV_LABEL_DECL(exp);
}
Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) {
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.cpp Wed Mar 31 16:12:42 2010
@@ -289,12 +289,10 @@
setCurrentLexicalBlock(desired);
}
-/// EmitFunctionStart - Constructs the debug code for entering a function -
-/// "llvm.dbg.func.start."
-void DebugInfo::EmitFunctionStart(tree FnDecl, Function *Fn,
- BasicBlock *CurBB) {
- setCurrentLexicalBlock(FnDecl);
+/// CreateSubprogramFromFnDecl - Constructs the debug code for
+/// entering a function - "llvm.dbg.func.start."
+DISubprogram DebugInfo::CreateSubprogramFromFnDecl(tree FnDecl) {
DIType FNType = getOrCreateType(TREE_TYPE(FnDecl));
std::map<tree_node *, WeakVH >::iterator I = SPCache.find(FnDecl);
@@ -302,12 +300,9 @@
DISubprogram SPDecl(cast<MDNode>(I->second));
DISubprogram SP =
DebugFactory.CreateSubprogramDefinition(SPDecl);
- SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
-
- // Push function on region stack.
- RegionStack.push_back(WeakVH(SP.getNode()));
- RegionMap[FnDecl] = WeakVH(SP.getNode());
- return;
+ if (SP.getNode() != SPDecl.getNode())
+ SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+ return SP;
}
bool ArtificialFnWithAbstractOrigin = false;
@@ -329,12 +324,13 @@
DISubprogram SPDecl(cast<MDNode>(I->second));
DISubprogram SP =
DebugFactory.CreateSubprogramDefinition(SPDecl);
- SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
+ if (SP.getNode() != SPDecl.getNode())
+ SPDecl.getNode()->replaceAllUsesWith(SP.getNode());
// Push function on region stack.
RegionStack.push_back(WeakVH(SP.getNode()));
RegionMap[FnDecl] = WeakVH(SP.getNode());
- return;
+ return SP;
}
// Gather location information.
@@ -356,23 +352,36 @@
}
StringRef FnName = getFunctionName(FnDecl);
-
+ // If the Function * hasn't been created yet, use a bogus value for
+ // the debug internal linkage bit.
+ bool hasInternalLinkage = true;
+ if (GET_DECL_LLVM_INDEX(FnDecl)) {
+ Function *Fn = cast<Function>DECL_LLVM(FnDecl);
+ hasInternalLinkage = Fn->hasInternalLinkage();
+ }
DISubprogram SP =
DebugFactory.CreateSubprogram(SPContext,
FnName, FnName,
LinkageName,
getOrCreateFile(Loc.file), lineno,
FNType,
- Fn->hasInternalLinkage(),
+ hasInternalLinkage,
true /*definition*/,
Virtuality, VIndex, ContainingType);
SPCache[FnDecl] = WeakVH(SP.getNode());
+ RegionMap[FnDecl] = WeakVH(SP.getNode());
+ return SP;
+}
+/// EmitFunctionStart - Constructs the debug code for entering a function -
+/// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+void DebugInfo::EmitFunctionStart(tree FnDecl) {
+ setCurrentLexicalBlock(FnDecl);
+ DISubprogram SP = CreateSubprogramFromFnDecl(FnDecl);
// Push function on region stack.
RegionStack.push_back(WeakVH(SP.getNode()));
- RegionMap[FnDecl] = WeakVH(SP.getNode());
}
/// getOrCreateNameSpace - Get name space descriptor for the tree node.
@@ -405,12 +414,20 @@
DIType Ty = getOrCreateType(Node);
return DIDescriptor(Ty.getNode());
} else if (DECL_P (Node)) {
- if (TREE_CODE (Node) == NAMESPACE_DECL) {
+ switch (TREE_CODE(Node)) {
+ default:
+ /// What kind of DECL is this?
+ return findRegion (DECL_CONTEXT (Node));
+ case NAMESPACE_DECL: {
DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node));
DINameSpace NS = getOrCreateNameSpace(Node, NSContext);
return DIDescriptor(NS.getNode());
}
- return findRegion (DECL_CONTEXT (Node));
+ case FUNCTION_DECL: {
+ DISubprogram SP = CreateSubprogramFromFnDecl(Node);
+ return SP;
+ }
+ }
} else if (TREE_CODE(Node) == BLOCK) {
// TREE_BLOCK is GCC's lexical block.
// Recursively create all necessary contexts:
@@ -631,7 +648,7 @@
sprintf(FwdTypeName, "fwd.type.%d", FwdTypeCount++);
llvm::DIType FwdType =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
- getOrCreateFile(main_input_filename),
+ findRegion(TYPE_CONTEXT(type)),
FwdTypeName,
getOrCreateFile(main_input_filename),
0, 0, 0, 0, 0,
@@ -717,9 +734,10 @@
return Ty;
}
+ tree type_with_context = TYPE_CONTEXT(type) ? type : TREE_TYPE(type);
StringRef PName = FromTy.getName();
DIType PTy =
- DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)),
+ DebugFactory.CreateDerivedType(Tag, findRegion(type_with_context),
Tag == DW_TAG_pointer_type ?
StringRef() : PName,
getOrCreateFile(main_input_filename),
Modified: llvm-gcc-4.2/trunk/gcc/llvm-debug.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-debug.h?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-debug.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-debug.h Wed Mar 31 16:12:42 2010
@@ -118,9 +118,13 @@
// by GCC's cfglayout.c:change_scope().
void change_regions(tree_node *desired, tree_node *grand);
- /// EmitFunctionStart - Constructs the debug code for entering a function -
+ /// CreateSubprogramFromFnDecl - Constructs the debug code for entering a function -
/// "llvm.dbg.func.start."
- void EmitFunctionStart(tree_node *FnDecl, Function *Fn, BasicBlock *CurBB);
+ DISubprogram CreateSubprogramFromFnDecl(tree_node *FnDecl);
+
+ /// EmitFunctionStart - Constructs the debug code for entering a function -
+ /// "llvm.dbg.func.start", and pushes it onto the RegionStack.
+ void EmitFunctionStart(tree_node *FnDecl);
/// EmitFunctionEnd - Constructs the debug code for exiting a declarative
/// region - "llvm.dbg.region.end."
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=100049&r1=100048&r2=100049&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Wed Mar 31 16:12:42 2010
@@ -75,7 +75,7 @@
extern llvm::Module *TheModule;
/// TheDebugInfo - This object is responsible for gather all debug information.
-/// If it's value is NULL then no debug information should be gathered.
+/// If its value is NULL then no debug information should be gathered.
extern llvm::DebugInfo *TheDebugInfo;
/// TheTarget - The current target being compiled for.
@@ -281,6 +281,7 @@
BasicBlock *ReturnBB;
BasicBlock *UnwindBB;
unsigned ReturnOffset;
+
// Lexical BLOCKS that we have previously seen and processed.
treeset SeenBlocks;
@@ -397,6 +398,10 @@
// allocation would change with -g, and users dislike that.
void switchLexicalBlock(tree_node *exp);
+ /// StartFunctionBody - Start the emission of 'FnDecl', outputing all
+ /// declarations for parameters and setting things up.
+ Function *StartFunctionBody();
+
private: // Helper functions.
// Walk over the lexical BLOCK() tree of the given FUNCTION_DECL;
@@ -405,10 +410,6 @@
// the given set.
void setLexicalBlockDepths(tree_node *t, treeset &s, unsigned level);
- /// StartFunctionBody - Start the emission of 'fndecl', outputing all
- /// declarations for parameters and setting things up.
- void StartFunctionBody();
-
/// FinishFunctionBody - Once the body of the function has been emitted, this
/// cleans up and returns the result function.
Function *FinishFunctionBody();
@@ -608,6 +609,9 @@
Constant *EmitLV_LABEL_DECL(tree_node *exp);
};
+/// Locate a previously exiting TreeToLLVM. Construct one if necessary.
+TreeToLLVM *getTreeToLLVM(tree_node *fndecl);
+
/// TreeConstantToLLVM - An instance of this class is created and used to
/// convert tree constant values to LLVM. This is primarily for things like
/// global variable initializers.
More information about the llvm-commits
mailing list