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
23namespace llvm {
24class MachineRegisterInfo;
25class GISelCSEInfo;
26class TargetPassConfig;
27class MachineFunction;
28class 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?
34class Combiner : public GIMatchTableExecutor {
35private:
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
57public:
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
69protected:
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