//===- ThreadSafetyTIL.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "clang/Analysis/Analyses/ThreadSafetyTIL.h" #include "clang/Basic/LLVM.h" #include "llvm/Support/Casting.h" #include <cassert> #include <cstddef> usingnamespaceclang; usingnamespacethreadSafety; usingnamespacetil; StringRef til::getUnaryOpcodeString(TIL_UnaryOpcode Op) { … } StringRef til::getBinaryOpcodeString(TIL_BinaryOpcode Op) { … } SExpr* Future::force() { … } unsigned BasicBlock::addPredecessor(BasicBlock *Pred) { … } void BasicBlock::reservePredecessors(unsigned NumPreds) { … } // If E is a variable, then trace back through any aliases or redundant // Phi nodes to find the canonical definition. const SExpr *til::getCanonicalVal(const SExpr *E) { … } // If E is a variable, then trace back through any aliases or redundant // Phi nodes to find the canonical definition. // The non-const version will simplify incomplete Phi nodes. SExpr *til::simplifyToCanonicalVal(SExpr *E) { … } // Trace the arguments of an incomplete Phi node to see if they have the same // canonical definition. If so, mark the Phi node as redundant. // getCanonicalVal() will recursively call simplifyIncompletePhi(). void til::simplifyIncompleteArg(til::Phi *Ph) { … } // Renumbers the arguments and instructions to have unique, sequential IDs. unsigned BasicBlock::renumberInstrs(unsigned ID) { … } // Sorts the CFGs blocks using a reverse post-order depth-first traversal. // Each block will be written into the Blocks array in order, and its BlockID // will be set to the index in the array. Sorting should start from the entry // block, and ID should be the total number of blocks. unsigned BasicBlock::topologicalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID) { … } // Performs a reverse topological traversal, starting from the exit block and // following back-edges. The dominator is serialized before any predecessors, // which guarantees that all blocks are serialized after their dominator and // before their post-dominator (because it's a reverse topological traversal). // ID should be initially set to 0. // // This sort assumes that (1) dominators have been computed, (2) there are no // critical edges, and (3) the entry block is reachable from the exit block // and no blocks are accessible via traversal of back-edges from the exit that // weren't accessible via forward edges from the entry. unsigned BasicBlock::topologicalFinalSort(SimpleArray<BasicBlock *> &Blocks, unsigned ID) { … } // Computes the immediate dominator of the current block. Assumes that all of // its predecessors have already computed their dominators. This is achieved // by visiting the nodes in topological order. void BasicBlock::computeDominator() { … } // Computes the immediate post-dominator of the current block. Assumes that all // of its successors have already computed their post-dominators. This is // achieved visiting the nodes in reverse topological order. void BasicBlock::computePostDominator() { … } // Renumber instructions in all blocks void SCFG::renumberInstrs() { … } static inline void computeNodeSize(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN) { … } static inline void computeNodeID(BasicBlock *B, BasicBlock::TopologyNode BasicBlock::*TN) { … } // Normalizes a CFG. Normalization has a few major components: // 1) Removing unreachable blocks. // 2) Computing dominators and post-dominators // 3) Topologically sorting the blocks into the "Blocks" array. void SCFG::computeNormalForm() { … }