LLVM  8.0.1
Combiner.cpp
Go to the documentation of this file.
1 //===-- lib/CodeGen/GlobalISel/Combiner.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 
25 #include "llvm/Support/Debug.h"
26 
27 #define DEBUG_TYPE "gi-combiner"
28 
29 using namespace llvm;
30 
31 namespace {
32 /// This class acts as the glue the joins the CombinerHelper to the overall
33 /// Combine algorithm. The CombinerHelper is intended to report the
34 /// modifications it makes to the MIR to the GISelChangeObserver and the
35 /// observer subclass will act on these events. In this case, instruction
36 /// erasure will cancel any future visits to the erased instruction and
37 /// instruction creation will schedule that instruction for a future visit.
38 /// Other Combiner implementations may require more complex behaviour from
39 /// their GISelChangeObserver subclass.
40 class WorkListMaintainer : public GISelChangeObserver {
41  using WorkListTy = GISelWorkList<512>;
42  WorkListTy &WorkList;
43  /// The instructions that have been created but we want to report once they
44  /// have their operands. This is only maintained if debug output is requested.
46 
47 public:
48  WorkListMaintainer(WorkListTy &WorkList)
49  : GISelChangeObserver(), WorkList(WorkList) {}
50  virtual ~WorkListMaintainer() {
51  }
52 
53  void erasingInstr(MachineInstr &MI) override {
54  LLVM_DEBUG(dbgs() << "Erased: " << MI << "\n");
55  WorkList.remove(&MI);
56  }
57  void createdInstr(MachineInstr &MI) override {
58  LLVM_DEBUG(dbgs() << "Creating: " << MI << "\n");
59  WorkList.insert(&MI);
60  LLVM_DEBUG(CreatedInstrs.insert(&MI));
61  }
62  void changingInstr(MachineInstr &MI) override {
63  LLVM_DEBUG(dbgs() << "Changing: " << MI << "\n");
64  WorkList.insert(&MI);
65  }
66  void changedInstr(MachineInstr &MI) override {
67  LLVM_DEBUG(dbgs() << "Changed: " << MI << "\n");
68  WorkList.insert(&MI);
69  }
70 
71  void reportFullyCreatedInstrs() {
72  LLVM_DEBUG(for (const auto *MI
73  : CreatedInstrs) {
74  dbgs() << "Created: ";
75  MI->print(dbgs());
76  });
77  LLVM_DEBUG(CreatedInstrs.clear());
78  }
79 };
80 }
81 
83  : CInfo(Info), TPC(TPC) {
84  (void)this->TPC; // FIXME: Remove when used.
85 }
86 
88  GISelCSEInfo *CSEInfo) {
89  // If the ISel pipeline failed, do not bother running this pass.
90  // FIXME: Should this be here or in individual combiner passes.
91  if (MF.getProperties().hasProperty(
93  return false;
94 
95  Builder =
96  CSEInfo ? make_unique<CSEMIRBuilder>() : make_unique<MachineIRBuilder>();
97  MRI = &MF.getRegInfo();
98  Builder->setMF(MF);
99  if (CSEInfo)
100  Builder->setCSEInfo(CSEInfo);
101 
102  LLVM_DEBUG(dbgs() << "Generic MI Combiner for: " << MF.getName() << '\n');
103 
104  MachineOptimizationRemarkEmitter MORE(MF, /*MBFI=*/nullptr);
105 
106  bool MFChanged = false;
107  bool Changed;
108  MachineIRBuilder &B = *Builder.get();
109 
110  do {
111  // Collect all instructions. Do a post order traversal for basic blocks and
112  // insert with list bottom up, so while we pop_back_val, we'll traverse top
113  // down RPOT.
114  Changed = false;
115  GISelWorkList<512> WorkList;
116  WorkListMaintainer Observer(WorkList);
117  GISelObserverWrapper WrapperObserver(&Observer);
118  if (CSEInfo)
119  WrapperObserver.addObserver(CSEInfo);
120  RAIIDelegateInstaller DelInstall(MF, &WrapperObserver);
121  for (MachineBasicBlock *MBB : post_order(&MF)) {
122  if (MBB->empty())
123  continue;
124  for (auto MII = MBB->rbegin(), MIE = MBB->rend(); MII != MIE;) {
125  MachineInstr *CurMI = &*MII;
126  ++MII;
127  // Erase dead insts before even adding to the list.
128  if (isTriviallyDead(*CurMI, *MRI)) {
129  LLVM_DEBUG(dbgs() << *CurMI << "Is dead; erasing.\n");
131  continue;
132  }
133  WorkList.insert(CurMI);
134  }
135  }
136  // Main Loop. Process the instructions here.
137  while (!WorkList.empty()) {
138  MachineInstr *CurrInst = WorkList.pop_back_val();
139  LLVM_DEBUG(dbgs() << "\nTry combining " << *CurrInst;);
140  Changed |= CInfo.combine(WrapperObserver, *CurrInst, B);
141  Observer.reportFullyCreatedInstrs();
142  }
143  MFChanged |= Changed;
144  } while (Changed);
145 
146  return MFChanged;
147 }
A simple RAII based CSEInfo installer.
The CSE Analysis object.
Definition: CSEInfo.h:69
This class represents lattice values for constants.
Definition: AllocatorList.h:24
const MachineFunctionProperties & getProperties() const
Get the function properties.
bool empty() const
Definition: GISelWorkList.h:39
Combiner(CombinerInfo &CombinerInfo, const TargetPassConfig *TPC)
Definition: Combiner.cpp:82
virtual bool combine(GISelChangeObserver &Observer, MachineInstr &MI, MachineIRBuilder &B) const =0
Attempt to combine instructions using MI as the root.
Target-Independent Code Generator Pass Configuration Options.
void eraseFromParentAndMarkDBGValuesForRemoval()
Unlink &#39;this&#39; from the containing basic block and delete it.
Analysis containing CSE Info
Definition: CSEInfo.cpp:21
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
Abstract class that contains various methods for clients to notify about changes. ...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CombinerInfo & CInfo
Definition: Combiner.h:38
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:371
Helper class to build MachineInstr.
iterator_range< po_iterator< T > > post_order(const T &G)
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
bool combineMachineInstrs(MachineFunction &MF, GISelCSEInfo *CSEInfo)
If CSEInfo is not null, then the Combiner will setup observer for CSEInfo and instantiate a CSEMIRBui...
Definition: Combiner.cpp:87
std::unique_ptr< MachineIRBuilder > Builder
Definition: Combiner.h:42
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:418
The optimization diagnostic interface.
#define MORE()
Definition: regcomp.c:251
MachineInstr * pop_back_val()
Definition: GISelWorkList.h:65
void insert(MachineInstr *I)
Add the specified instruction to the worklist if it isn&#39;t already in it.
Definition: GISelWorkList.h:44
This file declares the MachineIRBuilder class.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
MachineRegisterInfo * MRI
Definition: Combiner.h:40
bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn&#39;t have oth...
Definition: Utils.cpp:135
Representation of each machine instruction.
Definition: MachineInstr.h:64
void addObserver(GISelChangeObserver *O)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
bool hasProperty(Property P) const
IRTranslator LLVM IR MI
Simple wrapper observer that takes several observers, and calls each one for each event...
#define LLVM_DEBUG(X)
Definition: Debug.h:123