@@ -295,6 +295,113 @@ void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
295
295
}
296
296
}
297
297
298
+ bool RISCVRegisterInfo::requiresVirtualBaseRegisters (
299
+ const MachineFunction &MF) const {
300
+ return true ;
301
+ }
302
+
303
+ // Returns true if the instruction's frame index reference would be better
304
+ // served by a base register other than FP or SP.
305
+ // Used by LocalStackSlotAllocation pass to determine which frame index
306
+ // references it should create new base registers for.
307
+ bool RISCVRegisterInfo::needsFrameBaseReg (MachineInstr *MI,
308
+ int64_t Offset) const {
309
+ unsigned FIOperandNum = 0 ;
310
+ for (; !MI->getOperand (FIOperandNum).isFI (); FIOperandNum++)
311
+ assert (FIOperandNum < MI->getNumOperands () &&
312
+ " Instr doesn't have FrameIndex operand" );
313
+
314
+ // For RISC-V, The machine instructions that include a FrameIndex operand
315
+ // are load/store, ADDI instructions.
316
+ unsigned MIFrm = RISCVII::getFormat (MI->getDesc ().TSFlags );
317
+ if (MIFrm != RISCVII::InstFormatI && MIFrm != RISCVII::InstFormatS)
318
+ return false ;
319
+
320
+ const MachineFunction &MF = *MI->getMF ();
321
+ const MachineFrameInfo &MFI = MF.getFrameInfo ();
322
+ const RISCVFrameLowering *TFI = getFrameLowering (MF);
323
+ const MachineRegisterInfo &MRI = MF.getRegInfo ();
324
+ unsigned CalleeSavedSize = 0 ;
325
+ Offset += getFrameIndexInstrOffset (MI, FIOperandNum);
326
+
327
+ // Estimate the stack size used to store callee saved registers(
328
+ // excludes reserved registers).
329
+ BitVector ReservedRegs = getReservedRegs (MF);
330
+ for (const MCPhysReg *R = MRI.getCalleeSavedRegs (); MCPhysReg Reg = *R; ++R) {
331
+ if (!ReservedRegs.test (Reg))
332
+ CalleeSavedSize += getSpillSize (*getMinimalPhysRegClass (Reg));
333
+ }
334
+
335
+ int64_t MaxFPOffset = Offset - CalleeSavedSize;
336
+ if (TFI->hasFP (MF) && !shouldRealignStack (MF))
337
+ return !isFrameOffsetLegal (MI, RISCV::X8, MaxFPOffset);
338
+
339
+ // Assume 128 bytes spill slots size to estimate the maximum possible
340
+ // offset relative to the stack pointer.
341
+ // FIXME: The 128 is copied from ARM. We should run some statistics and pick a
342
+ // real one for RISC-V.
343
+ int64_t MaxSPOffset = Offset + 128 ;
344
+ MaxSPOffset += MFI.getLocalFrameSize ();
345
+ return !isFrameOffsetLegal (MI, RISCV::X2, MaxSPOffset);
346
+ }
347
+
348
+ // Determine whether a given base register plus offset immediate is
349
+ // encodable to resolve a frame index.
350
+ bool RISCVRegisterInfo::isFrameOffsetLegal (const MachineInstr *MI,
351
+ Register BaseReg,
352
+ int64_t Offset) const {
353
+ return isInt<12 >(Offset);
354
+ }
355
+
356
+ // Insert defining instruction(s) for a pointer to FrameIdx before
357
+ // insertion point I.
358
+ // Return materialized frame pointer.
359
+ Register RISCVRegisterInfo::materializeFrameBaseRegister (MachineBasicBlock *MBB,
360
+ int FrameIdx,
361
+ int64_t Offset) const {
362
+ MachineBasicBlock::iterator MBBI = MBB->begin ();
363
+ DebugLoc DL;
364
+ if (MBBI != MBB->end ())
365
+ DL = MBBI->getDebugLoc ();
366
+ MachineFunction *MF = MBB->getParent ();
367
+ MachineRegisterInfo &MFI = MF->getRegInfo ();
368
+ const TargetInstrInfo *TII = MF->getSubtarget ().getInstrInfo ();
369
+
370
+ Register BaseReg = MFI.createVirtualRegister (&RISCV::GPRRegClass);
371
+ BuildMI (*MBB, MBBI, DL, TII->get (RISCV::ADDI), BaseReg)
372
+ .addFrameIndex (FrameIdx)
373
+ .addImm (Offset);
374
+ return BaseReg;
375
+ }
376
+
377
+ // Resolve a frame index operand of an instruction to reference the
378
+ // indicated base register plus offset instead.
379
+ void RISCVRegisterInfo::resolveFrameIndex (MachineInstr &MI, Register BaseReg,
380
+ int64_t Offset) const {
381
+ unsigned FIOperandNum = 0 ;
382
+ while (!MI.getOperand (FIOperandNum).isFI ())
383
+ FIOperandNum++;
384
+ assert (FIOperandNum < MI.getNumOperands () &&
385
+ " Instr does not have a FrameIndex operand!" );
386
+ Offset += getFrameIndexInstrOffset (&MI, FIOperandNum);
387
+ // FrameIndex Operands are always represented as a
388
+ // register followed by an immediate.
389
+ MI.getOperand (FIOperandNum).ChangeToRegister (BaseReg, false );
390
+ MI.getOperand (FIOperandNum + 1 ).ChangeToImmediate (Offset);
391
+ }
392
+
393
+ // Get the offset from the referenced frame index in the instruction,
394
+ // if there is one.
395
+ int64_t RISCVRegisterInfo::getFrameIndexInstrOffset (const MachineInstr *MI,
396
+ int Idx) const {
397
+ assert ((RISCVII::getFormat (MI->getDesc ().TSFlags ) == RISCVII::InstFormatI ||
398
+ RISCVII::getFormat (MI->getDesc ().TSFlags ) == RISCVII::InstFormatS) &&
399
+ " The MI must be I or S format." );
400
+ assert (MI->getOperand (Idx).isFI () && " The Idx'th operand of MI is not a "
401
+ " FrameIndex operand" );
402
+ return MI->getOperand (Idx + 1 ).getImm ();
403
+ }
404
+
298
405
Register RISCVRegisterInfo::getFrameRegister (const MachineFunction &MF) const {
299
406
const TargetFrameLowering *TFI = getFrameLowering (MF);
300
407
return TFI->hasFP (MF) ? RISCV::X8 : RISCV::X2;
0 commit comments