LLVM: lib/Target/PowerPC/PPCCTRLoops.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

44#include

45

46using namespace llvm;

47

48#define DEBUG_TYPE "ppc-ctrloops"

49

50STATISTIC(NumCTRLoops, "Number of CTR loops generated");

51STATISTIC(NumNormalLoops, "Number of normal compare + branch loops generated");

52

53namespace {

55public:

56 static char ID;

57

59

60 void getAnalysisUsage(AnalysisUsage &AU) const override {

61 AU.addRequired();

63 }

64

65 bool runOnMachineFunction(MachineFunction &MF) override;

66

67private:

68 const PPCInstrInfo *TII = nullptr;

69 MachineRegisterInfo *MRI = nullptr;

70

71 bool processLoop(MachineLoop *ML);

72 bool isCTRClobber(MachineInstr *MI, bool CheckReads) const;

73 void expandNormalLoops(MachineLoop *ML, MachineInstr *Start,

74 MachineInstr *Dec);

75 void expandCTRLoops(MachineLoop *ML, MachineInstr *Start, MachineInstr *Dec);

76};

77}

78

79char PPCCTRLoops::ID = 0;

80

82 false, false)

86

88

89bool PPCCTRLoops::runOnMachineFunction(MachineFunction &MF) {

91

92 auto &MLI = getAnalysis().getLI();

95

96 for (auto *ML : MLI) {

97 if (ML->isOutermost())

99 }

100

101#ifndef NDEBUG

102 for (const MachineBasicBlock &BB : MF) {

103 for (const MachineInstr &I : BB)

104 assert((I.getOpcode() != PPC::DecreaseCTRloop &&

105 I.getOpcode() != PPC::DecreaseCTR8loop) &&

106 "CTR loop pseudo is not expanded!");

107 }

108#endif

109

111}

112

113bool PPCCTRLoops::isCTRClobber(MachineInstr *MI, bool CheckReads) const {

114 if (!CheckReads) {

115

116

117

118

119

120 return MI->definesRegister(PPC::CTR, nullptr) ||

121 MI->definesRegister(PPC::CTR8, nullptr);

122 }

123

124 if (MI->modifiesRegister(PPC::CTR, nullptr) ||

125 MI->modifiesRegister(PPC::CTR8, nullptr))

126 return true;

127

128 if (MI->getDesc().isCall())

129 return true;

130

131

132

133 if (MI->readsRegister(PPC::CTR, nullptr) ||

134 MI->readsRegister(PPC::CTR8, nullptr))

135 return true;

136

137 return false;

138}

139

140bool PPCCTRLoops::processLoop(MachineLoop *ML) {

142

143

144 for (MachineLoop *I : *ML)

146

147

148

150 return true;

151

152 auto IsLoopStart = [](MachineInstr &MI) {

153 return MI.getOpcode() == PPC::MTCTRloop ||

154 MI.getOpcode() == PPC::MTCTR8loop;

155 };

156

157 auto SearchForStart =

158 [&IsLoopStart](MachineBasicBlock *MBB) -> MachineInstr * {

159 for (auto &MI : *MBB) {

160 if (IsLoopStart(MI))

161 return &MI;

162 }

163 return nullptr;

164 };

165

166 MachineInstr *Start = nullptr;

167 MachineInstr *Dec = nullptr;

168 bool InvalidCTRLoop = false;

169

170 MachineBasicBlock *Preheader = ML->getLoopPreheader();

171

172

173 if (!Preheader)

174 return false;

175

176 Start = SearchForStart(Preheader);

177

178 if (!Start)

179 return false;

180

181

182 if (Preheader->isLiveIn(PPC::CTR) || Preheader->isLiveIn(PPC::CTR8))

183 InvalidCTRLoop = true;

184

185

186

188 std::next(Start->getReverseIterator());

190

191

192 if (isCTRClobber(&*I, false)) {

193 InvalidCTRLoop = true;

194 break;

195 }

196

197

198

201 if (isCTRClobber(&*I, true)) {

202 InvalidCTRLoop = true;

203 break;

204 }

205

206

207

209 for (auto &MI : *MBB) {

210 if (MI.getOpcode() == PPC::DecreaseCTRloop ||

211 MI.getOpcode() == PPC::DecreaseCTR8loop)

212 Dec = &MI;

213 else if (!InvalidCTRLoop)

214

215 InvalidCTRLoop |= isCTRClobber(&MI, true);

216 }

217 if (Dec && InvalidCTRLoop)

218 break;

219 }

220

221 assert(Dec && "CTR loop is not complete!");

222

223 if (InvalidCTRLoop) {

224 expandNormalLoops(ML, Start, Dec);

225 ++NumNormalLoops;

226 }

227 else {

228 expandCTRLoops(ML, Start, Dec);

229 ++NumCTRLoops;

230 }

231 return true;

232}

233

234void PPCCTRLoops::expandNormalLoops(MachineLoop *ML, MachineInstr *Start,

235 MachineInstr *Dec) {

236 bool Is64Bit =

237 Start->getParent()->getParent()->getSubtarget().isPPC64();

238

239 MachineBasicBlock *Preheader = Start->getParent();

240 MachineBasicBlock *Exiting = Dec->getParent();

241 assert((Preheader && Exiting) &&

242 "Preheader and exiting should exist for CTR loop!");

243

245 "Loop decrement stride must be 1");

246

247 unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;

248 unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;

249

251 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass

252 : &PPC::GPRC_and_GPRC_NOR0RegClass);

253

254 Start->getParent()->getParent()->getProperties().resetNoPHIs();

255

256

257 auto PHIMIB = BuildMI(*ML->getHeader(), ML->getHeader()->getFirstNonPHI(),

259 PHIMIB.addReg(Start->getOperand(0).getReg()).addMBB(Preheader);

260

262 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass

263 : &PPC::GPRC_and_GPRC_NOR0RegClass);

264

268

269

270 if (ML->isLoopLatch(Exiting)) {

271

272

273

274

275 assert(ML->getHeader()->pred_size() == 2 &&

276 "Loop header predecessor is not right!");

277 PHIMIB.addReg(ADDIDef).addMBB(Exiting);

278 } else {

279

280

281

282

283 for (MachineBasicBlock *P : ML->getHeader()->predecessors()) {

284 if (ML->contains(P)) {

286 "Loop's header in-loop predecessor is not loop latch!");

287 PHIMIB.addReg(ADDIDef).addMBB(P);

288 } else

290 "CTR loop should not be generated for irreducible loop!");

291 }

292 }

293

294

295 Register CMPDef = MRI->createVirtualRegister(&PPC::CRRCRegClass);

296 auto CMPMIB =

300

303 .addReg(CMPMIB->getOperand(0).getReg(), 0, PPC::sub_gt);

304

305

306 Start->eraseFromParent();

308}

309

310void PPCCTRLoops::expandCTRLoops(MachineLoop *ML, MachineInstr *Start,

311 MachineInstr *Dec) {

312 bool Is64Bit =

313 Start->getParent()->getParent()->getSubtarget().isPPC64();

314

315 MachineBasicBlock *Preheader = Start->getParent();

316 MachineBasicBlock *Exiting = Dec->getParent();

317

318 (void)Preheader;

319 assert((Preheader && Exiting) &&

320 "Preheader and exiting should exist for CTR loop!");

321

323

324 unsigned BDNZOpcode = Is64Bit ? PPC::BDNZ8 : PPC::BDNZ;

325 unsigned BDZOpcode = Is64Bit ? PPC::BDZ8 : PPC::BDZ;

328 "There should be only one user for loop decrement pseudo!");

329

330 unsigned Opcode = 0;

331 switch (BrInstr->getOpcode()) {

332 case PPC::BC:

333 Opcode = BDNZOpcode;

334 (void) ML;

335 assert(ML->contains(BrInstr->getOperand(1).getMBB()) &&

336 "Invalid ctr loop!");

337 break;

338 case PPC::BCn:

339 Opcode = BDZOpcode;

340 assert(ML->contains(BrInstr->getOperand(1).getMBB()) &&

341 "Invalid ctr loop!");

342 break;

343 default:

344 llvm_unreachable("Unhandled branch user for DecreaseCTRloop.");

345 }

346

347

348 BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(), TII->get(Opcode))

349 .addMBB(BrInstr->getOperand(1).getMBB());

350

351

354}

unsigned const MachineRegisterInfo * MRI

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

Promote Memory to Register

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

AnalysisUsage & addRequired()

FunctionPass class - This class is used to implement most global optimizations.

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

reverse_instr_iterator instr_rend()

Instructions::iterator instr_iterator

instr_iterator instr_end()

LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const

Return true if the specified register is in the live in set.

Instructions::reverse_iterator reverse_instr_iterator

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

const MachineBasicBlock * getParent() 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.

const MachineOperand & getOperand(unsigned i) const

Register getReg() const

getReg - Returns the register number.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

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.

FunctionPass * createPPCCTRLoopsPass()

Definition PPCCTRLoops.cpp:87

auto reverse(ContainerTy &&C)