GISelKnownBits.h revision 360784
1//===- llvm/CodeGen/GlobalISel/GISelKnownBits.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//
9/// Provides analysis for querying information about KnownBits during GISel
10/// passes.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
14#define LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
15
16#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
17#include "llvm/CodeGen/MachineFunctionPass.h"
18#include "llvm/CodeGen/Register.h"
19#include "llvm/IR/PassManager.h"
20#include "llvm/InitializePasses.h"
21#include "llvm/Pass.h"
22#include "llvm/Support/KnownBits.h"
23
24namespace llvm {
25
26class TargetLowering;
27class DataLayout;
28
29class GISelKnownBits : public GISelChangeObserver {
30  MachineFunction &MF;
31  MachineRegisterInfo &MRI;
32  const TargetLowering &TL;
33  const DataLayout &DL;
34
35public:
36  GISelKnownBits(MachineFunction &MF);
37  virtual ~GISelKnownBits() = default;
38  void setMF(MachineFunction &MF);
39  virtual void computeKnownBitsImpl(Register R, KnownBits &Known,
40                                    const APInt &DemandedElts,
41                                    unsigned Depth = 0);
42
43  unsigned computeNumSignBits(Register R, const APInt &DemandedElts,
44                              unsigned Depth = 0);
45  unsigned computeNumSignBits(Register R, unsigned Depth = 0);
46
47  // KnownBitsAPI
48  KnownBits getKnownBits(Register R);
49  // Calls getKnownBits for first operand def of MI.
50  KnownBits getKnownBits(MachineInstr &MI);
51  APInt getKnownZeroes(Register R);
52  APInt getKnownOnes(Register R);
53
54  /// \return true if 'V & Mask' is known to be zero in DemandedElts. We use
55  /// this predicate to simplify operations downstream.
56  /// Mask is known to be zero for bits that V cannot have.
57  bool maskedValueIsZero(Register Val, const APInt &Mask) {
58    return Mask.isSubsetOf(getKnownBits(Val).Zero);
59  }
60
61  /// \return true if the sign bit of Op is known to be zero.  We use this
62  /// predicate to simplify operations downstream.
63  bool signBitIsZero(Register Op);
64
65  // FIXME: Is this the right place for G_FRAME_INDEX? Should it be in
66  // TargetLowering?
67  void computeKnownBitsForFrameIndex(Register R, KnownBits &Known,
68                                     const APInt &DemandedElts,
69                                     unsigned Depth = 0);
70  static Align inferAlignmentForFrameIdx(int FrameIdx, int Offset,
71                                         const MachineFunction &MF);
72  static void computeKnownBitsForAlignment(KnownBits &Known,
73                                           MaybeAlign Alignment);
74
75  // Try to infer alignment for MI.
76  static MaybeAlign inferPtrAlignment(const MachineInstr &MI);
77
78  // Observer API. No-op for non-caching implementation.
79  void erasingInstr(MachineInstr &MI) override{};
80  void createdInstr(MachineInstr &MI) override{};
81  void changingInstr(MachineInstr &MI) override{};
82  void changedInstr(MachineInstr &MI) override{};
83
84protected:
85  unsigned getMaxDepth() const { return 6; }
86};
87
88/// To use KnownBitsInfo analysis in a pass,
89/// KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis>().get(MF);
90/// Add to observer if the Info is caching.
91/// WrapperObserver.addObserver(Info);
92
93/// Eventually add other features such as caching/ser/deserializing
94/// to MIR etc. Those implementations can derive from GISelKnownBits
95/// and override computeKnownBitsImpl.
96class GISelKnownBitsAnalysis : public MachineFunctionPass {
97  std::unique_ptr<GISelKnownBits> Info;
98
99public:
100  static char ID;
101  GISelKnownBitsAnalysis() : MachineFunctionPass(ID) {
102    initializeGISelKnownBitsAnalysisPass(*PassRegistry::getPassRegistry());
103  }
104  GISelKnownBits &get(MachineFunction &MF) {
105    if (!Info)
106      Info = std::make_unique<GISelKnownBits>(MF);
107    return *Info.get();
108  }
109  void getAnalysisUsage(AnalysisUsage &AU) const override;
110  bool runOnMachineFunction(MachineFunction &MF) override;
111  void releaseMemory() override { Info.reset(); }
112};
113} // namespace llvm
114
115#endif // ifdef
116