1319140Sdim//== llvm/CodeGen/GlobalISel/Localizer.h - Localizer -------------*- C++ -*-==//
2319140Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6319140Sdim//
7319140Sdim//===----------------------------------------------------------------------===//
8319140Sdim//
9319140Sdim/// \file This file describes the interface of the Localizer pass.
10319140Sdim/// This pass moves/duplicates constant-like instructions close to their uses.
11319140Sdim/// Its primarily goal is to workaround the deficiencies of the fast register
12319140Sdim/// allocator.
13319140Sdim/// With GlobalISel constants are all materialized in the entry block of
14319140Sdim/// a function. However, the fast allocator cannot rematerialize constants and
15319140Sdim/// has a lot more live-ranges to deal with and will most likely end up
16319140Sdim/// spilling a lot.
17319140Sdim/// By pushing the constants close to their use, we only create small
18319140Sdim/// live-ranges.
19319140Sdim//===----------------------------------------------------------------------===//
20319140Sdim
21319140Sdim#ifndef LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
22319140Sdim#define LLVM_CODEGEN_GLOBALISEL_LOCALIZER_H
23319140Sdim
24353358Sdim#include "llvm/ADT/SetVector.h"
25319140Sdim#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
26319140Sdim#include "llvm/CodeGen/MachineFunctionPass.h"
27319140Sdim
28319140Sdimnamespace llvm {
29319140Sdim// Forward declarations.
30319140Sdimclass MachineRegisterInfo;
31353358Sdimclass TargetTransformInfo;
32319140Sdim
33319140Sdim/// This pass implements the localization mechanism described at the
34319140Sdim/// top of this file. One specificity of the implementation is that
35319140Sdim/// it will materialize one and only one instance of a constant per
36319140Sdim/// basic block, thus enabling reuse of that constant within that block.
37319140Sdim/// Moreover, it only materializes constants in blocks where they
38319140Sdim/// are used. PHI uses are considered happening at the end of the
39319140Sdim/// related predecessor.
40319140Sdimclass Localizer : public MachineFunctionPass {
41319140Sdimpublic:
42319140Sdim  static char ID;
43319140Sdim
44319140Sdimprivate:
45360784Sdim  /// An input function to decide if the pass should run or not
46360784Sdim  /// on the given MachineFunction.
47360784Sdim  std::function<bool(const MachineFunction &)> DoNotRunPass;
48360784Sdim
49319140Sdim  /// MRI contains all the register class/bank information that this
50319140Sdim  /// pass uses and updates.
51319140Sdim  MachineRegisterInfo *MRI;
52353358Sdim  /// TTI used for getting remat costs for instructions.
53353358Sdim  TargetTransformInfo *TTI;
54319140Sdim
55319140Sdim  /// Check whether or not \p MI needs to be moved close to its uses.
56353358Sdim  bool shouldLocalize(const MachineInstr &MI);
57319140Sdim
58319140Sdim  /// Check if \p MOUse is used in the same basic block as \p Def.
59319140Sdim  /// If the use is in the same block, we say it is local.
60319140Sdim  /// When the use is not local, \p InsertMBB will contain the basic
61319140Sdim  /// block when to insert \p Def to have a local use.
62319140Sdim  static bool isLocalUse(MachineOperand &MOUse, const MachineInstr &Def,
63319140Sdim                         MachineBasicBlock *&InsertMBB);
64319140Sdim
65319140Sdim  /// Initialize the field members using \p MF.
66319140Sdim  void init(MachineFunction &MF);
67319140Sdim
68353358Sdim  typedef SmallSetVector<MachineInstr *, 32> LocalizedSetVecT;
69353358Sdim
70353358Sdim  /// Do inter-block localization from the entry block.
71353358Sdim  bool localizeInterBlock(MachineFunction &MF,
72353358Sdim                          LocalizedSetVecT &LocalizedInstrs);
73353358Sdim
74353358Sdim  /// Do intra-block localization of already localized instructions.
75353358Sdim  bool localizeIntraBlock(LocalizedSetVecT &LocalizedInstrs);
76353358Sdim
77319140Sdimpublic:
78319140Sdim  Localizer();
79360784Sdim  Localizer(std::function<bool(const MachineFunction &)>);
80319140Sdim
81319140Sdim  StringRef getPassName() const override { return "Localizer"; }
82319140Sdim
83319140Sdim  MachineFunctionProperties getRequiredProperties() const override {
84319140Sdim    return MachineFunctionProperties()
85319140Sdim        .set(MachineFunctionProperties::Property::IsSSA)
86319140Sdim        .set(MachineFunctionProperties::Property::Legalized)
87319140Sdim        .set(MachineFunctionProperties::Property::RegBankSelected);
88319140Sdim  }
89319140Sdim
90341825Sdim  void getAnalysisUsage(AnalysisUsage &AU) const override;
91341825Sdim
92319140Sdim  bool runOnMachineFunction(MachineFunction &MF) override;
93319140Sdim};
94319140Sdim
95319140Sdim} // End namespace llvm.
96319140Sdim
97319140Sdim#endif
98