LLVM: lib/Target/Hexagon/HexagonGenPredicate.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

30#include

31#include

32#include

33

34#define DEBUG_TYPE "gen-pred"

35

36using namespace llvm;

37

38namespace {

39

41

42struct PrintRegister {

44

47

48private:

51};

52

54 const PrintRegister &PR);

56 return OS << printReg(PR.Reg.Reg, &PR.TRI, PR.Reg.SubReg);

57}

58

60 public:

61 static char ID;

62

64

65 StringRef getPassName() const override {

66 return "Hexagon generate predicate operations";

67 }

68

69 void getAnalysisUsage(AnalysisUsage &AU) const override {

73 }

74

76

77 private:

81

85 SetOfReg PredGPRs;

86 VectOfInst PUsers;

87 RegToRegMap G2P;

88

92 unsigned getPredForm(unsigned Opc);

94 bool isScalarCmp(unsigned Opc);

99 };

100

101}

102

103char HexagonGenPredicate::ID = 0;

104

106 "Hexagon generate predicate operations", false, false)

109 "Hexagon generate predicate operations", false, false)

110

111bool HexagonGenPredicate::isPredReg(Register R) {

112 if (!R.isVirtual())

113 return false;

115 return RC == &Hexagon::PredRegsRegClass;

116}

117

118unsigned HexagonGenPredicate::getPredForm(unsigned Opc) {

119 using namespace Hexagon;

120

121 switch (Opc) {

122 case A2_and:

123 case A2_andp:

124 return C2_and;

125 case A4_andn:

126 case A4_andnp:

127 return C2_andn;

128 case M4_and_and:

129 return C4_and_and;

130 case M4_and_andn:

131 return C4_and_andn;

132 case M4_and_or:

133 return C4_and_or;

134

135 case A2_or:

136 case A2_orp:

137 return C2_or;

138 case A4_orn:

139 case A4_ornp:

140 return C2_orn;

141 case M4_or_and:

142 return C4_or_and;

143 case M4_or_andn:

144 return C4_or_andn;

145 case M4_or_or:

146 return C4_or_or;

147

148 case A2_xor:

149 case A2_xorp:

150 return C2_xor;

151

152 case C2_tfrrp:

153 return COPY;

154 }

155

156

157

158 static_assert(PHI == 0, "Use different value for ");

159 return 0;

160}

161

162bool HexagonGenPredicate::isConvertibleToPredForm(const MachineInstr *MI) {

163 unsigned Opc = MI->getOpcode();

164 if (getPredForm(Opc) != 0)

165 return true;

166

167

168

169

170

171 switch (Opc) {

172 case Hexagon::C2_cmpeqi:

173 case Hexagon::C4_cmpneqi:

174 if (MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)

175 return true;

176 break;

177 }

178 return false;

179}

180

181void HexagonGenPredicate::collectPredicateGPR(MachineFunction &MF) {

182 for (MachineBasicBlock &B : MF) {

183 for (MachineInstr &MI : B) {

184 unsigned Opc = MI.getOpcode();

185 switch (Opc) {

186 case Hexagon::C2_tfrpr:

187 case TargetOpcode::COPY:

188 if (isPredReg(MI.getOperand(1).getReg())) {

192 }

193 break;

194 }

195 }

196 }

197}

198

199void HexagonGenPredicate::processPredicateGPR(const RegSubRegPair &Reg) {

201 << "\n");

203

204 use_iterator I = MRI->use_begin(Reg.Reg), E = MRI->use_end();

205 if (I == E) {

207 << '\n');

208 MachineInstr *DefI = MRI->getVRegDef(Reg.Reg);

210 return;

211 }

212

213 for (; I != E; ++I) {

214 MachineInstr *UseI = I->getParent();

215 if (isConvertibleToPredForm(UseI))

217 }

218}

219

221

222

223

225 RegToRegMap::iterator F = G2P.find(Reg);

226 if (F != G2P.end())

227 return F->second;

228

230 MachineInstr *DefI = MRI->getVRegDef(Reg.Reg);

233 if (Opc == Hexagon::C2_tfrpr || Opc == TargetOpcode::COPY) {

236 G2P.insert(std::make_pair(Reg, PR));

238 return PR;

239 }

240

241 MachineBasicBlock &B = *DefI->getParent();

243 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;

244 Register NewPR = MRI->createVirtualRegister(PredRC);

245

246

247

248 if (isConvertibleToPredForm(DefI)) {

250 BuildMI(B, std::next(DefIt), DL, TII->get(TargetOpcode::COPY), NewPR)

254 << '\n');

256 }

257

259}

260

261bool HexagonGenPredicate::isScalarCmp(unsigned Opc) {

262 switch (Opc) {

263 case Hexagon::C2_cmpeq:

264 case Hexagon::C2_cmpgt:

265 case Hexagon::C2_cmpgtu:

266 case Hexagon::C2_cmpeqp:

267 case Hexagon::C2_cmpgtp:

268 case Hexagon::C2_cmpgtup:

269 case Hexagon::C2_cmpeqi:

270 case Hexagon::C2_cmpgti:

271 case Hexagon::C2_cmpgtui:

272 case Hexagon::C2_cmpgei:

273 case Hexagon::C2_cmpgeui:

274 case Hexagon::C4_cmpneqi:

275 case Hexagon::C4_cmpltei:

276 case Hexagon::C4_cmplteui:

277 case Hexagon::C4_cmpneq:

278 case Hexagon::C4_cmplte:

279 case Hexagon::C4_cmplteu:

280 case Hexagon::A4_cmpbeq:

281 case Hexagon::A4_cmpbeqi:

282 case Hexagon::A4_cmpbgtu:

283 case Hexagon::A4_cmpbgtui:

284 case Hexagon::A4_cmpbgt:

285 case Hexagon::A4_cmpbgti:

286 case Hexagon::A4_cmpheq:

287 case Hexagon::A4_cmphgt:

288 case Hexagon::A4_cmphgtu:

289 case Hexagon::A4_cmpheqi:

290 case Hexagon::A4_cmphgti:

291 case Hexagon::A4_cmphgtui:

292 return true;

293 }

294 return false;

295}

296

297bool HexagonGenPredicate::isScalarPred(RegSubRegPair PredReg) {

298 std::queue WorkQ;

299 WorkQ.push(PredReg);

300

301 while (!WorkQ.empty()) {

303 WorkQ.pop();

304 const MachineInstr *DefI = MRI->getVRegDef(PR.Reg);

305 if (!DefI)

306 return false;

307 unsigned DefOpc = DefI->getOpcode();

308 switch (DefOpc) {

309 case TargetOpcode::COPY: {

310 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;

311 if (MRI->getRegClass(PR.Reg) != PredRC)

312 return false;

313

314 [[fallthrough]];

315 }

316 case Hexagon::C2_and:

317 case Hexagon::C2_andn:

318 case Hexagon::C4_and_and:

319 case Hexagon::C4_and_andn:

320 case Hexagon::C4_and_or:

321 case Hexagon::C2_or:

322 case Hexagon::C2_orn:

323 case Hexagon::C4_or_and:

324 case Hexagon::C4_or_andn:

325 case Hexagon::C4_or_or:

326 case Hexagon::C4_or_orn:

327 case Hexagon::C2_xor:

328

329 for (const MachineOperand &MO : DefI->operands())

330 if (MO.isReg() && MO.isUse())

332 break;

333

334

335 default:

336 return isScalarCmp(DefOpc);

337 }

338 }

339

340 return true;

341}

342

343bool HexagonGenPredicate::convertToPredForm(MachineInstr *MI) {

345

346 unsigned Opc = MI->getOpcode();

347 assert(isConvertibleToPredForm(MI));

348 unsigned NumOps = MI->getNumOperands();

349 for (unsigned i = 0; i < NumOps; ++i) {

350 MachineOperand &MO = MI->getOperand(i);

352 continue;

354 if (Reg.SubReg && Reg.SubReg != Hexagon::isub_lo)

355 return false;

357 return false;

358 }

359

360 MachineBasicBlock &B = *MI->getParent();

362

363 unsigned NewOpc = getPredForm(Opc);

364

365 if (NewOpc == 0) {

366 switch (Opc) {

367 case Hexagon::C2_cmpeqi:

368 NewOpc = Hexagon::C2_not;

369 break;

370 case Hexagon::C4_cmpneqi:

371 NewOpc = TargetOpcode::COPY;

372 break;

373 default:

374 return false;

375 }

376

377

378

379

381 if (!isScalarPred(PR))

382 return false;

383

384

386 }

387

388

389 MachineOperand &Op0 = MI->getOperand(0);

392

393

394

395

396 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;

398 MachineInstrBuilder MIB = BuildMI(B, MI, DL, TII->get(NewOpc), NewPR.Reg);

399

400

401 for (unsigned i = 1; i < NumOps; ++i) {

405 }

407

408

409

410 const TargetRegisterClass *RC = MRI->getRegClass(OutR.Reg);

411 Register NewOutR = MRI->createVirtualRegister(RC);

412 BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), NewOutR)

414 MRI->replaceRegWith(OutR.Reg, NewOutR);

415 MI->eraseFromParent();

416

417

418

419

423 processPredicateGPR(R);

424 }

425 return true;

426}

427

428bool HexagonGenPredicate::eliminatePredCopies(MachineFunction &MF) {

430 const TargetRegisterClass *PredRC = &Hexagon::PredRegsRegClass;

432 VectOfInst Erase;

433

434

435

436

437

438

439

440

441

442

443

444 for (MachineBasicBlock &MBB : MF) {

445 for (MachineInstr &MI : MBB) {

446 if (MI.getOpcode() != TargetOpcode::COPY)

447 continue;

451 continue;

453 continue;

454 if (MRI->getRegClass(DR.Reg) != PredRC)

455 continue;

456 if (MRI->getRegClass(SR.Reg) != PredRC)

457 continue;

459 MRI->replaceRegWith(DR.Reg, SR.Reg);

460 Erase.insert(&MI);

462 }

463 }

464

465 for (MachineInstr *MI : Erase)

466 MI->eraseFromParent();

467

469}

470

471bool HexagonGenPredicate::runOnMachineFunction(MachineFunction &MF) {

473 return false;

474

475 TII = MF.getSubtarget().getInstrInfo();

476 TRI = MF.getSubtarget().getRegisterInfo();

478 PredGPRs.clear();

481

483 collectPredicateGPR(MF);

485 processPredicateGPR(R);

486

487 bool Again;

488 do {

489 Again = false;

490 VectOfInst Processed, Copy;

491

492 Copy = PUsers;

493 for (MachineInstr *MI : Copy) {

494 bool Done = convertToPredForm(MI);

496 Processed.insert(MI);

497 Again = true;

498 }

499 }

501

502 auto Done = [Processed] (MachineInstr *MI) -> bool {

503 return Processed.count(MI);

504 };

506 } while (Again);

507

508 Changed |= eliminatePredCopies(MF);

510}

511

513 return new HexagonGenPredicate();

514}

unsigned const MachineRegisterInfo * MRI

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

const HexagonInstrInfo * TII

const size_t AbstractManglingParser< Derived, Alloc >::NumOps

TargetInstrInfo::RegSubRegPair RegSubRegPair

Register const TargetRegisterInfo * TRI

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 implements a set that has insertion order iteration characteristics.

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

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

MachineInstrBundleIterator< MachineInstr > iterator

Analysis pass which computes a MachineDominatorTree.

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.

Function & getFunction()

Return the LLVM function that this machine code represents.

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

Add a new virtual register operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

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

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

defusechain_iterator< true, false, false, true, false > use_iterator

use_iterator/use_begin/use_end - Walk all uses of the specified register.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

A vector that has set insertion semantics.

bool remove_if(UnaryPredicate P)

Remove items from the set vector based on a predicate function.

size_type count(const_arg_type key) const

Count the number of elements of a given key in the SetVector.

void clear()

Completely clear the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

StringRef - Represent a constant reference to a string, i.e.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

This class implements an extremely fast bulk output stream that can only output to a stream.

#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.

bool isPredReg(MCRegisterInfo const &MRI, MCRegister Reg)

This is an optimization pass for GlobalISel generic memory operations.

TargetInstrInfo::RegSubRegPair getRegSubRegPair(const MachineOperand &O)

Create RegSubRegPair from a register MachineOperand.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionPass * createHexagonGenPredicate()

Definition HexagonGenPredicate.cpp:512

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

A pair composed of a register and a sub-register index.