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 
24 namespace llvm {
25 
26 class TargetLowering;
27 class DataLayout;
28 
29 class GISelKnownBits : public GISelChangeObserver {
30   MachineFunction &MF;
31   MachineRegisterInfo &MRI;
32   const TargetLowering &TL;
33   const DataLayout &DL;
34 
35 public:
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 
84 protected:
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.
96 class GISelKnownBitsAnalysis : public MachineFunctionPass {
97   std::unique_ptr<GISelKnownBits> Info;
98 
99 public:
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