Line data Source code
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 : //===----------------------------------------------------------------------===//
13 :
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"
23 :
24 : #define DEBUG_TYPE "gi-combiner"
25 :
26 : using namespace llvm;
27 :
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;
40 :
41 : public:
42 157 : WorkListMaintainer(WorkListTy &WorkList) : WorkList(WorkList) {}
43 157 : virtual ~WorkListMaintainer() {}
44 :
45 33 : void erasedInstr(MachineInstr &MI) override {
46 : LLVM_DEBUG(dbgs() << "Erased: "; MI.print(dbgs()); dbgs() << "\n");
47 33 : WorkList.remove(&MI);
48 33 : }
49 15 : void createdInstr(MachineInstr &MI) override {
50 : LLVM_DEBUG(dbgs() << "Created: "; MI.print(dbgs()); dbgs() << "\n");
51 15 : WorkList.insert(&MI);
52 15 : }
53 : };
54 : }
55 :
56 128 : Combiner::Combiner(CombinerInfo &Info, const TargetPassConfig *TPC)
57 128 : : CInfo(Info), TPC(TPC) {
58 : (void)this->TPC; // FIXME: Remove when used.
59 128 : }
60 :
61 128 : 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 128 : if (MF.getProperties().hasProperty(
65 : MachineFunctionProperties::Property::FailedISel))
66 : return false;
67 :
68 128 : MRI = &MF.getRegInfo();
69 128 : Builder.setMF(MF);
70 :
71 : LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');
72 :
73 : MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
74 :
75 : bool MFChanged = false;
76 : bool Changed;
77 :
78 157 : 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 157 : GISelWorkList<512> WorkList;
84 : WorkListMaintainer Observer(WorkList);
85 551 : for (MachineBasicBlock *MBB : post_order(&MF)) {
86 237 : if (MBB->empty())
87 : continue;
88 2098 : 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 1863 : if (isTriviallyDead(*CurMI, *MRI)) {
93 : LLVM_DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
94 24 : CurMI->eraseFromParentAndMarkDBGValuesForRemoval();
95 24 : continue;
96 : }
97 1839 : WorkList.insert(CurMI);
98 : }
99 : }
100 : // Main Loop. Process the instructions here.
101 1978 : while (!WorkList.empty()) {
102 1821 : MachineInstr *CurrInst = WorkList.pop_back_val();
103 : LLVM_DEBUG(dbgs() << "Try combining " << *CurrInst << "\n";);
104 1821 : Changed |= CInfo.combine(Observer, *CurrInst, Builder);
105 : }
106 157 : MFChanged |= Changed;
107 : } while (Changed);
108 :
109 : return MFChanged;
110 : }
|