summaryrefslogtreecommitdiff
path: root/clang-r353983/include/llvm/CodeGen/RegisterScavenging.h
diff options
context:
space:
mode:
authorRalf Luther <luther.ralf@gmail.com>2019-03-27 20:23:17 +0000
committerGerrit Code Review <gerrit2@aicp-server-3>2019-03-27 20:23:17 +0000
commit1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch)
tree391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/include/llvm/CodeGen/RegisterScavenging.h
parentd1d48b140bafaa8a50107292f5fce95562575765 (diff)
parent4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff)
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/include/llvm/CodeGen/RegisterScavenging.h')
-rw-r--r--clang-r353983/include/llvm/CodeGen/RegisterScavenging.h230
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