-/// getOrCreateRegularScope - Create regular DbgScope.
-DbgScope *DwarfDebug::getOrCreateRegularScope(MDNode *Scope) {
- DbgScope *WScope = DbgScopeMap.lookup(Scope);
- if (WScope)
- return WScope;
- WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
- DbgScopeMap.insert(std::make_pair(Scope, WScope));
- if (DIDescriptor(Scope).isLexicalBlock()) {
- DbgScope *Parent =
- getOrCreateDbgScope(DebugLoc::getFromDILexicalBlock(Scope));
- WScope->setParent(Parent);
- Parent->addScope(WScope);
- } else if (DIDescriptor(Scope).isSubprogram()
- && DISubprogram(Scope).describes(Asm->MF->getFunction()))
- CurrentFnDbgScope = WScope;
-
- return WScope;
-}
-
-/// getOrCreateInlinedScope - Create inlined scope.
-DbgScope *DwarfDebug::getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt){
- DbgScope *InlinedScope = DbgScopeMap.lookup(InlinedAt);
- if (InlinedScope)
- return InlinedScope;
-
- InlinedScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
- DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
- InlinedDbgScopeMap[InlinedLoc] = InlinedScope;
- DbgScopeMap[InlinedAt] = InlinedScope;
- DbgScope *Parent = getOrCreateDbgScope(InlinedLoc);
- InlinedScope->setParent(Parent);
- Parent->addScope(InlinedScope);
- return InlinedScope;
-}
-
-/// getOrCreateDbgScope - Create DbgScope for the scope.
-DbgScope *DwarfDebug::getOrCreateDbgScope(DebugLoc DL) {
- LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
- MDNode *Scope = NULL;
- MDNode *InlinedAt = NULL;
- DL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx);
- if (!InlinedAt)
- return getOrCreateRegularScope(Scope);
-
- // Create an abstract scope for inlined function.
- getOrCreateAbstractScope(Scope);
- // Create an inlined scope for inlined function.
- return getOrCreateInlinedScope(Scope, InlinedAt);
-}
-
-/// calculateDominanceGraph - Calculate dominance graph for DbgScope
-/// hierarchy.
-static void calculateDominanceGraph(DbgScope *Scope) {
- assert (Scope && "Unable to calculate scop edominance graph!");
- SmallVector<DbgScope *, 4> WorkStack;
- WorkStack.push_back(Scope);
- unsigned Counter = 0;
- while (!WorkStack.empty()) {
- DbgScope *WS = WorkStack.back();
- const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
- bool visitedChildren = false;
- for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
- SE = Children.end(); SI != SE; ++SI) {
- DbgScope *ChildScope = *SI;
- if (!ChildScope->getDFSOut()) {
- WorkStack.push_back(ChildScope);
- visitedChildren = true;
- ChildScope->setDFSIn(++Counter);
-#ifndef NDEBUG
- if (PrintDbgScope)
- dbgs() << "calculate dbgscope dom: In " << Counter << "\n";
-#endif
- break;
- }
- }
- if (!visitedChildren) {
- WorkStack.pop_back();
- WS->setDFSOut(++Counter);
-#ifndef NDEBUG
- if (PrintDbgScope)
- dbgs() << "calculate dbgscope dom: In " << WS->getDFSIn()
- << " Out " << Counter << "\n";
-#endif
- }
- }
-}
-
-/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
-static
-void printDbgScopeInfo(const MachineFunction *MF,
- DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
-{
-#ifndef NDEBUG
- LLVMContext &Ctx = MF->getFunction()->getContext();
- unsigned PrevDFSIn = 0;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
- I != E; ++I) {
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- const MachineInstr *MInsn = II;
- MDNode *Scope = NULL;
- MDNode *InlinedAt = NULL;
-
- // Check if instruction has valid location information.
- DebugLoc MIDL = MInsn->getDebugLoc();
- if (!MIDL.isUnknown()) {
- MIDL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx);
- dbgs() << " [ ";
- if (InlinedAt)
- dbgs() << "*";
- DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
- MI2ScopeMap.find(MInsn);
- if (DI != MI2ScopeMap.end()) {
- DbgScope *S = DI->second;
- dbgs() << S->getDFSIn();
- PrevDFSIn = S->getDFSIn();
- } else
- dbgs() << PrevDFSIn;
- } else
- dbgs() << " [ x" << PrevDFSIn;
- dbgs() << " ]";
- MInsn->dump();
- }
- dbgs() << "\n";
- }
-#endif
-}
-/// extractScopeInformation - Scan machine instructions in this function
-/// and collect DbgScopes. Return true, if at least one scope was found.
-bool DwarfDebug::extractScopeInformation() {
- // If scope information was extracted using .dbg intrinsics then there is not
- // any need to extract these information by scanning each instruction.
- if (!DbgScopeMap.empty())
- return false;
-
- // Scan each instruction and create scopes. First build working set of scopes.
- SmallVector<DbgRange, 4> MIRanges;
- DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
- for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
- I != E; ++I) {
- const MachineInstr *RangeBeginMI = NULL;
- const MachineInstr *PrevMI = NULL;
- DebugLoc PrevDL;
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- const MachineInstr *MInsn = II;
-
- // Check if instruction has valid location information.
- const DebugLoc MIDL = MInsn->getDebugLoc();
- if (MIDL.isUnknown()) {
- PrevMI = MInsn;
- continue;
- }
-
- // If scope has not changed then skip this instruction.
- if (MIDL == PrevDL) {
- PrevMI = MInsn;
- continue;
- }
-
- // Ignore DBG_VALUE. It does not contribute to any instruction in output.
- if (MInsn->isDebugValue())
- continue;
-
- if (RangeBeginMI) {
- // If we have already seen a beginning of an instruction range and
- // current instruction scope does not match scope of first instruction
- // in this range then create a new instruction range.
- DEBUG(dbgs() << "Creating new instruction range :\n");
- DEBUG(dbgs() << "Begin Range at " << *RangeBeginMI);
- DEBUG(dbgs() << "End Range at " << *PrevMI);
- DEBUG(dbgs() << "Next Range starting at " << *MInsn);
- DEBUG(dbgs() << "------------------------\n");
- DbgRange R(RangeBeginMI, PrevMI);
- MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL);
- MIRanges.push_back(R);
- }
-
- // This is a beginning of a new instruction range.
- RangeBeginMI = MInsn;
-
- // Reset previous markers.
- PrevMI = MInsn;
- PrevDL = MIDL;
- }
-
- // Create last instruction range.
- if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
- DbgRange R(RangeBeginMI, PrevMI);
- MIRanges.push_back(R);
- MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL);
- }
- }
-
- if (!CurrentFnDbgScope)
- return false;
-
- calculateDominanceGraph(CurrentFnDbgScope);
- if (PrintDbgScope)
- printDbgScopeInfo(Asm->MF, MI2ScopeMap);
-
- // Find ranges of instructions covered by each DbgScope;
- DbgScope *PrevDbgScope = NULL;
- for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
- RE = MIRanges.end(); RI != RE; ++RI) {
- const DbgRange &R = *RI;
- DbgScope *S = MI2ScopeMap.lookup(R.first);
- assert (S && "Lost DbgScope for a machine instruction!");
- if (PrevDbgScope && !PrevDbgScope->dominates(S))
- PrevDbgScope->closeInsnRange(S);
- S->openInsnRange(R.first);
- S->extendInsnRange(R.second);
- PrevDbgScope = S;
- }
-
- if (PrevDbgScope)
- PrevDbgScope->closeInsnRange();
-
- identifyScopeMarkers();
-
- return !DbgScopeMap.empty();
-}
-