OpenASIP  2.0
InstructionReferenceManager.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file InstructionReferenceManager.cc
26  *
27  * Implementation of InstructionReferenceManager class.
28  *
29  * @author Ari Metsähalme 2005 (ari.metsahalme-no.spam-tut.fi)
30  * @author Heikki Kultala 2009 (heikki.kultala-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
34 #include <iostream>
35 
37 #include "InstructionReference.hh"
39 #include "Application.hh"
40 #include "Instruction.hh"
41 #include "Procedure.hh"
42 
43 namespace TTAProgram {
44 
45 /////////////////////////////////////////////////////////////////////////////
46 // InstructionReferenceManager
47 /////////////////////////////////////////////////////////////////////////////
48 
49 /**
50  * Constructor.
51  *
52  * @note Should not be instantiated independent of a Program instance.
53  */
55 }
56 
57 /**
58  * Destructor. Clears all instruction references.
59  */
61 // assert(references_.empty());
63 }
64 
65 /**
66  * Creates a new reference to an instruction.
67  *
68  * @param ins Referred instruction.
69  * @return A new reference to an instruction, or if one already exists,
70  * return it.
71  */
74  RefMap::const_iterator iter = references_.find(&ins);
75  if (iter == references_.end()) {
76  InstructionReferenceImpl* newRef =
77  new InstructionReferenceImpl(ins, *this);
78  references_[&ins] = newRef;
79  return InstructionReference(newRef);
80  } else {
81  return InstructionReference(iter->second);
82  }
83 }
84 
85 /**
86  * Replaces a referred instruction with another.
87  * This replaces ALL references that point into the same instruction.
88  *
89  * @param insA Instruction to be replaced.
90  * @param insB The new referred instruction.
91  * @return A handle to the reference to the new referred instruction.
92  * @exception InstanceNotFound if the instruction to be replaced is not
93  * found.
94  */
95 void
97  RefMap::iterator itera = references_.find(&insA);
98  if (itera == references_.end()) {
99  throw InstanceNotFound(
100  __FILE__, __LINE__, "InstructionReferenceManager::replace()",
101  "Instruction reference to be replaced not found.");
102  }
103 
104  RefMap::iterator iterb = references_.find(&insB);
105  if (iterb == references_.end()) { // just update one.
106  // no ref to b, just update a to point to b.
107  InstructionReferenceImpl* impl = itera->second;
108  impl->setInstruction(insB);
109  references_.erase(itera);
110  references_[&insB] = impl;
111  return;
112  }
113 
114  // merge the two ref implementations.
115  iterb->second->merge(*itera->second);
116 }
117 
118 /**
119  * Clears all instruction references.
120  *
121  * The result is a totally empty instruction reference manager. This
122  * nullifies all instructionreferences handled by this reference manager.
123  */
124 void
126  // nullify modifies so take new iter every round.
127  for (RefMap::iterator iter = references_.begin();
128  iter != references_.end(); iter = references_.begin()) {
129  assert(iter->second != NULL);
130  // nullify causes use count to drop to 0 which kills this.
131  iter->second->nullify();
132  }
133  references_.clear();
134 }
135 
136 
137 /**
138  * Tells whether the manager has created a reference to the given instruction.
139  *
140  * @return True if the manager has created a reference to the given instruction.
141  */
142 bool
144  return references_.find(&ins) != references_.end();
145 }
146 
147 /**
148  * Tells how many alive references there are to an instruction.
149  */
150 unsigned int
152  RefMap::const_iterator iter = references_.find(&ins);
153  if (iter == references_.end()) {
154  return 0;
155  }
156  return iter->second->count();
157 }
158 
159 /**
160  * Notifies instructionreferencemanager that a reference has completely died.
161  *
162  * This causes the reference manager to remove the reference impl object.
163  */
164 void
166  RefMap::iterator iter = references_.find(ins);
167  assert (iter != references_.end());
168  assert (iter->second->count() == 0);
169  delete iter->second; iter->second = NULL;
170  references_.erase(iter);
171 }
172 
173 /**
174  * Performs sanity checks to the instruction references.
175  *
176  * Asserts in case of illegal irefs found. Before calling this method,
177  * all instruction references must have been "stabilized", i.e.,
178  * pointing to valid instructions inside the Program.
179  */
180 void
182 
184  i != end(); ++i) {
185  Instruction& targetInstruction = i->instruction();
186 
187  if (!targetInstruction.isInProcedure()) {
189  << "Reference to an instruction " << &targetInstruction
190  << " that is not in a Procedure." << std::endl;
191  PRINT_VAR(targetInstruction.address().location());
192  abort();
193  } else if (!targetInstruction.parent().isInProgram()) {
195  << "Reference to an instruction " << &targetInstruction
196  << " that is not in a Program." << std::endl;
197  PRINT_VAR(&(*i));
198  PRINT_VAR(
199  dynamic_cast<TTAProgram::Procedure&>(
200  targetInstruction.parent()).name());
201  PRINT_VAR(
202  &targetInstruction.parent().firstInstruction());
203  PRINT_VAR(targetInstruction.address().location());
204  abort();
205  }
206  }
207 }
208 
209 } // namespace TTAProgram
TTAProgram
Definition: Estimator.hh:65
TTAProgram::InstructionReferenceImpl::setInstruction
void setInstruction(Instruction &ins)
Definition: InstructionReferenceImpl.cc:151
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
TTAProgram::InstructionReferenceManager::end
Iterator end()
PRINT_VAR
#define PRINT_VAR(VARIABLE__)
Definition: Application.hh:118
TTAProgram::Instruction
Definition: Instruction.hh:57
Procedure.hh
TTAProgram::InstructionReferenceManager::references_
RefMap references_
Instruction references to maintain.
Definition: InstructionReferenceManager.hh:120
TTAProgram::InstructionReferenceManager::createReference
InstructionReference createReference(Instruction &ins)
Definition: InstructionReferenceManager.cc:73
TTAProgram::InstructionReferenceManager::InstructionReferenceManager
InstructionReferenceManager()
Definition: InstructionReferenceManager.cc:54
TTAProgram::InstructionReferenceManager::validate
void validate()
Definition: InstructionReferenceManager.cc:181
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
TTAProgram::InstructionReferenceManager::clearReferences
void clearReferences()
Definition: InstructionReferenceManager.cc:125
assert
#define assert(condition)
Definition: Application.hh:86
InstructionReferenceImpl.hh
TTAProgram::InstructionReferenceManager::~InstructionReferenceManager
virtual ~InstructionReferenceManager()
Definition: InstructionReferenceManager.cc:60
Instruction.hh
TTAProgram::InstructionReferenceManager::hasReference
bool hasReference(Instruction &ins) const
Definition: InstructionReferenceManager.cc:143
TTAProgram::InstructionReferenceManager::replace
void replace(Instruction &insA, Instruction &insB)
Definition: InstructionReferenceManager.cc:96
Application.hh
TTAProgram::Instruction::parent
CodeSnippet & parent() const
Definition: Instruction.cc:109
TTAProgram::InstructionReferenceManager::referenceCount
unsigned int referenceCount(Instruction &ins) const
Definition: InstructionReferenceManager.cc:151
TTAProgram::Address::location
InstructionAddress location() const
TTAProgram::Instruction::isInProcedure
bool isInProcedure() const
Definition: Instruction.cc:135
InstructionReference.hh
InstructionReferenceManager.hh
TTAProgram::Procedure::name
TCEString name() const
Definition: Procedure.hh:66
TTAProgram::InstructionReferenceImpl::merge
void merge(InstructionReferenceImpl &other)
Definition: InstructionReferenceImpl.cc:134
TTAProgram::InstructionReferenceManager::referenceDied
void referenceDied(Instruction *ins)
Definition: InstructionReferenceManager.cc:165
TTAProgram::InstructionReferenceManager::begin
Iterator begin()
TTAProgram::InstructionReference
Definition: InstructionReference.hh:49
TTAProgram::Procedure
Definition: Procedure.hh:55
TTAProgram::InstructionReferenceImpl
Definition: InstructionReferenceImpl.hh:48
TTAProgram::Instruction::address
Address address() const
Definition: Instruction.cc:327
InstanceNotFound
Definition: Exception.hh:304
TTAProgram::CodeSnippet::isInProgram
virtual bool isInProgram() const
Definition: CodeSnippet.cc:151
TTAProgram::InstructionReferenceManager::Iterator
Definition: InstructionReferenceManager.hh:99