summaryrefslogtreecommitdiff
path: root/src/cpu/pred
diff options
context:
space:
mode:
authorMitch Hayenga <mitch.hayenga@arm.com>2016-04-05 11:44:27 -0500
committerMitch Hayenga <mitch.hayenga@arm.com>2016-04-05 11:44:27 -0500
commit3f6874cb295695a225fca6825bfe24a4b97641fd (patch)
treee5a64a9441bc2934fce326d2753e63d126a8c4a0 /src/cpu/pred
parent1097aa1638dc3b1e009738932908ab5c253b461b (diff)
downloadgem5-3f6874cb295695a225fca6825bfe24a4b97641fd.tar.xz
cpu: Fix BTB threading oversight
The extant BTB code doesn't hash on the thread id but does check the thread id for 'btb hits'. This results in 1-thread of a multi-threaded workload taking a BTB entry, and all other threads missing for the same branch missing.
Diffstat (limited to 'src/cpu/pred')
-rw-r--r--src/cpu/pred/bpred_unit.cc3
-rw-r--r--src/cpu/pred/btb.cc18
-rw-r--r--src/cpu/pred/btb.hh7
3 files changed, 18 insertions, 10 deletions
diff --git a/src/cpu/pred/bpred_unit.cc b/src/cpu/pred/bpred_unit.cc
index 8bb84f836..c38927c8d 100644
--- a/src/cpu/pred/bpred_unit.cc
+++ b/src/cpu/pred/bpred_unit.cc
@@ -59,7 +59,8 @@ BPredUnit::BPredUnit(const Params *params)
predHist(numThreads),
BTB(params->BTBEntries,
params->BTBTagSize,
- params->instShiftAmt),
+ params->instShiftAmt,
+ params->numThreads),
RAS(numThreads),
instShiftAmt(params->instShiftAmt)
{
diff --git a/src/cpu/pred/btb.cc b/src/cpu/pred/btb.cc
index 393e52ccf..c7ef1959f 100644
--- a/src/cpu/pred/btb.cc
+++ b/src/cpu/pred/btb.cc
@@ -35,10 +35,12 @@
DefaultBTB::DefaultBTB(unsigned _numEntries,
unsigned _tagBits,
- unsigned _instShiftAmt)
+ unsigned _instShiftAmt,
+ unsigned _num_threads)
: numEntries(_numEntries),
tagBits(_tagBits),
- instShiftAmt(_instShiftAmt)
+ instShiftAmt(_instShiftAmt),
+ log2NumThreads(floorLog2(_num_threads))
{
DPRINTF(Fetch, "BTB: Creating BTB object.\n");
@@ -69,10 +71,12 @@ DefaultBTB::reset()
inline
unsigned
-DefaultBTB::getIndex(Addr instPC)
+DefaultBTB::getIndex(Addr instPC, ThreadID tid)
{
// Need to shift PC over by the word offset.
- return (instPC >> instShiftAmt) & idxMask;
+ return ((instPC >> instShiftAmt)
+ ^ (tid << (tagShiftAmt - instShiftAmt - log2NumThreads)))
+ & idxMask;
}
inline
@@ -85,7 +89,7 @@ DefaultBTB::getTag(Addr instPC)
bool
DefaultBTB::valid(Addr instPC, ThreadID tid)
{
- unsigned btb_idx = getIndex(instPC);
+ unsigned btb_idx = getIndex(instPC, tid);
Addr inst_tag = getTag(instPC);
@@ -106,7 +110,7 @@ DefaultBTB::valid(Addr instPC, ThreadID tid)
TheISA::PCState
DefaultBTB::lookup(Addr instPC, ThreadID tid)
{
- unsigned btb_idx = getIndex(instPC);
+ unsigned btb_idx = getIndex(instPC, tid);
Addr inst_tag = getTag(instPC);
@@ -124,7 +128,7 @@ DefaultBTB::lookup(Addr instPC, ThreadID tid)
void
DefaultBTB::update(Addr instPC, const TheISA::PCState &target, ThreadID tid)
{
- unsigned btb_idx = getIndex(instPC);
+ unsigned btb_idx = getIndex(instPC, tid);
assert(btb_idx < numEntries);
diff --git a/src/cpu/pred/btb.hh b/src/cpu/pred/btb.hh
index 3a773e40d..209bbdb49 100644
--- a/src/cpu/pred/btb.hh
+++ b/src/cpu/pred/btb.hh
@@ -66,7 +66,7 @@ class DefaultBTB
* @param instShiftAmt Offset amount for instructions to ignore alignment.
*/
DefaultBTB(unsigned numEntries, unsigned tagBits,
- unsigned instShiftAmt);
+ unsigned instShiftAmt, unsigned numThreads);
void reset();
@@ -97,7 +97,7 @@ class DefaultBTB
* @param inst_PC The branch to look up.
* @return Returns the index into the BTB.
*/
- inline unsigned getIndex(Addr instPC);
+ inline unsigned getIndex(Addr instPC, ThreadID tid);
/** Returns the tag bits of a given address.
* @param inst_PC The branch's address.
@@ -125,6 +125,9 @@ class DefaultBTB
/** Number of bits to shift PC when calculating tag. */
unsigned tagShiftAmt;
+
+ /** Log2 NumThreads used for hashing threadid */
+ unsigned log2NumThreads;
};
#endif // __CPU_PRED_BTB_HH__