1 //===- ThreadSafetyTIL.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 in the llvm repository for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h" 11 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h" 12 13 namespace clang { 14 namespace threadSafety { 15 namespace til { 16 17 18 StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op) { 19 switch (Op) { 20 case UOP_Minus: return "-"; 21 case UOP_BitNot: return "~"; 22 case UOP_LogicNot: return "!"; 23 } 24 return ""; 25 } 26 27 28 StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op) { 29 switch (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 "||"; 46 } 47 return ""; 48 } 49 50 51 52 // If E is a variable, then trace back through any aliases or redundant 53 // Phi nodes to find the canonical definition. 54 SExpr *getCanonicalVal(SExpr *E) { 55 while (auto *V = dyn_cast<Variable>(E)) { 56 SExpr *D; 57 do { 58 if (V->kind() != Variable::VK_Let) 59 return V; 60 D = V->definition(); 61 auto *V2 = dyn_cast<Variable>(D); 62 if (V2) 63 V = V2; 64 else 65 break; 66 } while (true); 67 68 if (ThreadSafetyTIL::isTrivial(D)) 69 return D; 70 71 if (Phi *Ph = dyn_cast<Phi>(D)) { 72 if (Ph->status() == Phi::PH_Incomplete) 73 simplifyIncompleteArg(V, Ph); 74 75 if (Ph->status() == Phi::PH_SingleVal) { 76 E = Ph->values()[0]; 77 continue; 78 } 79 } 80 return V; 81 } 82 return E; 83 } 84 85 86 // Trace the arguments of an incomplete Phi node to see if they have the same 87 // canonical definition. If so, mark the Phi node as redundant. 88 // getCanonicalVal() will recursively call simplifyIncompletePhi(). 89 void simplifyIncompleteArg(Variable *V, til::Phi *Ph) { 90 assert(Ph && Ph->status() == Phi::PH_Incomplete); 91 92 // eliminate infinite recursion -- assume that this node is not redundant. 93 Ph->setStatus(Phi::PH_MultiVal); 94 95 SExpr *E0 = getCanonicalVal(Ph->values()[0]); 96 for (unsigned i=1, n=Ph->values().size(); i<n; ++i) { 97 SExpr *Ei = getCanonicalVal(Ph->values()[i]); 98 if (Ei == V) 99 continue; // Recursive reference to itself. Don't count. 100 if (Ei != E0) { 101 return; // Status is already set to MultiVal. 102 } 103 } 104 Ph->setStatus(Phi::PH_SingleVal); 105 // Eliminate Redundant Phi node. 106 V->setDefinition(Ph->values()[0]); 107 } 108 109 110 } // end namespace til 111 } // end namespace threadSafety 112 } // end namespace clang 113 114