[llvm-branch-commits] [llvm-branch] r69323 - in /llvm/branches/Apple/Dib: include/llvm/Analysis/ include/llvm/CodeGen/ include/llvm/Target/ lib/Analysis/ lib/CodeGen/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/ lib/Target/X86/ lib/Transforms/Utils/ test/Transforms/Inline/
Devang Patel
dpatel at apple.com
Thu Apr 16 16:28:27 PDT 2009
Author: dpatel
Date: Thu Apr 16 18:28:27 2009
New Revision: 69323
URL: http://llvm.org/viewvc/llvm-project?rev=69323&view=rev
Log:
Merge patches from mainline to support debugging of inlined functions.
Following svn revisions from mainline are merged in to Dib branch:
68647 68727 68735 68813 68964 68973 69113 69116 69118
69202 69210 69216 69252 69253 69254 69286 69300
Removed:
llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll
Modified:
llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h
llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h
llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h
llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h
llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp
llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp
llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp
llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp
llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp
Modified: llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Analysis/DebugInfo.h Thu Apr 16 18:28:27 2009
@@ -309,6 +309,10 @@
/// dump - print subprogram.
void dump() const;
+
+ /// describes - Return true if this subprogram provides debugging
+ /// information for the function F.
+ bool describes(const Function *F);
};
/// DIGlobalVariable - This is a wrapper for a global variable.
Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/DwarfWriter.h Thu Apr 16 18:28:27 2009
@@ -29,11 +29,15 @@
class DwarfException;
class MachineModuleInfo;
class MachineFunction;
+class MachineInstr;
class Value;
class Module;
class GlobalVariable;
class TargetAsmInfo;
class raw_ostream;
+class Instruction;
+class DISubprogram;
+class DIVariable;
//===----------------------------------------------------------------------===//
// DwarfWriter - Emits Dwarf debug and exception handling directives.
@@ -77,7 +81,7 @@
void EndFunction(MachineFunction *MF);
/// ValidDebugInfo - Return true if V represents valid debug info value.
- bool ValidDebugInfo(Value *V);
+ bool ValidDebugInfo(Value *V, bool FastISel);
/// RecordSourceLine - Register a source line with debug info. Returns a
/// unique label ID used to generate a label and provide correspondence to
@@ -102,11 +106,23 @@
/// RecordVariable - Indicate the declaration of a local variable.
///
- void RecordVariable(GlobalVariable *GV, unsigned FrameIndex);
+ void RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
+ const MachineInstr *MI);
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
/// be emitted.
bool ShouldEmitDwarfDebug() const;
+
+ //// RecordInlinedFnStart - Indicate the start of a inlined function.
+ void RecordInlinedFnStart(Instruction *I, DISubprogram &SP, unsigned LabelID,
+ unsigned Src, unsigned Line, unsigned Col);
+
+ /// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+ unsigned RecordInlinedFnEnd(DISubprogram &SP);
+
+ /// RecordVariableScope - Record scope for the variable declared by
+ /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+ void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI);
};
Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h Thu Apr 16 18:28:27 2009
@@ -83,6 +83,9 @@
///
void setCurDebugLoc(DebugLoc dl) { DL = dl; }
+ /// getCurDebugLoc() - Return current debug location information.
+ DebugLoc getCurDebugLoc() const { return DL; }
+
/// SelectInstruction - Do "fast" instruction selection for the given
/// LLVM IR instruction, and append generated machine instructions to
/// the current block. Return true if selection was successful.
Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/MachineModuleInfo.h Thu Apr 16 18:28:27 2009
@@ -37,6 +37,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/GlobalValue.h"
@@ -115,6 +116,9 @@
// searchable format.
SmallPtrSet<const Function *, 32> UsedFunctions;
+ /// UsedDbgLabels - labels are used by debug info entries.
+ SmallSet<unsigned, 8> UsedDbgLabels;
+
bool CallsEHReturn;
bool CallsUnwindInit;
@@ -195,6 +199,19 @@
return LabelID ? LabelIDList[LabelID - 1] : 0;
}
+ /// isDbgLabelUsed - Return true if label with LabelID is used by
+ /// DwarfWriter.
+ bool isDbgLabelUsed(unsigned LabelID) {
+ return UsedDbgLabels.count(LabelID);
+ }
+
+ /// RecordUsedDbgLabel - Mark label with LabelID as used. This is used
+ /// by DwarfWriter to inform DebugLabelFolder that certain labels are
+ /// not to be deleted.
+ void RecordUsedDbgLabel(unsigned LabelID) {
+ UsedDbgLabels.insert(LabelID);
+ }
+
/// getFrameMoves - Returns a reference to a list of moves done in the current
/// function's prologue. Used to construct frame maps for debug and exception
/// handling comsumers.
Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetAsmInfo.h Thu Apr 16 18:28:27 2009
@@ -459,6 +459,10 @@
///
bool DwarfRequiresFrameSection; // Defaults to true.
+ /// DwarfUsesInlineInfoSection - True if DwarfDebugInlineSection is used to
+ /// encode inline subroutine information.
+ bool DwarfUsesInlineInfoSection; // Defaults to false.
+
/// SupportsMacInfo - true if the Dwarf output supports macro information
///
bool SupportsMacInfoSection; // Defaults to true
@@ -502,7 +506,11 @@
/// DwarfPubTypesSection - Section directive for Dwarf info.
///
const char *DwarfPubTypesSection; // Defaults to ".debug_pubtypes".
-
+
+ /// DwarfDebugInlineSection - Section directive for inline info.
+ ///
+ const char *DwarfDebugInlineSection; // Defaults to ".debug_inlined"
+
/// DwarfStrSection - Section directive for Dwarf info.
///
const char *DwarfStrSection; // Defaults to ".debug_str".
@@ -837,6 +845,9 @@
bool doesDwarfRequireFrameSection() const {
return DwarfRequiresFrameSection;
}
+ bool doesDwarfUsesInlineInfoSection() const {
+ return DwarfUsesInlineInfoSection;
+ }
bool doesSupportMacInfoSection() const {
return SupportsMacInfoSection;
}
@@ -870,6 +881,9 @@
const char *getDwarfPubTypesSection() const {
return DwarfPubTypesSection;
}
+ const char *getDwarfDebugInlineSection() const {
+ return DwarfDebugInlineSection;
+ }
const char *getDwarfStrSection() const {
return DwarfStrSection;
}
Modified: llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Analysis/DebugInfo.cpp Thu Apr 16 18:28:27 2009
@@ -290,6 +290,19 @@
return BT.getSizeInBits();
}
+/// describes - Return true if this subprogram provides debugging
+/// information for the function F.
+bool DISubprogram::describes(const Function *F) {
+ assert (F && "Invalid function");
+ std::string Name;
+ getLinkageName(Name);
+ if (Name.empty())
+ getName(Name);
+ if (!Name.empty() && (strcmp(Name.c_str(), F->getNameStart()) == false))
+ return true;
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// DIFactory: Basic Helpers
//===----------------------------------------------------------------------===//
Modified: llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Thu Apr 16 18:28:27 2009
@@ -1534,7 +1534,7 @@
void AsmPrinter::printDeclare(const MachineInstr *MI) const {
unsigned FI = MI->getOperand(0).getIndex();
GlobalValue *GV = MI->getOperand(1).getGlobal();
- DW->RecordVariable(cast<GlobalVariable>(GV), FI);
+ DW->RecordVariable(cast<GlobalVariable>(GV), FI, MI);
}
/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
Modified: llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/AsmPrinter/DwarfWriter.cpp Thu Apr 16 18:28:27 2009
@@ -1140,7 +1140,7 @@
DbgScope(DbgScope *P, DIDescriptor D)
: Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), Scopes(), Variables()
{}
- ~DbgScope() {
+ virtual ~DbgScope() {
for (unsigned i = 0, N = Scopes.size(); i < N; ++i) delete Scopes[i];
for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j];
}
@@ -1162,6 +1162,32 @@
/// AddVariable - Add a variable to the scope.
///
void AddVariable(DbgVariable *V) { Variables.push_back(V); }
+
+ virtual bool isInlinedSubroutine() { return false; }
+ virtual unsigned getLine() { assert ( 0 && "Unexpected scope!"); }
+ virtual unsigned getColumn() { assert ( 0 && "Unexpected scope!"); }
+ virtual unsigned getFile() { assert ( 0 && "Unexpected scope!"); }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// DbgInlinedSubroutineScope - This class is used to track inlined subroutine
+/// scope information.
+///
+class DbgInlinedSubroutineScope : public DbgScope {
+ unsigned Src;
+ unsigned Line;
+ unsigned Col;
+public:
+ DbgInlinedSubroutineScope(DbgScope *P, DIDescriptor D,
+ unsigned S, unsigned L, unsigned C)
+ : DbgScope(P, D), Src(S), Line(L), Col(C)
+ {}
+
+ unsigned getLine() { return Line; }
+ unsigned getColumn() { return Col; }
+ unsigned getFile() { return Src; }
+ bool isInlinedSubroutine() { return true; }
};
//===----------------------------------------------------------------------===//
@@ -1245,13 +1271,24 @@
///
bool shouldEmit;
- // RootDbgScope - Top level scope for the current function.
+ // FunctionDbgScope - Top level scope for the current function.
//
- DbgScope *RootDbgScope;
+ DbgScope *FunctionDbgScope;
/// DbgScopeMap - Tracks the scopes in the current function.
DenseMap<GlobalVariable *, DbgScope *> DbgScopeMap;
+ /// DbgInlinedScopeMap - Tracks inlined scopes in the current function.
+ DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> > DbgInlinedScopeMap;
+
+ /// InlineInfo - Keep track of inlined functions and their location.
+ /// This information is used to populate debug_inlined section.
+ DenseMap<GlobalVariable *, SmallVector<unsigned, 4> > InlineInfo;
+
+ /// InlinedVariableScopes - Scopes information for the inlined subroutine
+ /// variables.
+ DenseMap<const MachineInstr *, DbgScope *> InlinedVariableScopes;
+
/// DebugTimer - Timer for the Dwarf debug writer.
Timer *DebugTimer;
@@ -1465,7 +1502,7 @@
/// AddDelta - Add a label delta attribute data and value.
///
void AddDelta(DIE *Die, unsigned Attribute, unsigned Form,
- const DWLabel &Hi, const DWLabel &Lo) {
+ const DWLabel &Hi, const DWLabel &Lo) {
FoldingSetNodeID ID;
DIEDelta::Profile(ID, Hi, Lo);
void *Where;
@@ -1546,7 +1583,7 @@
/// AddAddress - Add an address attribute to a die based on the location
/// provided.
void AddAddress(DIE *Die, unsigned Attribute,
- const MachineLocation &Location) {
+ const MachineLocation &Location) {
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new DIEBlock();
@@ -1899,8 +1936,9 @@
DIArray Args = SPTy.getTypeArray();
// Add Return Type.
+ unsigned SPTag = SPTy.getTag();
if (!IsConstructor) {
- if (Args.isNull())
+ if (Args.isNull() || SPTag != DW_TAG_subroutine_type)
AddType(DW_Unit, SPDie, SPTy);
else
AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV()));
@@ -1911,7 +1949,7 @@
// Add arguments.
// Do not add arguments for subprogram definition. They will be
// handled through RecordVariable.
- if (!Args.isNull())
+ if (SPTag == DW_TAG_subroutine_type)
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
DIE *Arg = new DIE(DW_TAG_formal_parameter);
AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV()));
@@ -1927,6 +1965,10 @@
if (!SP.isLocalToUnit())
AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
+
+ // DW_TAG_inlined_subroutine may refer to this DIE.
+ DIE *&Slot = DW_Unit->getDieMapSlotFor(SP.getGV());
+ Slot = SPDie;
return SPDie;
}
@@ -1981,33 +2023,39 @@
DbgScope *&Slot = DbgScopeMap[V];
if (Slot) return Slot;
- // FIXME - breaks down when the context is an inlined function.
- DIDescriptor ParentDesc;
- DIDescriptor Desc(V);
-
- if (Desc.getTag() == dwarf::DW_TAG_lexical_block) {
- DIBlock Block(V);
- ParentDesc = Block.getContext();
+ DbgScope *Parent = NULL;
+ DIBlock Block(V);
+ if (!Block.isNull()) {
+ DIDescriptor ParentDesc = Block.getContext();
+ Parent =
+ ParentDesc.isNull() ? NULL : getOrCreateScope(ParentDesc.getGV());
}
+ Slot = new DbgScope(Parent, DIDescriptor(V));
- DbgScope *Parent = ParentDesc.isNull() ?
- NULL : getOrCreateScope(ParentDesc.getGV());
- Slot = new DbgScope(Parent, Desc);
-
- if (Parent) {
+ if (Parent)
Parent->AddScope(Slot);
- } else if (RootDbgScope) {
- // FIXME - Add inlined function scopes to the root so we can delete them
- // later. Long term, handle inlined functions properly.
- RootDbgScope->AddScope(Slot);
- } else {
+ else
// First function is top level function.
- RootDbgScope = Slot;
- }
+ FunctionDbgScope = Slot;
return Slot;
}
+ /// createInlinedSubroutineScope - Returns the scope associated with the
+ /// inlined subroutine.
+ ///
+ DbgScope *createInlinedSubroutineScope(DISubprogram SP, unsigned Src,
+ unsigned Line, unsigned Col) {
+ DbgScope *Scope =
+ new DbgInlinedSubroutineScope(NULL, SP, Src, Line, Col);
+
+ // FIXME - Add inlined function scopes to the root so we can delete them
+ // later.
+ assert (FunctionDbgScope && "Function scope info missing!");
+ FunctionDbgScope->AddScope(Scope);
+ return Scope;
+ }
+
/// ConstructDbgScope - Construct the components of a scope.
///
void ConstructDbgScope(DbgScope *ParentScope,
@@ -2025,48 +2073,61 @@
for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
// Define the Scope debug information entry.
DbgScope *Scope = Scopes[j];
- // FIXME - Ignore inlined functions for the time being.
- if (!Scope->getParent()) continue;
unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
- // Ignore empty scopes.
+ // Ignore empty scopes.
+ // Do not ignore inlined scope even if it does not have any
+ // variables or scopes.
if (StartID == EndID && StartID != 0) continue;
- if (Scope->getScopes().empty() && Scope->getVariables().empty()) continue;
+ if (!Scope->isInlinedSubroutine()
+ && Scope->getScopes().empty() && Scope->getVariables().empty())
+ continue;
if (StartID == ParentStartID && EndID == ParentEndID) {
// Just add stuff to the parent scope.
ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit);
} else {
- DIE *ScopeDie = new DIE(DW_TAG_lexical_block);
-
- // Add the scope bounds.
- if (StartID) {
- AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
- DWLabel("label", StartID));
- } else {
- AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
- DWLabel("func_begin", SubprogramCount));
- }
- if (EndID) {
- AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
- DWLabel("label", EndID));
- } else {
- AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
- DWLabel("func_end", SubprogramCount));
+ DIE *ScopeDie = NULL;
+ if (MainCU && TAI->doesDwarfUsesInlineInfoSection()
+ && Scope->isInlinedSubroutine()) {
+ ScopeDie = new DIE(DW_TAG_inlined_subroutine);
+ DIE *Origin = MainCU->getDieMapSlotFor(Scope->getDesc().getGV());
+ AddDIEntry(ScopeDie, DW_AT_abstract_origin, DW_FORM_ref4, Origin);
+ AddUInt(ScopeDie, DW_AT_call_file, 0, Scope->getFile());
+ AddUInt(ScopeDie, DW_AT_call_line, 0, Scope->getLine());
+ AddUInt(ScopeDie, DW_AT_call_column, 0, Scope->getColumn());
}
-
- // Add the scope contents.
- ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
- ParentDie->AddChild(ScopeDie);
+ else
+ ScopeDie = new DIE(DW_TAG_lexical_block);
+
+ // Add the scope bounds.
+ if (StartID) {
+ AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
+ DWLabel("label", StartID));
+ } else {
+ AddLabel(ScopeDie, DW_AT_low_pc, DW_FORM_addr,
+ DWLabel("func_begin", SubprogramCount));
+ }
+ if (EndID) {
+ AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
+ DWLabel("label", EndID));
+ } else {
+ AddLabel(ScopeDie, DW_AT_high_pc, DW_FORM_addr,
+ DWLabel("func_end", SubprogramCount));
+ }
+
+ // Add the scope contents.
+ ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
+ ParentDie->AddChild(ScopeDie);
}
}
}
- /// ConstructRootDbgScope - Construct the scope for the subprogram.
+ /// ConstructFunctionDbgScope - Construct the scope for the subprogram.
///
- void ConstructRootDbgScope(DbgScope *RootScope) {
+ void ConstructFunctionDbgScope(DbgScope *RootScope) {
// Exit if there is no root scope.
if (!RootScope) return;
DIDescriptor Desc = RootScope->getDesc();
@@ -2779,6 +2840,77 @@
}
}
+ /// EmitDebugInlineInfo - Emit inline info using following format.
+ /// Section Header:
+ /// 1. length of section
+ /// 2. Dwarf version number
+ /// 3. address size.
+ ///
+ /// Entries (one "entry" for each function that was inlined):
+ ///
+ /// 1. offset into __debug_str section for MIPS linkage name, if exists;
+ /// otherwise offset into __debug_str for regular function name.
+ /// 2. offset into __debug_str section for regular function name.
+ /// 3. an unsigned LEB128 number indicating the number of distinct inlining
+ /// instances for the function.
+ ///
+ /// The rest of the entry consists of a {die_offset, low_pc} pair for each
+ /// inlined instance; the die_offset points to the inlined_subroutine die in
+ /// the __debug_info section, and the low_pc is the starting address for the
+ /// inlining instance.
+ void EmitDebugInlineInfo() {
+ if (!TAI->doesDwarfUsesInlineInfoSection())
+ return;
+
+ if (!MainCU)
+ return;
+
+ Asm->SwitchToDataSection(TAI->getDwarfDebugInlineSection());
+ Asm->EOL();
+ EmitDifference("debug_inlined_end", 1,
+ "debug_inlined_begin", 1, true);
+ Asm->EOL("Length of Debug Inlined Information Entry");
+
+ EmitLabel("debug_inlined_begin", 1);
+
+ Asm->EmitInt16(DWARF_VERSION); Asm->EOL("Dwarf Version");
+ Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)");
+
+ for (DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator
+ I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) {
+ GlobalVariable *GV = I->first;
+ SmallVector<unsigned, 4> &Labels = I->second;
+ DISubprogram SP(GV);
+ std::string Name;
+ std::string LName;
+
+ SP.getLinkageName(LName);
+ SP.getName(Name);
+
+ Asm->EmitString(LName.empty() ? Name : LName);
+ Asm->EOL("MIPS linkage name");
+
+ Asm->EmitString(Name); Asm->EOL("Function name");
+
+ Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count");
+
+ for (SmallVector<unsigned, 4>::iterator LI = Labels.begin(),
+ LE = Labels.end(); LI != LE; ++LI) {
+ DIE *SP = MainCU->getDieMapSlotFor(GV);
+ Asm->EmitInt32(SP->getOffset()); Asm->EOL("DIE offset");
+
+ if (TD->getPointerSize() == sizeof(int32_t))
+ O << TAI->getData32bitsDirective();
+ else
+ O << TAI->getData64bitsDirective();
+ PrintLabelName("label", *LI); Asm->EOL("low_pc");
+ }
+ }
+
+ EmitLabel("debug_inlined_end", 1);
+ Asm->EOL();
+ }
+
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
@@ -2987,7 +3119,7 @@
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
ValuesSet(InitValuesSetSize), Values(), StringPool(), SectionMap(),
SectionSourceLines(), didInitial(false), shouldEmit(false),
- RootDbgScope(0), DebugTimer(0) {
+ FunctionDbgScope(0), DebugTimer(0) {
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer",
getDwarfTimerGroup());
@@ -3129,6 +3261,9 @@
// Emit info into a debug macinfo section.
EmitDebugMacInfo();
+ // Emit inline info.
+ EmitDebugInlineInfo();
+
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
@@ -3183,8 +3318,8 @@
}
// Construct scopes for subprogram.
- if (RootDbgScope)
- ConstructRootDbgScope(RootDbgScope);
+ if (FunctionDbgScope)
+ ConstructFunctionDbgScope(FunctionDbgScope);
else
// FIXME: This is wrong. We are essentially getting past a problem with
// debug information not being able to handle unreachable blocks that have
@@ -3200,10 +3335,12 @@
MMI->getFrameMoves()));
// Clear debug info
- if (RootDbgScope) {
- delete RootDbgScope;
+ if (FunctionDbgScope) {
+ delete FunctionDbgScope;
DbgScopeMap.clear();
- RootDbgScope = NULL;
+ DbgInlinedScopeMap.clear();
+ InlinedVariableScopes.clear();
+ FunctionDbgScope = NULL;
}
Lines.clear();
@@ -3213,7 +3350,7 @@
}
/// ValidDebugInfo - Return true if V represents valid debug info value.
- bool ValidDebugInfo(Value *V) {
+ bool ValidDebugInfo(Value *V, bool FastISel) {
if (!V)
return false;
@@ -3252,6 +3389,11 @@
case DW_TAG_subprogram:
assert(DISubprogram(GV).Verify() && "Invalid DebugInfo value");
break;
+ case DW_TAG_lexical_block:
+ /// FIXME. This interfers with the qualitfy of generated code when
+ /// during optimization.
+ if (FastISel == false)
+ return false;
default:
break;
}
@@ -3351,7 +3493,8 @@
}
/// RecordVariable - Indicate the declaration of a local variable.
- void RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
+ void RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
+ const MachineInstr *MI) {
if (TimePassesIsEnabled)
DebugTimer->startTimer();
@@ -3363,9 +3506,16 @@
DIGlobalVariable DG(GV);
Scope = getOrCreateScope(DG.getContext().getGV());
} else {
+ DenseMap<const MachineInstr *, DbgScope *>::iterator
+ SI = InlinedVariableScopes.find(MI);
+ if (SI != InlinedVariableScopes.end()) {
+ // or GV is an inlined local variable.
+ Scope = SI->second;
+ } else {
// or GV is a local variable.
- DIVariable DV(GV);
- Scope = getOrCreateScope(DV.getContext().getGV());
+ DIVariable DV(GV);
+ Scope = getOrCreateScope(DV.getContext().getGV());
+ }
}
assert(Scope && "Unable to find variable' scope");
@@ -3375,6 +3525,78 @@
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
+
+ //// RecordInlinedFnStart - Indicate the start of inlined subroutine.
+ void RecordInlinedFnStart(Instruction *FSI, DISubprogram &SP, unsigned LabelID,
+ unsigned Src, unsigned Line, unsigned Col) {
+ if (!TAI->doesDwarfUsesInlineInfoSection())
+ return;
+
+ DbgScope *Scope = createInlinedSubroutineScope(SP, Src, Line, Col);
+ Scope->setStartLabelID(LabelID);
+ MMI->RecordUsedDbgLabel(LabelID);
+ GlobalVariable *GV = SP.getGV();
+
+ DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+ SI = DbgInlinedScopeMap.find(GV);
+ if (SI == DbgInlinedScopeMap.end()) {
+ SmallVector<DbgScope *, 2> Scopes;
+ Scopes.push_back(Scope);
+ DbgInlinedScopeMap[GV] = Scopes;
+ } else {
+ SmallVector<DbgScope *, 2> &Scopes = SI->second;
+ Scopes.push_back(Scope);
+ }
+
+ DenseMap<GlobalVariable *, SmallVector<unsigned, 4> >::iterator
+ I = InlineInfo.find(GV);
+ if (I == InlineInfo.end()) {
+ SmallVector<unsigned, 4> Labels;
+ Labels.push_back(LabelID);
+ InlineInfo[GV] = Labels;
+ return;
+ }
+
+ SmallVector<unsigned, 4> &Labels = I->second;
+ Labels.push_back(LabelID);
+ }
+
+ /// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+ unsigned RecordInlinedFnEnd(DISubprogram &SP) {
+ if (!TAI->doesDwarfUsesInlineInfoSection())
+ return 0;
+
+ GlobalVariable *GV = SP.getGV();
+ DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+ I = DbgInlinedScopeMap.find(GV);
+ if (I == DbgInlinedScopeMap.end())
+ return 0;
+
+ SmallVector<DbgScope *, 2> &Scopes = I->second;
+ DbgScope *Scope = Scopes.back(); Scopes.pop_back();
+ unsigned ID = MMI->NextLabelID();
+ MMI->RecordUsedDbgLabel(ID);
+ Scope->setEndLabelID(ID);
+ return ID;
+ }
+
+ /// RecordVariableScope - Record scope for the variable declared by
+ /// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+ /// Record scopes for only inlined subroutine variables. Other
+ /// variables' scopes are determined during RecordVariable().
+ void RecordVariableScope(DIVariable &DV, const MachineInstr *DeclareMI) {
+ DISubprogram SP(DV.getContext().getGV());
+ if (SP.isNull())
+ return;
+ DenseMap<GlobalVariable *, SmallVector<DbgScope *, 2> >::iterator
+ I = DbgInlinedScopeMap.find(SP.getGV());
+ if (I == DbgInlinedScopeMap.end())
+ return;
+
+ SmallVector<DbgScope *, 2> &Scopes = I->second;
+ InlinedVariableScopes[DeclareMI] = Scopes.back();
+ }
+
};
//===----------------------------------------------------------------------===//
@@ -4504,8 +4726,8 @@
}
/// ValidDebugInfo - Return true if V represents valid debug info value.
-bool DwarfWriter::ValidDebugInfo(Value *V) {
- return DD && DD->ValidDebugInfo(V);
+bool DwarfWriter::ValidDebugInfo(Value *V, bool FastISel) {
+ return DD && DD->ValidDebugInfo(V, FastISel);
}
/// RecordSourceLine - Records location information and associates it with a
@@ -4542,8 +4764,9 @@
/// RecordVariable - Indicate the declaration of a local variable.
///
-void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex) {
- DD->RecordVariable(GV, FrameIndex);
+void DwarfWriter::RecordVariable(GlobalVariable *GV, unsigned FrameIndex,
+ const MachineInstr *MI) {
+ DD->RecordVariable(GV, FrameIndex, MI);
}
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
@@ -4551,3 +4774,23 @@
bool DwarfWriter::ShouldEmitDwarfDebug() const {
return DD->ShouldEmitDwarfDebug();
}
+
+//// RecordInlinedFnStart - Global variable GV is inlined at the location marked
+//// by LabelID label.
+void DwarfWriter::RecordInlinedFnStart(Instruction *I, DISubprogram &SP,
+ unsigned LabelID, unsigned Src,
+ unsigned Line, unsigned Col) {
+ DD->RecordInlinedFnStart(I, SP, LabelID, Src, Line, Col);
+}
+
+/// RecordInlinedFnEnd - Indicate the end of inlined subroutine.
+unsigned DwarfWriter::RecordInlinedFnEnd(DISubprogram &SP) {
+ return DD->RecordInlinedFnEnd(SP);
+}
+
+/// RecordVariableScope - Record scope for the variable declared by
+/// DeclareMI. DeclareMI must describe TargetInstrInfo::DECLARE.
+void DwarfWriter::RecordVariableScope(DIVariable &DV,
+ const MachineInstr *DeclareMI) {
+ DD->RecordVariableScope(DV, DeclareMI);
+}
Modified: llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/MachineModuleInfo.cpp Thu Apr 16 18:28:27 2009
@@ -333,7 +333,7 @@
// Iterate through instructions.
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
// Is it a label.
- if (I->isDebugLabel()) {
+ if (I->isDebugLabel() && !MMI->isDbgLabelUsed(I->getOperand(0).getImm())){
// The label ID # is always operand #0, an immediate.
unsigned NextLabel = I->getOperand(0).getImm();
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp Thu Apr 16 18:28:27 2009
@@ -47,6 +47,7 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/DebugLoc.h"
#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetData.h"
@@ -322,7 +323,7 @@
default: break;
case Intrinsic::dbg_stoppoint: {
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
- if (DW && DW->ValidDebugInfo(SPI->getContext())) {
+ if (DW && DW->ValidDebugInfo(SPI->getContext(), true)) {
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
std::string Dir, FN;
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir),
@@ -339,7 +340,7 @@
}
case Intrinsic::dbg_region_start: {
DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I);
- if (DW && DW->ValidDebugInfo(RSI->getContext())) {
+ if (DW && DW->ValidDebugInfo(RSI->getContext(), true)) {
unsigned ID =
DW->RecordRegionStart(cast<GlobalVariable>(RSI->getContext()));
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
@@ -349,11 +350,24 @@
}
case Intrinsic::dbg_region_end: {
DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I);
- if (DW && DW->ValidDebugInfo(REI->getContext())) {
- unsigned ID =
- DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, DL, II).addImm(ID);
+ if (DW && DW->ValidDebugInfo(REI->getContext(), true)) {
+ unsigned ID = 0;
+ DISubprogram Subprogram(cast<GlobalVariable>(REI->getContext()));
+ if (!Subprogram.isNull() && !Subprogram.describes(MF.getFunction())) {
+ // This is end of an inlined function.
+ const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+ ID = DW->RecordInlinedFnEnd(Subprogram);
+ if (ID)
+ // Returned ID is 0 if this is unbalanced "end of inlined
+ // scope". This could happen if optimizer eats dbg intrinsics
+ // or "beginning of inlined scope" is not recoginized due to
+ // missing location info. In such cases, do ignore this region.end.
+ BuildMI(MBB, DL, II).addImm(ID);
+ } else {
+ const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
+ ID = DW->RecordRegionEnd(cast<GlobalVariable>(REI->getContext()));
+ BuildMI(MBB, DL, II).addImm(ID);
+ }
}
return true;
}
@@ -362,25 +376,43 @@
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
Value *SP = FSI->getSubprogram();
- if (DW->ValidDebugInfo(SP)) {
+ if (DW->ValidDebugInfo(SP, true)) {
// llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
// (most?) gdb expects.
+ DebugLoc PrevLoc = DL;
DISubprogram Subprogram(cast<GlobalVariable>(SP));
DICompileUnit CompileUnit = Subprogram.getCompileUnit();
std::string Dir, FN;
unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
CompileUnit.getFilename(FN));
- // Record the source line but does not create a label for the normal
- // function start. It will be emitted at asm emission time. However,
- // create a label if this is a beginning of inlined function.
- unsigned Line = Subprogram.getLineNumber();
- unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
- setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+ if (!Subprogram.describes(MF.getFunction())) {
+ // This is a beginning of an inlined function.
+
+ // If llvm.dbg.func.start is seen in a new block before any
+ // llvm.dbg.stoppoint intrinsic then the location info is unknown.
+ // FIXME : Why DebugLoc is reset at the beginning of each block ?
+ if (PrevLoc.isUnknown())
+ return true;
+ // Record the source line.
+ unsigned Line = Subprogram.getLineNumber();
+ unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
- if (DW->getRecordSourceLineCount() != 1) {
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
BuildMI(MBB, DL, II).addImm(LabelID);
+ DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
+ DW->RecordInlinedFnStart(FSI, Subprogram, LabelID,
+ PrevLocTpl.Src,
+ PrevLocTpl.Line,
+ PrevLocTpl.Col);
+ } else {
+ // Record the source line.
+ unsigned Line = Subprogram.getLineNumber();
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+ DW->RecordSourceLine(Line, 0, SrcFile);
+ // llvm.dbg.func_start also defines beginning of function scope.
+ DW->RecordRegionStart(cast<GlobalVariable>(FSI->getSubprogram()));
}
}
@@ -389,7 +421,7 @@
case Intrinsic::dbg_declare: {
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
Value *Variable = DI->getVariable();
- if (DW && DW->ValidDebugInfo(Variable)) {
+ if (DW && DW->ValidDebugInfo(Variable, true)) {
// Determine the address of the declared object.
Value *Address = DI->getAddress();
if (BitCastInst *BCI = dyn_cast<BitCastInst>(Address))
@@ -407,7 +439,13 @@
// Build the DECLARE instruction.
const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE);
- BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV);
+ MachineInstr *DeclareMI
+ = BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV);
+ DIVariable DV(cast<GlobalVariable>(GV));
+ if (!DV.isNull()) {
+ // This is a local variable
+ DW->RecordVariableScope(DV, DeclareMI);
+ }
}
return true;
}
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Thu Apr 16 18:28:27 2009
@@ -332,7 +332,7 @@
DwarfWriter *DW = DAG.getDwarfWriter();
DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
- if (DW && DW->ValidDebugInfo(SPI->getContext())) {
+ if (DW && DW->ValidDebugInfo(SPI->getContext(), false)) {
DICompileUnit CU(cast<GlobalVariable>(SPI->getContext()));
std::string Dir, FN;
unsigned SrcFile = DW->getOrCreateSourceID(CU.getDirectory(Dir),
@@ -351,7 +351,7 @@
DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
Value *SP = FSI->getSubprogram();
- if (DW->ValidDebugInfo(SP)) {
+ if (DW->ValidDebugInfo(SP, false)) {
DISubprogram Subprogram(cast<GlobalVariable>(SP));
DICompileUnit CU(Subprogram.getCompileUnit());
std::string Dir, FN;
@@ -3929,7 +3929,7 @@
case Intrinsic::dbg_stoppoint: {
DwarfWriter *DW = DAG.getDwarfWriter();
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
- if (DW && DW->ValidDebugInfo(SPI.getContext())) {
+ if (DW && DW->ValidDebugInfo(SPI.getContext(), Fast)) {
MachineFunction &MF = DAG.getMachineFunction();
if (Fast)
DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
@@ -3949,12 +3949,11 @@
case Intrinsic::dbg_region_start: {
DwarfWriter *DW = DAG.getDwarfWriter();
DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
- if (DW && DW->ValidDebugInfo(RSI.getContext())) {
+ if (DW && DW->ValidDebugInfo(RSI.getContext(), Fast)) {
unsigned LabelID =
DW->RecordRegionStart(cast<GlobalVariable>(RSI.getContext()));
- if (Fast)
- DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
- getRoot(), LabelID));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
+ getRoot(), LabelID));
}
return 0;
@@ -3962,12 +3961,33 @@
case Intrinsic::dbg_region_end: {
DwarfWriter *DW = DAG.getDwarfWriter();
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
- if (DW && DW->ValidDebugInfo(REI.getContext())) {
+ if (DW && DW->ValidDebugInfo(REI.getContext(), Fast)) {
+
+ MachineFunction &MF = DAG.getMachineFunction();
+ DISubprogram Subprogram(cast<GlobalVariable>(REI.getContext()));
+ std::string SPName;
+ Subprogram.getLinkageName(SPName);
+ if (!SPName.empty()
+ && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+ // This is end of inlined function. Debugging information for
+ // inlined function is not handled yet (only supported by FastISel).
+ if (Fast) {
+ unsigned ID = DW->RecordInlinedFnEnd(Subprogram);
+ if (ID != 0)
+ // Returned ID is 0 if this is unbalanced "end of inlined
+ // scope". This could happen if optimizer eats dbg intrinsics
+ // or "beginning of inlined scope" is not recoginized due to
+ // missing location info. In such cases, do ignore this region.end.
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
+ getRoot(), ID));
+ }
+ return 0;
+ }
+
unsigned LabelID =
DW->RecordRegionEnd(cast<GlobalVariable>(REI.getContext()));
- if (Fast)
- DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
- getRoot(), LabelID));
+ DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
+ getRoot(), LabelID));
}
return 0;
@@ -3977,29 +3997,74 @@
if (!DW) return 0;
DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
Value *SP = FSI.getSubprogram();
- if (SP && DW->ValidDebugInfo(SP)) {
- // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
- // what (most?) gdb expects.
- MachineFunction &MF = DAG.getMachineFunction();
- DISubprogram Subprogram(cast<GlobalVariable>(SP));
- DICompileUnit CompileUnit = Subprogram.getCompileUnit();
- std::string Dir, FN;
- unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
- CompileUnit.getFilename(FN));
-
- // Record the source line but does not create a label for the normal
- // function start. It will be emitted at asm emission time. However,
- // create a label if this is a beginning of inlined function.
- unsigned Line = Subprogram.getLineNumber();
-
+ if (SP && DW->ValidDebugInfo(SP, Fast)) {
+ MachineFunction &MF = DAG.getMachineFunction();
if (Fast) {
- unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
- if (DW->getRecordSourceLineCount() != 1)
+ // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what
+ // (most?) gdb expects.
+ DebugLoc PrevLoc = CurDebugLoc;
+ DISubprogram Subprogram(cast<GlobalVariable>(SP));
+ DICompileUnit CompileUnit = Subprogram.getCompileUnit();
+ std::string Dir, FN;
+ unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
+ CompileUnit.getFilename(FN));
+
+ if (!Subprogram.describes(MF.getFunction())) {
+ // This is a beginning of an inlined function.
+
+ // If llvm.dbg.func.start is seen in a new block before any
+ // llvm.dbg.stoppoint intrinsic then the location info is unknown.
+ // FIXME : Why DebugLoc is reset at the beginning of each block ?
+ if (PrevLoc.isUnknown())
+ return 0;
+
+ // Record the source line.
+ unsigned Line = Subprogram.getLineNumber();
+ unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile);
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+
DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
getRoot(), LabelID));
- }
+ DebugLocTuple PrevLocTpl = MF.getDebugLocTuple(PrevLoc);
+ DW->RecordInlinedFnStart(&FSI, Subprogram, LabelID,
+ PrevLocTpl.Src,
+ PrevLocTpl.Line,
+ PrevLocTpl.Col);
+ } else {
+ // Record the source line.
+ unsigned Line = Subprogram.getLineNumber();
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+ DW->RecordSourceLine(Line, 0, SrcFile);
+ // llvm.dbg.func_start also defines beginning of function scope.
+ DW->RecordRegionStart(cast<GlobalVariable>(FSI.getSubprogram()));
+ }
+ } else {
+ DISubprogram Subprogram(cast<GlobalVariable>(SP));
+
+ std::string SPName;
+ Subprogram.getLinkageName(SPName);
+ if (!SPName.empty()
+ && strcmp(SPName.c_str(), MF.getFunction()->getNameStart())) {
+ // This is beginning of inlined function. Debugging information for
+ // inlined function is not handled yet (only supported by FastISel).
+ return 0;
+ }
- setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+ // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is
+ // what (most?) gdb expects.
+ DICompileUnit CompileUnit = Subprogram.getCompileUnit();
+ std::string Dir, FN;
+ unsigned SrcFile = DW->getOrCreateSourceID(CompileUnit.getDirectory(Dir),
+ CompileUnit.getFilename(FN));
+
+ // Record the source line but does not create a label for the normal
+ // function start. It will be emitted at asm emission time. However,
+ // create a label if this is a beginning of inlined function.
+ unsigned Line = Subprogram.getLineNumber();
+ setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0)));
+ // FIXME - Start new region because llvm.dbg.func_start also defines
+ // beginning of function scope.
+ }
}
return 0;
@@ -4009,7 +4074,7 @@
DwarfWriter *DW = DAG.getDwarfWriter();
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
Value *Variable = DI.getVariable();
- if (DW && DW->ValidDebugInfo(Variable))
+ if (DW && DW->ValidDebugInfo(Variable, Fast))
DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(),
getValue(DI.getAddress()), getValue(Variable)));
} else {
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h Thu Apr 16 18:28:27 2009
@@ -392,6 +392,7 @@
SDValue getControlRoot();
DebugLoc getCurDebugLoc() const { return CurDebugLoc; }
+ void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
void CopyValueToVirtualRegister(Value *V, unsigned Reg);
@@ -542,8 +543,6 @@
const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op);
const char *implVisitAluOverflow(CallInst &I, ISD::NodeType Op);
-
- void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
};
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Thu Apr 16 18:28:27 2009
@@ -824,6 +824,7 @@
R = FuncInfo->CreateRegForValue(BI);
}
+ SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
SelectBasicBlock(LLVMBB, BI, next(BI));
// If the instruction was codegen'd with multiple blocks,
// inform the FastISel object where to resume inserting.
@@ -850,8 +851,12 @@
// Run SelectionDAG instruction selection on the remainder of the block
// not handled by FastISel. If FastISel is not run, this is the entire
// block.
- if (BI != End)
+ if (BI != End) {
+ // If FastISel is run and it has known DebugLoc then use it.
+ if (FastIS && !FastIS->getCurDebugLoc().isUnknown())
+ SDL->setCurDebugLoc(FastIS->getCurDebugLoc());
SelectBasicBlock(LLVMBB, BI, End);
+ }
FinishBasicBlock();
}
Modified: llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/TargetAsmInfo.cpp Thu Apr 16 18:28:27 2009
@@ -100,6 +100,7 @@
SupportsDebugInformation = false;
SupportsExceptionHandling = false;
DwarfRequiresFrameSection = true;
+ DwarfUsesInlineInfoSection = false;
SupportsMacInfoSection = true;
NonLocalEHFrameLabel = false;
GlobalEHDirective = 0;
@@ -111,6 +112,7 @@
DwarfFrameSection = ".debug_frame";
DwarfPubNamesSection = ".debug_pubnames";
DwarfPubTypesSection = ".debug_pubtypes";
+ DwarfDebugInlineSection = ".debug_inlined";
DwarfStrSection = ".debug_str";
DwarfLocSection = ".debug_loc";
DwarfARangesSection = ".debug_aranges";
Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86TargetAsmInfo.cpp Thu Apr 16 18:28:27 2009
@@ -112,6 +112,8 @@
DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
+ DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug";
+ DwarfUsesInlineInfoSection = true;
DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
Modified: llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Utils/CloneFunction.cpp Thu Apr 16 18:28:27 2009
@@ -24,6 +24,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ADT/SmallVector.h"
#include <map>
using namespace llvm;
@@ -233,10 +234,13 @@
continue;
}
- // Do not clone llvm.dbg.func.start and corresponding llvm.dbg.region.end.
+ // Do not clone llvm.dbg.region.end. It will be adjusted by the inliner.
if (const DbgFuncStartInst *DFSI = dyn_cast<DbgFuncStartInst>(II)) {
- DbgFnStart = DFSI->getSubprogram();
- continue;
+ if (DbgFnStart == NULL) {
+ DISubprogram SP(cast<GlobalVariable>(DFSI->getSubprogram()));
+ if (SP.describes(BB->getParent()))
+ DbgFnStart = DFSI->getSubprogram();
+ }
}
if (const DbgRegionEndInst *DREIS = dyn_cast<DbgRegionEndInst>(II)) {
if (DREIS->getContext() == DbgFnStart)
Modified: llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp?rev=69323&r1=69322&r2=69323&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Utils/InlineFunction.cpp Thu Apr 16 18:28:27 2009
@@ -17,9 +17,11 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Intrinsics.h"
#include "llvm/Attributes.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
@@ -182,6 +184,31 @@
CallerNode->removeCallEdgeFor(CS);
}
+/// findFnRegionEndMarker - This is a utility routine that is used by
+/// InlineFunction. Return llvm.dbg.region.end intrinsic that corresponds
+/// to the llvm.dbg.func.start of the function F. Otherwise return NULL.
+static const DbgRegionEndInst *findFnRegionEndMarker(const Function *F) {
+
+ GlobalVariable *FnStart = NULL;
+ const DbgRegionEndInst *FnEnd = NULL;
+ for (Function::const_iterator FI = F->begin(), FE =F->end(); FI != FE; ++FI)
+ for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end(); BI != BE;
+ ++BI) {
+ if (FnStart == NULL) {
+ if (const DbgFuncStartInst *FSI = dyn_cast<DbgFuncStartInst>(BI)) {
+ DISubprogram SP(cast<GlobalVariable>(FSI->getSubprogram()));
+ assert (SP.isNull() == false && "Invalid llvm.dbg.func.start");
+ if (SP.describes(F))
+ FnStart = SP.getGV();
+ }
+ } else {
+ if (const DbgRegionEndInst *REI = dyn_cast<DbgRegionEndInst>(BI))
+ if (REI->getContext() == FnStart)
+ FnEnd = REI;
+ }
+ }
+ return FnEnd;
+}
// InlineFunction - This function inlines the called function into the basic
// block of the caller. This returns false if it is not possible to inline this
@@ -303,6 +330,24 @@
ValueMap[I] = ActualArg;
}
+ // Adjust llvm.dbg.region.end. If the CalledFunc has region end
+ // marker then clone that marker after next stop point at the
+ // call site. The function body cloner does not clone original
+ // region end marker from the CalledFunc. This will ensure that
+ // inlined function's scope ends at the right place.
+ const DbgRegionEndInst *DREI = findFnRegionEndMarker(CalledFunc);
+ if (DREI) {
+ for (BasicBlock::iterator BI = TheCall,
+ BE = TheCall->getParent()->end(); BI != BE; ++BI) {
+ if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BI)) {
+ if (DbgRegionEndInst *NewDREI =
+ dyn_cast<DbgRegionEndInst>(DREI->clone()))
+ NewDREI->insertAfter(DSPI);
+ break;
+ }
+ }
+ }
+
// We want the inliner to prune the code as it copies. We would LOVE to
// have no dead or constant instructions leftover after inlining occurs
// (which can happen, e.g., because an argument was constant), but we'll be
Removed: llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll?rev=69322&view=auto
==============================================================================
--- llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll (original)
+++ llvm/branches/Apple/Dib/test/Transforms/Inline/llvm.dbg.func.start.ll (removed)
@@ -1,86 +0,0 @@
-; RUN: llvm-as < %s | opt -inline | llvm-dis | grep func.start | count 3
-; RUN: llvm-as < %s | opt -inline | llvm-dis | grep region.end | count 3
- %llvm.dbg.anchor.type = type { i32, i32 }
- %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 }
- %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* }
- %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* }
- %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* }
- %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 }
- %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* }
- at llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
- at .str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
- at .str1 = internal constant [6 x i8] c"/tmp/\00", section "llvm.metadata" ; <[6 x i8]*> [#uses=1]
- at .str2 = internal constant [55 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build 00)\00", section "llvm.metadata" ; <[55 x i8]*> [#uses=1]
- at llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([55 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1]
- at .str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
- at llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
- at .str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
- at llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1]
- at llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]
- at llvm.dbg.array = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1]
- at llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
- at llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1]
- at .str6 = internal constant [4 x i8] c"bar\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1]
- at llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
- at .str7 = internal constant [2 x i8] c"c\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1]
- at llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1]
- at llvm.dbg.array8 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1]
- at llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array8 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1]
- at .str10 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1]
- at llvm.dbg.subprogram11 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str10, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1]
-@"\01LC" = internal constant [3 x i8] c"hi\00" ; <[3 x i8]*> [#uses=1]
-
-define i32 @bar(i8* %c) nounwind {
-entry:
- %c_addr = alloca i8* ; <i8**> [#uses=3]
- %retval = alloca i32 ; <i32*> [#uses=2]
- %0 = alloca i32 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- %1 = bitcast i8** %c_addr to { }* ; <{ }*> [#uses=1]
- call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*))
- store i8* %c, i8** %c_addr
- call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %2 = load i8** %c_addr, align 4 ; <i8*> [#uses=1]
- %3 = load i8* %2, align 1 ; <i8> [#uses=1]
- %4 = sext i8 %3 to i32 ; <i32> [#uses=1]
- %5 = add i32 %4, 42 ; <i32> [#uses=1]
- store i32 %5, i32* %0, align 4
- %6 = load i32* %0, align 4 ; <i32> [#uses=1]
- store i32 %6, i32* %retval, align 4
- br label %return
-
-return: ; preds = %entry
- %retval1 = load i32* %retval ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 1, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))
- ret i32 %retval1
-}
-
-declare void @llvm.dbg.func.start({ }*) nounwind
-
-declare void @llvm.dbg.declare({ }*, { }*) nounwind
-
-declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
-
-declare void @llvm.dbg.region.end({ }*) nounwind
-
-define i32 @main() nounwind {
-entry:
- %retval = alloca i32 ; <i32*> [#uses=2]
- %0 = alloca i32 ; <i32*> [#uses=2]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*))
- call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- %1 = call i32 @bar(i8* getelementptr ([3 x i8]* @"\01LC", i32 0, i32 0)) nounwind ; <i32> [#uses=1]
- store i32 %1, i32* %0, align 4
- %2 = load i32* %0, align 4 ; <i32> [#uses=1]
- store i32 %2, i32* %retval, align 4
- br label %return
-
-return: ; preds = %entry
- %retval1 = load i32* %retval ; <i32> [#uses=1]
- call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))
- call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram11 to { }*))
- ret i32 %retval1
-}
More information about the llvm-branch-commits
mailing list