Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/InterferenceCache.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- InterferenceCache.cpp - Caching per-block interference -------------===//
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
// InterferenceCache remembers per-block interference in LiveIntervalUnions.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "InterferenceCache.h"
14
#include "llvm/ADT/ArrayRef.h"
15
#include "llvm/CodeGen/LiveInterval.h"
16
#include "llvm/CodeGen/LiveIntervalUnion.h"
17
#include "llvm/CodeGen/LiveIntervals.h"
18
#include "llvm/CodeGen/MachineBasicBlock.h"
19
#include "llvm/CodeGen/MachineFunction.h"
20
#include "llvm/CodeGen/MachineOperand.h"
21
#include "llvm/CodeGen/SlotIndexes.h"
22
#include "llvm/CodeGen/TargetRegisterInfo.h"
23
#include "llvm/MC/MCRegisterInfo.h"
24
#include "llvm/Support/ErrorHandling.h"
25
#include <cassert>
26
#include <cstdint>
27
#include <cstdlib>
28
#include <tuple>
29
30
using namespace llvm;
31
32
#define DEBUG_TYPE "regalloc"
33
34
// Static member used for null interference cursors.
35
const InterferenceCache::BlockInterference
36
    InterferenceCache::Cursor::NoInterference;
37
38
// Initializes PhysRegEntries (instead of a SmallVector, PhysRegEntries is a
39
// buffer of size NumPhysRegs to speed up alloc/clear for targets with large
40
// reg files). Calloced memory is used for good form, and quites tools like
41
// Valgrind too, but zero initialized memory is not required by the algorithm:
42
// this is because PhysRegEntries works like a SparseSet and its entries are
43
// only valid when there is a corresponding CacheEntries assignment. There is
44
// also support for when pass managers are reused for targets with different
45
// numbers of PhysRegs: in this case PhysRegEntries is freed and reinitialized.
46
484k
void InterferenceCache::reinitPhysRegEntries() {
47
484k
  if (PhysRegEntriesCount == TRI->getNumRegs()) 
return452k
;
48
31.5k
  free(PhysRegEntries);
49
31.5k
  PhysRegEntriesCount = TRI->getNumRegs();
50
31.5k
  PhysRegEntries = static_cast<unsigned char*>(
51
31.5k
      safe_calloc(PhysRegEntriesCount, sizeof(unsigned char)));
52
31.5k
}
53
54
void InterferenceCache::init(MachineFunction *mf,
55
                             LiveIntervalUnion *liuarray,
56
                             SlotIndexes *indexes,
57
                             LiveIntervals *lis,
58
484k
                             const TargetRegisterInfo *tri) {
59
484k
  MF = mf;
60
484k
  LIUArray = liuarray;
61
484k
  TRI = tri;
62
484k
  reinitPhysRegEntries();
63
15.9M
  for (unsigned i = 0; i != CacheEntries; 
++i15.4M
)
64
15.4M
    Entries[i].clear(mf, indexes, lis);
65
484k
}
66
67
7.73M
InterferenceCache::Entry *InterferenceCache::get(unsigned PhysReg) {
68
7.73M
  unsigned E = PhysRegEntries[PhysReg];
69
7.73M
  if (E < CacheEntries && Entries[E].getPhysReg() == PhysReg) {
70
5.38M
    if (!Entries[E].valid(LIUArray, TRI))
71
335k
      Entries[E].revalidate(LIUArray, TRI);
72
5.38M
    return &Entries[E];
73
5.38M
  }
74
2.35M
  // No valid entry exists, pick the next round-robin entry.
75
2.35M
  E = RoundRobin;
76
2.35M
  if (++RoundRobin == CacheEntries)
77
70.7k
    RoundRobin = 0;
78
9.01M
  for (unsigned i = 0; i != CacheEntries; 
++i6.66M
) {
79
9.01M
    // Skip entries that are in use.
80
9.01M
    if (Entries[E].hasRefs()) {
81
6.66M
      if (++E == CacheEntries)
82
213k
        E = 0;
83
6.66M
      continue;
84
6.66M
    }
85
2.35M
    Entries[E].reset(PhysReg, LIUArray, TRI, MF);
86
2.35M
    PhysRegEntries[PhysReg] = E;
87
2.35M
    return &Entries[E];
88
2.35M
  }
89
2.35M
  
llvm_unreachable0
("Ran out of interference cache entries.");
90
2.35M
}
91
92
/// revalidate - LIU contents have changed, update tags.
93
void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray,
94
335k
                                          const TargetRegisterInfo *TRI) {
95
335k
  // Invalidate all block entries.
96
335k
  ++Tag;
97
335k
  // Invalidate all iterators.
98
335k
  PrevPos = SlotIndex();
99
335k
  unsigned i = 0;
100
732k
  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); 
++Units, ++i396k
)
101
396k
    RegUnits[i].VirtTag = LIUArray[*Units].getTag();
102
335k
}
103
104
void InterferenceCache::Entry::reset(unsigned physReg,
105
                                     LiveIntervalUnion *LIUArray,
106
                                     const TargetRegisterInfo *TRI,
107
2.35M
                                     const MachineFunction *MF) {
108
2.35M
  assert(!hasRefs() && "Cannot reset cache entry with references");
109
2.35M
  // LIU's changed, invalidate cache.
110
2.35M
  ++Tag;
111
2.35M
  PhysReg = physReg;
112
2.35M
  Blocks.resize(MF->getNumBlockIDs());
113
2.35M
114
2.35M
  // Reset iterators.
115
2.35M
  PrevPos = SlotIndex();
116
2.35M
  RegUnits.clear();
117
4.94M
  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); 
++Units2.59M
) {
118
2.59M
    RegUnits.push_back(LIUArray[*Units]);
119
2.59M
    RegUnits.back().Fixed = &LIS->getRegUnit(*Units);
120
2.59M
  }
121
2.35M
}
122
123
bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray,
124
5.38M
                                     const TargetRegisterInfo *TRI) {
125
5.38M
  unsigned i = 0, e = RegUnits.size();
126
10.7M
  for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); 
++Units, ++i5.37M
) {
127
5.70M
    if (i == e)
128
0
      return false;
129
5.70M
    if (LIUArray[*Units].changedSince(RegUnits[i].VirtTag))
130
335k
      return false;
131
5.70M
  }
132
5.38M
  
return i == e5.04M
;
133
5.38M
}
134
135
27.0M
void InterferenceCache::Entry::update(unsigned MBBNum) {
136
27.0M
  SlotIndex Start, Stop;
137
27.0M
  std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);
138
27.0M
139
27.0M
  // Use advanceTo only when possible.
140
27.0M
  if (PrevPos != Start) {
141
22.5M
    if (!PrevPos.isValid() || 
Start < PrevPos19.8M
) {
142
20.7M
      for (unsigned i = 0, e = RegUnits.size(); i != e; 
++i10.7M
) {
143
10.7M
        RegUnitInfo &RUI = RegUnits[i];
144
10.7M
        RUI.VirtI.find(Start);
145
10.7M
        RUI.FixedI = RUI.Fixed->find(Start);
146
10.7M
      }
147
12.5M
    } else {
148
26.0M
      for (unsigned i = 0, e = RegUnits.size(); i != e; 
++i13.4M
) {
149
13.4M
        RegUnitInfo &RUI = RegUnits[i];
150
13.4M
        RUI.VirtI.advanceTo(Start);
151
13.4M
        if (RUI.FixedI != RUI.Fixed->end())
152
2.72M
          RUI.FixedI = RUI.Fixed->advanceTo(RUI.FixedI, Start);
153
13.4M
      }
154
12.5M
    }
155
22.5M
    PrevPos = Start;
156
22.5M
  }
157
27.0M
158
27.0M
  MachineFunction::const_iterator MFI =
159
27.0M
      MF->getBlockNumbered(MBBNum)->getIterator();
160
27.0M
  BlockInterference *BI = &Blocks[MBBNum];
161
27.0M
  ArrayRef<SlotIndex> RegMaskSlots;
162
27.0M
  ArrayRef<const uint32_t*> RegMaskBits;
163
65.9M
  while (true) {
164
65.9M
    BI->Tag = Tag;
165
65.9M
    BI->First = BI->Last = SlotIndex();
166
65.9M
167
65.9M
    // Check for first interference from virtregs.
168
136M
    for (unsigned i = 0, e = RegUnits.size(); i != e; 
++i70.1M
) {
169
70.1M
      LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
170
70.1M
      if (!I.valid())
171
39.0M
        continue;
172
31.0M
      SlotIndex StartI = I.start();
173
31.0M
      if (StartI >= Stop)
174
20.4M
        continue;
175
10.6M
      if (!BI->First.isValid() || 
StartI < BI->First1.12M
)
176
9.49M
        BI->First = StartI;
177
10.6M
    }
178
65.9M
179
65.9M
    // Same thing for fixed interference.
180
136M
    for (unsigned i = 0, e = RegUnits.size(); i != e; 
++i70.1M
) {
181
70.1M
      LiveInterval::const_iterator I = RegUnits[i].FixedI;
182
70.1M
      LiveInterval::const_iterator E = RegUnits[i].Fixed->end();
183
70.1M
      if (I == E)
184
57.3M
        continue;
185
12.7M
      SlotIndex StartI = I->start;
186
12.7M
      if (StartI >= Stop)
187
10.1M
        continue;
188
2.62M
      if (!BI->First.isValid() || 
StartI < BI->First1.00M
)
189
1.85M
        BI->First = StartI;
190
2.62M
    }
191
65.9M
192
65.9M
    // Also check for register mask interference.
193
65.9M
    RegMaskSlots = LIS->getRegMaskSlotsInBlock(MBBNum);
194
65.9M
    RegMaskBits = LIS->getRegMaskBitsInBlock(MBBNum);
195
65.9M
    SlotIndex Limit = BI->First.isValid() ? 
BI->First11.1M
:
Stop54.8M
;
196
65.9M
    for (unsigned i = 0, e = RegMaskSlots.size();
197
69.8M
         i != e && 
RegMaskSlots[i] < Limit18.9M
;
++i3.88M
)
198
14.2M
      if (MachineOperand::clobbersPhysReg(RegMaskBits[i], PhysReg)) {
199
10.3M
        // Register mask i clobbers PhysReg before the LIU interference.
200
10.3M
        BI->First = RegMaskSlots[i];
201
10.3M
        break;
202
10.3M
      }
203
65.9M
204
65.9M
    PrevPos = Stop;
205
65.9M
    if (BI->First.isValid())
206
21.0M
      break;
207
44.8M
208
44.8M
    // No interference in this block? Go ahead and precompute the next block.
209
44.8M
    if (++MFI == MF->end())
210
534k
      return;
211
44.3M
    MBBNum = MFI->getNumber();
212
44.3M
    BI = &Blocks[MBBNum];
213
44.3M
    if (BI->Tag == Tag)
214
5.42M
      return;
215
38.9M
    std::tie(Start, Stop) = Indexes->getMBBRange(MBBNum);
216
38.9M
  }
217
27.0M
218
27.0M
  // Check for last interference in block.
219
44.0M
  
for (unsigned i = 0, e = RegUnits.size(); 21.0M
i != e;
++i22.9M
) {
220
22.9M
    LiveIntervalUnion::SegmentIter &I = RegUnits[i].VirtI;
221
22.9M
    if (!I.valid() || 
I.start() >= Stop13.5M
)
222
12.3M
      continue;
223
10.6M
    I.advanceTo(Stop);
224
10.6M
    bool Backup = !I.valid() || 
I.start() >= Stop9.78M
;
225
10.6M
    if (Backup)
226
4.70M
      --I;
227
10.6M
    SlotIndex StopI = I.stop();
228
10.6M
    if (!BI->Last.isValid() || 
StopI > BI->Last1.12M
)
229
9.49M
      BI->Last = StopI;
230
10.6M
    if (Backup)
231
4.70M
      ++I;
232
10.6M
  }
233
21.0M
234
21.0M
  // Fixed interference.
235
44.0M
  for (unsigned i = 0, e = RegUnits.size(); i != e; 
++i22.9M
) {
236
22.9M
    LiveInterval::iterator &I = RegUnits[i].FixedI;
237
22.9M
    LiveRange *LR = RegUnits[i].Fixed;
238
22.9M
    if (I == LR->end() || 
I->start >= Stop4.42M
)
239
20.2M
      continue;
240
2.62M
    I = LR->advanceTo(I, Stop);
241
2.62M
    bool Backup = I == LR->end() || 
I->start >= Stop2.34M
;
242
2.62M
    if (Backup)
243
2.62M
      --I;
244
2.62M
    SlotIndex StopI = I->end;
245
2.62M
    if (!BI->Last.isValid() || 
StopI > BI->Last1.00M
)
246
2.09M
      BI->Last = StopI;
247
2.62M
    if (Backup)
248
2.62M
      ++I;
249
2.62M
  }
250
21.0M
251
21.0M
  // Also check for register mask interference.
252
21.0M
  SlotIndex Limit = BI->Last.isValid() ? 
BI->Last11.1M
:
Start9.97M
;
253
21.0M
  for (unsigned i = RegMaskSlots.size();
254
21.4M
       i && 
RegMaskSlots[i-1].getDeadSlot() > Limit15.4M
;
--i405k
)
255
12.1M
    if (MachineOperand::clobbersPhysReg(RegMaskBits[i-1], PhysReg)) {
256
11.6M
      // Register mask i-1 clobbers PhysReg after the LIU interference.
257
11.6M
      // Model the regmask clobber as a dead def.
258
11.6M
      BI->Last = RegMaskSlots[i-1].getDeadSlot();
259
11.6M
      break;
260
11.6M
    }
261
21.0M
}