diff options
Diffstat (limited to 'clang-r353983/include/llvm/CodeGen/RegisterScavenging.h')
| -rw-r--r-- | clang-r353983/include/llvm/CodeGen/RegisterScavenging.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/CodeGen/RegisterScavenging.h b/clang-r353983/include/llvm/CodeGen/RegisterScavenging.h new file mode 100644 index 00000000..478ea38e --- /dev/null +++ b/clang-r353983/include/llvm/CodeGen/RegisterScavenging.h @@ -0,0 +1,230 @@ +//===- RegisterScavenging.h - Machine register scavenging -------*- 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 +/// This file declares the machine register scavenger class. It can provide +/// information such as unused register at any point in a machine basic block. +/// It also provides a mechanism to make registers available by evicting them +/// to spill slots. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H +#define LLVM_CODEGEN_REGISTERSCAVENGING_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/LiveRegUnits.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/MC/LaneBitmask.h" + +namespace llvm { + +class MachineInstr; +class TargetInstrInfo; +class TargetRegisterClass; +class TargetRegisterInfo; + +class RegScavenger { + const TargetRegisterInfo *TRI; + const TargetInstrInfo *TII; + MachineRegisterInfo* MRI; + MachineBasicBlock *MBB = nullptr; + MachineBasicBlock::iterator MBBI; + unsigned NumRegUnits = 0; + + /// True if RegScavenger is currently tracking the liveness of registers. + bool Tracking = false; + + /// Information on scavenged registers (held in a spill slot). + struct ScavengedInfo { + ScavengedInfo(int FI = -1) : FrameIndex(FI) {} + + /// A spill slot used for scavenging a register post register allocation. + int FrameIndex; + + /// If non-zero, the specific register is currently being + /// scavenged. That is, it is spilled to this scavenging stack slot. + unsigned Reg = 0; + + /// The instruction that restores the scavenged register from stack. + const MachineInstr *Restore = nullptr; + }; + + /// A vector of information on scavenged registers. + SmallVector<ScavengedInfo, 2> Scavenged; + + LiveRegUnits LiveUnits; + + // These BitVectors are only used internally to forward(). They are members + // to avoid frequent reallocations. + BitVector KillRegUnits, DefRegUnits; + BitVector TmpRegUnits; + +public: + RegScavenger() = default; + + /// Start tracking liveness from the begin of basic block \p MBB. + void enterBasicBlock(MachineBasicBlock &MBB); + + /// Start tracking liveness from the end of basic block \p MBB. + /// Use backward() to move towards the beginning of the block. This is + /// preferred to enterBasicBlock() and forward() because it does not depend + /// on the presence of kill flags. + void enterBasicBlockEnd(MachineBasicBlock &MBB); + + /// Move the internal MBB iterator and update register states. + void forward(); + + /// Move the internal MBB iterator and update register states until + /// it has processed the specific iterator. + void forward(MachineBasicBlock::iterator I) { + if (!Tracking && MBB->begin() != I) forward(); + while (MBBI != I) forward(); + } + + /// Invert the behavior of forward() on the current instruction (undo the + /// changes to the available registers made by forward()). + void unprocess(); + + /// Unprocess instructions until you reach the provided iterator. + void unprocess(MachineBasicBlock::iterator I) { + while (MBBI != I) unprocess(); + } + + /// Update internal register state and move MBB iterator backwards. + /// Contrary to unprocess() this method gives precise results even in the + /// absence of kill flags. + void backward(); + + /// Call backward() as long as the internal iterator does not point to \p I. + void backward(MachineBasicBlock::iterator I) { + while (MBBI != I) + backward(); + } + + /// Move the internal MBB iterator but do not update register states. + void skipTo(MachineBasicBlock::iterator I) { + if (I == MachineBasicBlock::iterator(nullptr)) + Tracking = false; + MBBI = I; + } + + MachineBasicBlock::iterator getCurrentPosition() const { return MBBI; } + + /// Return if a specific register is currently used. + bool isRegUsed(unsigned Reg, bool includeReserved = true) const; + + /// Return all available registers in the register class in Mask. + BitVector getRegsAvailable(const TargetRegisterClass *RC); + + /// Find an unused register of the specified register class. + /// Return 0 if none is found. + unsigned FindUnusedReg(const TargetRegisterClass *RC) const; + + /// Add a scavenging frame index. + void addScavengingFrameIndex(int FI) { + Scavenged.push_back(ScavengedInfo(FI)); + } + + /// Query whether a frame index is a scavenging frame index. + bool isScavengingFrameIndex(int FI) const { + for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex == FI) + return true; + + return false; + } + + /// Get an array of scavenging frame indices. + void getScavengingFrameIndices(SmallVectorImpl<int> &A) const { + for (SmallVectorImpl<ScavengedInfo>::const_iterator I = Scavenged.begin(), + IE = Scavenged.end(); I != IE; ++I) + if (I->FrameIndex >= 0) + A.push_back(I->FrameIndex); + } + + /// Make a register of the specific register class + /// available and do the appropriate bookkeeping. SPAdj is the stack + /// adjustment due to call frame, it's passed along to eliminateFrameIndex(). + /// Returns the scavenged register. + /// This is deprecated as it depends on the quality of the kill flags being + /// present; Use scavengeRegisterBackwards() instead! + unsigned scavengeRegister(const TargetRegisterClass *RC, + MachineBasicBlock::iterator I, int SPAdj); + unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) { + return scavengeRegister(RegClass, MBBI, SPAdj); + } + + /// Make a register of the specific register class available from the current + /// position backwards to the place before \p To. If \p RestoreAfter is true + /// this includes the instruction following the current position. + /// SPAdj is the stack adjustment due to call frame, it's passed along to + /// eliminateFrameIndex(). + /// Returns the scavenged register. + unsigned scavengeRegisterBackwards(const TargetRegisterClass &RC, + MachineBasicBlock::iterator To, + bool RestoreAfter, int SPAdj); + + /// Tell the scavenger a register is used. + void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll()); + +private: + /// Returns true if a register is reserved. It is never "unused". + bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); } + + /// setUsed / setUnused - Mark the state of one or a number of register units. + /// + void setUsed(const BitVector &RegUnits) { + LiveUnits.addUnits(RegUnits); + } + void setUnused(const BitVector &RegUnits) { + LiveUnits.removeUnits(RegUnits); + } + + /// Processes the current instruction and fill the KillRegUnits and + /// DefRegUnits bit vectors. + void determineKillsAndDefs(); + + /// Add all Reg Units that Reg contains to BV. + void addRegUnits(BitVector &BV, unsigned Reg); + + /// Remove all Reg Units that \p Reg contains from \p BV. + void removeRegUnits(BitVector &BV, unsigned Reg); + + /// Return the candidate register that is unused for the longest after + /// StartMI. UseMI is set to the instruction where the search stopped. + /// + /// No more than InstrLimit instructions are inspected. + unsigned findSurvivorReg(MachineBasicBlock::iterator StartMI, + BitVector &Candidates, + unsigned InstrLimit, + MachineBasicBlock::iterator &UseMI); + + /// Initialize RegisterScavenger. + void init(MachineBasicBlock &MBB); + + /// Mark live-in registers of basic block as used. + void setLiveInsUsed(const MachineBasicBlock &MBB); + + /// Spill a register after position \p After and reload it before position + /// \p UseMI. + ScavengedInfo &spill(unsigned Reg, const TargetRegisterClass &RC, int SPAdj, + MachineBasicBlock::iterator Before, + MachineBasicBlock::iterator &UseMI); +}; + +/// Replaces all frame index virtual registers with physical registers. Uses the +/// register scavenger to find an appropriate register to use. +void scavengeFrameVirtualRegs(MachineFunction &MF, RegScavenger &RS); + +} // end namespace llvm + +#endif // LLVM_CODEGEN_REGISTERSCAVENGING_H |
