forked from OSchip/llvm-project
Emit debug info for locals with proper scope.
llvm-svn: 72531
This commit is contained in:
parent
f193838d2b
commit
ae028d48be
|
@ -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,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 <PIC16Section *>AutosSections = PTAI->AutosSections;
|
||||
for (unsigned i = 0; i < AutosSections.size(); i++) {
|
||||
O << "\n";
|
||||
SwitchToSection(AutosSections[i]->S_);
|
||||
std::vector<const GlobalVariable*> 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<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];
|
||||
}
|
||||
}
|
||||
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++) {
|
||||
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";
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) << "\"" ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,10 @@
|
|||
#ifndef PIC16DBG_H
|
||||
#define PIC16DBG_H
|
||||
|
||||
#include "llvm/Analysis/DebugInfo.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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue