1 //===- ThreadSafetyTIL.cpp -------------------------------------*- C++ --*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT in the llvm repository for details.
8 //===----------------------------------------------------------------------===//
10 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
11 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
14 namespace threadSafety {
18 StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op) {
20 case UOP_Minus: return "-";
21 case UOP_BitNot: return "~";
22 case UOP_LogicNot: return "!";
28 StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op) {
30 case BOP_Mul: return "*";
31 case BOP_Div: return "/";
32 case BOP_Rem: return "%";
33 case BOP_Add: return "+";
34 case BOP_Sub: return "-";
35 case BOP_Shl: return "<<";
36 case BOP_Shr: return ">>";
37 case BOP_BitAnd: return "&";
38 case BOP_BitXor: return "^";
39 case BOP_BitOr: return "|";
40 case BOP_Eq: return "==";
41 case BOP_Neq: return "!=";
42 case BOP_Lt: return "<";
43 case BOP_Leq: return "<=";
44 case BOP_LogicAnd: return "&&";
45 case BOP_LogicOr: return "||";
51 unsigned BasicBlock::addPredecessor(BasicBlock *Pred) {
52 unsigned Idx = Predecessors.size();
53 Predecessors.reserveCheck(1, Arena);
54 Predecessors.push_back(Pred);
55 for (Variable *V : Args) {
56 if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
57 Ph->values().reserveCheck(1, Arena);
58 Ph->values().push_back(nullptr);
64 void BasicBlock::reservePredecessors(unsigned NumPreds) {
65 Predecessors.reserve(NumPreds, Arena);
66 for (Variable *V : Args) {
67 if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
68 Ph->values().reserve(NumPreds, Arena);
73 void BasicBlock::renumberVars() {
75 for (Variable *V : Args) {
76 V->setID(BlockID, VID++);
78 for (Variable *V : Instrs) {
79 V->setID(BlockID, VID++);
83 void SCFG::renumberVars() {
84 for (BasicBlock *B : Blocks) {
92 // If E is a variable, then trace back through any aliases or redundant
93 // Phi nodes to find the canonical definition.
94 SExpr *getCanonicalVal(SExpr *E) {
95 while (auto *V = dyn_cast<Variable>(E)) {
98 if (V->kind() != Variable::VK_Let)
101 auto *V2 = dyn_cast<Variable>(D);
108 if (ThreadSafetyTIL::isTrivial(D))
111 if (Phi *Ph = dyn_cast<Phi>(D)) {
112 if (Ph->status() == Phi::PH_Incomplete)
113 simplifyIncompleteArg(V, Ph);
115 if (Ph->status() == Phi::PH_SingleVal) {
126 // Trace the arguments of an incomplete Phi node to see if they have the same
127 // canonical definition. If so, mark the Phi node as redundant.
128 // getCanonicalVal() will recursively call simplifyIncompletePhi().
129 void simplifyIncompleteArg(Variable *V, til::Phi *Ph) {
130 assert(Ph && Ph->status() == Phi::PH_Incomplete);
132 // eliminate infinite recursion -- assume that this node is not redundant.
133 Ph->setStatus(Phi::PH_MultiVal);
135 SExpr *E0 = getCanonicalVal(Ph->values()[0]);
136 for (unsigned i=1, n=Ph->values().size(); i<n; ++i) {
137 SExpr *Ei = getCanonicalVal(Ph->values()[i]);
139 continue; // Recursive reference to itself. Don't count.
141 return; // Status is already set to MultiVal.
144 Ph->setStatus(Phi::PH_SingleVal);
145 // Eliminate Redundant Phi node.
146 V->setDefinition(Ph->values()[0]);
150 } // end namespace til
151 } // end namespace threadSafety
152 } // end namespace clang