1 | //== ----- llvm/CodeGen/GlobalISel/Combiner.h -------------------*- C++ -*-== // |
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 | /// \file |
9 | /// This contains the base class for all Combiners generated by TableGen. |
10 | /// Backends need to create class that inherits from "Combiner" and put all of |
11 | /// the TableGen-erated code in there, as it implements the virtual functions. |
12 | /// |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CODEGEN_GLOBALISEL_COMBINER_H |
16 | #define LLVM_CODEGEN_GLOBALISEL_COMBINER_H |
17 | |
18 | #include "llvm/CodeGen/GlobalISel/CombinerInfo.h" |
19 | #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h" |
20 | #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" |
21 | #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" |
22 | |
23 | namespace llvm { |
24 | class MachineRegisterInfo; |
25 | class GISelCSEInfo; |
26 | class TargetPassConfig; |
27 | class MachineFunction; |
28 | class MachineIRBuilder; |
29 | |
30 | /// Combiner implementation. This is per-function, so passes need to recreate |
31 | /// one of these each time they enter a new function. |
32 | /// |
33 | /// TODO: Is it worth making this module-wide? |
34 | class Combiner : public GIMatchTableExecutor { |
35 | private: |
36 | using WorkListTy = GISelWorkList<512>; |
37 | |
38 | class WorkListMaintainer; |
39 | template <CombinerInfo::ObserverLevel Lvl> class WorkListMaintainerImpl; |
40 | |
41 | WorkListTy WorkList; |
42 | |
43 | // We have a little hack here where keep the owned pointers private, and only |
44 | // expose a reference. This has two purposes: |
45 | // - Avoid derived classes messing with those pointers. |
46 | // - Keep the API consistent. CInfo, MF, MRI, etc. are all accessed as |
47 | // references. Accessing Observer/B as pointers unnecessarily leaks |
48 | // implementation details into derived classes. |
49 | std::unique_ptr<MachineIRBuilder> Builder; |
50 | std::unique_ptr<WorkListMaintainer> WLObserver; |
51 | std::unique_ptr<GISelObserverWrapper> ObserverWrapper; |
52 | |
53 | bool HasSetupMF = false; |
54 | |
55 | static bool tryDCE(MachineInstr &MI, MachineRegisterInfo &MRI); |
56 | |
57 | public: |
58 | /// If CSEInfo is not null, then the Combiner will use CSEInfo as the observer |
59 | /// and also create a CSEMIRBuilder. Pass nullptr if CSE is not needed. |
60 | Combiner(MachineFunction &MF, CombinerInfo &CInfo, |
61 | const TargetPassConfig *TPC, GISelValueTracking *VT, |
62 | GISelCSEInfo *CSEInfo = nullptr); |
63 | virtual ~Combiner(); |
64 | |
65 | virtual bool tryCombineAll(MachineInstr &I) const = 0; |
66 | |
67 | bool combineMachineInstrs(); |
68 | |
69 | protected: |
70 | CombinerInfo &CInfo; |
71 | GISelChangeObserver &Observer; |
72 | MachineIRBuilder &B; |
73 | MachineFunction &MF; |
74 | MachineRegisterInfo &MRI; |
75 | GISelValueTracking *VT; |
76 | |
77 | const TargetPassConfig *TPC; |
78 | GISelCSEInfo *CSEInfo; |
79 | }; |
80 | |
81 | } // End namespace llvm. |
82 | |
83 | #endif // LLVM_CODEGEN_GLOBALISEL_COMBINER_H |
84 | |