From dcb6da3efdfeb007ce222192f3af00736133682d Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Sat, 13 Jun 2009 17:35:54 +0000 Subject: [PATCH] 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 --- lib/Target/PIC16/PIC16AsmPrinter.cpp | 22 +++- lib/Target/PIC16/PIC16DebugInfo.cpp | 167 ++++++++++++++++----------- lib/Target/PIC16/PIC16DebugInfo.h | 23 ++-- 3 files changed, 134 insertions(+), 78 deletions(-) diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index d6282270ec5..f9a88012650 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -48,8 +48,21 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { const Function *F = MF.getFunction(); CurrentFnName = Mang->getValueName(F); - // Emit .file directive. - DbgInfo.EmitFileDirective(F); + // Iterate over the first basic block instructions to find if it has a + // 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). EmitFunctionFrame(MF); @@ -213,14 +226,13 @@ bool PIC16AsmPrinter::doInitialization (Module &M) { I->setSection(TAI->SectionForGlobal(I)->getName()); } - DbgInfo.EmitFileDirective(M); + DbgInfo.Init(M); EmitFunctionDecls(M); EmitUndefinedVars(M); EmitDefinedVars(M); EmitIData(M); EmitUData(M); EmitRomData(M); - DbgInfo.PopulateFunctsDI(M); return Result; } @@ -230,7 +242,7 @@ bool PIC16AsmPrinter::doInitialization (Module &M) { /// void PIC16AsmPrinter::EmitFunctionDecls (Module &M) { // Emit declarations for external functions. - O << TAI->getCommentString() << "Function Declarations - BEGIN." <<"\n"; + O <<"\n"<getCommentString() << "Function Declarations - BEGIN." <<"\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; I++) { std::string Name = Mang->getValueName(I); if (Name.compare("@abort") == 0) diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp index faf4590b43e..d7ebea7fa9d 100644 --- a/lib/Target/PIC16/PIC16DebugInfo.cpp +++ b/lib/Target/PIC16/PIC16DebugInfo.cpp @@ -18,13 +18,6 @@ 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) { @@ -70,7 +63,7 @@ void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, } HasAux = true; // In auxillary entry for array, 7th and 8th byte represent array size. - Aux[6] = size; + Aux[6] = size & 0xff; Aux[7] = size >> 8; DIType BaseType = CTy.getTypeDerivedFrom(); PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName); @@ -86,10 +79,14 @@ void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo, else TypeNo = TypeNo | PIC16Dbg::T_UNION; CTy.getName(TypeName); - unsigned size = CTy.getSizeInBits()/8; + // UniqueSuffix is .number where number is obtained from + // llvm.dbg.composite. + std::string UniqueSuffix = "." + Ty.getGV()->getName().substr(18); + TypeName += UniqueSuffix; + unsigned short size = CTy.getSizeInBits()/8; // 7th and 8th byte represent size. HasAux = true; - Aux[6] = size; + Aux[6] = size & 0xff; Aux[7] = size >> 8; break; } @@ -145,37 +142,84 @@ short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) { 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; +void PIC16DbgInfo::Init(Module &M) { + // Do all debug related initializations here. + EmitFileDirective(M); + EmitCompositeTypeDecls(M); } -DISubprogram* PIC16DbgInfo::getFunctDI(std::string FunctName) { - return FunctNameMap[FunctName]; +void PIC16DbgInfo::EmitCompositeTypeDecls(Module &M) { + for(iplist::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(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) { std::string FunctName = F->getName(); - DISubprogram *SP = getFunctDI(FunctName); - if (SP) { + if (EmitDebugDirectives) { 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; @@ -189,8 +233,7 @@ void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) { void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) { std::string FunctName = F->getName(); - DISubprogram *SP = getFunctDI(FunctName); - if (SP) { + if (EmitDebugDirectives) { std::string FunctEndSym = ".ef." + FunctName; std::string BlockEndSym = ".eb." + FunctName; @@ -208,14 +251,21 @@ void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) { /// 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" ; + if (tag != "") + O << ", " << tag; for (int i = 0; igetName(); - DISubprogram *SP = getFunctDI(FunctName); - if (SP) { - std::string Dir, FN; - DICompileUnit CU = SP->getCompileUnit(); - std::string File = CU.getDirectory(Dir) + "/" + CU.getFilename(FN); - if ( File != CurFile) { +void PIC16DbgInfo::EmitFileDirective(GlobalVariable *CU, bool EmitEof) { + std::string Dir, FN; + DICompileUnit DIUnit(CU); + std::string File = DIUnit.getDirectory(Dir) + "/" + DIUnit.getFilename(FN); + if ( File != CurFile ) { + if (EmitEof) EmitEOF(); - O << "\n\t.file\t\"" << File << "\"\n" ; - CurFile = File; - } + O << "\n\t.file\t\"" << File << "\"\n" ; + CurFile = File; } } @@ -290,3 +324,6 @@ void PIC16DbgInfo::EmitEOF() { O << "\n\t.EOF"; } +void PIC16DbgInfo::SetFunctBeginLine(unsigned line) { + FunctBeginLine = line; +} diff --git a/lib/Target/PIC16/PIC16DebugInfo.h b/lib/Target/PIC16/PIC16DebugInfo.h index be3939336b2..9d503807b20 100644 --- a/lib/Target/PIC16/PIC16DebugInfo.h +++ b/lib/Target/PIC16/PIC16DebugInfo.h @@ -91,29 +91,36 @@ namespace llvm { class raw_ostream; class PIC16DbgInfo { - std::map FunctNameMap; raw_ostream &O; const TargetAsmInfo *TAI; std::string CurFile; + // EmitDebugDirectives is set if debug information is available. Default + // value for it is false. + bool EmitDebugDirectives; + unsigned FunctBeginLine; public: 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, 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 Init(Module &M); + void EmitCompositeTypeDecls(Module &M); 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 EmitAuxEntry(const std::string VarName, int Aux[], + 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 EmitFileDirective(Module &M); - void EmitFileDirective(const Function *F); + void EmitFileDirective(GlobalVariable *CU, bool EmitEof = true); void EmitEOF(); + void SetFunctBeginLine(unsigned line); }; } // end namespace llvm; #endif