Foundation for call frame information.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27491 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Laskey 2006-04-07 16:34:46 +00:00
parent 38ab6d887c
commit 4188699f80
21 changed files with 359 additions and 65 deletions

View File

@ -41,10 +41,13 @@ class DIE;
class DIEAbbrev; class DIEAbbrev;
class GlobalVariableDesc; class GlobalVariableDesc;
class MachineDebugInfo; class MachineDebugInfo;
class MachineLocation;
class MachineFunction; class MachineFunction;
class MachineLocation;
class MachineMove;
class Module; class Module;
class MRegisterInfo;
class SubprogramDesc; class SubprogramDesc;
class TargetData;
class Type; class Type;
class TypeDesc; class TypeDesc;
@ -81,6 +84,12 @@ protected:
/// ///
AsmPrinter *Asm; AsmPrinter *Asm;
/// TD - Target data.
const TargetData &TD;
/// RI - Register Information.
const MRegisterInfo *RI;
/// M - Current module. /// M - Current module.
/// ///
Module *M; Module *M;
@ -324,7 +333,8 @@ private:
/// AddAddress - Add an address attribute to a die based on the location /// AddAddress - Add an address attribute to a die based on the location
/// provided. /// provided.
void AddAddress(DIE *Die, unsigned Attribute, MachineLocation &Location); void AddAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location);
/// NewType - Create a new type DIE. /// NewType - Create a new type DIE.
/// ///
@ -375,6 +385,11 @@ private:
/// ///
void SizeAndOffsets(); void SizeAndOffsets();
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
std::vector<MachineMove *> &Moves);
/// EmitDebugInfo - Emit the debug info section. /// EmitDebugInfo - Emit the debug info section.
/// ///
void EmitDebugInfo() const; void EmitDebugInfo() const;
@ -387,10 +402,14 @@ private:
/// ///
void EmitDebugLines() const; void EmitDebugLines() const;
/// EmitDebugFrame - Emit info into a debug frame section. /// EmitInitialDebugFrame - Emit common frame info into a debug frame section.
/// ///
void EmitDebugFrame(); void EmitInitialDebugFrame();
/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame
/// section.
void EmitFunctionDebugFrame();
/// EmitDebugPubNames - Emit info into a debug pubnames section. /// EmitDebugPubNames - Emit info into a debug pubnames section.
/// ///
void EmitDebugPubNames(); void EmitDebugPubNames();
@ -439,7 +458,7 @@ public:
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has /// SetDebugInfo - Set DebugInfo when it's known that pass manager has
/// created it. Set by the target AsmPrinter. /// created it. Set by the target AsmPrinter.
void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; } void SetDebugInfo(MachineDebugInfo *DI);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Main entry points. // Main entry points.

View File

@ -47,6 +47,8 @@ namespace llvm {
class Constant; class Constant;
class DebugInfoDesc; class DebugInfoDesc;
class GlobalVariable; class GlobalVariable;
class MachineFunction;
class MachineMove;
class Module; class Module;
class PointerType; class PointerType;
class StructType; class StructType;
@ -574,7 +576,7 @@ public:
void setName(const std::string &N) { Name = N; } void setName(const std::string &N) { Name = N; }
void setFile(CompileUnitDesc *U) { File = U; } void setFile(CompileUnitDesc *U) { File = U; }
void setLine(unsigned L) { Line = L; } void setLine(unsigned L) { Line = L; }
void setTypeDesc(TypeDesc *T) { TyDesc = T; } void setType(TypeDesc *T) { TyDesc = T; }
void setIsStatic(bool IS) { IsStatic = IS; } void setIsStatic(bool IS) { IsStatic = IS; }
void setIsDefinition(bool ID) { IsDefinition = ID; } void setIsDefinition(bool ID) { IsDefinition = ID; }
@ -940,6 +942,10 @@ private:
// RootScope - Top level scope for the current function. // RootScope - Top level scope for the current function.
// //
DebugScope *RootScope; DebugScope *RootScope;
// FrameMoves - List of moves done by a function's prolog. Used to construct
// frame maps by debug consumers.
std::vector<MachineMove *> FrameMoves;
public: public:
MachineDebugInfo(); MachineDebugInfo();
@ -953,6 +959,14 @@ public:
/// ///
bool doFinalization(); bool doFinalization();
/// BeginFunction - Begin gathering function debug information.
///
void BeginFunction(MachineFunction *MF);
/// EndFunction - Discard function debug information.
///
void EndFunction();
/// getDescFor - Convert a Value to a debug information descriptor. /// getDescFor - Convert a Value to a debug information descriptor.
/// ///
// FIXME - use new Value type when available. // FIXME - use new Value type when available.
@ -1060,10 +1074,10 @@ public:
/// getOrCreateScope - Returns the scope associated with the given descriptor. /// getOrCreateScope - Returns the scope associated with the given descriptor.
/// ///
DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc); DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
/// ClearScopes - Delete the scope and variable info after a function is /// getFrameMoves - Returns a reference to a list of moves done in the current
/// completed. /// function's prologue. Used to construct frame maps for debug comsumers.
void ClearScopes(); std::vector<MachineMove *> &getFrameMoves() { return FrameMoves; }
}; // End class MachineDebugInfo }; // End class MachineDebugInfo

View File

@ -44,6 +44,7 @@ namespace llvm {
class TargetData; class TargetData;
class TargetRegisterClass; class TargetRegisterClass;
class Type; class Type;
class MachineDebugInfo;
class MachineFunction; class MachineFunction;
class MachineFrameInfo { class MachineFrameInfo {
@ -106,12 +107,21 @@ class MachineFrameInfo {
/// insertion. /// insertion.
/// ///
unsigned MaxCallFrameSize; unsigned MaxCallFrameSize;
/// DebugInfo - This field is set (via setMachineDebugInfo) by a debug info
/// consumer (ex. DwarfWriter) to indicate that frame layout information
/// should be acquired. Typically, it's the responsibility of the target's
/// MRegisterInfo prologue/epilogue emitting code to inform MachineDebugInfo
/// of frame layouts.
MachineDebugInfo *DebugInfo;
public: public:
MachineFrameInfo() { MachineFrameInfo() {
NumFixedObjects = StackSize = MaxAlignment = 0; NumFixedObjects = StackSize = MaxAlignment = 0;
HasVarSizedObjects = false; HasVarSizedObjects = false;
HasCalls = false; HasCalls = false;
MaxCallFrameSize = 0; MaxCallFrameSize = 0;
DebugInfo = 0;
} }
/// hasStackObjects - Return true if there are any stack objects in this /// hasStackObjects - Return true if there are any stack objects in this
@ -230,6 +240,14 @@ public:
return Objects.size()-NumFixedObjects-1; return Objects.size()-NumFixedObjects-1;
} }
/// getMachineDebugInfo - Used by a prologue/epilogue emitter (MRegisterInfo)
/// to provide frame layout information.
MachineDebugInfo *getMachineDebugInfo() const { return DebugInfo; }
/// setMachineDebugInfo - Used by a debug consumer (DwarfWriter) to indicate
/// that frame layout information should be gathered.
void setMachineDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; }
/// print - Used by the MachineFunction printer to print information about /// print - Used by the MachineFunction printer to print information about
/// stack objects. Implemented in MachineFunction.cpp /// stack objects. Implemented in MachineFunction.cpp
/// ///

View File

@ -8,7 +8,13 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// The MachineLocation class is used to represent a simple location in a machine // The MachineLocation class is used to represent a simple location in a machine
// frame. Locations will be one of two forms; a register or an address formed // frame. Locations will be one of two forms; a register or an address formed
// from a base address plus an offset. // from a base address plus an offset. Register indirection can be specified by
// using an offset of zero.
//
// The MachineMove class is used to represent abstract move operations in the
// prolog/epilog of a compiled function. A collection of these objects can be
// used by a debug consumer to track the location of values when unwinding stack
// frames.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -24,6 +30,11 @@ private:
int Offset; // Displacement if not register. int Offset; // Displacement if not register.
public: public:
enum {
// The target register number for an abstract frame pointer. The value is
// an arbitrary value greater than MRegisterInfo::FirstVirtualRegister.
VirtualFP = ~0U
};
MachineLocation() MachineLocation()
: IsRegister(false) : IsRegister(false)
, Register(0) , Register(0)
@ -37,7 +48,7 @@ public:
MachineLocation(unsigned R, int O) MachineLocation(unsigned R, int O)
: IsRegister(false) : IsRegister(false)
, Register(R) , Register(R)
, Offset(0) , Offset(O)
{} {}
// Accessors // Accessors
@ -57,6 +68,31 @@ public:
Register = R; Register = R;
Offset = O; Offset = O;
} }
#ifndef NDEBUG
void dump();
#endif
};
class MachineMove {
private:
unsigned LabelID; // Label ID number for post-instruction
// address when result of move takes
// effect.
const MachineLocation Destination; // Move to location.
const MachineLocation Source; // Move from location.
public:
MachineMove(unsigned ID, MachineLocation &D, MachineLocation &S)
: LabelID(ID)
, Destination(D)
, Source(S)
{}
// Accessors
unsigned getLabelID() const { return LabelID; }
const MachineLocation &getDestination() const { return Destination; }
const MachineLocation &getSource() const { return Source; }
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -27,6 +27,7 @@ class Type;
class MachineFunction; class MachineFunction;
class MachineInstr; class MachineInstr;
class MachineLocation; class MachineLocation;
class MachineMove;
class TargetRegisterClass; class TargetRegisterClass;
/// TargetRegisterDesc - This record contains all of the information known about /// TargetRegisterDesc - This record contains all of the information known about
@ -345,18 +346,35 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// Debug information queries. /// Debug information queries.
/// getDwarfRegNum - Map a target register to an equivalent dwarf register
/// number. Returns -1 if there is no equivalent value.
virtual int getDwarfRegNum(unsigned RegNum) const = 0;
/// getFrameRegister - This method should return the register used as a base /// getFrameRegister - This method should return the register used as a base
/// for values allocated in the current stack frame. This value should be /// for values allocated in the current stack frame.
/// returned as a dwarf register number (getDwarfRegNum.)
virtual unsigned getFrameRegister(MachineFunction &MF) const = 0; virtual unsigned getFrameRegister(MachineFunction &MF) const = 0;
/// getRARegister - This method should return the register where the return
/// address can be found.
virtual unsigned getRARegister() const = 0;
/// getStackDirection - This method should return the factor by which stacks
/// grow. The tyical value is -4 which is the grows negatively in 4 byte
/// increments.
virtual int getStackDirection() const;
/// getLocation - This method should return the actual location of a frame /// getLocation - This method should return the actual location of a frame
/// variable given the frame index. The location is returned in ML. /// variable given the frame index. The location is returned in ML.
/// Subclasses should override this method for special handling of frame /// Subclasses should override this method for special handling of frame
/// variables and call MRegisterInfo::getLocation for the default action. /// variables and call MRegisterInfo::getLocation for the default action.
virtual void getLocation(MachineFunction &MF, unsigned Index, virtual void getLocation(MachineFunction &MF, unsigned Index,
MachineLocation &ML) const; MachineLocation &ML) const;
/// getInitialFrameState - Returns a list of machine moves that are assumed
/// on entry to all functions. Note that LabelID is ignored (assumed to be
/// the beginning of the function.)
virtual void getInitialFrameState(std::vector<MachineMove *> &Moves) const;
}; };
// This is useful when building DenseMaps keyed on virtual registers // This is useful when building DenseMaps keyed on virtual registers

View File

@ -18,6 +18,7 @@
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Support/Dwarf.h" #include "llvm/Support/Dwarf.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
@ -1073,8 +1074,6 @@ void DwarfWriter::EmitInt64(uint64_t Value) const {
if (Asm->Data64bitsDirective) { if (Asm->Data64bitsDirective) {
O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec; O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
} else { } else {
const TargetData &TD = Asm->TM.getTargetData();
if (TD.isBigEndian()) { if (TD.isBigEndian()) {
EmitInt32(unsigned(Value >> 32)); O << "\n"; EmitInt32(unsigned(Value >> 32)); O << "\n";
EmitInt32(unsigned(Value)); EmitInt32(unsigned(Value));
@ -1216,12 +1215,14 @@ void DwarfWriter::AddSourceLine(DIE *Die, CompileUnitDesc *File, unsigned Line)
/// AddAddress - Add an address attribute to a die based on the location /// AddAddress - Add an address attribute to a die based on the location
/// provided. /// provided.
void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute, void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute,
MachineLocation &Location) { const MachineLocation &Location) {
DIEBlock *Block = new DIEBlock(); DIEBlock *Block = new DIEBlock();
if (Location.isRegister()) { if (Location.isRegister()) {
Block->AddUInt(DW_FORM_data1, DW_OP_reg0 + Location.getRegister()); Block->AddUInt(DW_FORM_data1,
DW_OP_reg0 + RI->getDwarfRegNum(Location.getRegister()));
} else { } else {
Block->AddUInt(DW_FORM_data1, DW_OP_breg0 + Location.getRegister()); Block->AddUInt(DW_FORM_data1,
DW_OP_breg0 + RI->getDwarfRegNum(Location.getRegister()));
Block->AddUInt(DW_FORM_sdata, Location.getOffset()); Block->AddUInt(DW_FORM_sdata, Location.getOffset());
} }
Block->ComputeSize(*this); Block->ComputeSize(*this);
@ -1358,8 +1359,7 @@ DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) {
// Now normalize offset to the field. // Now normalize offset to the field.
Offset -= FieldOffset; Offset -= FieldOffset;
// Maybe we need to work from the other. // Maybe we need to work from the other end.
const TargetData &TD = Asm->TM.getTargetData();
if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size); if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size);
Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3); Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3);
@ -1515,8 +1515,11 @@ DIE *DwarfWriter::NewSubprogram(SubprogramDesc *SPD) {
DIE *SubprogramDie = new DIE(DW_TAG_subprogram); DIE *SubprogramDie = new DIE(DW_TAG_subprogram);
SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name); SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name);
SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type); if (Type) {
SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, IsExternal); SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
}
SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, IsExternal);
SubprogramDie->AddUInt (DW_AT_prototyped, DW_FORM_flag, 1);
// Add source line info if available. // Add source line info if available.
AddSourceLine(SubprogramDie, UnitDesc, SPD->getLine()); AddSourceLine(SubprogramDie, UnitDesc, SPD->getLine());
@ -1561,7 +1564,7 @@ DIE *DwarfWriter::NewScopeVariable(DebugVariable *DV, CompileUnit *Unit) {
// Add variable address. // Add variable address.
MachineLocation Location; MachineLocation Location;
Asm->TM.getRegisterInfo()->getLocation(*MF, DV->getFrameIndex(), Location); RI->getLocation(*MF, DV->getFrameIndex(), Location);
AddAddress(VariableDie, DW_AT_location, Location); AddAddress(VariableDie, DW_AT_location, Location);
return VariableDie; return VariableDie;
@ -1621,18 +1624,20 @@ void DwarfWriter::ConstructRootScope(DebugScope *RootScope) {
// Get the compile unit context. // Get the compile unit context.
CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(SPD->getContext()); CompileUnitDesc *UnitDesc = static_cast<CompileUnitDesc *>(SPD->getContext());
CompileUnit *Unit = FindCompileUnit(UnitDesc); CompileUnit *Unit = FindCompileUnit(UnitDesc);
// Generate the mangled name.
std::string MangledName = Asm->Mang->getValueName(MF->getFunction());
// Get the subprogram die. // Get the subprogram die.
DIE *SPDie = Unit->getDieMapSlotFor(SPD); DIE *SPDie = Unit->getDieMapSlotFor(SPD);
assert(SPDie && "Missing subprogram descriptor"); assert(SPDie && "Missing subprogram descriptor");
// Add the function bounds. // Add the function bounds.
SPDie->AddLabel(DW_AT_low_pc, DW_FORM_addr, SPDie->AddObjectLabel(DW_AT_low_pc, DW_FORM_addr, MangledName);
DWLabel("func_begin", SubprogramCount));
SPDie->AddLabel(DW_AT_high_pc, DW_FORM_addr, SPDie->AddLabel(DW_AT_high_pc, DW_FORM_addr,
DWLabel("func_end", SubprogramCount)); DWLabel("func_end", SubprogramCount));
MachineLocation Location(Asm->TM.getRegisterInfo()->getFrameRegister(*MF)); MachineLocation Location(RI->getFrameRegister(*MF));
AddAddress(SPDie, DW_AT_frame_base, Location); AddAddress(SPDie, DW_AT_frame_base, Location);
ConstructScope(RootScope, SPDie, Unit); ConstructScope(RootScope, SPDie, Unit);
@ -1792,6 +1797,50 @@ void DwarfWriter::SizeAndOffsets() {
} }
} }
/// EmitFrameMoves - Emit frame instructions to describe the layout of the
/// frame.
void DwarfWriter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID,
std::vector<MachineMove *> &Moves) {
for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
MachineMove *Move = Moves[i];
unsigned LabelID = Move->getLabelID();
const MachineLocation &Dst = Move->getDestination();
const MachineLocation &Src = Move->getSource();
// Advance row if new location.
if (BaseLabel && LabelID && BaseLabelID != LabelID) {
EmitULEB128Bytes(DW_CFA_advance_loc4);
EOL("DW_CFA_advance_loc4");
EmitDifference("loc", LabelID, BaseLabel, BaseLabelID);
EOL("");
BaseLabelID = LabelID;
BaseLabel = "loc";
}
// If advancing cfa.
if (Dst.isRegister() && Dst.getRegister() == MachineLocation::VirtualFP) {
if (!Src.isRegister()) {
if (Src.getRegister() == MachineLocation::VirtualFP) {
EmitULEB128Bytes(DW_CFA_def_cfa_offset);
EOL("DW_CFA_def_cfa_offset");
} else {
EmitULEB128Bytes(DW_CFA_def_cfa);
EOL("DW_CFA_def_cfa");
EmitULEB128Bytes(RI->getDwarfRegNum(Src.getRegister()));
EOL("Register");
}
EmitULEB128Bytes(Src.getOffset() / RI->getStackDirection());
EOL("Offset");
} else {
}
} else {
}
}
}
/// EmitDebugInfo - Emit the debug info section. /// EmitDebugInfo - Emit the debug info section.
/// ///
void DwarfWriter::EmitDebugInfo() const { void DwarfWriter::EmitDebugInfo() const {
@ -1999,10 +2048,10 @@ void DwarfWriter::EmitDebugLines() const {
O << "\n"; O << "\n";
} }
/// EmitDebugFrame - Emit visible names into a debug frame section. /// EmitInitialDebugFrame - Emit common frame info into a debug frame section.
/// ///
void DwarfWriter::EmitDebugFrame() { void DwarfWriter::EmitInitialDebugFrame() {
// Start the dwarf pubnames section. // Start the dwarf frame section.
Asm->SwitchSection(DwarfFrameSection, 0); Asm->SwitchSection(DwarfFrameSection, 0);
EmitDifference("frame_common_end", 0, EmitDifference("frame_common_end", 0,
@ -2014,20 +2063,49 @@ void DwarfWriter::EmitDebugFrame() {
EmitInt8(DW_CIE_VERSION); EOL("CIE Version"); EmitInt8(DW_CIE_VERSION); EOL("CIE Version");
EmitString(""); EOL("CIE Augmentation"); EmitString(""); EOL("CIE Augmentation");
EmitULEB128Bytes(1); EOL("CIE Code Alignment Factor"); EmitULEB128Bytes(1); EOL("CIE Code Alignment Factor");
// FIXME - needs to change based on stack direction. EmitSLEB128Bytes(RI->getStackDirection()); EOL("CIE Data Alignment Factor");
EmitSLEB128Bytes(-sizeof(int32_t)); EOL("CIE Data Alignment Factor"); EmitInt8(RI->getDwarfRegNum(RI->getRARegister())); EOL("CIE RA Column");
// FIXME - hard coded for PPC (LR).
EmitInt8(0x41); EOL("CIE RA Column Hardcoded (PPC LR)"); std::vector<MachineMove *> Moves;
// FIXME - hard coded for PPC 0(SP). RI->getInitialFrameState(Moves);
EmitULEB128Bytes(DW_CFA_def_cfa); EOL("DW_CFA_def_cfa"); EmitFrameMoves(NULL, 0, Moves);
EmitULEB128Bytes(1); EOL("PPC Register SP"); for (unsigned i = 0, N = Moves.size(); i < N; ++i) delete Moves[i];
EmitULEB128Bytes(0); EOL("PPC offset 0 as in 0(SP)");
EmitAlign(2); EmitAlign(2);
EmitLabel("frame_common_end", 0); EmitLabel("frame_common_end", 0);
O << "\n"; O << "\n";
} }
/// EmitFunctionDebugFrame - Emit per function frame info into a debug frame
/// section.
void DwarfWriter::EmitFunctionDebugFrame() {
// Start the dwarf frame section.
Asm->SwitchSection(DwarfFrameSection, 0);
EmitDifference("frame_end", SubprogramCount,
"frame_begin", SubprogramCount);
EOL("Length of Frame Information Entry");
EmitLabel("frame_begin", SubprogramCount);
EmitReference("section_frame", 0); EOL("FDE CIE offset");
EmitReference("func_begin", SubprogramCount); EOL("FDE initial location");
EmitDifference("func_end", SubprogramCount,
"func_begin", SubprogramCount);
EOL("FDE address range");
std::vector<MachineMove *> &Moves = DebugInfo->getFrameMoves();
EmitFrameMoves("func_begin", SubprogramCount, Moves);
EmitAlign(2);
EmitLabel("frame_end", SubprogramCount);
O << "\n";
}
/// EmitDebugPubNames - Emit visible names into a debug pubnames section. /// EmitDebugPubNames - Emit visible names into a debug pubnames section.
/// ///
void DwarfWriter::EmitDebugPubNames() { void DwarfWriter::EmitDebugPubNames() {
@ -2208,6 +2286,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
if (!didInitial) { if (!didInitial) {
EmitInitial(); EmitInitial();
// Emit common frame information.
EmitInitialDebugFrame();
// Create all the compile unit DIEs. // Create all the compile unit DIEs.
ConstructCompileUnitDIEs(); ConstructCompileUnitDIEs();
@ -2231,6 +2312,8 @@ bool DwarfWriter::ShouldEmitDwarf() {
DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A) DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
: O(OS) : O(OS)
, Asm(A) , Asm(A)
, TD(Asm->TM.getTargetData())
, RI(Asm->TM.getRegisterInfo())
, M(NULL) , M(NULL)
, MF(NULL) , MF(NULL)
, DebugInfo(NULL) , DebugInfo(NULL)
@ -2267,6 +2350,12 @@ DwarfWriter::~DwarfWriter() {
} }
} }
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
/// created it. Set by the target AsmPrinter.
void DwarfWriter::SetDebugInfo(MachineDebugInfo *DI) {
DebugInfo = DI;
}
/// BeginModule - Emit all Dwarf sections that should come prior to the content. /// BeginModule - Emit all Dwarf sections that should come prior to the content.
/// ///
void DwarfWriter::BeginModule(Module *M) { void DwarfWriter::BeginModule(Module *M) {
@ -2300,9 +2389,6 @@ void DwarfWriter::EndModule() {
// Emit source line correspondence into a debug line section. // Emit source line correspondence into a debug line section.
EmitDebugLines(); EmitDebugLines();
// Emit info into a debug frame section.
EmitDebugFrame();
// Emit info into a debug pubnames section. // Emit info into a debug pubnames section.
EmitDebugPubNames(); EmitDebugPubNames();
@ -2327,6 +2413,9 @@ void DwarfWriter::EndModule() {
void DwarfWriter::BeginFunction(MachineFunction *MF) { void DwarfWriter::BeginFunction(MachineFunction *MF) {
this->MF = MF; this->MF = MF;
// Begin accumulating function debug information.
DebugInfo->BeginFunction(MF);
if (!ShouldEmitDwarf()) return; if (!ShouldEmitDwarf()) return;
EOL("Dwarf Begin Function"); EOL("Dwarf Begin Function");
@ -2335,7 +2424,6 @@ void DwarfWriter::BeginFunction(MachineFunction *MF) {
EmitLabel("func_begin", ++SubprogramCount); EmitLabel("func_begin", ++SubprogramCount);
} }
/// EndFunction - Gather and emit post-function debug information. /// EndFunction - Gather and emit post-function debug information.
/// ///
void DwarfWriter::EndFunction() { void DwarfWriter::EndFunction() {
@ -2348,5 +2436,10 @@ void DwarfWriter::EndFunction() {
// Construct scopes for subprogram. // Construct scopes for subprogram.
ConstructRootScope(DebugInfo->getRootScope()); ConstructRootScope(DebugInfo->getRootScope());
DebugInfo->ClearScopes();
// Emit function frame information.
EmitFunctionDebugFrame();
// Clear function debug information.
DebugInfo->EndFunction();
} }

View File

@ -10,6 +10,7 @@
#include "llvm/CodeGen/MachineDebugInfo.h" #include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h" #include "llvm/Intrinsics.h"
@ -1424,9 +1425,8 @@ MachineDebugInfo::MachineDebugInfo()
, LabelID(0) , LabelID(0)
, ScopeMap() , ScopeMap()
, RootScope(NULL) , RootScope(NULL)
{ , FrameMoves()
{}
}
MachineDebugInfo::~MachineDebugInfo() { MachineDebugInfo::~MachineDebugInfo() {
} }
@ -1443,6 +1443,27 @@ bool MachineDebugInfo::doFinalization() {
return false; return false;
} }
/// BeginFunction - Begin gathering function debug information.
///
void MachineDebugInfo::BeginFunction(MachineFunction *MF) {
// Coming soon.
}
/// MachineDebugInfo::EndFunction - Discard function debug information.
///
void MachineDebugInfo::EndFunction() {
// Clean up scope information.
if (RootScope) {
delete RootScope;
ScopeMap.clear();
RootScope = NULL;
}
// Clean up frame info.
for (unsigned i = 0, N = FrameMoves.size(); i < N; ++i) delete FrameMoves[i];
FrameMoves.clear();
}
/// getDescFor - Convert a Value to a debug information descriptor. /// getDescFor - Convert a Value to a debug information descriptor.
/// ///
// FIXME - use new Value type when available. // FIXME - use new Value type when available.
@ -1565,14 +1586,4 @@ DebugScope *MachineDebugInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
return Slot; return Slot;
} }
/// ClearScopes - Delete the scope and variable info after a function is
/// completed.
void MachineDebugInfo::ClearScopes() {
if (RootScope) {
delete RootScope;
ScopeMap.clear();
RootScope = NULL;
}
}

View File

@ -36,6 +36,12 @@ namespace {
/// frame indexes with appropriate references. /// frame indexes with appropriate references.
/// ///
bool runOnMachineFunction(MachineFunction &Fn) { bool runOnMachineFunction(MachineFunction &Fn) {
// Get MachineDebugInfo so that we can track the construction of the
// frame.
if (MachineDebugInfo *DI = getAnalysisToUpdate<MachineDebugInfo>()) {
Fn.getFrameInfo()->setMachineDebugInfo(DI);
}
// Scan the function for modified caller saved registers and insert spill // Scan the function for modified caller saved registers and insert spill
// code for any caller saved registers that are modified. Also calculate // code for any caller saved registers that are modified. Also calculate
// the MaxCallFrameSize and HasCalls variables for the function's frame // the MaxCallFrameSize and HasCalls variables for the function's frame

View File

@ -354,8 +354,13 @@ void AlphaRegisterInfo::emitEpilogue(MachineFunction &MF,
} }
} }
unsigned AlphaRegisterInfo::getRARegister() const {
assert(0 && "What is the return address register");
return 0;
}
unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned AlphaRegisterInfo::getFrameRegister(MachineFunction &MF) const {
return getDwarfRegNum(hasFP(MF) ? Alpha::R15 : Alpha::R30); return hasFP(MF) ? Alpha::R15 : Alpha::R30;
} }
#include "AlphaGenRegisterInfo.inc" #include "AlphaGenRegisterInfo.inc"

View File

@ -53,7 +53,8 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
void emitPrologue(MachineFunction &MF) const; void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
static std::string getPrettyName(unsigned reg); static std::string getPrettyName(unsigned reg);

View File

@ -329,8 +329,13 @@ void IA64RegisterInfo::emitEpilogue(MachineFunction &MF,
} }
unsigned IA64RegisterInfo::getRARegister() const {
assert(0 && "What is the return address register");
return 0;
}
unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned IA64RegisterInfo::getFrameRegister(MachineFunction &MF) const {
return getDwarfRegNum(hasFP(MF) ? IA64::r5 : IA64::r12); return hasFP(MF) ? IA64::r5 : IA64::r12;
} }
#include "IA64GenRegisterInfo.inc" #include "IA64GenRegisterInfo.inc"

View File

@ -50,6 +50,7 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
}; };

View File

@ -44,6 +44,13 @@ std::vector<bool> MRegisterInfo::getAllocatableSet(MachineFunction &MF) const {
return Allocatable; return Allocatable;
} }
/// getStackDirection - This method should return the factor by which stacks
/// grow. The tyical value is -4 which is the grows negatively in 4 byte
/// increments.
int MRegisterInfo::getStackDirection() const {
return -sizeof(int32_t);
}
/// getLocation - This method should return the actual location of a frame /// getLocation - This method should return the actual location of a frame
/// variable given the frame index. The location is returned in ML. /// variable given the frame index. The location is returned in ML.
/// Subclasses should override this method for special handling of frame /// Subclasses should override this method for special handling of frame
@ -54,3 +61,11 @@ void MRegisterInfo::getLocation(MachineFunction &MF, unsigned Index,
ML.set(getFrameRegister(MF), ML.set(getFrameRegister(MF),
MFI->getObjectOffset(Index) + MFI->getStackSize()); MFI->getObjectOffset(Index) + MFI->getStackSize());
} }
/// getInitialFrameState - Returns a list of machine moves that are assumed
/// on entry to a function.
void
MRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves) const {
// Default is to do nothing.
}

View File

@ -19,9 +19,11 @@
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineLocation.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetOptions.h"
@ -339,6 +341,7 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin(); MachineBasicBlock::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo(); MachineFrameInfo *MFI = MF.getFrameInfo();
MachineDebugInfo *DebugInfo = MFI->getMachineDebugInfo();
// Do we have a frame pointer for this function? // Do we have a frame pointer for this function?
bool HasFP = hasFP(MF); bool HasFP = hasFP(MF);
@ -390,13 +393,13 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
// Update frame info to pretend that this is part of the stack... // Update frame info to pretend that this is part of the stack...
MFI->setStackSize(NumBytes); MFI->setStackSize(NumBytes);
int NegNumbytes = -NumBytes;
// Adjust stack pointer: r1 -= numbytes. // Adjust stack pointer: r1 -= numbytes.
if (NumBytes <= 32768) { if (NumBytes <= 32768) {
BuildMI(MBB, MBBI, PPC::STWU, 3) BuildMI(MBB, MBBI, PPC::STWU, 3)
.addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1); .addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
} else { } else {
int NegNumbytes = -NumBytes;
BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16); BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0) BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
.addReg(PPC::R0).addImm(NegNumbytes & 0xFFFF); .addReg(PPC::R0).addImm(NegNumbytes & 0xFFFF);
@ -404,6 +407,18 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
.addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0); .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
} }
if (DebugInfo) {
std::vector<MachineMove *> &Moves = DebugInfo->getFrameMoves();
unsigned LabelID = DebugInfo->NextLabelID();
// Show update of SP.
MachineLocation Dst(MachineLocation::VirtualFP);
MachineLocation Src(MachineLocation::VirtualFP, NegNumbytes);
Moves.push_back(new MachineMove(LabelID, Dst, Src));
BuildMI(MBB, MBBI, PPC::DWARF_LABEL, 1).addSImm(LabelID);
}
// If there is a preferred stack alignment, align R1 now // If there is a preferred stack alignment, align R1 now
// FIXME: If this ever matters, this could be made more efficient by folding // FIXME: If this ever matters, this could be made more efficient by folding
// this into the code above, so that we don't issue two store+update // this into the code above, so that we don't issue two store+update
@ -458,8 +473,20 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
} }
} }
unsigned PPCRegisterInfo::getRARegister() const {
return PPC::LR;
}
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
return getDwarfRegNum(hasFP(MF) ? PPC::R31 : PPC::R1); return hasFP(MF) ? PPC::R31 : PPC::R1;
}
void PPCRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves)
const {
// Initial state is the frame pointer is R1.
MachineLocation Dst(MachineLocation::VirtualFP);
MachineLocation Src(PPC::R1, 0);
Moves.push_back(new MachineMove(0, Dst, Src));
} }
#include "PPCGenRegisterInfo.inc" #include "PPCGenRegisterInfo.inc"

View File

@ -57,7 +57,9 @@ public:
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
void getInitialFrameState(std::vector<MachineMove *> &Moves) const;
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -200,8 +200,14 @@ void SparcRegisterInfo::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0); BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0);
} }
unsigned SparcRegisterInfo::getRARegister() const {
assert(0 && "What is the return address register");
return 0;
}
unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const {
return getDwarfRegNum(SP::G1); assert(0 && "What is the frame register");
return SP::G1;
} }
#include "SparcGenRegisterInfo.inc" #include "SparcGenRegisterInfo.inc"

View File

@ -58,6 +58,7 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
}; };

View File

@ -317,6 +317,15 @@ void SparcV9RegisterInfo::emitEpilogue(MachineFunction &MF,
abort (); abort ();
} }
int SparcV9RegisterInfo::getDwarfRegNum(unsigned RegNum) const {
abort ();
return 0;
}
unsigned SparcV9RegisterInfo::getRARegister() const {
abort ();
return 0;
}
unsigned SparcV9RegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned SparcV9RegisterInfo::getFrameRegister(MachineFunction &MF) const {
abort (); abort ();

View File

@ -46,6 +46,8 @@ struct SparcV9RegisterInfo : public MRegisterInfo {
void emitEpilogue (MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue (MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
int getDwarfRegNum(unsigned RegNum) const;
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
}; };

View File

@ -686,8 +686,12 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
} }
} }
unsigned X86RegisterInfo::getRARegister() const {
return X86::ST0; // use a non-register register
}
unsigned X86RegisterInfo::getFrameRegister(MachineFunction &MF) const { unsigned X86RegisterInfo::getFrameRegister(MachineFunction &MF) const {
return getDwarfRegNum(hasFP(MF) ? X86::EBP : X86::ESP); return hasFP(MF) ? X86::EBP : X86::ESP;
} }
#include "X86GenRegisterInfo.inc" #include "X86GenRegisterInfo.inc"

View File

@ -64,6 +64,7 @@ struct X86RegisterInfo : public X86GenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries. // Debug information queries.
unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const; unsigned getFrameRegister(MachineFunction &MF) const;
}; };