Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/MachineInstrBundle.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- lib/CodeGen/MachineInstrBundle.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 "llvm/CodeGen/MachineInstrBundle.h"
10
#include "llvm/ADT/SmallSet.h"
11
#include "llvm/ADT/SmallVector.h"
12
#include "llvm/CodeGen/MachineFunctionPass.h"
13
#include "llvm/CodeGen/MachineInstrBuilder.h"
14
#include "llvm/CodeGen/Passes.h"
15
#include "llvm/CodeGen/TargetInstrInfo.h"
16
#include "llvm/CodeGen/TargetRegisterInfo.h"
17
#include "llvm/CodeGen/TargetSubtargetInfo.h"
18
#include "llvm/Target/TargetMachine.h"
19
#include <utility>
20
using namespace llvm;
21
22
namespace {
23
  class UnpackMachineBundles : public MachineFunctionPass {
24
  public:
25
    static char ID; // Pass identification
26
    UnpackMachineBundles(
27
        std::function<bool(const MachineFunction &)> Ftor = nullptr)
28
5.19k
        : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
29
5.19k
      initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
30
5.19k
    }
31
32
    bool runOnMachineFunction(MachineFunction &MF) override;
33
34
  private:
35
    std::function<bool(const MachineFunction &)> PredicateFtor;
36
  };
37
} // end anonymous namespace
38
39
char UnpackMachineBundles::ID = 0;
40
char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
41
INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
42
                "Unpack machine instruction bundles", false, false)
43
44
26.5k
bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
45
26.5k
  if (PredicateFtor && !PredicateFtor(MF))
46
10.5k
    return false;
47
15.9k
48
15.9k
  bool Changed = false;
49
103k
  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; 
++I87.7k
) {
50
87.7k
    MachineBasicBlock *MBB = &*I;
51
87.7k
52
87.7k
    for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
53
782k
           MIE = MBB->instr_end(); MII != MIE; ) {
54
694k
      MachineInstr *MI = &*MII;
55
694k
56
694k
      // Remove BUNDLE instruction and the InsideBundle flags from bundled
57
694k
      // instructions.
58
694k
      if (MI->isBundle()) {
59
36.4k
        while (++MII != MIE && 
MII->isBundledWithPred()35.9k
) {
60
25.8k
          MII->unbundleFromPred();
61
160k
          for (unsigned i = 0, e = MII->getNumOperands(); i != e; 
++i134k
) {
62
134k
            MachineOperand &MO = MII->getOperand(i);
63
134k
            if (MO.isReg() && 
MO.isInternalRead()88.0k
)
64
20.2k
              MO.setIsInternalRead(false);
65
134k
          }
66
25.8k
        }
67
10.6k
        MI->eraseFromParent();
68
10.6k
69
10.6k
        Changed = true;
70
10.6k
        continue;
71
10.6k
      }
72
684k
73
684k
      ++MII;
74
684k
    }
75
87.7k
  }
76
15.9k
77
15.9k
  return Changed;
78
15.9k
}
79
80
FunctionPass *
81
llvm::createUnpackMachineBundles(
82
5.19k
    std::function<bool(const MachineFunction &)> Ftor) {
83
5.19k
  return new UnpackMachineBundles(std::move(Ftor));
84
5.19k
}
85
86
namespace {
87
  class FinalizeMachineBundles : public MachineFunctionPass {
88
  public:
89
    static char ID; // Pass identification
90
280
    FinalizeMachineBundles() : MachineFunctionPass(ID) {
91
280
      initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
92
280
    }
93
94
    bool runOnMachineFunction(MachineFunction &MF) override;
95
  };
96
} // end anonymous namespace
97
98
char FinalizeMachineBundles::ID = 0;
99
char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
100
INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
101
                "Finalize machine instruction bundles", false, false)
102
103
2.29k
bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
104
2.29k
  return llvm::finalizeBundles(MF);
105
2.29k
}
106
107
/// Return the first found DebugLoc that has a DILocation, given a range of
108
/// instructions. The search range is from FirstMI to LastMI (exclusive). If no
109
/// DILocation is found, then an empty location is returned.
110
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
111
34.2k
                            MachineBasicBlock::instr_iterator LastMI) {
112
107k
  for (auto MII = FirstMI; MII != LastMI; 
++MII72.9k
)
113
79.3k
    if (MII->getDebugLoc().get())
114
6.47k
      return MII->getDebugLoc();
115
34.2k
  
return DebugLoc()27.7k
;
116
34.2k
}
117
118
/// finalizeBundle - Finalize a machine instruction bundle which includes
119
/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
120
/// This routine adds a BUNDLE instruction to represent the bundle, it adds
121
/// IsInternalRead markers to MachineOperands which are defined inside the
122
/// bundle, and it copies externally visible defs and uses to the BUNDLE
123
/// instruction.
124
void llvm::finalizeBundle(MachineBasicBlock &MBB,
125
                          MachineBasicBlock::instr_iterator FirstMI,
126
34.2k
                          MachineBasicBlock::instr_iterator LastMI) {
127
34.2k
  assert(FirstMI != LastMI && "Empty bundle?");
128
34.2k
  MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
129
34.2k
130
34.2k
  MachineFunction &MF = *MBB.getParent();
131
34.2k
  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
132
34.2k
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
133
34.2k
134
34.2k
  MachineInstrBuilder MIB =
135
34.2k
      BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));
136
34.2k
  Bundle.prepend(MIB);
137
34.2k
138
34.2k
  SmallVector<unsigned, 32> LocalDefs;
139
34.2k
  SmallSet<unsigned, 32> LocalDefSet;
140
34.2k
  SmallSet<unsigned, 8> DeadDefSet;
141
34.2k
  SmallSet<unsigned, 16> KilledDefSet;
142
34.2k
  SmallVector<unsigned, 8> ExternUses;
143
34.2k
  SmallSet<unsigned, 8> ExternUseSet;
144
34.2k
  SmallSet<unsigned, 8> KilledUseSet;
145
34.2k
  SmallSet<unsigned, 8> UndefUseSet;
146
34.2k
  SmallVector<MachineOperand*, 4> Defs;
147
122k
  for (auto MII = FirstMI; MII != LastMI; 
++MII87.8k
) {
148
1.03M
    for (unsigned i = 0, e = MII->getNumOperands(); i != e; 
++i951k
) {
149
951k
      MachineOperand &MO = MII->getOperand(i);
150
951k
      if (!MO.isReg())
151
645k
        continue;
152
306k
      if (MO.isDef()) {
153
92.0k
        Defs.push_back(&MO);
154
92.0k
        continue;
155
92.0k
      }
156
214k
157
214k
      unsigned Reg = MO.getReg();
158
214k
      if (!Reg)
159
7.94k
        continue;
160
206k
      assert(TargetRegisterInfo::isPhysicalRegister(Reg));
161
206k
      if (LocalDefSet.count(Reg)) {
162
27.1k
        MO.setIsInternalRead();
163
27.1k
        if (MO.isKill())
164
17.8k
          // Internal def is now killed.
165
17.8k
          KilledDefSet.insert(Reg);
166
179k
      } else {
167
179k
        if (ExternUseSet.insert(Reg).second) {
168
129k
          ExternUses.push_back(Reg);
169
129k
          if (MO.isUndef())
170
203
            UndefUseSet.insert(Reg);
171
129k
        }
172
179k
        if (MO.isKill())
173
58.5k
          // External def is now killed.
174
58.5k
          KilledUseSet.insert(Reg);
175
179k
      }
176
206k
    }
177
87.8k
178
179k
    for (unsigned i = 0, e = Defs.size(); i != e; 
++i92.0k
) {
179
92.0k
      MachineOperand &MO = *Defs[i];
180
92.0k
      unsigned Reg = MO.getReg();
181
92.0k
      if (!Reg)
182
0
        continue;
183
92.0k
184
92.0k
      if (LocalDefSet.insert(Reg).second) {
185
87.3k
        LocalDefs.push_back(Reg);
186
87.3k
        if (MO.isDead()) {
187
5.21k
          DeadDefSet.insert(Reg);
188
5.21k
        }
189
87.3k
      } else {
190
4.69k
        // Re-defined inside the bundle, it's no longer killed.
191
4.69k
        KilledDefSet.erase(Reg);
192
4.69k
        if (!MO.isDead())
193
3.89k
          // Previously defined but dead.
194
3.89k
          DeadDefSet.erase(Reg);
195
4.69k
      }
196
92.0k
197
92.0k
      if (!MO.isDead()) {
198
94.0k
        for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); 
++SubRegs8.01k
) {
199
8.01k
          unsigned SubReg = *SubRegs;
200
8.01k
          if (LocalDefSet.insert(SubReg).second)
201
7.63k
            LocalDefs.push_back(SubReg);
202
8.01k
        }
203
86.0k
      }
204
92.0k
    }
205
87.8k
206
87.8k
    Defs.clear();
207
87.8k
  }
208
34.2k
209
34.2k
  SmallSet<unsigned, 32> Added;
210
129k
  for (unsigned i = 0, e = LocalDefs.size(); i != e; 
++i94.9k
) {
211
94.9k
    unsigned Reg = LocalDefs[i];
212
94.9k
    if (Added.insert(Reg).second) {
213
94.9k
      // If it's not live beyond end of the bundle, mark it dead.
214
94.9k
      bool isDead = DeadDefSet.count(Reg) || 
KilledDefSet.count(Reg)89.7k
;
215
94.9k
      MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
216
94.9k
                 getImplRegState(true));
217
94.9k
    }
218
94.9k
  }
219
34.2k
220
163k
  for (unsigned i = 0, e = ExternUses.size(); i != e; 
++i129k
) {
221
129k
    unsigned Reg = ExternUses[i];
222
129k
    bool isKill = KilledUseSet.count(Reg);
223
129k
    bool isUndef = UndefUseSet.count(Reg);
224
129k
    MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
225
129k
               getImplRegState(true));
226
129k
  }
227
34.2k
228
34.2k
  // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got
229
34.2k
  // the property, then also set it on the bundle.
230
122k
  for (auto MII = FirstMI; MII != LastMI; 
++MII87.8k
) {
231
87.8k
    if (MII->getFlag(MachineInstr::FrameSetup))
232
2
      MIB.setMIFlag(MachineInstr::FrameSetup);
233
87.8k
    if (MII->getFlag(MachineInstr::FrameDestroy))
234
2
      MIB.setMIFlag(MachineInstr::FrameDestroy);
235
87.8k
  }
236
34.2k
}
237
238
/// finalizeBundle - Same functionality as the previous finalizeBundle except
239
/// the last instruction in the bundle is not provided as an input. This is
240
/// used in cases where bundles are pre-determined by marking instructions
241
/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
242
/// points to the end of the bundle.
243
MachineBasicBlock::instr_iterator
244
llvm::finalizeBundle(MachineBasicBlock &MBB,
245
1.00k
                     MachineBasicBlock::instr_iterator FirstMI) {
246
1.00k
  MachineBasicBlock::instr_iterator E = MBB.instr_end();
247
1.00k
  MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
248
2.91k
  while (LastMI != E && 
LastMI->isInsideBundle()2.81k
)
249
1.91k
    ++LastMI;
250
1.00k
  finalizeBundle(MBB, FirstMI, LastMI);
251
1.00k
  return LastMI;
252
1.00k
}
253
254
/// finalizeBundles - Finalize instruction bundles in the specified
255
/// MachineFunction. Return true if any bundles are finalized.
256
2.29k
bool llvm::finalizeBundles(MachineFunction &MF) {
257
2.29k
  bool Changed = false;
258
4.58k
  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; 
++I2.29k
) {
259
2.29k
    MachineBasicBlock &MBB = *I;
260
2.29k
    MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
261
2.29k
    MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
262
2.29k
    if (MII == MIE)
263
2
      continue;
264
2.28k
    assert(!MII->isInsideBundle() &&
265
2.28k
           "First instr cannot be inside bundle before finalization!");
266
2.28k
267
62.0k
    for (++MII; MII != MIE; ) {
268
59.7k
      if (!MII->isInsideBundle())
269
59.6k
        ++MII;
270
86
      else {
271
86
        MII = finalizeBundle(MBB, std::prev(MII));
272
86
        Changed = true;
273
86
      }
274
59.7k
    }
275
2.28k
  }
276
2.29k
277
2.29k
  return Changed;
278
2.29k
}
279
280
//===----------------------------------------------------------------------===//
281
// MachineOperand iterator
282
//===----------------------------------------------------------------------===//
283
284
MachineOperandIteratorBase::VirtRegInfo
285
MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg,
286
761k
                    SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) {
287
761k
  VirtRegInfo RI = { false, false, false };
288
2.82M
  for(; isValid(); 
++*this2.05M
) {
289
2.05M
    MachineOperand &MO = deref();
290
2.05M
    if (!MO.isReg() || 
MO.getReg() != Reg1.64M
)
291
1.29M
      continue;
292
765k
293
765k
    // Remember each (MI, OpNo) that refers to Reg.
294
765k
    if (Ops)
295
765k
      Ops->push_back(std::make_pair(MO.getParent(), getOperandNo()));
296
765k
297
765k
    // Both defs and uses can read virtual registers.
298
765k
    if (MO.readsReg()) {
299
446k
      RI.Reads = true;
300
446k
      if (MO.isDef())
301
200
        RI.Tied = true;
302
446k
    }
303
765k
304
765k
    // Only defs can write.
305
765k
    if (MO.isDef())
306
318k
      RI.Writes = true;
307
446k
    else if (!RI.Tied && 
MO.getParent()->isRegTiedToDefOperand(getOperandNo())446k
)
308
2.26k
      RI.Tied = true;
309
765k
  }
310
761k
  return RI;
311
761k
}
312
313
MachineOperandIteratorBase::PhysRegInfo
314
MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
315
303k
                                           const TargetRegisterInfo *TRI) {
316
303k
  bool AllDefsDead = true;
317
303k
  PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
318
303k
319
303k
  assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
320
303k
         "analyzePhysReg not given a physical register!");
321
1.88M
  for (; isValid(); 
++*this1.58M
) {
322
1.58M
    MachineOperand &MO = deref();
323
1.58M
324
1.58M
    if (MO.isRegMask() && 
MO.clobbersPhysReg(Reg)47.2k
) {
325
47.2k
      PRI.Clobbered = true;
326
47.2k
      continue;
327
47.2k
    }
328
1.53M
329
1.53M
    if (!MO.isReg())
330
411k
      continue;
331
1.12M
332
1.12M
    unsigned MOReg = MO.getReg();
333
1.12M
    if (!MOReg || 
!TargetRegisterInfo::isPhysicalRegister(MOReg)899k
)
334
280k
      continue;
335
843k
336
843k
    if (!TRI->regsOverlap(MOReg, Reg))
337
774k
      continue;
338
68.4k
339
68.4k
    bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
340
68.4k
    if (MO.readsReg()) {
341
3.26k
      PRI.Read = true;
342
3.26k
      if (Covered) {
343
3.26k
        PRI.FullyRead = true;
344
3.26k
        if (MO.isKill())
345
2.25k
          PRI.Killed = true;
346
3.26k
      }
347
65.1k
    } else 
if (65.1k
MO.isDef()65.1k
) {
348
65.1k
      PRI.Defined = true;
349
65.1k
      if (Covered)
350
65.1k
        PRI.FullyDefined = true;
351
65.1k
      if (!MO.isDead())
352
45.7k
        AllDefsDead = false;
353
65.1k
    }
354
68.4k
  }
355
303k
356
303k
  if (AllDefsDead) {
357
257k
    if (PRI.FullyDefined || 
PRI.Clobbered238k
)
358
66.6k
      PRI.DeadDef = true;
359
191k
    else if (PRI.Defined)
360
0
      PRI.PartialDeadDef = true;
361
257k
  }
362
303k
363
303k
  return PRI;
364
303k
}