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/ADT/DenseMap.h" 17 #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" 18 #include "llvm/CodeGen/MachineFunctionPass.h" 19 #include "llvm/CodeGen/Register.h" 20 #include "llvm/InitializePasses.h" 21 #include "llvm/Support/KnownBits.h" 22 23 namespace llvm { 24 25 class TargetLowering; 26 class DataLayout; 27 28 class GISelKnownBits : public GISelChangeObserver { 29 MachineFunction &MF; 30 MachineRegisterInfo &MRI; 31 const TargetLowering &TL; 32 const DataLayout &DL; 33 unsigned MaxDepth; 34 /// Cache maintained during a computeKnownBits request. 35 SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache; 36 37 void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known, 38 const APInt &DemandedElts, 39 unsigned Depth = 0); 40 41 unsigned computeNumSignBitsMin(Register Src0, Register Src1, 42 const APInt &DemandedElts, unsigned Depth = 0); 43 44 public: 45 GISelKnownBits(MachineFunction &MF, unsigned MaxDepth = 6); 46 virtual ~GISelKnownBits() = default; 47 getMachineFunction()48 const MachineFunction &getMachineFunction() const { 49 return MF; 50 } 51 getDataLayout()52 const DataLayout &getDataLayout() const { 53 return DL; 54 } 55 56 virtual void computeKnownBitsImpl(Register R, KnownBits &Known, 57 const APInt &DemandedElts, 58 unsigned Depth = 0); 59 60 unsigned computeNumSignBits(Register R, const APInt &DemandedElts, 61 unsigned Depth = 0); 62 unsigned computeNumSignBits(Register R, unsigned Depth = 0); 63 64 // KnownBitsAPI 65 KnownBits getKnownBits(Register R); 66 KnownBits getKnownBits(Register R, const APInt &DemandedElts, 67 unsigned Depth = 0); 68 69 // Calls getKnownBits for first operand def of MI. 70 KnownBits getKnownBits(MachineInstr &MI); 71 APInt getKnownZeroes(Register R); 72 APInt getKnownOnes(Register R); 73 74 /// \return true if 'V & Mask' is known to be zero in DemandedElts. We use 75 /// this predicate to simplify operations downstream. 76 /// Mask is known to be zero for bits that V cannot have. maskedValueIsZero(Register Val,const APInt & Mask)77 bool maskedValueIsZero(Register Val, const APInt &Mask) { 78 return Mask.isSubsetOf(getKnownBits(Val).Zero); 79 } 80 81 /// \return true if the sign bit of Op is known to be zero. We use this 82 /// predicate to simplify operations downstream. 83 bool signBitIsZero(Register Op); 84 computeKnownBitsForAlignment(KnownBits & Known,Align Alignment)85 static void computeKnownBitsForAlignment(KnownBits &Known, 86 Align Alignment) { 87 // The low bits are known zero if the pointer is aligned. 88 Known.Zero.setLowBits(Log2(Alignment)); 89 } 90 91 /// \return The known alignment for the pointer-like value \p R. 92 Align computeKnownAlignment(Register R, unsigned Depth = 0); 93 94 // Observer API. No-op for non-caching implementation. erasingInstr(MachineInstr & MI)95 void erasingInstr(MachineInstr &MI) override{}; createdInstr(MachineInstr & MI)96 void createdInstr(MachineInstr &MI) override{}; changingInstr(MachineInstr & MI)97 void changingInstr(MachineInstr &MI) override{}; changedInstr(MachineInstr & MI)98 void changedInstr(MachineInstr &MI) override{}; 99 100 protected: getMaxDepth()101 unsigned getMaxDepth() const { return MaxDepth; } 102 }; 103 104 /// To use KnownBitsInfo analysis in a pass, 105 /// KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis>().get(MF); 106 /// Add to observer if the Info is caching. 107 /// WrapperObserver.addObserver(Info); 108 109 /// Eventually add other features such as caching/ser/deserializing 110 /// to MIR etc. Those implementations can derive from GISelKnownBits 111 /// and override computeKnownBitsImpl. 112 class GISelKnownBitsAnalysis : public MachineFunctionPass { 113 std::unique_ptr<GISelKnownBits> Info; 114 115 public: 116 static char ID; GISelKnownBitsAnalysis()117 GISelKnownBitsAnalysis() : MachineFunctionPass(ID) { 118 initializeGISelKnownBitsAnalysisPass(*PassRegistry::getPassRegistry()); 119 } get(MachineFunction & MF)120 GISelKnownBits &get(MachineFunction &MF) { 121 if (!Info) 122 Info = std::make_unique<GISelKnownBits>(MF); 123 return *Info.get(); 124 } 125 void getAnalysisUsage(AnalysisUsage &AU) const override; 126 bool runOnMachineFunction(MachineFunction &MF) override; releaseMemory()127 void releaseMemory() override { Info.reset(); } 128 }; 129 } // namespace llvm 130 131 #endif // ifdef 132