1*67e74705SXin Li //===- ThreadSafetyTIL.cpp -------------------------------------*- C++ --*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT in the llvm repository for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
11*67e74705SXin Li #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
12*67e74705SXin Li using namespace clang;
13*67e74705SXin Li using namespace threadSafety;
14*67e74705SXin Li using namespace til;
15*67e74705SXin Li
getUnaryOpcodeString(TIL_UnaryOpcode Op)16*67e74705SXin Li StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) {
17*67e74705SXin Li switch (Op) {
18*67e74705SXin Li case UOP_Minus: return "-";
19*67e74705SXin Li case UOP_BitNot: return "~";
20*67e74705SXin Li case UOP_LogicNot: return "!";
21*67e74705SXin Li }
22*67e74705SXin Li return "";
23*67e74705SXin Li }
24*67e74705SXin Li
getBinaryOpcodeString(TIL_BinaryOpcode Op)25*67e74705SXin Li StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) {
26*67e74705SXin Li switch (Op) {
27*67e74705SXin Li case BOP_Mul: return "*";
28*67e74705SXin Li case BOP_Div: return "/";
29*67e74705SXin Li case BOP_Rem: return "%";
30*67e74705SXin Li case BOP_Add: return "+";
31*67e74705SXin Li case BOP_Sub: return "-";
32*67e74705SXin Li case BOP_Shl: return "<<";
33*67e74705SXin Li case BOP_Shr: return ">>";
34*67e74705SXin Li case BOP_BitAnd: return "&";
35*67e74705SXin Li case BOP_BitXor: return "^";
36*67e74705SXin Li case BOP_BitOr: return "|";
37*67e74705SXin Li case BOP_Eq: return "==";
38*67e74705SXin Li case BOP_Neq: return "!=";
39*67e74705SXin Li case BOP_Lt: return "<";
40*67e74705SXin Li case BOP_Leq: return "<=";
41*67e74705SXin Li case BOP_LogicAnd: return "&&";
42*67e74705SXin Li case BOP_LogicOr: return "||";
43*67e74705SXin Li }
44*67e74705SXin Li return "";
45*67e74705SXin Li }
46*67e74705SXin Li
47*67e74705SXin Li
force()48*67e74705SXin Li SExpr* Future::force() {
49*67e74705SXin Li Status = FS_evaluating;
50*67e74705SXin Li Result = compute();
51*67e74705SXin Li Status = FS_done;
52*67e74705SXin Li return Result;
53*67e74705SXin Li }
54*67e74705SXin Li
55*67e74705SXin Li
addPredecessor(BasicBlock * Pred)56*67e74705SXin Li unsigned BasicBlock::addPredecessor(BasicBlock *Pred) {
57*67e74705SXin Li unsigned Idx = Predecessors.size();
58*67e74705SXin Li Predecessors.reserveCheck(1, Arena);
59*67e74705SXin Li Predecessors.push_back(Pred);
60*67e74705SXin Li for (SExpr *E : Args) {
61*67e74705SXin Li if (Phi* Ph = dyn_cast<Phi>(E)) {
62*67e74705SXin Li Ph->values().reserveCheck(1, Arena);
63*67e74705SXin Li Ph->values().push_back(nullptr);
64*67e74705SXin Li }
65*67e74705SXin Li }
66*67e74705SXin Li return Idx;
67*67e74705SXin Li }
68*67e74705SXin Li
69*67e74705SXin Li
reservePredecessors(unsigned NumPreds)70*67e74705SXin Li void BasicBlock::reservePredecessors(unsigned NumPreds) {
71*67e74705SXin Li Predecessors.reserve(NumPreds, Arena);
72*67e74705SXin Li for (SExpr *E : Args) {
73*67e74705SXin Li if (Phi* Ph = dyn_cast<Phi>(E)) {
74*67e74705SXin Li Ph->values().reserve(NumPreds, Arena);
75*67e74705SXin Li }
76*67e74705SXin Li }
77*67e74705SXin Li }
78*67e74705SXin Li
79*67e74705SXin Li
80*67e74705SXin Li // If E is a variable, then trace back through any aliases or redundant
81*67e74705SXin Li // Phi nodes to find the canonical definition.
getCanonicalVal(const SExpr * E)82*67e74705SXin Li const SExpr *til::getCanonicalVal(const SExpr *E) {
83*67e74705SXin Li while (true) {
84*67e74705SXin Li if (auto *V = dyn_cast<Variable>(E)) {
85*67e74705SXin Li if (V->kind() == Variable::VK_Let) {
86*67e74705SXin Li E = V->definition();
87*67e74705SXin Li continue;
88*67e74705SXin Li }
89*67e74705SXin Li }
90*67e74705SXin Li if (const Phi *Ph = dyn_cast<Phi>(E)) {
91*67e74705SXin Li if (Ph->status() == Phi::PH_SingleVal) {
92*67e74705SXin Li E = Ph->values()[0];
93*67e74705SXin Li continue;
94*67e74705SXin Li }
95*67e74705SXin Li }
96*67e74705SXin Li break;
97*67e74705SXin Li }
98*67e74705SXin Li return E;
99*67e74705SXin Li }
100*67e74705SXin Li
101*67e74705SXin Li
102*67e74705SXin Li // If E is a variable, then trace back through any aliases or redundant
103*67e74705SXin Li // Phi nodes to find the canonical definition.
104*67e74705SXin Li // The non-const version will simplify incomplete Phi nodes.
simplifyToCanonicalVal(SExpr * E)105*67e74705SXin Li SExpr *til::simplifyToCanonicalVal(SExpr *E) {
106*67e74705SXin Li while (true) {
107*67e74705SXin Li if (auto *V = dyn_cast<Variable>(E)) {
108*67e74705SXin Li if (V->kind() != Variable::VK_Let)
109*67e74705SXin Li return V;
110*67e74705SXin Li // Eliminate redundant variables, e.g. x = y, or x = 5,
111*67e74705SXin Li // but keep anything more complicated.
112*67e74705SXin Li if (til::ThreadSafetyTIL::isTrivial(V->definition())) {
113*67e74705SXin Li E = V->definition();
114*67e74705SXin Li continue;
115*67e74705SXin Li }
116*67e74705SXin Li return V;
117*67e74705SXin Li }
118*67e74705SXin Li if (auto *Ph = dyn_cast<Phi>(E)) {
119*67e74705SXin Li if (Ph->status() == Phi::PH_Incomplete)
120*67e74705SXin Li simplifyIncompleteArg(Ph);
121*67e74705SXin Li // Eliminate redundant Phi nodes.
122*67e74705SXin Li if (Ph->status() == Phi::PH_SingleVal) {
123*67e74705SXin Li E = Ph->values()[0];
124*67e74705SXin Li continue;
125*67e74705SXin Li }
126*67e74705SXin Li }
127*67e74705SXin Li return E;
128*67e74705SXin Li }
129*67e74705SXin Li }
130*67e74705SXin Li
131*67e74705SXin Li
132*67e74705SXin Li // Trace the arguments of an incomplete Phi node to see if they have the same
133*67e74705SXin Li // canonical definition. If so, mark the Phi node as redundant.
134*67e74705SXin Li // getCanonicalVal() will recursively call simplifyIncompletePhi().
simplifyIncompleteArg(til::Phi * Ph)135*67e74705SXin Li void til::simplifyIncompleteArg(til::Phi *Ph) {
136*67e74705SXin Li assert(Ph && Ph->status() == Phi::PH_Incomplete);
137*67e74705SXin Li
138*67e74705SXin Li // eliminate infinite recursion -- assume that this node is not redundant.
139*67e74705SXin Li Ph->setStatus(Phi::PH_MultiVal);
140*67e74705SXin Li
141*67e74705SXin Li SExpr *E0 = simplifyToCanonicalVal(Ph->values()[0]);
142*67e74705SXin Li for (unsigned i=1, n=Ph->values().size(); i<n; ++i) {
143*67e74705SXin Li SExpr *Ei = simplifyToCanonicalVal(Ph->values()[i]);
144*67e74705SXin Li if (Ei == Ph)
145*67e74705SXin Li continue; // Recursive reference to itself. Don't count.
146*67e74705SXin Li if (Ei != E0) {
147*67e74705SXin Li return; // Status is already set to MultiVal.
148*67e74705SXin Li }
149*67e74705SXin Li }
150*67e74705SXin Li Ph->setStatus(Phi::PH_SingleVal);
151*67e74705SXin Li }
152*67e74705SXin Li
153*67e74705SXin Li
154*67e74705SXin Li // Renumbers the arguments and instructions to have unique, sequential IDs.
renumberInstrs(int ID)155*67e74705SXin Li int BasicBlock::renumberInstrs(int ID) {
156*67e74705SXin Li for (auto *Arg : Args)
157*67e74705SXin Li Arg->setID(this, ID++);
158*67e74705SXin Li for (auto *Instr : Instrs)
159*67e74705SXin Li Instr->setID(this, ID++);
160*67e74705SXin Li TermInstr->setID(this, ID++);
161*67e74705SXin Li return ID;
162*67e74705SXin Li }
163*67e74705SXin Li
164*67e74705SXin Li // Sorts the CFGs blocks using a reverse post-order depth-first traversal.
165*67e74705SXin Li // Each block will be written into the Blocks array in order, and its BlockID
166*67e74705SXin Li // will be set to the index in the array. Sorting should start from the entry
167*67e74705SXin Li // block, and ID should be the total number of blocks.
topologicalSort(SimpleArray<BasicBlock * > & Blocks,int ID)168*67e74705SXin Li int BasicBlock::topologicalSort(SimpleArray<BasicBlock*>& Blocks, int ID) {
169*67e74705SXin Li if (Visited) return ID;
170*67e74705SXin Li Visited = true;
171*67e74705SXin Li for (auto *Block : successors())
172*67e74705SXin Li ID = Block->topologicalSort(Blocks, ID);
173*67e74705SXin Li // set ID and update block array in place.
174*67e74705SXin Li // We may lose pointers to unreachable blocks.
175*67e74705SXin Li assert(ID > 0);
176*67e74705SXin Li BlockID = --ID;
177*67e74705SXin Li Blocks[BlockID] = this;
178*67e74705SXin Li return ID;
179*67e74705SXin Li }
180*67e74705SXin Li
181*67e74705SXin Li // Performs a reverse topological traversal, starting from the exit block and
182*67e74705SXin Li // following back-edges. The dominator is serialized before any predecessors,
183*67e74705SXin Li // which guarantees that all blocks are serialized after their dominator and
184*67e74705SXin Li // before their post-dominator (because it's a reverse topological traversal).
185*67e74705SXin Li // ID should be initially set to 0.
186*67e74705SXin Li //
187*67e74705SXin Li // This sort assumes that (1) dominators have been computed, (2) there are no
188*67e74705SXin Li // critical edges, and (3) the entry block is reachable from the exit block
189*67e74705SXin Li // and no blocks are accessable via traversal of back-edges from the exit that
190*67e74705SXin Li // weren't accessable via forward edges from the entry.
topologicalFinalSort(SimpleArray<BasicBlock * > & Blocks,int ID)191*67e74705SXin Li int BasicBlock::topologicalFinalSort(SimpleArray<BasicBlock*>& Blocks, int ID) {
192*67e74705SXin Li // Visited is assumed to have been set by the topologicalSort. This pass
193*67e74705SXin Li // assumes !Visited means that we've visited this node before.
194*67e74705SXin Li if (!Visited) return ID;
195*67e74705SXin Li Visited = false;
196*67e74705SXin Li if (DominatorNode.Parent)
197*67e74705SXin Li ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID);
198*67e74705SXin Li for (auto *Pred : Predecessors)
199*67e74705SXin Li ID = Pred->topologicalFinalSort(Blocks, ID);
200*67e74705SXin Li assert(static_cast<size_t>(ID) < Blocks.size());
201*67e74705SXin Li BlockID = ID++;
202*67e74705SXin Li Blocks[BlockID] = this;
203*67e74705SXin Li return ID;
204*67e74705SXin Li }
205*67e74705SXin Li
206*67e74705SXin Li // Computes the immediate dominator of the current block. Assumes that all of
207*67e74705SXin Li // its predecessors have already computed their dominators. This is achieved
208*67e74705SXin Li // by visiting the nodes in topological order.
computeDominator()209*67e74705SXin Li void BasicBlock::computeDominator() {
210*67e74705SXin Li BasicBlock *Candidate = nullptr;
211*67e74705SXin Li // Walk backwards from each predecessor to find the common dominator node.
212*67e74705SXin Li for (auto *Pred : Predecessors) {
213*67e74705SXin Li // Skip back-edges
214*67e74705SXin Li if (Pred->BlockID >= BlockID) continue;
215*67e74705SXin Li // If we don't yet have a candidate for dominator yet, take this one.
216*67e74705SXin Li if (Candidate == nullptr) {
217*67e74705SXin Li Candidate = Pred;
218*67e74705SXin Li continue;
219*67e74705SXin Li }
220*67e74705SXin Li // Walk the alternate and current candidate back to find a common ancestor.
221*67e74705SXin Li auto *Alternate = Pred;
222*67e74705SXin Li while (Alternate != Candidate) {
223*67e74705SXin Li if (Candidate->BlockID > Alternate->BlockID)
224*67e74705SXin Li Candidate = Candidate->DominatorNode.Parent;
225*67e74705SXin Li else
226*67e74705SXin Li Alternate = Alternate->DominatorNode.Parent;
227*67e74705SXin Li }
228*67e74705SXin Li }
229*67e74705SXin Li DominatorNode.Parent = Candidate;
230*67e74705SXin Li DominatorNode.SizeOfSubTree = 1;
231*67e74705SXin Li }
232*67e74705SXin Li
233*67e74705SXin Li // Computes the immediate post-dominator of the current block. Assumes that all
234*67e74705SXin Li // of its successors have already computed their post-dominators. This is
235*67e74705SXin Li // achieved visiting the nodes in reverse topological order.
computePostDominator()236*67e74705SXin Li void BasicBlock::computePostDominator() {
237*67e74705SXin Li BasicBlock *Candidate = nullptr;
238*67e74705SXin Li // Walk back from each predecessor to find the common post-dominator node.
239*67e74705SXin Li for (auto *Succ : successors()) {
240*67e74705SXin Li // Skip back-edges
241*67e74705SXin Li if (Succ->BlockID <= BlockID) continue;
242*67e74705SXin Li // If we don't yet have a candidate for post-dominator yet, take this one.
243*67e74705SXin Li if (Candidate == nullptr) {
244*67e74705SXin Li Candidate = Succ;
245*67e74705SXin Li continue;
246*67e74705SXin Li }
247*67e74705SXin Li // Walk the alternate and current candidate back to find a common ancestor.
248*67e74705SXin Li auto *Alternate = Succ;
249*67e74705SXin Li while (Alternate != Candidate) {
250*67e74705SXin Li if (Candidate->BlockID < Alternate->BlockID)
251*67e74705SXin Li Candidate = Candidate->PostDominatorNode.Parent;
252*67e74705SXin Li else
253*67e74705SXin Li Alternate = Alternate->PostDominatorNode.Parent;
254*67e74705SXin Li }
255*67e74705SXin Li }
256*67e74705SXin Li PostDominatorNode.Parent = Candidate;
257*67e74705SXin Li PostDominatorNode.SizeOfSubTree = 1;
258*67e74705SXin Li }
259*67e74705SXin Li
260*67e74705SXin Li
261*67e74705SXin Li // Renumber instructions in all blocks
renumberInstrs()262*67e74705SXin Li void SCFG::renumberInstrs() {
263*67e74705SXin Li int InstrID = 0;
264*67e74705SXin Li for (auto *Block : Blocks)
265*67e74705SXin Li InstrID = Block->renumberInstrs(InstrID);
266*67e74705SXin Li }
267*67e74705SXin Li
268*67e74705SXin Li
computeNodeSize(BasicBlock * B,BasicBlock::TopologyNode BasicBlock::* TN)269*67e74705SXin Li static inline void computeNodeSize(BasicBlock *B,
270*67e74705SXin Li BasicBlock::TopologyNode BasicBlock::*TN) {
271*67e74705SXin Li BasicBlock::TopologyNode *N = &(B->*TN);
272*67e74705SXin Li if (N->Parent) {
273*67e74705SXin Li BasicBlock::TopologyNode *P = &(N->Parent->*TN);
274*67e74705SXin Li // Initially set ID relative to the (as yet uncomputed) parent ID
275*67e74705SXin Li N->NodeID = P->SizeOfSubTree;
276*67e74705SXin Li P->SizeOfSubTree += N->SizeOfSubTree;
277*67e74705SXin Li }
278*67e74705SXin Li }
279*67e74705SXin Li
computeNodeID(BasicBlock * B,BasicBlock::TopologyNode BasicBlock::* TN)280*67e74705SXin Li static inline void computeNodeID(BasicBlock *B,
281*67e74705SXin Li BasicBlock::TopologyNode BasicBlock::*TN) {
282*67e74705SXin Li BasicBlock::TopologyNode *N = &(B->*TN);
283*67e74705SXin Li if (N->Parent) {
284*67e74705SXin Li BasicBlock::TopologyNode *P = &(N->Parent->*TN);
285*67e74705SXin Li N->NodeID += P->NodeID; // Fix NodeIDs relative to starting node.
286*67e74705SXin Li }
287*67e74705SXin Li }
288*67e74705SXin Li
289*67e74705SXin Li
290*67e74705SXin Li // Normalizes a CFG. Normalization has a few major components:
291*67e74705SXin Li // 1) Removing unreachable blocks.
292*67e74705SXin Li // 2) Computing dominators and post-dominators
293*67e74705SXin Li // 3) Topologically sorting the blocks into the "Blocks" array.
computeNormalForm()294*67e74705SXin Li void SCFG::computeNormalForm() {
295*67e74705SXin Li // Topologically sort the blocks starting from the entry block.
296*67e74705SXin Li int NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.size());
297*67e74705SXin Li if (NumUnreachableBlocks > 0) {
298*67e74705SXin Li // If there were unreachable blocks shift everything down, and delete them.
299*67e74705SXin Li for (size_t I = NumUnreachableBlocks, E = Blocks.size(); I < E; ++I) {
300*67e74705SXin Li size_t NI = I - NumUnreachableBlocks;
301*67e74705SXin Li Blocks[NI] = Blocks[I];
302*67e74705SXin Li Blocks[NI]->BlockID = NI;
303*67e74705SXin Li // FIXME: clean up predecessor pointers to unreachable blocks?
304*67e74705SXin Li }
305*67e74705SXin Li Blocks.drop(NumUnreachableBlocks);
306*67e74705SXin Li }
307*67e74705SXin Li
308*67e74705SXin Li // Compute dominators.
309*67e74705SXin Li for (auto *Block : Blocks)
310*67e74705SXin Li Block->computeDominator();
311*67e74705SXin Li
312*67e74705SXin Li // Once dominators have been computed, the final sort may be performed.
313*67e74705SXin Li int NumBlocks = Exit->topologicalFinalSort(Blocks, 0);
314*67e74705SXin Li assert(static_cast<size_t>(NumBlocks) == Blocks.size());
315*67e74705SXin Li (void) NumBlocks;
316*67e74705SXin Li
317*67e74705SXin Li // Renumber the instructions now that we have a final sort.
318*67e74705SXin Li renumberInstrs();
319*67e74705SXin Li
320*67e74705SXin Li // Compute post-dominators and compute the sizes of each node in the
321*67e74705SXin Li // dominator tree.
322*67e74705SXin Li for (auto *Block : Blocks.reverse()) {
323*67e74705SXin Li Block->computePostDominator();
324*67e74705SXin Li computeNodeSize(Block, &BasicBlock::DominatorNode);
325*67e74705SXin Li }
326*67e74705SXin Li // Compute the sizes of each node in the post-dominator tree and assign IDs in
327*67e74705SXin Li // the dominator tree.
328*67e74705SXin Li for (auto *Block : Blocks) {
329*67e74705SXin Li computeNodeID(Block, &BasicBlock::DominatorNode);
330*67e74705SXin Li computeNodeSize(Block, &BasicBlock::PostDominatorNode);
331*67e74705SXin Li }
332*67e74705SXin Li // Assign IDs in the post-dominator tree.
333*67e74705SXin Li for (auto *Block : Blocks.reverse()) {
334*67e74705SXin Li computeNodeID(Block, &BasicBlock::PostDominatorNode);
335*67e74705SXin Li }
336*67e74705SXin Li }
337