[RISCV] Add FrameSetup/FrameDestroy flag to prologue/epilog instructions.

Differential Revision: https://reviews.llvm.org/D105086
This commit is contained in:
Hsiangkai Wang 2021-06-29 15:22:18 +08:00
parent edffb97d1e
commit 4b2dd318dd
8 changed files with 102 additions and 75 deletions

View File

@ -67,11 +67,13 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
.addReg(RAReg)
.addReg(SCSPReg)
.addImm(0);
.addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
.addReg(SCSPReg, RegState::Define)
.addReg(SCSPReg)
.addImm(SlotSize);
.addImm(SlotSize)
.setMIFlag(MachineInstr::FrameSetup);
}
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
@ -115,11 +117,13 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
BuildMI(MBB, MI, DL, TII->get(IsRV64 ? RISCV::LD : RISCV::LW))
.addReg(RAReg, RegState::Define)
.addReg(SCSPReg)
.addImm(-SlotSize);
.addImm(-SlotSize)
.setMIFlag(MachineInstr::FrameDestroy);
BuildMI(MBB, MI, DL, TII->get(RISCV::ADDI))
.addReg(SCSPReg, RegState::Define)
.addReg(SCSPReg)
.addImm(-SlotSize);
.addImm(-SlotSize)
.setMIFlag(MachineInstr::FrameDestroy);
}
// Get the ID of the libcall used for spilling and restoring callee saved
@ -306,8 +310,8 @@ getNonLibcallCSI(const MachineFunction &MF,
void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
const DebugLoc &DL,
int64_t Amount) const {
const DebugLoc &DL, int64_t Amount,
MachineInstr::MIFlag Flag) const {
assert(Amount != 0 && "Did not need to adjust stack pointer for RVV.");
const RISCVInstrInfo *TII = STI.getInstrInfo();
@ -317,14 +321,14 @@ void RISCVFrameLowering::adjustStackForRVV(MachineFunction &MF,
Amount = -Amount;
Opc = RISCV::SUB;
}
// 1. Multiply the number of v-slots to the length of registers
Register FactorRegister =
TII->getVLENFactoredAmount(MF, MBB, MBBI, DL, Amount);
TII->getVLENFactoredAmount(MF, MBB, MBBI, DL, Amount, Flag);
// 2. SP = SP - RVV stack size
BuildMI(MBB, MBBI, DL, TII->get(Opc), SPReg)
.addReg(SPReg)
.addReg(FactorRegister, RegState::Kill);
.addReg(FactorRegister, RegState::Kill)
.setMIFlag(Flag);
}
void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
@ -414,7 +418,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
unsigned CFIIndex = MF.addFrameInst(
MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
const auto &CSI = MFI.getCalleeSavedInfo();
@ -442,7 +447,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
nullptr, RI->getDwarfRegNum(Reg, true), Offset));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
}
// Generate new FP.
@ -459,7 +465,8 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
nullptr, RI->getDwarfRegNum(FPReg, true), RVFI->getVarArgsSaveSize()));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
}
// Emit the second SP adjustment after saving callee saved registers.
@ -477,12 +484,14 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
unsigned CFIIndex = MF.addFrameInst(
MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex);
.addCFIIndex(CFIIndex)
.setMIFlag(MachineInstr::FrameSetup);
}
}
if (RVVStackSize)
adjustStackForRVV(MF, MBB, MBBI, DL, -RVVStackSize);
adjustStackForRVV(MF, MBB, MBBI, DL, -RVVStackSize,
MachineInstr::FrameSetup);
if (hasFP(MF)) {
// Realign Stack
@ -494,24 +503,30 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
if (isInt<12>(-(int)MaxAlignment.value())) {
BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg)
.addReg(SPReg)
.addImm(-(int)MaxAlignment.value());
.addImm(-(int)MaxAlignment.value())
.setMIFlag(MachineInstr::FrameSetup);
} else {
unsigned ShiftAmount = Log2(MaxAlignment);
Register VR =
MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR)
.addReg(SPReg)
.addImm(ShiftAmount);
.addImm(ShiftAmount)
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg)
.addReg(VR)
.addImm(ShiftAmount);
.addImm(ShiftAmount)
.setMIFlag(MachineInstr::FrameSetup);
}
// FP will be used to restore the frame in the epilogue, so we need
// another base register BP to record SP after re-alignment. SP will
// track the current stack after allocating variable sized objects.
if (hasBP(MF)) {
// move BP, SP
TII->copyPhysReg(MBB, MBBI, DL, BPReg, SPReg, false);
BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), BPReg)
.addReg(SPReg)
.addImm(0)
.setMIFlag(MachineInstr::FrameSetup);
}
}
}
@ -575,7 +590,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
MachineInstr::FrameDestroy);
} else {
if (RVVStackSize)
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize);
adjustStackForRVV(MF, MBB, LastFrameDestroy, DL, RVVStackSize,
MachineInstr::FrameDestroy);
}
uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);

View File

@ -78,7 +78,7 @@ private:
int64_t Val, MachineInstr::MIFlag Flag) const;
void adjustStackForRVV(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, const DebugLoc &DL,
int64_t Amount) const;
int64_t Amount, MachineInstr::MIFlag Flag) const;
int64_t assignRVVStackObjectOffsets(MachineFrameInfo &MFI) const;
};
}

View File

@ -1467,7 +1467,8 @@ Register RISCVInstrInfo::getVLENFactoredAmount(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator II,
const DebugLoc &DL,
int64_t Amount) const {
int64_t Amount,
MachineInstr::MIFlag Flag) const {
assert(Amount > 0 && "There is no need to get VLEN scaled value.");
assert(Amount % 8 == 0 &&
"Reserve the stack by the multiple of one vector size.");
@ -1477,7 +1478,8 @@ Register RISCVInstrInfo::getVLENFactoredAmount(MachineFunction &MF,
int64_t NumOfVReg = Amount / 8;
Register VL = MRI.createVirtualRegister(&RISCV::GPRRegClass);
BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL);
BuildMI(MBB, II, DL, TII->get(RISCV::PseudoReadVLENB), VL)
.setMIFlag(Flag);
assert(isInt<32>(NumOfVReg) &&
"Expect the number of vector registers within 32-bits.");
if (isPowerOf2_32(NumOfVReg)) {
@ -1486,40 +1488,48 @@ Register RISCVInstrInfo::getVLENFactoredAmount(MachineFunction &MF,
return VL;
BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), VL)
.addReg(VL, RegState::Kill)
.addImm(ShiftAmount);
.addImm(ShiftAmount)
.setMIFlag(Flag);
} else if (isPowerOf2_32(NumOfVReg - 1)) {
Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
uint32_t ShiftAmount = Log2_32(NumOfVReg - 1);
BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), ScaledRegister)
.addReg(VL)
.addImm(ShiftAmount);
.addImm(ShiftAmount)
.setMIFlag(Flag);
BuildMI(MBB, II, DL, TII->get(RISCV::ADD), VL)
.addReg(ScaledRegister, RegState::Kill)
.addReg(VL, RegState::Kill);
.addReg(VL, RegState::Kill)
.setMIFlag(Flag);
} else if (isPowerOf2_32(NumOfVReg + 1)) {
Register ScaledRegister = MRI.createVirtualRegister(&RISCV::GPRRegClass);
uint32_t ShiftAmount = Log2_32(NumOfVReg + 1);
BuildMI(MBB, II, DL, TII->get(RISCV::SLLI), ScaledRegister)
.addReg(VL)
.addImm(ShiftAmount);
.addImm(ShiftAmount)
.setMIFlag(Flag);
BuildMI(MBB, II, DL, TII->get(RISCV::SUB), VL)
.addReg(ScaledRegister, RegState::Kill)
.addReg(VL, RegState::Kill);
.addReg(VL, RegState::Kill)
.setMIFlag(Flag);
} else {
Register N = MRI.createVirtualRegister(&RISCV::GPRRegClass);
if (!isInt<12>(NumOfVReg))
movImm(MBB, II, DL, N, NumOfVReg);
else
else {
BuildMI(MBB, II, DL, TII->get(RISCV::ADDI), N)
.addReg(RISCV::X0)
.addImm(NumOfVReg);
.addImm(NumOfVReg)
.setMIFlag(Flag);
}
if (!MF.getSubtarget<RISCVSubtarget>().hasStdExtM())
MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
MF.getFunction(),
"M-extension must be enabled to calculate the vscaled size/offset."});
BuildMI(MBB, II, DL, TII->get(RISCV::MUL), VL)
.addReg(VL, RegState::Kill)
.addReg(N, RegState::Kill);
.addReg(N, RegState::Kill)
.setMIFlag(Flag);
}
return VL;

View File

@ -147,9 +147,10 @@ public:
MachineInstr &MI,
LiveVariables *LV) const override;
Register getVLENFactoredAmount(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator II,
const DebugLoc &DL, int64_t Amount) const;
Register getVLENFactoredAmount(
MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator II, const DebugLoc &DL, int64_t Amount,
MachineInstr::MIFlag Flag = MachineInstr::NoFlags) const;
// Returns true if the given MI is an RVV instruction opcode for which we may
// expect to see a FrameIndex operand. When CheckFIs is true, the instruction

View File

@ -28,16 +28,16 @@ body: |
; CHECK-LABEL: name: add_scalable_offset
; CHECK: liveins: $x10, $x11, $x1
; CHECK: $x2 = frame-setup ADDI $x2, -2032
; CHECK: CFI_INSTRUCTION def_cfa_offset 2032
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 2032
; CHECK: SD killed $x1, $x2, 2024 :: (store (s64) into %stack.3)
; CHECK: SD killed $x8, $x2, 2016 :: (store (s64) into %stack.4)
; CHECK: CFI_INSTRUCTION offset $x1, -8
; CHECK: CFI_INSTRUCTION offset $x8, -16
; CHECK: frame-setup CFI_INSTRUCTION offset $x1, -8
; CHECK: frame-setup CFI_INSTRUCTION offset $x8, -16
; CHECK: $x8 = frame-setup ADDI $x2, 2032
; CHECK: CFI_INSTRUCTION def_cfa $x8, 0
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $x8, 0
; CHECK: $x2 = frame-setup ADDI $x2, -240
; CHECK: $x12 = PseudoReadVLENB
; CHECK: $x2 = SUB $x2, killed $x12
; CHECK: $x12 = frame-setup PseudoReadVLENB
; CHECK: $x2 = frame-setup SUB $x2, killed $x12
; CHECK: dead $x0 = PseudoVSETVLI killed renamable $x11, 88, implicit-def $vl, implicit-def $vtype
; CHECK: renamable $v25 = PseudoVLE64_V_M1 killed renamable $x10, $noreg, 6, implicit $vl, implicit $vtype :: (load unknown-size from %ir.pa, align 8)
; CHECK: $x11 = PseudoReadVLENB
@ -46,8 +46,8 @@ body: |
; CHECK: $x10 = ADD $x8, killed $x10
; CHECK: $x10 = SUB killed $x10, killed $x11
; CHECK: VS1R_V killed renamable $v25, killed renamable $x10
; CHECK: $x10 = PseudoReadVLENB
; CHECK: $x2 = ADD $x2, killed $x10
; CHECK: $x10 = frame-destroy PseudoReadVLENB
; CHECK: $x2 = frame-destroy ADD $x2, killed $x10
; CHECK: $x2 = frame-destroy ADDI $x2, 240
; CHECK: $x8 = LD $x2, 2016 :: (load (s64) from %stack.4)
; CHECK: $x1 = LD $x2, 2024 :: (load (s64) from %stack.3)

View File

@ -53,7 +53,7 @@ body: |
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK: liveins: $x12, $x1, $x9, $x18, $x19, $x20, $x21, $x22, $x23, $x24, $x25, $x26, $x27
; CHECK: $x2 = frame-setup ADDI $x2, -2032
; CHECK: CFI_INSTRUCTION def_cfa_offset 2032
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 2032
; CHECK: SD killed $x1, $x2, 2024 :: (store (s64) into %stack.3)
; CHECK: SD killed $x8, $x2, 2016 :: (store (s64) into %stack.4)
; CHECK: SD killed $x9, $x2, 2008 :: (store (s64) into %stack.5)
@ -67,27 +67,27 @@ body: |
; CHECK: SD killed $x25, $x2, 1944 :: (store (s64) into %stack.13)
; CHECK: SD killed $x26, $x2, 1936 :: (store (s64) into %stack.14)
; CHECK: SD killed $x27, $x2, 1928 :: (store (s64) into %stack.15)
; CHECK: CFI_INSTRUCTION offset $x1, -8
; CHECK: CFI_INSTRUCTION offset $x8, -16
; CHECK: CFI_INSTRUCTION offset $x9, -24
; CHECK: CFI_INSTRUCTION offset $x18, -32
; CHECK: CFI_INSTRUCTION offset $x19, -40
; CHECK: CFI_INSTRUCTION offset $x20, -48
; CHECK: CFI_INSTRUCTION offset $x21, -56
; CHECK: CFI_INSTRUCTION offset $x22, -64
; CHECK: CFI_INSTRUCTION offset $x23, -72
; CHECK: CFI_INSTRUCTION offset $x24, -80
; CHECK: CFI_INSTRUCTION offset $x25, -88
; CHECK: CFI_INSTRUCTION offset $x26, -96
; CHECK: CFI_INSTRUCTION offset $x27, -104
; CHECK: frame-setup CFI_INSTRUCTION offset $x1, -8
; CHECK: frame-setup CFI_INSTRUCTION offset $x8, -16
; CHECK: frame-setup CFI_INSTRUCTION offset $x9, -24
; CHECK: frame-setup CFI_INSTRUCTION offset $x18, -32
; CHECK: frame-setup CFI_INSTRUCTION offset $x19, -40
; CHECK: frame-setup CFI_INSTRUCTION offset $x20, -48
; CHECK: frame-setup CFI_INSTRUCTION offset $x21, -56
; CHECK: frame-setup CFI_INSTRUCTION offset $x22, -64
; CHECK: frame-setup CFI_INSTRUCTION offset $x23, -72
; CHECK: frame-setup CFI_INSTRUCTION offset $x24, -80
; CHECK: frame-setup CFI_INSTRUCTION offset $x25, -88
; CHECK: frame-setup CFI_INSTRUCTION offset $x26, -96
; CHECK: frame-setup CFI_INSTRUCTION offset $x27, -104
; CHECK: $x8 = frame-setup ADDI $x2, 2032
; CHECK: CFI_INSTRUCTION def_cfa $x8, 0
; CHECK: frame-setup CFI_INSTRUCTION def_cfa $x8, 0
; CHECK: $x2 = frame-setup ADDI $x2, -272
; CHECK: $x10 = PseudoReadVLENB
; CHECK: $x11 = ADDI $x0, 51
; CHECK: $x10 = MUL killed $x10, killed $x11
; CHECK: $x2 = SUB $x2, killed $x10
; CHECK: $x2 = ANDI $x2, -128
; CHECK: $x10 = frame-setup PseudoReadVLENB
; CHECK: $x11 = frame-setup ADDI $x0, 51
; CHECK: $x10 = frame-setup MUL killed $x10, killed $x11
; CHECK: $x2 = frame-setup SUB $x2, killed $x10
; CHECK: $x2 = frame-setup ANDI $x2, -128
; CHECK: dead renamable $x15 = PseudoVSETIVLI 1, 72, implicit-def $vl, implicit-def $vtype
; CHECK: renamable $v25 = PseudoVMV_V_X_M1 killed renamable $x12, $noreg, 16, implicit $vl, implicit $vtype
; CHECK: $x11 = PseudoReadVLENB

View File

@ -25,14 +25,14 @@ body: |
; CHECK-LABEL: name: foo
; CHECK: bb.0:
; CHECK: successors: %bb.1(0x80000000)
; CHECK: CFI_INSTRUCTION def_cfa_offset 0
; CHECK: $x10 = PseudoReadVLENB
; CHECK: $x10 = SLLI killed $x10, 1
; CHECK: $x2 = SUB $x2, killed $x10
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 0
; CHECK: $x10 = frame-setup PseudoReadVLENB
; CHECK: $x10 = frame-setup SLLI killed $x10, 1
; CHECK: $x2 = frame-setup SUB $x2, killed $x10
; CHECK: bb.1:
; CHECK: $x10 = PseudoReadVLENB
; CHECK: $x10 = SLLI killed $x10, 1
; CHECK: $x2 = ADD $x2, killed $x10
; CHECK: $x10 = frame-destroy PseudoReadVLENB
; CHECK: $x10 = frame-destroy SLLI killed $x10, 1
; CHECK: $x2 = frame-destroy ADD $x2, killed $x10
; CHECK: PseudoRET
bb.0:
bb.1:

View File

@ -21,10 +21,10 @@ body: |
; CHECK-LABEL: name: zvlsseg_spill
; CHECK: liveins: $x10, $x11
; CHECK: $x2 = frame-setup ADDI $x2, -16
; CHECK: CFI_INSTRUCTION def_cfa_offset 16
; CHECK: $x12 = PseudoReadVLENB
; CHECK: $x12 = SLLI killed $x12, 3
; CHECK: $x2 = SUB $x2, killed $x12
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 16
; CHECK: $x12 = frame-setup PseudoReadVLENB
; CHECK: $x12 = frame-setup SLLI killed $x12, 3
; CHECK: $x2 = frame-setup SUB $x2, killed $x12
; CHECK: dead $x0 = PseudoVSETVLI killed renamable $x11, 88, implicit-def $vl, implicit-def $vtype
; CHECK: $v0_v1_v2_v3_v4_v5_v6 = PseudoVLSEG7E64_V_M1 renamable $x10, $noreg, 6, implicit $vl, implicit $vtype
; CHECK: $x11 = ADDI $x2, 16
@ -34,9 +34,9 @@ body: |
; CHECK: $x12 = PseudoReadVLENB
; CHECK: dead renamable $v7_v8_v9_v10_v11_v12_v13 = PseudoVRELOAD7_M1 killed $x11, killed $x12, implicit-def $v8
; CHECK: VS1R_V killed $v8, killed renamable $x10
; CHECK: $x10 = PseudoReadVLENB
; CHECK: $x10 = SLLI killed $x10, 3
; CHECK: $x2 = ADD $x2, killed $x10
; CHECK: $x10 = frame-destroy PseudoReadVLENB
; CHECK: $x10 = frame-destroy SLLI killed $x10, 3
; CHECK: $x2 = frame-destroy ADD $x2, killed $x10
; CHECK: $x2 = frame-destroy ADDI $x2, 16
; CHECK: PseudoRET
%0:gpr = COPY $x10