cpu/o3: clean up scoreboard object

It had a bunch of fields (and associated constructor
parameters) thet it didn't really use, and the array
initialization was needlessly verbose.

Also just hardwired the getReg() method to aleays
return true for misc regs, rather than having an array
of bits that we always kept marked as ready.
This commit is contained in:
Steve Reinhardt 2013-10-15 14:22:43 -04:00
parent c009d0eb2a
commit 9bd017b8ae
4 changed files with 108 additions and 169 deletions

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2011-2012 ARM Limited
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -235,11 +236,9 @@ FullO3CPU<Impl>::FullO3CPU(DerivO3CPUParams *params)
params->smtROBPolicy, params->smtROBThreshold,
params->numThreads),
scoreboard(params->numThreads,
TheISA::NumIntRegs, params->numPhysIntRegs,
TheISA::NumFloatRegs, params->numPhysFloatRegs,
TheISA::NumMiscRegs * numThreads,
TheISA::ZeroReg),
scoreboard(name() + ".scoreboard",
regFile.totalNumPhysRegs(), TheISA::NumMiscRegs,
TheISA::ZeroReg, TheISA::ZeroReg),
isa(numThreads, NULL),

View file

@ -884,11 +884,6 @@ DefaultRename<Impl>::doSquash(const InstSeqNum &squashed_seq_num, ThreadID tid)
// Put the renamed physical register back on the free list.
freeList->addReg(hb_it->newPhysReg);
// Be sure to mark its register as ready if it's a misc register.
if (hb_it->newPhysReg >= maxPhysicalRegs) {
scoreboard->setReg(hb_it->newPhysReg);
}
historyBuffer[tid].erase(hb_it++);
++renameUndoneMaps;
@ -1050,8 +1045,7 @@ DefaultRename<Impl>::renameDestRegs(DynInstPtr &inst, ThreadID tid)
rename_result = renameMap[tid]->rename(flat_dest_reg);
//Mark Scoreboard entry as not ready
if (regIdxToClass(dest_reg) != MiscRegClass)
scoreboard->unsetReg(rename_result.first);
scoreboard->unsetReg(rename_result.first);
DPRINTF(Rename, "[tid:%u]: Renaming arch reg %i to physical "
"reg %i.\n", tid, (int)flat_dest_reg,

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2005-2006 The Regents of The University of Michigan
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,99 +34,13 @@
#include "cpu/o3/scoreboard.hh"
#include "debug/Scoreboard.hh"
Scoreboard::Scoreboard(unsigned activeThreads,
unsigned _numLogicalIntRegs,
unsigned _numPhysicalIntRegs,
unsigned _numLogicalFloatRegs,
unsigned _numPhysicalFloatRegs,
unsigned _numMiscRegs,
unsigned _zeroRegIdx)
: numLogicalIntRegs(_numLogicalIntRegs),
numPhysicalIntRegs(_numPhysicalIntRegs),
numLogicalFloatRegs(_numLogicalFloatRegs),
numPhysicalFloatRegs(_numPhysicalFloatRegs),
numMiscRegs(_numMiscRegs),
zeroRegIdx(_zeroRegIdx)
Scoreboard::Scoreboard(const std::string &_my_name,
unsigned _numPhysicalRegs, unsigned _numMiscRegs,
PhysRegIndex _zeroRegIdx, PhysRegIndex _fpZeroRegIdx)
: _name(_my_name),
regScoreBoard(_numPhysicalRegs, true),
numPhysRegs(_numPhysicalRegs),
numTotalRegs(_numPhysicalRegs + _numMiscRegs),
zeroRegIdx(_zeroRegIdx), fpZeroRegIdx(_fpZeroRegIdx)
{
//Get Register Sizes
numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
//Resize scoreboard appropriately
resize(numPhysicalRegs + (numMiscRegs * activeThreads));
//Initialize values
for (int i=0; i < numLogicalIntRegs * activeThreads; i++) {
assert(indexInBounds(i));
regScoreBoard[i] = 1;
}
for (int i= numPhysicalIntRegs;
i < numPhysicalIntRegs + (numLogicalFloatRegs * activeThreads);
i++) {
assert(indexInBounds(i));
regScoreBoard[i] = 1;
}
for (int i = numPhysicalRegs;
i < numPhysicalRegs + (numMiscRegs * activeThreads);
i++) {
assert(indexInBounds(i));
regScoreBoard[i] = 1;
}
}
std::string
Scoreboard::name() const
{
return "cpu.scoreboard";
}
bool
Scoreboard::getReg(PhysRegIndex phys_reg)
{
#if THE_ISA == ALPHA_ISA
// Always ready if int or fp zero reg.
if (phys_reg == zeroRegIdx ||
phys_reg == (zeroRegIdx + numPhysicalIntRegs)) {
return 1;
}
#else
// Always ready if int zero reg.
if (phys_reg == zeroRegIdx) {
return 1;
}
#endif
assert(indexInBounds(phys_reg));
return regScoreBoard[phys_reg];
}
void
Scoreboard::setReg(PhysRegIndex phys_reg)
{
DPRINTF(Scoreboard, "Setting reg %i as ready\n", phys_reg);
assert(indexInBounds(phys_reg));
regScoreBoard[phys_reg] = 1;
}
void
Scoreboard::unsetReg(PhysRegIndex ready_reg)
{
#if THE_ISA == ALPHA_ISA
if (ready_reg == zeroRegIdx ||
ready_reg == (zeroRegIdx + numPhysicalIntRegs)) {
// Don't do anything if int or fp zero reg.
return;
}
#else
if (ready_reg == zeroRegIdx) {
// Don't do anything if int zero reg.
return;
}
#endif
assert(indexInBounds(ready_reg));
regScoreBoard[ready_reg] = 0;
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2005-2006 The Regents of The University of Michigan
* Copyright (c) 2013 Advanced Micro Devices, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,6 +28,7 @@
*
* Authors: Korey Sewell
* Kevin Lim
* Steve Reinhardt
*/
#ifndef __CPU_O3_SCOREBOARD_HH__
@ -37,95 +39,124 @@
#include <vector>
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/o3/comm.hh"
#include "debug/Scoreboard.hh"
/**
* Implements a simple scoreboard to track which registers are ready.
* This class assumes that the fp registers start, index wise, right after
* the integer registers. The misc. registers start, index wise, right after
* the fp registers.
* @todo: Fix up handling of the zero register in case the decoder does not
* automatically make insts that write the zero register into nops.
* Implements a simple scoreboard to track which registers are
* ready. This class operates on the unified physical register space,
* so integer and floating-point registers are not distinguished. For
* convenience, it also accepts operations on the physical-space
* mapping of misc registers, which are numbered starting after the
* end of the actual physical register file. However, there is no
* actual scoreboard for misc registers, and they are always
* considered ready.
*/
class Scoreboard
{
private:
/** The object name, for DPRINTF. We have to declare this
* explicitly because Scoreboard is not a SimObject. */
const std::string _name;
/** Scoreboard of physical integer registers, saying whether or not they
* are ready. */
std::vector<bool> regScoreBoard;
/** The number of actual physical registers */
unsigned numPhysRegs;
/**
* The total number of registers which can be indexed, including
* the misc registers that come after the physical registers and
* which are hardwired to be always considered ready.
*/
unsigned numTotalRegs;
/** The index of the zero register. */
PhysRegIndex zeroRegIdx;
/** The index of the FP zero register. */
PhysRegIndex fpZeroRegIdx;
bool isZeroReg(PhysRegIndex idx) const
{
return (idx == zeroRegIdx ||
(THE_ISA == ALPHA_ISA && idx == fpZeroRegIdx));
}
public:
/** Constructs a scoreboard.
* @param activeThreads The number of active threads.
* @param _numLogicalIntRegs Number of logical integer registers.
* @param _numPhysicalIntRegs Number of physical integer registers.
* @param _numLogicalFloatRegs Number of logical fp registers.
* @param _numPhysicalFloatRegs Number of physical fp registers.
* @param _numPhysicalRegs Number of physical registers.
* @param _numMiscRegs Number of miscellaneous registers.
* @param _zeroRegIdx Index of the zero register.
* @param _fpZeroRegIdx Index of the FP zero register (if any, currently
* used only for Alpha).
*/
Scoreboard(unsigned activeThreads,
unsigned _numLogicalIntRegs,
unsigned _numPhysicalIntRegs,
unsigned _numLogicalFloatRegs,
unsigned _numPhysicalFloatRegs,
Scoreboard(const std::string &_my_name,
unsigned _numPhysicalRegs,
unsigned _numMiscRegs,
unsigned _zeroRegIdx);
PhysRegIndex _zeroRegIdx,
PhysRegIndex _fpZeroRegIdx);
/** Destructor. */
~Scoreboard() {}
/** Returns the name of the scoreboard. */
std::string name() const;
std::string name() const { return _name; };
/** Checks if the register is ready. */
bool getReg(PhysRegIndex ready_reg);
bool getReg(PhysRegIndex reg_idx) const
{
assert(reg_idx < numTotalRegs);
if (reg_idx >= numPhysRegs) {
// misc regs are always ready
return true;
}
bool ready = regScoreBoard[reg_idx];
if (isZeroReg(reg_idx))
assert(ready);
return ready;
}
/** Sets the register as ready. */
void setReg(PhysRegIndex phys_reg);
void setReg(PhysRegIndex reg_idx)
{
assert(reg_idx < numTotalRegs);
if (reg_idx >= numPhysRegs) {
// misc regs are always ready, ignore attempts to change that
return;
}
DPRINTF(Scoreboard, "Setting reg %i as ready\n", reg_idx);
assert(reg_idx < numTotalRegs);
regScoreBoard[reg_idx] = true;
}
/** Sets the register as not ready. */
void unsetReg(PhysRegIndex ready_reg);
private:
/** Scoreboard of physical integer registers, saying whether or not they
* are ready.
*/
std::vector<bool> regScoreBoard;
/** Number of logical integer registers. */
int numLogicalIntRegs;
/** Number of physical integer registers. */
int numPhysicalIntRegs;
/** Number of logical floating point registers. */
int numLogicalFloatRegs;
/** Number of physical floating point registers. */
int numPhysicalFloatRegs;
/** Number of miscellaneous registers. */
int numMiscRegs;
/** Number of logical integer + float registers. */
int numLogicalRegs;
/** Number of physical integer + float registers. */
int numPhysicalRegs;
/** The logical index of the zero register. */
int zeroRegIdx;
int currentSize;
void
resize(int newSize)
void unsetReg(PhysRegIndex reg_idx)
{
currentSize = newSize;
regScoreBoard.resize(newSize);
assert(reg_idx < numTotalRegs);
if (reg_idx >= numPhysRegs) {
// misc regs are always ready, ignore attempts to change that
return;
}
// zero reg should never be marked unready
if (isZeroReg(reg_idx))
return;
regScoreBoard[reg_idx] = false;
}
bool
indexInBounds(int idx)
{
return idx < currentSize;
}
};
#endif