26#define DEBUG_TYPE "arm-block-placement"
27#define DEBUG_PREFIX "ARM Block Placement: "
33 std::unique_ptr<ARMBasicBlockUtils> BBUtils =
nullptr;
84 return findWLSInBlock(*Predecessor->
pred_begin());
101 assert(WLS->getNextNode() == &Preheader->
back());
107 WLS->getOperand(1).setIsKill(
false);
108 if (WLS->getOpcode() == ARM::t2WhileLoopStartTP)
109 WLS->getOperand(2).setIsKill(
false);
124 BuildMI(*NewBlock, Br, WLS->getDebugLoc(),
125 TII->get(WLS->getOpcode() == ARM::t2WhileLoopStartTP
126 ? ARM::t2DoLoopStartTP
127 : ARM::t2DoLoopStart));
128 MIB.
add(WLS->getOperand(0));
129 MIB.
add(WLS->getOperand(1));
130 if (WLS->getOpcode() == ARM::t2WhileLoopStartTP)
131 MIB.
add(WLS->getOperand(2));
134 <<
"Reverting While Loop to Do Loop: " << *WLS <<
"\n");
142 BBUtils->computeAllBlockSizes();
143 BBUtils->adjustBBOffsetsAfter(Preheader);
190 if (WLSTarget == Predecessor) {
192 <<
"it would convert a WLS from forward to a "
193 <<
"backwards branching WLS\n");
207 bool Changed =
false;
208 for (
auto *InnerML : *
ML)
220 MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
222 BBUtils = std::make_unique<ARMBasicBlockUtils>(MF);
224 BBUtils->computeAllBlockSizes();
225 BBUtils->adjustBBOffsetsAfter(&MF.
front());
226 bool Changed =
false;
227 RevertedWhileLoops.
clear();
230 for (
auto *
ML : *MLI)
234 for (
auto *WlsInstr : RevertedWhileLoops)
242 return BBUtils->getOffsetOf(
Other) > BBUtils->getOffsetOf(BB);
249 <<
Before->getName() <<
"\n");
251 assert(BBPrevious &&
"Cannot move the function entry basic block");
256 "Cannot move the given block to before the function entry block");
265 <<
From->getName() <<
" to " << To->getName() <<
"\n");
267 "'To' is expected to be a successor of 'From'");
273 Terminator.isReturn()))
278 BuildMI(
From, Terminator.getDebugLoc(), TII->get(ARM::t2B));
281 MIB.
addReg(ARM::NoRegister);
283 <<
From->getName() <<
" to " << To->getName() <<
": "
289 FixFallthrough(BBPrevious, BB);
292 FixFallthrough(BeforePrev,
Before);
295 FixFallthrough(BB, BBNext);
298 BBUtils->computeAllBlockSizes();
299 BBUtils->adjustBBOffsetsAfter(BB);
static MachineInstr * findWLS(MachineLoop *ML)
Find WhileLoopStart in the loop predecessor BB or otherwise in its only predecessor.
BlockVerifier::State From
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isPredicated(const MachineInstr &MI) const override
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool revertWhileToDoLoop(MachineInstr *WLS)
void moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *Before)
bool fixBackwardsWLS(MachineLoop *ML)
Checks if loop has a backwards branching WLS, and if possible, fixes it.
bool blockIsBefore(MachineBasicBlock *BB, MachineBasicBlock *Other)
bool processPostOrderLoops(MachineLoop *ML)
Updates ordering (of WLS BB and their loopExits) in inner loops first Returns true if any change was ...
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
unsigned pred_size() const
void moveBefore(MachineBasicBlock *NewAfter)
Move 'this' block before or after the specified block.
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
pred_iterator pred_begin()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
std::string getFullName() const
Return a formatted string to identify this block and its parent function.
iterator_range< iterator > terminators()
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
const MachineBasicBlock & front() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
MachineBasicBlock * getMBB() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isIndirectBranchOpcode(int Opc)
static bool isJumpTableBranchOpcode(int Opc)
FunctionPass * createARMBlockPlacementPass()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)
static bool isUncondBranchOpcode(int Opc)
MachineBasicBlock * getWhileLoopStartTargetBB(const MachineInstr &MI)
static bool isWhileLoopStart(const MachineInstr &MI)
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().