Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
Line
Count
Source
1
//===-- llvm/CodeGen/GlobalISel/Legalizer.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
/// \file This file implements the LegalizerHelper class to legalize individual
11
/// instructions and the LegalizePass wrapper pass for the primary
12
/// legalization.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#include "llvm/CodeGen/GlobalISel/Legalizer.h"
17
#include "llvm/ADT/SetVector.h"
18
#include "llvm/CodeGen/GlobalISel/LegalizerCombiner.h"
19
#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
20
#include "llvm/CodeGen/GlobalISel/Utils.h"
21
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
22
#include "llvm/CodeGen/MachineRegisterInfo.h"
23
#include "llvm/CodeGen/TargetPassConfig.h"
24
#include "llvm/Support/Debug.h"
25
#include "llvm/Target/TargetInstrInfo.h"
26
#include "llvm/Target/TargetSubtargetInfo.h"
27
28
#include <iterator>
29
30
#define DEBUG_TYPE "legalizer"
31
32
using namespace llvm;
33
34
char Legalizer::ID = 0;
35
90.2k
INITIALIZE_PASS_BEGIN90.2k
(Legalizer, DEBUG_TYPE,
36
90.2k
                      "Legalize the Machine IR a function's Machine IR", false,
37
90.2k
                      false)
38
90.2k
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
39
90.2k
INITIALIZE_PASS_END(Legalizer, DEBUG_TYPE,
40
                    "Legalize the Machine IR a function's Machine IR", false,
41
                    false)
42
43
6.46k
Legalizer::Legalizer() : MachineFunctionPass(ID) {
44
6.46k
  initializeLegalizerPass(*PassRegistry::getPassRegistry());
45
6.46k
}
46
47
6.44k
void Legalizer::getAnalysisUsage(AnalysisUsage &AU) const {
48
6.44k
  AU.addRequired<TargetPassConfig>();
49
6.44k
  MachineFunctionPass::getAnalysisUsage(AU);
50
6.44k
}
51
52
221k
void Legalizer::init(MachineFunction &MF) {
53
221k
}
54
55
222k
bool Legalizer::runOnMachineFunction(MachineFunction &MF) {
56
222k
  // If the ISel pipeline failed, do not bother running that pass.
57
222k
  if (MF.getProperties().hasProperty(
58
222k
          MachineFunctionProperties::Property::FailedISel))
59
1.54k
    return false;
60
221k
  
DEBUG221k
(dbgs() << "Legalize Machine IR for: " << MF.getName() << '\n');
61
221k
  init(MF);
62
221k
  const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
63
221k
  MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
64
221k
  LegalizerHelper Helper(MF);
65
221k
66
221k
  // FIXME: an instruction may need more than one pass before it is legal. For
67
221k
  // example on most architectures <3 x i3> is doubly-illegal. It would
68
221k
  // typically proceed along a path like: <3 x i3> -> <3 x i8> -> <8 x i8>. We
69
221k
  // probably want a worklist of instructions rather than naive iterate until
70
221k
  // convergence for performance reasons.
71
221k
  bool Changed = false;
72
221k
  MachineBasicBlock::iterator NextMI;
73
973k
  for (auto &MBB : MF) {
74
12.9M
    for (auto MI = MBB.begin(); 
MI != MBB.end()12.9M
;
MI = NextMI12.0M
) {
75
12.0M
      // Get the next Instruction before we try to legalize, because there's a
76
12.0M
      // good chance MI will be deleted.
77
12.0M
      NextMI = std::next(MI);
78
12.0M
79
12.0M
      // Only legalize pre-isel generic instructions: others don't have types
80
12.0M
      // and are assumed to be legal.
81
12.0M
      if (!isPreISelGenericOpcode(MI->getOpcode()))
82
6.11M
        continue;
83
5.93M
      unsigned NumNewInsns = 0;
84
5.93M
      using VecType = SetVector<MachineInstr *, SmallVector<MachineInstr *, 8>>;
85
5.93M
      VecType WorkList;
86
5.93M
      VecType CombineList;
87
1.89M
      Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) {
88
1.89M
        // Only legalize pre-isel generic instructions.
89
1.89M
        // Legalization process could generate Target specific pseudo
90
1.89M
        // instructions with generic types. Don't record them
91
1.89M
        if (
isPreISelGenericOpcode(MI->getOpcode())1.89M
) {
92
1.77M
          ++NumNewInsns;
93
1.77M
          WorkList.insert(MI);
94
1.77M
          CombineList.insert(MI);
95
1.77M
        }
96
1.89M
      });
97
5.93M
      WorkList.insert(&*MI);
98
5.93M
      LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo());
99
5.93M
      bool Changed = false;
100
5.93M
      LegalizerHelper::LegalizeResult Res;
101
5.97M
      do {
102
5.97M
        assert(!WorkList.empty() && "Expecting illegal ops");
103
13.6M
        while (
!WorkList.empty()13.6M
) {
104
7.71M
          NumNewInsns = 0;
105
7.71M
          MachineInstr *CurrInst = WorkList.pop_back_val();
106
7.71M
          Res = Helper.legalizeInstrStep(*CurrInst);
107
7.71M
          // Error out if we couldn't legalize this instruction. We may want to
108
7.71M
          // fall back to DAG ISel instead in the future.
109
7.71M
          if (
Res == LegalizerHelper::UnableToLegalize7.71M
) {
110
41.7k
            Helper.MIRBuilder.stopRecordingInsertions();
111
41.7k
            if (
Res == LegalizerHelper::UnableToLegalize41.7k
) {
112
41.7k
              reportGISelFailure(MF, TPC, MORE, "gisel-legalize",
113
41.7k
                                 "unable to legalize instruction", *CurrInst);
114
41.7k
              return false;
115
41.7k
            }
116
7.67M
          }
117
7.67M
          Changed |= Res == LegalizerHelper::Legalized;
118
7.67M
          // If CurrInst was legalized, there's a good chance that it might have
119
7.67M
          // been erased. So remove it from the Combine List.
120
7.67M
          if (Res == LegalizerHelper::Legalized)
121
770k
            CombineList.remove(CurrInst);
122
7.67M
123
#ifndef NDEBUG
124
          if (NumNewInsns)
125
            for (unsigned I = WorkList.size() - NumNewInsns,
126
                          E = WorkList.size();
127
                 I != E; ++I)
128
              DEBUG(dbgs() << ".. .. New MI: " << *WorkList[I];);
129
#endif
130
        }
131
5.97M
        // Do the combines.
132
7.67M
        
while (5.93M
!CombineList.empty()7.67M
) {
133
1.74M
          NumNewInsns = 0;
134
1.74M
          MachineInstr *CurrInst = CombineList.pop_back_val();
135
1.74M
          SmallVector<MachineInstr *, 4> DeadInstructions;
136
1.74M
          Changed |= C.tryCombineInstruction(*CurrInst, DeadInstructions);
137
104k
          for (auto *DeadMI : DeadInstructions) {
138
104k
            DEBUG(dbgs() << ".. Erasing Dead Instruction " << *DeadMI);
139
104k
            CombineList.remove(DeadMI);
140
104k
            WorkList.remove(DeadMI);
141
104k
            DeadMI->eraseFromParent();
142
104k
          }
143
#ifndef NDEBUG
144
          if (NumNewInsns)
145
            for (unsigned I = CombineList.size() - NumNewInsns,
146
                          E = CombineList.size();
147
                 I != E; ++I)
148
              DEBUG(dbgs() << ".. .. Combine New MI: " << *CombineList[I];);
149
#endif
150
        }
151
5.93M
      } while (!WorkList.empty());
152
5.93M
153
5.89M
      Helper.MIRBuilder.stopRecordingInsertions();
154
5.89M
    }
155
973k
  }
156
221k
157
179k
  MachineRegisterInfo &MRI = MF.getRegInfo();
158
179k
  MachineIRBuilder MIRBuilder(MF);
159
179k
  LegalizerCombiner C(MIRBuilder, MRI);
160
676k
  for (auto &MBB : MF) {
161
10.2M
    for (auto MI = MBB.begin(); 
MI != MBB.end()10.2M
;
MI = NextMI9.53M
) {
162
9.53M
      // Get the next Instruction before we try to legalize, because there's a
163
9.53M
      // good chance MI will be deleted.
164
9.53M
      // TOOD: Perhaps move this to a combiner pass later?.
165
9.53M
      NextMI = std::next(MI);
166
9.53M
      SmallVector<MachineInstr *, 4> DeadInsts;
167
9.53M
      Changed |= C.tryCombineMerges(*MI, DeadInsts);
168
9.53M
      for (auto *DeadMI : DeadInsts)
169
38
        DeadMI->eraseFromParent();
170
9.53M
    }
171
676k
  }
172
179k
173
179k
  return Changed;
174
222k
}