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 ()
292 return false;
293
294
297
298
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
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
340 return false;
341 }
342
343
345 return false;
346
347
348 if ()
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 (.isVirtual())
461 return nullptr;
462 if (.hasOneNonDBGUse(Reg))
463 return nullptr;
465 if ()
466 return nullptr;
467
468 if (->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 (->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 = ;
503 return nullptr;
504
505
507 Register DestReg = MI.getOperand(0).getReg();
509 if (.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.