LLVM: lib/Target/MSP430/MSP430BranchSelector.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
26using namespace llvm;
27
28#define DEBUG_TYPE "msp430-branch-select"
29
32 cl::desc("Expand out of range branches"));
33
34STATISTIC(NumSplit, "Number of machine basic blocks split");
35STATISTIC(NumExpanded, "Number of branches expanded to long format");
36
37namespace {
39
41
44
45 unsigned measureFunction(OffsetVector &BlockOffsets,
47 bool expandBranches(OffsetVector &BlockOffsets);
48
49public:
50 static char ID;
52
53 bool runOnMachineFunction(MachineFunction &MF) override;
54
55 MachineFunctionProperties getRequiredProperties() const override {
56 return MachineFunctionProperties().setNoVRegs();
57 }
58
59 StringRef getPassName() const override { return "MSP430 Branch Selector"; }
60};
61char MSP430BSel::ID = 0;
62}
63
64static bool isInRage(int DistanceInBytes) {
65
66
67
68
69 const int WordSize = 2;
70
71 assert((DistanceInBytes % WordSize == 0) &&
72 "Branch offset should be word aligned!");
73
74 int Words = DistanceInBytes / WordSize;
76}
77
78
79
80unsigned MSP430BSel::measureFunction(OffsetVector &BlockOffsets,
82
84
86 if (FromBB == nullptr) {
87 Begin = MF->begin();
88 } else {
90 }
91
93
94 unsigned TotalSize = BlockOffsets[Begin->getNumber()];
97 for (MachineInstr &MI : MBB) {
98 TotalSize += TII->getInstSizeInBytes(MI);
99 }
100 }
101 return TotalSize;
102}
103
104
105
106bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) {
107
108
109
110
111
112
113
114
115
116 bool MadeChange = false;
118 unsigned MBBStartOffset = 0;
120 MBBStartOffset += TII->getInstSizeInBytes(*MI);
121
122
123 if (MI->getOpcode() != MSP430::JCC && MI->getOpcode() != MSP430::JMP) {
124 continue;
125 }
126
127 MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
128
129
130
131 int BlockDistance =
133 int BranchDistance = BlockDistance - MBBStartOffset;
134
135
136 if (isInRage(BranchDistance)) {
137 continue;
138 }
139
140 LLVM_DEBUG(dbgs() << " Found a branch that needs expanding, "
142 << BranchDistance << "\n");
143
144
145 if (MI->getOpcode() == MSP430::JCC && std::next(MI) != EE) {
146
147 LLVM_DEBUG(dbgs() << " Found a basic block that needs to be split, "
149
150
151 MachineBasicBlock *NewBB =
153 MF->insert(std::next(MBB), NewBB);
154
155
157
158
159 for (MachineBasicBlock *Succ : MBB->successors()) {
160 if (Succ == DestBB) {
161 continue;
162 }
165 }
166
167
168
169 measureFunction(BlockOffsets, &*MBB);
170
171 ++NumSplit;
172
173
174
175 return true;
176 }
177
178 MachineInstr &OldBranch = *MI;
180 int InstrSizeDiff = -TII->getInstSizeInBytes(OldBranch);
181
182 if (MI->getOpcode() == MSP430::JCC) {
183 MachineBasicBlock *NextMBB = &*std::next(MBB);
185 "This block must have a layout successor!");
186
187
188
189
191 Cond.push_back(MI->getOperand(1));
192
193
198 InstrSizeDiff += TII->getInstSizeInBytes(*MI);
199 ++MI;
200 }
201
202
204 InstrSizeDiff += TII->getInstSizeInBytes(*MI);
205
206
208
209
210
211 for (int i = MBB->getNumber() + 1, e = BlockOffsets.size(); i < e; ++i) {
212 BlockOffsets[i] += InstrSizeDiff;
213 }
214 MBBStartOffset += InstrSizeDiff;
215
216 ++NumExpanded;
217 MadeChange = true;
218 }
219 }
220 return MadeChange;
221}
222
223bool MSP430BSel::runOnMachineFunction(MachineFunction &mf) {
224 MF = &mf;
225 TII = static_cast<const MSP430InstrInfo *>(MF->getSubtarget().getInstrInfo());
226
227
229 return false;
230
231 LLVM_DEBUG(dbgs() << "\n********** " << getPassName() << " **********\n");
232
233
234
235 OffsetVector BlockOffsets;
236
237 unsigned FunctionSize = measureFunction(BlockOffsets);
238
239
240
241 if (isInRage(FunctionSize)) {
242 return false;
243 }
244
245
246 bool MadeChange = false;
247 while (expandBranches(BlockOffsets))
248 MadeChange = true;
249
250 return MadeChange;
251}
252
253
255 return new MSP430BSel();
256}
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)
Definition MSP430BranchSelector.cpp:64
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...
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 void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
FunctionPass * createMSP430BranchSelectionPass()
Returns an instance of the Branch Selection Pass.
Definition MSP430BranchSelector.cpp:254
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...
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.