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.