// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: MemoryAccessHistory.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
/************************************************************************
** Copyright (C) 2002, Sun Microsystems, Inc.
** Sun considers its source code as an unpublished, proprietary
** trade secret and it is available only under strict license provisions.
** This copyright notice is placed here only to protect Sun in the event
** the source is deemed a published work. Disassembly, decompilation,
** or other means of reducing the object code to human readable form
** is prohibited by the license agreement under which this code is
** provided to the user or company in possession of this copy."
*************************************************************************/
#include "MemoryAccessHistory.h"
////////////////////////////////////////////////
MemoryAccessHistory::MemoryAccessHistory()
////////////////////////////////////////////////
MemoryAccessHistory::MemoryAccessHistory( const MemoryAccessHistory
& orig
)
////////////////////////////////////////////////
MemoryAccessHistory::~MemoryAccessHistory()
////////////////////////////////////////////////
const MemoryAccessHistory
&
MemoryAccessHistory::operator=( const MemoryAccessHistory
& rhs
)
////////////////////////////////////////////////
MemoryAccessHistory::operator==( const MemoryAccessHistory
& rhs
) const
////////////////////////////////////////////////
MemoryAccessHistory::toString() const
map
<uint64_t,MemoryAccessHistoryItem
>::const_iterator ii
;
os
<< "MemoryAccessHistory (size=" << hist_
.size() << ")" << endl
;
for (ii
= hist_
.begin(); ii
!= hist_
.end(); ii
++) {
const MemoryAccessHistoryItem
& mahi
= ii
->second
;
MemoryAccessHistory::storeCommit (TsoNode
* storeNode
)
pair
<map
<uint64_t,MemoryAccessHistoryItem
>::iterator
,bool> p
;
map
<uint64_t,MemoryAccessHistoryItem
>::iterator ii
;
MemoryAccessHistoryItem
* mahItemPtr
;
list
<TsoNode
*>::iterator ni
;
uint64_t addr
= storeNode
->getAddr();
uint64_t data
= storeNode
->getData();
uint8_t sizeV
= storeNode
->getSizeV();
for (int i
= 0; i
< 8; i
++, bmask
>>= 1, addr
++) {
if (ii
== hist_
.end()) { // insert a new one
mahItemPtr
= new MemoryAccessHistoryItem();
mahItemPtr
->setAddr(addr
);
mahItemPtr
->setData((data
>> (bsft
- i
*8)) & 0xffull
);
p
= hist_
.insert(make_pair(addr
, *mahItemPtr
));
/* form anti-dependence edges */
MemoryAccessHistoryItem
& mahi
= ii
->second
;
mahi
.setData((data
>> (bsft
- i
*8)) & 0xffull
); // update data
for (ni
= mahi
.ldNodeBegin(); ni
!= mahi
.ldNodeEnd(); ni
++) {
if (loadNode
!= storeNode
) { // exclude atomic node
edge
.addEdge (ET_ANTI
, loadNode
, storeNode
);
mahi
.ldNodeClear(); // clear the flow dependence list
/* new storeNode's global observed order idx becomes previous node's retire */
if (mahi
.stNodeSize() > 0) {
(*ni
)->setRetire(storeNode
->getGobs());
edge
.addEdge (ET_OUTPUT
, (*ni
), storeNode
);
mahi
.stNodePushFront(storeNode
);
MSYNC_DEBUG(6, "MAH Push %s",(*(mahi
.stNodeBegin()))->toString().c_str());
MSYNC_DEBUG(8, "%s", toString().c_str());
MemoryAccessHistory::loadAccess (TsoNode
* loadNode
)
map
<uint64_t, MemoryAccessHistoryItem
>::iterator ii
;
list
<TsoNode
*>::iterator ni
;
uint64_t addr
= loadNode
->getAddr();
uint8_t sizeV
= loadNode
->getSizeV();
if (hist_
.size() == 0) return;
MSYNC_DEBUG(8, "%s", toString().c_str());
for (int i
= 0; i
< 8; i
++, bmask
>>= 1, addr
++) {
MemoryAccessHistoryItem
& mahi
= ii
->second
;
MSYNC_DEBUG(8, "Found the node (i=%d) %s", i
, mahi
.toString().c_str());
for (; ni
!= mahi
.stNodeEnd(); ni
++) {
if (loadNode
->getCommit() >= (*ni
)->getCommit()) {
if (ni
== mahi
.stNodeBegin()) { // ldNodeList_ contains only flow-dependent load
mahi
.ldNodePushFront(loadNode
); // to the head stNodeList_ node
edge
.addEdge(ET_FLOW
, *ni
, loadNode
);
if (ni
!= mahi
.stNodeBegin()) {
edge
.addEdge(ET_ANTI
, loadNode
, *ni
);
MSYNC_DEBUG(8, "Not Found the node (i=%d)", i
);
MemoryAccessHistory::removeStoreNode (TsoNode
* storeNodeP
)
pair
<map
<uint64_t,MemoryAccessHistoryItem
>::iterator
,bool> p
;
map
<uint64_t,MemoryAccessHistoryItem
>::iterator ii
;
list
<TsoNode
*>::iterator ni
;
uint64_t addr
= storeNodeP
->getAddr();
uint64_t data
= storeNodeP
->getData();
uint8_t sizeV
= storeNodeP
->getSizeV();
for (int i
= 0; i
< 8; i
++, bmask
>>= 1, addr
++) {
MS_ERROR("Removed storeNode's MAP missing in MemoryAccess History. PA=%llx", addr
);
MemoryAccessHistoryItem
& mahi
= ii
->second
;
for (ni
= mahi
.stNodeBegin(); ni
!= mahi
.stNodeEnd(); ni
++) {
if (ni
== mahi
.stNodeBegin())
MS_ERROR("Removed storeNode matches with the 1st in the list. PA=%llx", addr
);