xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h (revision 297eecfb02bb25902531dbb5c3b9a88caf8adf29)
10b57cec5SDimitry Andric //== llvm/CodeGen/GlobalISel/Localizer.h - Localizer -------------*- 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 //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file This file describes the interface of the Localizer pass.
100b57cec5SDimitry Andric /// This pass moves/duplicates constant-like instructions close to their uses.
110b57cec5SDimitry Andric /// Its primarily goal is to workaround the deficiencies of the fast register
120b57cec5SDimitry Andric /// allocator.
130b57cec5SDimitry Andric /// With GlobalISel constants are all materialized in the entry block of
140b57cec5SDimitry Andric /// a function. However, the fast allocator cannot rematerialize constants and
150b57cec5SDimitry Andric /// has a lot more live-ranges to deal with and will most likely end up
160b57cec5SDimitry Andric /// spilling a lot.
170b57cec5SDimitry Andric /// By pushing the constants close to their use, we only create small
180b57cec5SDimitry Andric /// live-ranges.
190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
220b57cec5SDimitry Andric #define LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace llvm {
280b57cec5SDimitry Andric // Forward declarations.
2981ad6265SDimitry Andric class AnalysisUsage;
3081ad6265SDimitry Andric class MachineBasicBlock;
3181ad6265SDimitry Andric class MachineInstr;
3281ad6265SDimitry Andric class MachineOperand;
330b57cec5SDimitry Andric class MachineRegisterInfo;
340b57cec5SDimitry Andric class TargetTransformInfo;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric /// This pass implements the localization mechanism described at the
370b57cec5SDimitry Andric /// top of this file. One specificity of the implementation is that
380b57cec5SDimitry Andric /// it will materialize one and only one instance of a constant per
390b57cec5SDimitry Andric /// basic block, thus enabling reuse of that constant within that block.
400b57cec5SDimitry Andric /// Moreover, it only materializes constants in blocks where they
410b57cec5SDimitry Andric /// are used. PHI uses are considered happening at the end of the
420b57cec5SDimitry Andric /// related predecessor.
430b57cec5SDimitry Andric class Localizer : public MachineFunctionPass {
440b57cec5SDimitry Andric public:
450b57cec5SDimitry Andric   static char ID;
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric private:
48480093f4SDimitry Andric   /// An input function to decide if the pass should run or not
49480093f4SDimitry Andric   /// on the given MachineFunction.
50480093f4SDimitry Andric   std::function<bool(const MachineFunction &)> DoNotRunPass;
51480093f4SDimitry Andric 
520b57cec5SDimitry Andric   /// MRI contains all the register class/bank information that this
530b57cec5SDimitry Andric   /// pass uses and updates.
5406c3fb27SDimitry Andric   MachineRegisterInfo *MRI = nullptr;
550b57cec5SDimitry Andric   /// TTI used for getting remat costs for instructions.
5606c3fb27SDimitry Andric   TargetTransformInfo *TTI = nullptr;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   /// Check if \p MOUse is used in the same basic block as \p Def.
590b57cec5SDimitry Andric   /// If the use is in the same block, we say it is local.
600b57cec5SDimitry Andric   /// When the use is not local, \p InsertMBB will contain the basic
610b57cec5SDimitry Andric   /// block when to insert \p Def to have a local use.
620b57cec5SDimitry Andric   static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
630b57cec5SDimitry Andric                          MachineBasicBlock *&InsertMBB);
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   /// Initialize the field members using \p MF.
660b57cec5SDimitry Andric   void init(MachineFunction &MF);
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
690b57cec5SDimitry Andric 
70*297eecfbSDimitry Andric   /// If \p Op is a reg operand of a PHI, return the number of total
71*297eecfbSDimitry Andric   /// operands in the PHI that are the same as \p Op, including itself.
72*297eecfbSDimitry Andric   unsigned getNumPhiUses(MachineOperand &Op) const;
73e8d8bef9SDimitry Andric 
740b57cec5SDimitry Andric   /// Do inter-block localization from the entry block.
750b57cec5SDimitry Andric   bool localizeInterBlock(MachineFunction &MF,
760b57cec5SDimitry Andric                           LocalizedSetVecT &LocalizedInstrs);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   /// Do intra-block localization of already localized instructions.
790b57cec5SDimitry Andric   bool localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs);
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric public:
820b57cec5SDimitry Andric   Localizer();
83480093f4SDimitry Andric   Localizer(std::function<bool(const MachineFunction &)>);
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   StringRef getPassName() const override { return "Localizer"; }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   MachineFunctionProperties getRequiredProperties() const override {
880b57cec5SDimitry Andric     return MachineFunctionProperties()
895ffd83dbSDimitry Andric         .set(MachineFunctionProperties::Property::IsSSA);
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
950b57cec5SDimitry Andric };
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric } // End namespace llvm.
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric #endif
100