1e1649c31SDevang Patel //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===// 2e1649c31SDevang Patel // 3e1649c31SDevang Patel // The LLVM Compiler Infrastructure 4e1649c31SDevang Patel // 5e1649c31SDevang Patel // This file is distributed under the University of Illinois Open Source 6e1649c31SDevang Patel // License. See LICENSE.TXT for details. 7e1649c31SDevang Patel // 8e1649c31SDevang Patel //===----------------------------------------------------------------------===// 9e1649c31SDevang Patel // 10e1649c31SDevang Patel // This file implements LexicalScopes analysis. 11e1649c31SDevang Patel // 12e1649c31SDevang Patel // This pass collects lexical scope information and maps machine instructions 13e1649c31SDevang Patel // to respective lexical scopes. 14e1649c31SDevang Patel // 15e1649c31SDevang Patel //===----------------------------------------------------------------------===// 16e1649c31SDevang Patel 17e1649c31SDevang Patel #define DEBUG_TYPE "lexicalscopes" 18e1649c31SDevang Patel #include "llvm/CodeGen/LexicalScopes.h" 19e1649c31SDevang Patel #include "llvm/Function.h" 20e1649c31SDevang Patel #include "llvm/Analysis/DebugInfo.h" 21e1649c31SDevang Patel #include "llvm/CodeGen/MachineFunction.h" 22e1649c31SDevang Patel #include "llvm/CodeGen/MachineInstr.h" 23e1649c31SDevang Patel #include "llvm/Support/Debug.h" 24e1649c31SDevang Patel #include "llvm/Support/ErrorHandling.h" 25e1649c31SDevang Patel #include "llvm/Support/FormattedStream.h" 26e1649c31SDevang Patel using namespace llvm; 27e1649c31SDevang Patel 28e1649c31SDevang Patel LexicalScopes::~LexicalScopes() { 29e1649c31SDevang Patel releaseMemory(); 30e1649c31SDevang Patel } 31e1649c31SDevang Patel 32e1649c31SDevang Patel /// releaseMemory - release memory. 33e1649c31SDevang Patel void LexicalScopes::releaseMemory() { 34e1649c31SDevang Patel MF = NULL; 35e1649c31SDevang Patel CurrentFnLexicalScope = NULL; 36e1649c31SDevang Patel DeleteContainerSeconds(LexicalScopeMap); 37e1649c31SDevang Patel DeleteContainerSeconds(AbstractScopeMap); 38e1649c31SDevang Patel InlinedLexicalScopeMap.clear(); 39e1649c31SDevang Patel AbstractScopesList.clear(); 40e1649c31SDevang Patel } 41e1649c31SDevang Patel 42e1649c31SDevang Patel /// initialize - Scan machine function and constuct lexical scope nest. 43e1649c31SDevang Patel void LexicalScopes::initialize(const MachineFunction &Fn) { 44e1649c31SDevang Patel releaseMemory(); 45e1649c31SDevang Patel MF = &Fn; 46e1649c31SDevang Patel SmallVector<InsnRange, 4> MIRanges; 47e1649c31SDevang Patel DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap; 48e1649c31SDevang Patel extractLexicalScopes(MIRanges, MI2ScopeMap); 49e1649c31SDevang Patel if (CurrentFnLexicalScope) { 50e1649c31SDevang Patel constructScopeNest(CurrentFnLexicalScope); 51e1649c31SDevang Patel assignInstructionRanges(MIRanges, MI2ScopeMap); 52e1649c31SDevang Patel } 53e1649c31SDevang Patel } 54e1649c31SDevang Patel 55e1649c31SDevang Patel /// extractLexicalScopes - Extract instruction ranges for each lexical scopes 56e1649c31SDevang Patel /// for the given machine function. 57e1649c31SDevang Patel void LexicalScopes:: 58e1649c31SDevang Patel extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges, 59e1649c31SDevang Patel DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { 60e1649c31SDevang Patel 61e1649c31SDevang Patel // Scan each instruction and create scopes. First build working set of scopes. 62e1649c31SDevang Patel for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 63e1649c31SDevang Patel I != E; ++I) { 64e1649c31SDevang Patel const MachineInstr *RangeBeginMI = NULL; 65e1649c31SDevang Patel const MachineInstr *PrevMI = NULL; 66e1649c31SDevang Patel DebugLoc PrevDL; 67e1649c31SDevang Patel for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); 68e1649c31SDevang Patel II != IE; ++II) { 69e1649c31SDevang Patel const MachineInstr *MInsn = II; 70e1649c31SDevang Patel 71e1649c31SDevang Patel // Check if instruction has valid location information. 72e1649c31SDevang Patel const DebugLoc MIDL = MInsn->getDebugLoc(); 73e1649c31SDevang Patel if (MIDL.isUnknown()) { 74e1649c31SDevang Patel PrevMI = MInsn; 75e1649c31SDevang Patel continue; 76e1649c31SDevang Patel } 77e1649c31SDevang Patel 78e1649c31SDevang Patel // If scope has not changed then skip this instruction. 79e1649c31SDevang Patel if (MIDL == PrevDL) { 80e1649c31SDevang Patel PrevMI = MInsn; 81e1649c31SDevang Patel continue; 82e1649c31SDevang Patel } 83e1649c31SDevang Patel 84e1649c31SDevang Patel // Ignore DBG_VALUE. It does not contribute to any instruction in output. 85e1649c31SDevang Patel if (MInsn->isDebugValue()) 86e1649c31SDevang Patel continue; 87e1649c31SDevang Patel 88e1649c31SDevang Patel if (RangeBeginMI) { 89e1649c31SDevang Patel // If we have already seen a beginning of an instruction range and 90e1649c31SDevang Patel // current instruction scope does not match scope of first instruction 91e1649c31SDevang Patel // in this range then create a new instruction range. 92e1649c31SDevang Patel InsnRange R(RangeBeginMI, PrevMI); 93e1649c31SDevang Patel MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 94e1649c31SDevang Patel MIRanges.push_back(R); 95e1649c31SDevang Patel } 96e1649c31SDevang Patel 97e1649c31SDevang Patel // This is a beginning of a new instruction range. 98e1649c31SDevang Patel RangeBeginMI = MInsn; 99e1649c31SDevang Patel 100e1649c31SDevang Patel // Reset previous markers. 101e1649c31SDevang Patel PrevMI = MInsn; 102e1649c31SDevang Patel PrevDL = MIDL; 103e1649c31SDevang Patel } 104e1649c31SDevang Patel 105e1649c31SDevang Patel // Create last instruction range. 106e1649c31SDevang Patel if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { 107e1649c31SDevang Patel InsnRange R(RangeBeginMI, PrevMI); 108e1649c31SDevang Patel MIRanges.push_back(R); 109e1649c31SDevang Patel MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 110e1649c31SDevang Patel } 111e1649c31SDevang Patel } 112e1649c31SDevang Patel } 113e1649c31SDevang Patel 114e1649c31SDevang Patel /// findLexicalScope - Find lexical scope, either regular or inlined, for the 115e1649c31SDevang Patel /// given DebugLoc. Return NULL if not found. 116e1649c31SDevang Patel LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { 117e1649c31SDevang Patel MDNode *Scope = NULL; 118e1649c31SDevang Patel MDNode *IA = NULL; 119e1649c31SDevang Patel DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext()); 120e1649c31SDevang Patel if (!Scope) return NULL; 1216647b830SEric Christopher 1226647b830SEric Christopher // The scope that we were created with could have an extra file - which 1236647b830SEric Christopher // isn't what we care about in this case. 1246647b830SEric Christopher DIDescriptor D = DIDescriptor(Scope); 1256647b830SEric Christopher if (D.isLexicalBlockFile()) 1266647b830SEric Christopher Scope = DILexicalBlockFile(Scope).getScope(); 1276647b830SEric Christopher 128e1649c31SDevang Patel if (IA) 129e1649c31SDevang Patel return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA)); 1306647b830SEric Christopher return LexicalScopeMap.lookup(Scope); 131e1649c31SDevang Patel } 132e1649c31SDevang Patel 133e1649c31SDevang Patel /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If 134e1649c31SDevang Patel /// not available then create new lexical scope. 135e1649c31SDevang Patel LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) { 136e1649c31SDevang Patel MDNode *Scope = NULL; 137e1649c31SDevang Patel MDNode *InlinedAt = NULL; 138e1649c31SDevang Patel DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext()); 1396647b830SEric Christopher 140e1649c31SDevang Patel if (InlinedAt) { 141e1649c31SDevang Patel // Create an abstract scope for inlined function. 142e1649c31SDevang Patel getOrCreateAbstractScope(Scope); 143e1649c31SDevang Patel // Create an inlined scope for inlined function. 144e1649c31SDevang Patel return getOrCreateInlinedScope(Scope, InlinedAt); 145e1649c31SDevang Patel } 146e1649c31SDevang Patel 147e1649c31SDevang Patel return getOrCreateRegularScope(Scope); 148e1649c31SDevang Patel } 149e1649c31SDevang Patel 150e1649c31SDevang Patel /// getOrCreateRegularScope - Find or create a regular lexical scope. 151e1649c31SDevang Patel LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { 1526647b830SEric Christopher DIDescriptor D = DIDescriptor(Scope); 153*76933f4cSEric Christopher if (D.isLexicalBlockFile()) { 1546647b830SEric Christopher Scope = DILexicalBlockFile(Scope).getScope(); 155*76933f4cSEric Christopher D = DIDescriptor(Scope); 156*76933f4cSEric Christopher } 1576647b830SEric Christopher 158e1649c31SDevang Patel LexicalScope *WScope = LexicalScopeMap.lookup(Scope); 159e1649c31SDevang Patel if (WScope) 160e1649c31SDevang Patel return WScope; 161e1649c31SDevang Patel 162e1649c31SDevang Patel LexicalScope *Parent = NULL; 1636647b830SEric Christopher if (D.isLexicalBlock()) 164e1649c31SDevang Patel Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope)); 165e1649c31SDevang Patel WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false); 166e1649c31SDevang Patel LexicalScopeMap.insert(std::make_pair(Scope, WScope)); 167e1649c31SDevang Patel if (!Parent && DIDescriptor(Scope).isSubprogram() 168e1649c31SDevang Patel && DISubprogram(Scope).describes(MF->getFunction())) 169e1649c31SDevang Patel CurrentFnLexicalScope = WScope; 170e1649c31SDevang Patel 171e1649c31SDevang Patel return WScope; 172e1649c31SDevang Patel } 173e1649c31SDevang Patel 174e1649c31SDevang Patel /// getOrCreateInlinedScope - Find or create an inlined lexical scope. 175e1649c31SDevang Patel LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope, 176e1649c31SDevang Patel MDNode *InlinedAt) { 177e1649c31SDevang Patel LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt); 178e1649c31SDevang Patel if (InlinedScope) 179e1649c31SDevang Patel return InlinedScope; 180e1649c31SDevang Patel 181e1649c31SDevang Patel DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt); 182e1649c31SDevang Patel InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc), 183e1649c31SDevang Patel DIDescriptor(Scope), InlinedAt, false); 184e1649c31SDevang Patel InlinedLexicalScopeMap[InlinedLoc] = InlinedScope; 185e1649c31SDevang Patel LexicalScopeMap[InlinedAt] = InlinedScope; 186e1649c31SDevang Patel return InlinedScope; 187e1649c31SDevang Patel } 188e1649c31SDevang Patel 189e1649c31SDevang Patel /// getOrCreateAbstractScope - Find or create an abstract lexical scope. 190e1649c31SDevang Patel LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) { 191e1649c31SDevang Patel assert(N && "Invalid Scope encoding!"); 192e1649c31SDevang Patel 1936647b830SEric Christopher DIDescriptor Scope(N); 1946647b830SEric Christopher if (Scope.isLexicalBlockFile()) 1956647b830SEric Christopher Scope = DILexicalBlockFile(Scope).getScope(); 196e1649c31SDevang Patel LexicalScope *AScope = AbstractScopeMap.lookup(N); 197e1649c31SDevang Patel if (AScope) 198e1649c31SDevang Patel return AScope; 199e1649c31SDevang Patel 200e1649c31SDevang Patel LexicalScope *Parent = NULL; 201e1649c31SDevang Patel if (Scope.isLexicalBlock()) { 202e1649c31SDevang Patel DILexicalBlock DB(N); 203e1649c31SDevang Patel DIDescriptor ParentDesc = DB.getContext(); 204e1649c31SDevang Patel Parent = getOrCreateAbstractScope(ParentDesc); 205e1649c31SDevang Patel } 206e1649c31SDevang Patel AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true); 207e1649c31SDevang Patel AbstractScopeMap[N] = AScope; 208e1649c31SDevang Patel if (DIDescriptor(N).isSubprogram()) 209e1649c31SDevang Patel AbstractScopesList.push_back(AScope); 210e1649c31SDevang Patel return AScope; 211e1649c31SDevang Patel } 212e1649c31SDevang Patel 213e1649c31SDevang Patel /// constructScopeNest 214e1649c31SDevang Patel void LexicalScopes::constructScopeNest(LexicalScope *Scope) { 215e1649c31SDevang Patel assert (Scope && "Unable to calculate scop edominance graph!"); 216e1649c31SDevang Patel SmallVector<LexicalScope *, 4> WorkStack; 217e1649c31SDevang Patel WorkStack.push_back(Scope); 218e1649c31SDevang Patel unsigned Counter = 0; 219e1649c31SDevang Patel while (!WorkStack.empty()) { 220e1649c31SDevang Patel LexicalScope *WS = WorkStack.back(); 221e1649c31SDevang Patel const SmallVector<LexicalScope *, 4> &Children = WS->getChildren(); 222e1649c31SDevang Patel bool visitedChildren = false; 223e1649c31SDevang Patel for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(), 224e1649c31SDevang Patel SE = Children.end(); SI != SE; ++SI) { 225e1649c31SDevang Patel LexicalScope *ChildScope = *SI; 226e1649c31SDevang Patel if (!ChildScope->getDFSOut()) { 227e1649c31SDevang Patel WorkStack.push_back(ChildScope); 228e1649c31SDevang Patel visitedChildren = true; 229e1649c31SDevang Patel ChildScope->setDFSIn(++Counter); 230e1649c31SDevang Patel break; 231e1649c31SDevang Patel } 232e1649c31SDevang Patel } 233e1649c31SDevang Patel if (!visitedChildren) { 234e1649c31SDevang Patel WorkStack.pop_back(); 235e1649c31SDevang Patel WS->setDFSOut(++Counter); 236e1649c31SDevang Patel } 237e1649c31SDevang Patel } 238e1649c31SDevang Patel } 239e1649c31SDevang Patel 240784077ebSDevang Patel /// assignInstructionRanges - Find ranges of instructions covered by each 241784077ebSDevang Patel /// lexical scope. 242e1649c31SDevang Patel void LexicalScopes:: 243e1649c31SDevang Patel assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges, 244784077ebSDevang Patel DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) 245784077ebSDevang Patel { 246e1649c31SDevang Patel 247e1649c31SDevang Patel LexicalScope *PrevLexicalScope = NULL; 248e1649c31SDevang Patel for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(), 249e1649c31SDevang Patel RE = MIRanges.end(); RI != RE; ++RI) { 250e1649c31SDevang Patel const InsnRange &R = *RI; 251e1649c31SDevang Patel LexicalScope *S = MI2ScopeMap.lookup(R.first); 252e1649c31SDevang Patel assert (S && "Lost LexicalScope for a machine instruction!"); 253e1649c31SDevang Patel if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) 254e1649c31SDevang Patel PrevLexicalScope->closeInsnRange(S); 255e1649c31SDevang Patel S->openInsnRange(R.first); 256e1649c31SDevang Patel S->extendInsnRange(R.second); 257e1649c31SDevang Patel PrevLexicalScope = S; 258e1649c31SDevang Patel } 259e1649c31SDevang Patel 260e1649c31SDevang Patel if (PrevLexicalScope) 261e1649c31SDevang Patel PrevLexicalScope->closeInsnRange(); 262e1649c31SDevang Patel } 263e1649c31SDevang Patel 264e1649c31SDevang Patel /// getMachineBasicBlocks - Populate given set using machine basic blocks which 265e1649c31SDevang Patel /// have machine instructions that belong to lexical scope identified by 266e1649c31SDevang Patel /// DebugLoc. 267e1649c31SDevang Patel void LexicalScopes:: 268784077ebSDevang Patel getMachineBasicBlocks(DebugLoc DL, 269784077ebSDevang Patel SmallPtrSet<const MachineBasicBlock*, 4> &MBBs) { 270e1649c31SDevang Patel MBBs.clear(); 271e1649c31SDevang Patel LexicalScope *Scope = getOrCreateLexicalScope(DL); 272e1649c31SDevang Patel if (!Scope) 273e1649c31SDevang Patel return; 274e1649c31SDevang Patel 275db4374a2SDevang Patel if (Scope == CurrentFnLexicalScope) { 276db4374a2SDevang Patel for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 277db4374a2SDevang Patel I != E; ++I) 278db4374a2SDevang Patel MBBs.insert(I); 279db4374a2SDevang Patel return; 280db4374a2SDevang Patel } 281db4374a2SDevang Patel 282e1649c31SDevang Patel SmallVector<InsnRange, 4> &InsnRanges = Scope->getRanges(); 283e1649c31SDevang Patel for (SmallVector<InsnRange, 4>::iterator I = InsnRanges.begin(), 284e1649c31SDevang Patel E = InsnRanges.end(); I != E; ++I) { 285e1649c31SDevang Patel InsnRange &R = *I; 286e1649c31SDevang Patel MBBs.insert(R.first->getParent()); 287e1649c31SDevang Patel } 288e1649c31SDevang Patel } 289e1649c31SDevang Patel 290e1649c31SDevang Patel /// dominates - Return true if DebugLoc's lexical scope dominates at least one 291e1649c31SDevang Patel /// machine instruction's lexical scope in a given machine basic block. 292e1649c31SDevang Patel bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) { 293e1649c31SDevang Patel LexicalScope *Scope = getOrCreateLexicalScope(DL); 294e1649c31SDevang Patel if (!Scope) 295e1649c31SDevang Patel return false; 296db4374a2SDevang Patel 297db4374a2SDevang Patel // Current function scope covers all basic blocks in the function. 298db4374a2SDevang Patel if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF) 299db4374a2SDevang Patel return true; 300db4374a2SDevang Patel 301e1649c31SDevang Patel bool Result = false; 302e1649c31SDevang Patel for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); 303e1649c31SDevang Patel I != E; ++I) { 304e1649c31SDevang Patel DebugLoc IDL = I->getDebugLoc(); 305e1649c31SDevang Patel if (IDL.isUnknown()) 306e1649c31SDevang Patel continue; 307e1649c31SDevang Patel if (LexicalScope *IScope = getOrCreateLexicalScope(IDL)) 308e1649c31SDevang Patel if (Scope->dominates(IScope)) 309e1649c31SDevang Patel return true; 310e1649c31SDevang Patel } 311e1649c31SDevang Patel return Result; 312e1649c31SDevang Patel } 313e1649c31SDevang Patel 314e1649c31SDevang Patel /// dump - Print data structures. 315e1649c31SDevang Patel void LexicalScope::dump() const { 316e1649c31SDevang Patel #ifndef NDEBUG 317e1649c31SDevang Patel raw_ostream &err = dbgs(); 318e1649c31SDevang Patel err.indent(IndentLevel); 319e1649c31SDevang Patel err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; 320e1649c31SDevang Patel const MDNode *N = Desc; 321e1649c31SDevang Patel N->dump(); 322e1649c31SDevang Patel if (AbstractScope) 323e1649c31SDevang Patel err << "Abstract Scope\n"; 324e1649c31SDevang Patel 325e1649c31SDevang Patel IndentLevel += 2; 326e1649c31SDevang Patel if (!Children.empty()) 327e1649c31SDevang Patel err << "Children ...\n"; 328e1649c31SDevang Patel for (unsigned i = 0, e = Children.size(); i != e; ++i) 329e1649c31SDevang Patel if (Children[i] != this) 330e1649c31SDevang Patel Children[i]->dump(); 331e1649c31SDevang Patel 332e1649c31SDevang Patel IndentLevel -= 2; 333e1649c31SDevang Patel #endif 334e1649c31SDevang Patel } 335e1649c31SDevang Patel 336