aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/MachineDebugInfo.h36
-rw-r--r--include/llvm/CodeGen/Passes.h5
-rw-r--r--lib/CodeGen/DwarfWriter.cpp37
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp3
-rw-r--r--lib/CodeGen/MachineDebugInfo.cpp102
5 files changed, 124 insertions, 59 deletions
diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h
index 39b2464072..7b6386730b 100644
--- a/include/llvm/CodeGen/MachineDebugInfo.h
+++ b/include/llvm/CodeGen/MachineDebugInfo.h
@@ -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.
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 642039817f..adccf531eb 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -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.
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index 81c8963e16..c8a1333d6c 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -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);
}
}
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index b12634ae28..ae13625c20 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -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));
diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp
index 490e48d926..bdbdd144fd 100644
--- a/lib/CodeGen/MachineDebugInfo.cpp
+++ b/lib/CodeGen/MachineDebugInfo.cpp
@@ -10,7 +10,11 @@
#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(); }
+
+}