12 using namespace clang;
13 using namespace threadSafety;
48 SExpr* Future::force() {
57 unsigned Idx = Predecessors.
size();
60 for (
SExpr *E : Args) {
61 if (
Phi* Ph = dyn_cast<Phi>(E)) {
62 Ph->values().reserveCheck(1, Arena);
63 Ph->values().push_back(
nullptr);
71 Predecessors.
reserve(NumPreds, Arena);
72 for (
SExpr *E : Args) {
73 if (
Phi* Ph = dyn_cast<Phi>(E)) {
74 Ph->values().reserve(NumPreds, Arena);
84 if (
auto *V = dyn_cast<Variable>(E)) {
90 if (
const Phi *Ph = dyn_cast<Phi>(E)) {
107 if (
auto *V = dyn_cast<Variable>(E)) {
118 if (
auto *Ph = dyn_cast<Phi>(E)) {
142 for (
unsigned i=1, n=Ph->
values().
size(); i<n; ++i) {
155 int BasicBlock::renumberInstrs(
int ID) {
156 for (
auto *Arg : Args)
157 Arg->setID(
this, ID++);
158 for (
auto *Instr : Instrs)
159 Instr->setID(
this, ID++);
160 TermInstr->
setID(
this, ID++);
169 if (Visited)
return ID;
172 ID =
Block->topologicalSort(Blocks, ID);
177 Blocks[BlockID] =
this;
194 if (!Visited)
return ID;
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;
236 void BasicBlock::computePostDominator() {
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;
262 void SCFG::renumberInstrs() {
264 for (
auto *
Block : Blocks)
265 InstrID =
Block->renumberInstrs(InstrID);
296 int NumUnreachableBlocks = Entry->topologicalSort(Blocks, Blocks.size());
297 if (NumUnreachableBlocks > 0) {
299 for (
size_t I = NumUnreachableBlocks, E = Blocks.size(); I < E; ++I) {
300 size_t NI = I - NumUnreachableBlocks;
301 Blocks[NI] = Blocks[I];
302 Blocks[NI]->BlockID = NI;
305 Blocks.drop(NumUnreachableBlocks);
309 for (
auto *
Block : Blocks)
310 Block->computeDominator();
313 int NumBlocks = Exit->topologicalFinalSort(Blocks, 0);
314 assert(static_cast<size_t>(NumBlocks) == Blocks.size());
322 for (
auto *
Block : Blocks.reverse()) {
323 Block->computePostDominator();
328 for (
auto *
Block : Blocks) {
333 for (
auto *
Block : Blocks.reverse()) {
ArrayRef< BasicBlock * > successors()
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op)
Return the name of a binary opcode.
void setID(BasicBlock *B, unsigned id)
Set the basic block and instruction ID for this expression.
const ValArray & values() const
SExpr * simplifyToCanonicalVal(SExpr *E)
unsigned addPredecessor(BasicBlock *Pred)
void push_back(const T &Elem)
virtual SExpr * compute()
static void computeNodeSize(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)
ID
Defines the set of possible language-specific address spaces.
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op)
Return the name of a unary opcode.
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void reservePredecessors(unsigned NumPreds)
TIL_UnaryOpcode
Opcode for unary arithmetic operations.
const SExpr * getCanonicalVal(const SExpr *E)
void reserveCheck(size_t N, MemRegionRef A)
static void computeNodeID(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN)
void reserve(size_t Ncp, MemRegionRef A)
bool isTrivial(const SExpr *E)
void simplifyIncompleteArg(til::Phi *Ph)
Base class for AST nodes in the typed intermediate language.