46 #define DEBUG_TYPE "wasm-fix-irreducible-control-flow"
51 return "WebAssembly Fix Irreducible Control Flow";
75 return new WebAssemblyFixIrreducibleControlFlow();
96 Preds.push_back(Pred);
112 class SuccessorList final :
public MetaBlock {
118 : MetaBlock(MBB), Index(0), Num(
successors().size()) {}
121 : MetaBlock(Loop), Index(0), Num(
successors().size()) {}
123 bool HasNext()
const {
return Index != Num; }
133 bool WebAssemblyFixIrreducibleControlFlow::VisitLoop(
MachineFunction &MF,
145 LoopWorklist.
push_back(SuccessorList(Header));
148 while (!LoopWorklist.
empty()) {
149 SuccessorList &Top = LoopWorklist.
back();
152 if (Next == Header || (Loop && !Loop->
contains(Next)))
155 if (!Visited.
insert(Next).second) {
160 if (InnerLoop != Loop)
161 LoopWorklist.
push_back(SuccessorList(InnerLoop));
163 LoopWorklist.
push_back(SuccessorList(Next));
165 RewriteSuccs.
insert(Top.getBlock());
169 OnStack.
erase(Top.getBlock());
177 DEBUG(
dbgs() <<
"Irreducible control flow detected!\n");
188 TII.get(WebAssembly::BR_TABLE_I32));
193 unsigned Reg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
201 while (!SuccWorklist.empty()) {
203 auto Pair = Indices.
insert(std::make_pair(MBB, 0));
211 Pair.first->second = Index;
213 RewriteSuccs.
insert(Pred);
219 for (
auto *Succ :
Meta.successors())
220 if (Succ != Header && (!Loop || Loop->
contains(Succ)))
221 SuccWorklist.push_back(Succ);
230 if (!Indices.
count(Succ))
243 .addImm(Indices[Succ]);
251 for (
auto &
Op : Term.explicit_uses())
252 if (
Op.isMBB() && Indices.
count(
Op.getMBB()))
253 Op.setMBB(Map[
Op.getMBB()]);
254 for (
auto Rewrite : Map)
266 bool WebAssemblyFixIrreducibleControlFlow::runOnMachineFunction(
268 DEBUG(
dbgs() <<
"********** Fixing Irreducible Control Flow **********\n"
269 "********** Function: "
272 bool Changed =
false;
273 auto &MLI = getAnalysis<MachineLoopInfo>();
276 Changed |= VisitLoop(MF, MLI,
nullptr);
280 while (!Worklist.empty()) {
282 Worklist.append(CurLoop->
begin(), CurLoop->
end());
283 Changed |= VisitLoop(MF, MLI, CurLoop);
288 DEBUG(
dbgs() <<
"Recomputing dominators and loops.\n");
291 getAnalysis<MachineDominatorTree>().runOnMachineFunction(MF);
void push_back(const T &Elt)
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
const_iterator end(StringRef path)
Get end iterator over path.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
#define LLVM_UNLIKELY(EXPR)
#define LLVM_LIKELY(EXPR)
iterator end()
Get an iterator to the end of the SetVector.
This file contains the entry points for global functions defined in the LLVM WebAssembly back-end...
BlockT * getHeader() const
iterator_range< succ_iterator > successors()
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Reg
All possible values of the reg field in the ModR/M byte.
iterator_range< iterator > terminators()
LLVM_NODISCARD bool empty() const
void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const
Return all of the successor blocks of this loop.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool insert(const value_type &X)
Insert a new element into the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Interval::succ_iterator succ_end(Interval *I)
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Control flow instructions. These all have token chains.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineOperand & getOperand(unsigned i) const
This file provides WebAssembly-specific target descriptions.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
Represent the analysis usage information of a pass.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
FunctionPass class - This class is used to implement most global optimizations.
Interval::pred_iterator pred_end(Interval *I)
iterator_range< pred_iterator > predecessors()
This file declares the WebAssembly-specific subclass of TargetSubtarget.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
FunctionPass * createWebAssemblyFixIrreducibleControlFlow()
pred_range predecessors(BasicBlock *BB)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
void invalidateLiveness()
invalidateLiveness - Indicates that register liveness is no longer being tracked accurately.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
bool operator!=(uint64_t V1, const APInt &V2)
Representation of each machine instruction.
bool runOnMachineFunction(MachineFunction &F) override
Calculate the natural loop information.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Represents a single loop in the control flow graph.
This file declares WebAssembly-specific per-machine-function information.
void changeLoopFor(MachineBasicBlock *BB, MachineLoop *L)
Change the top-level loop that contains BB to the specified loop.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
succ_range successors(BasicBlock *BB)
A vector that has set insertion semantics.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
BasicBlockListType::iterator iterator
StringRef - Represent a constant reference to a string, i.e.
bool operator==(uint64_t V1, const APInt &V2)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
static void Split(std::vector< std::string > &V, StringRef S)
Split - Splits a string of comma separated items in to a vector of strings.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...