Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/CodeGen/GlobalISel/Combiner.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- lib/CodeGen/GlobalISel/Combiner.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
// This file constains common code to combine machine functions at generic
10
// level.
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/CodeGen/GlobalISel/Combiner.h"
14
#include "llvm/ADT/PostOrderIterator.h"
15
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
16
#include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
17
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
18
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
19
#include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
20
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
21
#include "llvm/CodeGen/GlobalISel/Utils.h"
22
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
23
#include "llvm/CodeGen/MachineRegisterInfo.h"
24
#include "llvm/Support/Debug.h"
25
26
#define DEBUG_TYPE "gi-combiner"
27
28
using namespace llvm;
29
30
namespace {
31
/// This class acts as the glue the joins the CombinerHelper to the overall
32
/// Combine algorithm. The CombinerHelper is intended to report the
33
/// modifications it makes to the MIR to the GISelChangeObserver and the
34
/// observer subclass will act on these events. In this case, instruction
35
/// erasure will cancel any future visits to the erased instruction and
36
/// instruction creation will schedule that instruction for a future visit.
37
/// Other Combiner implementations may require more complex behaviour from
38
/// their GISelChangeObserver subclass.
39
class WorkListMaintainer : public GISelChangeObserver {
40
  using WorkListTy = GISelWorkList<512>;
41
  WorkListTy &WorkList;
42
  /// The instructions that have been created but we want to report once they
43
  /// have their operands. This is only maintained if debug output is requested.
44
  SmallPtrSet<const MachineInstr *, 4> CreatedInstrs;
45
46
public:
47
  WorkListMaintainer(WorkListTy &WorkList)
48
369k
      : GISelChangeObserver(), WorkList(WorkList) {}
49
369k
  virtual ~WorkListMaintainer() {
50
369k
  }
51
52
1.66M
  void erasingInstr(MachineInstr &MI) override {
53
1.66M
    LLVM_DEBUG(dbgs() << "Erasing: " << MI << "\n");
54
1.66M
    WorkList.remove(&MI);
55
1.66M
  }
56
35.6k
  void createdInstr(MachineInstr &MI) override {
57
35.6k
    LLVM_DEBUG(dbgs() << "Creating: " << MI << "\n");
58
35.6k
    WorkList.insert(&MI);
59
35.6k
    LLVM_DEBUG(CreatedInstrs.insert(&MI));
60
35.6k
  }
61
1.78M
  void changingInstr(MachineInstr &MI) override {
62
1.78M
    LLVM_DEBUG(dbgs() << "Changing: " << MI << "\n");
63
1.78M
    WorkList.insert(&MI);
64
1.78M
  }
65
1.78M
  void changedInstr(MachineInstr &MI) override {
66
1.78M
    LLVM_DEBUG(dbgs() << "Changed: " << MI << "\n");
67
1.78M
    WorkList.insert(&MI);
68
1.78M
  }
69
70
41.4M
  void reportFullyCreatedInstrs() {
71
41.4M
    LLVM_DEBUG(for (const auto *MI
72
41.4M
                    : CreatedInstrs) {
73
41.4M
      dbgs() << "Created: ";
74
41.4M
      MI->print(dbgs());
75
41.4M
    });
76
41.4M
    LLVM_DEBUG(CreatedInstrs.clear());
77
41.4M
  }
78
};
79
}
80
81
Combiner::Combiner(CombinerInfo &Info, const TargetPassConfig *TPC)
82
235k
    : CInfo(Info), TPC(TPC) {
83
235k
  (void)this->TPC; // FIXME: Remove when used.
84
235k
}
85
86
bool Combiner::combineMachineInstrs(MachineFunction &MF,
87
235k
                                    GISelCSEInfo *CSEInfo) {
88
235k
  // If the ISel pipeline failed, do not bother running this pass.
89
235k
  // FIXME: Should this be here or in individual combiner passes.
90
235k
  if (MF.getProperties().hasProperty(
91
235k
          MachineFunctionProperties::Property::FailedISel))
92
0
    return false;
93
235k
94
235k
  Builder =
95
235k
      CSEInfo ? 
make_unique<CSEMIRBuilder>()0
: make_unique<MachineIRBuilder>();
96
235k
  MRI = &MF.getRegInfo();
97
235k
  Builder->setMF(MF);
98
235k
  if (CSEInfo)
99
0
    Builder->setCSEInfo(CSEInfo);
100
235k
101
235k
  LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');
102
235k
103
235k
  MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
104
235k
105
235k
  bool MFChanged = false;
106
235k
  bool Changed;
107
235k
  MachineIRBuilder &B = *Builder.get();
108
235k
109
369k
  do {
110
369k
    // Collect all instructions. Do a post order traversal for basic blocks and
111
369k
    // insert with list bottom up, so while we pop_back_val, we'll traverse top
112
369k
    // down RPOT.
113
369k
    Changed = false;
114
369k
    GISelWorkList<512> WorkList;
115
369k
    WorkListMaintainer Observer(WorkList);
116
369k
    GISelObserverWrapper WrapperObserver(&Observer);
117
369k
    if (CSEInfo)
118
0
      WrapperObserver.addObserver(CSEInfo);
119
369k
    RAIIDelegateInstaller DelInstall(MF, &WrapperObserver);
120
3.69M
    for (MachineBasicBlock *MBB : post_order(&MF)) {
121
3.69M
      if (MBB->empty())
122
114k
        continue;
123
44.5M
      
for (auto MII = MBB->rbegin(), MIE = MBB->rend(); 3.57M
MII != MIE;) {
124
40.9M
        MachineInstr *CurMI = &*MII;
125
40.9M
        ++MII;
126
40.9M
        // Erase dead insts before even adding to the list.
127
40.9M
        if (isTriviallyDead(*CurMI, *MRI)) {
128
351k
          LLVM_DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
129
351k
          CurMI->eraseFromParentAndMarkDBGValuesForRemoval();
130
351k
          continue;
131
351k
        }
132
40.6M
        WorkList.deferred_insert(CurMI);
133
40.6M
      }
134
3.57M
    }
135
369k
    WorkList.finalize();
136
369k
    // Main Loop. Process the instructions here.
137
41.7M
    while (!WorkList.empty()) {
138
41.4M
      MachineInstr *CurrInst = WorkList.pop_back_val();
139
41.4M
      LLVM_DEBUG(dbgs() << "\nTry combining " << *CurrInst;);
140
41.4M
      Changed |= CInfo.combine(WrapperObserver, *CurrInst, B);
141
41.4M
      Observer.reportFullyCreatedInstrs();
142
41.4M
    }
143
369k
    MFChanged |= Changed;
144
369k
  } while (Changed);
145
235k
146
235k
  return MFChanged;
147
235k
}