From bacbb8ecbcee2b4c5c3fe71f415abc5852ae4a8f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 5 Dec 2014 01:47:35 -0800 Subject: cpu: Only check for PC events on instruction boundaries. Only the instruction address is actually checked, so there's no need to check repeatedly while we're working through the microops of a macroop and that's not changing. --- src/cpu/o3/commit_impl.hh | 41 ++++++++++++++++++++++++----------------- src/cpu/simple/atomic.cc | 6 ++++-- src/cpu/simple/timing.cc | 7 ++++--- 3 files changed, 32 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index f0566233c..bb2b17209 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -1,4 +1,5 @@ /* + * Copyright 2014 Google, Inc. * Copyright (c) 2010-2014 ARM Limited * All rights reserved * @@ -1105,20 +1106,27 @@ DefaultCommit::commitInsts() } } - int count = 0; - Addr oldpc; - // Debug statement. Checks to make sure we're not - // currently updating state while handling PC events. - assert(!thread[tid]->noSquashFromTC && !thread[tid]->trapPending); - do { - oldpc = pc[tid].instAddr(); - cpu->system->pcEventQueue.service(thread[tid]->getTC()); - count++; - } while (oldpc != pc[tid].instAddr()); - if (count > 1) { - DPRINTF(Commit, - "PC skip function event, stopping commit\n"); - break; + bool onInstBoundary = !head_inst->isMicroop() || + head_inst->isLastMicroop() || + !head_inst->isDelayedCommit(); + + if (onInstBoundary) { + int count = 0; + Addr oldpc; + // Make sure we're not currently updating state while + // handling PC events. + assert(!thread[tid]->noSquashFromTC && + !thread[tid]->trapPending); + do { + oldpc = pc[tid].instAddr(); + cpu->system->pcEventQueue.service(thread[tid]->getTC()); + count++; + } while (oldpc != pc[tid].instAddr()); + if (count > 1) { + DPRINTF(Commit, + "PC skip function event, stopping commit\n"); + break; + } } // Check if an instruction just enabled interrupts and we've @@ -1128,9 +1136,8 @@ DefaultCommit::commitInsts() // case squash now to make sure the interrupt is handled. // // If we don't do this, we might end up in a live lock situation - if (!interrupt && avoidQuiesceLiveLock && - (!head_inst->isMicroop() || head_inst->isLastMicroop()) && - cpu->checkInterrupts(cpu->tcBase(0))) + if (!interrupt && avoidQuiesceLiveLock && + onInstBoundary && cpu->checkInterrupts(cpu->tcBase(0))) squashAfter(tid, head_inst); } else { DPRINTF(Commit, "Unable to commit head instruction PC:%s " diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 8dcae01c5..aeaebcdb8 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -1,4 +1,5 @@ /* + * Copyright 2014 Google, Inc. * Copyright (c) 2012-2013 ARM Limited * All rights reserved. * @@ -518,10 +519,11 @@ AtomicSimpleCPU::tick() numCycles++; ppCycles->notify(1); - if (!curStaticInst || !curStaticInst->isDelayedCommit()) + if (!curStaticInst || !curStaticInst->isDelayedCommit()) { checkForInterrupts(); + checkPcEventQueue(); + } - checkPcEventQueue(); // We must have just got suspended by a PC event if (_status == Idle) { tryCompleteDrain(); diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index c2bcdee63..c7db5c4f8 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -1,4 +1,5 @@ /* + * Copyright 2014 Google, Inc. * Copyright (c) 2010-2013 ARM Limited * All rights reserved * @@ -551,10 +552,10 @@ TimingSimpleCPU::fetch() { DPRINTF(SimpleCPU, "Fetch\n"); - if (!curStaticInst || !curStaticInst->isDelayedCommit()) + if (!curStaticInst || !curStaticInst->isDelayedCommit()) { checkForInterrupts(); - - checkPcEventQueue(); + checkPcEventQueue(); + } // We must have just got suspended by a PC event if (_status == Idle) -- cgit v1.2.3