summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Laskey <jlaskey@mac.com>2006-04-07 16:34:46 +0000
committerJim Laskey <jlaskey@mac.com>2006-04-07 16:34:46 +0000
commit4188699f80c233a20b6ddc61570a8a8c1804cb85 (patch)
treea711460fdce84b3c1fdd9c1dcce8be21fef48786
parent38ab6d887c660c7e2fe08707e8f982ab451fb224 (diff)
downloadllvm-4188699f80c233a20b6ddc61570a8a8c1804cb85.tar.gz
llvm-4188699f80c233a20b6ddc61570a8a8c1804cb85.tar.bz2
llvm-4188699f80c233a20b6ddc61570a8a8c1804cb85.tar.xz
Foundation for call frame information.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27491 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h31
-rw-r--r--include/llvm/CodeGen/MachineDebugInfo.h24
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h18
-rw-r--r--include/llvm/CodeGen/MachineLocation.h40
-rw-r--r--include/llvm/Target/MRegisterInfo.h22
-rw-r--r--lib/CodeGen/DwarfWriter.cpp153
-rw-r--r--lib/CodeGen/MachineDebugInfo.cpp37
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp6
-rw-r--r--lib/Target/Alpha/AlphaRegisterInfo.cpp7
-rw-r--r--lib/Target/Alpha/AlphaRegisterInfo.h3
-rw-r--r--lib/Target/IA64/IA64RegisterInfo.cpp7
-rw-r--r--lib/Target/IA64/IA64RegisterInfo.h1
-rw-r--r--lib/Target/MRegisterInfo.cpp15
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp31
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.h2
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.cpp8
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.h1
-rw-r--r--lib/Target/SparcV9/SparcV9RegisterInfo.cpp9
-rw-r--r--lib/Target/SparcV9/SparcV9RegisterInfo.h2
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp6
-rw-r--r--lib/Target/X86/X86RegisterInfo.h1
21 files changed, 359 insertions, 65 deletions
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 7ac5aa6ba4..34c69b907d 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -41,10 +41,13 @@ class DIE;
class DIEAbbrev;
class GlobalVariableDesc;
class MachineDebugInfo;
-class MachineLocation;
class MachineFunction;
+class MachineLocation;
+class MachineMove;
class Module;
+class MRegisterInfo;
class SubprogramDesc;
+class TargetData;
class Type;
class TypeDesc;
@@ -81,6 +84,12 @@ protected:
///
AsmPrinter *Asm;
+ /// TD - Target data.
+ const TargetData &TD;
+
+ /// RI - Register Information.
+ const MRegisterInfo *RI;
+
/// M - Current module.
///
Module *M;
@@ -324,7 +333,8 @@ private:
/// AddAddress - Add an address attribute to a die based on the location
/// provided.
- void AddAddress(DIE *Die, unsigned Attribute, MachineLocation &Location);
+ void AddAddress(DIE *Die, unsigned Attribute,
+ const MachineLocation &Location);
/// NewType - Create a new type DIE.
///
@@ -375,6 +385,11 @@ private:
///
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.
///
void EmitDebugInfo() const;
@@ -387,10 +402,14 @@ private:
///
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.
///
void EmitDebugPubNames();
@@ -439,7 +458,7 @@ public:
/// SetDebugInfo - Set DebugInfo when it's known that pass manager has
/// created it. Set by the target AsmPrinter.
- void SetDebugInfo(MachineDebugInfo *DI) { DebugInfo = DI; }
+ void SetDebugInfo(MachineDebugInfo *DI);
//===--------------------------------------------------------------------===//
// Main entry points.
diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h
index 2e20e94e78..0a95f4b235 100644
--- a/include/llvm/CodeGen/MachineDebugInfo.h
+++ b/include/llvm/CodeGen/MachineDebugInfo.h
@@ -47,6 +47,8 @@ namespace llvm {
class Constant;
class DebugInfoDesc;
class GlobalVariable;
+class MachineFunction;
+class MachineMove;
class Module;
class PointerType;
class StructType;
@@ -574,7 +576,7 @@ public:
void setName(const std::string &N) { Name = N; }
void setFile(CompileUnitDesc *U) { File = U; }
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 setIsDefinition(bool ID) { IsDefinition = ID; }
@@ -940,6 +942,10 @@ private:
// RootScope - Top level scope for the current function.
//
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:
MachineDebugInfo();
@@ -953,6 +959,14 @@ public:
///
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.
///
// FIXME - use new Value type when available.
@@ -1060,10 +1074,10 @@ public:
/// getOrCreateScope - Returns the scope associated with the given descriptor.
///
DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
-
- /// ClearScopes - Delete the scope and variable info after a function is
- /// completed.
- void ClearScopes();
+
+ /// getFrameMoves - Returns a reference to a list of moves done in the current
+ /// function's prologue. Used to construct frame maps for debug comsumers.
+ std::vector<MachineMove *> &getFrameMoves() { return FrameMoves; }
}; // End class MachineDebugInfo
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
index d6810bf4e5..baeb47c47d 100644
--- a/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -44,6 +44,7 @@ namespace llvm {
class TargetData;
class TargetRegisterClass;
class Type;
+class MachineDebugInfo;
class MachineFunction;
class MachineFrameInfo {
@@ -106,12 +107,21 @@ class MachineFrameInfo {
/// insertion.
///
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:
MachineFrameInfo() {
NumFixedObjects = StackSize = MaxAlignment = 0;
HasVarSizedObjects = false;
HasCalls = false;
MaxCallFrameSize = 0;
+ DebugInfo = 0;
}
/// hasStackObjects - Return true if there are any stack objects in this
@@ -230,6 +240,14 @@ public:
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
/// stack objects. Implemented in MachineFunction.cpp
///
diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/CodeGen/MachineLocation.h
index 1756d325a2..ab6a82b14f 100644
--- a/include/llvm/CodeGen/MachineLocation.h
+++ b/include/llvm/CodeGen/MachineLocation.h
@@ -8,7 +8,13 @@
//===----------------------------------------------------------------------===//
// 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
-// 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.
public:
+ enum {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value greater than MRegisterInfo::FirstVirtualRegister.
+ VirtualFP = ~0U
+ };
MachineLocation()
: IsRegister(false)
, Register(0)
@@ -37,7 +48,7 @@ public:
MachineLocation(unsigned R, int O)
: IsRegister(false)
, Register(R)
- , Offset(0)
+ , Offset(O)
{}
// Accessors
@@ -57,6 +68,31 @@ public:
Register = R;
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
diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h
index e69661b228..00d9d6b39f 100644
--- a/include/llvm/Target/MRegisterInfo.h
+++ b/include/llvm/Target/MRegisterInfo.h
@@ -27,6 +27,7 @@ class Type;
class MachineFunction;
class MachineInstr;
class MachineLocation;
+class MachineMove;
class TargetRegisterClass;
/// TargetRegisterDesc - This record contains all of the information known about
@@ -345,18 +346,35 @@ public:
//===--------------------------------------------------------------------===//
/// 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
- /// for values allocated in the current stack frame. This value should be
- /// returned as a dwarf register number (getDwarfRegNum.)
+ /// for values allocated in the current stack frame.
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
/// variable given the frame index. The location is returned in ML.
/// Subclasses should override this method for special handling of frame
/// variables and call MRegisterInfo::getLocation for the default action.
virtual void getLocation(MachineFunction &MF, unsigned Index,
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
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index 43fbb3b902..19b1d8409c 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -18,6 +18,7 @@
#include "llvm/Type.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineDebugInfo.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/CommandLine.h"
@@ -1073,8 +1074,6 @@ void DwarfWriter::EmitInt64(uint64_t Value) const {
if (Asm->Data64bitsDirective) {
O << Asm->Data64bitsDirective << "0x" << std::hex << Value << std::dec;
} else {
- const TargetData &TD = Asm->TM.getTargetData();
-
if (TD.isBigEndian()) {
EmitInt32(unsigned(Value >> 32)); O << "\n";
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
/// provided.
void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute,
- MachineLocation &Location) {
+ const MachineLocation &Location) {
DIEBlock *Block = new DIEBlock();
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 {
- 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->ComputeSize(*this);
@@ -1358,8 +1359,7 @@ DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) {
// Now normalize offset to the field.
Offset -= FieldOffset;
- // Maybe we need to work from the other.
- const TargetData &TD = Asm->TM.getTargetData();
+ // Maybe we need to work from the other end.
if (TD.isLittleEndian()) Offset = FieldSize - (Offset + Size);
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);
SubprogramDie->AddString (DW_AT_name, DW_FORM_string, Name);
- SubprogramDie->AddDIEntry (DW_AT_type, DW_FORM_ref4, Type);
- SubprogramDie->AddUInt (DW_AT_external, DW_FORM_flag, IsExternal);
+ if (Type) {
+ 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.
AddSourceLine(SubprogramDie, UnitDesc, SPD->getLine());
@@ -1561,7 +1564,7 @@ DIE *DwarfWriter::NewScopeVariable(DebugVariable *DV, CompileUnit *Unit) {
// Add variable address.
MachineLocation Location;
- Asm->TM.getRegisterInfo()->getLocation(*MF, DV->getFrameIndex(), Location);
+ RI->getLocation(*MF, DV->getFrameIndex(), Location);
AddAddress(VariableDie, DW_AT_location, Location);
return VariableDie;
@@ -1621,18 +1624,20 @@ void DwarfWriter::ConstructRootScope(DebugScope *RootScope) {
// Get the compile unit context.
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.
DIE *SPDie = Unit->getDieMapSlotFor(SPD);
assert(SPDie && "Missing subprogram descriptor");
// Add the function bounds.
- SPDie->AddLabel(DW_AT_low_pc, DW_FORM_addr,
- DWLabel("func_begin", SubprogramCount));
+ SPDie->AddObjectLabel(DW_AT_low_pc, DW_FORM_addr, MangledName);
SPDie->AddLabel(DW_AT_high_pc, DW_FORM_addr,
DWLabel("func_end", SubprogramCount));
- MachineLocation Location(Asm->TM.getRegisterInfo()->getFrameRegister(*MF));
+ MachineLocation Location(RI->getFrameRegister(*MF));
AddAddress(SPDie, DW_AT_frame_base, Location);
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.
///
void DwarfWriter::EmitDebugInfo() const {
@@ -1999,10 +2048,10 @@ void DwarfWriter::EmitDebugLines() const {
O << "\n";
}
-/// EmitDebugFrame - Emit visible names into a debug frame section.
+/// EmitInitialDebugFrame - Emit common frame info into a debug frame section.
///
-void DwarfWriter::EmitDebugFrame() {
- // Start the dwarf pubnames section.
+void DwarfWriter::EmitInitialDebugFrame() {
+ // Start the dwarf frame section.
Asm->SwitchSection(DwarfFrameSection, 0);
EmitDifference("frame_common_end", 0,
@@ -2014,20 +2063,49 @@ void DwarfWriter::EmitDebugFrame() {
EmitInt8(DW_CIE_VERSION); EOL("CIE Version");
EmitString(""); EOL("CIE Augmentation");
EmitULEB128Bytes(1); EOL("CIE Code Alignment Factor");
- // FIXME - needs to change based on stack direction.
- EmitSLEB128Bytes(-sizeof(int32_t)); EOL("CIE Data Alignment Factor");
- // FIXME - hard coded for PPC (LR).
- EmitInt8(0x41); EOL("CIE RA Column Hardcoded (PPC LR)");
- // FIXME - hard coded for PPC 0(SP).
- EmitULEB128Bytes(DW_CFA_def_cfa); EOL("DW_CFA_def_cfa");
- EmitULEB128Bytes(1); EOL("PPC Register SP");
- EmitULEB128Bytes(0); EOL("PPC offset 0 as in 0(SP)");
+ EmitSLEB128Bytes(RI->getStackDirection()); EOL("CIE Data Alignment Factor");
+ EmitInt8(RI->getDwarfRegNum(RI->getRARegister())); EOL("CIE RA Column");
+
+ std::vector<MachineMove *> Moves;
+ RI->getInitialFrameState(Moves);
+ EmitFrameMoves(NULL, 0, Moves);
+ for (unsigned i = 0, N = Moves.size(); i < N; ++i) delete Moves[i];
+
EmitAlign(2);
EmitLabel("frame_common_end", 0);
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.
///
void DwarfWriter::EmitDebugPubNames() {
@@ -2208,6 +2286,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
if (!didInitial) {
EmitInitial();
+ // Emit common frame information.
+ EmitInitialDebugFrame();
+
// Create all the compile unit DIEs.
ConstructCompileUnitDIEs();
@@ -2231,6 +2312,8 @@ bool DwarfWriter::ShouldEmitDwarf() {
DwarfWriter::DwarfWriter(std::ostream &OS, AsmPrinter *A)
: O(OS)
, Asm(A)
+, TD(Asm->TM.getTargetData())
+, RI(Asm->TM.getRegisterInfo())
, M(NULL)
, MF(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.
///
void DwarfWriter::BeginModule(Module *M) {
@@ -2300,9 +2389,6 @@ void DwarfWriter::EndModule() {
// Emit source line correspondence into a debug line section.
EmitDebugLines();
- // Emit info into a debug frame section.
- EmitDebugFrame();
-
// Emit info into a debug pubnames section.
EmitDebugPubNames();
@@ -2327,6 +2413,9 @@ void DwarfWriter::EndModule() {
void DwarfWriter::BeginFunction(MachineFunction *MF) {
this->MF = MF;
+ // Begin accumulating function debug information.
+ DebugInfo->BeginFunction(MF);
+
if (!ShouldEmitDwarf()) return;
EOL("Dwarf Begin Function");
@@ -2335,7 +2424,6 @@ void DwarfWriter::BeginFunction(MachineFunction *MF) {
EmitLabel("func_begin", ++SubprogramCount);
}
-
/// EndFunction - Gather and emit post-function debug information.
///
void DwarfWriter::EndFunction() {
@@ -2348,5 +2436,10 @@ void DwarfWriter::EndFunction() {
// Construct scopes for subprogram.
ConstructRootScope(DebugInfo->getRootScope());
- DebugInfo->ClearScopes();
+
+ // Emit function frame information.
+ EmitFunctionDebugFrame();
+
+ // Clear function debug information.
+ DebugInfo->EndFunction();
}
diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp
index 9876e652a8..2e7e8c0d9f 100644
--- a/lib/CodeGen/MachineDebugInfo.cpp
+++ b/lib/CodeGen/MachineDebugInfo.cpp
@@ -10,6 +10,7 @@
#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/Constants.h"
+#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Intrinsics.h"
@@ -1424,9 +1425,8 @@ MachineDebugInfo::MachineDebugInfo()
, LabelID(0)
, ScopeMap()
, RootScope(NULL)
-{
-
-}
+, FrameMoves()
+{}
MachineDebugInfo::~MachineDebugInfo() {
}
@@ -1443,6 +1443,27 @@ bool MachineDebugInfo::doFinalization() {
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.
///
// FIXME - use new Value type when available.
@@ -1565,14 +1586,4 @@ DebugScope *MachineDebugInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
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;
- }
-}
-
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index aabf78bd33..114610bd25 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -36,6 +36,12 @@ namespace {
/// frame indexes with appropriate references.
///
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
// code for any caller saved registers that are modified. Also calculate
// the MaxCallFrameSize and HasCalls variables for the function's frame
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.cpp b/lib/Target/Alpha/AlphaRegisterInfo.cpp
index d2a398465b..8f6310e439 100644
--- a/lib/Target/Alpha/AlphaRegisterInfo.cpp
+++ b/lib/Target/Alpha/AlphaRegisterInfo.cpp
@@ -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 {
- return getDwarfRegNum(hasFP(MF) ? Alpha::R15 : Alpha::R30);
+ return hasFP(MF) ? Alpha::R15 : Alpha::R30;
}
#include "AlphaGenRegisterInfo.inc"
diff --git a/lib/Target/Alpha/AlphaRegisterInfo.h b/lib/Target/Alpha/AlphaRegisterInfo.h
index 161a826856..d4d86f3916 100644
--- a/lib/Target/Alpha/AlphaRegisterInfo.h
+++ b/lib/Target/Alpha/AlphaRegisterInfo.h
@@ -53,7 +53,8 @@ struct AlphaRegisterInfo : public AlphaGenRegisterInfo {
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
- // Debug information queries.
+ // Debug information queries.
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
static std::string getPrettyName(unsigned reg);
diff --git a/lib/Target/IA64/IA64RegisterInfo.cpp b/lib/Target/IA64/IA64RegisterInfo.cpp
index b1e681d9b4..e9a809f407 100644
--- a/lib/Target/IA64/IA64RegisterInfo.cpp
+++ b/lib/Target/IA64/IA64RegisterInfo.cpp
@@ -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 {
- return getDwarfRegNum(hasFP(MF) ? IA64::r5 : IA64::r12);
+ return hasFP(MF) ? IA64::r5 : IA64::r12;
}
#include "IA64GenRegisterInfo.inc"
diff --git a/lib/Target/IA64/IA64RegisterInfo.h b/lib/Target/IA64/IA64RegisterInfo.h
index 328b415573..93d09deae9 100644
--- a/lib/Target/IA64/IA64RegisterInfo.h
+++ b/lib/Target/IA64/IA64RegisterInfo.h
@@ -50,6 +50,7 @@ struct IA64RegisterInfo : public IA64GenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
};
diff --git a/lib/Target/MRegisterInfo.cpp b/lib/Target/MRegisterInfo.cpp
index 558783aedc..4ddfe9f323 100644
--- a/lib/Target/MRegisterInfo.cpp
+++ b/lib/Target/MRegisterInfo.cpp
@@ -44,6 +44,13 @@ std::vector<bool> MRegisterInfo::getAllocatableSet(MachineFunction &MF) const {
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
/// variable given the frame index. The location is returned in ML.
/// 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),
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.
+}
+
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index c3007c4aec..67f5285b7d 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -19,9 +19,11 @@
#include "llvm/Type.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineDebugInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetMachine.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::iterator MBBI = MBB.begin();
MachineFrameInfo *MFI = MF.getFrameInfo();
+ MachineDebugInfo *DebugInfo = MFI->getMachineDebugInfo();
// Do we have a frame pointer for this function?
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...
MFI->setStackSize(NumBytes);
+ int NegNumbytes = -NumBytes;
// Adjust stack pointer: r1 -= numbytes.
if (NumBytes <= 32768) {
BuildMI(MBB, MBBI, PPC::STWU, 3)
.addReg(PPC::R1).addSImm(-NumBytes).addReg(PPC::R1);
} else {
- int NegNumbytes = -NumBytes;
BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addSImm(NegNumbytes >> 16);
BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0)
.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);
}
+ 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
// 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
@@ -458,8 +473,20 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
}
}
+unsigned PPCRegisterInfo::getRARegister() const {
+ return PPC::LR;
+}
+
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"
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h
index d05bc70c11..7fb0af2953 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.h
+++ b/lib/Target/PowerPC/PPCRegisterInfo.h
@@ -57,7 +57,9 @@ public:
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
+ void getInitialFrameState(std::vector<MachineMove *> &Moves) const;
};
} // end namespace llvm
diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp
index 44f3adce04..75c3378cbb 100644
--- a/lib/Target/Sparc/SparcRegisterInfo.cpp
+++ b/lib/Target/Sparc/SparcRegisterInfo.cpp
@@ -200,8 +200,14 @@ void SparcRegisterInfo::emitEpilogue(MachineFunction &MF,
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 {
- return getDwarfRegNum(SP::G1);
+ assert(0 && "What is the frame register");
+ return SP::G1;
}
#include "SparcGenRegisterInfo.inc"
diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h
index d36b3c1eed..176e93491b 100644
--- a/lib/Target/Sparc/SparcRegisterInfo.h
+++ b/lib/Target/Sparc/SparcRegisterInfo.h
@@ -58,6 +58,7 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
};
diff --git a/lib/Target/SparcV9/SparcV9RegisterInfo.cpp b/lib/Target/SparcV9/SparcV9RegisterInfo.cpp
index 267d69a4f7..a49525b46e 100644
--- a/lib/Target/SparcV9/SparcV9RegisterInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9RegisterInfo.cpp
@@ -317,6 +317,15 @@ void SparcV9RegisterInfo::emitEpilogue(MachineFunction &MF,
abort ();
}
+int SparcV9RegisterInfo::getDwarfRegNum(unsigned RegNum) const {
+ abort ();
+ return 0;
+}
+
+unsigned SparcV9RegisterInfo::getRARegister() const {
+ abort ();
+ return 0;
+}
unsigned SparcV9RegisterInfo::getFrameRegister(MachineFunction &MF) const {
abort ();
diff --git a/lib/Target/SparcV9/SparcV9RegisterInfo.h b/lib/Target/SparcV9/SparcV9RegisterInfo.h
index 6de47cbb62..c9570d3a93 100644
--- a/lib/Target/SparcV9/SparcV9RegisterInfo.h
+++ b/lib/Target/SparcV9/SparcV9RegisterInfo.h
@@ -46,6 +46,8 @@ struct SparcV9RegisterInfo : public MRegisterInfo {
void emitEpilogue (MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
+ int getDwarfRegNum(unsigned RegNum) const;
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
};
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 08dea90ddd..647f3886b9 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -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 {
- return getDwarfRegNum(hasFP(MF) ? X86::EBP : X86::ESP);
+ return hasFP(MF) ? X86::EBP : X86::ESP;
}
#include "X86GenRegisterInfo.inc"
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index 998fb398d9..1cfd2730d8 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -64,6 +64,7 @@ struct X86RegisterInfo : public X86GenRegisterInfo {
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
// Debug information queries.
+ unsigned getRARegister() const;
unsigned getFrameRegister(MachineFunction &MF) const;
};