Emit debug info for locals with proper scope.

llvm-svn: 72531
This commit is contained in:
Sanjiv Gupta 2009-05-28 18:24:11 +00:00
parent f193838d2b
commit ae028d48be
5 changed files with 195 additions and 70 deletions

View File

@ -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<MachineModuleInfo>();
assert(MMI);
DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
@ -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,16 +375,18 @@ 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 <PIC16Section *>AutosSections = PTAI->AutosSections;
for (unsigned i = 0; i < AutosSections.size(); i++) {
O << "\n";
if (AutosSections[i]->S_->getName() == SectionName) {
SwitchToSection(AutosSections[i]->S_);
std::vector<const GlobalVariable*> Items = AutosSections[i]->Items;
for (unsigned j = 0; j < Items.size(); j++) {
@ -384,50 +397,8 @@ void PIC16AsmPrinter::EmitAutos (Module &M)
// Emit memory reserve directive.
O << VarName << " RES " << Size << "\n";
}
break;
}
}
}
void PIC16AsmPrinter::EmitVarDebugInfo(Module &M) {
GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables");
if (!Root)
return;
O << TAI->getCommentString() << " Debug Information:";
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) {
DIGlobalVariable DIGV(cast<GlobalVariable>(*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];
}
}
}
}
}
O << "\n";
}

View File

@ -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<const PIC16TargetAsmInfo *> (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);

View File

@ -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<std::string, DISubprogram *>::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<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) {
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<num; i++)
O << "," << Aux[i];
}
void PIC16DbgInfo::EmitSymbol(std::string Name, int Class) {
O << "\n\t" << ".def "<< Name << ", debug, class = " << Class;
}
void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables");
if (!Root)
return;
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) {
DIGlobalVariable DIGV(cast<GlobalVariable>(*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<PIC16Dbg::AuxSize; i++)
O << "," << Aux[i];*/
}
else {
EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize);
}
}
}
}
}
O << "\n";
}
void PIC16DbgInfo::EmitFileDirective(Module &M) {
GlobalVariable *CU = M.getNamedGlobal("llvm.dbg.compile_unit");
if (CU) {
DICompileUnit DIUnit(CU);
std::string Dir, FN;
O << "\n\t.file\t\"" << DIUnit.getDirectory(Dir) <<"/"
<< DIUnit.getFilename(FN) << "\"" ;
}
}

View File

@ -15,6 +15,9 @@
#define PIC16DBG_H
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetAsmInfo.h"
#include <map>
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 <std::string, DISubprogram *> 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

View File

@ -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