Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Hexagon/HexagonBlockRanges.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- HexagonBlockRanges.cpp ---------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "HexagonBlockRanges.h"
10
#include "HexagonInstrInfo.h"
11
#include "HexagonSubtarget.h"
12
#include "llvm/ADT/BitVector.h"
13
#include "llvm/ADT/STLExtras.h"
14
#include "llvm/CodeGen/MachineBasicBlock.h"
15
#include "llvm/CodeGen/MachineFunction.h"
16
#include "llvm/CodeGen/MachineInstr.h"
17
#include "llvm/CodeGen/MachineOperand.h"
18
#include "llvm/CodeGen/MachineRegisterInfo.h"
19
#include "llvm/CodeGen/TargetRegisterInfo.h"
20
#include "llvm/MC/MCRegisterInfo.h"
21
#include "llvm/Support/Debug.h"
22
#include "llvm/Support/raw_ostream.h"
23
#include <algorithm>
24
#include <cassert>
25
#include <cstdint>
26
#include <iterator>
27
#include <map>
28
#include <utility>
29
30
using namespace llvm;
31
32
#define DEBUG_TYPE "hbr"
33
34
33.4k
bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const {
35
33.4k
  // If A contains start(), or "this" contains A.start(), then overlap.
36
33.4k
  IndexType S = start(), E = end(), AS = A.start(), AE = A.end();
37
33.4k
  if (AS == S)
38
366
    return true;
39
33.0k
  bool SbAE = (S < AE) || 
(18
S == AE18
&&
A.TiedEnd0
); // S-before-AE.
40
33.0k
  bool ASbE = (AS < E) || 
(31.9k
AS == E31.9k
&&
TiedEnd8.94k
); // AS-before-E.
41
33.0k
  if ((AS < S && 
SbAE18
) || (S < AS &&
ASbE33.0k
))
42
1.16k
    return true;
43
31.9k
  // Otherwise no overlap.
44
31.9k
  return false;
45
31.9k
}
46
47
23.4k
bool HexagonBlockRanges::IndexRange::contains(const IndexRange &A) const {
48
23.4k
  if (start() <= A.start()) {
49
7.17k
    // Treat "None" in the range end as equal to the range start.
50
7.17k
    IndexType E = (end() != IndexType::None) ? end() : 
start()0
;
51
7.17k
    IndexType AE = (A.end() != IndexType::None) ? A.end() : 
A.start()0
;
52
7.17k
    if (AE <= E)
53
48
      return true;
54
23.3k
  }
55
23.3k
  return false;
56
23.3k
}
57
58
1.43k
void HexagonBlockRanges::IndexRange::merge(const IndexRange &A) {
59
1.43k
  // Allow merging adjacent ranges.
60
1.43k
  assert(end() == A.start() || overlaps(A));
61
1.43k
  IndexType AS = A.start(), AE = A.end();
62
1.43k
  if (AS < start() || start() == IndexType::None)
63
0
    setStart(AS);
64
1.43k
  if (end() < AE || 
end() == IndexType::None1.39k
) {
65
39
    setEnd(AE);
66
39
    TiedEnd = A.TiedEnd;
67
1.39k
  } else {
68
1.39k
    if (end() == AE)
69
457
      TiedEnd |= A.TiedEnd;
70
1.39k
  }
71
1.43k
  if (A.Fixed)
72
0
    Fixed = true;
73
1.43k
}
74
75
48
void HexagonBlockRanges::RangeList::include(const RangeList &RL) {
76
48
  for (auto &R : RL)
77
87
    if (!is_contained(*this, R))
78
87
      push_back(R);
79
48
}
80
81
// Merge all overlapping ranges in the list, so that all that remains
82
// is a list of disjoint ranges.
83
48.3k
void HexagonBlockRanges::RangeList::unionize(bool MergeAdjacent) {
84
48.3k
  if (empty())
85
0
    return;
86
48.3k
87
48.3k
  llvm::sort(begin(), end());
88
48.3k
  iterator Iter = begin();
89
48.3k
90
81.5k
  while (Iter != end()-1) {
91
33.2k
    iterator Next = std::next(Iter);
92
33.2k
    // If MergeAdjacent is true, merge ranges A and B, where A.end == B.start.
93
33.2k
    // This allows merging dead ranges, but is not valid for live ranges.
94
33.2k
    bool Merge = MergeAdjacent && 
(Iter->end() == Next->start())0
;
95
33.2k
    if (Merge || Iter->overlaps(*Next)) {
96
1.43k
      Iter->merge(*Next);
97
1.43k
      erase(Next);
98
1.43k
      continue;
99
1.43k
    }
100
31.7k
    ++Iter;
101
31.7k
  }
102
48.3k
}
103
104
// Compute a range A-B and add it to the list.
105
void HexagonBlockRanges::RangeList::addsub(const IndexRange &A,
106
48
      const IndexRange &B) {
107
48
  // Exclusion of non-overlapping ranges makes some checks simpler
108
48
  // later in this function.
109
48
  if (!A.overlaps(B)) {
110
0
    // A - B = A.
111
0
    add(A);
112
0
    return;
113
0
  }
114
48
115
48
  IndexType AS = A.start(), AE = A.end();
116
48
  IndexType BS = B.start(), BE = B.end();
117
48
118
48
  // If AE is None, then A is included in B, since A and B overlap.
119
48
  // The result of subtraction if empty, so just return.
120
48
  if (AE == IndexType::None)
121
0
    return;
122
48
123
48
  if (AS < BS) {
124
43
    // A starts before B.
125
43
    // AE cannot be None since A and B overlap.
126
43
    assert(AE != IndexType::None);
127
43
    // Add the part of A that extends on the "less" side of B.
128
43
    add(AS, BS, A.Fixed, false);
129
43
  }
130
48
131
48
  if (BE < AE) {
132
44
    // BE cannot be Exit here.
133
44
    if (BE == IndexType::None)
134
0
      add(BS, AE, A.Fixed, false);
135
44
    else
136
44
      add(BE, AE, A.Fixed, false);
137
44
  }
138
48
}
139
140
// Subtract a given range from each element in the list.
141
48
void HexagonBlockRanges::RangeList::subtract(const IndexRange &Range) {
142
48
  // Cannot assume that the list is unionized (i.e. contains only non-
143
48
  // overlapping ranges.
144
48
  RangeList T;
145
228
  for (iterator Next, I = begin(); I != end(); 
I = Next180
) {
146
180
    IndexRange &Rg = *I;
147
180
    if (Rg.overlaps(Range)) {
148
48
      T.addsub(Rg, Range);
149
48
      Next = this->erase(I);
150
132
    } else {
151
132
      Next = std::next(I);
152
132
    }
153
180
  }
154
48
  include(T);
155
48
}
156
157
HexagonBlockRanges::InstrIndexMap::InstrIndexMap(MachineBasicBlock &B)
158
5.57k
    : Block(B) {
159
5.57k
  IndexType Idx = IndexType::First;
160
5.57k
  First = Idx;
161
28.4k
  for (auto &In : B) {
162
28.4k
    if (In.isDebugInstr())
163
27
      continue;
164
28.3k
    assert(getIndex(&In) == IndexType::None && "Instruction already in map");
165
28.3k
    Map.insert(std::make_pair(Idx, &In));
166
28.3k
    ++Idx;
167
28.3k
  }
168
5.57k
  Last = B.empty() ? 
IndexType::None218
:
unsigned(Idx)-15.36k
;
169
5.57k
}
170
171
148
MachineInstr *HexagonBlockRanges::InstrIndexMap::getInstr(IndexType Idx) const {
172
148
  auto F = Map.find(Idx);
173
148
  return (F != Map.end()) ? F->second : 
nullptr0
;
174
148
}
175
176
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getIndex(
177
29.3k
      MachineInstr *MI) const {
178
29.3k
  for (auto &I : Map)
179
1.60M
    if (I.second == MI)
180
29.3k
      return I.first;
181
29.3k
  
return IndexType::None1
;
182
29.3k
}
183
184
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getPrevIndex(
185
61.9k
      IndexType Idx) const {
186
61.9k
  assert (Idx != IndexType::None);
187
61.9k
  if (Idx == IndexType::Entry)
188
0
    return IndexType::None;
189
61.9k
  if (Idx == IndexType::Exit)
190
0
    return Last;
191
61.9k
  if (Idx == First)
192
8.23k
    return IndexType::Entry;
193
53.7k
  return unsigned(Idx)-1;
194
53.7k
}
195
196
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getNextIndex(
197
66.3k
      IndexType Idx) const {
198
66.3k
  assert (Idx != IndexType::None);
199
66.3k
  if (Idx == IndexType::Entry)
200
0
    return IndexType::First;
201
66.3k
  if (Idx == IndexType::Exit || Idx == Last)
202
11.4k
    return IndexType::None;
203
54.8k
  return unsigned(Idx)+1;
204
54.8k
}
205
206
void HexagonBlockRanges::InstrIndexMap::replaceInstr(MachineInstr *OldMI,
207
109
      MachineInstr *NewMI) {
208
17.1k
  for (auto &I : Map) {
209
17.1k
    if (I.second != OldMI)
210
17.0k
      continue;
211
109
    if (NewMI != nullptr)
212
109
      I.second = NewMI;
213
0
    else
214
0
      Map.erase(I.first);
215
109
    break;
216
109
  }
217
109
}
218
219
HexagonBlockRanges::HexagonBlockRanges(MachineFunction &mf)
220
  : MF(mf), HST(mf.getSubtarget<HexagonSubtarget>()),
221
    TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()),
222
3.36k
    Reserved(TRI.getReservedRegs(mf)) {
223
3.36k
  // Consider all non-allocatable registers as reserved.
224
84.1k
  for (const TargetRegisterClass *RC : TRI.regclasses()) {
225
84.1k
    if (RC->isAllocatable())
226
43.7k
      continue;
227
40.3k
    for (unsigned R : *RC)
228
360k
      Reserved[R] = true;
229
40.3k
  }
230
3.36k
}
231
232
HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns(
233
      const MachineBasicBlock &B, const MachineRegisterInfo &MRI,
234
8.80k
      const TargetRegisterInfo &TRI) {
235
8.80k
  RegisterSet LiveIns;
236
8.80k
  RegisterSet Tmp;
237
8.80k
238
37.4k
  for (auto I : B.liveins()) {
239
37.4k
    MCSubRegIndexIterator S(I.PhysReg, &TRI);
240
37.4k
    if (I.LaneMask.all() || 
(31.4k
I.LaneMask.any()31.4k
&&
!S.isValid()31.4k
)) {
241
37.3k
      Tmp.insert({I.PhysReg, 0});
242
37.3k
      continue;
243
37.3k
    }
244
261
    
for (; 87
S.isValid();
++S174
) {
245
174
      unsigned SI = S.getSubRegIndex();
246
174
      if ((I.LaneMask & TRI.getSubRegIndexLaneMask(SI)).any())
247
89
        Tmp.insert({S.getSubReg(), 0});
248
174
    }
249
87
  }
250
8.80k
251
37.4k
  for (auto R : Tmp) {
252
37.4k
    if (!Reserved[R.Reg])
253
32.2k
      LiveIns.insert(R);
254
37.4k
    for (auto S : expandToSubRegs(R, MRI, TRI))
255
38.4k
      if (!Reserved[S.Reg])
256
33.2k
        LiveIns.insert(S);
257
37.4k
  }
258
8.80k
  return LiveIns;
259
8.80k
}
260
261
HexagonBlockRanges::RegisterSet HexagonBlockRanges::expandToSubRegs(
262
      RegisterRef R, const MachineRegisterInfo &MRI,
263
1.19M
      const TargetRegisterInfo &TRI) {
264
1.19M
  RegisterSet SRs;
265
1.19M
266
1.19M
  if (R.Sub != 0) {
267
0
    SRs.insert(R);
268
0
    return SRs;
269
0
  }
270
1.19M
271
1.19M
  if (TargetRegisterInfo::isPhysicalRegister(R.Reg)) {
272
1.19M
    MCSubRegIterator I(R.Reg, &TRI);
273
1.19M
    if (!I.isValid())
274
805k
      SRs.insert({R.Reg, 0});
275
2.14M
    for (; I.isValid(); 
++I948k
)
276
948k
      SRs.insert({*I, 0});
277
1.19M
  } else {
278
156
    assert(TargetRegisterInfo::isVirtualRegister(R.Reg));
279
156
    auto &RC = *MRI.getRegClass(R.Reg);
280
156
    unsigned PReg = *RC.begin();
281
156
    MCSubRegIndexIterator I(PReg, &TRI);
282
156
    if (!I.isValid())
283
156
      SRs.insert({R.Reg, 0});
284
156
    for (; I.isValid(); 
++I0
)
285
0
      SRs.insert({R.Reg, I.getSubRegIndex()});
286
156
  }
287
1.19M
  return SRs;
288
1.19M
}
289
290
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
291
5.57k
      RegToRangeMap &LiveMap) {
292
5.57k
  std::map<RegisterRef,IndexType> LastDef, LastUse;
293
5.57k
  RegisterSet LiveOnEntry;
294
5.57k
  MachineBasicBlock &B = IndexMap.getBlock();
295
5.57k
  MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
296
5.57k
297
5.57k
  for (auto R : getLiveIns(B, MRI, TRI))
298
17.9k
    LiveOnEntry.insert(R);
299
5.57k
300
5.57k
  for (auto R : LiveOnEntry)
301
17.9k
    LastDef[R] = IndexType::Entry;
302
5.57k
303
81.5k
  auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void {
304
81.5k
    auto LD = LastDef[R], LU = LastUse[R];
305
81.5k
    if (LD == IndexType::None)
306
572
      LD = IndexType::Entry;
307
81.5k
    if (LU == IndexType::None)
308
1.39k
      LU = IndexType::Exit;
309
81.5k
    LiveMap[R].add(LD, LU, false, false);
310
81.5k
    LastUse[R] = LastDef[R] = IndexType::None;
311
81.5k
  };
312
5.57k
313
5.57k
  RegisterSet Defs, Clobbers;
314
5.57k
315
28.4k
  for (auto &In : B) {
316
28.4k
    if (In.isDebugInstr())
317
27
      continue;
318
28.3k
    IndexType Index = IndexMap.getIndex(&In);
319
28.3k
    // Process uses first.
320
86.1k
    for (auto &Op : In.operands()) {
321
86.1k
      if (!Op.isReg() || 
!Op.isUse()66.9k
||
Op.isUndef()38.5k
)
322
48.0k
        continue;
323
38.1k
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
324
38.1k
      if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && 
Reserved[R.Reg]38.0k
)
325
5.40k
        continue;
326
32.7k
      bool IsKill = Op.isKill();
327
36.5k
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
328
36.5k
        LastUse[S] = Index;
329
36.5k
        if (IsKill)
330
19.8k
          closeRange(S);
331
36.5k
      }
332
32.7k
    }
333
28.3k
    // Process defs and clobbers.
334
28.3k
    Defs.clear();
335
28.3k
    Clobbers.clear();
336
86.1k
    for (auto &Op : In.operands()) {
337
86.1k
      if (!Op.isReg() || 
!Op.isDef()66.9k
||
Op.isUndef()28.4k
)
338
57.7k
        continue;
339
28.4k
      RegisterRef R = { Op.getReg(), Op.getSubReg() };
340
31.5k
      for (auto S : expandToSubRegs(R, MRI, TRI)) {
341
31.5k
        if (TargetRegisterInfo::isPhysicalRegister(S.Reg) && 
Reserved[S.Reg]31.4k
)
342
8.66k
          continue;
343
22.8k
        if (Op.isDead())
344
361
          Clobbers.insert(S);
345
22.4k
        else
346
22.4k
          Defs.insert(S);
347
22.8k
      }
348
28.4k
    }
349
28.3k
350
86.1k
    for (auto &Op : In.operands()) {
351
86.1k
      if (!Op.isRegMask())
352
85.4k
        continue;
353
717
      const uint32_t *BM = Op.getRegMask();
354
141k
      for (unsigned PR = 1, N = TRI.getNumRegs(); PR != N; 
++PR140k
) {
355
140k
        // Skip registers that have subregisters. A register is preserved
356
140k
        // iff its bit is set in the regmask, so if R1:0 was preserved, both
357
140k
        // R1 and R0 would also be present.
358
140k
        if (MCSubRegIterator(PR, &TRI, false).isValid())
359
48.7k
          continue;
360
91.7k
        if (Reserved[PR])
361
42.3k
          continue;
362
49.4k
        if (BM[PR/32] & (1u << (PR%32)))
363
8.60k
          continue;
364
40.8k
        RegisterRef R = { PR, 0 };
365
40.8k
        if (!Defs.count(R))
366
40.3k
          Clobbers.insert(R);
367
40.8k
      }
368
717
    }
369
28.3k
    // Defs and clobbers can overlap, e.g.
370
28.3k
    // dead %d0 = COPY %5, implicit-def %r0, implicit-def %r1
371
28.3k
    for (RegisterRef R : Defs)
372
22.4k
      Clobbers.erase(R);
373
28.3k
374
28.3k
    // Update maps for defs.
375
28.3k
    for (RegisterRef S : Defs) {
376
22.4k
      // Defs should already be expanded into subregs.
377
22.4k
      assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) ||
378
22.4k
             !MCSubRegIterator(S.Reg, &TRI, false).isValid());
379
22.4k
      if (LastDef[S] != IndexType::None || 
LastUse[S] != IndexType::None19.2k
)
380
3.47k
        closeRange(S);
381
22.4k
      LastDef[S] = Index;
382
22.4k
    }
383
28.3k
    // Update maps for clobbers.
384
40.5k
    for (RegisterRef S : Clobbers) {
385
40.5k
      // Clobbers should already be expanded into subregs.
386
40.5k
      assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) ||
387
40.5k
             !MCSubRegIterator(S.Reg, &TRI, false).isValid());
388
40.5k
      if (LastDef[S] != IndexType::None || 
LastUse[S] != IndexType::None40.1k
)
389
470
        closeRange(S);
390
40.5k
      // Create a single-instruction range.
391
40.5k
      LastDef[S] = LastUse[S] = Index;
392
40.5k
      closeRange(S);
393
40.5k
    }
394
28.3k
  }
395
5.57k
396
5.57k
  // Collect live-on-exit.
397
5.57k
  RegisterSet LiveOnExit;
398
5.57k
  for (auto *SB : B.successors())
399
3.22k
    for (auto R : getLiveIns(*SB, MRI, TRI))
400
16.3k
      LiveOnExit.insert(R);
401
5.57k
402
5.57k
  for (auto R : LiveOnExit)
403
12.5k
    LastUse[R] = IndexType::Exit;
404
5.57k
405
5.57k
  // Process remaining registers.
406
5.57k
  RegisterSet Left;
407
5.57k
  for (auto &I : LastUse)
408
47.2k
    if (I.second != IndexType::None)
409
16.0k
      Left.insert(I.first);
410
5.57k
  for (auto &I : LastDef)
411
48.1k
    if (I.second != IndexType::None)
412
16.9k
      Left.insert(I.first);
413
5.57k
  for (auto R : Left)
414
17.2k
    closeRange(R);
415
5.57k
416
5.57k
  // Finalize the live ranges.
417
5.57k
  for (auto &P : LiveMap)
418
48.3k
    P.second.unionize();
419
5.57k
}
420
421
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeLiveMap(
422
5.57k
      InstrIndexMap &IndexMap) {
423
5.57k
  RegToRangeMap LiveMap;
424
5.57k
  LLVM_DEBUG(dbgs() << __func__ << ": index map\n" << IndexMap << '\n');
425
5.57k
  computeInitialLiveRanges(IndexMap, LiveMap);
426
5.57k
  LLVM_DEBUG(dbgs() << __func__ << ": live map\n"
427
5.57k
                    << PrintRangeMap(LiveMap, TRI) << '\n');
428
5.57k
  return LiveMap;
429
5.57k
}
430
431
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeDeadMap(
432
5.57k
      InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) {
433
5.57k
  RegToRangeMap DeadMap;
434
5.57k
435
474k
  auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (RegisterRef R) -> void {
436
474k
    auto F = LiveMap.find(R);
437
474k
    if (F == LiveMap.end() || 
F->second.empty()48.0k
) {
438
426k
      DeadMap[R].add(IndexType::Entry, IndexType::Exit, false, false);
439
426k
      return;
440
426k
    }
441
48.0k
442
48.0k
    RangeList &RL = F->second;
443
48.0k
    RangeList::iterator A = RL.begin(), Z = RL.end()-1;
444
48.0k
445
48.0k
    // Try to create the initial range.
446
48.0k
    if (A->start() != IndexType::Entry) {
447
30.1k
      IndexType DE = IndexMap.getPrevIndex(A->start());
448
30.1k
      if (DE != IndexType::Entry)
449
23.0k
        DeadMap[R].add(IndexType::Entry, DE, false, false);
450
30.1k
    }
451
48.0k
452
79.8k
    while (A != Z) {
453
31.7k
      // Creating a dead range that follows A.  Pay attention to empty
454
31.7k
      // ranges (i.e. those ending with "None").
455
31.7k
      IndexType AE = (A->end() == IndexType::None) ? 
A->start()0
: A->end();
456
31.7k
      IndexType DS = IndexMap.getNextIndex(AE);
457
31.7k
      ++A;
458
31.7k
      IndexType DE = IndexMap.getPrevIndex(A->start());
459
31.7k
      if (DS < DE)
460
15.8k
        DeadMap[R].add(DS, DE, false, false);
461
31.7k
    }
462
48.0k
463
48.0k
    // Try to create the final range.
464
48.0k
    if (Z->end() != IndexType::Exit) {
465
34.5k
      IndexType ZE = (Z->end() == IndexType::None) ? 
Z->start()0
: Z->end();
466
34.5k
      IndexType DS = IndexMap.getNextIndex(ZE);
467
34.5k
      if (DS < IndexType::Exit)
468
23.3k
        DeadMap[R].add(DS, IndexType::Exit, false, false);
469
34.5k
    }
470
48.0k
  };
471
5.57k
472
5.57k
  MachineFunction &MF = *IndexMap.getBlock().getParent();
473
5.57k
  auto &MRI = MF.getRegInfo();
474
5.57k
  unsigned NumRegs = TRI.getNumRegs();
475
5.57k
  BitVector Visited(NumRegs);
476
1.09M
  for (unsigned R = 1; R < NumRegs; 
++R1.09M
) {
477
1.64M
    for (auto S : expandToSubRegs({R,0}, MRI, TRI)) {
478
1.64M
      if (Reserved[S.Reg] || 
Visited[S.Reg]993k
)
479
1.17M
        continue;
480
474k
      addDeadRanges(S);
481
474k
      Visited[S.Reg] = true;
482
474k
    }
483
1.09M
  }
484
5.57k
  for (auto &P : LiveMap)
485
48.3k
    if (TargetRegisterInfo::isVirtualRegister(P.first.Reg))
486
78
      addDeadRanges(P.first);
487
5.57k
488
5.57k
  LLVM_DEBUG(dbgs() << __func__ << ": dead map\n"
489
5.57k
                    << PrintRangeMap(DeadMap, TRI) << '\n');
490
5.57k
  return DeadMap;
491
5.57k
}
492
493
raw_ostream &llvm::operator<<(raw_ostream &OS,
494
0
                              HexagonBlockRanges::IndexType Idx) {
495
0
  if (Idx == HexagonBlockRanges::IndexType::None)
496
0
    return OS << '-';
497
0
  if (Idx == HexagonBlockRanges::IndexType::Entry)
498
0
    return OS << 'n';
499
0
  if (Idx == HexagonBlockRanges::IndexType::Exit)
500
0
    return OS << 'x';
501
0
  return OS << unsigned(Idx)-HexagonBlockRanges::IndexType::First+1;
502
0
}
503
504
// A mapping to translate between instructions and their indices.
505
raw_ostream &llvm::operator<<(raw_ostream &OS,
506
0
                              const HexagonBlockRanges::IndexRange &IR) {
507
0
  OS << '[' << IR.start() << ':' << IR.end() << (IR.TiedEnd ? '}' : ']');
508
0
  if (IR.Fixed)
509
0
    OS << '!';
510
0
  return OS;
511
0
}
512
513
raw_ostream &llvm::operator<<(raw_ostream &OS,
514
0
                              const HexagonBlockRanges::RangeList &RL) {
515
0
  for (auto &R : RL)
516
0
    OS << R << " ";
517
0
  return OS;
518
0
}
519
520
raw_ostream &llvm::operator<<(raw_ostream &OS,
521
0
                              const HexagonBlockRanges::InstrIndexMap &M) {
522
0
  for (auto &In : M.Block) {
523
0
    HexagonBlockRanges::IndexType Idx = M.getIndex(&In);
524
0
    OS << Idx << (Idx == M.Last ? ". " : "  ") << In;
525
0
  }
526
0
  return OS;
527
0
}
528
529
raw_ostream &llvm::operator<<(raw_ostream &OS,
530
0
                              const HexagonBlockRanges::PrintRangeMap &P) {
531
0
  for (auto &I : P.Map) {
532
0
    const HexagonBlockRanges::RangeList &RL = I.second;
533
0
    OS << printReg(I.first.Reg, &P.TRI, I.first.Sub) << " -> " << RL << "\n";
534
0
  }
535
0
  return OS;
536
0
}