1 //===-- SIMachineFunctionInfo.cpp - SI Machine Function Info -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
12 #include "SIMachineFunctionInfo.h"
13 #include "SIInstrInfo.h"
14 #include "SIRegisterInfo.h"
15 #include "llvm/CodeGen/MachineRegisterInfo.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/LLVMContext.h"
24 // Pin the vtable to this file.
25 void SIMachineFunctionInfo::anchor() {}
27 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
28 : AMDGPUMachineFunction(MF),
33 static unsigned createLaneVGPR(MachineRegisterInfo &MRI, MachineFunction *MF) {
34 unsigned VGPR = MRI.createVirtualRegister(&AMDGPU::VReg_32RegClass);
36 // We need to add this register as live out for the function, in order to
37 // have the live range calculated directly.
39 // When register spilling begins, we have already calculated the live
40 // live intervals for all the registers. Since we are spilling SGPRs to
41 // VGPRs, we need to update the Lane VGPR's live interval every time we
42 // spill or restore a register.
44 // Unfortunately, there is no good way to update the live interval as
45 // the TargetInstrInfo callbacks for spilling and restoring don't give
46 // us access to the live interval information.
48 // We are lucky, though, because the InlineSpiller calls
49 // LiveRangeEdit::calculateRegClassAndHint() which iterates through
50 // all the new register that have been created when restoring a register
51 // and calls LiveIntervals::getInterval(), which creates and computes
52 // the live interval for the newly created register. However, once this
53 // live intervals is created, it doesn't change and since we usually reuse
54 // the Lane VGPR multiple times, this means any uses after the first aren't
55 // added to the live interval.
57 // To work around this, we add Lane VGPRs to the functions live out list,
58 // so that we can guarantee its live range will cover all of its uses.
60 for (MachineBasicBlock &MBB : *MF) {
61 if (MBB.back().getOpcode() == AMDGPU::S_ENDPGM) {
62 MBB.back().addOperand(*MF, MachineOperand::CreateReg(VGPR, false, true));
67 LLVMContext &Ctx = MF->getFunction()->getContext();
68 Ctx.emitError("Could not find S_ENDPGM instruction.");
73 unsigned SIMachineFunctionInfo::RegSpillTracker::reserveLanes(
74 MachineRegisterInfo &MRI, MachineFunction *MF, unsigned NumRegs) {
75 unsigned StartLane = CurrentLane;
76 CurrentLane += NumRegs;
78 LaneVGPR = createLaneVGPR(MRI, MF);
80 if (CurrentLane >= MAX_LANES) {
81 StartLane = CurrentLane = 0;
82 LaneVGPR = createLaneVGPR(MRI, MF);
88 void SIMachineFunctionInfo::RegSpillTracker::addSpilledReg(unsigned FrameIndex,
91 SpilledRegisters[FrameIndex] = SpilledReg(Reg, Lane);
94 const SIMachineFunctionInfo::SpilledReg&
95 SIMachineFunctionInfo::RegSpillTracker::getSpilledReg(unsigned FrameIndex) {
96 return SpilledRegisters[FrameIndex];