//===-- ARMBlockPlacement.cpp - ARM block placement pass ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This pass re-arranges machine basic blocks to suit target requirements. // Currently it only moves blocks to fix backwards WLS branches. // //===----------------------------------------------------------------------===// #include "ARM.h" #include "ARMBaseInstrInfo.h" #include "ARMBasicBlockInfo.h" #include "ARMSubtarget.h" #include "MVETailPredUtils.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" usingnamespacellvm; #define DEBUG_TYPE … #define DEBUG_PREFIX … namespace llvm { class ARMBlockPlacement : public MachineFunctionPass { … }; } // namespace llvm FunctionPass *llvm::createARMBlockPlacementPass() { … } char ARMBlockPlacement::ID = …; INITIALIZE_PASS(…) static MachineInstr *findWLSInBlock(MachineBasicBlock *MBB) { … } /// Find WhileLoopStart in the loop predecessor BB or otherwise in its only /// predecessor. If found, returns (BB, WLS Instr) pair, otherwise a null pair. static MachineInstr *findWLS(MachineLoop *ML) { … } // Revert a WhileLoopStart to an equivalent DoLoopStart and branch. Note that // because of the branches this requires an extra block to be created. bool ARMBlockPlacement::revertWhileToDoLoop(MachineInstr *WLS) { … } /// Checks if loop has a backwards branching WLS, and if possible, fixes it. /// This requires checking the predecessor (ie. preheader or it's predecessor) /// for a WLS and if its loopExit/target is before it. /// If moving the predecessor won't convert a WLS (to the predecessor) from /// a forward to a backward branching WLS, then move the predecessor block /// to before the loopExit/target. bool ARMBlockPlacement::fixBackwardsWLS(MachineLoop *ML) { … } /// Updates ordering (of WLS BB and their loopExits) in inner loops first /// Returns true if any change was made in any of the loops bool ARMBlockPlacement::processPostOrderLoops(MachineLoop *ML) { … } bool ARMBlockPlacement::runOnMachineFunction(MachineFunction &MF) { … } bool ARMBlockPlacement::blockIsBefore(MachineBasicBlock *BB, MachineBasicBlock *Other) { … } // Moves a BasicBlock before another, without changing the control flow void ARMBlockPlacement::moveBasicBlock(MachineBasicBlock *BB, MachineBasicBlock *Before) { … }