37#define DEBUG_TYPE "wasm-cfg-sort" 
   44        "WebAssembly: Disable EH pad-first sort order. Testing purpose only."),
 
   50  StringRef getPassName()
 const override { 
return "WebAssembly CFG Sort"; }
 
   52  void getAnalysisUsage(AnalysisUsage &AU)
 const override {
 
   63  bool runOnMachineFunction(MachineFunction &MF) 
override;
 
   67  WebAssemblyCFGSort() : MachineFunctionPass(ID) {}
 
   71char WebAssemblyCFGSort::ID = 0;
 
   73                "Reorders blocks in topological order", 
false, 
false)
 
   76  return new WebAssemblyCFGSort();
 
 
   81  bool AnyBarrier = 
false;
 
   83  bool AllAnalyzable = 
true;
 
   86    AnyBarrier |= Term.isBarrier();
 
   88    AllAnalyzable &= Term.isBranch() && !Term.isIndirectBranch();
 
   90  assert((AnyBarrier || AllAnalyzable) &&
 
   91         "analyzeBranch needs to analyze any block with a fallthrough");
 
  101    MBB->updateTerminator(OriginalSuccessor);
 
 
  139struct CompareBlockNumbers {
 
  140  bool operator()(
const MachineBasicBlock *
A,
 
  141                  const MachineBasicBlock *
B)
 const {
 
  143      if (
A->isEHPad() && !
B->isEHPad())
 
  145      if (!
A->isEHPad() && 
B->isEHPad())
 
  149    return A->getNumber() > 
B->getNumber();
 
  153struct CompareBlockNumbersBackwards {
 
  154  bool operator()(
const MachineBasicBlock *
A,
 
  155                  const MachineBasicBlock *
B)
 const {
 
  157      if (
A->isEHPad() && !
B->isEHPad())
 
  159      if (!
A->isEHPad() && 
B->isEHPad())
 
  163    return A->getNumber() < 
B->getNumber();
 
  169  const SortRegion *TheRegion;
 
  170  unsigned NumBlocksLeft;
 
  174  std::vector<MachineBasicBlock *> Deferred;
 
  176  explicit Entry(
const SortRegion *R)
 
  177      : TheRegion(
R), NumBlocksLeft(
R->getNumBlocks()) {}
 
  197    unsigned N = 
MBB.pred_size();
 
  199      if (L->getHeader() == &
MBB)
 
  201          if (L->contains(Pred))
 
  203    NumPredsLeft[
MBB.getNumber()] = 
N;
 
  218                CompareBlockNumbersBackwards>
 
  222  SortRegionInfo SRI(MLI, WEI);
 
  225    const SortRegion *R = SRI.getRegionFor(
MBB);
 
  230      if (R->getHeader() == 
MBB)
 
  235      for (Entry &
E : Entries)
 
  236        if (
E.TheRegion->contains(
MBB) && --
E.NumBlocksLeft == 0)
 
  237          for (
auto *DeferredBlock : 
E.Deferred)
 
  238            Ready.push(DeferredBlock);
 
  239      while (!Entries.empty() && Entries.back().NumBlocksLeft == 0)
 
  246        if (SuccL->getHeader() == Succ && SuccL->contains(
MBB))
 
  249      if (--NumPredsLeft[Succ->getNumber()] == 0) {
 
  261        if (EHInfo && EHInfo->hasUnwindSrcs(Succ)) {
 
  263              EHInfo->getUnwindSrcs(Succ);
 
  264          bool IsDeferred = 
false;
 
  265          for (Entry &
E : Entries) {
 
  266            if (UnwindSrcs.
count(
E.TheRegion->getHeader())) {
 
  267              E.Deferred.push_back(Succ);
 
  275        Preferred.push(Succ);
 
  281    while (!Preferred.empty()) {
 
  282      Next = Preferred.top();
 
  286      if (!Entries.
empty() &&
 
  288        Entries.
back().Deferred.push_back(
Next);
 
  294      if (
Next->getNumber() < 
MBB->getNumber() &&
 
  296          (!R || !R->contains(
Next) ||
 
  297           R->getHeader()->getNumber() < 
Next->getNumber())) {
 
  317        if (!Entries.
empty() &&
 
  319          Entries.
back().Deferred.push_back(
Next);
 
  330  assert(Entries.
empty() && 
"Active sort region list not finished");
 
  342  for (
auto &
MBB : MF) {
 
  343    assert(
MBB.getNumber() >= 0 && 
"Renumbered blocks should be non-negative.");
 
  344    const SortRegion *
Region = SRI.getRegionFor(&
MBB);
 
  351        for (
auto *Pred : 
MBB.predecessors())
 
  354              "Loop header predecessors must be loop predecessors or " 
  358        for (
auto *Pred : 
MBB.predecessors())
 
  359          assert(Pred->getNumber() < 
MBB.getNumber() &&
 
  360                 "Non-loop-header predecessors should be topologically sorted");
 
  363             "Regions should be declared at most once.");
 
  367      for (
auto *Pred : 
MBB.predecessors())
 
  368        assert(Pred->getNumber() < 
MBB.getNumber() &&
 
  369               "Non-loop-header predecessors should be topologically sorted");
 
  371             "Blocks must be nested in their regions");
 
  373    while (OnStack.
size() > 1 && &
MBB == SRI.getBottom(OnStack.
back()))
 
  377         "The function entry block shouldn't actually be a region header");
 
  379         "Control flow stack pushes and pops should be balanced.");
 
 
  385                       "********** Function: " 
  388  const auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
 
  389  const auto &WEI = getAnalysis<WebAssemblyExceptionInfo>();
 
  390  auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the PriorityQueue class.
This file implements a set that has insertion order iteration characteristics.
static void maybeUpdateTerminator(MachineBasicBlock *MBB)
static cl::opt< bool > WasmDisableEHPadSort("wasm-disable-ehpad-sort", cl::ReallyHidden, cl::desc("WebAssembly: Disable EH pad-first sort order. Testing purpose only."), cl::init(false))
This file implements WebAssemblyException information analysis.
This file implements regions used in CFGSort and CFGStackify.
This file contains the declaration of the WebAssembly-specific utility functions.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
std::enable_if_t< GraphHasNodeNumbers< T * >, void > updateBlockNumbers()
Update dominator tree after renumbering blocks.
FunctionPass class - This class is used to implement most global optimizations.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const WasmEHFuncInfo * getWasmEHFuncInfo() const
getWasmEHFuncInfo - Return information about how the current function uses Wasm exception handling.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
const MachineBasicBlock & front() const
Representation of each machine instruction.
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
PriorityQueue - This class behaves like std::priority_queue and provides a few additional convenience...
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
size_type size() const
Determine the number of elements in the SetVector.
const value_type & back() const
Return the last element of the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void pop_back()
Remove the last element of the SetVector.
value_type pop_back_val()
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool sortBlocks(Function &F)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Next
FunctionPass * createWebAssemblyCFGSort()