Foundation for call frame information.
authorJim Laskey <jlaskey@mac.com>
Fri, 7 Apr 2006 16:34:46 +0000 (16:34 +0000)
committerJim Laskey <jlaskey@mac.com>
Fri, 7 Apr 2006 16:34:46 +0000 (16:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27491 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
include/llvm/CodeGen/DwarfWriter.h
include/llvm/CodeGen/MachineDebugInfo.h
include/llvm/CodeGen/MachineFrameInfo.h
include/llvm/CodeGen/MachineLocation.h
include/llvm/Target/MRegisterInfo.h
lib/CodeGen/DwarfWriter.cpp
lib/CodeGen/MachineDebugInfo.cpp
lib/CodeGen/PrologEpilogInserter.cpp
lib/Target/Alpha/AlphaRegisterInfo.cpp
lib/Target/Alpha/AlphaRegisterInfo.h
lib/Target/IA64/IA64RegisterInfo.cpp
lib/Target/IA64/IA64RegisterInfo.h
lib/Target/MRegisterInfo.cpp
lib/Target/PowerPC/PPCRegisterInfo.cpp
lib/Target/PowerPC/PPCRegisterInfo.h
lib/Target/Sparc/SparcRegisterInfo.cpp
lib/Target/Sparc/SparcRegisterInfo.h
lib/Target/SparcV9/SparcV9RegisterInfo.cpp
lib/Target/SparcV9/SparcV9RegisterInfo.h
lib/Target/X86/X86RegisterInfo.cpp
lib/Target/X86/X86RegisterInfo.h

index 7ac5aa6ba465ac6fc34fc30246fb91d997738a58..34c69b907de8483660caac0a2f910cf6b9d6d321 100644 (file)
@@ -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.
index 2e20e94e78fcd64697b7005321c81ca84bfa7464..0a95f4b235ba7ad2eff273dbb405c360e26746bc 100644 (file)
@@ -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
 
index d6810bf4e5bad9375be1cb242dca7a86434d8a0e..baeb47c47dfb0194959ab4ac11b8230ebf069eca 100644 (file)
@@ -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
   ///
index 1756d325a299150883f2fceaa2480df29e8e8eac..ab6a82b14fc97e8b810de6207599ed496cd839e9 100644 (file)
@@ -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
index e69661b2282fa0365e3801f1f4bb6d8fe2745e36..00d9d6b39f90925b13717753d1e22e2920751ab6 100644 (file)
@@ -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
index 43fbb3b902fe949a7f34e2ac249575fd539282e2..19b1d8409c6190c9e3f0b97e54fcaafdb1d1cb1f 100644 (file)
@@ -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();
 }
index 9876e652a830750a703c05364466175855c634b2..2e7e8c0d9f12b4b72da54f5ab7f10eb9b85ab700 100644 (file)
@@ -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;
-  }
-}
-
 
index aabf78bd338775528b5ebd7961bdb5f3fa3277ae..114610bd253bdc14e8fbf5d2d7c8a5e25637cb38 100644 (file)
@@ -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
index d2a398465b0b5b045970dfa64a65d4d31ce3697b..8f6310e4398f69c1efb01c73fab6ca2421efe6a2 100644 (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 {
-  return getDwarfRegNum(hasFP(MF) ? Alpha::R15 : Alpha::R30);
+  return hasFP(MF) ? Alpha::R15 : Alpha::R30;
 }
 
 #include "AlphaGenRegisterInfo.inc"
index 161a8268568a1e6c87afa47327b6b77f2c88c090..d4d86f391631479160456b001ba1e4505b1dfbde 100644 (file)
@@ -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);
index b1e681d9b432cf28feacc8b5d44ff9813ce57107..e9a809f40752e01d71f54dbe38e68a5b73accd0a 100644 (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 {
-  return getDwarfRegNum(hasFP(MF) ? IA64::r5 : IA64::r12);
+  return hasFP(MF) ? IA64::r5 : IA64::r12;
 }
 
 #include "IA64GenRegisterInfo.inc"
index 328b415573709179a95b53173993f6626718db53..93d09deae921ed2287a09d869f98b09ed9c7bb90 100644 (file)
@@ -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;
 };
 
index 558783aedc4780c9f35b4a2c9090efa5d28bd72d..4ddfe9f323049a4fd5331e7eb071713bc4592c84 100644 (file)
@@ -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.
+}
+
index c3007c4aec08720113f166bf6694a4289461d475..67f5285b7d2cbd0eebed1d00ce62b9a55205878c 100644 (file)
 #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"
index d05bc70c11d04e0159aedf36bea319973281ec33..7fb0af295304c2fa857a8d4b3eb3517d951e0368 100644 (file)
@@ -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
index 44f3adce043372277e1dad47cb128cfd92930d65..75c3378cbb6281c152a509b7e4459e366a1a5132 100644 (file)
@@ -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"
index d36b3c1eed099ec0ded57899ab9dfeae707d31a6..176e93491b08fa8442928fa69c9f2598e5c38256 100644 (file)
@@ -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;
 };
 
index 267d69a4f76d2ae56da0410bda26c43f5a956527..a49525b46e484b98c1d1204a7bc9f983e982156d 100644 (file)
@@ -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 ();
index 6de47cbb6296fbcffc00061fdba70181c5c47936..c9570d3a9335900ded5438285cabd7c363e6554d 100644 (file)
@@ -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;
 };
 
index 08dea90ddd070b21988e42b176059fa1406aac03..647f3886b92b59e4c93581dcd3791f536f260526 100644 (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 {
-  return getDwarfRegNum(hasFP(MF) ? X86::EBP : X86::ESP);
+  return hasFP(MF) ? X86::EBP : X86::ESP;
 }
 
 #include "X86GenRegisterInfo.inc"
index 998fb398d911fa4e345ee0e34981fdab49da51aa..1cfd2730d866155edd7cd8dc1a083912c6beafba 100644 (file)
@@ -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;
 };