Merge alignment of common GlobalValue.
[oota-llvm.git] / lib / Target / R600 / SIMachineFunctionInfo.cpp
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/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineRegisterInfo.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/LLVMContext.h"
19
20 #define MAX_LANES 64
21
22 using namespace llvm;
23
24
25 // Pin the vtable to this file.
26 void SIMachineFunctionInfo::anchor() {}
27
28 SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
29   : AMDGPUMachineFunction(MF),
30     PSInputAddr(0),
31     NumUserSGPRs(0) { }
32
33 /// \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.
36 static unsigned findUnusedVGPR(const MachineRegisterInfo &MRI) {
37
38   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
48 SIMachineFunctionInfo::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;
78 }