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