summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp91
1 files changed, 11 insertions, 80 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
index 8442b49e25f4..eb3e9b91d40d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
@@ -19,6 +19,7 @@
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyExceptionInfo.h"
+#include "WebAssemblySortRegion.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
#include "llvm/ADT/PriorityQueue.h"
@@ -31,6 +32,8 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
+using WebAssembly::SortRegion;
+using WebAssembly::SortRegionInfo;
#define DEBUG_TYPE "wasm-cfg-sort"
@@ -44,78 +47,6 @@ static cl::opt<bool> WasmDisableEHPadSort(
namespace {
-// Wrapper for loops and exceptions
-class Region {
-public:
- virtual ~Region() = default;
- virtual MachineBasicBlock *getHeader() const = 0;
- virtual bool contains(const MachineBasicBlock *MBB) const = 0;
- virtual unsigned getNumBlocks() const = 0;
- using block_iterator = typename ArrayRef<MachineBasicBlock *>::const_iterator;
- virtual iterator_range<block_iterator> blocks() const = 0;
- virtual bool isLoop() const = 0;
-};
-
-template <typename T> class ConcreteRegion : public Region {
- const T *Region;
-
-public:
- ConcreteRegion(const T *Region) : Region(Region) {}
- MachineBasicBlock *getHeader() const override { return Region->getHeader(); }
- bool contains(const MachineBasicBlock *MBB) const override {
- return Region->contains(MBB);
- }
- unsigned getNumBlocks() const override { return Region->getNumBlocks(); }
- iterator_range<block_iterator> blocks() const override {
- return Region->blocks();
- }
- bool isLoop() const override { return false; }
-};
-
-template <> bool ConcreteRegion<MachineLoop>::isLoop() const { return true; }
-
-// This class has information of nested Regions; this is analogous to what
-// LoopInfo is for loops.
-class RegionInfo {
- const MachineLoopInfo &MLI;
- const WebAssemblyExceptionInfo &WEI;
- DenseMap<const MachineLoop *, std::unique_ptr<Region>> LoopMap;
- DenseMap<const WebAssemblyException *, std::unique_ptr<Region>> ExceptionMap;
-
-public:
- RegionInfo(const MachineLoopInfo &MLI, const WebAssemblyExceptionInfo &WEI)
- : MLI(MLI), WEI(WEI) {}
-
- // Returns a smallest loop or exception that contains MBB
- const Region *getRegionFor(const MachineBasicBlock *MBB) {
- const auto *ML = MLI.getLoopFor(MBB);
- const auto *WE = WEI.getExceptionFor(MBB);
- if (!ML && !WE)
- return nullptr;
- // We determine subregion relationship by domination of their headers, i.e.,
- // if region A's header dominates region B's header, B is a subregion of A.
- // WebAssemblyException contains BBs in all its subregions (loops or
- // exceptions), but MachineLoop may not, because MachineLoop does not contain
- // BBs that don't have a path to its header even if they are dominated by
- // its header. So here we should use WE->contains(ML->getHeader()), but not
- // ML->contains(WE->getHeader()).
- if ((ML && !WE) || (ML && WE && WE->contains(ML->getHeader()))) {
- // If the smallest region containing MBB is a loop
- if (LoopMap.count(ML))
- return LoopMap[ML].get();
- LoopMap[ML] = std::make_unique<ConcreteRegion<MachineLoop>>(ML);
- return LoopMap[ML].get();
- } else {
- // If the smallest region containing MBB is an exception
- if (ExceptionMap.count(WE))
- return ExceptionMap[WE].get();
- ExceptionMap[WE] =
- std::make_unique<ConcreteRegion<WebAssemblyException>>(WE);
- return ExceptionMap[WE].get();
- }
- }
-};
-
class WebAssemblyCFGSort final : public MachineFunctionPass {
StringRef getPassName() const override { return "WebAssembly CFG Sort"; }
@@ -236,14 +167,14 @@ struct CompareBlockNumbersBackwards {
/// Bookkeeping for a region to help ensure that we don't mix blocks not
/// dominated by the its header among its blocks.
struct Entry {
- const Region *TheRegion;
+ const SortRegion *TheRegion;
unsigned NumBlocksLeft;
/// List of blocks not dominated by Loop's header that are deferred until
/// after all of Loop's blocks have been seen.
std::vector<MachineBasicBlock *> Deferred;
- explicit Entry(const class Region *R)
+ explicit Entry(const SortRegion *R)
: TheRegion(R), NumBlocksLeft(R->getNumBlocks()) {}
};
} // end anonymous namespace
@@ -287,10 +218,10 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
CompareBlockNumbersBackwards>
Ready;
- RegionInfo RI(MLI, WEI);
+ SortRegionInfo SRI(MLI, WEI);
SmallVector<Entry, 4> Entries;
for (MachineBasicBlock *MBB = &MF.front();;) {
- const Region *R = RI.getRegionFor(MBB);
+ const SortRegion *R = SRI.getRegionFor(MBB);
if (R) {
// If MBB is a region header, add it to the active region list. We can't
// put any blocks that it doesn't dominate until we see the end of the
@@ -373,7 +304,7 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
MF.RenumberBlocks();
#ifndef NDEBUG
- SmallSetVector<const Region *, 8> OnStack;
+ SmallSetVector<const SortRegion *, 8> OnStack;
// Insert a sentinel representing the degenerate loop that starts at the
// function entry block and includes the entire function as a "loop" that
@@ -382,7 +313,7 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
for (auto &MBB : MF) {
assert(MBB.getNumber() >= 0 && "Renumbered blocks should be non-negative.");
- const Region *Region = RI.getRegionFor(&MBB);
+ const SortRegion *Region = SRI.getRegionFor(&MBB);
if (Region && &MBB == Region->getHeader()) {
// Region header.
@@ -408,10 +339,10 @@ static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI,
for (auto Pred : MBB.predecessors())
assert(Pred->getNumber() < MBB.getNumber() &&
"Non-loop-header predecessors should be topologically sorted");
- assert(OnStack.count(RI.getRegionFor(&MBB)) &&
+ assert(OnStack.count(SRI.getRegionFor(&MBB)) &&
"Blocks must be nested in their regions");
}
- while (OnStack.size() > 1 && &MBB == WebAssembly::getBottom(OnStack.back()))
+ while (OnStack.size() > 1 && &MBB == SRI.getBottom(OnStack.back()))
OnStack.pop_back();
}
assert(OnStack.pop_back_val() == nullptr &&