37#define DEBUG_TYPE "wasm-cfg-sort"
44 "WebAssembly: Disable EH pad-first sort order. Testing purpose only."),
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");
139struct CompareBlockNumbers {
143 if (
A->isEHPad() && !
B->isEHPad())
145 if (!
A->isEHPad() &&
B->isEHPad())
149 return A->getNumber() >
B->getNumber();
153struct CompareBlockNumbersBackwards {
157 if (
A->isEHPad() && !
B->isEHPad())
159 if (!
A->isEHPad() &&
B->isEHPad())
163 return A->getNumber() <
B->getNumber();
170 unsigned NumBlocksLeft;
174 std::vector<MachineBasicBlock *> Deferred;
177 : TheRegion(
R), NumBlocksLeft(
R->getNumBlocks()) {}
199 if (L->getHeader() == &
MBB)
201 if (L->contains(Pred))
218 CompareBlockNumbersBackwards>
230 if (R->getHeader() ==
MBB)
231 Entries.push_back(Entry(R));
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() &&
287 !MDT.
dominates(Entries.back().TheRegion->getHeader(), Next)) {
288 Entries.back().Deferred.push_back(Next);
296 (!R || !R->contains(Next) ||
297 R->getHeader()->getNumber() < Next->
getNumber())) {
317 if (!Entries.empty() &&
318 !MDT.
dominates(Entries.back().TheRegion->getHeader(), Next)) {
319 Entries.back().Deferred.push_back(Next);
330 assert(Entries.empty() &&
"Active sort region list not finished");
342 for (
auto &
MBB : MF) {
354 "Loop header predecessors must be loop predecessors or "
360 "Non-loop-header predecessors should be topologically sorted");
363 "Regions should be declared at most once.");
369 "Non-loop-header predecessors should be topologically sorted");
371 "Blocks must be nested in their regions");
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();
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file defines the PriorityQueue class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
static void sortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI, const WebAssemblyExceptionInfo &WEI, MachineDominatorTree &MDT)
Sort the blocks, taking special care to make sure that regions are not interrupted by blocks not domi...
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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.
unsigned pred_size() const
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor)
Update the terminator instructions in block to account for changes to block layout which may have bee...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
void moveAfter(MachineBasicBlock *NewBefore)
Analysis pass which computes a MachineDominatorTree.
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
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.
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.
const SortRegion * getRegionFor(const MachineBasicBlock *MBB)
MachineBasicBlock * getBottom(const SortRegion *R)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createWebAssemblyCFGSort()