diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFRegisters.h')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFRegisters.h | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFRegisters.h b/llvm/lib/Target/Hexagon/RDFRegisters.h new file mode 100644 index 000000000000..4afaf80e4659 --- /dev/null +++ b/llvm/lib/Target/Hexagon/RDFRegisters.h @@ -0,0 +1,240 @@ +//===- RDFRegisters.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H +#define LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/MC/LaneBitmask.h" +#include <cassert> +#include <cstdint> +#include <map> +#include <set> +#include <vector> + +namespace llvm { + +class MachineFunction; +class raw_ostream; + +namespace rdf { + + using RegisterId = uint32_t; + + // Template class for a map translating uint32_t into arbitrary types. + // The map will act like an indexed set: upon insertion of a new object, + // it will automatically assign a new index to it. Index of 0 is treated + // as invalid and is never allocated. + template <typename T, unsigned N = 32> + struct IndexedSet { + IndexedSet() { Map.reserve(N); } + + T get(uint32_t Idx) const { + // Index Idx corresponds to Map[Idx-1]. + assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size()); + return Map[Idx-1]; + } + + uint32_t insert(T Val) { + // Linear search. + auto F = llvm::find(Map, Val); + if (F != Map.end()) + return F - Map.begin() + 1; + Map.push_back(Val); + return Map.size(); // Return actual_index + 1. + } + + uint32_t find(T Val) const { + auto F = llvm::find(Map, Val); + assert(F != Map.end()); + return F - Map.begin() + 1; + } + + uint32_t size() const { return Map.size(); } + + using const_iterator = typename std::vector<T>::const_iterator; + + const_iterator begin() const { return Map.begin(); } + const_iterator end() const { return Map.end(); } + + private: + std::vector<T> Map; + }; + + struct RegisterRef { + RegisterId Reg = 0; + LaneBitmask Mask = LaneBitmask::getNone(); + + RegisterRef() = default; + explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll()) + : Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {} + + operator bool() const { + return Reg != 0 && Mask.any(); + } + + bool operator== (const RegisterRef &RR) const { + return Reg == RR.Reg && Mask == RR.Mask; + } + + bool operator!= (const RegisterRef &RR) const { + return !operator==(RR); + } + + bool operator< (const RegisterRef &RR) const { + return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask); + } + }; + + + struct PhysicalRegisterInfo { + PhysicalRegisterInfo(const TargetRegisterInfo &tri, + const MachineFunction &mf); + + static bool isRegMaskId(RegisterId R) { + return Register::isStackSlot(R); + } + + RegisterId getRegMaskId(const uint32_t *RM) const { + return Register::index2StackSlot(RegMasks.find(RM)); + } + + const uint32_t *getRegMaskBits(RegisterId R) const { + return RegMasks.get(Register::stackSlot2Index(R)); + } + + RegisterRef normalize(RegisterRef RR) const; + + bool alias(RegisterRef RA, RegisterRef RB) const { + if (!isRegMaskId(RA.Reg)) + return !isRegMaskId(RB.Reg) ? aliasRR(RA, RB) : aliasRM(RA, RB); + return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB); + } + + std::set<RegisterId> getAliasSet(RegisterId Reg) const; + + RegisterRef getRefForUnit(uint32_t U) const { + return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask); + } + + const BitVector &getMaskUnits(RegisterId MaskId) const { + return MaskInfos[Register::stackSlot2Index(MaskId)].Units; + } + + RegisterRef mapTo(RegisterRef RR, unsigned R) const; + const TargetRegisterInfo &getTRI() const { return TRI; } + + private: + struct RegInfo { + const TargetRegisterClass *RegClass = nullptr; + }; + struct UnitInfo { + RegisterId Reg = 0; + LaneBitmask Mask; + }; + struct MaskInfo { + BitVector Units; + }; + + const TargetRegisterInfo &TRI; + IndexedSet<const uint32_t*> RegMasks; + std::vector<RegInfo> RegInfos; + std::vector<UnitInfo> UnitInfos; + std::vector<MaskInfo> MaskInfos; + + bool aliasRR(RegisterRef RA, RegisterRef RB) const; + bool aliasRM(RegisterRef RR, RegisterRef RM) const; + bool aliasMM(RegisterRef RM, RegisterRef RN) const; + }; + + struct RegisterAggr { + RegisterAggr(const PhysicalRegisterInfo &pri) + : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {} + RegisterAggr(const RegisterAggr &RG) = default; + + bool empty() const { return Units.none(); } + bool hasAliasOf(RegisterRef RR) const; + bool hasCoverOf(RegisterRef RR) const; + + static bool isCoverOf(RegisterRef RA, RegisterRef RB, + const PhysicalRegisterInfo &PRI) { + return RegisterAggr(PRI).insert(RA).hasCoverOf(RB); + } + + RegisterAggr &insert(RegisterRef RR); + RegisterAggr &insert(const RegisterAggr &RG); + RegisterAggr &intersect(RegisterRef RR); + RegisterAggr &intersect(const RegisterAggr &RG); + RegisterAggr &clear(RegisterRef RR); + RegisterAggr &clear(const RegisterAggr &RG); + + RegisterRef intersectWith(RegisterRef RR) const; + RegisterRef clearIn(RegisterRef RR) const; + RegisterRef makeRegRef() const; + + void print(raw_ostream &OS) const; + + struct rr_iterator { + using MapType = std::map<RegisterId, LaneBitmask>; + + private: + MapType Masks; + MapType::iterator Pos; + unsigned Index; + const RegisterAggr *Owner; + + public: + rr_iterator(const RegisterAggr &RG, bool End); + + RegisterRef operator*() const { + return RegisterRef(Pos->first, Pos->second); + } + + rr_iterator &operator++() { + ++Pos; + ++Index; + return *this; + } + + bool operator==(const rr_iterator &I) const { + assert(Owner == I.Owner); + (void)Owner; + return Index == I.Index; + } + + bool operator!=(const rr_iterator &I) const { + return !(*this == I); + } + }; + + rr_iterator rr_begin() const { + return rr_iterator(*this, false); + } + rr_iterator rr_end() const { + return rr_iterator(*this, true); + } + + private: + BitVector Units; + const PhysicalRegisterInfo &PRI; + }; + + // Optionally print the lane mask, if it is not ~0. + struct PrintLaneMaskOpt { + PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {} + LaneBitmask Mask; + }; + raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P); + +} // end namespace rdf + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_HEXAGON_RDFREGISTERS_H |