@@ -498,6 +498,117 @@ bool RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
498
498
return false ;
499
499
}
500
500
501
+ bool RISCVRegisterInfo::requiresVirtualBaseRegisters (
502
+ const MachineFunction &MF) const {
503
+ return true ;
504
+ }
505
+
506
+ // Returns true if the instruction's frame index reference would be better
507
+ // served by a base register other than FP or SP.
508
+ // Used by LocalStackSlotAllocation pass to determine which frame index
509
+ // references it should create new base registers for.
510
+ bool RISCVRegisterInfo::needsFrameBaseReg (MachineInstr *MI,
511
+ int64_t Offset) const {
512
+ unsigned FIOperandNum = 0 ;
513
+ for (; !MI->getOperand (FIOperandNum).isFI (); FIOperandNum++)
514
+ assert (FIOperandNum < MI->getNumOperands () &&
515
+ " Instr doesn't have FrameIndex operand" );
516
+
517
+ // For RISC-V, The machine instructions that include a FrameIndex operand
518
+ // are load/store, ADDI instructions.
519
+ unsigned MIFrm = RISCVII::getFormat (MI->getDesc ().TSFlags );
520
+ if (MIFrm != RISCVII::InstFormatI && MIFrm != RISCVII::InstFormatS)
521
+ return false ;
522
+ // We only generate virtual base registers for loads and stores, so
523
+ // return false for everything else.
524
+ if (!MI->mayLoad () && !MI->mayStore ())
525
+ return false ;
526
+
527
+ const MachineFunction &MF = *MI->getMF ();
528
+ const MachineFrameInfo &MFI = MF.getFrameInfo ();
529
+ const RISCVFrameLowering *TFI = getFrameLowering (MF);
530
+ const MachineRegisterInfo &MRI = MF.getRegInfo ();
531
+ unsigned CalleeSavedSize = 0 ;
532
+ Offset += getFrameIndexInstrOffset (MI, FIOperandNum);
533
+
534
+ // Estimate the stack size used to store callee saved registers(
535
+ // excludes reserved registers).
536
+ BitVector ReservedRegs = getReservedRegs (MF);
537
+ for (const MCPhysReg *R = MRI.getCalleeSavedRegs (); MCPhysReg Reg = *R; ++R) {
538
+ if (!ReservedRegs.test (Reg))
539
+ CalleeSavedSize += getSpillSize (*getMinimalPhysRegClass (Reg));
540
+ }
541
+
542
+ int64_t MaxFPOffset = Offset - CalleeSavedSize;
543
+ if (TFI->hasFP (MF) && !shouldRealignStack (MF))
544
+ return !isFrameOffsetLegal (MI, RISCV::X8, MaxFPOffset);
545
+
546
+ // Assume 128 bytes spill slots size to estimate the maximum possible
547
+ // offset relative to the stack pointer.
548
+ // FIXME: The 128 is copied from ARM. We should run some statistics and pick a
549
+ // real one for RISC-V.
550
+ int64_t MaxSPOffset = Offset + 128 ;
551
+ MaxSPOffset += MFI.getLocalFrameSize ();
552
+ return !isFrameOffsetLegal (MI, RISCV::X2, MaxSPOffset);
553
+ }
554
+
555
+ // Determine whether a given base register plus offset immediate is
556
+ // encodable to resolve a frame index.
557
+ bool RISCVRegisterInfo::isFrameOffsetLegal (const MachineInstr *MI,
558
+ Register BaseReg,
559
+ int64_t Offset) const {
560
+ return isInt<12 >(Offset);
561
+ }
562
+
563
+ // Insert defining instruction(s) for a pointer to FrameIdx before
564
+ // insertion point I.
565
+ // Return materialized frame pointer.
566
+ Register RISCVRegisterInfo::materializeFrameBaseRegister (MachineBasicBlock *MBB,
567
+ int FrameIdx,
568
+ int64_t Offset) const {
569
+ MachineBasicBlock::iterator MBBI = MBB->begin ();
570
+ DebugLoc DL;
571
+ if (MBBI != MBB->end ())
572
+ DL = MBBI->getDebugLoc ();
573
+ MachineFunction *MF = MBB->getParent ();
574
+ MachineRegisterInfo &MFI = MF->getRegInfo ();
575
+ const TargetInstrInfo *TII = MF->getSubtarget ().getInstrInfo ();
576
+
577
+ Register BaseReg = MFI.createVirtualRegister (&RISCV::GPRRegClass);
578
+ BuildMI (*MBB, MBBI, DL, TII->get (RISCV::ADDI), BaseReg)
579
+ .addFrameIndex (FrameIdx)
580
+ .addImm (Offset);
581
+ return BaseReg;
582
+ }
583
+
584
+ // Resolve a frame index operand of an instruction to reference the
585
+ // indicated base register plus offset instead.
586
+ void RISCVRegisterInfo::resolveFrameIndex (MachineInstr &MI, Register BaseReg,
587
+ int64_t Offset) const {
588
+ unsigned FIOperandNum = 0 ;
589
+ while (!MI.getOperand (FIOperandNum).isFI ())
590
+ FIOperandNum++;
591
+ assert (FIOperandNum < MI.getNumOperands () &&
592
+ " Instr does not have a FrameIndex operand!" );
593
+ Offset += getFrameIndexInstrOffset (&MI, FIOperandNum);
594
+ // FrameIndex Operands are always represented as a
595
+ // register followed by an immediate.
596
+ MI.getOperand (FIOperandNum).ChangeToRegister (BaseReg, false );
597
+ MI.getOperand (FIOperandNum + 1 ).ChangeToImmediate (Offset);
598
+ }
599
+
600
+ // Get the offset from the referenced frame index in the instruction,
601
+ // if there is one.
602
+ int64_t RISCVRegisterInfo::getFrameIndexInstrOffset (const MachineInstr *MI,
603
+ int Idx) const {
604
+ assert ((RISCVII::getFormat (MI->getDesc ().TSFlags ) == RISCVII::InstFormatI ||
605
+ RISCVII::getFormat (MI->getDesc ().TSFlags ) == RISCVII::InstFormatS) &&
606
+ " The MI must be I or S format." );
607
+ assert (MI->getOperand (Idx).isFI () && " The Idx'th operand of MI is not a "
608
+ " FrameIndex operand" );
609
+ return MI->getOperand (Idx + 1 ).getImm ();
610
+ }
611
+
501
612
Register RISCVRegisterInfo::getFrameRegister (const MachineFunction &MF) const {
502
613
const TargetFrameLowering *TFI = getFrameLowering (MF);
503
614
return TFI->hasFP (MF) ? RISCV::X8 : RISCV::X2;
0 commit comments