1. Add a pass to fold debug label instructions so a debug info client can detect
authorJim Laskey <jlaskey@mac.com>
Tue, 7 Nov 2006 19:33:46 +0000 (19:33 +0000)
committerJim Laskey <jlaskey@mac.com>
Tue, 7 Nov 2006 19:33:46 +0000 (19:33 +0000)
empty ranges.

2. Reorg how MachineDebugInfo maintains changes to debug labels.

3. Have dwarf writer use debug label info to simplify scopes and source line
coorespondence.

4. Revert the merging of compile units until I can get the bugs ironed out.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31507 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineDebugInfo.h
include/llvm/CodeGen/Passes.h
lib/CodeGen/DwarfWriter.cpp
lib/CodeGen/LLVMTargetMachine.cpp
lib/CodeGen/MachineDebugInfo.cpp

index 39b2464072333df6c276ea8ed0b98672887aafb2..7b6386730b7c06a2f367a060b77ffbfb8e194ecc 100644 (file)
@@ -969,8 +969,11 @@ private:
   // Lines - List of of source line correspondence.
   std::vector<SourceLineInfo> Lines;
   
-  // LabelID - Current number assigned to unique label numbers.
-  unsigned LabelID;
+  // LabelIDList - One entry per assigned label.  Normally the entry is equal to
+  // the list index(+1).  If the entry is zero then the label has been deleted.
+  // Any other value indicates the label has been deleted by is mapped to
+  // another label.
+  std::vector<unsigned> LabelIDList;
   
   // ScopeMap - Tracks the scopes in the current function.
   std::map<DebugInfoDesc *, DebugScope *> ScopeMap;
@@ -979,10 +982,6 @@ private:
   //
   DebugScope *RootScope;
   
-  // DeletedLabelIDs - Sorted list of label IDs that have been removed from the
-  // module.
-  std::vector<unsigned> DeletedLabelIDs;
-  
   // FrameMoves - List of moves done by a function's prolog.  Used to construct
   // frame maps by debug consumers.
   std::vector<MachineMove *> FrameMoves;
@@ -1026,7 +1025,11 @@ public:
   
   /// NextLabelID - Return the next unique label id.
   ///
-  unsigned NextLabelID() { return ++LabelID; }
+  unsigned NextLabelID() {
+    unsigned ID = LabelIDList.size() + 1;
+    LabelIDList.push_back(ID);
+    return ID;
+  }
   
   /// RecordLabel - Records location information and associates it with a
   /// debug label.  Returns a unique label ID used to generate a label and 
@@ -1035,11 +1038,22 @@ public:
   
   /// InvalidateLabel - Inhibit use of the specified label # from
   /// MachineDebugInfo, for example because the code was deleted.
-  void InvalidateLabel(unsigned LabelID);
+  void InvalidateLabel(unsigned LabelID) {
+    // Remap to zero to indicate deletion.
+    RemapLabel(LabelID, 0);
+  }
+
+  /// RemapLabel - Indicate that a label has been merged into another.
+  ///
+  void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
+    LabelIDList[OldLabelID - 1] = NewLabelID;
+  }
   
-  /// isLabelValid - Check to make sure the label is still valid before
-  /// attempting to use.
-  bool isLabelValid(unsigned LabelID);
+  /// MappedLabel - Find out the label's final ID.  Zero indicates deletion.
+  /// ID != Mapped ID indicates that the label was folded into another label.
+  unsigned MappedLabel(unsigned LabelID) const {
+    return LabelIDList[LabelID - 1];
+  }
 
   /// RecordSource - Register a source file with debug info. Returns an source
   /// ID.
index 642039817f392603fc72389772a71705c1c15b74..adccf531eb2219072c5b1cbb10de2a2937bda5a3 100644 (file)
@@ -81,6 +81,11 @@ namespace llvm {
   /// branches.
   FunctionPass *createBranchFoldingPass();
 
+  /// DebugLabelFoldingPass - This pass prunes out redundant debug labels.  This
+  /// allows a debug emitter to determine if the range of two labels is empty,
+  /// by seeing if the labels map to the same reduced label.
+  FunctionPass *createDebugLabelFoldingPass();
+
   /// MachineCodeDeletion Pass - This pass deletes all of the machine code for
   /// the current function, which should happen after the function has been
   /// emitted to a .s file or to memory.
index 81c8963e16d64acef682409248b3c9578e13c49f..c8a1333d6c4dfc0c0da7919aff7e67551b09d1cf 100644 (file)
@@ -1695,15 +1695,18 @@ private:
     return Unit;
   }
 
+  /// GetBaseCompileUnit - Get the main compile unit.
+  ///
+  CompileUnit *GetBaseCompileUnit() const {
+    CompileUnit *Unit = CompileUnits[0];
+    assert(Unit && "Missing compile unit.");
+    return Unit;
+  }
+
   /// FindCompileUnit - Get the compile unit for the given descriptor.
   ///
   CompileUnit *FindCompileUnit(CompileUnitDesc *UnitDesc) {
-#if 1
-    // FIXME - Using only one compile unit.  Needs to me fixed at the FE.
-    CompileUnit *Unit = CompileUnits[0];
-#else
     CompileUnit *Unit = DescToUnitMap[UnitDesc];
-#endif
     assert(Unit && "Missing compile unit.");
     return Unit;
   }
@@ -1859,13 +1862,12 @@ private:
       // FIXME - Ignore inlined functions for the time being.
       if (!Scope->getParent()) continue;
       
-      unsigned StartID = Scope->getStartLabelID();
-      unsigned EndID = Scope->getEndLabelID();
+      unsigned StartID = DebugInfo->MappedLabel(Scope->getStartLabelID());
+      unsigned EndID = DebugInfo->MappedLabel(Scope->getEndLabelID());
       
-      // Widen scope if label is discarded.
-      // FIXME - really need to find a GOOD label if a block is dead.
-      if (StartID && !DebugInfo->isLabelValid(StartID)) StartID = 0;
-      if (EndID && !DebugInfo->isLabelValid(EndID)) EndID = 0;
+      // Ignore empty scopes.
+      if (StartID == EndID && StartID != 0) continue;
+      if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue;
       
       DIE *ScopeDie = new DIE(DW_TAG_lexical_block);
       
@@ -2084,10 +2086,10 @@ private:
                                    std::vector<MachineMove *> &Moves) {
     for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
       MachineMove *Move = Moves[i];
-      unsigned LabelID = Move->getLabelID();
+      unsigned LabelID = DebugInfo->MappedLabel(Move->getLabelID());
       
       // Throw out move if the label is invalid.
-      if (LabelID && !DebugInfo->isLabelValid(LabelID)) continue;
+      if (!LabelID) continue;
       
       const MachineLocation &Dst = Move->getDestination();
       const MachineLocation &Src = Move->getSource();
@@ -2307,9 +2309,8 @@ private:
       // Construct rows of the address, source, line, column matrix.
       for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
         const SourceLineInfo &LineInfo = LineInfos[i];
-        unsigned LabelID = LineInfo.getLabelID();
-        
-        // Source line labels are validated at the MachineDebugInfo level.
+        unsigned LabelID = DebugInfo->MappedLabel(LineInfo.getLabelID());
+        if (!LabelID) continue;
         
         if (DwarfVerbose) {
           unsigned SourceID = LineInfo.getSourceID();
@@ -2420,6 +2421,7 @@ private:
   void EmitFunctionDebugFrame() {
     if (!TAI->getDwarfRequiresFrameSection())
       return;
+       
     // Start the dwarf frame section.
     Asm->SwitchToDataSection(TAI->getDwarfFrameSection());
     
@@ -2588,7 +2590,8 @@ private:
     const UniqueVector<CompileUnitDesc *> CUW = DebugInfo->getCompileUnits();
     
     for (unsigned i = 1, N = CUW.size(); i <= N; ++i) {
-      CompileUnit *Unit = NewCompileUnit(CUW[i], i);
+      unsigned ID = DebugInfo->RecordSource(CUW[i]);
+      CompileUnit *Unit = NewCompileUnit(CUW[i], ID);
       CompileUnits.push_back(Unit);
     }
   }
index b12634ae28138cb2be133adf97bdf49c227a7e67..ae13625c20529382bad919dafa869dc69a2cbb9e 100644 (file)
@@ -66,6 +66,9 @@ bool LLVMTargetMachine::addPassesToEmitFile(FunctionPassManager &PM,
   // Branch folding must be run after regalloc and prolog/epilog insertion.
   if (!Fast)
     PM.add(createBranchFoldingPass());
+    
+  // Fold redundant debug labels.
+  PM.add(createDebugLabelFoldingPass());
   
   if (PrintMachineCode)  // Print the register-allocated code
     PM.add(createMachineFunctionPrinterPass(&std::cerr));
index 490e48d926259d6d657987bc9137256d061a32ea..bdbdd144fd7d16c67bcf807cbab4e7cf1b42003b 100644 (file)
 #include "llvm/CodeGen/MachineDebugInfo.h"
 
 #include "llvm/Constants.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Intrinsics.h"
@@ -1448,10 +1452,9 @@ MachineDebugInfo::MachineDebugInfo()
 , Directories()
 , SourceFiles()
 , Lines()
-, LabelID(0)
+, LabelIDList()
 , ScopeMap()
 , RootScope(NULL)
-, DeletedLabelIDs()
 , FrameMoves()
 {}
 MachineDebugInfo::~MachineDebugInfo() {
@@ -1544,35 +1547,6 @@ unsigned MachineDebugInfo::RecordLabel(unsigned Line, unsigned Column,
   return ID;
 }
 
-static bool LabelUIDComparison(const SourceLineInfo &LI, unsigned UID) {
-  return LI.getLabelID() < UID;
-}
-/// InvalidateLabel - Inhibit use of the specified label # from
-/// MachineDebugInfo, for example because the code was deleted.
-void MachineDebugInfo::InvalidateLabel(unsigned LabelID) {
-  // Check source line list first.  SourceLineInfo is sorted by LabelID.
-  std::vector<SourceLineInfo>::iterator I =
-    std::lower_bound(Lines.begin(), Lines.end(), LabelID, LabelUIDComparison);
-  if (I != Lines.end() && I->getLabelID() == LabelID) {
-    Lines.erase(I);
-    return;
-  }
-  
-  // Otherwise add for use by isLabelValid.
-  std::vector<unsigned>::iterator J =
-    std::lower_bound(DeletedLabelIDs.begin(), DeletedLabelIDs.end(), LabelID);
-  DeletedLabelIDs.insert(J, LabelID);
-}
-
-/// isLabelValid - Check to make sure the label is still valid before
-/// attempting to use.
-bool MachineDebugInfo::isLabelValid(unsigned LabelID) {
-  std::vector<unsigned>::iterator I =
-    std::lower_bound(DeletedLabelIDs.begin(), DeletedLabelIDs.end(), LabelID);
-  return I == DeletedLabelIDs.end() || *I != LabelID;
-}
-
 /// RecordSource - Register a source file with debug info. Returns an source
 /// ID.
 unsigned MachineDebugInfo::RecordSource(const std::string &Directory,
@@ -1642,4 +1616,70 @@ DebugScope *MachineDebugInfo::getOrCreateScope(DebugInfoDesc *ScopeDesc) {
   return Slot;
 }
 
+//===----------------------------------------------------------------------===//
+/// DebugLabelFolding pass - This pass prunes out redundant debug labels.  This
+/// allows a debug emitter to determine if the range of two labels is empty,
+/// by seeing if the labels map to the same reduced label.
+
+namespace llvm {
+
+struct DebugLabelFolder : public MachineFunctionPass {
+  virtual bool runOnMachineFunction(MachineFunction &MF);
+  virtual const char *getPassName() const { return "Debug Label Folder"; }
+};
+
+bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
+  // Get machine debug info.
+  MachineDebugInfo *MDI = getAnalysisToUpdate<MachineDebugInfo>();
+  if (!MDI) return false;
+  // Get target instruction info.
+  const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
+  if (!TII) return false;
+  // Get target version of the debug label opcode.
+  unsigned DWARF_LABELOpc = TII->getDWARF_LABELOpcode();
+  if (!DWARF_LABELOpc) return false;
+  
+  // Track if change is made.
+  bool MadeChange = false;
+  // No prior label to begin.
+  unsigned PriorLabel = 0;
+  
+  // Iterate through basic blocks.
+  for (MachineFunction::iterator BB = MF.begin(), E = MF.end();
+       BB != E; ++BB) {
+    // Iterate through instructions.
+    for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
+      // Is it a debug label.
+      if ((unsigned)I->getOpcode() == DWARF_LABELOpc) {
+        // The label ID # is always operand #0, an immediate.
+        unsigned NextLabel = I->getOperand(0).getImm();
+        
+        // If there was an immediate prior label.
+        if (PriorLabel) {
+          // Remap the current label to prior label.
+          MDI->RemapLabel(NextLabel, PriorLabel);
+          // Delete the current label.
+          I = BB->erase(I);
+          // Indicate a change has been made.
+          MadeChange = true;
+          continue;
+        } else {
+          // Start a new round.
+          PriorLabel = NextLabel;
+        }
+       } else {
+        // No consecutive labels.
+        PriorLabel = 0;
+      }
+      
+      ++I;
+    }
+  }
+  
+  return MadeChange;
+}
+
+FunctionPass *createDebugLabelFoldingPass() { return new DebugLabelFolder(); }
+
+}