28 #define DEBUG_TYPE "msp430-branch-select" 32 cl::desc(
"Expand out of range branches"));
34 STATISTIC(NumSplit,
"Number of machine basic blocks split");
35 STATISTIC(NumExpanded,
"Number of branches expanded to long format");
45 unsigned measureFunction(OffsetVector &BlockOffsets,
47 bool expandBranches(OffsetVector &BlockOffsets);
60 StringRef getPassName()
const override {
return "MSP430 Branch Selector"; }
70 const int WordSize = 2;
72 assert((DistanceInBytes % WordSize == 0) &&
73 "Branch offset should be word aligned!");
75 int Words = DistanceInBytes / WordSize;
76 return isInt<10>(Words);
81 unsigned MSP430BSel::measureFunction(OffsetVector &BlockOffsets,
84 MF->RenumberBlocks(FromBB);
87 if (FromBB ==
nullptr) {
93 BlockOffsets.resize(MF->getNumBlockIDs());
95 unsigned TotalSize = BlockOffsets[Begin->getNumber()];
96 for (
auto &MBB :
make_range(Begin, MF->end())) {
97 BlockOffsets[MBB.getNumber()] = TotalSize;
99 TotalSize +=
TII->getInstSizeInBytes(
MI);
107 bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) {
117 bool MadeChange =
false;
118 for (
auto MBB = MF->begin(),
E = MF->end(); MBB !=
E; ++MBB) {
119 unsigned MBBStartOffset = 0;
120 for (
auto MI = MBB->begin(), EE = MBB->end();
MI != EE; ++
MI) {
121 MBBStartOffset +=
TII->getInstSizeInBytes(*
MI);
124 if (
MI->getOpcode() != MSP430::JCC &&
MI->getOpcode() != MSP430::JMP) {
133 BlockOffsets[DestBB->
getNumber()] - BlockOffsets[MBB->getNumber()];
134 int BranchDistance = BlockDistance - MBBStartOffset;
143 << BranchDistance <<
"\n");
146 if (
MI->getOpcode() == MSP430::JCC && std::next(
MI) != EE) {
148 LLVM_DEBUG(
dbgs() <<
" Found a basic block that needs to be split, " 153 MF->CreateMachineBasicBlock(MBB->getBasicBlock());
154 MF->
insert(std::next(MBB), NewBB);
157 NewBB->
splice(NewBB->
end(), &*MBB, std::next(
MI), MBB->end());
161 if (Succ == DestBB) {
164 MBB->replaceSuccessor(Succ, NewBB);
170 measureFunction(BlockOffsets, &*MBB);
181 int InstrSizeDiff = -
TII->getInstSizeInBytes(OldBranch);
183 if (
MI->getOpcode() == MSP430::JCC) {
185 assert(MBB->isSuccessor(NextMBB) &&
186 "This block must have a layout successor!");
199 InstrSizeDiff +=
TII->getInstSizeInBytes(*
MI);
205 InstrSizeDiff +=
TII->getInstSizeInBytes(*
MI);
212 for (
int i = MBB->getNumber() + 1, e = BlockOffsets.size(); i < e; ++i) {
213 BlockOffsets[i] += InstrSizeDiff;
215 MBBStartOffset += InstrSizeDiff;
232 LLVM_DEBUG(
dbgs() <<
"\n********** " << getPassName() <<
" **********\n");
236 OffsetVector BlockOffsets;
238 unsigned FunctionSize = measureFunction(BlockOffsets);
247 bool MadeChange =
false;
248 while (expandBranches(BlockOffsets))
256 return new MSP430BSel();
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
STATISTIC(NumFunctions, "Total number of functions")
iterator_range< succ_iterator > successors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
FunctionPass * createMSP430BranchSelectionPass()
Returns an instance of the Branch Selection Pass.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
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 '...
static bool isInRage(int DistanceInBytes)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
static cl::opt< bool > BranchSelectEnabled("msp430-branch-select", cl::Hidden, cl::init(true), cl::desc("Expand out of range branches"))
Properties which a MachineFunction may have at a given point in time.