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()];
99 TotalSize +=
TII->getInstSizeInBytes(
MI);
107 bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) {
117 bool MadeChange =
false;
119 unsigned MBBStartOffset = 0;
121 MBBStartOffset +=
TII->getInstSizeInBytes(*
MI);
124 if (
MI->getOpcode() != MSP430::JCC &&
MI->getOpcode() != MSP430::JMP) {
134 int BranchDistance = BlockDistance - MBBStartOffset;
141 DEBUG(
dbgs() <<
" Found a branch that needs expanding, BB#"
142 << DestBB->
getNumber() <<
", Distance " << BranchDistance
146 if (
MI->getOpcode() == MSP430::JCC && std::next(
MI) != EE) {
148 DEBUG(
dbgs() <<
" Found a basic block that needs to be split, BB#"
157 NewBB->splice(NewBB->end(), &*
MBB, std::next(
MI),
MBB->
end());
161 if (Succ == DestBB) {
165 NewBB->addSuccessor(Succ);
170 measureFunction(BlockOffsets, &*
MBB);
181 int InstrSizeDiff = -
TII->getInstSizeInBytes(OldBranch);
183 if (
MI->getOpcode() == MSP430::JCC) {
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 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();
void push_back(const T &Elt)
STATISTIC(NumFunctions,"Total number of functions")
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
iterator_range< succ_iterator > successors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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.
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)
Replace successor OLD with NEW and update probability info.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
static bool isInRage(int DistanceInBytes)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
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.