12 using namespace clang;
13 using namespace threadSafety;
49 SExpr* Future::force() {
58 unsigned Idx = Predecessors.size();
59 Predecessors.reserveCheck(1, Arena);
60 Predecessors.push_back(Pred);
61 for (
SExpr *E : Args) {
62 if (
Phi* Ph = dyn_cast<Phi>(E)) {
63 Ph->values().reserveCheck(1, Arena);
64 Ph->values().push_back(
nullptr);
72 Predecessors.reserve(NumPreds, Arena);
73 for (
SExpr *E : Args) {
74 if (
Phi* Ph = dyn_cast<Phi>(E)) {
75 Ph->values().reserve(NumPreds, Arena);
85 if (
auto *V = dyn_cast<Variable>(E)) {
91 if (
const Phi *Ph = dyn_cast<Phi>(E)) {
108 if (
auto *V = dyn_cast<Variable>(E)) {
119 if (
auto *Ph = dyn_cast<Phi>(E)) {
143 for (
unsigned i=1, n=Ph->
values().
size(); i<n; ++i) {
156 int BasicBlock::renumberInstrs(
int ID) {
157 for (
auto *Arg : Args)
158 Arg->setID(
this, ID++);
159 for (
auto *Instr : Instrs)
160 Instr->setID(
this, ID++);
161 TermInstr->setID(
this, ID++);
170 if (Visited)
return ID;
172 for (
auto *
Block : successors())
173 ID =
Block->topologicalSort(Blocks, ID);
178 Blocks[BlockID] =
this;
195 if (!Visited)
return ID;
197 if (DominatorNode.Parent)
198 ID = DominatorNode.Parent->topologicalFinalSort(Blocks, ID);
199 for (
auto *Pred : Predecessors)
200 ID = Pred->topologicalFinalSort(Blocks, ID);
201 assert(static_cast<size_t>(ID) < Blocks.
size());
203 Blocks[BlockID] =
this;
210 void BasicBlock::computeDominator() {
213 for (
auto *Pred : Predecessors) {
215 if (Pred->BlockID >= BlockID)
continue;
217 if (Candidate ==
nullptr) {
222 auto *Alternate = Pred;
223 while (Alternate != Candidate) {
224 if (Candidate->BlockID > Alternate->BlockID)
225 Candidate = Candidate->DominatorNode.
Parent;
227 Alternate = Alternate->DominatorNode.
Parent;
230 DominatorNode.Parent = Candidate;
231 DominatorNode.SizeOfSubTree = 1;
237 void BasicBlock::computePostDominator() {
240 for (
auto *Succ : successors()) {
242 if (Succ->BlockID <= BlockID)
continue;
244 if (Candidate ==
nullptr) {
249 auto *Alternate = Succ;
250 while (Alternate != Candidate) {
251 if (Candidate->BlockID < Alternate->BlockID)
252 Candidate = Candidate->PostDominatorNode.
Parent;
254 Alternate = Alternate->PostDominatorNode.
Parent;
257 PostDominatorNode.Parent = Candidate;
258 PostDominatorNode.SizeOfSubTree = 1;
263 void SCFG::renumberInstrs() {
265 for (
auto *
Block : Blocks)
266 InstrID =
Block->renumberInstrs(InstrID);
297 int NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.
size());
298 if (NumUnreachableBlocks > 0) {
300 for (
size_t I = NumUnreachableBlocks, E = Blocks.
size(); I < E; ++I) {
301 size_t NI = I - NumUnreachableBlocks;
302 Blocks[NI] = Blocks[I];
303 Blocks[NI]->BlockID = NI;
306 Blocks.
drop(NumUnreachableBlocks);
310 for (
auto *
Block : Blocks)
311 Block->computeDominator();
314 int NumBlocks = Exit->topologicalFinalSort(Blocks, 0);
315 assert(static_cast<size_t>(NumBlocks) == Blocks.size());
323 for (
auto *
Block : Blocks.reverse()) {
324 Block->computePostDominator();
329 for (
auto *
Block : Blocks) {
334 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)
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.