123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/CodeGen/GlobalISel/GISelKnownBits.h ---------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- /// \file
- /// Provides analysis for querying information about KnownBits during GISel
- /// passes.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CODEGEN_GLOBALISEL_GISELKNOWNBITS_H
- #define LLVM_CODEGEN_GLOBALISEL_GISELKNOWNBITS_H
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
- #include "llvm/CodeGen/MachineFunctionPass.h"
- #include "llvm/CodeGen/Register.h"
- #include "llvm/InitializePasses.h"
- #include "llvm/Support/KnownBits.h"
- namespace llvm {
- class TargetLowering;
- class DataLayout;
- class GISelKnownBits : public GISelChangeObserver {
- MachineFunction &MF;
- MachineRegisterInfo &MRI;
- const TargetLowering &TL;
- const DataLayout &DL;
- unsigned MaxDepth;
- /// Cache maintained during a computeKnownBits request.
- SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache;
- void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known,
- const APInt &DemandedElts,
- unsigned Depth = 0);
- unsigned computeNumSignBitsMin(Register Src0, Register Src1,
- const APInt &DemandedElts, unsigned Depth = 0);
- public:
- GISelKnownBits(MachineFunction &MF, unsigned MaxDepth = 6);
- virtual ~GISelKnownBits() = default;
- const MachineFunction &getMachineFunction() const {
- return MF;
- }
- const DataLayout &getDataLayout() const {
- return DL;
- }
- virtual void computeKnownBitsImpl(Register R, KnownBits &Known,
- const APInt &DemandedElts,
- unsigned Depth = 0);
- unsigned computeNumSignBits(Register R, const APInt &DemandedElts,
- unsigned Depth = 0);
- unsigned computeNumSignBits(Register R, unsigned Depth = 0);
- // KnownBitsAPI
- KnownBits getKnownBits(Register R);
- KnownBits getKnownBits(Register R, const APInt &DemandedElts,
- unsigned Depth = 0);
- // Calls getKnownBits for first operand def of MI.
- KnownBits getKnownBits(MachineInstr &MI);
- APInt getKnownZeroes(Register R);
- APInt getKnownOnes(Register R);
- /// \return true if 'V & Mask' is known to be zero in DemandedElts. We use
- /// this predicate to simplify operations downstream.
- /// Mask is known to be zero for bits that V cannot have.
- bool maskedValueIsZero(Register Val, const APInt &Mask) {
- return Mask.isSubsetOf(getKnownBits(Val).Zero);
- }
- /// \return true if the sign bit of Op is known to be zero. We use this
- /// predicate to simplify operations downstream.
- bool signBitIsZero(Register Op);
- static void computeKnownBitsForAlignment(KnownBits &Known,
- Align Alignment) {
- // The low bits are known zero if the pointer is aligned.
- Known.Zero.setLowBits(Log2(Alignment));
- }
- /// \return The known alignment for the pointer-like value \p R.
- Align computeKnownAlignment(Register R, unsigned Depth = 0);
- // Observer API. No-op for non-caching implementation.
- void erasingInstr(MachineInstr &MI) override{};
- void createdInstr(MachineInstr &MI) override{};
- void changingInstr(MachineInstr &MI) override{};
- void changedInstr(MachineInstr &MI) override{};
- protected:
- unsigned getMaxDepth() const { return MaxDepth; }
- };
- /// To use KnownBitsInfo analysis in a pass,
- /// KnownBitsInfo &Info = getAnalysis<GISelKnownBitsInfoAnalysis>().get(MF);
- /// Add to observer if the Info is caching.
- /// WrapperObserver.addObserver(Info);
- /// Eventually add other features such as caching/ser/deserializing
- /// to MIR etc. Those implementations can derive from GISelKnownBits
- /// and override computeKnownBitsImpl.
- class GISelKnownBitsAnalysis : public MachineFunctionPass {
- std::unique_ptr<GISelKnownBits> Info;
- public:
- static char ID;
- GISelKnownBitsAnalysis() : MachineFunctionPass(ID) {
- initializeGISelKnownBitsAnalysisPass(*PassRegistry::getPassRegistry());
- }
- GISelKnownBits &get(MachineFunction &MF) {
- if (!Info)
- Info = std::make_unique<GISelKnownBits>(MF);
- return *Info.get();
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnMachineFunction(MachineFunction &MF) override;
- void releaseMemory() override { Info.reset(); }
- };
- } // namespace llvm
- #endif // LLVM_CODEGEN_GLOBALISEL_GISELKNOWNBITS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|