1 //===- ThreadSafetyCommon.cpp ----------------------------------*- C++ --*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implementation of the interfaces declared in ThreadSafetyCommon.h 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Analysis/Analyses/ThreadSafetyCommon.h" 15 #include "clang/AST/Attr.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/ExprCXX.h" 18 #include "clang/AST/StmtCXX.h" 19 #include "clang/Analysis/Analyses/PostOrderCFGView.h" 20 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h" 21 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h" 22 #include "clang/Analysis/AnalysisContext.h" 23 #include "clang/Analysis/CFG.h" 24 #include "clang/Basic/OperatorKinds.h" 25 #include "clang/Basic/SourceLocation.h" 26 #include "clang/Basic/SourceManager.h" 27 #include "llvm/ADT/DenseMap.h" 28 #include "llvm/ADT/SmallVector.h" 29 #include "llvm/ADT/StringRef.h" 30 31 #include <algorithm> 32 #include <climits> 33 #include <vector> 34 35 36 namespace clang { 37 namespace threadSafety { 38 39 namespace til { 40 41 // If E is a variable, then trace back through any aliases or redundant 42 // Phi nodes to find the canonical definition. 43 SExpr *getCanonicalVal(SExpr *E) { 44 while (auto *V = dyn_cast<Variable>(E)) { 45 SExpr *D; 46 do { 47 if (V->kind() != Variable::VK_Let) 48 return V; 49 D = V->definition(); 50 if (auto *V2 = dyn_cast<Variable>(D)) { 51 V = V2; 52 continue; 53 } 54 } while(false); 55 56 if (ThreadSafetyTIL::isTrivial(D)) 57 return D; 58 59 if (Phi *Ph = dyn_cast<Phi>(D)) { 60 if (Ph->status() == Phi::PH_Incomplete) 61 simplifyIncompleteArg(V, Ph); 62 63 if (Ph->status() == Phi::PH_SingleVal) { 64 E = Ph->values()[0]; 65 continue; 66 } 67 } 68 return V; 69 } 70 return E; 71 } 72 73 74 // Trace the arguments of an incomplete Phi node to see if they have the same 75 // canonical definition. If so, mark the Phi node as redundant. 76 // getCanonicalVal() will recursively call simplifyIncompletePhi(). 77 void simplifyIncompleteArg(Variable *V, til::Phi *Ph) { 78 assert(!Ph && Ph->status() == Phi::PH_Incomplete); 79 80 // eliminate infinite recursion -- assume that this node is not redundant. 81 Ph->setStatus(Phi::PH_MultiVal); 82 83 SExpr *E0 = getCanonicalVal(Ph->values()[0]); 84 for (unsigned i=1, n=Ph->values().size(); i<n; ++i) { 85 SExpr *Ei = getCanonicalVal(Ph->values()[i]); 86 if (Ei == V) 87 continue; // Recursive reference to itself. Don't count. 88 if (Ei != E0) { 89 return; // Status is already set to MultiVal. 90 } 91 } 92 Ph->setStatus(Phi::PH_SingleVal); 93 } 94 95 } // end namespace til 96 97 98 typedef SExprBuilder::CallingContext CallingContext; 99 100 101 til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) { 102 auto It = SMap.find(S); 103 if (It != SMap.end()) 104 return It->second; 105 return nullptr; 106 } 107 108 109 til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) { 110 Walker.walk(*this); 111 return Scfg; 112 } 113 114 115 // Translate a clang statement or expression to a TIL expression. 116 // Also performs substitution of variables; Ctx provides the context. 117 // Dispatches on the type of S. 118 til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) { 119 if (!S) 120 return nullptr; 121 122 // Check if S has already been translated and cached. 123 // This handles the lookup of SSA names for DeclRefExprs here. 124 if (til::SExpr *E = lookupStmt(S)) 125 return E; 126 127 switch (S->getStmtClass()) { 128 case Stmt::DeclRefExprClass: 129 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx); 130 case Stmt::CXXThisExprClass: 131 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx); 132 case Stmt::MemberExprClass: 133 return translateMemberExpr(cast<MemberExpr>(S), Ctx); 134 case Stmt::CallExprClass: 135 return translateCallExpr(cast<CallExpr>(S), Ctx); 136 case Stmt::CXXMemberCallExprClass: 137 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx); 138 case Stmt::CXXOperatorCallExprClass: 139 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx); 140 case Stmt::UnaryOperatorClass: 141 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx); 142 case Stmt::BinaryOperatorClass: 143 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx); 144 145 case Stmt::ArraySubscriptExprClass: 146 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx); 147 case Stmt::ConditionalOperatorClass: 148 return translateConditionalOperator(cast<ConditionalOperator>(S), Ctx); 149 case Stmt::BinaryConditionalOperatorClass: 150 return translateBinaryConditionalOperator( 151 cast<BinaryConditionalOperator>(S), Ctx); 152 153 // We treat these as no-ops 154 case Stmt::ParenExprClass: 155 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx); 156 case Stmt::ExprWithCleanupsClass: 157 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx); 158 case Stmt::CXXBindTemporaryExprClass: 159 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx); 160 161 // Collect all literals 162 case Stmt::CharacterLiteralClass: 163 case Stmt::CXXNullPtrLiteralExprClass: 164 case Stmt::GNUNullExprClass: 165 case Stmt::CXXBoolLiteralExprClass: 166 case Stmt::FloatingLiteralClass: 167 case Stmt::ImaginaryLiteralClass: 168 case Stmt::IntegerLiteralClass: 169 case Stmt::StringLiteralClass: 170 case Stmt::ObjCStringLiteralClass: 171 return new (Arena) til::Literal(cast<Expr>(S)); 172 173 case Stmt::DeclStmtClass: 174 return translateDeclStmt(cast<DeclStmt>(S), Ctx); 175 default: 176 break; 177 } 178 if (const CastExpr *CE = dyn_cast<CastExpr>(S)) 179 return translateCastExpr(CE, Ctx); 180 181 return new (Arena) til::Undefined(S); 182 } 183 184 185 til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, 186 CallingContext *Ctx) { 187 const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl()); 188 189 // Function parameters require substitution and/or renaming. 190 if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) { 191 const FunctionDecl *FD = 192 cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl(); 193 unsigned I = PV->getFunctionScopeIndex(); 194 195 if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) { 196 // Substitute call arguments for references to function parameters 197 assert(I < Ctx->NumArgs); 198 return translate(Ctx->FunArgs[I], Ctx->Prev); 199 } 200 // Map the param back to the param of the original function declaration 201 // for consistent comparisons. 202 VD = FD->getParamDecl(I); 203 } 204 205 // For non-local variables, treat it as a referenced to a named object. 206 return new (Arena) til::LiteralPtr(VD); 207 } 208 209 210 til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE, 211 CallingContext *Ctx) { 212 // Substitute for 'this' 213 if (Ctx && Ctx->SelfArg) 214 return translate(Ctx->SelfArg, Ctx->Prev); 215 assert(SelfVar && "We have no variable for 'this'!"); 216 return SelfVar; 217 } 218 219 220 til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME, 221 CallingContext *Ctx) { 222 til::SExpr *E = translate(ME->getBase(), Ctx); 223 E = new (Arena) til::SApply(E); 224 return new (Arena) til::Project(E, ME->getMemberDecl()); 225 } 226 227 228 til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE, 229 CallingContext *Ctx) { 230 // TODO -- Lock returned 231 til::SExpr *E = translate(CE->getCallee(), Ctx); 232 for (const auto *Arg : CE->arguments()) { 233 til::SExpr *A = translate(Arg, Ctx); 234 E = new (Arena) til::Apply(E, A); 235 } 236 return new (Arena) til::Call(E, CE); 237 } 238 239 240 til::SExpr *SExprBuilder::translateCXXMemberCallExpr( 241 const CXXMemberCallExpr *ME, CallingContext *Ctx) { 242 return translateCallExpr(cast<CallExpr>(ME), Ctx); 243 } 244 245 246 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr( 247 const CXXOperatorCallExpr *OCE, CallingContext *Ctx) { 248 return translateCallExpr(cast<CallExpr>(OCE), Ctx); 249 } 250 251 252 til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO, 253 CallingContext *Ctx) { 254 switch (UO->getOpcode()) { 255 case UO_PostInc: 256 case UO_PostDec: 257 case UO_PreInc: 258 case UO_PreDec: 259 return new (Arena) til::Undefined(UO); 260 261 // We treat these as no-ops 262 case UO_AddrOf: 263 case UO_Deref: 264 case UO_Plus: 265 return translate(UO->getSubExpr(), Ctx); 266 267 case UO_Minus: 268 case UO_Not: 269 case UO_LNot: 270 case UO_Real: 271 case UO_Imag: 272 case UO_Extension: 273 return new (Arena) 274 til::UnaryOp(UO->getOpcode(), translate(UO->getSubExpr(), Ctx)); 275 } 276 return new (Arena) til::Undefined(UO); 277 } 278 279 280 til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO, 281 CallingContext *Ctx) { 282 switch (BO->getOpcode()) { 283 case BO_PtrMemD: 284 case BO_PtrMemI: 285 return new (Arena) til::Undefined(BO); 286 287 case BO_Mul: 288 case BO_Div: 289 case BO_Rem: 290 case BO_Add: 291 case BO_Sub: 292 case BO_Shl: 293 case BO_Shr: 294 case BO_LT: 295 case BO_GT: 296 case BO_LE: 297 case BO_GE: 298 case BO_EQ: 299 case BO_NE: 300 case BO_And: 301 case BO_Xor: 302 case BO_Or: 303 case BO_LAnd: 304 case BO_LOr: 305 return new (Arena) 306 til::BinaryOp(BO->getOpcode(), translate(BO->getLHS(), Ctx), 307 translate(BO->getRHS(), Ctx)); 308 309 case BO_Assign: { 310 const Expr *LHS = BO->getLHS(); 311 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) { 312 const Expr *RHS = BO->getRHS(); 313 til::SExpr *E1 = translate(RHS, Ctx); 314 return updateVarDecl(DRE->getDecl(), E1); 315 } 316 til::SExpr *E0 = translate(LHS, Ctx); 317 til::SExpr *E1 = translate(BO->getRHS(), Ctx); 318 return new (Arena) til::Store(E0, E1); 319 } 320 case BO_MulAssign: 321 case BO_DivAssign: 322 case BO_RemAssign: 323 case BO_AddAssign: 324 case BO_SubAssign: 325 case BO_ShlAssign: 326 case BO_ShrAssign: 327 case BO_AndAssign: 328 case BO_XorAssign: 329 case BO_OrAssign: 330 return new (Arena) til::Undefined(BO); 331 332 case BO_Comma: 333 // TODO: handle LHS 334 return translate(BO->getRHS(), Ctx); 335 } 336 337 return new (Arena) til::Undefined(BO); 338 } 339 340 341 til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE, 342 CallingContext *Ctx) { 343 clang::CastKind K = CE->getCastKind(); 344 switch (K) { 345 case CK_LValueToRValue: { 346 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) { 347 til::SExpr *E0 = lookupVarDecl(DRE->getDecl()); 348 if (E0) 349 return E0; 350 } 351 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 352 return new (Arena) til::Load(E0); 353 } 354 case CK_NoOp: 355 case CK_DerivedToBase: 356 case CK_UncheckedDerivedToBase: 357 case CK_ArrayToPointerDecay: 358 case CK_FunctionToPointerDecay: { 359 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 360 return E0; 361 } 362 default: { 363 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx); 364 return new (Arena) til::Cast(K, E0); 365 } 366 } 367 } 368 369 370 til::SExpr * 371 SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E, 372 CallingContext *Ctx) { 373 return new (Arena) til::Undefined(E); 374 } 375 376 377 til::SExpr * 378 SExprBuilder::translateConditionalOperator(const ConditionalOperator *C, 379 CallingContext *Ctx) { 380 return new (Arena) til::Undefined(C); 381 } 382 383 384 til::SExpr *SExprBuilder::translateBinaryConditionalOperator( 385 const BinaryConditionalOperator *C, CallingContext *Ctx) { 386 return new (Arena) til::Undefined(C); 387 } 388 389 390 til::SExpr * 391 SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) { 392 DeclGroupRef DGrp = S->getDeclGroup(); 393 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) { 394 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) { 395 Expr *E = VD->getInit(); 396 til::SExpr* SE = translate(E, Ctx); 397 398 // Add local variables with trivial type to the variable map 399 QualType T = VD->getType(); 400 if (T.isTrivialType(VD->getASTContext())) { 401 return addVarDecl(VD, SE); 402 } 403 else { 404 // TODO: add alloca 405 } 406 } 407 } 408 return nullptr; 409 } 410 411 412 413 // If (E) is non-trivial, then add it to the current basic block, and 414 // update the statement map so that S refers to E. Returns a new variable 415 // that refers to E. 416 // If E is trivial returns E. 417 til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S, 418 const ValueDecl *VD) { 419 if (!E) 420 return nullptr; 421 if (til::ThreadSafetyTIL::isTrivial(E)) 422 return E; 423 424 til::Variable *V = new (Arena) til::Variable(E, VD); 425 CurrentInstructions.push_back(V); 426 if (S) 427 insertStmt(S, V); 428 return V; 429 } 430 431 432 // Returns the current value of VD, if known, and nullptr otherwise. 433 til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) { 434 auto It = LVarIdxMap.find(VD); 435 if (It != LVarIdxMap.end()) { 436 assert(CurrentLVarMap[It->second].first == VD); 437 return CurrentLVarMap[It->second].second; 438 } 439 return nullptr; 440 } 441 442 443 // if E is a til::Variable, update its clangDecl. 444 inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) { 445 if (!E) 446 return; 447 if (til::Variable *V = dyn_cast<til::Variable>(E)) { 448 if (!V->clangDecl()) 449 V->setClangDecl(VD); 450 } 451 } 452 453 // Adds a new variable declaration. 454 til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) { 455 maybeUpdateVD(E, VD); 456 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size())); 457 CurrentLVarMap.makeWritable(); 458 CurrentLVarMap.push_back(std::make_pair(VD, E)); 459 return E; 460 } 461 462 463 // Updates a current variable declaration. (E.g. by assignment) 464 til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) { 465 maybeUpdateVD(E, VD); 466 auto It = LVarIdxMap.find(VD); 467 if (It == LVarIdxMap.end()) { 468 til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD); 469 til::SExpr *St = new (Arena) til::Store(Ptr, E); 470 return St; 471 } 472 CurrentLVarMap.makeWritable(); 473 CurrentLVarMap.elem(It->second).second = E; 474 return E; 475 } 476 477 478 // Make a Phi node in the current block for the i^th variable in CurrentVarMap. 479 // If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E. 480 // If E == null, this is a backedge and will be set later. 481 void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) { 482 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors; 483 assert(ArgIndex > 0 && ArgIndex < NPreds); 484 485 til::Variable *V = dyn_cast<til::Variable>(CurrentLVarMap[i].second); 486 if (V && V->getBlockID() == CurrentBB->blockID()) { 487 // We already have a Phi node in the current block, 488 // so just add the new variable to the Phi node. 489 til::Phi *Ph = dyn_cast<til::Phi>(V->definition()); 490 assert(Ph && "Expecting Phi node."); 491 if (E) 492 Ph->values()[ArgIndex] = E; 493 return; 494 } 495 496 // Make a new phi node: phi(..., E) 497 // All phi args up to the current index are set to the current value. 498 til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds); 499 Ph->values().setValues(NPreds, nullptr); 500 for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx) 501 Ph->values()[PIdx] = CurrentLVarMap[i].second; 502 if (E) 503 Ph->values()[ArgIndex] = E; 504 if (!E) { 505 // This is a non-minimal SSA node, which may be removed later. 506 Ph->setStatus(til::Phi::PH_Incomplete); 507 } 508 509 // Add Phi node to current block, and update CurrentLVarMap[i] 510 auto *Var = new (Arena) til::Variable(Ph, CurrentLVarMap[i].first); 511 CurrentArguments.push_back(Var); 512 if (Ph->status() == til::Phi::PH_Incomplete) 513 IncompleteArgs.push_back(Var); 514 515 CurrentLVarMap.makeWritable(); 516 CurrentLVarMap.elem(i).second = Var; 517 } 518 519 520 // Merge values from Map into the current variable map. 521 // This will construct Phi nodes in the current basic block as necessary. 522 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) { 523 assert(CurrentBlockInfo && "Not processing a block!"); 524 525 if (!CurrentLVarMap.valid()) { 526 // Steal Map, using copy-on-write. 527 CurrentLVarMap = std::move(Map); 528 return; 529 } 530 if (CurrentLVarMap.sameAs(Map)) 531 return; // Easy merge: maps from different predecessors are unchanged. 532 533 unsigned NPreds = CurrentBB->numPredecessors(); 534 unsigned ESz = CurrentLVarMap.size(); 535 unsigned MSz = Map.size(); 536 unsigned Sz = std::min(ESz, MSz); 537 538 for (unsigned i=0; i<Sz; ++i) { 539 if (CurrentLVarMap[i].first != Map[i].first) { 540 // We've reached the end of variables in common. 541 CurrentLVarMap.makeWritable(); 542 CurrentLVarMap.downsize(i); 543 break; 544 } 545 if (CurrentLVarMap[i].second != Map[i].second) 546 makePhiNodeVar(i, NPreds, Map[i].second); 547 } 548 if (ESz > MSz) { 549 CurrentLVarMap.makeWritable(); 550 CurrentLVarMap.downsize(Map.size()); 551 } 552 } 553 554 555 // Merge a back edge into the current variable map. 556 // This will create phi nodes for all variables in the variable map. 557 void SExprBuilder::mergeEntryMapBackEdge() { 558 // We don't have definitions for variables on the backedge, because we 559 // haven't gotten that far in the CFG. Thus, when encountering a back edge, 560 // we conservatively create Phi nodes for all variables. Unnecessary Phi 561 // nodes will be marked as incomplete, and stripped out at the end. 562 // 563 // An Phi node is unnecessary if it only refers to itself and one other 564 // variable, e.g. x = Phi(y, y, x) can be reduced to x = y. 565 566 assert(CurrentBlockInfo && "Not processing a block!"); 567 568 if (CurrentBlockInfo->HasBackEdges) 569 return; 570 CurrentBlockInfo->HasBackEdges = true; 571 572 CurrentLVarMap.makeWritable(); 573 unsigned Sz = CurrentLVarMap.size(); 574 unsigned NPreds = CurrentBB->numPredecessors(); 575 576 for (unsigned i=0; i < Sz; ++i) { 577 makePhiNodeVar(i, NPreds, nullptr); 578 } 579 } 580 581 582 // Update the phi nodes that were initially created for a back edge 583 // once the variable definitions have been computed. 584 // I.e., merge the current variable map into the phi nodes for Blk. 585 void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) { 586 til::BasicBlock *BB = lookupBlock(Blk); 587 unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors; 588 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors()); 589 590 for (til::Variable *V : BB->arguments()) { 591 til::Phi *Ph = dyn_cast_or_null<til::Phi>(V->definition()); 592 assert(Ph && "Expecting Phi Node."); 593 assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge."); 594 assert(V->clangDecl() && "No local variable for Phi node."); 595 596 til::SExpr *E = lookupVarDecl(V->clangDecl()); 597 assert(E && "Couldn't find local variable for Phi node."); 598 599 Ph->values()[ArgIndex] = E; 600 } 601 } 602 603 604 605 void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D, 606 const CFGBlock *First) { 607 // Perform initial setup operations. 608 unsigned NBlocks = Cfg->getNumBlockIDs(); 609 Scfg = new (Arena) til::SCFG(Arena, NBlocks); 610 611 // allocate all basic blocks immediately, to handle forward references. 612 BBInfo.resize(NBlocks); 613 BlockMap.resize(NBlocks, nullptr); 614 // create map from clang blockID to til::BasicBlocks 615 for (auto *B : *Cfg) { 616 auto *BB = new (Arena) til::BasicBlock(Arena, 0, B->size()); 617 BlockMap[B->getBlockID()] = BB; 618 } 619 CallCtx = new SExprBuilder::CallingContext(D); 620 } 621 622 623 void SExprBuilder::enterCFGBlock(const CFGBlock *B) { 624 // Intialize TIL basic block and add it to the CFG. 625 CurrentBB = BlockMap[B->getBlockID()]; 626 CurrentBB->setNumPredecessors(B->pred_size()); 627 Scfg->add(CurrentBB); 628 629 CurrentBlockInfo = &BBInfo[B->getBlockID()]; 630 CurrentArguments.clear(); 631 CurrentInstructions.clear(); 632 633 // CurrentLVarMap is moved to ExitMap on block exit. 634 assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized."); 635 } 636 637 638 void SExprBuilder::handlePredecessor(const CFGBlock *Pred) { 639 // Compute CurrentLVarMap on entry from ExitMaps of predecessors 640 641 BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()]; 642 assert(PredInfo->UnprocessedSuccessors > 0); 643 644 if (--PredInfo->UnprocessedSuccessors == 0) 645 mergeEntryMap(std::move(PredInfo->ExitMap)); 646 else 647 mergeEntryMap(PredInfo->ExitMap.clone()); 648 649 ++CurrentBlockInfo->ProcessedPredecessors; 650 } 651 652 653 void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) { 654 mergeEntryMapBackEdge(); 655 } 656 657 658 void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) { 659 // The merge*() methods have created arguments. 660 // Push those arguments onto the basic block. 661 CurrentBB->arguments().reserve( 662 static_cast<unsigned>(CurrentArguments.size()), Arena); 663 for (auto *V : CurrentArguments) 664 CurrentBB->addArgument(V); 665 } 666 667 668 void SExprBuilder::handleStatement(const Stmt *S) { 669 til::SExpr *E = translate(S, CallCtx); 670 addStatement(E, S); 671 } 672 673 674 void SExprBuilder::handleDestructorCall(const VarDecl *VD, 675 const CXXDestructorDecl *DD) { 676 til::SExpr *Sf = new (Arena) til::LiteralPtr(VD); 677 til::SExpr *Dr = new (Arena) til::LiteralPtr(DD); 678 til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf); 679 til::SExpr *E = new (Arena) til::Call(Ap); 680 addStatement(E, nullptr); 681 } 682 683 684 685 void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) { 686 CurrentBB->instructions().reserve( 687 static_cast<unsigned>(CurrentInstructions.size()), Arena); 688 for (auto *V : CurrentInstructions) 689 CurrentBB->addInstruction(V); 690 691 // Create an appropriate terminator 692 unsigned N = B->succ_size(); 693 auto It = B->succ_begin(); 694 if (N == 1) { 695 til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr; 696 // TODO: set index 697 til::SExpr *Tm = new (Arena) til::Goto(BB, 0); 698 CurrentBB->setTerminator(Tm); 699 } 700 else if (N == 2) { 701 til::SExpr *C = translate(B->getTerminatorCondition(true), CallCtx); 702 til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr; 703 ++It; 704 til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr; 705 // TODO: set conditional, set index 706 til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2); 707 CurrentBB->setTerminator(Tm); 708 } 709 } 710 711 712 void SExprBuilder::handleSuccessor(const CFGBlock *Succ) { 713 ++CurrentBlockInfo->UnprocessedSuccessors; 714 } 715 716 717 void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) { 718 mergePhiNodesBackEdge(Succ); 719 ++BBInfo[Succ->getBlockID()].ProcessedPredecessors; 720 } 721 722 723 void SExprBuilder::exitCFGBlock(const CFGBlock *B) { 724 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap); 725 CurrentBB = nullptr; 726 CurrentBlockInfo = nullptr; 727 } 728 729 730 void SExprBuilder::exitCFG(const CFGBlock *Last) { 731 for (auto *V : IncompleteArgs) { 732 til::Phi *Ph = dyn_cast<til::Phi>(V->definition()); 733 if (Ph && Ph->status() == til::Phi::PH_Incomplete) 734 simplifyIncompleteArg(V, Ph); 735 } 736 737 CurrentArguments.clear(); 738 CurrentInstructions.clear(); 739 IncompleteArgs.clear(); 740 } 741 742 743 744 class LLVMPrinter : public til::PrettyPrinter<LLVMPrinter, llvm::raw_ostream> { 745 }; 746 747 748 void printSCFG(CFGWalker &Walker) { 749 llvm::BumpPtrAllocator Bpa; 750 til::MemRegionRef Arena(&Bpa); 751 SExprBuilder builder(Arena); 752 til::SCFG *Cfg = builder.buildCFG(Walker); 753 LLVMPrinter::print(Cfg, llvm::errs()); 754 } 755 756 757 758 } // end namespace threadSafety 759 760 } // end namespace clang 761