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