1223013Sdim//===-- RegisterClassInfo.cpp - Dynamic Register Class Info ---------------===//
2223013Sdim//
3223013Sdim//                     The LLVM Compiler Infrastructure
4223013Sdim//
5223013Sdim// This file is distributed under the University of Illinois Open Source
6223013Sdim// License. See LICENSE.TXT for details.
7223013Sdim//
8223013Sdim//===----------------------------------------------------------------------===//
9223013Sdim//
10223013Sdim// This file implements the RegisterClassInfo class which provides dynamic
11223013Sdim// information about target register classes. Callee saved and reserved
12223013Sdim// registers depends on calling conventions and other dynamic information, so
13223013Sdim// some things cannot be determined statically.
14223013Sdim//
15223013Sdim//===----------------------------------------------------------------------===//
16223013Sdim
17223013Sdim#define DEBUG_TYPE "regalloc"
18243830Sdim#include "llvm/CodeGen/RegisterClassInfo.h"
19223013Sdim#include "llvm/CodeGen/MachineFunction.h"
20243830Sdim#include "llvm/CodeGen/MachineRegisterInfo.h"
21234353Sdim#include "llvm/Support/CommandLine.h"
22223013Sdim#include "llvm/Support/Debug.h"
23223013Sdim#include "llvm/Support/raw_ostream.h"
24249423Sdim#include "llvm/Target/TargetMachine.h"
25223013Sdim
26223013Sdimusing namespace llvm;
27223013Sdim
28234353Sdimstatic cl::opt<unsigned>
29234353SdimStressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"),
30234353Sdim         cl::desc("Limit all regclasses to N registers"));
31234353Sdim
32223013SdimRegisterClassInfo::RegisterClassInfo() : Tag(0), MF(0), TRI(0), CalleeSaved(0)
33223013Sdim{}
34223013Sdim
35223013Sdimvoid RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) {
36223013Sdim  bool Update = false;
37223013Sdim  MF = &mf;
38223013Sdim
39223013Sdim  // Allocate new array the first time we see a new target.
40223013Sdim  if (MF->getTarget().getRegisterInfo() != TRI) {
41223013Sdim    TRI = MF->getTarget().getRegisterInfo();
42223013Sdim    RegClass.reset(new RCInfo[TRI->getNumRegClasses()]);
43263508Sdim    unsigned NumPSets = TRI->getNumRegPressureSets();
44263508Sdim    PSetLimits.reset(new unsigned[NumPSets]);
45263508Sdim    std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0);
46223013Sdim    Update = true;
47223013Sdim  }
48223013Sdim
49223013Sdim  // Does this MF have different CSRs?
50249423Sdim  const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
51223013Sdim  if (Update || CSR != CalleeSaved) {
52223013Sdim    // Build a CSRNum map. Every CSR alias gets an entry pointing to the last
53223013Sdim    // overlapping CSR.
54223013Sdim    CSRNum.clear();
55223013Sdim    CSRNum.resize(TRI->getNumRegs(), 0);
56223013Sdim    for (unsigned N = 0; unsigned Reg = CSR[N]; ++N)
57239462Sdim      for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
58239462Sdim        CSRNum[*AI] = N + 1; // 0 means no CSR, 1 means CalleeSaved[0], ...
59223013Sdim    Update = true;
60223013Sdim  }
61223013Sdim  CalleeSaved = CSR;
62223013Sdim
63223013Sdim  // Different reserved registers?
64243830Sdim  const BitVector &RR = MF->getRegInfo().getReservedRegs();
65243830Sdim  if (Reserved.size() != RR.size() || RR != Reserved) {
66223013Sdim    Update = true;
67243830Sdim    Reserved = RR;
68243830Sdim  }
69223013Sdim
70223013Sdim  // Invalidate cached information from previous function.
71223013Sdim  if (Update)
72223013Sdim    ++Tag;
73223013Sdim}
74223013Sdim
75223013Sdim/// compute - Compute the preferred allocation order for RC with reserved
76223013Sdim/// registers filtered out. Volatile registers come first followed by CSR
77223013Sdim/// aliases ordered according to the CSR order specified by the target.
78223013Sdimvoid RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
79223013Sdim  RCInfo &RCI = RegClass[RC->getID()];
80223013Sdim
81223013Sdim  // Raw register count, including all reserved regs.
82223013Sdim  unsigned NumRegs = RC->getNumRegs();
83223013Sdim
84223013Sdim  if (!RCI.Order)
85249423Sdim    RCI.Order.reset(new MCPhysReg[NumRegs]);
86223013Sdim
87223013Sdim  unsigned N = 0;
88249423Sdim  SmallVector<MCPhysReg, 16> CSRAlias;
89249423Sdim  unsigned MinCost = 0xff;
90249423Sdim  unsigned LastCost = ~0u;
91249423Sdim  unsigned LastCostChange = 0;
92223013Sdim
93223013Sdim  // FIXME: Once targets reserve registers instead of removing them from the
94223013Sdim  // allocation order, we can simply use begin/end here.
95249423Sdim  ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF);
96224145Sdim  for (unsigned i = 0; i != RawOrder.size(); ++i) {
97224145Sdim    unsigned PhysReg = RawOrder[i];
98223013Sdim    // Remove reserved registers from the allocation order.
99223013Sdim    if (Reserved.test(PhysReg))
100223013Sdim      continue;
101249423Sdim    unsigned Cost = TRI->getCostPerUse(PhysReg);
102249423Sdim    MinCost = std::min(MinCost, Cost);
103249423Sdim
104223013Sdim    if (CSRNum[PhysReg])
105223013Sdim      // PhysReg aliases a CSR, save it for later.
106223013Sdim      CSRAlias.push_back(PhysReg);
107249423Sdim    else {
108249423Sdim      if (Cost != LastCost)
109249423Sdim        LastCostChange = N;
110223013Sdim      RCI.Order[N++] = PhysReg;
111249423Sdim      LastCost = Cost;
112249423Sdim    }
113223013Sdim  }
114223013Sdim  RCI.NumRegs = N + CSRAlias.size();
115223013Sdim  assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
116223013Sdim
117223013Sdim  // CSR aliases go after the volatile registers, preserve the target's order.
118249423Sdim  for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) {
119249423Sdim    unsigned PhysReg = CSRAlias[i];
120249423Sdim    unsigned Cost = TRI->getCostPerUse(PhysReg);
121249423Sdim    if (Cost != LastCost)
122249423Sdim      LastCostChange = N;
123249423Sdim    RCI.Order[N++] = PhysReg;
124249423Sdim    LastCost = Cost;
125249423Sdim  }
126223013Sdim
127234353Sdim  // Register allocator stress test.  Clip register class to N registers.
128234353Sdim  if (StressRA && RCI.NumRegs > StressRA)
129234353Sdim    RCI.NumRegs = StressRA;
130234353Sdim
131226633Sdim  // Check if RC is a proper sub-class.
132226633Sdim  if (const TargetRegisterClass *Super = TRI->getLargestLegalSuperClass(RC))
133226633Sdim    if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
134226633Sdim      RCI.ProperSubClass = true;
135226633Sdim
136249423Sdim  RCI.MinCost = uint8_t(MinCost);
137249423Sdim  RCI.LastCostChange = LastCostChange;
138249423Sdim
139223013Sdim  DEBUG({
140223013Sdim    dbgs() << "AllocationOrder(" << RC->getName() << ") = [";
141224145Sdim    for (unsigned I = 0; I != RCI.NumRegs; ++I)
142223013Sdim      dbgs() << ' ' << PrintReg(RCI.Order[I], TRI);
143226633Sdim    dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");
144223013Sdim  });
145223013Sdim
146223013Sdim  // RCI is now up-to-date.
147223013Sdim  RCI.Tag = Tag;
148223013Sdim}
149223013Sdim
150263508Sdim/// This is not accurate because two overlapping register sets may have some
151263508Sdim/// nonoverlapping reserved registers. However, computing the allocation order
152263508Sdim/// for all register classes would be too expensive.
153263508Sdimunsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const {
154263508Sdim  const TargetRegisterClass *RC = 0;
155263508Sdim  unsigned NumRCUnits = 0;
156263508Sdim  for (TargetRegisterInfo::regclass_iterator
157263508Sdim         RI = TRI->regclass_begin(), RE = TRI->regclass_end(); RI != RE; ++RI) {
158263508Sdim    const int *PSetID = TRI->getRegClassPressureSets(*RI);
159263508Sdim    for (; *PSetID != -1; ++PSetID) {
160263508Sdim      if ((unsigned)*PSetID == Idx)
161263508Sdim        break;
162263508Sdim    }
163263508Sdim    if (*PSetID == -1)
164263508Sdim      continue;
165263508Sdim
166263508Sdim    // Found a register class that counts against this pressure set.
167263508Sdim    // For efficiency, only compute the set order for the largest set.
168263508Sdim    unsigned NUnits = TRI->getRegClassWeight(*RI).WeightLimit;
169263508Sdim    if (!RC || NUnits > NumRCUnits) {
170263508Sdim      RC = *RI;
171263508Sdim      NumRCUnits = NUnits;
172263508Sdim    }
173263508Sdim  }
174263508Sdim  compute(RC);
175263508Sdim  unsigned NReserved = RC->getNumRegs() - getNumAllocatableRegs(RC);
176263508Sdim  return TRI->getRegPressureSetLimit(Idx)
177263508Sdim    - TRI->getRegClassWeight(RC).RegWeight * NReserved;
178263508Sdim}
179