зеркало из https://github.com/mozilla/gecko-dev.git
387 строки
9.9 KiB
C++
387 строки
9.9 KiB
C++
/* -*- 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_ */
|