1 //=- LiveVariables.cpp - Live Variable Analysis for Source CFGs ----------*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements Live Variables analysis for source-level CFGs. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Analysis/Analyses/LiveVariables.h" 14 #include "clang/AST/Stmt.h" 15 #include "clang/AST/StmtVisitor.h" 16 #include "clang/Analysis/AnalysisDeclContext.h" 17 #include "clang/Analysis/CFG.h" 18 #include "clang/Analysis/FlowSensitive/DataflowWorklist.h" 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <algorithm> 22 #include <vector> 23 24 using namespace clang; 25 26 namespace { 27 class LiveVariablesImpl { 28 public: 29 AnalysisDeclContext &analysisContext; 30 llvm::ImmutableSet<const Stmt *>::Factory SSetFact; 31 llvm::ImmutableSet<const VarDecl *>::Factory DSetFact; 32 llvm::ImmutableSet<const BindingDecl *>::Factory BSetFact; 33 llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksEndToLiveness; 34 llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues> blocksBeginToLiveness; 35 llvm::DenseMap<const Stmt *, LiveVariables::LivenessValues> stmtsToLiveness; 36 llvm::DenseMap<const DeclRefExpr *, unsigned> inAssignment; 37 const bool killAtAssign; 38 39 LiveVariables::LivenessValues 40 merge(LiveVariables::LivenessValues valsA, 41 LiveVariables::LivenessValues valsB); 42 43 LiveVariables::LivenessValues 44 runOnBlock(const CFGBlock *block, LiveVariables::LivenessValues val, 45 LiveVariables::Observer *obs = nullptr); 46 47 void dumpBlockLiveness(const SourceManager& M); 48 void dumpStmtLiveness(const SourceManager& M); 49 50 LiveVariablesImpl(AnalysisDeclContext &ac, bool KillAtAssign) 51 : analysisContext(ac), 52 SSetFact(false), // Do not canonicalize ImmutableSets by default. 53 DSetFact(false), // This is a *major* performance win. 54 BSetFact(false), 55 killAtAssign(KillAtAssign) {} 56 }; 57 } 58 59 static LiveVariablesImpl &getImpl(void *x) { 60 return *((LiveVariablesImpl *) x); 61 } 62 63 //===----------------------------------------------------------------------===// 64 // Operations and queries on LivenessValues. 65 //===----------------------------------------------------------------------===// 66 67 bool LiveVariables::LivenessValues::isLive(const Stmt *S) const { 68 return liveStmts.contains(S); 69 } 70 71 bool LiveVariables::LivenessValues::isLive(const VarDecl *D) const { 72 if (const auto *DD = dyn_cast<DecompositionDecl>(D)) { 73 bool alive = false; 74 for (const BindingDecl *BD : DD->bindings()) 75 alive |= liveBindings.contains(BD); 76 return alive; 77 } 78 return liveDecls.contains(D); 79 } 80 81 namespace { 82 template <typename SET> 83 SET mergeSets(SET A, SET B) { 84 if (A.isEmpty()) 85 return B; 86 87 for (typename SET::iterator it = B.begin(), ei = B.end(); it != ei; ++it) { 88 A = A.add(*it); 89 } 90 return A; 91 } 92 } // namespace 93 94 void LiveVariables::Observer::anchor() { } 95 96 LiveVariables::LivenessValues 97 LiveVariablesImpl::merge(LiveVariables::LivenessValues valsA, 98 LiveVariables::LivenessValues valsB) { 99 100 llvm::ImmutableSetRef<const Stmt *> 101 SSetRefA(valsA.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()), 102 SSetRefB(valsB.liveStmts.getRootWithoutRetain(), SSetFact.getTreeFactory()); 103 104 105 llvm::ImmutableSetRef<const VarDecl *> 106 DSetRefA(valsA.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()), 107 DSetRefB(valsB.liveDecls.getRootWithoutRetain(), DSetFact.getTreeFactory()); 108 109 llvm::ImmutableSetRef<const BindingDecl *> 110 BSetRefA(valsA.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()), 111 BSetRefB(valsB.liveBindings.getRootWithoutRetain(), BSetFact.getTreeFactory()); 112 113 SSetRefA = mergeSets(SSetRefA, SSetRefB); 114 DSetRefA = mergeSets(DSetRefA, DSetRefB); 115 BSetRefA = mergeSets(BSetRefA, BSetRefB); 116 117 // asImmutableSet() canonicalizes the tree, allowing us to do an easy 118 // comparison afterwards. 119 return LiveVariables::LivenessValues(SSetRefA.asImmutableSet(), 120 DSetRefA.asImmutableSet(), 121 BSetRefA.asImmutableSet()); 122 } 123 124 bool LiveVariables::LivenessValues::equals(const LivenessValues &V) const { 125 return liveStmts == V.liveStmts && liveDecls == V.liveDecls; 126 } 127 128 //===----------------------------------------------------------------------===// 129 // Query methods. 130 //===----------------------------------------------------------------------===// 131 132 static bool isAlwaysAlive(const VarDecl *D) { 133 return D->hasGlobalStorage(); 134 } 135 136 bool LiveVariables::isLive(const CFGBlock *B, const VarDecl *D) { 137 return isAlwaysAlive(D) || getImpl(impl).blocksEndToLiveness[B].isLive(D); 138 } 139 140 bool LiveVariables::isLive(const Stmt *S, const VarDecl *D) { 141 return isAlwaysAlive(D) || getImpl(impl).stmtsToLiveness[S].isLive(D); 142 } 143 144 bool LiveVariables::isLive(const Stmt *Loc, const Stmt *S) { 145 return getImpl(impl).stmtsToLiveness[Loc].isLive(S); 146 } 147 148 //===----------------------------------------------------------------------===// 149 // Dataflow computation. 150 //===----------------------------------------------------------------------===// 151 152 namespace { 153 class TransferFunctions : public StmtVisitor<TransferFunctions> { 154 LiveVariablesImpl &LV; 155 LiveVariables::LivenessValues &val; 156 LiveVariables::Observer *observer; 157 const CFGBlock *currentBlock; 158 public: 159 TransferFunctions(LiveVariablesImpl &im, 160 LiveVariables::LivenessValues &Val, 161 LiveVariables::Observer *Observer, 162 const CFGBlock *CurrentBlock) 163 : LV(im), val(Val), observer(Observer), currentBlock(CurrentBlock) {} 164 165 void VisitBinaryOperator(BinaryOperator *BO); 166 void VisitBlockExpr(BlockExpr *BE); 167 void VisitDeclRefExpr(DeclRefExpr *DR); 168 void VisitDeclStmt(DeclStmt *DS); 169 void VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS); 170 void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE); 171 void VisitUnaryOperator(UnaryOperator *UO); 172 void Visit(Stmt *S); 173 }; 174 } // namespace 175 176 static const VariableArrayType *FindVA(QualType Ty) { 177 const Type *ty = Ty.getTypePtr(); 178 while (const ArrayType *VT = dyn_cast<ArrayType>(ty)) { 179 if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(VT)) 180 if (VAT->getSizeExpr()) 181 return VAT; 182 183 ty = VT->getElementType().getTypePtr(); 184 } 185 186 return nullptr; 187 } 188 189 static const Stmt *LookThroughStmt(const Stmt *S) { 190 while (S) { 191 if (const Expr *Ex = dyn_cast<Expr>(S)) 192 S = Ex->IgnoreParens(); 193 if (const FullExpr *FE = dyn_cast<FullExpr>(S)) { 194 S = FE->getSubExpr(); 195 continue; 196 } 197 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) { 198 S = OVE->getSourceExpr(); 199 continue; 200 } 201 break; 202 } 203 return S; 204 } 205 206 static void AddLiveStmt(llvm::ImmutableSet<const Stmt *> &Set, 207 llvm::ImmutableSet<const Stmt *>::Factory &F, 208 const Stmt *S) { 209 Set = F.add(Set, LookThroughStmt(S)); 210 } 211 212 void TransferFunctions::Visit(Stmt *S) { 213 if (observer) 214 observer->observeStmt(S, currentBlock, val); 215 216 StmtVisitor<TransferFunctions>::Visit(S); 217 218 if (isa<Expr>(S)) { 219 val.liveStmts = LV.SSetFact.remove(val.liveStmts, S); 220 } 221 222 // Mark all children expressions live. 223 224 switch (S->getStmtClass()) { 225 default: 226 break; 227 case Stmt::StmtExprClass: { 228 // For statement expressions, look through the compound statement. 229 S = cast<StmtExpr>(S)->getSubStmt(); 230 break; 231 } 232 case Stmt::CXXMemberCallExprClass: { 233 // Include the implicit "this" pointer as being live. 234 CXXMemberCallExpr *CE = cast<CXXMemberCallExpr>(S); 235 if (Expr *ImplicitObj = CE->getImplicitObjectArgument()) { 236 AddLiveStmt(val.liveStmts, LV.SSetFact, ImplicitObj); 237 } 238 break; 239 } 240 case Stmt::ObjCMessageExprClass: { 241 // In calls to super, include the implicit "self" pointer as being live. 242 ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S); 243 if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance) 244 val.liveDecls = LV.DSetFact.add(val.liveDecls, 245 LV.analysisContext.getSelfDecl()); 246 break; 247 } 248 case Stmt::DeclStmtClass: { 249 const DeclStmt *DS = cast<DeclStmt>(S); 250 if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) { 251 for (const VariableArrayType* VA = FindVA(VD->getType()); 252 VA != nullptr; VA = FindVA(VA->getElementType())) { 253 AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr()); 254 } 255 } 256 break; 257 } 258 case Stmt::PseudoObjectExprClass: { 259 // A pseudo-object operation only directly consumes its result 260 // expression. 261 Expr *child = cast<PseudoObjectExpr>(S)->getResultExpr(); 262 if (!child) return; 263 if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(child)) 264 child = OV->getSourceExpr(); 265 child = child->IgnoreParens(); 266 val.liveStmts = LV.SSetFact.add(val.liveStmts, child); 267 return; 268 } 269 270 // FIXME: These cases eventually shouldn't be needed. 271 case Stmt::ExprWithCleanupsClass: { 272 S = cast<ExprWithCleanups>(S)->getSubExpr(); 273 break; 274 } 275 case Stmt::CXXBindTemporaryExprClass: { 276 S = cast<CXXBindTemporaryExpr>(S)->getSubExpr(); 277 break; 278 } 279 case Stmt::UnaryExprOrTypeTraitExprClass: { 280 // No need to unconditionally visit subexpressions. 281 return; 282 } 283 case Stmt::IfStmtClass: { 284 // If one of the branches is an expression rather than a compound 285 // statement, it will be bad if we mark it as live at the terminator 286 // of the if-statement (i.e., immediately after the condition expression). 287 AddLiveStmt(val.liveStmts, LV.SSetFact, cast<IfStmt>(S)->getCond()); 288 return; 289 } 290 case Stmt::WhileStmtClass: { 291 // If the loop body is an expression rather than a compound statement, 292 // it will be bad if we mark it as live at the terminator of the loop 293 // (i.e., immediately after the condition expression). 294 AddLiveStmt(val.liveStmts, LV.SSetFact, cast<WhileStmt>(S)->getCond()); 295 return; 296 } 297 case Stmt::DoStmtClass: { 298 // If the loop body is an expression rather than a compound statement, 299 // it will be bad if we mark it as live at the terminator of the loop 300 // (i.e., immediately after the condition expression). 301 AddLiveStmt(val.liveStmts, LV.SSetFact, cast<DoStmt>(S)->getCond()); 302 return; 303 } 304 case Stmt::ForStmtClass: { 305 // If the loop body is an expression rather than a compound statement, 306 // it will be bad if we mark it as live at the terminator of the loop 307 // (i.e., immediately after the condition expression). 308 AddLiveStmt(val.liveStmts, LV.SSetFact, cast<ForStmt>(S)->getCond()); 309 return; 310 } 311 312 } 313 314 for (Stmt *Child : S->children()) { 315 if (Child) 316 AddLiveStmt(val.liveStmts, LV.SSetFact, Child); 317 } 318 } 319 320 static bool writeShouldKill(const VarDecl *VD) { 321 return VD && !VD->getType()->isReferenceType() && 322 !isAlwaysAlive(VD); 323 } 324 325 void TransferFunctions::VisitBinaryOperator(BinaryOperator *B) { 326 if (B->isAssignmentOp()) { 327 if (!LV.killAtAssign) 328 return; 329 330 // Assigning to a variable? 331 Expr *LHS = B->getLHS()->IgnoreParens(); 332 333 if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(LHS)) { 334 const Decl* D = DR->getDecl(); 335 bool Killed = false; 336 337 if (const BindingDecl* BD = dyn_cast<BindingDecl>(D)) { 338 Killed = !BD->getType()->isReferenceType(); 339 if (Killed) 340 val.liveBindings = LV.BSetFact.remove(val.liveBindings, BD); 341 } else if (const auto *VD = dyn_cast<VarDecl>(D)) { 342 Killed = writeShouldKill(VD); 343 if (Killed) 344 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD); 345 346 } 347 348 if (Killed && observer) 349 observer->observerKill(DR); 350 } 351 } 352 } 353 354 void TransferFunctions::VisitBlockExpr(BlockExpr *BE) { 355 for (const VarDecl *VD : 356 LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl())) { 357 if (isAlwaysAlive(VD)) 358 continue; 359 val.liveDecls = LV.DSetFact.add(val.liveDecls, VD); 360 } 361 } 362 363 void TransferFunctions::VisitDeclRefExpr(DeclRefExpr *DR) { 364 const Decl* D = DR->getDecl(); 365 bool InAssignment = LV.inAssignment[DR]; 366 if (const auto *BD = dyn_cast<BindingDecl>(D)) { 367 if (!InAssignment) 368 val.liveBindings = LV.BSetFact.add(val.liveBindings, BD); 369 } else if (const auto *VD = dyn_cast<VarDecl>(D)) { 370 if (!InAssignment && !isAlwaysAlive(VD)) 371 val.liveDecls = LV.DSetFact.add(val.liveDecls, VD); 372 } 373 } 374 375 void TransferFunctions::VisitDeclStmt(DeclStmt *DS) { 376 for (const auto *DI : DS->decls()) { 377 if (const auto *DD = dyn_cast<DecompositionDecl>(DI)) { 378 for (const auto *BD : DD->bindings()) 379 val.liveBindings = LV.BSetFact.remove(val.liveBindings, BD); 380 } else if (const auto *VD = dyn_cast<VarDecl>(DI)) { 381 if (!isAlwaysAlive(VD)) 382 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD); 383 } 384 } 385 } 386 387 void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) { 388 // Kill the iteration variable. 389 DeclRefExpr *DR = nullptr; 390 const VarDecl *VD = nullptr; 391 392 Stmt *element = OS->getElement(); 393 if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) { 394 VD = cast<VarDecl>(DS->getSingleDecl()); 395 } 396 else if ((DR = dyn_cast<DeclRefExpr>(cast<Expr>(element)->IgnoreParens()))) { 397 VD = cast<VarDecl>(DR->getDecl()); 398 } 399 400 if (VD) { 401 val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD); 402 if (observer && DR) 403 observer->observerKill(DR); 404 } 405 } 406 407 void TransferFunctions:: 408 VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *UE) 409 { 410 // While sizeof(var) doesn't technically extend the liveness of 'var', it 411 // does extent the liveness of metadata if 'var' is a VariableArrayType. 412 // We handle that special case here. 413 if (UE->getKind() != UETT_SizeOf || UE->isArgumentType()) 414 return; 415 416 const Expr *subEx = UE->getArgumentExpr(); 417 if (subEx->getType()->isVariableArrayType()) { 418 assert(subEx->isLValue()); 419 val.liveStmts = LV.SSetFact.add(val.liveStmts, subEx->IgnoreParens()); 420 } 421 } 422 423 void TransferFunctions::VisitUnaryOperator(UnaryOperator *UO) { 424 // Treat ++/-- as a kill. 425 // Note we don't actually have to do anything if we don't have an observer, 426 // since a ++/-- acts as both a kill and a "use". 427 if (!observer) 428 return; 429 430 switch (UO->getOpcode()) { 431 default: 432 return; 433 case UO_PostInc: 434 case UO_PostDec: 435 case UO_PreInc: 436 case UO_PreDec: 437 break; 438 } 439 440 if (auto *DR = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens())) { 441 const Decl *D = DR->getDecl(); 442 if (isa<VarDecl>(D) || isa<BindingDecl>(D)) { 443 // Treat ++/-- as a kill. 444 observer->observerKill(DR); 445 } 446 } 447 } 448 449 LiveVariables::LivenessValues 450 LiveVariablesImpl::runOnBlock(const CFGBlock *block, 451 LiveVariables::LivenessValues val, 452 LiveVariables::Observer *obs) { 453 454 TransferFunctions TF(*this, val, obs, block); 455 456 // Visit the terminator (if any). 457 if (const Stmt *term = block->getTerminatorStmt()) 458 TF.Visit(const_cast<Stmt*>(term)); 459 460 // Apply the transfer function for all Stmts in the block. 461 for (CFGBlock::const_reverse_iterator it = block->rbegin(), 462 ei = block->rend(); it != ei; ++it) { 463 const CFGElement &elem = *it; 464 465 if (Optional<CFGAutomaticObjDtor> Dtor = 466 elem.getAs<CFGAutomaticObjDtor>()) { 467 val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl()); 468 continue; 469 } 470 471 if (!elem.getAs<CFGStmt>()) 472 continue; 473 474 const Stmt *S = elem.castAs<CFGStmt>().getStmt(); 475 TF.Visit(const_cast<Stmt*>(S)); 476 stmtsToLiveness[S] = val; 477 } 478 return val; 479 } 480 481 void LiveVariables::runOnAllBlocks(LiveVariables::Observer &obs) { 482 const CFG *cfg = getImpl(impl).analysisContext.getCFG(); 483 for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) 484 getImpl(impl).runOnBlock(*it, getImpl(impl).blocksEndToLiveness[*it], &obs); 485 } 486 487 LiveVariables::LiveVariables(void *im) : impl(im) {} 488 489 LiveVariables::~LiveVariables() { 490 delete (LiveVariablesImpl*) impl; 491 } 492 493 std::unique_ptr<LiveVariables> 494 LiveVariables::computeLiveness(AnalysisDeclContext &AC, bool killAtAssign) { 495 496 // No CFG? Bail out. 497 CFG *cfg = AC.getCFG(); 498 if (!cfg) 499 return nullptr; 500 501 // The analysis currently has scalability issues for very large CFGs. 502 // Bail out if it looks too large. 503 if (cfg->getNumBlockIDs() > 300000) 504 return nullptr; 505 506 LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign); 507 508 // Construct the dataflow worklist. Enqueue the exit block as the 509 // start of the analysis. 510 BackwardDataflowWorklist worklist(*cfg, AC); 511 llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs()); 512 513 // FIXME: we should enqueue using post order. 514 for (CFG::const_iterator it = cfg->begin(), ei = cfg->end(); it != ei; ++it) { 515 const CFGBlock *block = *it; 516 worklist.enqueueBlock(block); 517 518 // FIXME: Scan for DeclRefExprs using in the LHS of an assignment. 519 // We need to do this because we lack context in the reverse analysis 520 // to determine if a DeclRefExpr appears in such a context, and thus 521 // doesn't constitute a "use". 522 if (killAtAssign) 523 for (CFGBlock::const_iterator bi = block->begin(), be = block->end(); 524 bi != be; ++bi) { 525 if (Optional<CFGStmt> cs = bi->getAs<CFGStmt>()) { 526 const Stmt* stmt = cs->getStmt(); 527 if (const auto *BO = dyn_cast<BinaryOperator>(stmt)) { 528 if (BO->getOpcode() == BO_Assign) { 529 if (const auto *DR = 530 dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) { 531 LV->inAssignment[DR] = 1; 532 } 533 } 534 } 535 } 536 } 537 } 538 539 while (const CFGBlock *block = worklist.dequeue()) { 540 // Determine if the block's end value has changed. If not, we 541 // have nothing left to do for this block. 542 LivenessValues &prevVal = LV->blocksEndToLiveness[block]; 543 544 // Merge the values of all successor blocks. 545 LivenessValues val; 546 for (CFGBlock::const_succ_iterator it = block->succ_begin(), 547 ei = block->succ_end(); it != ei; ++it) { 548 if (const CFGBlock *succ = *it) { 549 val = LV->merge(val, LV->blocksBeginToLiveness[succ]); 550 } 551 } 552 553 if (!everAnalyzedBlock[block->getBlockID()]) 554 everAnalyzedBlock[block->getBlockID()] = true; 555 else if (prevVal.equals(val)) 556 continue; 557 558 prevVal = val; 559 560 // Update the dataflow value for the start of this block. 561 LV->blocksBeginToLiveness[block] = LV->runOnBlock(block, val); 562 563 // Enqueue the value to the predecessors. 564 worklist.enqueuePredecessors(block); 565 } 566 567 return std::unique_ptr<LiveVariables>(new LiveVariables(LV)); 568 } 569 570 void LiveVariables::dumpBlockLiveness(const SourceManager &M) { 571 getImpl(impl).dumpBlockLiveness(M); 572 } 573 574 void LiveVariablesImpl::dumpBlockLiveness(const SourceManager &M) { 575 std::vector<const CFGBlock *> vec; 576 for (llvm::DenseMap<const CFGBlock *, LiveVariables::LivenessValues>::iterator 577 it = blocksEndToLiveness.begin(), ei = blocksEndToLiveness.end(); 578 it != ei; ++it) { 579 vec.push_back(it->first); 580 } 581 llvm::sort(vec, [](const CFGBlock *A, const CFGBlock *B) { 582 return A->getBlockID() < B->getBlockID(); 583 }); 584 585 std::vector<const VarDecl*> declVec; 586 587 for (std::vector<const CFGBlock *>::iterator 588 it = vec.begin(), ei = vec.end(); it != ei; ++it) { 589 llvm::errs() << "\n[ B" << (*it)->getBlockID() 590 << " (live variables at block exit) ]\n"; 591 592 LiveVariables::LivenessValues vals = blocksEndToLiveness[*it]; 593 declVec.clear(); 594 595 for (llvm::ImmutableSet<const VarDecl *>::iterator si = 596 vals.liveDecls.begin(), 597 se = vals.liveDecls.end(); si != se; ++si) { 598 declVec.push_back(*si); 599 } 600 601 llvm::sort(declVec, [](const Decl *A, const Decl *B) { 602 return A->getBeginLoc() < B->getBeginLoc(); 603 }); 604 605 for (std::vector<const VarDecl*>::iterator di = declVec.begin(), 606 de = declVec.end(); di != de; ++di) { 607 llvm::errs() << " " << (*di)->getDeclName().getAsString() 608 << " <"; 609 (*di)->getLocation().print(llvm::errs(), M); 610 llvm::errs() << ">\n"; 611 } 612 } 613 llvm::errs() << "\n"; 614 } 615 616 void LiveVariables::dumpStmtLiveness(const SourceManager &M) { 617 getImpl(impl).dumpStmtLiveness(M); 618 } 619 620 void LiveVariablesImpl::dumpStmtLiveness(const SourceManager &M) { 621 // Don't iterate over blockEndsToLiveness directly because it's not sorted. 622 for (auto I : *analysisContext.getCFG()) { 623 624 llvm::errs() << "\n[ B" << I->getBlockID() 625 << " (live statements at block exit) ]\n"; 626 for (auto S : blocksEndToLiveness[I].liveStmts) { 627 llvm::errs() << "\n"; 628 S->dump(); 629 } 630 llvm::errs() << "\n"; 631 } 632 } 633 634 const void *LiveVariables::getTag() { static int x; return &x; } 635 const void *RelaxedLiveVariables::getTag() { static int x; return &x; } 636