blob: b97820383121cfad9fc9d711723530c20066b85d [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===-- 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"
Tom Stellardeba61072014-05-02 15:41:42 +000013#include "SIInstrInfo.h"
Tom Stellardc149dc02013-11-27 21:23:35 +000014#include "SIRegisterInfo.h"
Tom Stellardc5cf2f02014-08-21 20:40:54 +000015#include "llvm/CodeGen/MachineFrameInfo.h"
Tom Stellardc149dc02013-11-27 21:23:35 +000016#include "llvm/CodeGen/MachineRegisterInfo.h"
Tom Stellardeba61072014-05-02 15:41:42 +000017#include "llvm/IR/Function.h"
18#include "llvm/IR/LLVMContext.h"
Tom Stellardc149dc02013-11-27 21:23:35 +000019
20#define MAX_LANES 64
Tom Stellard75aadc22012-12-11 21:25:42 +000021
22using namespace llvm;
23
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000024
25// Pin the vtable to this file.
26void SIMachineFunctionInfo::anchor() {}
27
Tom Stellard75aadc22012-12-11 21:25:42 +000028SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
Vincent Lejeuneace6f732013-04-01 21:47:53 +000029 : AMDGPUMachineFunction(MF),
Tom Stellardc149dc02013-11-27 21:23:35 +000030 PSInputAddr(0),
Tom Stellardb02094e2014-07-21 15:45:01 +000031 NumUserSGPRs(0) { }
Tom Stellardc149dc02013-11-27 21:23:35 +000032
Tom Stellardc5cf2f02014-08-21 20:40:54 +000033/// \brief Returns a register that is not used at any point in the function.
34/// If all registers are used, then this function will return
35// AMDGPU::NoRegister.
36static unsigned findUnusedVGPR(const MachineRegisterInfo &MRI) {
Tom Stellardc149dc02013-11-27 21:23:35 +000037
Tom Stellardc5cf2f02014-08-21 20:40:54 +000038 const TargetRegisterClass *RC = &AMDGPU::VGPR_32RegClass;
39
40 for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end();
41 I != E; ++I) {
42 if (!MRI.isPhysRegUsed(*I))
43 return *I;
44 }
45 return AMDGPU::NoRegister;
46}
47
48SIMachineFunctionInfo::SpilledReg SIMachineFunctionInfo::getSpilledReg(
49 MachineFunction *MF,
50 unsigned FrameIndex,
51 unsigned SubIdx) {
52 const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
53 MachineRegisterInfo &MRI = MF->getRegInfo();
54 int64_t Offset = FrameInfo->getObjectOffset(FrameIndex);
55 Offset += SubIdx * 4;
56
57 unsigned LaneVGPRIdx = Offset / (64 * 4);
58 unsigned Lane = (Offset / 4) % 64;
59
60 struct SpilledReg Spill;
61
62 if (!LaneVGPRs.count(LaneVGPRIdx)) {
63 unsigned LaneVGPR = findUnusedVGPR(MRI);
64 LaneVGPRs[LaneVGPRIdx] = LaneVGPR;
65 MRI.setPhysRegUsed(LaneVGPR);
66
67 // Add this register as live-in to all blocks to avoid machine verifer
68 // complaining about use of an undefined physical register.
69 for (MachineFunction::iterator BI = MF->begin(), BE = MF->end();
70 BI != BE; ++BI) {
71 BI->addLiveIn(LaneVGPR);
72 }
73 }
74
75 Spill.VGPR = LaneVGPRs[LaneVGPRIdx];
76 Spill.Lane = Lane;
77 return Spill;
Tom Stellardc149dc02013-11-27 21:23:35 +000078}