clang: lib/Analysis/ThreadSafetyTIL.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

11#include "llvm/Support/Casting.h"

12#include

13#include

14

15using namespace clang;

16using namespace threadSafety;

17using namespace til;

18

20 switch (Op) {

24 }

25 return {};

26}

27

29 switch (Op) {

35 case BOP_Shl: return "<<";

36 case BOP_Shr: return ">>";

40 case BOP_Eq: return "==";

41 case BOP_Neq: return "!=";

42 case BOP_Lt: return "<";

43 case BOP_Leq: return "<=";

44 case BOP_Cmp: return "<=>";

47 }

48 return {};

49}

50

51SExpr* Future::force() {

55 return Result;

56}

57

59 unsigned Idx = Predecessors.size();

62 for (auto *E : Args) {

63 if (auto *Ph = dyn_cast(E)) {

64 Ph->values().reserveCheck(1, Arena);

65 Ph->values().push_back(nullptr);

66 }

67 }

68 return Idx;

69}

70

72 Predecessors.reserve(NumPreds, Arena);

73 for (auto *E : Args) {

74 if (auto *Ph = dyn_cast(E)) {

75 Ph->values().reserve(NumPreds, Arena);

76 }

77 }

78}

79

80

81

83 while (true) {

84 if (const auto *V = dyn_cast(E)) {

86 E = V->definition();

87 continue;

88 }

89 }

90 if (const auto *Ph = dyn_cast(E)) {

92 E = Ph->values()[0];

93 continue;

94 }

95 }

96 break;

97 }

98 return E;

99}

100

101

102

103

105 while (true) {

106 if (auto *V = dyn_cast(E)) {

108 return V;

109

110

112 E = V->definition();

113 continue;

114 }

115 return V;

116 }

117 if (auto *Ph = dyn_cast(E)) {

120

122 E = Ph->values()[0];

123 continue;

124 }

125 }

126 return E;

127 }

128}

129

130

131

132

135

136

138

140 for (unsigned i = 1, n = Ph->values().size(); i < n; ++i) {

142 if (Ei == Ph)

143 continue;

144 if (Ei != E0) {

145 return;

146 }

147 }

149}

150

151

152unsigned BasicBlock::renumberInstrs(unsigned ID) {

153 for (auto *Arg : Args)

154 Arg->setID(this, ID++);

155 for (auto *Instr : Instrs)

156 Instr->setID(this, ID++);

157 TermInstr->setID(this, ID++);

158 return ID;

159}

160

161

162

163

164

166 unsigned ID) {

167 if (Visited) return ID;

168 Visited = true;

170 ID = Block->topologicalSort(Blocks, ID);

171

172

173 assert(ID > 0);

174 BlockID = --ID;

175 Blocks[BlockID] = this;

176 return ID;

177}

178

179

180

181

182

183

184

185

186

187

188

190 unsigned ID) {

191

192

193 if (!Visited) return ID;

194 Visited = false;

195 if (DominatorNode.Parent)

196 ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID);

197 for (auto *Pred : Predecessors)

198 ID = Pred->topologicalFinalSort(Blocks, ID);

199 assert(static_cast<size_t>(ID) < Blocks.size());

200 BlockID = ID++;

201 Blocks[BlockID] = this;

202 return ID;

203}

204

205

206

207

208void BasicBlock::computeDominator() {

210

211 for (auto *Pred : Predecessors) {

212

213 if (Pred->BlockID >= BlockID) continue;

214

215 if (Candidate == nullptr) {

216 Candidate = Pred;

217 continue;

218 }

219

220 auto *Alternate = Pred;

221 while (Alternate != Candidate) {

222 if (Candidate->BlockID > Alternate->BlockID)

223 Candidate = Candidate->DominatorNode.Parent;

224 else

225 Alternate = Alternate->DominatorNode.Parent;

226 }

227 }

228 DominatorNode.Parent = Candidate;

230}

231

232

233

234

235void BasicBlock::computePostDominator() {

237

239

240 if (Succ->BlockID <= BlockID) continue;

241

242 if (Candidate == nullptr) {

243 Candidate = Succ;

244 continue;

245 }

246

247 auto *Alternate = Succ;

248 while (Alternate != Candidate) {

249 if (Candidate->BlockID < Alternate->BlockID)

250 Candidate = Candidate->PostDominatorNode.Parent;

251 else

252 Alternate = Alternate->PostDominatorNode.Parent;

253 }

254 }

255 PostDominatorNode.Parent = Candidate;

257}

258

259

260void SCFG::renumberInstrs() {

261 unsigned InstrID = 0;

262 for (auto *Block : Blocks)

263 InstrID = Block->renumberInstrs(InstrID);

264}

265

271

272 N->NodeID = P->SizeOfSubTree;

274 }

275}

276

282 N->NodeID += P->NodeID;

283 }

284}

285

286

287

288

289

291

292 unsigned NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.size());

293 if (NumUnreachableBlocks > 0) {

294

295 for (unsigned I = NumUnreachableBlocks, E = Blocks.size(); I < E; ++I) {

296 unsigned NI = I - NumUnreachableBlocks;

297 Blocks[NI] = Blocks[I];

298 Blocks[NI]->BlockID = NI;

299

300 }

301 Blocks.drop(NumUnreachableBlocks);

302 }

303

304

305 for (auto *Block : Blocks)

306 Block->computeDominator();

307

308

309 unsigned NumBlocks = Exit->topologicalFinalSort(Blocks, 0);

310 assert(static_cast<size_t>(NumBlocks) == Blocks.size());

311 (void) NumBlocks;

312

313

314 renumberInstrs();

315

316

317

318 for (auto *Block : Blocks.reverse()) {

319 Block->computePostDominator();

321 }

322

323

324 for (auto *Block : Blocks) {

327 }

328

329 for (auto *Block : Blocks.reverse()) {

331 }

332}

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

static void computeNodeSize(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)

static void computeNodeID(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)

A basic block is part of an SCFG.

unsigned addPredecessor(BasicBlock *Pred)

ArrayRef< BasicBlock * > successors()

void reservePredecessors(unsigned NumPreds)

virtual SExpr * compute()

Phi Node, for code in SSA form.

const ValArray & values() const

Base class for AST nodes in the typed intermediate language.

void setID(BasicBlock *B, unsigned id)

Set the basic block and instruction ID for this expression.

void reserve(size_t Ncp, MemRegionRef A)

void push_back(const T &Elem)

void reserveCheck(size_t N, MemRegionRef A)

bool isTrivial(const SExpr *E)

TIL_UnaryOpcode

Opcode for unary arithmetic operations.

void simplifyIncompleteArg(til::Phi *Ph)

StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op)

Return the name of a binary opcode.

StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op)

Return the name of a unary opcode.

TIL_BinaryOpcode

Opcode for binary arithmetic operations.

SExpr * simplifyToCanonicalVal(SExpr *E)

const SExpr * getCanonicalVal(const SExpr *E)

The JSON file list parser is used to communicate input to InstallAPI.