From ae028d48befb24d4638b81d9369da400ba4d1747 Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Thu, 28 May 2009 18:24:11 +0000 Subject: [PATCH] Emit debug info for locals with proper scope. llvm-svn: 72531 --- llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp | 99 +++++--------- llvm/lib/Target/PIC16/PIC16AsmPrinter.h | 8 +- llvm/lib/Target/PIC16/PIC16DebugInfo.cpp | 132 +++++++++++++++++++ llvm/lib/Target/PIC16/PIC16DebugInfo.h | 23 +++- llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp | 3 + 5 files changed, 195 insertions(+), 70 deletions(-) diff --git a/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp b/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp index 738723bbb5e4..ef3bc4b52a96 100644 --- a/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -48,7 +48,12 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { CurrentFnName = Mang->getValueName(F); // Emit the function variables. - emitFunctionData(MF); + EmitFunctionFrame(MF); + + // Emit function begin debug directives + DbgInfo.EmitFunctBeginDI(F); + + EmitAutos(CurrentFnName); const char *codeSection = PAN::getCodeSectionName(CurrentFnName).c_str(); const Section *fCodeSection = TAI->getNamedSection(codeSection, @@ -64,6 +69,10 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Emit function start label. O << CurrentFnName << ":\n"; + // For emitting line directives, we need to keep track of the current + // source line. When it changes then only emit the line directive. + unsigned CurLine = 0; + O << "\n"; // Print out code for the function. for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { @@ -73,9 +82,6 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { O << '\n'; } - // For emitting line directives, we need to keep track of the current - // source line. When it changes then only emit the line directive. - unsigned CurLine = 0; for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { // Emit the line directive if source line changed. @@ -92,6 +98,9 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { printMachineInstruction(II); } } + + // Emit function end debug directives. + DbgInfo.EmitFunctEndDI(F, CurLine); return false; // we didn't modify anything. } @@ -172,10 +181,12 @@ void PIC16AsmPrinter::printLibcallDecls(void) { bool PIC16AsmPrinter::doInitialization (Module &M) { bool Result = AsmPrinter::doInitialization(M); + DbgInfo.EmitFileDirective(M); + // FIXME:: This is temporary solution to generate the include file. // The processor should be passed to llc as in input and the header file // should be generated accordingly. - O << "\t#include P16F1937.INC\n"; + O << "\n\t#include P16F1937.INC\n"; MachineModuleInfo *MMI = getAnalysisIfAvailable(); assert(MMI); DwarfWriter *DW = getAnalysisIfAvailable(); @@ -194,7 +205,7 @@ bool PIC16AsmPrinter::doInitialization (Module &M) { EmitIData(M); EmitUData(M); EmitRomData(M); - EmitAutos(M); + DbgInfo.PopulateFunctsDI(M); return Result; } @@ -273,14 +284,14 @@ void PIC16AsmPrinter::EmitRomData (Module &M) bool PIC16AsmPrinter::doFinalization(Module &M) { printLibcallDecls(); - EmitVarDebugInfo(M); - O << "\t" << ".EOF\n"; - O << "\t" << "END\n"; + DbgInfo.EmitVarDebugInfo(M); + O << "\n\t" << ".EOF"; + O << "\n\t" << "END\n"; bool Result = AsmPrinter::doFinalization(M); return Result; } -void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { +void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) { const Function *F = MF.getFunction(); std::string FuncName = Mang->getValueName(F); const TargetData *TD = TM.getTargetData(); @@ -364,70 +375,30 @@ void PIC16AsmPrinter::EmitUData (Module &M) { } } -void PIC16AsmPrinter::EmitAutos (Module &M) +void PIC16AsmPrinter::EmitAutos (std::string FunctName) { // Section names for all globals are already set. const TargetData *TD = TM.getTargetData(); - // Now print all Autos sections. + // Now print Autos section for this function. + std::string SectionName = PAN::getAutosSectionName(FunctName); std::vector AutosSections = PTAI->AutosSections; for (unsigned i = 0; i < AutosSections.size(); i++) { O << "\n"; - SwitchToSection(AutosSections[i]->S_); - std::vector Items = AutosSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string VarName = Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - // Emit memory reserve directive. - O << VarName << " RES " << Size << "\n"; - } - } -} - -void PIC16AsmPrinter::EmitVarDebugInfo(Module &M) { - GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables"); - if (!Root) - return; - - O << TAI->getCommentString() << " Debug Information:"; - Constant *RootC = cast(*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) { - DIGlobalVariable DIGV(cast(*UUI)); - DIType Ty = DIGV.getType(); - unsigned short TypeNo = 0; - bool HasAux = false; - int Aux[20] = { 0 }; - std::string TypeName = ""; - std::string VarName = TAI->getGlobalPrefix()+DIGV.getGlobal()->getName(); - DbgInfo.PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TypeName); - // Emit debug info only if type information is availaible. - if (TypeNo != PIC16Dbg::T_NULL) { - O << "\n\t.type " << VarName << ", " << TypeNo; - short ClassNo = DbgInfo.getClass(DIGV); - O << "\n\t.class " << VarName << ", " << ClassNo; - if (HasAux) { - if (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<20; i++) - O << "," << Aux[i];*/ - } - else { - O << "\n\t.dim " << VarName << ", 1" ; - for (int i = 0; i<20; i++) - O << "," << Aux[i]; - } - } + if (AutosSections[i]->S_->getName() == SectionName) { + SwitchToSection(AutosSections[i]->S_); + std::vector Items = AutosSections[i]->Items; + for (unsigned j = 0; j < Items.size(); j++) { + std::string VarName = Mang->getValueName(Items[j]); + Constant *C = Items[j]->getInitializer(); + const Type *Ty = C->getType(); + unsigned Size = TD->getTypeAllocSize(Ty); + // Emit memory reserve directive. + O << VarName << " RES " << Size << "\n"; } + break; } } - O << "\n"; } diff --git a/llvm/lib/Target/PIC16/PIC16AsmPrinter.h b/llvm/lib/Target/PIC16/PIC16AsmPrinter.h index adcd64d44eaf..2545dfd680a8 100644 --- a/llvm/lib/Target/PIC16/PIC16AsmPrinter.h +++ b/llvm/lib/Target/PIC16/PIC16AsmPrinter.h @@ -32,7 +32,7 @@ namespace llvm { explicit PIC16AsmPrinter(raw_ostream &O, PIC16TargetMachine &TM, const TargetAsmInfo *T, CodeGenOpt::Level OL, bool V) - : AsmPrinter(O, TM, T, OL, V) { + : AsmPrinter(O, TM, T, OL, V), DbgInfo(O,T) { PTLI = TM.getTargetLowering(); PTAI = static_cast (T); } @@ -51,12 +51,10 @@ namespace llvm { void EmitDefinedVars (Module &M); void EmitIData (Module &M); void EmitUData (Module &M); - void EmitAutos (Module &M); + void EmitAutos (std::string FunctName); void EmitRomData (Module &M); - void emitFunctionData(MachineFunction &MF); + void EmitFunctionFrame(MachineFunction &MF); void printLibcallDecls(void); - void EmitVarDebugInfo (Module &M); - protected: bool doInitialization(Module &M); bool doFinalization(Module &M); diff --git a/llvm/lib/Target/PIC16/PIC16DebugInfo.cpp b/llvm/lib/Target/PIC16/PIC16DebugInfo.cpp index 166d96e9f65c..4d43811f24a6 100644 --- a/llvm/lib/Target/PIC16/PIC16DebugInfo.cpp +++ b/llvm/lib/Target/PIC16/PIC16DebugInfo.cpp @@ -14,9 +14,17 @@ #include "PIC16.h" #include "PIC16DebugInfo.h" #include "llvm/GlobalVariable.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; +PIC16DbgInfo::~PIC16DbgInfo() { + for(std::map::iterator i = FunctNameMap.begin(); + i!=FunctNameMap.end(); i++) + delete i->second; + FunctNameMap.clear(); +} + void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux, int Aux[], std::string &TypeName) { @@ -136,3 +144,127 @@ short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) { ClassNo = PIC16Dbg::C_EXT; return ClassNo; } + +void PIC16DbgInfo::PopulateFunctsDI(Module &M) { + GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.subprograms"); + if (!Root) + return; + Constant *RootC = cast(*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(*UUI); + DISubprogram *SP = new DISubprogram(GVSP); + std::string Name; + SP->getLinkageName(Name); + FunctNameMap[Name] = SP; + } + return; +} + +DISubprogram* PIC16DbgInfo::getFunctDI(std::string FunctName) { + return FunctNameMap[FunctName]; +} + +void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) { + std::string FunctName = F->getName(); + DISubprogram *SP = getFunctDI(FunctName); + if (SP) { + std::string FunctBeginSym = ".bf." + FunctName; + std::string BlockBeginSym = ".bb." + FunctName; + + int FunctBeginLine = SP->getLineNumber(); + int BFAux[PIC16Dbg::AuxSize] = {0}; + BFAux[4] = FunctBeginLine; + BFAux[5] = FunctBeginLine >> 8; + // Emit debug directives for beginning of function. + EmitSymbol(FunctBeginSym, PIC16Dbg::C_FCN); + EmitAuxEntry(FunctBeginSym, BFAux, PIC16Dbg::AuxSize); + EmitSymbol(BlockBeginSym, PIC16Dbg::C_BLOCK); + EmitAuxEntry(BlockBeginSym, BFAux, PIC16Dbg::AuxSize); + } +} + +void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) { + std::string FunctName = F->getName(); + DISubprogram *SP = getFunctDI(FunctName); + if (SP) { + std::string FunctEndSym = ".ef." + FunctName; + std::string BlockEndSym = ".eb." + FunctName; + + // Emit debug directives for end of function. + EmitSymbol(BlockEndSym, PIC16Dbg::C_BLOCK); + int EFAux[PIC16Dbg::AuxSize] = {0}; + // 5th and 6th byte stand for line number. + EFAux[4] = Line; + EFAux[5] = Line >> 8; + EmitAuxEntry(BlockEndSym, EFAux, PIC16Dbg::AuxSize); + EmitSymbol(FunctEndSym, PIC16Dbg::C_FCN); + EmitAuxEntry(FunctEndSym, EFAux, PIC16Dbg::AuxSize); + } +} + +/// EmitAuxEntry - Emit Auxiliary debug information. +/// +void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int num) { + O << "\n\t.dim " << VarName << ", 1" ; + for (int i = 0; i(*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) { + DIGlobalVariable DIGV(cast(*UUI)); + DIType Ty = DIGV.getType(); + unsigned short TypeNo = 0; + bool HasAux = false; + int Aux[PIC16Dbg::AuxSize] = { 0 }; + std::string TypeName = ""; + std::string VarName = TAI->getGlobalPrefix()+DIGV.getGlobal()->getName(); + PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TypeName); + // Emit debug info only if type information is availaible. + if (TypeNo != PIC16Dbg::T_NULL) { + O << "\n\t.type " << VarName << ", " << TypeNo; + short ClassNo = getClass(DIGV); + O << "\n\t.class " << VarName << ", " << ClassNo; + if (HasAux) { + if (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 namespace llvm { namespace PIC16Dbg { @@ -80,14 +83,32 @@ namespace llvm { C_SECTION, C_EFCN = 255 }; + enum SymbolSize { + AuxSize =20 + }; } + class raw_ostream; + class PIC16DbgInfo { + std::map FunctNameMap; + raw_ostream &O; + const TargetAsmInfo *TAI; public: + PIC16DbgInfo(raw_ostream &o, const TargetAsmInfo *T) : O(o), TAI(T) {} + ~PIC16DbgInfo(); void PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, bool &HasAux, int Aux[], std::string &TypeName); unsigned GetTypeDebugNumber(std::string &type); short getClass(DIGlobalVariable DIGV); + void PopulateFunctsDI(Module &M); + DISubprogram *getFunctDI(std::string FunctName); + void EmitFunctBeginDI(const Function *F); + void EmitFunctEndDI(const Function *F, unsigned Line); + void EmitAuxEntry(const std::string VarName, int Aux[], int num); + inline void EmitSymbol(std::string Name, int Class); + void EmitVarDebugInfo(Module &M); + void EmitFileDirective(Module &M); }; } // end namespace llvm; #endif diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp index 9d7592a2e12b..d2657f018f88 100644 --- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp +++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp @@ -47,6 +47,9 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM) ROSection = new PIC16Section(getReadOnlySection()); ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls")); ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs")); + // Set it to false because we weed to generate c file name and not bc file + // name. + HasSingleParameterDotFile = false; } const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const