From 4188699f80c233a20b6ddc61570a8a8c1804cb85 Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Fri, 7 Apr 2006 16:34:46 +0000 Subject: [PATCH] Foundation for call frame information. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27491 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/DwarfWriter.h | 31 ++++- include/llvm/CodeGen/MachineDebugInfo.h | 24 +++- include/llvm/CodeGen/MachineFrameInfo.h | 18 +++ include/llvm/CodeGen/MachineLocation.h | 40 +++++- include/llvm/Target/MRegisterInfo.h | 22 ++- lib/CodeGen/DwarfWriter.cpp | 153 +++++++++++++++++---- lib/CodeGen/MachineDebugInfo.cpp | 37 +++-- lib/CodeGen/PrologEpilogInserter.cpp | 6 + lib/Target/Alpha/AlphaRegisterInfo.cpp | 7 +- lib/Target/Alpha/AlphaRegisterInfo.h | 3 +- lib/Target/IA64/IA64RegisterInfo.cpp | 7 +- lib/Target/IA64/IA64RegisterInfo.h | 1 + lib/Target/MRegisterInfo.cpp | 15 ++ lib/Target/PowerPC/PPCRegisterInfo.cpp | 31 ++++- lib/Target/PowerPC/PPCRegisterInfo.h | 2 + lib/Target/Sparc/SparcRegisterInfo.cpp | 8 +- lib/Target/Sparc/SparcRegisterInfo.h | 1 + lib/Target/SparcV9/SparcV9RegisterInfo.cpp | 9 ++ lib/Target/SparcV9/SparcV9RegisterInfo.h | 2 + lib/Target/X86/X86RegisterInfo.cpp | 6 +- lib/Target/X86/X86RegisterInfo.h | 1 + 21 files changed, 359 insertions(+), 65 deletions(-) diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h index 7ac5aa6ba46..34c69b907de 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 &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 2e20e94e78f..0a95f4b235b 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 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 &getFrameMoves() { return FrameMoves; } }; // End class MachineDebugInfo diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index d6810bf4e5b..baeb47c47df 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 1756d325a29..ab6a82b14fc 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 e69661b2282..00d9d6b39f9 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 &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 43fbb3b902f..19b1d8409c6 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(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 &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 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 &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 9876e652a83..2e7e8c0d9f1 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 aabf78bd338..114610bd253 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()) { + 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 d2a398465b0..8f6310e4398 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 161a8268568..d4d86f39163 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 b1e681d9b43..e9a809f4075 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 328b4155737..93d09deae92 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 558783aedc4..4ddfe9f3230 100644 --- a/lib/Target/MRegisterInfo.cpp +++ b/lib/Target/MRegisterInfo.cpp @@ -44,6 +44,13 @@ std::vector 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 &Moves) const { + // Default is to do nothing. +} + diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index c3007c4aec0..67f5285b7d2 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 &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 &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 d05bc70c11d..7fb0af29530 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 &Moves) const; }; } // end namespace llvm diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp index 44f3adce043..75c3378cbb6 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 d36b3c1eed0..176e93491b0 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 267d69a4f76..a49525b46e4 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 6de47cbb629..c9570d3a933 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 08dea90ddd0..647f3886b92 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 998fb398d91..1cfd2730d86 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; };