LLVM: lib/Target/Lanai/LanaiMemAluCombiner.cpp Source File (original) (raw)

41STATISTIC(NumLdStAluCombined, "Number of memory and ALU instructions combined");

85 "Lanai memory ALU combiner pass", false, false)

86

87namespace {

88bool isSpls(uint16_t Opcode) { return Lanai::splsIdempotent(Opcode) == Opcode; }

89

90

91

92

93unsigned mergedOpcode(unsigned OldOpcode, bool ImmediateOffset) {

94 switch (OldOpcode) {

95 case Lanai::LDW_RI:

96 case Lanai::LDW_RR:

97 if (ImmediateOffset)

98 return Lanai::LDW_RI;

99 return Lanai::LDW_RR;

100 case Lanai::LDHs_RI:

101 case Lanai::LDHs_RR:

102 if (ImmediateOffset)

103 return Lanai::LDHs_RI;

104 return Lanai::LDHs_RR;

105 case Lanai::LDHz_RI:

106 case Lanai::LDHz_RR:

107 if (ImmediateOffset)

108 return Lanai::LDHz_RI;

109 return Lanai::LDHz_RR;

110 case Lanai::LDBs_RI:

111 case Lanai::LDBs_RR:

112 if (ImmediateOffset)

113 return Lanai::LDBs_RI;

114 return Lanai::LDBs_RR;

115 case Lanai::LDBz_RI:

116 case Lanai::LDBz_RR:

117 if (ImmediateOffset)

118 return Lanai::LDBz_RI;

119 return Lanai::LDBz_RR;

120 case Lanai::SW_RI:

121 case Lanai::SW_RR:

122 if (ImmediateOffset)

123 return Lanai::SW_RI;

124 return Lanai::SW_RR;

125 case Lanai::STB_RI:

126 case Lanai::STB_RR:

127 if (ImmediateOffset)

128 return Lanai::STB_RI;

129 return Lanai::STB_RR;

130 case Lanai::STH_RI:

131 case Lanai::STH_RR:

132 if (ImmediateOffset)

133 return Lanai::STH_RI;

134 return Lanai::STH_RR;

135 default:

136 return 0;

137 }

138}

139

140

141

143 if (MI.hasOneMemOperand())

144 return false;

145

146

147

148 if (mergedOpcode(MI.getOpcode(), false) == 0)

149 return false;

150

152

153

154

156 return false;

157

158 return true;

159}

160

161

162

165 return false;

166

172 default:

173 return false;

174 }

175}

176

178 return ((Op.isReg() && Op.getReg() == Lanai::R0) ||

179 (Op.isImm() && Op.getImm() == 0));

180}

181

182

183bool InstrUsesReg(const MbbIterator &Instr, const MachineOperand *Reg) {

185 Mop != Instr->operands_end(); ++Mop) {

186 if (isSameOperand(*Mop, *Reg))

187 return true;

188 }

189 return false;

190}

191

192

193

194

196 switch (AluOpcode) {

197 case Lanai::ADD_I_LO:

198 case Lanai::ADD_R:

200 case Lanai::SUB_I_LO:

201 case Lanai::SUB_R:

203 case Lanai::AND_I_LO:

204 case Lanai::AND_R:

206 case Lanai::OR_I_LO:

207 case Lanai::OR_R:

209 case Lanai::XOR_I_LO:

210 case Lanai::XOR_R:

212 case Lanai::SHL_R:

214 case Lanai::SRL_R:

216 case Lanai::SRA_R:

218 case Lanai::SA_I:

219 case Lanai::SL_I:

220 default:

222 }

223}

224

225

226

227

228

229void LanaiMemAluCombiner::insertMergedInstruction(MachineBasicBlock *BB,

230 const MbbIterator &MemInstr,

231 const MbbIterator &AluInstr,

232 bool Before) {

233

238

239

241 "Unsupported operand type in merge");

242

243

244 LPAC::AluCode AluOpcode = mergedAluCode(AluInstr->getOpcode());

245 unsigned NewOpc = mergedOpcode(MemInstr->getOpcode(), AluOffset.isImm());

246

248 assert(NewOpc != 0 && "Unknown merged node opcode");

249

250

252 BuildMI(*BB, MemInstr, MemInstr->getDebugLoc(), TII->get(NewOpc));

255

256

257 if (AluOffset.isReg())

259 else if (AluOffset.isImm())

261 else

263

264

265

266

267 if (Before || !isZeroOperand(MemOffset))

269 else

271

272

273 InstrBuilder.setMemRefs(MemInstr->memoperands());

274}

275

276

277

278bool isSuitableAluInstr(bool IsSpls, const MbbIterator &AluIter,

281

282 if (AluIter->getNumOperands() != 3)

283 return false;

284

288

289

290

291 if (!isSameOperand(Dest, Base) || !isSameOperand(Dest, Op1))

292 return false;

293

294 if (Op2.isImm()) {

295

296

297 if (AluIter->getOpcode() != Lanai::ADD_I_LO)

298 return false;

299

300 if (Offset.isReg() && Offset.getReg() == Lanai::R0)

301 return true;

302

303 if (Offset.isImm() &&

304 ((Offset.getImm() == 0 &&

305

306

310 return true;

311 } else if (Op2.isReg()) {

312

314 return true;

315 } else

316

317 return false;

318

319 return false;

320}

321

322MbbIterator LanaiMemAluCombiner::findClosestSuitableAluInstr(

323 MachineBasicBlock *BB, const MbbIterator &MemInstr, const bool Decrement) {

326 bool IsSpls = isSpls(MemInstr->getOpcode());

327

328 MbbIterator First = MemInstr;

329 MbbIterator Last = Decrement ? BB->begin() : BB->end();

330

333

335 break;

336

337

338 if (First->isDebugInstr())

339 continue;

340

343 }

344

345

348 break;

350 break;

351 }

352 }

353

354 return MemInstr;

355}

356

357bool LanaiMemAluCombiner::combineMemAluInBasicBlock(MachineBasicBlock *BB) {

359

360 MbbIterator MBBIter = BB->begin(), End = BB->end();

361 while (MBBIter != End) {

362 bool IsMemOp = isNonVolatileMemoryOp(*MBBIter);

363

364 if (IsMemOp) {

366 unsigned int DestReg = MBBIter->getOperand(0).getReg(),

367 BaseReg = MBBIter->getOperand(1).getReg();

368 assert(AluOperand.isImm() && "Unexpected memory operator type");

370

371

372

374 for (int Inc = 0; Inc <= 1; ++Inc) {

375 MbbIterator AluIter =

376 findClosestSuitableAluInstr(BB, MBBIter, Inc == 0);

377 if (AluIter != MBBIter) {

378 insertMergedInstruction(BB, MBBIter, AluIter, Inc == 0);

379

380 ++NumLdStAluCombined;

382

383

384 BB->erase(AluIter);

385

386 BB->erase(MBBIter++);

387 break;

388 }

389 }

390 }

391 }

392 if (MBBIter == End)

393 break;

394 ++MBBIter;

395 }

396

398}

399

400

401

402bool LanaiMemAluCombiner::runOnMachineFunction(MachineFunction &MF) {

404 return false;

405

409 Modified |= combineMemAluInBasicBlock(&MBB);

411}

412}

415 return new LanaiMemAluCombiner();

416}