Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/GlobalISel/InstructionSelect.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/CodeGen/GlobalISel/InstructionSelect.cpp - InstructionSelect ---==//
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
/// \file
10
/// This file implements the InstructionSelect class.
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
14
#include "llvm/ADT/PostOrderIterator.h"
15
#include "llvm/ADT/ScopeExit.h"
16
#include "llvm/ADT/Twine.h"
17
#include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
18
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
19
#include "llvm/CodeGen/GlobalISel/Utils.h"
20
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
21
#include "llvm/CodeGen/MachineRegisterInfo.h"
22
#include "llvm/CodeGen/TargetPassConfig.h"
23
#include "llvm/IR/Constants.h"
24
#include "llvm/IR/Function.h"
25
#include "llvm/Support/CommandLine.h"
26
#include "llvm/Support/Debug.h"
27
#include "llvm/Target/TargetLowering.h"
28
#include "llvm/Target/TargetSubtargetInfo.h"
29
30
#define DEBUG_TYPE "instruction-select"
31
32
using namespace llvm;
33
34
char InstructionSelect::ID = 0;
35
90.2k
INITIALIZE_PASS_BEGIN90.2k
(InstructionSelect, DEBUG_TYPE,
36
90.2k
                      "Select target instructions out of generic instructions",
37
90.2k
                      false, false)
38
90.2k
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
39
90.2k
INITIALIZE_PASS_END(InstructionSelect, DEBUG_TYPE,
40
                    "Select target instructions out of generic instructions",
41
                    false, false)
42
43
6.52k
InstructionSelect::InstructionSelect() : MachineFunctionPass(ID) {
44
6.52k
  initializeInstructionSelectPass(*PassRegistry::getPassRegistry());
45
6.52k
}
46
47
6.50k
void InstructionSelect::getAnalysisUsage(AnalysisUsage &AU) const {
48
6.50k
  AU.addRequired<TargetPassConfig>();
49
6.50k
  MachineFunctionPass::getAnalysisUsage(AU);
50
6.50k
}
51
52
223k
bool InstructionSelect::runOnMachineFunction(MachineFunction &MF) {
53
223k
  const MachineRegisterInfo &MRI = MF.getRegInfo();
54
223k
55
223k
  // No matter what happens, whether we successfully select the function or not,
56
223k
  // nothing is going to use the vreg types after us.  Make sure they disappear.
57
223k
  auto ClearVRegTypesOnReturn =
58
223k
      make_scope_exit([&]() { MRI.getVRegToType().clear(); });
59
223k
60
223k
  // If the ISel pipeline failed, do not bother running that pass.
61
223k
  if (MF.getProperties().hasProperty(
62
223k
          MachineFunctionProperties::Property::FailedISel))
63
43.3k
    return false;
64
179k
65
179k
  
DEBUG179k
(dbgs() << "Selecting function: " << MF.getName() << '\n');
66
179k
67
179k
  const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
68
179k
  const InstructionSelector *ISel = MF.getSubtarget().getInstructionSelector();
69
179k
  assert(ISel && "Cannot work without InstructionSelector");
70
179k
71
179k
  // An optimization remark emitter. Used to report failures.
72
179k
  MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
73
179k
74
179k
  // FIXME: There are many other MF/MFI fields we need to initialize.
75
179k
76
#ifndef NDEBUG
77
  // Check that our input is fully legal: we require the function to have the
78
  // Legalized property, so it should be.
79
  // FIXME: This should be in the MachineVerifier, but it can't use the
80
  // LegalizerInfo as it's currently in the separate GlobalISel library.
81
  // The RegBankSelected property is already checked in the verifier. Note
82
  // that it has the same layering problem, but we only use inline methods so
83
  // end up not needing to link against the GlobalISel library.
84
  if (const LegalizerInfo *MLI = MF.getSubtarget().getLegalizerInfo())
85
    for (MachineBasicBlock &MBB : MF)
86
      for (MachineInstr &MI : MBB)
87
        if (isPreISelGenericOpcode(MI.getOpcode()) && !MLI->isLegal(MI, MRI)) {
88
          reportGISelFailure(MF, TPC, MORE, "gisel-select",
89
                             "instruction is not legal", MI);
90
          return false;
91
        }
92
93
#endif
94
  // FIXME: We could introduce new blocks and will need to fix the outer loop.
95
179k
  // Until then, keep track of the number of blocks to assert that we don't.
96
179k
  const size_t NumBlocks = MF.size();
97
179k
98
472k
  for (MachineBasicBlock *MBB : post_order(&MF)) {
99
472k
    if (MBB->empty())
100
2.31k
      continue;
101
470k
102
470k
    // Select instructions in reverse block order. We permit erasing so have
103
470k
    // to resort to manually iterating and recognizing the begin (rend) case.
104
470k
    bool ReachedBegin = false;
105
470k
    for (auto MII = std::prev(MBB->end()), Begin = MBB->begin();
106
7.70M
         
!ReachedBegin7.70M
;) {
107
#ifndef NDEBUG
108
      // Keep track of the insertion range for debug printing.
109
      const auto AfterIt = std::next(MII);
110
#endif
111
      // Select this instruction.
112
7.25M
      MachineInstr &MI = *MII;
113
7.25M
114
7.25M
      // And have our iterator point to the next instruction, if there is one.
115
7.25M
      if (MII == Begin)
116
455k
        ReachedBegin = true;
117
7.25M
      else
118
6.79M
        --MII;
119
7.25M
120
7.25M
      DEBUG(dbgs() << "Selecting: \n  " << MI);
121
7.25M
122
7.25M
      // We could have folded this instruction away already, making it dead.
123
7.25M
      // If so, erase it.
124
7.25M
      if (
isTriviallyDead(MI, MRI)7.25M
) {
125
769k
        DEBUG(dbgs() << "Is dead; erasing.\n");
126
769k
        MI.eraseFromParentAndMarkDBGValuesForRemoval();
127
769k
        continue;
128
769k
      }
129
6.48M
130
6.48M
      
if (6.48M
!ISel->select(MI)6.48M
) {
131
20.1k
        // FIXME: It would be nice to dump all inserted instructions.  It's
132
20.1k
        // not obvious how, esp. considering select() can insert after MI.
133
20.1k
        reportGISelFailure(MF, TPC, MORE, "gisel-select", "cannot select", MI);
134
20.1k
        return false;
135
20.1k
      }
136
6.46M
137
6.46M
      // Dump the range of instructions that MI expanded into.
138
6.46M
      
DEBUG6.46M
({
139
6.46M
        auto InsertedBegin = ReachedBegin ? MBB->begin() : std::next(MII);
140
6.46M
        dbgs() << "Into:\n";
141
6.46M
        for (auto &InsertedMI : make_range(InsertedBegin, AfterIt))
142
6.46M
          dbgs() << "  " << InsertedMI;
143
6.46M
        dbgs() << '\n';
144
6.46M
      });
145
6.46M
    }
146
472k
  }
147
179k
148
159k
  const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
149
159k
150
159k
  // Now that selection is complete, there are no more generic vregs.  Verify
151
159k
  // that the size of the now-constrained vreg is unchanged and that it has a
152
159k
  // register class.
153
3.18M
  for (auto &VRegToType : MRI.getVRegToType()) {
154
3.18M
    unsigned VReg = VRegToType.first;
155
3.18M
    auto *RC = MRI.getRegClassOrNull(VReg);
156
3.18M
    MachineInstr *MI = nullptr;
157
3.18M
    if (!MRI.def_empty(VReg))
158
2.42M
      MI = &*MRI.def_instr_begin(VReg);
159
765k
    else 
if (765k
!MRI.use_empty(VReg)765k
)
160
0
      MI = &*MRI.use_instr_begin(VReg);
161
3.18M
162
3.18M
    if (
MI && 3.18M
!RC2.42M
) {
163
179
      reportGISelFailure(MF, TPC, MORE, "gisel-select",
164
179
                         "VReg has no regclass after selection", *MI);
165
179
      return false;
166
3.18M
    } else 
if (3.18M
!RC3.18M
)
167
765k
      continue;
168
2.42M
169
2.42M
    
if (2.42M
VRegToType.second.isValid() &&
170
2.42M
        
VRegToType.second.getSizeInBits() > TRI.getRegSizeInBits(*RC)2.42M
) {
171
0
      reportGISelFailure(MF, TPC, MORE, "gisel-select",
172
0
                         "VReg has explicit size different from class size",
173
0
                         *MI);
174
0
      return false;
175
0
    }
176
159k
  }
177
159k
178
159k
  
if (159k
MF.size() != NumBlocks159k
) {
179
0
    MachineOptimizationRemarkMissed R("gisel-select", "GISelFailure",
180
0
                                      MF.getFunction()->getSubprogram(),
181
0
                                      /*MBB=*/nullptr);
182
0
    R << "inserting blocks is not supported yet";
183
0
    reportGISelFailure(MF, TPC, MORE, R);
184
0
    return false;
185
0
  }
186
159k
187
159k
  auto &TLI = *MF.getSubtarget().getTargetLowering();
188
159k
  TLI.finalizeLowering(MF);
189
159k
190
159k
  // FIXME: Should we accurately track changes?
191
159k
  return true;
192
159k
}