25#define DEBUG_TYPE "arc-branch-finalize"
46 StringRef getPassName()
const override {
47 return "ARC Branch Finalization Pass";
50 bool runOnMachineFunction(MachineFunction &MF)
override;
51 void replaceWithBRcc(MachineInstr *
MI)
const;
52 void replaceWithCmpBcc(MachineInstr *
MI)
const;
55 const ARCInstrInfo *TII{
nullptr};
58char ARCBranchFinalize::ID = 0;
63 "ARC finalize branches",
false,
false)
96 return !(
MI->getOpcode() != ARC::BRcc_rr_p &&
97 MI->getOpcode() != ARC::BRcc_ru6_p);
102 if (
MI->getOpcode() == ARC::BRcc_rr_p)
104 return ARC::BRcc_ru6;
109 if (
MI->getOpcode() == ARC::BRcc_rr_p)
122 .
add(
MI->getOperand(2))
124 MI->eraseFromParent();
126 replaceWithCmpBcc(
MI);
130void ARCBranchFinalize::replaceWithCmpBcc(MachineInstr *
MI)
const {
136 .
add(
MI->getOperand(2));
139 .
addImm(
MI->getOperand(3).getImm());
140 MI->eraseFromParent();
143bool ARCBranchFinalize::runOnMachineFunction(MachineFunction &MF) {
146 std::vector<MachineInstr *> Branches;
148 unsigned MaxSize = 0;
150 std::map<MachineBasicBlock *, unsigned> BlockToPCMap;
151 std::vector<std::pair<MachineInstr *, unsigned>> BranchToPCList;
154 for (
auto &
MBB : MF) {
155 BlockToPCMap.insert(std::make_pair(&
MBB, PC));
156 for (
auto &
MI :
MBB) {
157 unsigned Size =
TII->getInstSizeInBytes(
MI);
164 Branches.push_back(&
MI);
165 BranchToPCList.emplace_back(&
MI, PC);
170 for (
auto P : BranchToPCList) {
172 isInt<9>(MaxSize) ? replaceWithBRcc(
P.first) : replaceWithCmpBcc(
P.first);
175 LLVM_DEBUG(
dbgs() <<
"Estimated function size for " << MF.getName() <<
": "
182 return new ARCBranchFinalize();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static unsigned getCmpForPseudo(MachineInstr *MI)
static unsigned getBRccForPseudo(MachineInstr *MI)
static bool isBRccPseudo(MachineInstr *MI)
arc branch ARC finalize static false unsigned getCCForBRcc(unsigned CC)
const HexagonInstrInfo * TII
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
FunctionPass class - This class is used to implement most global optimizations.
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
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
Representation of each machine instruction.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A global registry used in conjunction with static constructors to make pluggable components (like tar...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void initializeARCBranchFinalizePass(PassRegistry &Registry)
FunctionPass * createARCBranchFinalizePass()