1 //===- llvm/CodeGen/GlobalISel/GISelKnownBits.h ---------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 /// Provides analysis for querying information about KnownBits during GISel
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
14 #define LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
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"
29 class GISelKnownBits
: public GISelChangeObserver
{
31 MachineRegisterInfo
&MRI
;
32 const TargetLowering
&TL
;
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
,
44 KnownBits
getKnownBits(Register R
);
45 // Calls getKnownBits for first operand def of MI.
46 KnownBits
getKnownBits(MachineInstr
&MI
);
47 APInt
getKnownZeroes(Register R
);
48 APInt
getKnownOnes(Register R
);
50 /// \return true if 'V & Mask' is known to be zero in DemandedElts. We use
51 /// this predicate to simplify operations downstream.
52 /// Mask is known to be zero for bits that V cannot have.
53 bool maskedValueIsZero(Register Val
, const APInt
&Mask
) {
54 return Mask
.isSubsetOf(getKnownBits(Val
).Zero
);
57 /// \return true if the sign bit of Op is known to be zero. We use this
58 /// predicate to simplify operations downstream.
59 bool signBitIsZero(Register Op
);
61 // FIXME: Is this the right place for G_FRAME_INDEX? Should it be in
63 void computeKnownBitsForFrameIndex(Register R
, KnownBits
&Known
,
64 const APInt
&DemandedElts
,
66 static Align
inferAlignmentForFrameIdx(int FrameIdx
, int Offset
,
67 const MachineFunction
&MF
);
68 static void computeKnownBitsForAlignment(KnownBits
&Known
,
69 MaybeAlign Alignment
);
71 // Try to infer alignment for MI.
72 static MaybeAlign
inferPtrAlignment(const MachineInstr
&MI
);
74 // Observer API. No-op for non-caching implementation.
75 void erasingInstr(MachineInstr
&MI
) override
{};
76 void createdInstr(MachineInstr
&MI
) override
{};
77 void changingInstr(MachineInstr
&MI
) override
{};
78 void changedInstr(MachineInstr
&MI
) override
{};
81 unsigned getMaxDepth() const { return 6; }
84 /// To use KnownBitsInfo analysis in a pass,
85 /// KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis>().get(MF);
86 /// Add to observer if the Info is caching.
87 /// WrapperObserver.addObserver(Info);
89 /// Eventually add other features such as caching/ser/deserializing
90 /// to MIR etc. Those implementations can derive from GISelKnownBits
91 /// and override computeKnownBitsImpl.
92 class GISelKnownBitsAnalysis
: public MachineFunctionPass
{
93 std::unique_ptr
<GISelKnownBits
> Info
;
97 GISelKnownBitsAnalysis() : MachineFunctionPass(ID
) {
98 initializeGISelKnownBitsAnalysisPass(*PassRegistry::getPassRegistry());
100 GISelKnownBits
&get(MachineFunction
&MF
) {
102 Info
= std::make_unique
<GISelKnownBits
>(MF
);
105 void getAnalysisUsage(AnalysisUsage
&AU
) const override
;
106 bool runOnMachineFunction(MachineFunction
&MF
) override
;
107 void releaseMemory() override
{ Info
.reset(); }