10b57cec5SDimitry Andric //== ----- llvm/CodeGen/GlobalISel/Combiner.h -------------------*- C++ -*-== //
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric /// \file
95f757f3fSDimitry Andric /// This contains the base class for all Combiners generated by TableGen.
105f757f3fSDimitry Andric /// Backends need to create class that inherits from "Combiner" and put all of
115f757f3fSDimitry Andric /// the TableGen-erated code in there, as it implements the virtual functions.
12fe6060f1SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_GLOBALISEL_COMBINER_H
160b57cec5SDimitry Andric #define LLVM_CODEGEN_GLOBALISEL_COMBINER_H
170b57cec5SDimitry Andric 
185f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h"
195f757f3fSDimitry Andric #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric class MachineRegisterInfo;
245f757f3fSDimitry Andric struct CombinerInfo;
250b57cec5SDimitry Andric class GISelCSEInfo;
260b57cec5SDimitry Andric class TargetPassConfig;
270b57cec5SDimitry Andric class MachineFunction;
285f757f3fSDimitry Andric class MachineIRBuilder;
290b57cec5SDimitry Andric 
305f757f3fSDimitry Andric /// Combiner implementation. This is per-function, so passes need to recreate
315f757f3fSDimitry Andric /// one of these each time they enter a new function.
325f757f3fSDimitry Andric ///
335f757f3fSDimitry Andric /// TODO: Is it worth making this module-wide?
345f757f3fSDimitry Andric class Combiner : public GIMatchTableExecutor {
355f757f3fSDimitry Andric private:
365f757f3fSDimitry Andric   class WorkListMaintainer;
375f757f3fSDimitry Andric   GISelWorkList<512> WorkList;
385f757f3fSDimitry Andric 
395f757f3fSDimitry Andric   // We have a little hack here where keep the owned pointers private, and only
405f757f3fSDimitry Andric   // expose a reference. This has two purposes:
415f757f3fSDimitry Andric   //  - Avoid derived classes messing with those pointers.
425f757f3fSDimitry Andric   //  - Keep the API consistent. CInfo, MF, MRI, etc. are all accessed as
435f757f3fSDimitry Andric   //  references. Accessing Observer/B as pointers unnecessarily leaks
445f757f3fSDimitry Andric   //  implementation details into derived classes.
455f757f3fSDimitry Andric   std::unique_ptr<MachineIRBuilder> Builder;
465f757f3fSDimitry Andric   std::unique_ptr<WorkListMaintainer> WLObserver;
475f757f3fSDimitry Andric   std::unique_ptr<GISelObserverWrapper> ObserverWrapper;
485f757f3fSDimitry Andric 
495f757f3fSDimitry Andric   bool HasSetupMF = false;
505f757f3fSDimitry Andric 
510b57cec5SDimitry Andric public:
525f757f3fSDimitry Andric   /// If CSEInfo is not null, then the Combiner will use CSEInfo as the observer
535f757f3fSDimitry Andric   /// and also create a CSEMIRBuilder. Pass nullptr if CSE is not needed.
545f757f3fSDimitry Andric   Combiner(MachineFunction &MF, CombinerInfo &CInfo,
555f757f3fSDimitry Andric            const TargetPassConfig *TPC, GISelKnownBits *KB,
565f757f3fSDimitry Andric            GISelCSEInfo *CSEInfo = nullptr);
575f757f3fSDimitry Andric   virtual ~Combiner();
580b57cec5SDimitry Andric 
595f757f3fSDimitry Andric   virtual bool tryCombineAll(MachineInstr &I) const = 0;
605f757f3fSDimitry Andric 
615f757f3fSDimitry Andric   bool combineMachineInstrs();
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric protected:
640b57cec5SDimitry Andric   CombinerInfo &CInfo;
655f757f3fSDimitry Andric   GISelChangeObserver &Observer;
665f757f3fSDimitry Andric   MachineIRBuilder &B;
675f757f3fSDimitry Andric   MachineFunction &MF;
685f757f3fSDimitry Andric   MachineRegisterInfo &MRI;
695f757f3fSDimitry Andric   GISelKnownBits *KB;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   const TargetPassConfig *TPC;
725f757f3fSDimitry Andric   GISelCSEInfo *CSEInfo;
730b57cec5SDimitry Andric };
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric } // End namespace llvm.
760b57cec5SDimitry Andric 
77fe6060f1SDimitry Andric #endif // LLVM_CODEGEN_GLOBALISEL_COMBINER_H
78