LLVM  9.0.0svn
MSP430BranchSelector.cpp
Go to the documentation of this file.
1 //===-- MSP430BranchSelector.cpp - Emit long conditional branches ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a pass that scans a machine function to determine which
10 // conditional branches need more than 10 bits of displacement to reach their
11 // target basic block. It does this in two passes; a calculation of basic block
12 // positions pass, and a branch pseudo op to machine branch opcode pass. This
13 // pass should be run last, just before the assembly printer.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "MSP430.h"
18 #include "MSP430InstrInfo.h"
19 #include "MSP430Subtarget.h"
20 #include "llvm/ADT/Statistic.h"
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "msp430-branch-select"
28 
29 static cl::opt<bool>
30  BranchSelectEnabled("msp430-branch-select", cl::Hidden, cl::init(true),
31  cl::desc("Expand out of range branches"));
32 
33 STATISTIC(NumSplit, "Number of machine basic blocks split");
34 STATISTIC(NumExpanded, "Number of branches expanded to long format");
35 
36 namespace {
37 class MSP430BSel : public MachineFunctionPass {
38 
39  typedef SmallVector<int, 16> OffsetVector;
40 
41  MachineFunction *MF;
42  const MSP430InstrInfo *TII;
43 
44  unsigned measureFunction(OffsetVector &BlockOffsets,
45  MachineBasicBlock *FromBB = nullptr);
46  bool expandBranches(OffsetVector &BlockOffsets);
47 
48 public:
49  static char ID;
50  MSP430BSel() : MachineFunctionPass(ID) {}
51 
52  bool runOnMachineFunction(MachineFunction &MF) override;
53 
54  MachineFunctionProperties getRequiredProperties() const override {
57  }
58 
59  StringRef getPassName() const override { return "MSP430 Branch Selector"; }
60 };
61 char MSP430BSel::ID = 0;
62 }
63 
64 static bool isInRage(int DistanceInBytes) {
65  // According to CC430 Family User's Guide, Section 4.5.1.3, branch
66  // instructions have the signed 10-bit word offset field, so first we need to
67  // convert the distance from bytes to words, then check if it fits in 10-bit
68  // signed integer.
69  const int WordSize = 2;
70 
71  assert((DistanceInBytes % WordSize == 0) &&
72  "Branch offset should be word aligned!");
73 
74  int Words = DistanceInBytes / WordSize;
75  return isInt<10>(Words);
76 }
77 
78 /// Measure each basic block, fill the BlockOffsets, and return the size of
79 /// the function, starting with BB
80 unsigned MSP430BSel::measureFunction(OffsetVector &BlockOffsets,
81  MachineBasicBlock *FromBB) {
82  // Give the blocks of the function a dense, in-order, numbering.
83  MF->RenumberBlocks(FromBB);
84 
86  if (FromBB == nullptr) {
87  Begin = MF->begin();
88  } else {
89  Begin = FromBB->getIterator();
90  }
91 
92  BlockOffsets.resize(MF->getNumBlockIDs());
93 
94  unsigned TotalSize = BlockOffsets[Begin->getNumber()];
95  for (auto &MBB : make_range(Begin, MF->end())) {
96  BlockOffsets[MBB.getNumber()] = TotalSize;
97  for (MachineInstr &MI : MBB) {
98  TotalSize += TII->getInstSizeInBytes(MI);
99  }
100  }
101  return TotalSize;
102 }
103 
104 /// Do expand branches and split the basic blocks if necessary.
105 /// Returns true if made any change.
106 bool MSP430BSel::expandBranches(OffsetVector &BlockOffsets) {
107  // For each conditional branch, if the offset to its destination is larger
108  // than the offset field allows, transform it into a long branch sequence
109  // like this:
110  // short branch:
111  // bCC MBB
112  // long branch:
113  // b!CC $PC+6
114  // b MBB
115  //
116  bool MadeChange = false;
117  for (auto MBB = MF->begin(), E = MF->end(); MBB != E; ++MBB) {
118  unsigned MBBStartOffset = 0;
119  for (auto MI = MBB->begin(), EE = MBB->end(); MI != EE; ++MI) {
120  MBBStartOffset += TII->getInstSizeInBytes(*MI);
121 
122  // If this instruction is not a short branch then skip it.
123  if (MI->getOpcode() != MSP430::JCC && MI->getOpcode() != MSP430::JMP) {
124  continue;
125  }
126 
127  MachineBasicBlock *DestBB = MI->getOperand(0).getMBB();
128  // Determine the distance from the current branch to the destination
129  // block. MBBStartOffset already includes the size of the current branch
130  // instruction.
131  int BlockDistance =
132  BlockOffsets[DestBB->getNumber()] - BlockOffsets[MBB->getNumber()];
133  int BranchDistance = BlockDistance - MBBStartOffset;
134 
135  // If this branch is in range, ignore it.
136  if (isInRage(BranchDistance)) {
137  continue;
138  }
139 
140  LLVM_DEBUG(dbgs() << " Found a branch that needs expanding, "
141  << printMBBReference(*DestBB) << ", Distance "
142  << BranchDistance << "\n");
143 
144  // If JCC is not the last instruction we need to split the MBB.
145  if (MI->getOpcode() == MSP430::JCC && std::next(MI) != EE) {
146 
147  LLVM_DEBUG(dbgs() << " Found a basic block that needs to be split, "
148  << printMBBReference(*MBB) << "\n");
149 
150  // Create a new basic block.
151  MachineBasicBlock *NewBB =
152  MF->CreateMachineBasicBlock(MBB->getBasicBlock());
153  MF->insert(std::next(MBB), NewBB);
154 
155  // Splice the instructions following MI over to the NewBB.
156  NewBB->splice(NewBB->end(), &*MBB, std::next(MI), MBB->end());
157 
158  // Update the successor lists.
159  for (MachineBasicBlock *Succ : MBB->successors()) {
160  if (Succ == DestBB) {
161  continue;
162  }
163  MBB->replaceSuccessor(Succ, NewBB);
164  NewBB->addSuccessor(Succ);
165  }
166 
167  // We introduced a new MBB so all following blocks should be numbered
168  // and measured again.
169  measureFunction(BlockOffsets, &*MBB);
170 
171  ++NumSplit;
172 
173  // It may be not necessary to start all over at this point, but it's
174  // safer do this anyway.
175  return true;
176  }
177 
178  MachineInstr &OldBranch = *MI;
179  DebugLoc dl = OldBranch.getDebugLoc();
180  int InstrSizeDiff = -TII->getInstSizeInBytes(OldBranch);
181 
182  if (MI->getOpcode() == MSP430::JCC) {
183  MachineBasicBlock *NextMBB = &*std::next(MBB);
184  assert(MBB->isSuccessor(NextMBB) &&
185  "This block must have a layout successor!");
186 
187  // The BCC operands are:
188  // 0. Target MBB
189  // 1. MSP430 branch predicate
191  Cond.push_back(MI->getOperand(1));
192 
193  // Jump over the long branch on the opposite condition
195  MI = BuildMI(*MBB, MI, dl, TII->get(MSP430::JCC))
196  .addMBB(NextMBB)
197  .add(Cond[0]);
198  InstrSizeDiff += TII->getInstSizeInBytes(*MI);
199  ++MI;
200  }
201 
202  // Unconditional branch to the real destination.
203  MI = BuildMI(*MBB, MI, dl, TII->get(MSP430::Bi)).addMBB(DestBB);
204  InstrSizeDiff += TII->getInstSizeInBytes(*MI);
205 
206  // Remove the old branch from the function.
207  OldBranch.eraseFromParent();
208 
209  // The size of a new instruction is different from the old one, so we need
210  // to correct all block offsets.
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 
223 bool MSP430BSel::runOnMachineFunction(MachineFunction &mf) {
224  MF = &mf;
225  TII = static_cast<const MSP430InstrInfo *>(MF->getSubtarget().getInstrInfo());
226 
227  // If the pass is disabled, just bail early.
228  if (!BranchSelectEnabled)
229  return false;
230 
231  LLVM_DEBUG(dbgs() << "\n********** " << getPassName() << " **********\n");
232 
233  // BlockOffsets - Contains the distance from the beginning of the function to
234  // the beginning of each basic block.
235  OffsetVector BlockOffsets;
236 
237  unsigned FunctionSize = measureFunction(BlockOffsets);
238  // If the entire function is smaller than the displacement of a branch field,
239  // we know we don't need to expand any branches in this
240  // function. This is a common case.
241  if (isInRage(FunctionSize)) {
242  return false;
243  }
244 
245  // Iteratively expand branches until we reach a fixed point.
246  bool MadeChange = false;
247  while (expandBranches(BlockOffsets))
248  MadeChange = true;
249 
250  return MadeChange;
251 }
252 
253 /// Returns an instance of the Branch Selection Pass
255  return new MSP430BSel();
256 }
const MachineInstrBuilder & add(const MachineOperand &MO) const
This class represents lattice values for constants.
Definition: AllocatorList.h:23
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:385
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")
A debug info location.
Definition: DebugLoc.h:33
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 &#39;this&#39; from the containing basic block and delete it.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they&#39;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)
Definition: CommandLine.h:432
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.
Definition: Pass.h:284
self_iterator getIterator()
Definition: ilist_node.h:81
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 &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
Definition: MachineInstr.h:64
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB &#39;Other&#39; at the position From, and insert it into this MBB right before &#39;...
static bool isInRage(int DistanceInBytes)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static cl::opt< bool > BranchSelectEnabled("msp430-branch-select", cl::Hidden, cl::init(true), cl::desc("Expand out of range branches"))
#define LLVM_DEBUG(X)
Definition: Debug.h:122
Properties which a MachineFunction may have at a given point in time.