gecko-dev/ef/Compiler/RegisterAllocator/VirtualRegister.h
1999-11-02 06:38:29 +00:00

387 lines
9.9 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef _VIRTUAL_REGISTER_H_
#define _VIRTUAL_REGISTER_H_
#include "Fundamentals.h"
#include "DoublyLinkedList.h"
#include "FastBitSet.h"
#include "FastBitMatrix.h"
class VirtualRegisterManager;
class VirtualRegister;
class Instruction;
/*
*--------------------------VirtualRegister.h----------------------------
*
* enum VRClass --
*
*-----------------------------------------------------------------------
*/
enum VRClass
{
InvalidRegisterKind,
IntegerRegister,
FloatingPointRegister,
FixedPointRegister,
MemoryRegister,
StackSlotRegister,
MemoryArgumentRegister,
nVRClass
};
const VRClass vrcUnspecified = InvalidRegisterKind;
const VRClass vrcInteger = IntegerRegister;
const VRClass vrcFloatingPoint = FloatingPointRegister;
const VRClass vrcFixedPoint = FixedPointRegister;
const VRClass vrcStackSlot = StackSlotRegister;
typedef VRClass VirtualRegisterKind;
/*
*--------------------------VirtualRegister.h----------------------------
*
* class VirtualRegisterPtr --
*
*-----------------------------------------------------------------------
*/
class VirtualRegisterPtr : public DoublyLinkedEntry<VirtualRegisterPtr>
{
friend class VirtualRegisterManager;
friend class VirtualRegister;
private:
VirtualRegister* virtualRegisterAddress;
VRClass registerClassConstraint;
inline VirtualRegister* link(VirtualRegister* vReg);
inline VirtualRegister* unlink();
public:
#if DEBUG
/*
* Copying a VirtualRegisterPtr is forbidden.
*/
VirtualRegisterPtr(const VirtualRegisterPtr& vRegPtr) {PR_ASSERT(0);}
void operator = (const VirtualRegisterPtr& vRegPtr) {PR_ASSERT(0);}
#endif
/*
* Constructors & destructors.
*/
inline VirtualRegisterPtr() : virtualRegisterAddress(NULL), registerClassConstraint(vrcInteger) {}
~VirtualRegisterPtr() {unlink();}
/*
* Initialization.
*/
inline bool isInitialized() {return (virtualRegisterAddress != NULL) ? true : false;}
inline void initialize(VirtualRegister& vReg, VRClass constraint = vrcInteger);
inline void uninitialize() {unlink(); DEBUG_ONLY(registerClassConstraint = vrcUnspecified;)}
/*
* Getting the virtual registers or the register class constraint.
*/
inline VirtualRegister& getVirtualRegister() {return *virtualRegisterAddress;}
inline VRClass getClassConstraint() {return registerClassConstraint;}
inline void setClassConstraint(VRClass constraint) {registerClassConstraint = constraint;}
};
/*
*--------------------------VirtualRegister.h----------------------------
*
* class VirtualRegister --
*
*-----------------------------------------------------------------------
*/
class VirtualRegister
{
friend class VirtualRegisterManager;
private:
DoublyLinkedList<VirtualRegisterPtr> virtualRegisterPtrs;
Instruction* definingInstruction;
VirtualRegisterManager& registerManager;
PRUint32 registerIndex;
VRClass registerClass;
bool isMachineRegister;
/*
* Copying a VirtualRegister is forbidden.
*/
VirtualRegister(const VirtualRegister& vReg);
void operator = (const VirtualRegister& vReg);
VirtualRegisterPtr lock;
#if DEBUG
bool isLocked;
#endif
/*
* Constructors.
*/
VirtualRegister(VirtualRegisterManager& myManager, PRUint32 myIndex, VRClass myClass = vrcInteger);
public:
VirtualRegister* equivalentRegister[nVRClass];
FastBitSet specialInterference;
FastBitSet liveness;
bool hasSpecialInterference;
#ifdef DEBUG
bool isAnnotated;
#endif
/*
* Spilling & Coloring informations.
*/
struct
{
Flt32 nLoads;
Flt32 nStores;
Flt32 nCopies;
Uint32 liveLength;
Flt32 spillCost;
bool infiniteSpillCost;
bool willSpill;
Instruction* lastUsingInstruction;
} spillInfo;
struct
{
PRUint32 interferenceDegree;
PRUint8 color;
PRUint8 preColor;
PRUint32 preColoredRegisterIndex;
bool isPreColored;
} colorInfo;
/*
* For Code Generation
*/
inline void setDefiningInstruction(Instruction& insn) {definingInstruction = &insn;}
inline Instruction* getDefiningInstruction() {return definingInstruction;}
/*
* Setting the color.
*/
inline void preColorRegister(PRUint8 preColor);
inline bool isPreColored() {return colorInfo.isPreColored;}
inline PRUint8 getPreColor() {PR_ASSERT(isPreColored()); return colorInfo.preColor;}
inline void colorRegister(PRUint8 color) {colorInfo.color = color;}
inline PRUint8 getColor() {return colorInfo.color;}
void resetColoringInfo();
inline void setClass(VRClass myClass) {registerClass = myClass;}
inline VRClass getClass() {return registerClass;}
/*
* Getting the register's variables.
*/
inline bool isReferenced() {return !virtualRegisterPtrs.empty();}
inline DoublyLinkedList<VirtualRegisterPtr>& getVirtualRegisterPtrs() {return virtualRegisterPtrs;}
inline PRUint32 getRegisterIndex() {return registerIndex;}
inline VirtualRegisterManager& getManager() {return registerManager;}
// check for real use of these methods !.
inline VirtualRegister& getAlias() {return *equivalentRegister[registerClass];}
inline void setAlias(VirtualRegister& alias) {equivalentRegister[registerClass] = &alias;}
// lock
inline void retainSelf() {PR_ASSERT(!isLocked); lock.initialize(*this); DEBUG_ONLY(isLocked = true);}
inline void releaseSelf() {PR_ASSERT(isLocked); lock.uninitialize(); DEBUG_ONLY(isLocked = false);}
};
/*
*--------------------------VirtualRegister.h----------------------------
*
* class VirtualRegisterManager --
*
*-----------------------------------------------------------------------
*/
class VirtualRegisterManager
{
private:
VirtualRegister** virtualRegisters;
VirtualRegister** machineRegisters;
PRUint32 nAllocatedRegisters;
PRUint32 firstFreeRegisterIndex;
PRUint32 size;
void resize(PRUint32 amount);
void freeVirtualRegister(PRUint32 index);
public:
Pool& pool;
typedef PRUint32 iterator;
#if 0
struct
{
#endif
PRUint8 nUsedStackSlots;
PRUint8 nUsedCalleeSavedRegisters;
#if 0
} RegisterUsageInfo;
#endif
VirtualRegisterManager(Pool& p);
VirtualRegister& newVirtualRegister(VRClass cl = vrcInteger);
inline VirtualRegister& getVirtualRegister(PRUint32 index);
VirtualRegister& getMachineRegister(PRUint8 color);
void checkForVirtualRegisterDeath(PRUint32 index);
void compactMemory();
void moveVirtualRegister(PRUint32 source, PRUint32 dest);
inline iterator begin() {return advance(~0);}
inline bool done(iterator i) {return (i >= size) ? true : false;}
inline iterator advance(iterator i);
inline PRUint32 count() {return size;}
};
/*
*--------------------------VirtualRegister.h----------------------------
*
* Inlines
*
*-----------------------------------------------------------------------
*/
inline void VirtualRegister::
preColorRegister(PRUint8 preColor)
{
#ifdef DEBUG
if (isAnnotated)
trespass("This is not a temporary register. It cannot be preColored. !!!");
#endif
colorInfo.isPreColored = true;
colorInfo.preColor = preColor;
colorInfo.preColoredRegisterIndex = registerManager.getMachineRegister(preColor).getRegisterIndex();
}
inline VirtualRegister& VirtualRegisterManager::
getVirtualRegister(PRUint32 index)
{
PR_ASSERT((index < size) && virtualRegisters[index]);
return *virtualRegisters[index];
}
/*
* Return the next valid VirtualRegister index.
*/
inline VirtualRegisterManager::iterator VirtualRegisterManager::
advance(VirtualRegisterManager::iterator i)
{
i++;
while (i < size)
{
if ((virtualRegisters[i] != NULL) && !virtualRegisters[i]->isMachineRegister)
break;
i++;
}
return i;
}
/*
* VirtualRegister constructor
*/
inline VirtualRegister::
VirtualRegister(VirtualRegisterManager& myManager, PRUint32 myIndex, VRClass myClass) :
registerManager(myManager), registerIndex(myIndex), registerClass(myClass), isMachineRegister(false),
specialInterference(myManager.pool), liveness(myManager.pool)
{
colorInfo.isPreColored = false;
colorInfo.color = 0;
spillInfo.willSpill = false;
spillInfo.spillCost = 0;
hasSpecialInterference = false;
#if DEBUG
colorInfo.color = 0;
definingInstruction = NULL;
isLocked = false;
isAnnotated = false;
#endif
}
/*
* Add this VirtualRegisterPtr to the VirtualRegister's owners list.
*/
inline VirtualRegister* VirtualRegisterPtr::
link(VirtualRegister* vReg)
{
PR_ASSERT(vReg != NULL);
vReg->getVirtualRegisterPtrs().addLast(*this);
return vReg;
}
/*
* Remove this VirtualRegisterPtr from the VirtualRegister's owners list
*/
inline VirtualRegister* VirtualRegisterPtr::
unlink()
{
if (virtualRegisterAddress != NULL)
{
remove();
virtualRegisterAddress->getManager().checkForVirtualRegisterDeath(virtualRegisterAddress->getRegisterIndex());
virtualRegisterAddress = NULL;
}
return virtualRegisterAddress;
}
inline void VirtualRegisterPtr::
initialize(VirtualRegister& vReg, VRClass constraint)
{
unlink();
virtualRegisterAddress = link(&vReg);
registerClassConstraint = constraint;
}
#endif /* _VIRTUAL_REGISTER_H_ */