SIMachineFunctionInfo.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1//===-- SIMachineFunctionInfo.cpp - SI Machine Function Info -------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8/// \file
9//===----------------------------------------------------------------------===//
10
11
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"
18
19#define MAX_LANES 64
20
21using namespace llvm;
22
23
24// Pin the vtable to this file.
25void SIMachineFunctionInfo::anchor() {}
26
27SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
28  : AMDGPUMachineFunction(MF),
29    PSInputAddr(0),
30    SpillTracker() { }
31
32static unsigned createLaneVGPR(MachineRegisterInfo &MRI, MachineFunction *MF) {
33  unsigned VGPR = MRI.createVirtualRegister(&AMDGPU::VReg_32RegClass);
34
35  // We need to add this register as live out for the function, in order to
36  // have the live range calculated directly.
37  //
38  // When register spilling begins, we have already calculated the live
39  // live intervals for all the registers.  Since we are spilling SGPRs to
40  // VGPRs, we need to update the Lane VGPR's live interval every time we
41  // spill or restore a register.
42  //
43  // Unfortunately, there is no good way to update the live interval as
44  // the TargetInstrInfo callbacks for spilling and restoring don't give
45  // us access to the live interval information.
46  //
47  // We are lucky, though, because the InlineSpiller calls
48  // LiveRangeEdit::calculateRegClassAndHint() which iterates through
49  // all the new register that have been created when restoring a register
50  // and calls LiveIntervals::getInterval(), which creates and computes
51  // the live interval for the newly created register.  However, once this
52  // live intervals is created, it doesn't change and since we usually reuse
53  // the Lane VGPR multiple times, this means any uses after the first aren't
54  // added to the live interval.
55  //
56  // To work around this, we add Lane VGPRs to the functions live out list,
57  // so that we can guarantee its live range will cover all of its uses.
58
59  for (MachineBasicBlock &MBB : *MF) {
60    if (MBB.back().getOpcode() == AMDGPU::S_ENDPGM) {
61      MBB.back().addOperand(*MF, MachineOperand::CreateReg(VGPR, false, true));
62      return VGPR;
63    }
64  }
65  MF->getFunction()->getContext().emitError(
66      "Could not found S_ENGPGM instrtuction.");
67  return VGPR;
68}
69
70unsigned SIMachineFunctionInfo::RegSpillTracker::reserveLanes(
71    MachineRegisterInfo &MRI, MachineFunction *MF, unsigned NumRegs) {
72  unsigned StartLane = CurrentLane;
73  CurrentLane += NumRegs;
74  if (!LaneVGPR) {
75    LaneVGPR = createLaneVGPR(MRI, MF);
76  } else {
77    if (CurrentLane >= MAX_LANES) {
78      StartLane = CurrentLane = 0;
79      LaneVGPR = createLaneVGPR(MRI, MF);
80    }
81  }
82  return StartLane;
83}
84
85void SIMachineFunctionInfo::RegSpillTracker::addSpilledReg(unsigned FrameIndex,
86                                                           unsigned Reg,
87                                                           int Lane) {
88  SpilledRegisters[FrameIndex] = SpilledReg(Reg, Lane);
89}
90
91const SIMachineFunctionInfo::SpilledReg&
92SIMachineFunctionInfo::RegSpillTracker::getSpilledReg(unsigned FrameIndex) {
93  return SpilledRegisters[FrameIndex];
94}
95