The subprogram descriptor for a function may be missing (llvm-ld linking two static functions with same name), so pick up the compilation unit for the function from the first valid debug loc of its instructions.

This patch also emits debug info for structure (aggregate types in 
general) types.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73295 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sanjiv Gupta 2009-06-13 17:35:54 +00:00
parent 4d8414f420
commit dcb6da3efd
3 changed files with 134 additions and 78 deletions

View File

@ -48,8 +48,21 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
const Function *F = MF.getFunction(); const Function *F = MF.getFunction();
CurrentFnName = Mang->getValueName(F); CurrentFnName = Mang->getValueName(F);
// Emit .file directive. // Iterate over the first basic block instructions to find if it has a
DbgInfo.EmitFileDirective(F); // DebugLoc. If so emit .file directive. Instructions such as movlw do not
// have valid DebugLoc, so need to iterate over instructions.
MachineFunction::const_iterator I = MF.begin();
for (MachineBasicBlock::const_iterator MBBI = I->begin(), E = I->end();
MBBI != E; MBBI++) {
const DebugLoc DLoc = MBBI->getDebugLoc();
if (!DLoc.isUnknown()) {
GlobalVariable *CU = MF.getDebugLocTuple(DLoc).CompileUnit;
unsigned line = MF.getDebugLocTuple(DLoc).Line;
DbgInfo.EmitFileDirective(CU);
DbgInfo.SetFunctBeginLine(line);
break;
}
}
// Emit the function frame (args and temps). // Emit the function frame (args and temps).
EmitFunctionFrame(MF); EmitFunctionFrame(MF);
@ -213,14 +226,13 @@ bool PIC16AsmPrinter::doInitialization (Module &M) {
I->setSection(TAI->SectionForGlobal(I)->getName()); I->setSection(TAI->SectionForGlobal(I)->getName());
} }
DbgInfo.EmitFileDirective(M); DbgInfo.Init(M);
EmitFunctionDecls(M); EmitFunctionDecls(M);
EmitUndefinedVars(M); EmitUndefinedVars(M);
EmitDefinedVars(M); EmitDefinedVars(M);
EmitIData(M); EmitIData(M);
EmitUData(M); EmitUData(M);
EmitRomData(M); EmitRomData(M);
DbgInfo.PopulateFunctsDI(M);
return Result; return Result;
} }
@ -230,7 +242,7 @@ bool PIC16AsmPrinter::doInitialization (Module &M) {
/// ///
void PIC16AsmPrinter::EmitFunctionDecls (Module &M) { void PIC16AsmPrinter::EmitFunctionDecls (Module &M) {
// Emit declarations for external functions. // Emit declarations for external functions.
O << TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; O <<"\n"<<TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n";
for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) {
std::string Name = Mang->getValueName(I); std::string Name = Mang->getValueName(I);
if (Name.compare("@abort") == 0) if (Name.compare("@abort") == 0)

View File

@ -18,13 +18,6 @@
using namespace llvm; using namespace llvm;
PIC16DbgInfo::~PIC16DbgInfo() {
for(std::map<std::string, DISubprogram *>::iterator i = FunctNameMap.begin();
i!=FunctNameMap.end(); i++)
delete i->second;
FunctNameMap.clear();
}
void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
bool &HasAux, int Aux[], bool &HasAux, int Aux[],
std::string &TypeName) { std::string &TypeName) {
@ -70,7 +63,7 @@ void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
} }
HasAux = true; HasAux = true;
// In auxillary entry for array, 7th and 8th byte represent array size. // In auxillary entry for array, 7th and 8th byte represent array size.
Aux[6] = size; Aux[6] = size & 0xff;
Aux[7] = size >> 8; Aux[7] = size >> 8;
DIType BaseType = CTy.getTypeDerivedFrom(); DIType BaseType = CTy.getTypeDerivedFrom();
PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName); PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
@ -86,10 +79,14 @@ void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
else else
TypeNo = TypeNo | PIC16Dbg::T_UNION; TypeNo = TypeNo | PIC16Dbg::T_UNION;
CTy.getName(TypeName); CTy.getName(TypeName);
unsigned size = CTy.getSizeInBits()/8; // UniqueSuffix is .number where number is obtained from
// llvm.dbg.composite<number>.
std::string UniqueSuffix = "." + Ty.getGV()->getName().substr(18);
TypeName += UniqueSuffix;
unsigned short size = CTy.getSizeInBits()/8;
// 7th and 8th byte represent size. // 7th and 8th byte represent size.
HasAux = true; HasAux = true;
Aux[6] = size; Aux[6] = size & 0xff;
Aux[7] = size >> 8; Aux[7] = size >> 8;
break; break;
} }
@ -145,37 +142,84 @@ short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) {
return ClassNo; return ClassNo;
} }
void PIC16DbgInfo::PopulateFunctsDI(Module &M) { void PIC16DbgInfo::Init(Module &M) {
GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.subprograms"); // Do all debug related initializations here.
if (!Root) EmitFileDirective(M);
return; EmitCompositeTypeDecls(M);
Constant *RootC = cast<Constant>(*Root->use_begin());
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
UI != UE; ++UI)
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
UUI != UUE; ++UUI) {
GlobalVariable *GVSP = cast<GlobalVariable>(*UUI);
DISubprogram *SP = new DISubprogram(GVSP);
std::string Name;
SP->getLinkageName(Name);
FunctNameMap[Name] = SP;
}
return;
} }
DISubprogram* PIC16DbgInfo::getFunctDI(std::string FunctName) { void PIC16DbgInfo::EmitCompositeTypeDecls(Module &M) {
return FunctNameMap[FunctName]; for(iplist<GlobalVariable>::iterator I = M.getGlobalList().begin(),
E = M.getGlobalList().end(); I != E; I++) {
// Structures and union declaration's debug info has llvm.dbg.composite
// in its name.
if(I->getName().find("llvm.dbg.composite") != std::string::npos) {
GlobalVariable *GV = cast<GlobalVariable >(I);
DICompositeType CTy(GV);
if (CTy.getTag() == dwarf::DW_TAG_union_type ||
CTy.getTag() == dwarf::DW_TAG_structure_type ) {
std::string name;
CTy.getName(name);
std::string DIVar = I->getName();
// Get the number after llvm.dbg.composite and make UniqueSuffix from
// it.
std::string UniqueSuffix = "." + DIVar.substr(18);
std::string MangledCTyName = name + UniqueSuffix;
unsigned short size = CTy.getSizeInBits()/8;
int Aux[PIC16Dbg::AuxSize] = {0};
// 7th and 8th byte represent size of structure/union.
Aux[6] = size & 0xff;
Aux[7] = size >> 8;
// Emit .def for structure/union tag.
if( CTy.getTag() == dwarf::DW_TAG_union_type)
EmitSymbol(MangledCTyName, PIC16Dbg::C_UNTAG);
else if (CTy.getTag() == dwarf::DW_TAG_structure_type)
EmitSymbol(MangledCTyName, PIC16Dbg::C_STRTAG);
// Emit auxiliary debug information for structure/union tag.
EmitAuxEntry(MangledCTyName, Aux, PIC16Dbg::AuxSize);
unsigned long Value = 0;
DIArray Elements = CTy.getTypeArray();
for (unsigned i = 0, N = Elements.getNumElements(); i < N; i++) {
DIDescriptor Element = Elements.getElement(i);
unsigned short TypeNo = 0;
bool HasAux = false;
int ElementAux[PIC16Dbg::AuxSize] = { 0 };
std::string TypeName = "";
std::string ElementName;
GlobalVariable *GV = Element.getGV();
DIDerivedType DITy(GV);
DITy.getName(ElementName);
unsigned short ElementSize = DITy.getSizeInBits()/8;
// Get mangleddd name for this structure/union element.
std::string MangMemName = ElementName + UniqueSuffix;
PopulateDebugInfo(DITy, TypeNo, HasAux, ElementAux, TypeName);
short Class;
if( CTy.getTag() == dwarf::DW_TAG_union_type)
Class = PIC16Dbg::C_MOU;
else if (CTy.getTag() == dwarf::DW_TAG_structure_type)
Class = PIC16Dbg::C_MOS;
EmitSymbol(MangMemName, Class, TypeNo, Value);
if (CTy.getTag() == dwarf::DW_TAG_structure_type)
Value += ElementSize;
if (HasAux)
EmitAuxEntry(MangMemName, ElementAux, PIC16Dbg::AuxSize, TypeName);
}
// Emit mangled Symbol for end of structure/union.
std::string EOSSymbol = ".eos" + UniqueSuffix;
EmitSymbol(EOSSymbol, PIC16Dbg::C_EOS);
EmitAuxEntry(EOSSymbol, Aux, PIC16Dbg::AuxSize, MangledCTyName);
}
}
}
} }
void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) { void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) {
std::string FunctName = F->getName(); std::string FunctName = F->getName();
DISubprogram *SP = getFunctDI(FunctName); if (EmitDebugDirectives) {
if (SP) {
std::string FunctBeginSym = ".bf." + FunctName; std::string FunctBeginSym = ".bf." + FunctName;
std::string BlockBeginSym = ".bb." + FunctName; std::string BlockBeginSym = ".bb." + FunctName;
int FunctBeginLine = SP->getLineNumber();
int BFAux[PIC16Dbg::AuxSize] = {0}; int BFAux[PIC16Dbg::AuxSize] = {0};
BFAux[4] = FunctBeginLine; BFAux[4] = FunctBeginLine;
BFAux[5] = FunctBeginLine >> 8; BFAux[5] = FunctBeginLine >> 8;
@ -189,8 +233,7 @@ void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) {
void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) { void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) {
std::string FunctName = F->getName(); std::string FunctName = F->getName();
DISubprogram *SP = getFunctDI(FunctName); if (EmitDebugDirectives) {
if (SP) {
std::string FunctEndSym = ".ef." + FunctName; std::string FunctEndSym = ".ef." + FunctName;
std::string BlockEndSym = ".eb." + FunctName; std::string BlockEndSym = ".eb." + FunctName;
@ -208,14 +251,21 @@ void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) {
/// EmitAuxEntry - Emit Auxiliary debug information. /// EmitAuxEntry - Emit Auxiliary debug information.
/// ///
void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int num) { void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int num,
std::string tag) {
O << "\n\t.dim " << VarName << ", 1" ; O << "\n\t.dim " << VarName << ", 1" ;
if (tag != "")
O << ", " << tag;
for (int i = 0; i<num; i++) for (int i = 0; i<num; i++)
O << "," << Aux[i]; O << "," << Aux[i];
} }
void PIC16DbgInfo::EmitSymbol(std::string Name, int Class) { void PIC16DbgInfo::EmitSymbol(std::string Name, short Class, unsigned short
O << "\n\t" << ".def "<< Name << ", debug, class = " << Class; Type, unsigned long Value) {
O << "\n\t" << ".def "<< Name << ", type = " << Type << ", class = "
<< Class;
if (Value > 0)
O << ", value = " << Value;
} }
void PIC16DbgInfo::EmitVarDebugInfo(Module &M) { void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
@ -241,18 +291,8 @@ void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
O << "\n\t.type " << VarName << ", " << TypeNo; O << "\n\t.type " << VarName << ", " << TypeNo;
short ClassNo = getClass(DIGV); short ClassNo = getClass(DIGV);
O << "\n\t.class " << VarName << ", " << ClassNo; O << "\n\t.class " << VarName << ", " << ClassNo;
if (HasAux) { if (HasAux)
if (TypeName != "") { EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize, TypeName);
// Emit debug info for structure and union objects after
// .dim directive supports structure/union tag name in aux entry.
/* O << "\n\t.dim " << VarName << ", 1," << TypeName;
for (int i = 0; i<PIC16Dbg::AuxSize; i++)
O << "," << Aux[i];*/
}
else {
EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize);
}
}
} }
} }
} }
@ -262,31 +302,28 @@ void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
void PIC16DbgInfo::EmitFileDirective(Module &M) { void PIC16DbgInfo::EmitFileDirective(Module &M) {
GlobalVariable *CU = M.getNamedGlobal("llvm.dbg.compile_unit"); GlobalVariable *CU = M.getNamedGlobal("llvm.dbg.compile_unit");
if (CU) { if (CU) {
DICompileUnit DIUnit(CU); EmitDebugDirectives = true;
std::string Dir, FN; EmitFileDirective(CU, false);
std::string File = DIUnit.getDirectory(Dir) + "/" + DIUnit.getFilename(FN);
O << "\n\t.file\t\"" << File << "\"\n" ;
CurFile = File;
} }
} }
void PIC16DbgInfo::EmitFileDirective(const Function *F) { void PIC16DbgInfo::EmitFileDirective(GlobalVariable *CU, bool EmitEof) {
std::string FunctName = F->getName();
DISubprogram *SP = getFunctDI(FunctName);
if (SP) {
std::string Dir, FN; std::string Dir, FN;
DICompileUnit CU = SP->getCompileUnit(); DICompileUnit DIUnit(CU);
std::string File = CU.getDirectory(Dir) + "/" + CU.getFilename(FN); std::string File = DIUnit.getDirectory(Dir) + "/" + DIUnit.getFilename(FN);
if ( File != CurFile ) { if ( File != CurFile ) {
if (EmitEof)
EmitEOF(); EmitEOF();
O << "\n\t.file\t\"" << File << "\"\n" ; O << "\n\t.file\t\"" << File << "\"\n" ;
CurFile = File; CurFile = File;
} }
} }
}
void PIC16DbgInfo::EmitEOF() { void PIC16DbgInfo::EmitEOF() {
if (CurFile != "") if (CurFile != "")
O << "\n\t.EOF"; O << "\n\t.EOF";
} }
void PIC16DbgInfo::SetFunctBeginLine(unsigned line) {
FunctBeginLine = line;
}

View File

@ -91,29 +91,36 @@ namespace llvm {
class raw_ostream; class raw_ostream;
class PIC16DbgInfo { class PIC16DbgInfo {
std::map <std::string, DISubprogram *> FunctNameMap;
raw_ostream &O; raw_ostream &O;
const TargetAsmInfo *TAI; const TargetAsmInfo *TAI;
std::string CurFile; std::string CurFile;
// EmitDebugDirectives is set if debug information is available. Default
// value for it is false.
bool EmitDebugDirectives;
unsigned FunctBeginLine;
public: public:
PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) { PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) {
CurFile = ""; CurFile = "";
EmitDebugDirectives = false;
} }
~PIC16DbgInfo();
void PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux, void PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux,
int Aux[], std::string &TypeName); int Aux[], std::string &TypeName);
unsigned GetTypeDebugNumber(std::string &type); unsigned GetTypeDebugNumber(std::string &type);
short getClass(DIGlobalVariable DIGV); short getClass(DIGlobalVariable DIGV);
void PopulateFunctsDI(Module &M);
DISubprogram *getFunctDI(std::string FunctName);
void EmitFunctBeginDI(const Function *F); void EmitFunctBeginDI(const Function *F);
void Init(Module &M);
void EmitCompositeTypeDecls(Module &M);
void EmitFunctEndDI(const Function *F, unsigned Line); void EmitFunctEndDI(const Function *F, unsigned Line);
void EmitAuxEntry(const std::string VarName, int Aux[], int num); void EmitAuxEntry(const std::string VarName, int Aux[],
inline void EmitSymbol(std::string Name, int Class); int num = PIC16Dbg::AuxSize, std::string tag = "");
inline void EmitSymbol(std::string Name, short Class,
unsigned short Type = PIC16Dbg::T_NULL,
unsigned long Value = 0);
void EmitVarDebugInfo(Module &M); void EmitVarDebugInfo(Module &M);
void EmitFileDirective(Module &M); void EmitFileDirective(Module &M);
void EmitFileDirective(const Function *F); void EmitFileDirective(GlobalVariable *CU, bool EmitEof = true);
void EmitEOF(); void EmitEOF();
void SetFunctBeginLine(unsigned line);
}; };
} // end namespace llvm; } // end namespace llvm;
#endif #endif