Mozilla/mozilla/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp
fur%netscape.com 9789a62ec6 Change c-basic-offset in header to 4, instead of 2
git-svn-id: svn://10.0.0.236/trunk@22565 18797224-902f-48f8-a5cc-f745e15eee43
1999-03-02 15:57:56 +00:00

241 lines
7.4 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "Fundamentals.h"
#include "VirtualRegister.h"
#include "FastBitMatrix.h"
#include "FastBitSet.h"
// ----------------------------------------------------------------------------
// VirtualRegister
#ifdef DEBUG_LOG
//
// Print this VirtualRegister.
//
void VirtualRegister::printPretty(FILE* f) const
{
virtualRegisterClasses[kind]->printPretty(f);
fprintf(f, "%d: ", index);
if (isPreColored())
fprintf(f, "preColor = %d ", getPreColor());
if (isColored())
fprintf(f, "color = %d ", getColor());
else
fprintf(f, "not yet colored ");
fprintf(f, "\n");
}
#endif // DEBUG_LOG
// ----------------------------------------------------------------------------
// VirtualRegisterManager
static BlocksHeader<VirtualRegisterHandle> nullVirtualRegisterHandlesHeader = {0, 0, {NULL}};
static BlocksHeader<VirtualRegister> nullVirtualRegistersHeader = {0, 0, {NULL}};
//
// Create a new VirtualRegisterManager.
//
VirtualRegisterManager::VirtualRegisterManager(Pool& pool) :
pool(pool), machineRegisters(pool, NUMBER_OF_REGISTERS, NUMBER_OF_REGISTERS)
{
handlesHeader = nullVirtualRegisterHandlesHeader.allocateAnotherBlock(pool);
registersHeader = nullVirtualRegistersHeader.allocateAnotherBlock(pool);
indexes = new(pool) FastBitSet(pool, registersHeader->numberOfElementsInABlock);
firstFree = 0;
biggestUsed = -1;
DEBUG_ONLY(lock = false);
}
inline void *operator new(size_t, VirtualRegister* ptr) {return ptr;}
//
// Allocate a new VirtualRegister of kind 'kind'.
//
VirtualRegister& VirtualRegisterManager::newVirtualRegister(VirtualRegisterKind kind)
{
// If we are lock, no new VirtualRegister can be created.
PR_ASSERT(!lock);
// Get a new VirtualRegister.
Int32 registerIndex = firstFree;
indexes->set(registerIndex);
firstFree = indexes->nextZero(firstFree);
if (firstFree == -1 || registersHeader->getBlockNumber(registerIndex) >= registersHeader->nBlocks) {
registersHeader = registersHeader->allocateAnotherBlock(pool);
FastBitSet& newIndexes = *new(pool) FastBitSet(pool, registersHeader->nBlocks * registersHeader->numberOfElementsInABlock);
newIndexes = *indexes;
indexes = &newIndexes;
firstFree = indexes->nextZero(registerIndex);
}
if (Uint32(registerIndex) == registersHeader->next)
registersHeader->next++;
if (registerIndex > biggestUsed)
biggestUsed = registerIndex;
// Get a new handle.
Uint32 handleIndex = handlesHeader->next++;
if (handlesHeader->getBlockNumber(handleIndex) >= handlesHeader->nBlocks)
handlesHeader = handlesHeader->allocateAnotherBlock(pool);
VirtualRegisterHandle* handle = handlesHeader->getElementPtr(handleIndex);
VirtualRegister& vReg = *new(registersHeader->getElementPtr(registerIndex)) VirtualRegister(handle, registerIndex, kind);
handle->ptr = &vReg;
handle->next = handle;
return vReg;
}
//
// Coalesce the VirtualRegister at index from with the VirtualRegister at index to.
//
void VirtualRegisterManager::coalesceVirtualRegisters(VirtualRegisterIndex from, VirtualRegisterIndex to)
{
// When we coalesce the VirtualRegister 'from' to the VirtualRegister 'to' we must
// update all from's handle to point to. 'from' has an unique handle index, but this
// handle is chain to all the handle also pointing it.
VirtualRegister* toVR = &getVirtualRegister(to);
VirtualRegisterHandle* beginOfToChain = toVR->getHandle();
VirtualRegisterHandle* endOfToChain = beginOfToChain;
// Get the end of to's handle chain.
while (endOfToChain->next != beginOfToChain)
endOfToChain = endOfToChain->next;
VirtualRegister* fromVR = &getVirtualRegister(from);
VirtualRegisterHandle* beginOfFromChain = fromVR->getHandle();
VirtualRegisterHandle* endOfFromChain = beginOfFromChain;
// For each from's handle update the pointer.
while (true) {
endOfFromChain->ptr = toVR;
if (endOfFromChain->next == beginOfFromChain)
break;
endOfFromChain = endOfFromChain->next;
}
// Merge the chains.
endOfToChain->next = beginOfFromChain;
endOfFromChain->next = beginOfToChain;
// Free the from register.
indexes->clear(from);
if (from < firstFree)
firstFree = from;
if (from == biggestUsed)
biggestUsed = indexes->previousOne(from);
if (fromVR->isPreColored())
machineRegisters.clear(fromVR->getPreColor(), fromVR->index);
}
//
// PreColor the VirtualRegister at index with color.
//
void VirtualRegisterManager::preColorVirtualRegister(VirtualRegisterIndex index, VirtualRegisterColor color)
{
machineRegisters.set(color, index);
getVirtualRegister(index).setPreColor(color);
}
//
// Return a Matrix of valid interferences.
//
FastBitMatrix& VirtualRegisterManager::getValidInterferencesMatrix() const
{
const Uint32 matrixSize = getSize();
FastBitMatrix& matrix = *new(pool) FastBitMatrix(pool, matrixSize, matrixSize);
FastBitSet* classesIndex = new FastBitSet[nVirtualRegisterKind](pool, matrixSize);
for (VirtualRegisterIndex i = first(); !done(i); i = advance(i))
classesIndex[getVirtualRegister(i).kind].set(i);
for (VirtualRegisterIndex j = first(); !done(j); j = advance(j))
matrix.copyRows(classesIndex[getVirtualRegister(j).kind], j);
return matrix;
}
#ifdef DEBUG_LOG
//
// Print all the VirtualRegisters in this manager.
//
void VirtualRegisterManager::printPretty(FILE* f) const
{
fprintf(f, "----- VirtualRegisters -----\n");
for (VirtualRegisterIndex i = first(); !done(i); i = advance(i))
getVirtualRegister(i).printPretty(f);
fprintf(f, "----- MachineRegisters -----\n");
for (Uint32 j = 0; j < NUMBER_OF_REGISTERS; j++) {
FastBitSet preColoredRegisters(machineRegisters.getRowBits(j), NUMBER_OF_REGISTERS);
if (!preColoredRegisters.empty()) {
fprintf(f, "preColored to %d: ", j);
preColoredRegisters.printPrettyOnes(f);
}
}
fprintf(f, "----------------------------\n");
}
#endif // DEBUG_LOG
// ----------------------------------------------------------------------------
// VirtualRegisterClass
static IntegerRegisterClass integerRegister;
static FloatingPointRegisterClass floatingPointRegister;
static MemoryRegisterClass memoryRegister;
const VirtualRegisterClass* virtualRegisterClasses[nVirtualRegisterKind] =
{
NULL, // InvalidRegisterKind
&integerRegister,
&floatingPointRegister,
NULL, // FixedPointRegister
&memoryRegister,
NULL, // StackSlotRegister
NULL, // MemoryArgumentRegister
};
//
// Return the kind of register for the given color.
//
VirtualRegisterKind VirtualRegisterClass::getKind(VirtualRegisterColor color)
{
for (Uint32 i = 0; i < nVirtualRegisterKind; i++)
if (virtualRegisterClasses[i] != NULL) {
const VirtualRegisterClass& vrClass = *virtualRegisterClasses[i];
if (color >= vrClass.getMinColor() && color <= vrClass.getMaxColor())
return vrClass.kind;
}
return InvalidRegisterKind;
}