blob: fb96834b3e70adfd2828ea25440ba96cdd23fe7e [file] [log] [blame]
DeLesley Hutchinsb2213912014-04-07 18:09:54 +00001//===- 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
Aaron Ballman28347a72014-04-09 21:12:04 +000014#include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000015#include "clang/AST/Attr.h"
16#include "clang/AST/DeclCXX.h"
Benjamin Kramera7bcab72014-05-09 17:08:01 +000017#include "clang/AST/DeclObjC.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000018#include "clang/AST/ExprCXX.h"
19#include "clang/AST/StmtCXX.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000020#include "clang/Analysis/Analyses/PostOrderCFGView.h"
DeLesley Hutchinsf7813c52014-04-08 22:21:22 +000021#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
DeLesley Hutchins7e615c22014-04-09 22:39:43 +000022#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000023#include "clang/Analysis/AnalysisContext.h"
24#include "clang/Analysis/CFG.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000025#include "clang/Basic/OperatorKinds.h"
26#include "clang/Basic/SourceLocation.h"
27#include "clang/Basic/SourceManager.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000028#include "llvm/ADT/DenseMap.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000029#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/StringRef.h"
DeLesley Hutchins7e615c22014-04-09 22:39:43 +000031
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +000032#include <algorithm>
33#include <climits>
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000034#include <vector>
35
36
37namespace clang {
38namespace threadSafety {
39
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000040namespace til {
41
42// If E is a variable, then trace back through any aliases or redundant
43// Phi nodes to find the canonical definition.
44SExpr *getCanonicalVal(SExpr *E) {
45 while (auto *V = dyn_cast<Variable>(E)) {
46 SExpr *D;
47 do {
48 if (V->kind() != Variable::VK_Let)
49 return V;
50 D = V->definition();
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000051 auto *V2 = dyn_cast<Variable>(D);
52 if (V2)
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000053 V = V2;
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000054 else
55 break;
56 } while (true);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000057
58 if (ThreadSafetyTIL::isTrivial(D))
59 return D;
60
61 if (Phi *Ph = dyn_cast<Phi>(D)) {
62 if (Ph->status() == Phi::PH_Incomplete)
63 simplifyIncompleteArg(V, Ph);
64
65 if (Ph->status() == Phi::PH_SingleVal) {
66 E = Ph->values()[0];
67 continue;
68 }
69 }
70 return V;
71 }
72 return E;
73}
74
75
76// Trace the arguments of an incomplete Phi node to see if they have the same
77// canonical definition. If so, mark the Phi node as redundant.
78// getCanonicalVal() will recursively call simplifyIncompletePhi().
79void simplifyIncompleteArg(Variable *V, til::Phi *Ph) {
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000080 assert(Ph && Ph->status() == Phi::PH_Incomplete);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000081
82 // eliminate infinite recursion -- assume that this node is not redundant.
83 Ph->setStatus(Phi::PH_MultiVal);
84
85 SExpr *E0 = getCanonicalVal(Ph->values()[0]);
86 for (unsigned i=1, n=Ph->values().size(); i<n; ++i) {
87 SExpr *Ei = getCanonicalVal(Ph->values()[i]);
88 if (Ei == V)
89 continue; // Recursive reference to itself. Don't count.
90 if (Ei != E0) {
91 return; // Status is already set to MultiVal.
92 }
93 }
94 Ph->setStatus(Phi::PH_SingleVal);
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000095 // Eliminate Redundant Phi node.
96 V->setDefinition(Ph->values()[0]);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000097}
98
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000099
100// Return true if E is a variable that points to an incomplete Phi node.
Aaron Ballmanbf58a6a2014-04-23 13:58:21 +0000101static bool isIncompleteVar(const SExpr *E) {
102 if (const auto *V = dyn_cast<Variable>(E)) {
103 if (const auto *Ph = dyn_cast<Phi>(V->definition()))
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000104 return Ph->status() == Phi::PH_Incomplete;
105 }
106 return false;
107}
108
109
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000110} // end namespace til
111
112
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000113typedef SExprBuilder::CallingContext CallingContext;
114
115
116til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000117 auto It = SMap.find(S);
118 if (It != SMap.end())
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000119 return It->second;
Aaron Ballman3f993c12014-04-09 17:45:44 +0000120 return nullptr;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000121}
122
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000123
124til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {
125 Walker.walk(*this);
126 return Scfg;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000127}
128
129
130// Translate a clang statement or expression to a TIL expression.
131// Also performs substitution of variables; Ctx provides the context.
132// Dispatches on the type of S.
133til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000134 if (!S)
135 return nullptr;
136
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000137 // Check if S has already been translated and cached.
138 // This handles the lookup of SSA names for DeclRefExprs here.
139 if (til::SExpr *E = lookupStmt(S))
140 return E;
141
142 switch (S->getStmtClass()) {
143 case Stmt::DeclRefExprClass:
144 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
145 case Stmt::CXXThisExprClass:
146 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
147 case Stmt::MemberExprClass:
148 return translateMemberExpr(cast<MemberExpr>(S), Ctx);
149 case Stmt::CallExprClass:
150 return translateCallExpr(cast<CallExpr>(S), Ctx);
151 case Stmt::CXXMemberCallExprClass:
152 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
153 case Stmt::CXXOperatorCallExprClass:
154 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
155 case Stmt::UnaryOperatorClass:
156 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
157 case Stmt::BinaryOperatorClass:
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000158 case Stmt::CompoundAssignOperatorClass:
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000159 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
160
161 case Stmt::ArraySubscriptExprClass:
162 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
163 case Stmt::ConditionalOperatorClass:
164 return translateConditionalOperator(cast<ConditionalOperator>(S), Ctx);
165 case Stmt::BinaryConditionalOperatorClass:
166 return translateBinaryConditionalOperator(
167 cast<BinaryConditionalOperator>(S), Ctx);
168
169 // We treat these as no-ops
170 case Stmt::ParenExprClass:
171 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
172 case Stmt::ExprWithCleanupsClass:
173 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
174 case Stmt::CXXBindTemporaryExprClass:
175 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
176
177 // Collect all literals
178 case Stmt::CharacterLiteralClass:
179 case Stmt::CXXNullPtrLiteralExprClass:
180 case Stmt::GNUNullExprClass:
181 case Stmt::CXXBoolLiteralExprClass:
182 case Stmt::FloatingLiteralClass:
183 case Stmt::ImaginaryLiteralClass:
184 case Stmt::IntegerLiteralClass:
185 case Stmt::StringLiteralClass:
186 case Stmt::ObjCStringLiteralClass:
187 return new (Arena) til::Literal(cast<Expr>(S));
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000188
189 case Stmt::DeclStmtClass:
190 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000191 default:
192 break;
193 }
194 if (const CastExpr *CE = dyn_cast<CastExpr>(S))
195 return translateCastExpr(CE, Ctx);
196
197 return new (Arena) til::Undefined(S);
198}
199
200
201til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
202 CallingContext *Ctx) {
203 const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
204
205 // Function parameters require substitution and/or renaming.
206 if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
207 const FunctionDecl *FD =
208 cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
209 unsigned I = PV->getFunctionScopeIndex();
210
211 if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
212 // Substitute call arguments for references to function parameters
213 assert(I < Ctx->NumArgs);
214 return translate(Ctx->FunArgs[I], Ctx->Prev);
215 }
216 // Map the param back to the param of the original function declaration
217 // for consistent comparisons.
218 VD = FD->getParamDecl(I);
219 }
220
221 // For non-local variables, treat it as a referenced to a named object.
222 return new (Arena) til::LiteralPtr(VD);
223}
224
225
226til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
227 CallingContext *Ctx) {
228 // Substitute for 'this'
229 if (Ctx && Ctx->SelfArg)
230 return translate(Ctx->SelfArg, Ctx->Prev);
231 assert(SelfVar && "We have no variable for 'this'!");
232 return SelfVar;
233}
234
235
236til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
237 CallingContext *Ctx) {
238 til::SExpr *E = translate(ME->getBase(), Ctx);
239 E = new (Arena) til::SApply(E);
240 return new (Arena) til::Project(E, ME->getMemberDecl());
241}
242
243
244til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
245 CallingContext *Ctx) {
246 // TODO -- Lock returned
247 til::SExpr *E = translate(CE->getCallee(), Ctx);
Aaron Ballman3f993c12014-04-09 17:45:44 +0000248 for (const auto *Arg : CE->arguments()) {
249 til::SExpr *A = translate(Arg, Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000250 E = new (Arena) til::Apply(E, A);
251 }
252 return new (Arena) til::Call(E, CE);
253}
254
255
256til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
257 const CXXMemberCallExpr *ME, CallingContext *Ctx) {
258 return translateCallExpr(cast<CallExpr>(ME), Ctx);
259}
260
261
262til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
263 const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {
264 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
265}
266
267
268til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
269 CallingContext *Ctx) {
270 switch (UO->getOpcode()) {
271 case UO_PostInc:
272 case UO_PostDec:
273 case UO_PreInc:
274 case UO_PreDec:
275 return new (Arena) til::Undefined(UO);
276
277 // We treat these as no-ops
278 case UO_AddrOf:
279 case UO_Deref:
280 case UO_Plus:
281 return translate(UO->getSubExpr(), Ctx);
282
283 case UO_Minus:
284 case UO_Not:
285 case UO_LNot:
286 case UO_Real:
287 case UO_Imag:
Aaron Ballman3f993c12014-04-09 17:45:44 +0000288 case UO_Extension:
289 return new (Arena)
290 til::UnaryOp(UO->getOpcode(), translate(UO->getSubExpr(), Ctx));
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000291 }
292 return new (Arena) til::Undefined(UO);
293}
294
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000295
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000296til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
297 const BinaryOperator *BO,
298 CallingContext *Ctx) {
299 const Expr *LHS = BO->getLHS();
300 const Expr *RHS = BO->getRHS();
301 til::SExpr *E0 = translate(LHS, Ctx);
302 til::SExpr *E1 = translate(RHS, Ctx);
303
304 const ValueDecl *VD = nullptr;
305 til::SExpr *CV = nullptr;
306 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
307 VD = DRE->getDecl();
308 CV = lookupVarDecl(VD);
309 }
310
311 if (Op != BO_Assign) {
312 til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0);
313 E1 = new (Arena) til::BinaryOp(Op, Arg, E1);
314 E1 = addStatement(E1, nullptr, VD);
315 }
316 if (VD && CV)
317 return updateVarDecl(VD, E1);
318 return new (Arena) til::Store(E0, E1);
319}
320
321
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000322til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
323 CallingContext *Ctx) {
324 switch (BO->getOpcode()) {
325 case BO_PtrMemD:
326 case BO_PtrMemI:
327 return new (Arena) til::Undefined(BO);
328
329 case BO_Mul:
330 case BO_Div:
331 case BO_Rem:
332 case BO_Add:
333 case BO_Sub:
334 case BO_Shl:
335 case BO_Shr:
336 case BO_LT:
337 case BO_GT:
338 case BO_LE:
339 case BO_GE:
340 case BO_EQ:
341 case BO_NE:
342 case BO_And:
343 case BO_Xor:
344 case BO_Or:
345 case BO_LAnd:
Aaron Ballman3f993c12014-04-09 17:45:44 +0000346 case BO_LOr:
347 return new (Arena)
348 til::BinaryOp(BO->getOpcode(), translate(BO->getLHS(), Ctx),
349 translate(BO->getRHS(), Ctx));
350
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000351 case BO_Assign: return translateBinAssign(BO_Assign, BO, Ctx);
352 case BO_MulAssign: return translateBinAssign(BO_Mul, BO, Ctx);
353 case BO_DivAssign: return translateBinAssign(BO_Div, BO, Ctx);
354 case BO_RemAssign: return translateBinAssign(BO_Rem, BO, Ctx);
355 case BO_AddAssign: return translateBinAssign(BO_Add, BO, Ctx);
356 case BO_SubAssign: return translateBinAssign(BO_Sub, BO, Ctx);
357 case BO_ShlAssign: return translateBinAssign(BO_Shl, BO, Ctx);
358 case BO_ShrAssign: return translateBinAssign(BO_Shr, BO, Ctx);
359 case BO_AndAssign: return translateBinAssign(BO_And, BO, Ctx);
360 case BO_XorAssign: return translateBinAssign(BO_Xor, BO, Ctx);
361 case BO_OrAssign: return translateBinAssign(BO_Or, BO, Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000362
363 case BO_Comma:
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000364 // The clang CFG should have already processed both sides.
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000365 return translate(BO->getRHS(), Ctx);
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000366 }
DeLesley Hutchins78340012014-04-22 14:51:04 +0000367 return new (Arena) til::Undefined(BO);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000368}
369
370
371til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
372 CallingContext *Ctx) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000373 clang::CastKind K = CE->getCastKind();
374 switch (K) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000375 case CK_LValueToRValue: {
376 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
377 til::SExpr *E0 = lookupVarDecl(DRE->getDecl());
378 if (E0)
379 return E0;
380 }
381 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000382 return new (Arena) til::Load(E0);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000383 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000384 case CK_NoOp:
385 case CK_DerivedToBase:
386 case CK_UncheckedDerivedToBase:
387 case CK_ArrayToPointerDecay:
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000388 case CK_FunctionToPointerDecay: {
389 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000390 return E0;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000391 }
392 default: {
393 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000394 return new (Arena) til::Cast(K, E0);
395 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000396 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000397}
398
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000399
Aaron Ballman3f993c12014-04-09 17:45:44 +0000400til::SExpr *
401SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
402 CallingContext *Ctx) {
DeLesley Hutchinsf1a31162014-04-22 17:31:23 +0000403 til::SExpr *E0 = translate(E->getBase(), Ctx);
404 til::SExpr *E1 = translate(E->getIdx(), Ctx);
405 auto *AA = new (Arena) til::ArrayAdd(E0, E1);
406 return new (Arena) til::ArrayFirst(AA);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000407}
408
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000409
Aaron Ballman3f993c12014-04-09 17:45:44 +0000410til::SExpr *
411SExprBuilder::translateConditionalOperator(const ConditionalOperator *C,
412 CallingContext *Ctx) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000413 return new (Arena) til::Undefined(C);
414}
415
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000416
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000417til::SExpr *SExprBuilder::translateBinaryConditionalOperator(
418 const BinaryConditionalOperator *C, CallingContext *Ctx) {
419 return new (Arena) til::Undefined(C);
420}
421
DeLesley Hutchins7e615c22014-04-09 22:39:43 +0000422
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000423til::SExpr *
424SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {
425 DeclGroupRef DGrp = S->getDeclGroup();
426 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
427 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
428 Expr *E = VD->getInit();
429 til::SExpr* SE = translate(E, Ctx);
DeLesley Hutchins7e615c22014-04-09 22:39:43 +0000430
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000431 // Add local variables with trivial type to the variable map
432 QualType T = VD->getType();
433 if (T.isTrivialType(VD->getASTContext())) {
434 return addVarDecl(VD, SE);
435 }
436 else {
437 // TODO: add alloca
438 }
439 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000440 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000441 return nullptr;
442}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000443
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000444
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000445
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000446// If (E) is non-trivial, then add it to the current basic block, and
447// update the statement map so that S refers to E. Returns a new variable
448// that refers to E.
449// If E is trivial returns E.
450til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
451 const ValueDecl *VD) {
452 if (!E)
453 return nullptr;
454 if (til::ThreadSafetyTIL::isTrivial(E))
455 return E;
456
457 til::Variable *V = new (Arena) til::Variable(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000458 CurrentInstructions.push_back(V);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000459 if (S)
460 insertStmt(S, V);
461 return V;
462}
463
464
465// Returns the current value of VD, if known, and nullptr otherwise.
466til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000467 auto It = LVarIdxMap.find(VD);
468 if (It != LVarIdxMap.end()) {
469 assert(CurrentLVarMap[It->second].first == VD);
470 return CurrentLVarMap[It->second].second;
471 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000472 return nullptr;
473}
474
475
476// if E is a til::Variable, update its clangDecl.
477inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
478 if (!E)
479 return;
480 if (til::Variable *V = dyn_cast<til::Variable>(E)) {
481 if (!V->clangDecl())
482 V->setClangDecl(VD);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000483 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000484}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000485
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000486// Adds a new variable declaration.
487til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {
488 maybeUpdateVD(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000489 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
490 CurrentLVarMap.makeWritable();
491 CurrentLVarMap.push_back(std::make_pair(VD, E));
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000492 return E;
493}
494
495
496// Updates a current variable declaration. (E.g. by assignment)
497til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {
498 maybeUpdateVD(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000499 auto It = LVarIdxMap.find(VD);
500 if (It == LVarIdxMap.end()) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000501 til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD);
502 til::SExpr *St = new (Arena) til::Store(Ptr, E);
503 return St;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000504 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000505 CurrentLVarMap.makeWritable();
506 CurrentLVarMap.elem(It->second).second = E;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000507 return E;
508}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000509
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000510
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000511// Make a Phi node in the current block for the i^th variable in CurrentVarMap.
512// If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
513// If E == null, this is a backedge and will be set later.
514void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {
515 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
516 assert(ArgIndex > 0 && ArgIndex < NPreds);
517
518 til::Variable *V = dyn_cast<til::Variable>(CurrentLVarMap[i].second);
519 if (V && V->getBlockID() == CurrentBB->blockID()) {
520 // We already have a Phi node in the current block,
521 // so just add the new variable to the Phi node.
522 til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
523 assert(Ph && "Expecting Phi node.");
524 if (E)
525 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000526 return;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000527 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000528
529 // Make a new phi node: phi(..., E)
530 // All phi args up to the current index are set to the current value.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000531 til::SExpr *CurrE = CurrentLVarMap[i].second;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000532 til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds);
533 Ph->values().setValues(NPreds, nullptr);
534 for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000535 Ph->values()[PIdx] = CurrE;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000536 if (E)
537 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000538 // If E is from a back-edge, or either E or CurrE are incomplete, then
539 // mark this node as incomplete; we may need to remove it later.
540 if (!E || isIncompleteVar(E) || isIncompleteVar(CurrE)) {
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000541 Ph->setStatus(til::Phi::PH_Incomplete);
542 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000543
544 // Add Phi node to current block, and update CurrentLVarMap[i]
545 auto *Var = new (Arena) til::Variable(Ph, CurrentLVarMap[i].first);
546 CurrentArguments.push_back(Var);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000547 if (Ph->status() == til::Phi::PH_Incomplete)
548 IncompleteArgs.push_back(Var);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000549
550 CurrentLVarMap.makeWritable();
551 CurrentLVarMap.elem(i).second = Var;
552}
553
554
555// Merge values from Map into the current variable map.
556// This will construct Phi nodes in the current basic block as necessary.
557void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
558 assert(CurrentBlockInfo && "Not processing a block!");
559
560 if (!CurrentLVarMap.valid()) {
561 // Steal Map, using copy-on-write.
562 CurrentLVarMap = std::move(Map);
563 return;
564 }
565 if (CurrentLVarMap.sameAs(Map))
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000566 return; // Easy merge: maps from different predecessors are unchanged.
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000567
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000568 unsigned NPreds = CurrentBB->numPredecessors();
569 unsigned ESz = CurrentLVarMap.size();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000570 unsigned MSz = Map.size();
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000571 unsigned Sz = std::min(ESz, MSz);
572
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000573 for (unsigned i=0; i<Sz; ++i) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000574 if (CurrentLVarMap[i].first != Map[i].first) {
575 // We've reached the end of variables in common.
576 CurrentLVarMap.makeWritable();
577 CurrentLVarMap.downsize(i);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000578 break;
579 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000580 if (CurrentLVarMap[i].second != Map[i].second)
581 makePhiNodeVar(i, NPreds, Map[i].second);
DeLesley Hutchins11bb30872014-04-07 22:56:24 +0000582 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000583 if (ESz > MSz) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000584 CurrentLVarMap.makeWritable();
585 CurrentLVarMap.downsize(Map.size());
586 }
587}
588
589
590// Merge a back edge into the current variable map.
591// This will create phi nodes for all variables in the variable map.
592void SExprBuilder::mergeEntryMapBackEdge() {
593 // We don't have definitions for variables on the backedge, because we
594 // haven't gotten that far in the CFG. Thus, when encountering a back edge,
595 // we conservatively create Phi nodes for all variables. Unnecessary Phi
596 // nodes will be marked as incomplete, and stripped out at the end.
597 //
598 // An Phi node is unnecessary if it only refers to itself and one other
599 // variable, e.g. x = Phi(y, y, x) can be reduced to x = y.
600
601 assert(CurrentBlockInfo && "Not processing a block!");
602
603 if (CurrentBlockInfo->HasBackEdges)
604 return;
605 CurrentBlockInfo->HasBackEdges = true;
606
607 CurrentLVarMap.makeWritable();
608 unsigned Sz = CurrentLVarMap.size();
609 unsigned NPreds = CurrentBB->numPredecessors();
610
611 for (unsigned i=0; i < Sz; ++i) {
612 makePhiNodeVar(i, NPreds, nullptr);
613 }
614}
615
616
617// Update the phi nodes that were initially created for a back edge
618// once the variable definitions have been computed.
619// I.e., merge the current variable map into the phi nodes for Blk.
620void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
621 til::BasicBlock *BB = lookupBlock(Blk);
622 unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;
623 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
624
625 for (til::Variable *V : BB->arguments()) {
626 til::Phi *Ph = dyn_cast_or_null<til::Phi>(V->definition());
627 assert(Ph && "Expecting Phi Node.");
628 assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge.");
629 assert(V->clangDecl() && "No local variable for Phi node.");
630
631 til::SExpr *E = lookupVarDecl(V->clangDecl());
632 assert(E && "Couldn't find local variable for Phi node.");
633
634 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000635 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000636}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000637
Benjamin Kramera7bcab72014-05-09 17:08:01 +0000638void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000639 const CFGBlock *First) {
640 // Perform initial setup operations.
641 unsigned NBlocks = Cfg->getNumBlockIDs();
642 Scfg = new (Arena) til::SCFG(Arena, NBlocks);
643
644 // allocate all basic blocks immediately, to handle forward references.
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000645 BBInfo.resize(NBlocks);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000646 BlockMap.resize(NBlocks, nullptr);
647 // create map from clang blockID to til::BasicBlocks
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000648 for (auto *B : *Cfg) {
649 auto *BB = new (Arena) til::BasicBlock(Arena, 0, B->size());
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000650 BlockMap[B->getBlockID()] = BB;
DeLesley Hutchins11bb30872014-04-07 22:56:24 +0000651 }
Benjamin Kramera7bcab72014-05-09 17:08:01 +0000652 CallCtx.reset(new SExprBuilder::CallingContext(D));
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000653
654 CurrentBB = lookupBlock(&Cfg->getEntry());
Benjamin Kramera7bcab72014-05-09 17:08:01 +0000655 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
656 : cast<FunctionDecl>(D)->parameters();
657 for (auto *Pm : Parms) {
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000658 QualType T = Pm->getType();
659 if (!T.isTrivialType(Pm->getASTContext()))
660 continue;
661
662 // Add parameters to local variable map.
663 // FIXME: right now we emulate params with loads; that should be fixed.
664 til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm);
665 til::SExpr *Ld = new (Arena) til::Load(Lp);
666 til::SExpr *V = addStatement(Ld, nullptr, Pm);
667 addVarDecl(Pm, V);
668 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000669}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000670
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000671
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000672void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
673 // Intialize TIL basic block and add it to the CFG.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000674 CurrentBB = lookupBlock(B);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000675 CurrentBB->setNumPredecessors(B->pred_size());
676 Scfg->add(CurrentBB);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000677
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000678 CurrentBlockInfo = &BBInfo[B->getBlockID()];
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000679
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000680 // CurrentLVarMap is moved to ExitMap on block exit.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000681 // FIXME: the entry block will hold function parameters.
682 // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized.");
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000683}
684
685
686void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000687 // Compute CurrentLVarMap on entry from ExitMaps of predecessors
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000688
689 BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000690 assert(PredInfo->UnprocessedSuccessors > 0);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000691
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000692 if (--PredInfo->UnprocessedSuccessors == 0)
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000693 mergeEntryMap(std::move(PredInfo->ExitMap));
694 else
695 mergeEntryMap(PredInfo->ExitMap.clone());
696
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000697 ++CurrentBlockInfo->ProcessedPredecessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000698}
699
700
701void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000702 mergeEntryMapBackEdge();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000703}
704
705
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000706void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {
707 // The merge*() methods have created arguments.
708 // Push those arguments onto the basic block.
709 CurrentBB->arguments().reserve(
710 static_cast<unsigned>(CurrentArguments.size()), Arena);
711 for (auto *V : CurrentArguments)
712 CurrentBB->addArgument(V);
713}
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000714
715
716void SExprBuilder::handleStatement(const Stmt *S) {
Aaron Ballman8e8026d2014-04-23 14:26:59 +0000717 til::SExpr *E = translate(S, CallCtx.get());
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000718 addStatement(E, S);
719}
720
721
722void SExprBuilder::handleDestructorCall(const VarDecl *VD,
723 const CXXDestructorDecl *DD) {
724 til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
725 til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
726 til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
727 til::SExpr *E = new (Arena) til::Call(Ap);
728 addStatement(E, nullptr);
729}
730
731
732
733void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000734 CurrentBB->instructions().reserve(
735 static_cast<unsigned>(CurrentInstructions.size()), Arena);
736 for (auto *V : CurrentInstructions)
737 CurrentBB->addInstruction(V);
738
739 // Create an appropriate terminator
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000740 unsigned N = B->succ_size();
741 auto It = B->succ_begin();
742 if (N == 1) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000743 til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000744 // TODO: set index
745 til::SExpr *Tm = new (Arena) til::Goto(BB, 0);
746 CurrentBB->setTerminator(Tm);
747 }
748 else if (N == 2) {
Aaron Ballman8e8026d2014-04-23 14:26:59 +0000749 til::SExpr *C = translate(B->getTerminatorCondition(true), CallCtx.get());
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000750 til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000751 ++It;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000752 til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000753 // TODO: set conditional, set index
754 til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2);
755 CurrentBB->setTerminator(Tm);
756 }
757}
758
759
760void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000761 ++CurrentBlockInfo->UnprocessedSuccessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000762}
763
764
765void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000766 mergePhiNodesBackEdge(Succ);
767 ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000768}
769
770
771void SExprBuilder::exitCFGBlock(const CFGBlock *B) {
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000772 CurrentArguments.clear();
773 CurrentInstructions.clear();
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000774 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000775 CurrentBB = nullptr;
776 CurrentBlockInfo = nullptr;
777}
778
779
780void SExprBuilder::exitCFG(const CFGBlock *Last) {
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000781 for (auto *V : IncompleteArgs) {
782 til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
783 if (Ph && Ph->status() == til::Phi::PH_Incomplete)
784 simplifyIncompleteArg(V, Ph);
785 }
786
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000787 CurrentArguments.clear();
788 CurrentInstructions.clear();
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000789 IncompleteArgs.clear();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000790}
791
792
793
794class LLVMPrinter : public til::PrettyPrinter<LLVMPrinter, llvm::raw_ostream> {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000795};
796
797
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000798void printSCFG(CFGWalker &Walker) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000799 llvm::BumpPtrAllocator Bpa;
800 til::MemRegionRef Arena(&Bpa);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000801 SExprBuilder builder(Arena);
802 til::SCFG *Cfg = builder.buildCFG(Walker);
803 LLVMPrinter::print(Cfg, llvm::errs());
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000804}
805
806
807
808} // end namespace threadSafety
809
810} // end namespace clang