12 #include "llvm/Support/Casting.h" 16 using namespace clang;
17 using namespace threadSafety;
52 SExpr* Future::force() {
60 unsigned Idx = Predecessors.size();
61 Predecessors.reserveCheck(1, Arena);
62 Predecessors.push_back(Pred);
63 for (
auto *E : Args) {
64 if (
auto *Ph = dyn_cast<Phi>(E)) {
65 Ph->values().reserveCheck(1, Arena);
66 Ph->values().push_back(
nullptr);
73 Predecessors.reserve(NumPreds, Arena);
74 for (
auto *E : Args) {
75 if (
auto *Ph = dyn_cast<Phi>(E)) {
76 Ph->values().reserve(NumPreds, Arena);
85 if (
const auto *V = dyn_cast<Variable>(E)) {
91 if (
const auto *Ph = dyn_cast<Phi>(E)) {
107 if (
auto *V = dyn_cast<Variable>(E)) {
118 if (
auto *Ph = dyn_cast<Phi>(E)) {
141 for (
unsigned i = 1, n = Ph->
values().
size(); i < n; ++i) {
153 unsigned BasicBlock::renumberInstrs(
unsigned ID) {
154 for (
auto *Arg : Args)
155 Arg->setID(
this, ID++);
156 for (
auto *Instr : Instrs)
157 Instr->setID(
this, ID++);
158 TermInstr->setID(
this, ID++);
168 if (Visited)
return ID;
170 for (
auto *
Block : successors())
171 ID =
Block->topologicalSort(Blocks, ID);
176 Blocks[BlockID] =
this;
194 if (!Visited)
return ID;
196 if (DominatorNode.Parent)
197 ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID);
198 for (
auto *Pred : Predecessors)
199 ID = Pred->topologicalFinalSort(Blocks, ID);
200 assert(static_cast<size_t>(ID) < Blocks.
size());
202 Blocks[BlockID] =
this;
209 void BasicBlock::computeDominator() {
212 for (
auto *Pred : Predecessors) {
214 if (Pred->BlockID >= BlockID)
continue;
216 if (Candidate ==
nullptr) {
221 auto *Alternate = Pred;
222 while (Alternate != Candidate) {
223 if (Candidate->BlockID > Alternate->BlockID)
224 Candidate = Candidate->DominatorNode.
Parent;
226 Alternate = Alternate->DominatorNode.
Parent;
229 DominatorNode.Parent = Candidate;
230 DominatorNode.SizeOfSubTree = 1;
236 void BasicBlock::computePostDominator() {
239 for (
auto *Succ : successors()) {
241 if (Succ->BlockID <= BlockID)
continue;
243 if (Candidate ==
nullptr) {
248 auto *Alternate = Succ;
249 while (Alternate != Candidate) {
250 if (Candidate->BlockID < Alternate->BlockID)
251 Candidate = Candidate->PostDominatorNode.
Parent;
253 Alternate = Alternate->PostDominatorNode.
Parent;
256 PostDominatorNode.Parent = Candidate;
257 PostDominatorNode.SizeOfSubTree = 1;
261 void SCFG::renumberInstrs() {
262 unsigned InstrID = 0;
263 for (
auto *
Block : Blocks)
264 InstrID =
Block->renumberInstrs(InstrID);
293 unsigned NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.
size());
294 if (NumUnreachableBlocks > 0) {
296 for (
unsigned I = NumUnreachableBlocks, E = Blocks.
size(); I < E; ++I) {
297 unsigned NI = I - NumUnreachableBlocks;
298 Blocks[NI] = Blocks[I];
299 Blocks[NI]->BlockID = NI;
302 Blocks.
drop(NumUnreachableBlocks);
306 for (
auto *
Block : Blocks)
307 Block->computeDominator();
310 unsigned NumBlocks = Exit->topologicalFinalSort(Blocks, 0);
311 assert(static_cast<size_t>(NumBlocks) == Blocks.size());
319 for (
auto *
Block : Blocks.reverse()) {
320 Block->computePostDominator();
325 for (
auto *
Block : Blocks) {
330 for (
auto *
Block : Blocks.reverse()) {
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op)
Return the name of a binary opcode.
SExpr * simplifyToCanonicalVal(SExpr *E)
unsigned addPredecessor(BasicBlock *Pred)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
virtual SExpr * compute()
A basic block is part of an SCFG.
static void computeNodeSize(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op)
Return the name of a unary opcode.
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void reservePredecessors(unsigned NumPreds)
const ValArray & values() const
TIL_UnaryOpcode
Opcode for unary arithmetic operations.
const SExpr * getCanonicalVal(const SExpr *E)
Dataflow Directional Tag Classes.
Phi Node, for code in SSA form.
static void computeNodeID(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)
bool isTrivial(const SExpr *E)
void simplifyIncompleteArg(til::Phi *Ph)
Base class for AST nodes in the typed intermediate language.