//===-- RegisterAliasingTracker.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 /// Defines classes to keep track of register aliasing. /// //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ALIASINGTRACKER_H #define LLVM_TOOLS_LLVM_EXEGESIS_ALIASINGTRACKER_H #include #include #include "llvm/ADT/BitVector.h" #include "llvm/ADT/PackedVector.h" #include "llvm/MC/MCRegisterInfo.h" namespace llvm { namespace exegesis { // Returns the registers that are aliased by the ones set in SourceBits. BitVector getAliasedBits(const MCRegisterInfo &RegInfo, const BitVector &SourceBits); // Keeps track of a mapping from one register (or a register class) to its // aliased registers. // // e.g. // RegisterAliasingTracker Tracker(RegInfo, X86::EAX); // Tracker.sourceBits() == { X86::EAX } // Tracker.aliasedBits() == { X86::AL, X86::AH, X86::AX, // X86::EAX,X86::HAX, X86::RAX } // Tracker.getOrigin(X86::AL) == X86::EAX; // Tracker.getOrigin(X86::BX) == -1; struct RegisterAliasingTracker { // Construct a tracker from an MCRegisterClass. RegisterAliasingTracker(const MCRegisterInfo &RegInfo, const BitVector &ReservedReg, const MCRegisterClass &RegClass); // Construct a tracker from an MCPhysReg. RegisterAliasingTracker(const MCRegisterInfo &RegInfo, const MCPhysReg Register); const BitVector &sourceBits() const { return SourceBits; } // Retrieves all the touched registers as a BitVector. const BitVector &aliasedBits() const { return AliasedBits; } // Returns the origin of this register or -1. int getOrigin(MCPhysReg Aliased) const { if (!AliasedBits[Aliased]) return -1; return Origins[Aliased]; } private: RegisterAliasingTracker(const MCRegisterInfo &RegInfo); RegisterAliasingTracker(const RegisterAliasingTracker &) = delete; void FillOriginAndAliasedBits(const MCRegisterInfo &RegInfo, const BitVector &OriginalBits); BitVector SourceBits; BitVector AliasedBits; PackedVector Origins; // Max 1024 physical registers. }; // A cache of existing trackers. struct RegisterAliasingTrackerCache { // RegInfo must outlive the cache. RegisterAliasingTrackerCache(const MCRegisterInfo &RegInfo, const BitVector &ReservedReg); // Convenient function to retrieve a BitVector of the right size. const BitVector &emptyRegisters() const { return EmptyRegisters; } // Convenient function to retrieve the registers the function body can't use. const BitVector &reservedRegisters() const { return ReservedReg; } // Convenient function to retrieve the underlying MCRegInfo. const MCRegisterInfo ®Info() const { return RegInfo; } // Retrieves the RegisterAliasingTracker for this particular register. const RegisterAliasingTracker &getRegister(MCPhysReg Reg) const; // Retrieves the RegisterAliasingTracker for this particular register class. const RegisterAliasingTracker &getRegisterClass(unsigned RegClassIndex) const; private: const MCRegisterInfo &RegInfo; const BitVector ReservedReg; const BitVector EmptyRegisters; mutable std::unordered_map> Registers; mutable std::unordered_map> RegisterClasses; }; // `a = a & ~b`, optimized for few bit sets in B and no allocation. inline void remove(BitVector &A, const BitVector &B) { assert(A.size() == B.size()); for (auto I : B.set_bits()) A.reset(I); } // Returns a debug string for the list of registers. std::string debugString(const MCRegisterInfo &RegInfo, const BitVector &Regs); } // namespace exegesis } // namespace llvm #endif // LLVM_TOOLS_LLVM_EXEGESIS_ALIASINGTRACKER_H