[llvm-exegesis] Fix missing std::move.
[llvm-complete.git] / lib / CodeGen / GlobalISel / Combiner.cpp
blobf3f075af4869598c724f9e833d3d4556e9394d58
1 //===-- lib/CodeGen/GlobalISel/GICombiner.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 // This file constains common code to combine machine functions at generic
11 // level.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/CodeGen/GlobalISel/Combiner.h"
15 #include "llvm/CodeGen/GlobalISel/CombinerInfo.h"
16 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
17 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
18 #include "llvm/CodeGen/GlobalISel/GISelWorkList.h"
19 #include "llvm/ADT/PostOrderIterator.h"
20 #include "llvm/CodeGen/GlobalISel/Utils.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/Support/Debug.h"
24 #define DEBUG_TYPE "gi-combiner"
26 using namespace llvm;
28 namespace {
29 /// This class acts as the glue the joins the CombinerHelper to the overall
30 /// Combine algorithm. The CombinerHelper is intended to report the
31 /// modifications it makes to the MIR to the CombinerChangeObserver and the
32 /// observer subclass will act on these events. In this case, instruction
33 /// erasure will cancel any future visits to the erased instruction and
34 /// instruction creation will schedule that instruction for a future visit.
35 /// Other Combiner implementations may require more complex behaviour from
36 /// their CombinerChangeObserver subclass.
37 class WorkListMaintainer : public CombinerChangeObserver {
38 using WorkListTy = GISelWorkList<512>;
39 WorkListTy &WorkList;
41 public:
42 WorkListMaintainer(WorkListTy &WorkList) : WorkList(WorkList) {}
43 virtual ~WorkListMaintainer() {}
45 void erasedInstr(MachineInstr &MI) override {
46 LLVM_DEBUG(dbgs() << "Erased: "; MI.print(dbgs()); dbgs() << "\n");
47 WorkList.remove(&MI);
49 void createdInstr(MachineInstr &MI) override {
50 LLVM_DEBUG(dbgs() << "Created: "; MI.print(dbgs()); dbgs() << "\n");
51 WorkList.insert(&MI);
56 Combiner::Combiner(CombinerInfo &Info, const TargetPassConfig *TPC)
57 : CInfo(Info), TPC(TPC) {
58 (void)this->TPC; // FIXME: Remove when used.
61 bool Combiner::combineMachineInstrs(MachineFunction &MF) {
62 // If the ISel pipeline failed, do not bother running this pass.
63 // FIXME: Should this be here or in individual combiner passes.
64 if (MF.getProperties().hasProperty(
65 MachineFunctionProperties::Property::FailedISel))
66 return false;
68 MRI = &MF.getRegInfo();
69 Builder.setMF(MF);
71 LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');
73 MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
75 bool MFChanged = false;
76 bool Changed;
78 do {
79 // Collect all instructions. Do a post order traversal for basic blocks and
80 // insert with list bottom up, so while we pop_back_val, we'll traverse top
81 // down RPOT.
82 Changed = false;
83 GISelWorkList<512> WorkList;
84 WorkListMaintainer Observer(WorkList);
85 for (MachineBasicBlock *MBB : post_order(&MF)) {
86 if (MBB->empty())
87 continue;
88 for (auto MII = MBB->rbegin(), MIE = MBB->rend(); MII != MIE;) {
89 MachineInstr *CurMI = &*MII;
90 ++MII;
91 // Erase dead insts before even adding to the list.
92 if (isTriviallyDead(*CurMI, *MRI)) {
93 LLVM_DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
94 CurMI->eraseFromParentAndMarkDBGValuesForRemoval();
95 continue;
97 WorkList.insert(CurMI);
100 // Main Loop. Process the instructions here.
101 while (!WorkList.empty()) {
102 MachineInstr *CurrInst = WorkList.pop_back_val();
103 LLVM_DEBUG(dbgs() << "Try combining " << *CurrInst << "\n";);
104 Changed |= CInfo.combine(Observer, *CurrInst, Builder);
106 MFChanged |= Changed;
107 } while (Changed);
109 return MFChanged;