LLVM  4.0.0
HexagonBlockRanges.cpp
Go to the documentation of this file.
1 //===--- HexagonBlockRanges.cpp -------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 
10 #define DEBUG_TYPE "hbr"
11 
12 #include "HexagonBlockRanges.h"
13 #include "HexagonInstrInfo.h"
14 #include "HexagonSubtarget.h"
15 #include "llvm/ADT/BitVector.h"
16 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/Support/Debug.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <iterator>
28 #include <map>
29 
30 using namespace llvm;
31 
33  // If A contains start(), or "this" contains A.start(), then overlap.
34  IndexType S = start(), E = end(), AS = A.start(), AE = A.end();
35  if (AS == S)
36  return true;
37  bool SbAE = (S < AE) || (S == AE && A.TiedEnd); // S-before-AE.
38  bool ASbE = (AS < E) || (AS == E && TiedEnd); // AS-before-E.
39  if ((AS < S && SbAE) || (S < AS && ASbE))
40  return true;
41  // Otherwise no overlap.
42  return false;
43 }
44 
46  if (start() <= A.start()) {
47  // Treat "None" in the range end as equal to the range start.
48  IndexType E = (end() != IndexType::None) ? end() : start();
49  IndexType AE = (A.end() != IndexType::None) ? A.end() : A.start();
50  if (AE <= E)
51  return true;
52  }
53  return false;
54 }
55 
57  // Allow merging adjacent ranges.
58  assert(end() == A.start() || overlaps(A));
59  IndexType AS = A.start(), AE = A.end();
60  if (AS < start() || start() == IndexType::None)
61  setStart(AS);
62  if (end() < AE || end() == IndexType::None) {
63  setEnd(AE);
64  TiedEnd = A.TiedEnd;
65  } else {
66  if (end() == AE)
67  TiedEnd |= A.TiedEnd;
68  }
69  if (A.Fixed)
70  Fixed = true;
71 }
72 
74  for (auto &R : RL)
75  if (!is_contained(*this, R))
76  push_back(R);
77 }
78 
79 // Merge all overlapping ranges in the list, so that all that remains
80 // is a list of disjoint ranges.
81 void HexagonBlockRanges::RangeList::unionize(bool MergeAdjacent) {
82  if (empty())
83  return;
84 
85  std::sort(begin(), end());
86  iterator Iter = begin();
87 
88  while (Iter != end()-1) {
89  iterator Next = std::next(Iter);
90  // If MergeAdjacent is true, merge ranges A and B, where A.end == B.start.
91  // This allows merging dead ranges, but is not valid for live ranges.
92  bool Merge = MergeAdjacent && (Iter->end() == Next->start());
93  if (Merge || Iter->overlaps(*Next)) {
94  Iter->merge(*Next);
95  erase(Next);
96  continue;
97  }
98  ++Iter;
99  }
100 }
101 
102 // Compute a range A-B and add it to the list.
103 void HexagonBlockRanges::RangeList::addsub(const IndexRange &A,
104  const IndexRange &B) {
105  // Exclusion of non-overlapping ranges makes some checks simpler
106  // later in this function.
107  if (!A.overlaps(B)) {
108  // A - B = A.
109  add(A);
110  return;
111  }
112 
113  IndexType AS = A.start(), AE = A.end();
114  IndexType BS = B.start(), BE = B.end();
115 
116  // If AE is None, then A is included in B, since A and B overlap.
117  // The result of subtraction if empty, so just return.
118  if (AE == IndexType::None)
119  return;
120 
121  if (AS < BS) {
122  // A starts before B.
123  // AE cannot be None since A and B overlap.
124  assert(AE != IndexType::None);
125  // Add the part of A that extends on the "less" side of B.
126  add(AS, BS, A.Fixed, false);
127  }
128 
129  if (BE < AE) {
130  // BE cannot be Exit here.
131  if (BE == IndexType::None)
132  add(BS, AE, A.Fixed, false);
133  else
134  add(BE, AE, A.Fixed, false);
135  }
136 }
137 
138 // Subtract a given range from each element in the list.
140  // Cannot assume that the list is unionized (i.e. contains only non-
141  // overlapping ranges.
142  RangeList T;
143  for (iterator Next, I = begin(); I != end(); I = Next) {
144  IndexRange &Rg = *I;
145  if (Rg.overlaps(Range)) {
146  T.addsub(Rg, Range);
147  Next = this->erase(I);
148  } else {
149  Next = std::next(I);
150  }
151  }
152  include(T);
153 }
154 
156  : Block(B) {
158  First = Idx;
159  for (auto &In : B) {
160  if (In.isDebugValue())
161  continue;
162  assert(getIndex(&In) == IndexType::None && "Instruction already in map");
163  Map.insert(std::make_pair(Idx, &In));
164  ++Idx;
165  }
166  Last = B.empty() ? IndexType::None : unsigned(Idx)-1;
167 }
168 
170  auto F = Map.find(Idx);
171  return (F != Map.end()) ? F->second : nullptr;
172 }
173 
175  MachineInstr *MI) const {
176  for (auto &I : Map)
177  if (I.second == MI)
178  return I.first;
179  return IndexType::None;
180 }
181 
183  IndexType Idx) const {
184  assert (Idx != IndexType::None);
185  if (Idx == IndexType::Entry)
186  return IndexType::None;
187  if (Idx == IndexType::Exit)
188  return Last;
189  if (Idx == First)
190  return IndexType::Entry;
191  return unsigned(Idx)-1;
192 }
193 
195  IndexType Idx) const {
196  assert (Idx != IndexType::None);
197  if (Idx == IndexType::Entry)
198  return IndexType::First;
199  if (Idx == IndexType::Exit || Idx == Last)
200  return IndexType::None;
201  return unsigned(Idx)+1;
202 }
203 
205  MachineInstr *NewMI) {
206  for (auto &I : Map) {
207  if (I.second != OldMI)
208  continue;
209  if (NewMI != nullptr)
210  I.second = NewMI;
211  else
212  Map.erase(I.first);
213  break;
214  }
215 }
216 
218  : MF(mf), HST(mf.getSubtarget<HexagonSubtarget>()),
219  TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()),
220  Reserved(TRI.getReservedRegs(mf)) {
221  // Consider all non-allocatable registers as reserved.
222  for (auto I = TRI.regclass_begin(), E = TRI.regclass_end(); I != E; ++I) {
223  auto *RC = *I;
224  if (RC->isAllocatable())
225  continue;
226  for (unsigned R : *RC)
227  Reserved[R] = true;
228  }
229 }
230 
231 HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns(
232  const MachineBasicBlock &B, const MachineRegisterInfo &MRI,
233  const TargetRegisterInfo &TRI) {
234  RegisterSet LiveIns;
235  RegisterSet Tmp;
236  for (auto I : B.liveins()) {
237  if (I.LaneMask.all()) {
238  Tmp.insert({I.PhysReg,0});
239  continue;
240  }
241  for (MCSubRegIndexIterator S(I.PhysReg, &TRI); S.isValid(); ++S) {
242  LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
243  if ((M & I.LaneMask).any())
244  Tmp.insert({S.getSubReg(), 0});
245  }
246  }
247 
248  for (auto R : Tmp) {
249  if (!Reserved[R.Reg])
250  LiveIns.insert(R);
251  for (auto S : expandToSubRegs(R, MRI, TRI))
252  if (!Reserved[S.Reg])
253  LiveIns.insert(S);
254  }
255  return LiveIns;
256 }
257 
258 HexagonBlockRanges::RegisterSet HexagonBlockRanges::expandToSubRegs(
259  RegisterRef R, const MachineRegisterInfo &MRI,
260  const TargetRegisterInfo &TRI) {
262 
263  if (R.Sub != 0) {
264  SRs.insert(R);
265  return SRs;
266  }
267 
269  MCSubRegIterator I(R.Reg, &TRI);
270  if (!I.isValid())
271  SRs.insert({R.Reg, 0});
272  for (; I.isValid(); ++I)
273  SRs.insert({*I, 0});
274  } else {
276  auto &RC = *MRI.getRegClass(R.Reg);
277  unsigned PReg = *RC.begin();
278  MCSubRegIndexIterator I(PReg, &TRI);
279  if (!I.isValid())
280  SRs.insert({R.Reg, 0});
281  for (; I.isValid(); ++I)
282  SRs.insert({R.Reg, I.getSubRegIndex()});
283  }
284  return SRs;
285 }
286 
287 void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
288  RegToRangeMap &LiveMap) {
289  std::map<RegisterRef,IndexType> LastDef, LastUse;
290  RegisterSet LiveOnEntry;
291  MachineBasicBlock &B = IndexMap.getBlock();
293 
294  for (auto R : getLiveIns(B, MRI, TRI))
295  LiveOnEntry.insert(R);
296 
297  for (auto R : LiveOnEntry)
298  LastDef[R] = IndexType::Entry;
299 
300  auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void {
301  auto LD = LastDef[R], LU = LastUse[R];
302  if (LD == IndexType::None)
304  if (LU == IndexType::None)
305  LU = IndexType::Exit;
306  LiveMap[R].add(LD, LU, false, false);
307  LastUse[R] = LastDef[R] = IndexType::None;
308  };
309 
310  for (auto &In : B) {
311  if (In.isDebugValue())
312  continue;
313  IndexType Index = IndexMap.getIndex(&In);
314  // Process uses first.
315  for (auto &Op : In.operands()) {
316  if (!Op.isReg() || !Op.isUse() || Op.isUndef())
317  continue;
318  RegisterRef R = { Op.getReg(), Op.getSubReg() };
319  if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg])
320  continue;
321  bool IsKill = Op.isKill();
322  for (auto S : expandToSubRegs(R, MRI, TRI)) {
323  LastUse[S] = Index;
324  if (IsKill)
325  closeRange(S);
326  }
327  }
328  // Process defs.
329  for (auto &Op : In.operands()) {
330  if (!Op.isReg() || !Op.isDef() || Op.isUndef())
331  continue;
332  RegisterRef R = { Op.getReg(), Op.getSubReg() };
333  if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg])
334  continue;
335  for (auto S : expandToSubRegs(R, MRI, TRI)) {
336  if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None)
337  closeRange(S);
338  LastDef[S] = Index;
339  }
340  }
341  }
342 
343  // Collect live-on-exit.
344  RegisterSet LiveOnExit;
345  for (auto *SB : B.successors())
346  for (auto R : getLiveIns(*SB, MRI, TRI))
347  LiveOnExit.insert(R);
348 
349  for (auto R : LiveOnExit)
350  LastUse[R] = IndexType::Exit;
351 
352  // Process remaining registers.
354  for (auto &I : LastUse)
355  if (I.second != IndexType::None)
356  Left.insert(I.first);
357  for (auto &I : LastDef)
358  if (I.second != IndexType::None)
359  Left.insert(I.first);
360  for (auto R : Left)
361  closeRange(R);
362 
363  // Finalize the live ranges.
364  for (auto &P : LiveMap)
365  P.second.unionize();
366 }
367 
369  InstrIndexMap &IndexMap) {
370  RegToRangeMap LiveMap;
371  DEBUG(dbgs() << __func__ << ": index map\n" << IndexMap << '\n');
372  computeInitialLiveRanges(IndexMap, LiveMap);
373  DEBUG(dbgs() << __func__ << ": live map\n"
374  << PrintRangeMap(LiveMap, TRI) << '\n');
375  return LiveMap;
376 }
377 
379  InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) {
380  RegToRangeMap DeadMap;
381 
382  auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (RegisterRef R) -> void {
383  auto F = LiveMap.find(R);
384  if (F == LiveMap.end() || F->second.empty()) {
385  DeadMap[R].add(IndexType::Entry, IndexType::Exit, false, false);
386  return;
387  }
388 
389  RangeList &RL = F->second;
390  RangeList::iterator A = RL.begin(), Z = RL.end()-1;
391 
392  // Try to create the initial range.
393  if (A->start() != IndexType::Entry) {
394  IndexType DE = IndexMap.getPrevIndex(A->start());
395  if (DE != IndexType::Entry)
396  DeadMap[R].add(IndexType::Entry, DE, false, false);
397  }
398 
399  while (A != Z) {
400  // Creating a dead range that follows A. Pay attention to empty
401  // ranges (i.e. those ending with "None").
402  IndexType AE = (A->end() == IndexType::None) ? A->start() : A->end();
403  IndexType DS = IndexMap.getNextIndex(AE);
404  ++A;
405  IndexType DE = IndexMap.getPrevIndex(A->start());
406  if (DS < DE)
407  DeadMap[R].add(DS, DE, false, false);
408  }
409 
410  // Try to create the final range.
411  if (Z->end() != IndexType::Exit) {
412  IndexType ZE = (Z->end() == IndexType::None) ? Z->start() : Z->end();
413  IndexType DS = IndexMap.getNextIndex(ZE);
414  if (DS < IndexType::Exit)
415  DeadMap[R].add(DS, IndexType::Exit, false, false);
416  }
417  };
418 
419  MachineFunction &MF = *IndexMap.getBlock().getParent();
420  auto &MRI = MF.getRegInfo();
421  unsigned NumRegs = TRI.getNumRegs();
422  BitVector Visited(NumRegs);
423  for (unsigned R = 1; R < NumRegs; ++R) {
424  for (auto S : expandToSubRegs({R,0}, MRI, TRI)) {
425  if (Reserved[S.Reg] || Visited[S.Reg])
426  continue;
427  addDeadRanges(S);
428  Visited[S.Reg] = true;
429  }
430  }
431  for (auto &P : LiveMap)
433  addDeadRanges(P.first);
434 
435  DEBUG(dbgs() << __func__ << ": dead map\n"
436  << PrintRangeMap(DeadMap, TRI) << '\n');
437  return DeadMap;
438 }
439 
443  return OS << '-';
445  return OS << 'n';
447  return OS << 'x';
449 }
450 
451 // A mapping to translate between instructions and their indices.
454  OS << '[' << IR.start() << ':' << IR.end() << (IR.TiedEnd ? '}' : ']');
455  if (IR.Fixed)
456  OS << '!';
457  return OS;
458 }
459 
461  const HexagonBlockRanges::RangeList &RL) {
462  for (auto &R : RL)
463  OS << R << " ";
464  return OS;
465 }
466 
469  for (auto &In : M.Block) {
471  OS << Idx << (Idx == M.Last ? ". " : " ") << In;
472  }
473  return OS;
474 }
475 
478  for (auto &I : P.Map) {
479  const HexagonBlockRanges::RangeList &RL = I.second;
480  OS << PrintReg(I.first.Reg, &P.TRI, I.first.Sub) << " -> " << RL << "\n";
481  }
482  return OS;
483 }
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:241
iterator_range< livein_iterator > liveins() const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
regclass_iterator regclass_end() const
bool isValid() const
Returns true if this iterator is not yet at the end.
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:233
I SRs[*I]
LaneBitmask getSubRegIndexLaneMask(unsigned SubIdx) const
Return a bitmask representing the parts of a register that are covered by SubIdx. ...
std::set< RegisterRef > RegisterSet
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
iterator begin() const
begin/end - Return all of the registers in this class.
bool overlaps(const IndexRange &A) const
MachineBasicBlock & getBlock() const
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
#define F(x, y, z)
Definition: MD5.cpp:51
IndexType getNextIndex(IndexType Idx) const
#define T
static bool add(uint64_t *dest, const uint64_t *x, const uint64_t *y, unsigned len)
This function adds the integer array x to the integer array Y and places the result in dest...
Definition: APInt.cpp:239
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
INITIALIZE_PASS(HexagonEarlyIfConversion,"hexagon-eif","Hexagon early if conversion", false, false) bool HexagonEarlyIfConversion MachineBasicBlock * SB
#define P(N)
MachineInstr * getInstr(IndexType Idx) const
unsigned const MachineRegisterInfo * MRI
regclass_iterator regclass_begin() const
Register class iterators.
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MCSubRegIterator enumerates all sub-registers of Reg.
void subtract(const IndexRange &Range)
static void Merge(const std::string &Input, const std::vector< std::string > Result, size_t NumNewFeatures)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
HexagonBlockRanges(MachineFunction &MF)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
IndexType getPrevIndex(IndexType Idx) const
Representation of each machine instruction.
Definition: MachineInstr.h:52
bool contains(const IndexRange &A) const
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap)
std::map< RegisterRef, RangeList > RegToRangeMap
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
IndexType getIndex(MachineInstr *MI) const
#define I(x, y, z)
Definition: MD5.cpp:54
RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:1726
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void unionize(bool MergeAdjacent=false)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
#define DEBUG(X)
Definition: Debug.h:100
IRTranslator LLVM IR MI
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
Statically lint checks LLVM IR
Definition: Lint.cpp:192
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:783