From 65e5a61eadd38d501ae9cc0261aba750f20c3cf3 Mon Sep 17 00:00:00 2001 From: "fur%netscape.com" Date: Tue, 2 Mar 1999 15:57:56 +0000 Subject: [PATCH] Change c-basic-offset in header to 4, instead of 2 --- ef/Compiler/RegisterAllocator/Coloring.cpp | 2 +- ef/Compiler/RegisterAllocator/Coloring.h | 2 +- ef/Compiler/RegisterAllocator/Liveness.cpp | 2 +- ef/Compiler/RegisterAllocator/Liveness.h | 2 +- .../NewRegisterAllocator.cpp | 659 ------------------ .../RegisterAllocator/NewRegisterAllocator.h | 94 --- .../RegisterAllocator/NewVirtualRegister.cpp | 240 ------- .../RegisterAllocator/NewVirtualRegister.h | 352 ---------- .../RegisterAllocator/RegisterAllocator.cpp | 2 +- .../RegisterAllocator/RegisterAllocator.h | 2 +- .../RegisterAllocator/RegisterAssigner.h | 2 +- ef/Compiler/RegisterAllocator/SSATools.cpp | 2 +- ef/Compiler/RegisterAllocator/SSATools.h | 2 +- ef/Compiler/RegisterAllocator/Spilling.cpp | 2 +- ef/Compiler/RegisterAllocator/Spilling.h | 2 +- ef/Compiler/RegisterAllocator/Timer.cpp | 2 +- ef/Compiler/RegisterAllocator/Timer.h | 2 +- .../RegisterAllocator/VirtualRegister.cpp | 2 +- .../RegisterAllocator/VirtualRegister.h | 2 +- 19 files changed, 15 insertions(+), 1360 deletions(-) diff --git a/ef/Compiler/RegisterAllocator/Coloring.cpp b/ef/Compiler/RegisterAllocator/Coloring.cpp index 846bf058f61..0b1d9ea5677 100644 --- a/ef/Compiler/RegisterAllocator/Coloring.cpp +++ b/ef/Compiler/RegisterAllocator/Coloring.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Coloring.h b/ef/Compiler/RegisterAllocator/Coloring.h index f83b6d535ae..2292e26da69 100644 --- a/ef/Compiler/RegisterAllocator/Coloring.h +++ b/ef/Compiler/RegisterAllocator/Coloring.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Liveness.cpp b/ef/Compiler/RegisterAllocator/Liveness.cpp index 70b7c085bbb..b8cba69ebff 100644 --- a/ef/Compiler/RegisterAllocator/Liveness.cpp +++ b/ef/Compiler/RegisterAllocator/Liveness.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Liveness.h b/ef/Compiler/RegisterAllocator/Liveness.h index 894214ae5cc..6745da6f687 100644 --- a/ef/Compiler/RegisterAllocator/Liveness.h +++ b/ef/Compiler/RegisterAllocator/Liveness.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp index 9c347f0fa93..e69de29bb2d 100644 --- a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp +++ b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.cpp @@ -1,659 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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" - -#define INCLUDE_EMITTER -#include "CpuInfo.h" - -#include "RegisterAllocator.h" -#include "VirtualRegister.h" -#include "DoublyLinkedList.h" -#include "ControlNodes.h" -#include "Instruction.h" - -#include "Liveness.h" - -#if !defined(DEBUG_LOG) || !defined(DEBUG_laurentm) -#define NO_TIMER -#endif // !DEBUG_LOG || !DEBUG_laurentm -#include "Timer.h" - -// -// Annotate the phi nodes. We call an annotation a VirtualRegister assignment to a DataProducer. -// Phi nodes are special data nodes that will not generate an instruction. For this reason, -// it is possible that after code generation, some DataProducer were not annotated. -// The RegisterAllocator assumes that each DataProducer has been annotated. So we must annotate -// the DataProducer that were not. -// -void RegisterAllocator::annotatePhiNodes() -{ - for (Uint32 n = 0; n < nNodes; n++) { // For each nodes in this graph. - DoublyLinkedList& phiNodes = dfsList[n]->getPhiNodes(); - - for (DoublyLinkedList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) { // For each phi nodes. - PhiNode& phiNode = phiNodes.get(p); - - VirtualRegisterKind constraint; - switch (phiNode.getKind()) { - case vkCond: - case vkMemory: - continue; // Condition and Memory phi nodes are not seen after code generation. - - case vkInt: - constraint = IntegerRegister; - break; - case vkLong: - constraint = IntegerRegister; // FIXME: But should annotate 2 registers. - break; - case vkFloat: - constraint = FloatingPointRegister; - break; - case vkDouble: - constraint = FloatingPointRegister; // FIXME: Is it always the case ?. - break; - case vkAddr: - constraint = IntegerRegister; - break; - default: - PR_ASSERT(!"Unhandled kind of phi node"); - } - // Check the outgoing edge annotation. We do not check the consumers because - // they must be or have been defined by either a primitive or another phi node. - if (phiNode.getVirtualRegisterAnnotation() == NULL) - phiNode.annotate(vrManager.newVirtualRegister(constraint)); - } - } -} - -// -// Get the liveness information and build the interference graph. The interference graph -// is represented by a bitmatrix. Each row of this bitmatrix represents a VirtualRegister, -// and each bits on this row an interference with another VirtualRegister. -// 2 registers will interfere if they are live at the same time. A register is alive between -// its definition and its last use. -// -void RegisterAllocator::buildInterferenceGraph() -{ - // To get the number of VirtualRegisters in the manager, we must be sure - // that no one will try to allocate new VirtualRegisters. - // We are locking the manager for the entire method. - DEBUG_ONLY(TIMER_SAFE(vrManager.lockAllocation())); - - Uint32 nVirtualRegisters = vrManager.getSize(); // Maximum of allocated VirtualRegister. - - // ControlNodes hold some fields for the register allocation (liveAtBegin, liveAtEnd, etc ...). - // We need to reset these fields and allocate the memory fro the bitsets. - for (Uint32 n = 0; n < nNodes; n++) { - ControlNode& node = *dfsList[n]; - - node.liveAtBegin.sizeToAndClear(pool, nVirtualRegisters); - node.liveAtEnd.sizeToAndClear(pool, nVirtualRegisters); - node.hasNewLiveAtEnd = true; - node.liveAtBeginIsValid = false; - } - - // Reset the interference matrix. This matrix must hold nVirtualRegisters rows and - // nVirtualRegisters column. - interferenceMatrix.sizeToAndClear(pool, nVirtualRegisters, nVirtualRegisters); - DEBUG_ONLY(interferenceMatrixSize = nVirtualRegisters); - - FastBitSet currentLive(pool, nVirtualRegisters); // Bitset for the registers currently alive. - - while(true) { - bool needsToLoop = false; - - for (Int32 n = (nNodes - 1); n >= 0; n--) { // For each nodes in this graph. - ControlNode& node = *dfsList[n]; - - // We skip the nodes that we already looked at and that do - // not have any new liveness information at the end. - if (node.liveAtBeginIsValid && !node.hasNewLiveAtEnd) - continue; - - // The register currently alive are the register alive at - // the end of this node. - currentLive = node.liveAtEnd; - // We are looking at this node so for now it doesn't have - // any new liveness information at the end. - node.hasNewLiveAtEnd = false; - - // We walk backward all the instructions defined in this node. - // A register becomes alive with its last use (first found), interfere with - // all the registers alive at its definition, and is killed by its definition. - InstructionList& instructions = node.getInstructions(); - for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) { - Instruction& instruction = instructions.get(i); - InstructionUse* useBegin = instruction.getInstructionUseBegin(); - InstructionUse* useEnd = instruction.getInstructionUseEnd(); - InstructionUse* usePtr; - InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); - InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); - InstructionDefine* defPtr; - - InstructionFlags flags = instruction.getFlags(); - - // Move is handled specially to avoid adding an interference between the - // source and the destination. If an interference exists between these - // registers another instruction will set it. For now the source register - // and the destination register will contain the same value. - if (flags & ifCopy) { - PR_ASSERT(useBegin[0].isVirtualRegister()); - currentLive.clear(useBegin[0].getVirtualRegister().index); - } - - // Registers are defined. This definition has an interference with all the - // registers currently alive. - for (defPtr = defBegin; defPtr < defEnd; defPtr++) - if (defPtr->isVirtualRegister()) { - VirtualRegisterIndex index = defPtr->getVirtualRegister().index; - interferenceMatrix.orRows(index, currentLive, index); - } - - // The definition just killed these registers. - for (defPtr = defBegin; defPtr < defEnd; defPtr++) - if (defPtr->isVirtualRegister()) - currentLive.clear(defPtr->getVirtualRegister().index); - - // If this instruction is a Call instruction, we want all the caller-save - // registers to interfere with the current live registers. We do not want an - // interference with the callee-save registers because the call will save & - // restore these registers. - if (flags & ifCall) { - // FIXME - } - - if (flags & ifSpecialCall) { - // FIXME - } - - // Each use of a register makes it alive. - for (usePtr = useBegin; usePtr < useEnd; usePtr++) - if (usePtr->isVirtualRegister()) - currentLive.set(usePtr->getVirtualRegister().index); - } - - // If the liveness information is different than the previous one, we - // need to propagate the changes to each predecessor of this node. - // We also need to add the liveness information from the phi nodes. - if (currentLive != node.liveAtBegin) { - FastBitSet liveAtEnd(pool, nVirtualRegisters); // Bitset for the registers alive at the end of a predecessor of this node. - - DoublyLinkedList& phiNodes = node.getPhiNodes(); - const DoublyLinkedList& predecessors = node.getPredecessors(); - DoublyLinkedList::iterator i; - Uint32 predecessorIndex; - - for (predecessorIndex = 0, i = predecessors.begin(); !predecessors.done(i); predecessorIndex++, i = predecessors.advance(i)) { - ControlNode& predecessor = predecessors.get(i).getSource(); - bool predecessorHasNewLiveAtEnd = false; - - if (!phiNodes.empty()) { - liveAtEnd = currentLive; - - for (DoublyLinkedList::iterator p = phiNodes.end(); !phiNodes.done(p); p = phiNodes.retreat(p)) { - PhiNode& phiNode = phiNodes.get(p); - - if (isStorableKind(phiNode.getKind())) { - DataNode& producer = phiNode.nthInput(predecessorIndex).getVariable(); - VirtualRegisterIndex use = producer.getVirtualRegisterAnnotation()->index; - VirtualRegisterIndex define = phiNode.getVirtualRegisterAnnotation()->index; - - // If this phi node has been coalesced then the producer and the consumer for this - // edge hold the same VirtualRegister. In this case we don't update the liveness - // information. - if (define != use) { - // A phiNode, if not coalesced will generate a Copy instruction. So we do - // not want the use and the definition to interfere. - liveAtEnd.clear(use); - interferenceMatrix.orRows(define, liveAtEnd, define); - liveAtEnd.clear(define); - liveAtEnd.set(use); - } - } - } - predecessorHasNewLiveAtEnd |= predecessor.liveAtEnd.set(liveAtEnd); - } else { // phiNode.empty() == true - predecessorHasNewLiveAtEnd = predecessor.liveAtEnd.set(currentLive); - } - - predecessor.hasNewLiveAtEnd |= predecessorHasNewLiveAtEnd; - needsToLoop |= predecessorHasNewLiveAtEnd; - } - } - node.liveAtBegin = currentLive; - node.liveAtBeginIsValid = true; - } - - // If this graph is an acyclic graph we are sure that after the first pass all - // the interferences are found. We stop this loop in this case and also - // if no new live registers are found. - if (!needsToLoop || isAcyclic) - break; - } - - // Summarize the interference matrix. This matrix must be diagonale and some interferences - // are not valid (i.e. IntegerRegister with FloatingPointRegister, 2 precolored registers - // to different colors. - - FastBitMatrix trans(pool, nVirtualRegisters, nVirtualRegisters); - for (VirtualRegisterIndex r = vrManager.first(); !vrManager.done(r); r = vrManager.advance(r)) { - interferenceMatrix.clear(r, r); // A register do not interfere with itself; - - FastBitSet row(interferenceMatrix.getRowBits(r), nVirtualRegisters); - for (Int32 i = row.firstOne(); !row.done(i); i = row.nextOne(i)) - trans.set(i, r); - } - - for (VirtualRegisterIndex s = vrManager.first(); !vrManager.done(s); s = vrManager.advance(s)) { - interferenceMatrix.orRows(s, FastBitSet(trans.getRowBits(s), nVirtualRegisters), s); - } - - interferenceMatrix &= vrManager.getValidInterferencesMatrix(); - - // Get the interference degrees from the interference matrix. - if (interferenceDegreesSize < nVirtualRegisters) { - interferenceDegreesSize = nVirtualRegisters; - interferenceDegrees = new(pool) Uint32[interferenceDegreesSize]; - } - - for (Uint32 j = 0; j < nVirtualRegisters; j++) - interferenceDegrees[j] = FastBitSet(interferenceMatrix.getRowBits(j), nVirtualRegisters).countOnes(); - - // We are done with this method. We can now unlock the VirtualRegisterManager. - DEBUG_ONLY(TIMER_SAFE(vrManager.unlockAllocation())); -} - -// -// Return true if the VirtualRegisters source to dest were coalesced. -// -bool RegisterAllocator::coalesceRegistersIfPossible(VirtualRegister& sourceRegister, VirtualRegister& destRegister) -{ - VirtualRegisterIndex source = sourceRegister.index; - VirtualRegisterIndex dest = destRegister.index; - - if (source == dest) - return true; - -#ifdef DEBUG - if (sourceRegister.isPreColored()) - PR_ASSERT(destRegister.isPreColored()); -#endif // DEBUG - - if (destRegister.isPreColored() && sourceRegister.isPreColored()) - if (sourceRegister.getPreColor() != destRegister.getPreColor()) - return false; - else // 2 precolored registers cannot interfere. - PR_ASSERT(!interferenceMatrix.test(source, dest)); - else if (interferenceMatrix.test(source, dest)) - return false; - - Uint32 nVirtualRegisters = vrManager.getSize(); - FastBitSet sourceInterferences(interferenceMatrix.getRowBits(source), nVirtualRegisters); - - tempBitSet.sizeTo(pool, nVirtualRegisters); - tempBitSet = sourceInterferences; - tempBitSet -= FastBitSet(interferenceMatrix.getRowBits(dest), nVirtualRegisters); - - Uint32 nNewInterferences = tempBitSet.countOnes(); - if ((nNewInterferences + interferenceDegrees[dest]) >= virtualRegisterClasses[destRegister.kind]->getNumberOfColor()) - return false; - - // Coalesce the registers. - vrManager.coalesceVirtualRegisters(source, dest); - - // Update the interference matrix. - for (Int32 i = sourceInterferences.firstOne(); !sourceInterferences.done(i); i = sourceInterferences.nextOne(i)) { - interferenceMatrix.clear(i, source); - if (tempBitSet.test(i)) // This is a new interference for dest. - interferenceMatrix.set(i, dest); - else - interferenceDegrees[i]--; - } - - interferenceDegrees[dest] += nNewInterferences; - interferenceMatrix.orRows(source, dest, dest); - -#ifdef DEBUG -START_TIMER_SAFE - interferenceMatrix.clear(source); - interferenceDegrees[source] = 0; - - // Check the validity of the dest row. - PR_ASSERT(FastBitSet(interferenceMatrix.getRowBits(dest), nVirtualRegisters).countOnes() == interferenceDegrees[dest]); -END_TIMER_SAFE -#endif - - return true; -} - -// -// Check all Copy instructions & phiNodes for possible register coalescing. -// If two registers are coalesced there's no need to keep the instruction (or the phiNode). -// The ControlFlow graph is analysed from the most executed node to the least. -// -// TODO: loop nesting depth is not good enough (should analyse the program regions instead). -// -void RegisterAllocator::removeUneededCopyInstructions() -{ - for (Int32 n = nNodes - 1; n >= 0; n--) { - ControlNode& node = *lndList[n]; - - // - // Check the Copy in the instruction list. - // - InstructionList& instructions = node.getInstructions(); - InstructionList::iterator i = instructions.begin(); - - while (!instructions.done(i)) { // For each instruction in this node. - Instruction& instruction = instructions.get(i); - i = instructions.advance(i); - - if (instruction.getFlags() & ifCopy) { // This is a Copy Instruction - PR_ASSERT(instruction.getInstructionUseBegin()[0].isVirtualRegister()); - PR_ASSERT(instruction.getInstructionDefineBegin()[0].isVirtualRegister()); - - VirtualRegister& sourceRegister = instruction.getInstructionUseBegin()[0].getVirtualRegister(); - VirtualRegister& destRegister = instruction.getInstructionDefineBegin()[0].getVirtualRegister(); - - // If a VirtualRegister is precolored then this register must be the destination - // register if the coalescing is possible. - if (destRegister.isPreColored()) { - if (coalesceRegistersIfPossible(sourceRegister, destRegister)) - instruction.remove(); - } else { - if (coalesceRegistersIfPossible(destRegister, sourceRegister)) - instruction.remove(); - } - } - } - - // - // Check the phi nodes. - // - DoublyLinkedList& phiNodes = node.getPhiNodes(); - DoublyLinkedList::iterator p = phiNodes.end(); - - while (!phiNodes.done(p)) { // For each phi nodes. - PhiNode& phiNode = phiNodes.get(p); - p = phiNodes.retreat(p); - - if (isStorableKind(phiNode.getKind())) { - bool canRemoveThisPhiNode = true; // Can we remove the phi node from the graph ? - - DataConsumer* limit = phiNode.getInputsEnd(); - for (DataConsumer* consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) { - VirtualRegister& sourceRegister = *phiNode.getVirtualRegisterAnnotation(); - VirtualRegister& destRegister = *consumer->getVariable().getVirtualRegisterAnnotation(); - - - // If a VirtualRegister is precolored then this register must be the destination - // register if the coalescing is possible. - if (destRegister.isPreColored()) { - if (!coalesceRegistersIfPossible(sourceRegister, destRegister)) - canRemoveThisPhiNode = false; - } else { - if (!coalesceRegistersIfPossible(destRegister, sourceRegister)) - canRemoveThisPhiNode = false; - } - } - - if (canRemoveThisPhiNode) - phiNode.remove(); - } - } - } -} - -// -// Replace the remaining phi nodes by their equivalent instruction (Copy, Load, Store). -// Return true if the register allocator needs one more pass. -// -bool RegisterAllocator::replacePhiNodesByCopyInstructions() -{ - bool addedANode = false; - bool needsRebuild = false; - - for (Uint32 n = 0; n < nNodes; n++) { // For all nodes. - ControlNode& node = *dfsList[n]; - - DoublyLinkedList& phiNodes = node.getPhiNodes(); - const DoublyLinkedList& predecessors = node.getPredecessors(); - bool hasOnlyOneInput = predecessors.lengthIs(1); - - // If this node has only one predecessor, it is possible to insert the copy instruction - // at the begining of this node. To respect the interference order, we have to append - // each phiNode in the same order they are in the linked list. - DoublyLinkedList::iterator i = hasOnlyOneInput ? phiNodes.begin() : phiNodes.end(); - while (!phiNodes.done(i)) { - PhiNode& phiNode = phiNodes.get(i); - i = hasOnlyOneInput ? phiNodes.advance(i) : phiNodes.retreat(i); - - if (isStorableKind(phiNode.getKind())) { - VirtualRegister& definedVR = *phiNode.getVirtualRegisterAnnotation(); - - DoublyLinkedList::iterator e = predecessors.begin(); - DataConsumer* limit = phiNode.getInputsEnd(); - for (DataConsumer* consumer = phiNode.getInputsBegin(); consumer < limit; consumer++) { // For each consumer - ControlEdge& edge = predecessors.get(e); - e = predecessors.advance(e); - - VirtualRegister& usedVR = *consumer->getVariable().getVirtualRegisterAnnotation(); - - if (definedVR.index != usedVR.index) { // We have to emit an instruction. - InstructionList::iterator place; - - if (hasOnlyOneInput) - place = node.getInstructions().begin()->prev; - else { - ControlNode& source = edge.getSource(); - if (source.nSuccessors() != 1) { // This predecessor has more than one outgoing edge. We need to add - // a new ControlBlock to insert the copy instruction. - ControlNode& cn = edge.getSource().controlGraph.newControlNode(); - cn.setControlBlock(); - ControlEdge& newEdge = cn.getNormalSuccessor(); - - newEdge.substituteTarget(edge); - cn.addPredecessor(edge); - - // append at the begin of this new node. - place = cn.getInstructions().begin(); - addedANode = true; - } else - place = edge.getSource().getInstructions().end(); - } - - needsRebuild |= emitter.emitCopyAfter(phiNode, place, usedVR, definedVR); - } - } - phiNode.remove(); - } - } - } - - if (addedANode) { - ControlGraph& cg = dfsList[0]->controlGraph; - cg.dfsSearch(); - - if (needsRebuild) { - nNodes = cg.nNodes; - dfsList = cg.dfsList; - cg.lndSearch(); - lndList = cg.lndList; - } - } - - return needsRebuild; -} - -// -// Calculate the spill cost for each VirtualRegister. -// -void RegisterAllocator::calculateSpillCosts() -{ - Uint32 nVirtualRegisters = vrManager.getSize(); - FastBitSet currentLive(pool, nVirtualRegisters); - - // Reset the spillCosts. - for (VirtualRegisterIndex r = vrManager.first(); !vrManager.done(r); r = vrManager.advance(r)) { - VirtualRegister& vReg = vrManager.getVirtualRegister(r); - vReg.spillCosts.copyCosts = 0.; - vReg.spillCosts.loadOrStoreCosts = 0.; - } - - for (Int32 n = (nNodes - 1); n >= 0; n--) { // For each node in this graph. - ControlNode& node = *dfsList[n]; - - currentLive = node.liveAtEnd; - - InstructionList& instructions = node.getInstructions(); - for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) { - Instruction& instruction = instructions.get(i); - InstructionUse* useBegin = instruction.getInstructionUseBegin(); - InstructionUse* useEnd = instruction.getInstructionUseEnd(); - InstructionUse* usePtr; - InstructionDefine* defBegin = instruction.getInstructionDefineBegin(); - InstructionDefine* defEnd = instruction.getInstructionDefineEnd(); - InstructionDefine* defPtr; - - if (instruction.getFlags() & ifCopy) { - PR_ASSERT(useBegin[0].isVirtualRegister() && defBegin[0].isVirtualRegister()); - // If one of these registers are spilled, this instruction will be replaced by a load or a store. - useBegin[0].getVirtualRegister().spillCosts.copyCosts -= node.nVisited; - defBegin[0].getVirtualRegister().spillCosts.copyCosts -= node.nVisited; - } - - // Handle the definition a new VirtualRegister. - for (defPtr = defBegin; defPtr < defEnd; defPtr++) - if (defPtr->isVirtualRegister()) { - VirtualRegister& vReg = defPtr->getVirtualRegister(); - if (virtualRegisterClasses[vReg.kind]->canSpill()) { - } - } - - } - } -} - -void RegisterAllocator::allocateRegisters() -{ - // - // Timer names. - // - const char* ANNOTATE_PHINODES = "RegAlloc.annotatePhiNodes"; - const char* BUILD_INTERFERENCEGRAPH = "RegAlloc.buildInterferenceGraph"; - const char* ALLOCATE_REGISTERS = "RegAlloc.allocateRegisters"; - const char* COALESCE_REGISTERS = "RegAlloc.coalesceRegisters"; - const char* REPLACE_PHI_NODES = "RegAlloc.replacePhiNodesByCopyInstructions"; - - startTimer(ALLOCATE_REGISTERS); - - // Add the missing annotations to the phi nodes. - startTimer(ANNOTATE_PHINODES); - annotatePhiNodes(); - stopTimer(ANNOTATE_PHINODES); - - // Build the interference matrix. - startTimer(BUILD_INTERFERENCEGRAPH); - buildInterferenceGraph(); - stopTimer(BUILD_INTERFERENCEGRAPH); - -#if 0 - // Remove uneeded copy & phi nodes. - startTimer(COALESCE_REGISTERS); - removeUneededCopyInstructions(); - stopTimer(COALESCE_REGISTERS); - - // Just to be sure that the coalescing didn't corrupt the interference matrix. - DEBUG_ONLY(TIMER_SAFE(checkCoalescingValidity())); - - // Get the cost for register spilling. - calculateSpillCosts(); -#endif - -#if 0 - bool successfulColoring = colorRegisters(); - - if (!successfulColoring) - insertSpillCode(); - - // Emit the instructions for the remaining phi nodes in the graph. - startTimer(REPLACE_PHI_NODES); - replacePhiNodesByCopyInstructions(); - stopTimer(REPLACE_PHI_NODES); -#endif - - stopTimer(ALLOCATE_REGISTERS); - - - interferenceMatrix.printPretty(stdout); - -#if 1 - for (VirtualRegisterIndex i = vrManager.first(); !vrManager.done(i); i = vrManager.advance(i)) { - fprintf(stdout, "degree of vr%d = %d\n", i, interferenceDegrees[i]); - vrManager.getVirtualRegister(i).setColor(0); - } - - for (Uint32 m = 0; m < nNodes; m++) { - ControlNode& node = *dfsList[m]; - node.printRef(stdout); - fprintf(stdout, "\n"); - - InstructionList& instructions = node.getInstructions(); - for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) { - instructions.get(i).printDebug(stdout); - fprintf(stdout, "\n"); - } - } -#endif - - ControlGraph& cg = dfsList[0]->controlGraph; - Liveness liveness(pool); - liveness.buildLivenessAnalysis(cg, vrManager); - - exit(-1); -} - -#ifdef DEBUG -// -// -// -void RegisterAllocator::checkCoalescingValidity() -{ - FastBitMatrix backup(pool, interferenceMatrixSize, interferenceMatrixSize); - backup = interferenceMatrix; - - buildInterferenceGraph(); - if (backup != interferenceMatrix) { -#ifdef DEBUG_LOG - fprintf(stdout, "\n" - "!!! RegisterAllocator Warning: Interference matrix is invalid after coalescing.\n" - "!!! The RegisterAllocator will reconstruct a valid interferenceMatrix.\n" - "!!!\n" - "!!! Please mail your java source file to laurentm@netscape.com with\n" - "!!! the subject \"RegAlloc Bug\". Thanks, Laurent.\n" - "\n"); -#ifdef DEBUG_laurentm - interferenceMatrix.printDiff(stdout, backup); -#endif // DEBUG_laurentm -#else // DEBUG_LOG - PR_ASSERT(!"Invalid interferenceMatrix after coalescing"); -#endif // DEBUG_LOG - } -} -#endif // DEBUG diff --git a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h index 188bae9f2d6..e69de29bb2d 100644 --- a/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h +++ b/ef/Compiler/RegisterAllocator/NewRegisterAllocator.h @@ -1,94 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. - */ - -#ifndef _REGISTER_ALLOCATOR_H_ -#define _REGISTER_ALLOCATOR_H_ - - -#include "Fundamentals.h" - -#define INCLUDE_EMITTER -#include "CpuInfo.h" - -#include "FastBitMatrix.h" -#include "ControlGraph.h" - -class Pool; -class VirtualRegisterManager; - -// ---------------------------------------------------------------------------- -// RegisterAllocator - -class RegisterAllocator -{ -private: - Pool& pool; // RegisterAllocator's pool. - ControlNode** dfsList; // List of nodes in a Depth First Search order. - ControlNode** lndList; // List of nodes in a Loop Nesting Depth order. - Uint32 nNodes; // Number of nodes in this graph. - bool isAcyclic; // True if the graph is acyclic. - VirtualRegisterManager& vrManager; // VirtualRegister's manager. - MdEmitter& emitter; // The machine dependant instruction emitter. - - FastBitMatrix interferenceMatrix; // The interference matrix. Each row is assign to a VirtualRegister. -#ifdef DEBUG - Uint32 interferenceMatrixSize; // The number of rows and cols in the interference matrix. -#endif // DEBUG - Uint32* interferenceDegrees; // The interference degree of all the VirtualRegisters in the graph. - Uint32 interferenceDegreesSize; // The size of interferenceDegrees. - - FastBitSet tempBitSet; // Temporary bitset (one time allocation). - - - // Annotate the phi nodes. - void annotatePhiNodes(); - // Get the liveness information and build the interference graph. - void buildInterferenceGraph(); - // Coalesce the VirtualRegisters source to dest if it is possible. - bool coalesceRegistersIfPossible(VirtualRegister& sourceRegister, VirtualRegister& destRegister); - // Remove uneeded compy instructions (when the source and destination don not interfere); - void removeUneededCopyInstructions(); - // Replace the remaining phi nodes by their equivalent instruction (Copy, Load, Store). - bool replacePhiNodesByCopyInstructions(); - // Get the spilling cost for each VirtualRegister. - void calculateSpillCosts(); - -#ifdef DEBUG - // Check if the coalescing didn't corrupt the interferenceMatrix. - void checkCoalescingValidity(); -#endif // DEBUG - -public: - inline RegisterAllocator(Pool& pool, ControlGraph& graph, VirtualRegisterManager& vrManager, MdEmitter& emitter); - - void allocateRegisters(); -}; - -// ---------------------------------------------------------------------------- -// Inlines - -inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& graph, VirtualRegisterManager& vrManager, MdEmitter& emitter) : - pool(pool), vrManager(vrManager), emitter(emitter), interferenceDegreesSize(0) -{ - dfsList = graph.dfsList; - lndList = graph.lndList; - nNodes = graph.nNodes; - isAcyclic = !graph.hasBackEdges; -} - -#endif // _REGISTER_ALLOCATOR_H_ diff --git a/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp b/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp index a08eeb237d3..e69de29bb2d 100644 --- a/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp +++ b/ef/Compiler/RegisterAllocator/NewVirtualRegister.cpp @@ -1,240 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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 nullVirtualRegisterHandlesHeader = {0, 0, {NULL}}; -static BlocksHeader 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; -} diff --git a/ef/Compiler/RegisterAllocator/NewVirtualRegister.h b/ef/Compiler/RegisterAllocator/NewVirtualRegister.h index 094ca580b29..e69de29bb2d 100644 --- a/ef/Compiler/RegisterAllocator/NewVirtualRegister.h +++ b/ef/Compiler/RegisterAllocator/NewVirtualRegister.h @@ -1,352 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * 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. - */ - -#ifndef _VIRTUAL_REGISTER_H_ -#define _VIRTUAL_REGISTER_H_ - -#include "Fundamentals.h" -#include "FastBitMatrix.h" -#include "FastBitSet.h" - -class Instruction; -class Pool; - -enum VirtualRegisterKind -{ - InvalidRegisterKind, - IntegerRegister, - FloatingPointRegister, - FixedPointRegister, - MemoryRegister, - StackSlotRegister, - MemoryArgumentRegister, -}; -const nVirtualRegisterKind = MemoryArgumentRegister + 1; - -// ---------------------------------------------------------------------------- -// VirtualRegister - -// A VirtualRegisterIndex is an index to the VirtualRegisterManager table -// of handles. It is an invalid index if its value is 'invalidRegisterIndex'. -typedef Int32 VirtualRegisterIndex; -typedef Uint8 VirtualRegisterColor; - -const VirtualRegisterIndex invalidRegisterIndex = -1; // An invalid register index. -const VirtualRegisterColor invalidRegisterColor = 255; // An invalid register color. - -struct VirtualRegisterHandle; - -const Flt32 copyCost = 1.; -const Flt32 loadCost = 2.; -const Flt32 storeCost = 2.; - -class VirtualRegister -{ -public: - - VirtualRegisterIndex index; // This VirtualRegister's index. - const VirtualRegisterKind kind; // This VirtualRegister kind (i.e. IntegerRegister, FloatingPointRegister ...). - - struct SpillCost - { - Flt32 copyCosts; - Flt32 loadOrStoreCosts; - } spillCosts; - -private: - - Instruction* definingInstruction; // The instruction defining this register. - VirtualRegisterHandle* handle; // This VirtualRegister's handle. - - struct - { - VirtualRegisterColor color; // Register's color - VirtualRegisterColor preColor; // PreColor or 255 if it is not precolored. - } colorInfo; - -private: - - VirtualRegister(const VirtualRegister&); // No copy constructor. - void operator = (const VirtualRegister&); // No copy operator. - -public: - - // Create a new VirtualRegister - inline VirtualRegister(VirtualRegisterHandle* handle, VirtualRegisterIndex index, VirtualRegisterKind kind); - - // Set the defining instruction (for code generation). - void setDefiningInstruction(Instruction& instruction) {definingInstruction = &instruction;} - // Get the defining instruction (for code generation). - Instruction* getDefiningInstruction() {return definingInstruction;} - - // - // Helpers. - // - - // Get this VirtualRegister's handle. - VirtualRegisterHandle* getHandle() {return handle;} - - // Set the Register's color. - void setColor(VirtualRegisterColor color) {colorInfo.color = color;} - // Set the preColor (by setting the preColor this register becomes a preColored register). - void setPreColor(VirtualRegisterColor color) {colorInfo.preColor = color;} - // Return true is this register has been succesfully colored. - bool isColored() const {return colorInfo.color != invalidRegisterColor;} - // Return true is this register is preColored. (If this register is not colored then return invalidRegisterColor). - bool isPreColored() const {return colorInfo.preColor != invalidRegisterColor;} - // Return this register's color. - VirtualRegisterColor getColor() const {return colorInfo.color;} - // Return this register's preColor. (If this register is not preColored then return invalidRegisterColor). - VirtualRegisterColor getPreColor() const {return colorInfo.preColor;} - -#ifdef DEBUG_LOG - // Print the register in the file f. - void printPretty(FILE* f) const; -#endif // DEBUG_LOG -}; - -struct VirtualRegisterHandle -{ - VirtualRegister* ptr; - VirtualRegisterHandle* next; -}; - -// ---------------------------------------------------------------------------- -// VirtualRegisterManager - -template -struct BlocksHeader -{ - const Uint32 numberOfElementsInABlock = 128; // Number of elements in a block. - - Uint32 nBlocks; // Number of available blocks. - Uint32 next; // Next available element. - Class* blocks[1]; // Array of block pointers. - - // Allocate another block and return the new this. - BlocksHeader* allocateAnotherBlock(Pool& pool); - // Get the block number for this element index. - static Uint32 getBlockNumber(Uint32 index) {return index >> 7;} - // Get the element's pointer at index. - Class* getElementPtr(Uint32 index); -}; - -#include "CpuInfo.h" - -class VirtualRegisterManager -{ -private: - - Pool& pool; // This VirtualRegisterManager's allocation pool. - BlocksHeader* handlesHeader; // VirtualRegisterHandles blocks' header. - BlocksHeader* registersHeader; // VirtualRegisters blocks' header. - FastBitMatrix machineRegisters; // Matrix of machine registers. -#ifdef DEBUG - bool lock; // If lock is true then no new register can be created. -#endif // DEBUG - - FastBitSet* indexes; // Register indexes currently used. - - Int32 firstFree; // First free register index. - Int32 biggestUsed; // Biggest used register index. - - VirtualRegisterManager(const VirtualRegisterManager&); // No copy constructor. - void operator = (const VirtualRegisterManager&); // No copy operator. - -public: - // Create a new VirtualRegisterManager. - VirtualRegisterManager(Pool& pool); - - // Return the maximum number of VirtualRegisters currently in use. - Uint32 getSize() const {return biggestUsed + 1;} -#ifdef DEBUG - // Lock the manager. When it is locked no one can create new VirtualRegisters. - void lockAllocation() {PR_ASSERT(!lock); lock = true;} - // Unlock the manager. - void unlockAllocation() {PR_ASSERT(lock); lock = false;} -#endif // DEBUG - - // Return the reference to the VirtualRegister at index. - inline VirtualRegister& getVirtualRegister(VirtualRegisterIndex index) const; - - // Allocate a new VirtualRegister of kind 'kind'. - VirtualRegister& newVirtualRegister(VirtualRegisterKind kind); - // Coalesce the VirtualRegister at index from with the VirtualRegister at index to. - void coalesceVirtualRegisters(VirtualRegisterIndex from, VirtualRegisterIndex to); - // PreColor the VirtualRegister at index with color. - void preColorVirtualRegister(VirtualRegisterIndex index, VirtualRegisterColor color); - - // Return the first valid VirtualRegisterIndex. - VirtualRegisterIndex first() const {return advance(-1);} - // Return the next valid VirtualRegister after index. - inline VirtualRegisterIndex advance(VirtualRegisterIndex index) const {return indexes->nextOne(index);} - // Return true is this index is outside the array of handles. - bool done(VirtualRegisterIndex index) const {return (index < 0 || index > biggestUsed);} - - // Return the matrix of valid interferences (i.e. a IntegerRegister interferes only with others IntegerRegisters). - FastBitMatrix& getValidInterferencesMatrix() const; - -#ifdef DEBUG_LOG - // Print all the VirtualRegisters in this manager. - void printPretty(FILE* f) const; -#endif // DEBUG_LOG -}; - -// ---------------------------------------------------------------------------- -// VirtualRegisterClass(es) - -class VirtualRegisterClass -{ -private: - - VirtualRegisterClass(const VirtualRegisterClass&); // No copy constructor. - void operator = (const VirtualRegisterClass&); // No copy operator. - -public: - - VirtualRegisterKind kind; // This class kind. - - VirtualRegisterClass(VirtualRegisterKind kind) : kind(kind) {} - - // Return the VirtualRegisterKind this class can spill to. - virtual VirtualRegisterKind willSpillTo() const {return InvalidRegisterKind;} - // Return the smallest color index this register class can take. - virtual Uint8 getMinColor() const = 0; - // Return the bigest color index this register class can take. - virtual Uint8 getMaxColor() const = 0; - // Return the number of color available for this class. - Uint8 getNumberOfColor() const {return getMaxColor() - getMinColor() + 1;} - // Return true if this class canSpill; - bool canSpill() const {return willSpillTo() != InvalidRegisterKind;} - - // Return the kind of register for the given color. - static VirtualRegisterKind getKind(VirtualRegisterColor color); -#ifdef DEBUG_LOG - // Print the class string for the VirtualRegisterClass. - virtual void printPretty(FILE* f) const = 0; -#endif // DEBUG_LOG -}; - -// virtualRegisterClasses is an array of VirtualRegisterClass instances. -// Each instance is a different class of registers (i.e. Integer, FP, memory). -extern const VirtualRegisterClass* virtualRegisterClasses[]; - -// -// An IntegerRegister's possible colors are [FIRST_GREGISTER ... LAST_GREGISTER]. -// It can spill in a MemoryRegister. -// -class IntegerRegisterClass : public VirtualRegisterClass -{ -public: - IntegerRegisterClass() : VirtualRegisterClass(IntegerRegister) {} - - virtual VirtualRegisterKind willSpillTo() const {return MemoryRegister;} - virtual Uint8 getMinColor() const {return FIRST_GREGISTER;} - virtual Uint8 getMaxColor() const {return LAST_GREGISTER;} - -#ifdef DEBUG_LOG - virtual void printPretty(FILE* f) const {fprintf(f, "integer register ");} -#endif // DEBUG_LOG -}; - -// -// A FloatingRegister's possible colors are [FIRST_FPREGISTER ... LAST_FPREGISTER]. -// It can spill in a MemoryRegister. -// -class FloatingPointRegisterClass : public VirtualRegisterClass -{ -public: - FloatingPointRegisterClass() : VirtualRegisterClass(FloatingPointRegister) {} - - virtual VirtualRegisterKind willSpillTo() const {return MemoryRegister;} - virtual Uint8 getMinColor() const {return FIRST_FPREGISTER;} - virtual Uint8 getMaxColor() const {return LAST_FPREGISTER;} - -#ifdef DEBUG_LOG - virtual void printPretty(FILE* f) const {fprintf(f, "floating point register ");} -#endif // DEBUG_LOG -}; - -// -// A MemoryRegister has an infinite color space. It cannot spill ! -// -class MemoryRegisterClass : public VirtualRegisterClass -{ -public: - MemoryRegisterClass() : VirtualRegisterClass(MemoryRegister) {} - - virtual Uint8 getMinColor() const {return 0;} - virtual Uint8 getMaxColor() const {return ~0;} // Infinite space for a memory register. - -#ifdef DEBUG_LOG - virtual void printPretty(FILE* f) const {fprintf(f, "memory register ");} -#endif // DEBUG_LOG -}; - -// ---------------------------------------------------------------------------- -// Inlines - -inline VirtualRegister& VirtualRegisterManager::getVirtualRegister(VirtualRegisterIndex index) const -{ - PR_ASSERT(indexes->test(index)); - return *registersHeader->getElementPtr(index); -} - -inline VirtualRegister::VirtualRegister(VirtualRegisterHandle* handle, VirtualRegisterIndex index, VirtualRegisterKind kind) : - index(index), kind(kind), definingInstruction(NULL), handle(handle) -{ - setColor(invalidRegisterColor); - setPreColor(invalidRegisterColor); -} - -// -// Allocate another block and return the new this. -// -template -BlocksHeader* BlocksHeader::allocateAnotherBlock(Pool& pool) -{ - // Get the number of 32bits words needed for this block. A block is composed by: - // [BlockHeader] (nBlocks-1)*[pointers to block] numberOfElementsInABlock*[element Class]. - Uint32 blockSize = ((sizeof(BlocksHeader) + nBlocks * sizeof(Uint32) + - (numberOfElementsInABlock * sizeof(Class))) + 3 & -4) >> 2; - Uint32* ptr = new(pool) Uint32[blockSize]; - fill(ptr, &ptr[blockSize], 0); - - BlocksHeader* newThis = static_cast*>(ptr); - *newThis = *this; - - if (nBlocks > 0) - copy(&blocks[1], &blocks[nBlocks], &newThis->blocks[1]); - - newThis->blocks[nBlocks] = static_cast(&newThis->blocks[nBlocks + 1]); - newThis->nBlocks++; - - return newThis; -} - -// -// Get the element's pointer at index. -// -template -Class* BlocksHeader::getElementPtr(Uint32 index) -{ - PR_ASSERT((getBlockNumber(index) < nBlocks) && (index < next)); - return &(blocks[getBlockNumber(index)])[index & (numberOfElementsInABlock - 1)]; -} - -#endif // _VIRTUAL_REGISTER_H_ diff --git a/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp b/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp index 8f78dfec951..b7196422d4b 100644 --- a/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp +++ b/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/RegisterAllocator.h b/ef/Compiler/RegisterAllocator/RegisterAllocator.h index be73f37874e..e2abdbb02d1 100644 --- a/ef/Compiler/RegisterAllocator/RegisterAllocator.h +++ b/ef/Compiler/RegisterAllocator/RegisterAllocator.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/RegisterAssigner.h b/ef/Compiler/RegisterAllocator/RegisterAssigner.h index c2051b72272..125b0cd49cc 100644 --- a/ef/Compiler/RegisterAllocator/RegisterAssigner.h +++ b/ef/Compiler/RegisterAllocator/RegisterAssigner.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/SSATools.cpp b/ef/Compiler/RegisterAllocator/SSATools.cpp index 7a7252697a5..cd74bb8051b 100644 --- a/ef/Compiler/RegisterAllocator/SSATools.cpp +++ b/ef/Compiler/RegisterAllocator/SSATools.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/SSATools.h b/ef/Compiler/RegisterAllocator/SSATools.h index bc5717e08b4..fc0600d4607 100644 --- a/ef/Compiler/RegisterAllocator/SSATools.h +++ b/ef/Compiler/RegisterAllocator/SSATools.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Spilling.cpp b/ef/Compiler/RegisterAllocator/Spilling.cpp index 015e33d170f..27df689a792 100644 --- a/ef/Compiler/RegisterAllocator/Spilling.cpp +++ b/ef/Compiler/RegisterAllocator/Spilling.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Spilling.h b/ef/Compiler/RegisterAllocator/Spilling.h index bde09a0fd41..929069d6966 100644 --- a/ef/Compiler/RegisterAllocator/Spilling.h +++ b/ef/Compiler/RegisterAllocator/Spilling.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Timer.cpp b/ef/Compiler/RegisterAllocator/Timer.cpp index 35e210c5982..aae675cf4f5 100644 --- a/ef/Compiler/RegisterAllocator/Timer.cpp +++ b/ef/Compiler/RegisterAllocator/Timer.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/Timer.h b/ef/Compiler/RegisterAllocator/Timer.h index 30fbdae66d4..23e0bad45cf 100644 --- a/ef/Compiler/RegisterAllocator/Timer.h +++ b/ef/Compiler/RegisterAllocator/Timer.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/VirtualRegister.cpp b/ef/Compiler/RegisterAllocator/VirtualRegister.cpp index a39fab8338c..2e333ba8427 100644 --- a/ef/Compiler/RegisterAllocator/VirtualRegister.cpp +++ b/ef/Compiler/RegisterAllocator/VirtualRegister.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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 diff --git a/ef/Compiler/RegisterAllocator/VirtualRegister.h b/ef/Compiler/RegisterAllocator/VirtualRegister.h index 39f3c010387..8b3c602e50b 100644 --- a/ef/Compiler/RegisterAllocator/VirtualRegister.h +++ b/ef/Compiler/RegisterAllocator/VirtualRegister.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- 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