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

1

2

3

4

5

6

7

8

9

10

11

12

23

24using namespace llvm;

25

26#define GET_INSTRINFO_CTOR_DTOR

27#include "LanaiGenInstrInfo.inc"

28

31 Lanai::ADJCALLSTACKUP),

32 RegisterInfo() {}

33

38 Register SourceRegister, bool KillSource,

39 bool RenamableDest, bool RenamableSrc) const {

40 if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {

42 }

43

44 BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)

47}

48

51 Register SourceRegister, bool IsKill, int FrameIndex,

55 if (Position != MBB.end()) {

56 DL = Position->getDebugLoc();

57 }

58

59 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {

61 }

67}

68

71 Register DestinationRegister, int FrameIndex,

75 if (Position != MBB.end()) {

76 DL = Position->getDebugLoc();

77 }

78

79 if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {

81 }

82 BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)

86}

87

92

95 return false;

96

97

98

99

100

101

103 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;

104 int64_t OffsetA = 0, OffsetB = 0;

110 int LowOffset = std::min(OffsetA, OffsetB);

111 int HighOffset = std::max(OffsetA, OffsetB);

112 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;

114 LowOffset + (int)LowWidth.getValue() <= HighOffset)

115 return true;

116 }

117 }

118 return false;

119}

120

124

126 switch (CC) {

147 case LPCC::ICC_PL:

159 default:

161 }

162}

163

164std::pair<unsigned, unsigned>

166 return std::make_pair(TF, 0u);

167}

168

172 static const std::pair<unsigned, const char *> TargetFlags[] = {

173 {MO_ABS_HI, "lanai-hi"},

174 {MO_ABS_LO, "lanai-lo"},

175 {MO_NO_FLAG, "lanai-nf"}};

176 return ArrayRef(TargetFlags);

177}

178

180 Register &SrcReg2, int64_t &CmpMask,

181 int64_t &CmpValue) const {

182 switch (MI.getOpcode()) {

183 default:

184 break;

185 case Lanai::SFSUB_F_RI_LO:

186 case Lanai::SFSUB_F_RI_HI:

187 SrcReg = MI.getOperand(0).getReg();

189 CmpMask = ~0;

190 CmpValue = MI.getOperand(1).getImm();

191 return true;

192 case Lanai::SFSUB_F_RR:

193 SrcReg = MI.getOperand(0).getReg();

194 SrcReg2 = MI.getOperand(1).getReg();

195 CmpMask = ~0;

196 CmpValue = 0;

197 return true;

198 }

199

200 return false;

201}

202

203

204

205

206

208 unsigned SrcReg2, int64_t ImmValue,

210 if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&

211 OI->getOpcode() == Lanai::SUB_R &&

216 return true;

217

218 if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&

219 OI->getOpcode() == Lanai::SUB_I_LO) ||

220 (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&

221 OI->getOpcode() == Lanai::SUB_I_HI)) &&

224 return true;

225 return false;

226}

227

229 switch (OldOpcode) {

230 case Lanai::ADD_I_HI:

231 return Lanai::ADD_F_I_HI;

232 case Lanai::ADD_I_LO:

233 return Lanai::ADD_F_I_LO;

234 case Lanai::ADD_R:

235 return Lanai::ADD_F_R;

236 case Lanai::ADDC_I_HI:

237 return Lanai::ADDC_F_I_HI;

238 case Lanai::ADDC_I_LO:

239 return Lanai::ADDC_F_I_LO;

240 case Lanai::ADDC_R:

241 return Lanai::ADDC_F_R;

242 case Lanai::AND_I_HI:

243 return Lanai::AND_F_I_HI;

244 case Lanai::AND_I_LO:

245 return Lanai::AND_F_I_LO;

246 case Lanai::AND_R:

247 return Lanai::AND_F_R;

248 case Lanai::OR_I_HI:

249 return Lanai::OR_F_I_HI;

250 case Lanai::OR_I_LO:

251 return Lanai::OR_F_I_LO;

252 case Lanai::OR_R:

253 return Lanai::OR_F_R;

254 case Lanai::SL_I:

255 return Lanai::SL_F_I;

256 case Lanai::SRL_R:

257 return Lanai::SRL_F_R;

258 case Lanai::SA_I:

259 return Lanai::SA_F_I;

260 case Lanai::SRA_R:

261 return Lanai::SRA_F_R;

262 case Lanai::SUB_I_HI:

263 return Lanai::SUB_F_I_HI;

264 case Lanai::SUB_I_LO:

265 return Lanai::SUB_F_I_LO;

266 case Lanai::SUB_R:

267 return Lanai::SUB_F_R;

268 case Lanai::SUBB_I_HI:

269 return Lanai::SUBB_F_I_HI;

270 case Lanai::SUBB_I_LO:

271 return Lanai::SUBB_F_I_LO;

272 case Lanai::SUBB_R:

273 return Lanai::SUBB_F_R;

274 case Lanai::XOR_I_HI:

275 return Lanai::XOR_F_I_HI;

276 case Lanai::XOR_I_LO:

277 return Lanai::XOR_F_I_LO;

278 case Lanai::XOR_R:

279 return Lanai::XOR_F_R;

280 default:

281 return Lanai::NOP;

282 }

283}

284

287 int64_t , int64_t CmpValue,

289

291 if (MI)

292 return false;

293

294

297

298

299 if (I == B)

300 return false;

301

302

303

304

305

307 if (SrcReg2 != 0)

308

309 MI = nullptr;

310 else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {

311

312

313

314 if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)

315 MI = nullptr;

316 else

317 return false;

318 }

319

320

321

323 for (--I; I != E; --I) {

325

326 if (Instr.modifiesRegister(Lanai::SR, TRI) ||

327 Instr.readsRegister(Lanai::SR, TRI))

328

329

330 return false;

331

332

335 break;

336 }

337

338

339 if (I == B)

340 return false;

341 }

342

343

345 return false;

346

347

348 if (MI)

350

352 bool isSafe = false;

353

355 OperandsToUpdate;

356 I = CmpInstr;

358 while (!isSafe && ++I != E) {

360 for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;

361 ++IO) {

364 isSafe = true;

365 break;

366 }

367 if (!MO.isReg() || MO.getReg() != Lanai::SR)

368 continue;

369 if (MO.isDef()) {

370 isSafe = true;

371 break;

372 }

373

375 CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();

376

377 if (Sub) {

380 return false;

381

382

383

384

385 if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&

386 Sub->getOperand(2).getReg() == SrcReg) {

388 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));

389 }

390 } else {

391

392 switch (CC) {

399

400 break;

411

412 return false;

414 return false;

415 }

416 }

417 }

418 }

419

420

421

422 if (!isSafe) {

425 if (Succ->isLiveIn(Lanai::SR))

426 return false;

427 }

428

429

431 MI->addRegisterDefined(Lanai::SR);

433 return true;

434 }

435

436 return false;

437}

438

441 unsigned &TrueOp, unsigned &FalseOp,

442 bool &Optimizable) const {

443 assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");

444

445

446

447

448

449 TrueOp = 1;

450 FalseOp = 2;

451 Cond.push_back(MI.getOperand(3));

452 Optimizable = true;

453 return false;

454}

455

456

457

460 if (Reg.isVirtual())

461 return nullptr;

462 if (MRI.hasOneNonDBGUse(Reg))

463 return nullptr;

465 if (MI)

466 return nullptr;

467

468 if (MI->isPredicable())

469 return nullptr;

470

471

473

474 if (MO.isFI() || MO.isCPI() || MO.isJTI())

475 return nullptr;

476 if (!MO.isReg())

477 continue;

478

479 if (MO.isTied())

480 return nullptr;

481 if (MO.getReg().isPhysical())

482 return nullptr;

483 if (MO.isDef() && !MO.isDead())

484 return nullptr;

485 }

486 bool DontMoveAcrossStores = true;

487 if (MI->isSafeToMove(DontMoveAcrossStores))

488 return nullptr;

489 return MI;

490}

491

495 bool ) const {

496 assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");

499 bool Invert = DefMI;

503 return nullptr;

504

505

507 Register DestReg = MI.getOperand(0).getReg();

509 if (MRI.constrainRegClass(DestReg, PreviousClass))

510 return nullptr;

511

512

514 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);

515

516

519 i != e && !DefDesc.operands()[i].isPredicate(); ++i)

520 NewMI.add(DefMI->getOperand(i));

521

522 unsigned CondCode = MI.getOperand(3).getImm();

523 if (Invert)

525 else

526 NewMI.addImm(CondCode);

528

529

530

531

533 NewMI.add(FalseReg);

535

536

537 SeenMIs.insert(NewMI);

539

540

541

542

543

544 if (DefMI->getParent() != MI.getParent())

546

547

548 DefMI->eraseFromParent();

549 return NewMI;

550}

551

552

553

554

555

556

557

558

559

560

561

566 bool AllowModify) const {

567

569

570

571

574

575

577 continue;

578

579

580

581 if (!isUnpredicatedTerminator(*Instruction))

582 break;

583

584

585

587 return true;

588

589

591 if (!AllowModify) {

593 continue;

594 }

595

596

598

599 Condition.clear();

600 FalseBlock = nullptr;

601

602

604 TrueBlock = nullptr;

607 continue;

608 }

609

610

612 continue;

613 }

614

615

617 if (Opcode != Lanai::BRCC)

618 return true;

619

620

621

622 if (Condition.empty()) {

625

626

627 FalseBlock = TrueBlock;

630 continue;

631 }

632

633

634 return true;

635 }

636

637

638 return false;

639}

640

641

642

643

647 "Lanai branch conditions should have one component.");

648

652 return false;

653}

654

655

656

657

663 int *BytesAdded) const {

664

665 assert(TrueBlock && "insertBranch must not be told to insert a fallthrough");

666 assert(!BytesAdded && "code size not handled");

667

668

669 if (Condition.empty()) {

670 assert(!FalseBlock && "Unconditional branch with multiple successors!");

672 return 1;

673 }

674

675

677 "Lanai branch conditions should have one component.");

678 unsigned ConditionalCode = Condition[0].getImm();

680

681

682

683 if (!FalseBlock)

684 return 1;

685

687 return 2;

688}

689

691 int *BytesRemoved) const {

692 assert(!BytesRemoved && "code size not handled");

693

695 unsigned Count = 0;

696

700 continue;

703 break;

704 }

705

706

710 }

711

713}

714

716 int &FrameIndex) const {

717 if (MI.getOpcode() == Lanai::LDW_RI)

718 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&

719 MI.getOperand(2).getImm() == 0) {

720 FrameIndex = MI.getOperand(1).getIndex();

721 return MI.getOperand(0).getReg();

722 }

723 return 0;

724}

725

727 int &FrameIndex) const {

728 if (MI.getOpcode() == Lanai::LDW_RI) {

729 unsigned Reg;

731 return Reg;

732

734 if (hasLoadFromStackSlot(MI, Accesses)){

735 FrameIndex =

737 ->getFrameIndex();

738 return 1;

739 }

740 }

741 return 0;

742}

743

745 int &FrameIndex) const {

746 if (MI.getOpcode() == Lanai::SW_RI)

747 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&

748 MI.getOperand(1).getImm() == 0) {

749 FrameIndex = MI.getOperand(0).getIndex();

750 return MI.getOperand(2).getReg();

751 }

752 return 0;

753}

754

758

759

761 return false;

764 return false;

765

767 default:

768 return false;

769 case Lanai::LDW_RI:

770 case Lanai::LDW_RR:

771 case Lanai::SW_RR:

772 case Lanai::SW_RI:

774 break;

775 case Lanai::LDHs_RI:

776 case Lanai::LDHz_RI:

777 case Lanai::STH_RI:

779 break;

780 case Lanai::LDBs_RI:

781 case Lanai::LDBz_RI:

782 case Lanai::STB_RI:

784 break;

785 }

786

789

790 if (!BaseOp->isReg())

791 return false;

792

793 return true;

794}

795

801 default:

802 return false;

803 case Lanai::LDW_RI:

804 case Lanai::LDW_RR:

805 case Lanai::SW_RR:

806 case Lanai::SW_RI:

807 case Lanai::LDHs_RI:

808 case Lanai::LDHz_RI:

809 case Lanai::STH_RI:

810 case Lanai::LDBs_RI:

811 case Lanai::LDBz_RI:

813 OffsetIsScalable = false;

815 return false;

817 return true;

818 }

819}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder MachineInstrBuilder & DefMI

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

static bool isRedundantFlagInstr(const MachineInstr *CmpI, Register SrcReg, Register SrcReg2, int64_t ImmValue, const MachineInstr *OI, bool &IsThumb1)

isRedundantFlagInstr - check whether the first instruction, whose only purpose is to update flags,...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

DXIL Forward Handle Accesses

static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC)

Definition LanaiInstrInfo.cpp:125

static unsigned flagSettingOpcodeVariant(unsigned OldOpcode)

Definition LanaiInstrInfo.cpp:228

static MachineInstr * canFoldIntoSelect(Register Reg, const MachineRegisterInfo &MRI)

Definition LanaiInstrInfo.cpp:458

Register const TargetRegisterInfo * TRI

Promote Memory to Register

const SmallVectorImpl< MachineOperand > & Cond

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

This file defines the SmallVector class.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

LLVM_ABI InstListType::iterator eraseFromParent()

This method unlinks 'this' from the containing basic block and deletes it.

unsigned getOpcode() const

Returns a member of one of the enums like Instruction::Add.

bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override

Definition LanaiInstrInfo.cpp:88

unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock, MachineBasicBlock *FalseBlock, ArrayRef< MachineOperand > Condition, const DebugLoc &DL, int *BytesAdded=nullptr) const override

Definition LanaiInstrInfo.cpp:658

Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition LanaiInstrInfo.cpp:744

bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override

Definition LanaiInstrInfo.cpp:439

Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const override

Definition LanaiInstrInfo.cpp:726

std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override

Definition LanaiInstrInfo.cpp:165

bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock, MachineBasicBlock *&FalseBlock, SmallVectorImpl< MachineOperand > &Condition, bool AllowModify) const override

Definition LanaiInstrInfo.cpp:562

virtual const LanaiRegisterInfo & getRegisterInfo() const

MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool PreferFalse) const override

Definition LanaiInstrInfo.cpp:493

bool expandPostRAPseudo(MachineInstr &MI) const override

Definition LanaiInstrInfo.cpp:121

LanaiInstrInfo(const LanaiSubtarget &STI)

Definition LanaiInstrInfo.cpp:29

bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const

Definition LanaiInstrInfo.cpp:755

ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override

Definition LanaiInstrInfo.cpp:170

void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register SourceRegister, bool IsKill, int FrameIndex, const TargetRegisterClass *RegisterClass, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition LanaiInstrInfo.cpp:49

bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override

Definition LanaiInstrInfo.cpp:285

bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override

Definition LanaiInstrInfo.cpp:179

Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition LanaiInstrInfo.cpp:715

unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override

Definition LanaiInstrInfo.cpp:690

bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override

Definition LanaiInstrInfo.cpp:796

void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, Register DestinationRegister, int FrameIndex, const TargetRegisterClass *RegisterClass, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition LanaiInstrInfo.cpp:69

bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Condition) const override

Definition LanaiInstrInfo.cpp:644

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position, const DebugLoc &DL, Register DestinationRegister, Register SourceRegister, bool KillSource, bool RenamableDest=false, bool RenamableSrc=false) const override

Definition LanaiInstrInfo.cpp:34

static LocationSize precise(uint64_t Value)

TypeSize getValue() const

Describe properties that are true of each instruction in the target description file.

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

ArrayRef< MCOperandInfo > operands() const

MachineInstrBundleIterator< MachineInstr > iterator

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addFrameIndex(int Idx) const

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 MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const

Copy all the implicit operands from OtherMI onto this one.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

bool mayLoadOrStore(QueryType Type=AnyInBundle) const

Return true if this instruction could possibly read or modify memory.

const MachineBasicBlock * getParent() const

unsigned getNumOperands() const

Retuns the total number of operands.

LLVM_ABI bool hasUnmodeledSideEffects() const

Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...

LLVM_ABI void tieOperands(unsigned DefIdx, unsigned UseIdx)

Add a tie between the register operands at DefIdx and UseIdx.

LLVM_ABI bool hasOrderedMemoryRef() const

Return true if this instruction may have an ordered or volatile memory reference, or if the informati...

LLVM_ABI void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

const MachineOperand & getOperand(unsigned i) const

LLVM_ABI void clearKillInfo()

Clears kill flags on all operands.

MachineOperand class - Representation of each machine instruction operand.

void setImplicit(bool Val=true)

bool isReg() const

isReg - Tests if this is a MO_Register operand.

bool isRegMask() const

isRegMask - Tests if this is a MO_RegisterMask operand.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

static MachineOperand CreateImm(int64_t Val)

Register getReg() const

getReg - Returns the register number.

LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const

Returns true if this operand is identical to the specified operand except for liveness related flags ...

static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)

clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.

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

Wrapper class representing virtual and physical registers.

A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...

bool erase(PtrType Ptr)

Remove pointer from the set.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

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

Value * getOperand(unsigned i) const

#define llvm_unreachable(msg)

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

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

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

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

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

FunctionAddr VTableAddr Count

@ Sub

Subtraction of integers.

unsigned getKillRegState(bool B)

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.