31#define DEBUG_TYPE "msp430-branch-select"
35 cl::desc(
"Expand out of range branches"));
37STATISTIC(NumSplit,
"Number of machine basic blocks split");
38STATISTIC(NumExpanded,
"Number of branches expanded to long format");
48 unsigned measureFunction(OffsetVector &BlockOffsets,
50 bool expandBranches(OffsetVector &BlockOffsets);
59 MSP430BranchSelectLegacyPass() : MachineFunctionPass(ID) {}
61 bool runOnMachineFunction(MachineFunction &MF)
override;
63 MachineFunctionProperties getRequiredProperties()
const override {
64 return MachineFunctionProperties().setNoVRegs();
67 StringRef getPassName()
const override {
return "MSP430 Branch Selector"; }
70char MSP430BranchSelectLegacyPass::ID = 0;
78 const int WordSize = 2;
80 assert((DistanceInBytes % WordSize == 0) &&
81 "Branch offset should be word aligned!");
83 int Words = DistanceInBytes / WordSize;
89unsigned MSP430BSelImpl::measureFunction(OffsetVector &BlockOffsets,
95 if (FromBB ==
nullptr) {
103 unsigned TotalSize = BlockOffsets[Begin->getNumber()];
106 for (MachineInstr &
MI :
MBB) {
107 TotalSize +=
TII->getInstSizeInBytes(
MI);
115bool MSP430BSelImpl::expandBranches(OffsetVector &BlockOffsets) {
125 bool MadeChange =
false;
127 unsigned MBBStartOffset = 0;
129 MBBStartOffset +=
TII->getInstSizeInBytes(*
MI);
132 if (
MI->getOpcode() != MSP430::JCC &&
MI->getOpcode() != MSP430::JMP) {
136 MachineBasicBlock *DestBB =
MI->getOperand(0).getMBB();
142 int BranchDistance = BlockDistance - MBBStartOffset;
151 << BranchDistance <<
"\n");
154 if (
MI->getOpcode() == MSP430::JCC && std::next(
MI) != EE) {
156 LLVM_DEBUG(
dbgs() <<
" Found a basic block that needs to be split, "
160 MachineBasicBlock *NewBB =
169 if (Succ == DestBB) {
178 measureFunction(BlockOffsets, &*
MBB);
187 MachineInstr &OldBranch = *
MI;
189 int InstrSizeDiff = -
TII->getInstSizeInBytes(OldBranch);
191 if (
MI->getOpcode() == MSP430::JCC) {
192 MachineBasicBlock *NextMBB = &*std::next(
MBB);
194 "This block must have a layout successor!");
200 Cond.push_back(
MI->getOperand(1));
207 InstrSizeDiff +=
TII->getInstSizeInBytes(*
MI);
213 InstrSizeDiff +=
TII->getInstSizeInBytes(*
MI);
220 for (
int i =
MBB->
getNumber() + 1, e = BlockOffsets.size(); i < e; ++i) {
221 BlockOffsets[i] += InstrSizeDiff;
223 MBBStartOffset += InstrSizeDiff;
232bool MSP430BSelImpl::runOnMachineFunction(MachineFunction &mf) {
234 TII =
static_cast<const MSP430InstrInfo *
>(MF->
getSubtarget().getInstrInfo());
244 OffsetVector BlockOffsets;
246 unsigned FunctionSize = measureFunction(BlockOffsets);
255 bool MadeChange =
false;
256 while (expandBranches(BlockOffsets))
262bool MSP430BranchSelectLegacyPass::runOnMachineFunction(MachineFunction &MF) {
263 return MSP430BSelImpl().runOnMachineFunction(MF);
269 return MSP430BSelImpl().runOnMachineFunction(MF)
276 return new MSP430BranchSelectLegacyPass();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
static bool isInRage(int DistanceInBytes)
static cl::opt< bool > BranchSelectEnabled("msp430-branch-select", cl::Hidden, cl::init(true), cl::desc("Expand out of range branches"))
const SmallVectorImpl< MachineOperand > & Cond
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
FunctionPass class - This class is used to implement most global optimizations.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
iterator_range< succ_iterator > successors()
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
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.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
self_iterator getIterator()
Pass manager infrastructure for declaring and invalidating analyses.
initializer< Ty > init(const Ty &Val)
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.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionPass * createMSP430BranchSelectLegacyPass()
Returns an instance of the Branch Selection Pass.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.