mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-27 15:29:51 +00:00
a virtual register to eliminate a frame index, it can return that register and the constant stored there to PEI to track. When scavenging to allocate for those registers, PEI then tracks the last-used register and value, and if it is still available and matches the value for the next index, reuses the existing value rather and removes the re-materialization instructions. Fancier tracking and adjustment of scavenger allocations to keep more values live for longer is possible, but not yet implemented and would likely be better done via a different, less special-purpose, approach to the problem. eliminateFrameIndex() is modified so the target implementations can return the registers they wish to be tracked for reuse. ARM Thumb1 implements and utilizes the new mechanism. All other targets are simply modified to adjust for the changed eliminateFrameIndex() prototype. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83467 91177308-0d34-0410-b5e6-96231b3b80d8
160 lines
5.4 KiB
C++
160 lines
5.4 KiB
C++
//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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 availbale by evicting them
|
|
// to spill slots.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
|
|
#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
|
|
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/ADT/BitVector.h"
|
|
|
|
namespace llvm {
|
|
|
|
class MachineRegisterInfo;
|
|
class TargetRegisterInfo;
|
|
class TargetInstrInfo;
|
|
class TargetRegisterClass;
|
|
|
|
class RegScavenger {
|
|
const TargetRegisterInfo *TRI;
|
|
const TargetInstrInfo *TII;
|
|
MachineRegisterInfo* MRI;
|
|
MachineBasicBlock *MBB;
|
|
MachineBasicBlock::iterator MBBI;
|
|
unsigned NumPhysRegs;
|
|
|
|
/// Tracking - True if RegScavenger is currently tracking the liveness of
|
|
/// registers.
|
|
bool Tracking;
|
|
|
|
/// ScavengingFrameIndex - Special spill slot used for scavenging a register
|
|
/// post register allocation.
|
|
int ScavengingFrameIndex;
|
|
|
|
/// ScavengedReg - If none zero, the specific register is currently being
|
|
/// scavenged. That is, it is spilled to the special scavenging stack slot.
|
|
unsigned ScavengedReg;
|
|
|
|
/// ScavengedRC - Register class of the scavenged register.
|
|
///
|
|
const TargetRegisterClass *ScavengedRC;
|
|
|
|
/// ScavengeRestore - Instruction that restores the scavenged register from
|
|
/// stack.
|
|
const MachineInstr *ScavengeRestore;
|
|
|
|
/// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
|
|
///
|
|
BitVector CalleeSavedRegs;
|
|
|
|
/// ReservedRegs - A bitvector of reserved registers.
|
|
///
|
|
BitVector ReservedRegs;
|
|
|
|
/// RegsAvailable - The current state of all the physical registers immediately
|
|
/// before MBBI. One bit per physical register. If bit is set that means it's
|
|
/// available, unset means the register is currently being used.
|
|
BitVector RegsAvailable;
|
|
|
|
public:
|
|
RegScavenger()
|
|
: MBB(NULL), NumPhysRegs(0), Tracking(false),
|
|
ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {}
|
|
|
|
/// enterBasicBlock - Start tracking liveness from the begin of the specific
|
|
/// basic block.
|
|
void enterBasicBlock(MachineBasicBlock *mbb);
|
|
|
|
/// initRegState - allow resetting register state info for multiple
|
|
/// passes over/within the same function.
|
|
void initRegState();
|
|
|
|
/// forward - Move the internal MBB iterator and update register states.
|
|
void forward();
|
|
|
|
/// 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();
|
|
}
|
|
|
|
/// skipTo - Move the internal MBB iterator but do not update register states.
|
|
///
|
|
void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
|
|
|
|
/// getRegsUsed - return all registers currently in use in used.
|
|
void getRegsUsed(BitVector &used, bool includeReserved);
|
|
|
|
/// FindUnusedReg - Find a unused register of the specified register class.
|
|
/// Return 0 if none is found.
|
|
unsigned FindUnusedReg(const TargetRegisterClass *RegClass) const;
|
|
|
|
/// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
|
|
/// ScavengingFrameIndex.
|
|
void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
|
|
int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
|
|
|
|
/// scavengeRegister - 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.
|
|
unsigned scavengeRegister(const TargetRegisterClass *RegClass,
|
|
MachineBasicBlock::iterator I, int SPAdj);
|
|
unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
|
|
return scavengeRegister(RegClass, MBBI, SPAdj);
|
|
}
|
|
|
|
/// setUsed - Tell the scavenger a register is used.
|
|
///
|
|
void setUsed(unsigned Reg);
|
|
private:
|
|
/// isReserved - Returns true if a register is reserved. It is never "unused".
|
|
bool isReserved(unsigned Reg) const { return ReservedRegs.test(Reg); }
|
|
|
|
/// isUsed / isUnused - Test if a register is currently being used.
|
|
///
|
|
bool isUsed(unsigned Reg) const { return !RegsAvailable.test(Reg); }
|
|
bool isUnused(unsigned Reg) const { return RegsAvailable.test(Reg); }
|
|
|
|
/// isAliasUsed - Is Reg or an alias currently in use?
|
|
bool isAliasUsed(unsigned Reg) const;
|
|
|
|
/// setUsed / setUnused - Mark the state of one or a number of registers.
|
|
///
|
|
void setUsed(BitVector &Regs) {
|
|
RegsAvailable &= ~Regs;
|
|
}
|
|
void setUnused(BitVector &Regs) {
|
|
RegsAvailable |= Regs;
|
|
}
|
|
|
|
/// Add Reg and all its sub-registers to BV.
|
|
void addRegWithSubRegs(BitVector &BV, unsigned Reg);
|
|
|
|
/// Add Reg and its aliases to BV.
|
|
void addRegWithAliases(BitVector &BV, unsigned Reg);
|
|
|
|
unsigned findSurvivorReg(MachineBasicBlock::iterator MI,
|
|
BitVector &Candidates,
|
|
unsigned InstrLimit,
|
|
MachineBasicBlock::iterator &UseMI);
|
|
|
|
};
|
|
|
|
} // End llvm namespace
|
|
|
|
#endif
|