Newer
Older
//===-- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing dwarf debug info into asm files.
//
//===----------------------------------------------------------------------===//
#include "DwarfDebug.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/Timer.h"
#include "llvm/System/Path.h"
using namespace llvm;
static TimerGroup &getDwarfTimerGroup() {
static TimerGroup DwarfTimerGroup("Dwarf Debugging");
return DwarfTimerGroup;
}
//===----------------------------------------------------------------------===//
/// Configuration values for initial hash set sizes (log2).
///
static const unsigned InitDiesSetSize = 9; // log2(512)
static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
static const unsigned InitValuesSetSize = 9; // log2(512)
namespace llvm {
//===----------------------------------------------------------------------===//
/// CompileUnit - This dwarf writer support class manages information associate
/// with a source file.
class VISIBILITY_HIDDEN CompileUnit {
/// ID - File identifier for source.
///
unsigned ID;
/// Die - Compile unit debug information entry.
///
DIE *Die;
/// GVToDieMap - Tracks the mapping of unit level debug informaton
/// variables to debug information entries.
/// FIXME : Rename GVToDieMap -> NodeToDieMap
std::map<MDNode *, DIE *> GVToDieMap;
/// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
/// descriptors to debug information entries using a DIEEntry proxy.
/// FIXME : Rename
std::map<MDNode *, DIEEntry *> GVToDIEEntryMap;
/// Globals - A map of globally visible named entities for this unit.
///
StringMap<DIE*> Globals;
/// DiesSet - Used to uniquely define dies within the compile unit.
///
FoldingSet<DIE> DiesSet;
public:
CompileUnit(unsigned I, DIE *D)
: ID(I), Die(D), DiesSet(InitDiesSetSize) {}
~CompileUnit() { delete Die; }
// Accessors.
unsigned getID() const { return ID; }
DIE* getDie() const { return Die; }
StringMap<DIE*> &getGlobals() { return Globals; }
/// hasContent - Return true if this compile unit has something to write out.
///
bool hasContent() const { return !Die->getChildren().empty(); }
/// AddGlobal - Add a new global entity to the compile unit.
///
void AddGlobal(const std::string &Name, DIE *Die) { Globals[Name] = Die; }
/// getDieMapSlotFor - Returns the debug information entry map slot for the
/// specified debug variable.
DIE *&getDieMapSlotFor(MDNode *N) { return GVToDieMap[N]; }
/// getDIEEntrySlotFor - Returns the debug information entry proxy slot for
/// the specified debug variable.
DIEEntry *&getDIEEntrySlotFor(MDNode *N) {
return GVToDIEEntryMap[N];
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
}
/// AddDie - Adds or interns the DIE to the compile unit.
///
DIE *AddDie(DIE &Buffer) {
FoldingSetNodeID ID;
Buffer.Profile(ID);
void *Where;
DIE *Die = DiesSet.FindNodeOrInsertPos(ID, Where);
if (!Die) {
Die = new DIE(Buffer);
DiesSet.InsertNode(Die, Where);
this->Die->AddChild(Die);
Buffer.Detach();
}
return Die;
}
};
//===----------------------------------------------------------------------===//
/// DbgVariable - This class is used to track local variable information.
///
class VISIBILITY_HIDDEN DbgVariable {
DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index.
bool InlinedFnVar; // Variable for an inlined function.
DbgVariable(DIVariable V, unsigned I, bool IFV)
: Var(V), FrameIndex(I), InlinedFnVar(IFV) {}
// Accessors.
DIVariable getVariable() const { return Var; }
unsigned getFrameIndex() const { return FrameIndex; }
bool isInlinedFnVar() const { return InlinedFnVar; }
};
//===----------------------------------------------------------------------===//
/// DbgScope - This class is used to track scope information.
///
class DbgConcreteScope;
class VISIBILITY_HIDDEN DbgScope {
DbgScope *Parent; // Parent to this scope.
DIDescriptor Desc; // Debug info descriptor for scope.
// Either subprogram or block.
unsigned StartLabelID; // Label ID of the beginning of scope.
unsigned EndLabelID; // Label ID of the end of scope.
const MachineInstr *LastInsn; // Last instruction of this scope.
const MachineInstr *FirstInsn; // First instruction of this scope.
SmallVector<DbgScope *, 4> Scopes; // Scopes defined in scope.
SmallVector<DbgVariable *, 8> Variables;// Variables declared in scope.
SmallVector<DbgConcreteScope *, 8> ConcreteInsts;// Concrete insts of funcs.
// Private state for dump()
mutable unsigned IndentLevel;
public:
DbgScope(DbgScope *P, DIDescriptor D)
: Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), LastInsn(0),
FirstInsn(0), IndentLevel(0) {}
virtual ~DbgScope();
// Accessors.
DbgScope *getParent() const { return Parent; }
DIDescriptor getDesc() const { return Desc; }
unsigned getStartLabelID() const { return StartLabelID; }
unsigned getEndLabelID() const { return EndLabelID; }
SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
SmallVector<DbgConcreteScope*,8> &getConcreteInsts() { return ConcreteInsts; }
void setStartLabelID(unsigned S) { StartLabelID = S; }
void setEndLabelID(unsigned E) { EndLabelID = E; }
void setLastInsn(const MachineInstr *MI) { LastInsn = MI; }
const MachineInstr *getLastInsn() { return LastInsn; }
void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; }
const MachineInstr *getFirstInsn() { return FirstInsn; }
/// AddScope - Add a scope to the scope.
///
void AddScope(DbgScope *S) { Scopes.push_back(S); }
/// AddVariable - Add a variable to the scope.
///
void AddVariable(DbgVariable *V) { Variables.push_back(V); }
/// AddConcreteInst - Add a concrete instance to the scope.
///
void AddConcreteInst(DbgConcreteScope *C) { ConcreteInsts.push_back(C); }
Devang Patel
committed
void FixInstructionMarkers() {
assert (getFirstInsn() && "First instruction is missing!");
if (getLastInsn())
return;
// If a scope does not have an instruction to mark an end then use
// the end of last child scope.
SmallVector<DbgScope *, 4> &Scopes = getScopes();
assert (!Scopes.empty() && "Inner most scope does not have last insn!");
DbgScope *L = Scopes.back();
if (!L->getLastInsn())
Loading
Loading full blame...