blob: 0a6efebd3110de1707ad31ad0301b236fe64da2c [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"
17#include "clang/AST/ExprCXX.h"
18#include "clang/AST/StmtCXX.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000019#include "clang/Analysis/Analyses/PostOrderCFGView.h"
DeLesley Hutchinsf7813c52014-04-08 22:21:22 +000020#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
DeLesley Hutchins7e615c22014-04-09 22:39:43 +000021#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000022#include "clang/Analysis/AnalysisContext.h"
23#include "clang/Analysis/CFG.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000024#include "clang/Basic/OperatorKinds.h"
25#include "clang/Basic/SourceLocation.h"
26#include "clang/Basic/SourceManager.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000027#include "llvm/ADT/DenseMap.h"
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000028#include "llvm/ADT/SmallVector.h"
29#include "llvm/ADT/StringRef.h"
DeLesley Hutchins7e615c22014-04-09 22:39:43 +000030
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +000031#include <algorithm>
32#include <climits>
DeLesley Hutchinsb2213912014-04-07 18:09:54 +000033#include <vector>
34
35
36namespace clang {
37namespace threadSafety {
38
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000039namespace til {
40
41// If E is a variable, then trace back through any aliases or redundant
42// Phi nodes to find the canonical definition.
43SExpr *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();
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000050 auto *V2 = dyn_cast<Variable>(D);
51 if (V2)
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000052 V = V2;
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000053 else
54 break;
55 } while (true);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000056
57 if (ThreadSafetyTIL::isTrivial(D))
58 return D;
59
60 if (Phi *Ph = dyn_cast<Phi>(D)) {
61 if (Ph->status() == Phi::PH_Incomplete)
62 simplifyIncompleteArg(V, Ph);
63
64 if (Ph->status() == Phi::PH_SingleVal) {
65 E = Ph->values()[0];
66 continue;
67 }
68 }
69 return V;
70 }
71 return E;
72}
73
74
75// Trace the arguments of an incomplete Phi node to see if they have the same
76// canonical definition. If so, mark the Phi node as redundant.
77// getCanonicalVal() will recursively call simplifyIncompletePhi().
78void simplifyIncompleteArg(Variable *V, til::Phi *Ph) {
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000079 assert(Ph && Ph->status() == Phi::PH_Incomplete);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000080
81 // eliminate infinite recursion -- assume that this node is not redundant.
82 Ph->setStatus(Phi::PH_MultiVal);
83
84 SExpr *E0 = getCanonicalVal(Ph->values()[0]);
85 for (unsigned i=1, n=Ph->values().size(); i<n; ++i) {
86 SExpr *Ei = getCanonicalVal(Ph->values()[i]);
87 if (Ei == V)
88 continue; // Recursive reference to itself. Don't count.
89 if (Ei != E0) {
90 return; // Status is already set to MultiVal.
91 }
92 }
93 Ph->setStatus(Phi::PH_SingleVal);
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000094 // Eliminate Redundant Phi node.
95 V->setDefinition(Ph->values()[0]);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +000096}
97
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +000098
99// Return true if E is a variable that points to an incomplete Phi node.
Aaron Ballmanbf58a6a2014-04-23 13:58:21 +0000100static bool isIncompleteVar(const SExpr *E) {
101 if (const auto *V = dyn_cast<Variable>(E)) {
102 if (const auto *Ph = dyn_cast<Phi>(V->definition()))
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000103 return Ph->status() == Phi::PH_Incomplete;
104 }
105 return false;
106}
107
108
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000109} // end namespace til
110
111
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000112typedef SExprBuilder::CallingContext CallingContext;
113
114
115til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000116 auto It = SMap.find(S);
117 if (It != SMap.end())
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000118 return It->second;
Aaron Ballman3f993c12014-04-09 17:45:44 +0000119 return nullptr;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000120}
121
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000122
123til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {
124 Walker.walk(*this);
125 return Scfg;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000126}
127
128
129// Translate a clang statement or expression to a TIL expression.
130// Also performs substitution of variables; Ctx provides the context.
131// Dispatches on the type of S.
132til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000133 if (!S)
134 return nullptr;
135
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000136 // Check if S has already been translated and cached.
137 // This handles the lookup of SSA names for DeclRefExprs here.
138 if (til::SExpr *E = lookupStmt(S))
139 return E;
140
141 switch (S->getStmtClass()) {
142 case Stmt::DeclRefExprClass:
143 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
144 case Stmt::CXXThisExprClass:
145 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
146 case Stmt::MemberExprClass:
147 return translateMemberExpr(cast<MemberExpr>(S), Ctx);
148 case Stmt::CallExprClass:
149 return translateCallExpr(cast<CallExpr>(S), Ctx);
150 case Stmt::CXXMemberCallExprClass:
151 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
152 case Stmt::CXXOperatorCallExprClass:
153 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
154 case Stmt::UnaryOperatorClass:
155 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
156 case Stmt::BinaryOperatorClass:
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000157 case Stmt::CompoundAssignOperatorClass:
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000158 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
159
160 case Stmt::ArraySubscriptExprClass:
161 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
162 case Stmt::ConditionalOperatorClass:
163 return translateConditionalOperator(cast<ConditionalOperator>(S), Ctx);
164 case Stmt::BinaryConditionalOperatorClass:
165 return translateBinaryConditionalOperator(
166 cast<BinaryConditionalOperator>(S), Ctx);
167
168 // We treat these as no-ops
169 case Stmt::ParenExprClass:
170 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
171 case Stmt::ExprWithCleanupsClass:
172 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
173 case Stmt::CXXBindTemporaryExprClass:
174 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
175
176 // Collect all literals
177 case Stmt::CharacterLiteralClass:
178 case Stmt::CXXNullPtrLiteralExprClass:
179 case Stmt::GNUNullExprClass:
180 case Stmt::CXXBoolLiteralExprClass:
181 case Stmt::FloatingLiteralClass:
182 case Stmt::ImaginaryLiteralClass:
183 case Stmt::IntegerLiteralClass:
184 case Stmt::StringLiteralClass:
185 case Stmt::ObjCStringLiteralClass:
186 return new (Arena) til::Literal(cast<Expr>(S));
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000187
188 case Stmt::DeclStmtClass:
189 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000190 default:
191 break;
192 }
193 if (const CastExpr *CE = dyn_cast<CastExpr>(S))
194 return translateCastExpr(CE, Ctx);
195
196 return new (Arena) til::Undefined(S);
197}
198
199
200til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
201 CallingContext *Ctx) {
202 const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
203
204 // Function parameters require substitution and/or renaming.
205 if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
206 const FunctionDecl *FD =
207 cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
208 unsigned I = PV->getFunctionScopeIndex();
209
210 if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
211 // Substitute call arguments for references to function parameters
212 assert(I < Ctx->NumArgs);
213 return translate(Ctx->FunArgs[I], Ctx->Prev);
214 }
215 // Map the param back to the param of the original function declaration
216 // for consistent comparisons.
217 VD = FD->getParamDecl(I);
218 }
219
220 // For non-local variables, treat it as a referenced to a named object.
221 return new (Arena) til::LiteralPtr(VD);
222}
223
224
225til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
226 CallingContext *Ctx) {
227 // Substitute for 'this'
228 if (Ctx && Ctx->SelfArg)
229 return translate(Ctx->SelfArg, Ctx->Prev);
230 assert(SelfVar && "We have no variable for 'this'!");
231 return SelfVar;
232}
233
234
235til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
236 CallingContext *Ctx) {
237 til::SExpr *E = translate(ME->getBase(), Ctx);
238 E = new (Arena) til::SApply(E);
239 return new (Arena) til::Project(E, ME->getMemberDecl());
240}
241
242
243til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
244 CallingContext *Ctx) {
245 // TODO -- Lock returned
246 til::SExpr *E = translate(CE->getCallee(), Ctx);
Aaron Ballman3f993c12014-04-09 17:45:44 +0000247 for (const auto *Arg : CE->arguments()) {
248 til::SExpr *A = translate(Arg, Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000249 E = new (Arena) til::Apply(E, A);
250 }
251 return new (Arena) til::Call(E, CE);
252}
253
254
255til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
256 const CXXMemberCallExpr *ME, CallingContext *Ctx) {
257 return translateCallExpr(cast<CallExpr>(ME), Ctx);
258}
259
260
261til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
262 const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {
263 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
264}
265
266
267til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
268 CallingContext *Ctx) {
269 switch (UO->getOpcode()) {
270 case UO_PostInc:
271 case UO_PostDec:
272 case UO_PreInc:
273 case UO_PreDec:
274 return new (Arena) til::Undefined(UO);
275
276 // We treat these as no-ops
277 case UO_AddrOf:
278 case UO_Deref:
279 case UO_Plus:
280 return translate(UO->getSubExpr(), Ctx);
281
282 case UO_Minus:
283 case UO_Not:
284 case UO_LNot:
285 case UO_Real:
286 case UO_Imag:
Aaron Ballman3f993c12014-04-09 17:45:44 +0000287 case UO_Extension:
288 return new (Arena)
289 til::UnaryOp(UO->getOpcode(), translate(UO->getSubExpr(), Ctx));
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000290 }
291 return new (Arena) til::Undefined(UO);
292}
293
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000294
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000295til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
296 const BinaryOperator *BO,
297 CallingContext *Ctx) {
298 const Expr *LHS = BO->getLHS();
299 const Expr *RHS = BO->getRHS();
300 til::SExpr *E0 = translate(LHS, Ctx);
301 til::SExpr *E1 = translate(RHS, Ctx);
302
303 const ValueDecl *VD = nullptr;
304 til::SExpr *CV = nullptr;
305 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
306 VD = DRE->getDecl();
307 CV = lookupVarDecl(VD);
308 }
309
310 if (Op != BO_Assign) {
311 til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0);
312 E1 = new (Arena) til::BinaryOp(Op, Arg, E1);
313 E1 = addStatement(E1, nullptr, VD);
314 }
315 if (VD && CV)
316 return updateVarDecl(VD, E1);
317 return new (Arena) til::Store(E0, E1);
318}
319
320
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000321til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
322 CallingContext *Ctx) {
323 switch (BO->getOpcode()) {
324 case BO_PtrMemD:
325 case BO_PtrMemI:
326 return new (Arena) til::Undefined(BO);
327
328 case BO_Mul:
329 case BO_Div:
330 case BO_Rem:
331 case BO_Add:
332 case BO_Sub:
333 case BO_Shl:
334 case BO_Shr:
335 case BO_LT:
336 case BO_GT:
337 case BO_LE:
338 case BO_GE:
339 case BO_EQ:
340 case BO_NE:
341 case BO_And:
342 case BO_Xor:
343 case BO_Or:
344 case BO_LAnd:
Aaron Ballman3f993c12014-04-09 17:45:44 +0000345 case BO_LOr:
346 return new (Arena)
347 til::BinaryOp(BO->getOpcode(), translate(BO->getLHS(), Ctx),
348 translate(BO->getRHS(), Ctx));
349
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000350 case BO_Assign: return translateBinAssign(BO_Assign, BO, Ctx);
351 case BO_MulAssign: return translateBinAssign(BO_Mul, BO, Ctx);
352 case BO_DivAssign: return translateBinAssign(BO_Div, BO, Ctx);
353 case BO_RemAssign: return translateBinAssign(BO_Rem, BO, Ctx);
354 case BO_AddAssign: return translateBinAssign(BO_Add, BO, Ctx);
355 case BO_SubAssign: return translateBinAssign(BO_Sub, BO, Ctx);
356 case BO_ShlAssign: return translateBinAssign(BO_Shl, BO, Ctx);
357 case BO_ShrAssign: return translateBinAssign(BO_Shr, BO, Ctx);
358 case BO_AndAssign: return translateBinAssign(BO_And, BO, Ctx);
359 case BO_XorAssign: return translateBinAssign(BO_Xor, BO, Ctx);
360 case BO_OrAssign: return translateBinAssign(BO_Or, BO, Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000361
362 case BO_Comma:
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000363 // The clang CFG should have already processed both sides.
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000364 return translate(BO->getRHS(), Ctx);
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000365 }
DeLesley Hutchins78340012014-04-22 14:51:04 +0000366 return new (Arena) til::Undefined(BO);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000367}
368
369
370til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
371 CallingContext *Ctx) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000372 clang::CastKind K = CE->getCastKind();
373 switch (K) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000374 case CK_LValueToRValue: {
375 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
376 til::SExpr *E0 = lookupVarDecl(DRE->getDecl());
377 if (E0)
378 return E0;
379 }
380 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000381 return new (Arena) til::Load(E0);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000382 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000383 case CK_NoOp:
384 case CK_DerivedToBase:
385 case CK_UncheckedDerivedToBase:
386 case CK_ArrayToPointerDecay:
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000387 case CK_FunctionToPointerDecay: {
388 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000389 return E0;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000390 }
391 default: {
392 til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000393 return new (Arena) til::Cast(K, E0);
394 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000395 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000396}
397
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000398
Aaron Ballman3f993c12014-04-09 17:45:44 +0000399til::SExpr *
400SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
401 CallingContext *Ctx) {
DeLesley Hutchinsf1a31162014-04-22 17:31:23 +0000402 til::SExpr *E0 = translate(E->getBase(), Ctx);
403 til::SExpr *E1 = translate(E->getIdx(), Ctx);
404 auto *AA = new (Arena) til::ArrayAdd(E0, E1);
405 return new (Arena) til::ArrayFirst(AA);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000406}
407
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000408
Aaron Ballman3f993c12014-04-09 17:45:44 +0000409til::SExpr *
410SExprBuilder::translateConditionalOperator(const ConditionalOperator *C,
411 CallingContext *Ctx) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000412 return new (Arena) til::Undefined(C);
413}
414
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000415
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000416til::SExpr *SExprBuilder::translateBinaryConditionalOperator(
417 const BinaryConditionalOperator *C, CallingContext *Ctx) {
418 return new (Arena) til::Undefined(C);
419}
420
DeLesley Hutchins7e615c22014-04-09 22:39:43 +0000421
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000422til::SExpr *
423SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {
424 DeclGroupRef DGrp = S->getDeclGroup();
425 for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
426 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
427 Expr *E = VD->getInit();
428 til::SExpr* SE = translate(E, Ctx);
DeLesley Hutchins7e615c22014-04-09 22:39:43 +0000429
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000430 // Add local variables with trivial type to the variable map
431 QualType T = VD->getType();
432 if (T.isTrivialType(VD->getASTContext())) {
433 return addVarDecl(VD, SE);
434 }
435 else {
436 // TODO: add alloca
437 }
438 }
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000439 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000440 return nullptr;
441}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000442
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000443
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000444
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000445// If (E) is non-trivial, then add it to the current basic block, and
446// update the statement map so that S refers to E. Returns a new variable
447// that refers to E.
448// If E is trivial returns E.
449til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
450 const ValueDecl *VD) {
451 if (!E)
452 return nullptr;
453 if (til::ThreadSafetyTIL::isTrivial(E))
454 return E;
455
456 til::Variable *V = new (Arena) til::Variable(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000457 CurrentInstructions.push_back(V);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000458 if (S)
459 insertStmt(S, V);
460 return V;
461}
462
463
464// Returns the current value of VD, if known, and nullptr otherwise.
465til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000466 auto It = LVarIdxMap.find(VD);
467 if (It != LVarIdxMap.end()) {
468 assert(CurrentLVarMap[It->second].first == VD);
469 return CurrentLVarMap[It->second].second;
470 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000471 return nullptr;
472}
473
474
475// if E is a til::Variable, update its clangDecl.
476inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
477 if (!E)
478 return;
479 if (til::Variable *V = dyn_cast<til::Variable>(E)) {
480 if (!V->clangDecl())
481 V->setClangDecl(VD);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000482 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000483}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000484
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000485// Adds a new variable declaration.
486til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {
487 maybeUpdateVD(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000488 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
489 CurrentLVarMap.makeWritable();
490 CurrentLVarMap.push_back(std::make_pair(VD, E));
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000491 return E;
492}
493
494
495// Updates a current variable declaration. (E.g. by assignment)
496til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {
497 maybeUpdateVD(E, VD);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000498 auto It = LVarIdxMap.find(VD);
499 if (It == LVarIdxMap.end()) {
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000500 til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD);
501 til::SExpr *St = new (Arena) til::Store(Ptr, E);
502 return St;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000503 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000504 CurrentLVarMap.makeWritable();
505 CurrentLVarMap.elem(It->second).second = E;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000506 return E;
507}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000508
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000509
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000510// Make a Phi node in the current block for the i^th variable in CurrentVarMap.
511// If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
512// If E == null, this is a backedge and will be set later.
513void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {
514 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
515 assert(ArgIndex > 0 && ArgIndex < NPreds);
516
517 til::Variable *V = dyn_cast<til::Variable>(CurrentLVarMap[i].second);
518 if (V && V->getBlockID() == CurrentBB->blockID()) {
519 // We already have a Phi node in the current block,
520 // so just add the new variable to the Phi node.
521 til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
522 assert(Ph && "Expecting Phi node.");
523 if (E)
524 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000525 return;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000526 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000527
528 // Make a new phi node: phi(..., E)
529 // All phi args up to the current index are set to the current value.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000530 til::SExpr *CurrE = CurrentLVarMap[i].second;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000531 til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds);
532 Ph->values().setValues(NPreds, nullptr);
533 for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000534 Ph->values()[PIdx] = CurrE;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000535 if (E)
536 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000537 // If E is from a back-edge, or either E or CurrE are incomplete, then
538 // mark this node as incomplete; we may need to remove it later.
539 if (!E || isIncompleteVar(E) || isIncompleteVar(CurrE)) {
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000540 Ph->setStatus(til::Phi::PH_Incomplete);
541 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000542
543 // Add Phi node to current block, and update CurrentLVarMap[i]
544 auto *Var = new (Arena) til::Variable(Ph, CurrentLVarMap[i].first);
545 CurrentArguments.push_back(Var);
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000546 if (Ph->status() == til::Phi::PH_Incomplete)
547 IncompleteArgs.push_back(Var);
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000548
549 CurrentLVarMap.makeWritable();
550 CurrentLVarMap.elem(i).second = Var;
551}
552
553
554// Merge values from Map into the current variable map.
555// This will construct Phi nodes in the current basic block as necessary.
556void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
557 assert(CurrentBlockInfo && "Not processing a block!");
558
559 if (!CurrentLVarMap.valid()) {
560 // Steal Map, using copy-on-write.
561 CurrentLVarMap = std::move(Map);
562 return;
563 }
564 if (CurrentLVarMap.sameAs(Map))
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000565 return; // Easy merge: maps from different predecessors are unchanged.
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000566
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000567 unsigned NPreds = CurrentBB->numPredecessors();
568 unsigned ESz = CurrentLVarMap.size();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000569 unsigned MSz = Map.size();
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000570 unsigned Sz = std::min(ESz, MSz);
571
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000572 for (unsigned i=0; i<Sz; ++i) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000573 if (CurrentLVarMap[i].first != Map[i].first) {
574 // We've reached the end of variables in common.
575 CurrentLVarMap.makeWritable();
576 CurrentLVarMap.downsize(i);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000577 break;
578 }
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000579 if (CurrentLVarMap[i].second != Map[i].second)
580 makePhiNodeVar(i, NPreds, Map[i].second);
DeLesley Hutchins11bb30872014-04-07 22:56:24 +0000581 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000582 if (ESz > MSz) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000583 CurrentLVarMap.makeWritable();
584 CurrentLVarMap.downsize(Map.size());
585 }
586}
587
588
589// Merge a back edge into the current variable map.
590// This will create phi nodes for all variables in the variable map.
591void SExprBuilder::mergeEntryMapBackEdge() {
592 // We don't have definitions for variables on the backedge, because we
593 // haven't gotten that far in the CFG. Thus, when encountering a back edge,
594 // we conservatively create Phi nodes for all variables. Unnecessary Phi
595 // nodes will be marked as incomplete, and stripped out at the end.
596 //
597 // An Phi node is unnecessary if it only refers to itself and one other
598 // variable, e.g. x = Phi(y, y, x) can be reduced to x = y.
599
600 assert(CurrentBlockInfo && "Not processing a block!");
601
602 if (CurrentBlockInfo->HasBackEdges)
603 return;
604 CurrentBlockInfo->HasBackEdges = true;
605
606 CurrentLVarMap.makeWritable();
607 unsigned Sz = CurrentLVarMap.size();
608 unsigned NPreds = CurrentBB->numPredecessors();
609
610 for (unsigned i=0; i < Sz; ++i) {
611 makePhiNodeVar(i, NPreds, nullptr);
612 }
613}
614
615
616// Update the phi nodes that were initially created for a back edge
617// once the variable definitions have been computed.
618// I.e., merge the current variable map into the phi nodes for Blk.
619void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
620 til::BasicBlock *BB = lookupBlock(Blk);
621 unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;
622 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
623
624 for (til::Variable *V : BB->arguments()) {
625 til::Phi *Ph = dyn_cast_or_null<til::Phi>(V->definition());
626 assert(Ph && "Expecting Phi Node.");
627 assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge.");
628 assert(V->clangDecl() && "No local variable for Phi node.");
629
630 til::SExpr *E = lookupVarDecl(V->clangDecl());
631 assert(E && "Couldn't find local variable for Phi node.");
632
633 Ph->values()[ArgIndex] = E;
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000634 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000635}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000636
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000637
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000638void SExprBuilder::enterCFG(CFG *Cfg, const FunctionDecl *FD,
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 }
Aaron Ballman8e8026d2014-04-23 14:26:59 +0000652 CallCtx.reset(new SExprBuilder::CallingContext(FD));
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000653
654 CurrentBB = lookupBlock(&Cfg->getEntry());
655 for (auto *Pm : FD->parameters()) {
656 QualType T = Pm->getType();
657 if (!T.isTrivialType(Pm->getASTContext()))
658 continue;
659
660 // Add parameters to local variable map.
661 // FIXME: right now we emulate params with loads; that should be fixed.
662 til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm);
663 til::SExpr *Ld = new (Arena) til::Load(Lp);
664 til::SExpr *V = addStatement(Ld, nullptr, Pm);
665 addVarDecl(Pm, V);
666 }
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000667}
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000668
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000669
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000670void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
671 // Intialize TIL basic block and add it to the CFG.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000672 CurrentBB = lookupBlock(B);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000673 CurrentBB->setNumPredecessors(B->pred_size());
674 Scfg->add(CurrentBB);
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000675
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000676 CurrentBlockInfo = &BBInfo[B->getBlockID()];
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000677
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000678 // CurrentLVarMap is moved to ExitMap on block exit.
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000679 // FIXME: the entry block will hold function parameters.
680 // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized.");
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000681}
682
683
684void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000685 // Compute CurrentLVarMap on entry from ExitMaps of predecessors
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000686
687 BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000688 assert(PredInfo->UnprocessedSuccessors > 0);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000689
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000690 if (--PredInfo->UnprocessedSuccessors == 0)
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000691 mergeEntryMap(std::move(PredInfo->ExitMap));
692 else
693 mergeEntryMap(PredInfo->ExitMap.clone());
694
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000695 ++CurrentBlockInfo->ProcessedPredecessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000696}
697
698
699void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000700 mergeEntryMapBackEdge();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000701}
702
703
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000704void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {
705 // The merge*() methods have created arguments.
706 // Push those arguments onto the basic block.
707 CurrentBB->arguments().reserve(
708 static_cast<unsigned>(CurrentArguments.size()), Arena);
709 for (auto *V : CurrentArguments)
710 CurrentBB->addArgument(V);
711}
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000712
713
714void SExprBuilder::handleStatement(const Stmt *S) {
Aaron Ballman8e8026d2014-04-23 14:26:59 +0000715 til::SExpr *E = translate(S, CallCtx.get());
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000716 addStatement(E, S);
717}
718
719
720void SExprBuilder::handleDestructorCall(const VarDecl *VD,
721 const CXXDestructorDecl *DD) {
722 til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
723 til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
724 til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
725 til::SExpr *E = new (Arena) til::Call(Ap);
726 addStatement(E, nullptr);
727}
728
729
730
731void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000732 CurrentBB->instructions().reserve(
733 static_cast<unsigned>(CurrentInstructions.size()), Arena);
734 for (auto *V : CurrentInstructions)
735 CurrentBB->addInstruction(V);
736
737 // Create an appropriate terminator
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000738 unsigned N = B->succ_size();
739 auto It = B->succ_begin();
740 if (N == 1) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000741 til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000742 // TODO: set index
743 til::SExpr *Tm = new (Arena) til::Goto(BB, 0);
744 CurrentBB->setTerminator(Tm);
745 }
746 else if (N == 2) {
Aaron Ballman8e8026d2014-04-23 14:26:59 +0000747 til::SExpr *C = translate(B->getTerminatorCondition(true), CallCtx.get());
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000748 til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000749 ++It;
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000750 til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000751 // TODO: set conditional, set index
752 til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2);
753 CurrentBB->setTerminator(Tm);
754 }
755}
756
757
758void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000759 ++CurrentBlockInfo->UnprocessedSuccessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000760}
761
762
763void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000764 mergePhiNodesBackEdge(Succ);
765 ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000766}
767
768
769void SExprBuilder::exitCFGBlock(const CFGBlock *B) {
DeLesley Hutchinsf8b412a2014-04-21 23:18:18 +0000770 CurrentArguments.clear();
771 CurrentInstructions.clear();
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000772 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000773 CurrentBB = nullptr;
774 CurrentBlockInfo = nullptr;
775}
776
777
778void SExprBuilder::exitCFG(const CFGBlock *Last) {
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000779 for (auto *V : IncompleteArgs) {
780 til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
781 if (Ph && Ph->status() == til::Phi::PH_Incomplete)
782 simplifyIncompleteArg(V, Ph);
783 }
784
DeLesley Hutchinsae497de2014-04-19 00:35:54 +0000785 CurrentArguments.clear();
786 CurrentInstructions.clear();
DeLesley Hutchinsa9db0012014-04-19 03:54:41 +0000787 IncompleteArgs.clear();
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000788}
789
790
791
792class LLVMPrinter : public til::PrettyPrinter<LLVMPrinter, llvm::raw_ostream> {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000793};
794
795
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000796void printSCFG(CFGWalker &Walker) {
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000797 llvm::BumpPtrAllocator Bpa;
798 til::MemRegionRef Arena(&Bpa);
DeLesley Hutchinsaab9aff2014-04-15 23:23:19 +0000799 SExprBuilder builder(Arena);
800 til::SCFG *Cfg = builder.buildCFG(Walker);
801 LLVMPrinter::print(Cfg, llvm::errs());
DeLesley Hutchinsb2213912014-04-07 18:09:54 +0000802}
803
804
805
806} // end namespace threadSafety
807
808} // end namespace clang