OpenASIP 2.2
Loading...
Searching...
No Matches
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
39#include "Application.hh"
40#include "Instruction.hh"
41#include "Procedure.hh"
42
43namespace TTAProgram {
44
45/////////////////////////////////////////////////////////////////////////////
46// InstructionReferenceManager
47/////////////////////////////////////////////////////////////////////////////
48
49/**
50 * Constructor.
51 *
52 * @note Should not be instantiated independent of a Program instance.
53 */
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()) {
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 */
95void
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 */
124void
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 */
142bool
144 return references_.find(&ins) != references_.end();
145}
146
147/**
148 * Tells how many alive references there are to an instruction.
149 */
150unsigned 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 */
164void
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 */
180void
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
#define PRINT_VAR(VARIABLE__)
#define assert(condition)
static std::ostream & logStream()
InstructionAddress location() const
virtual Instruction & firstInstruction() const
virtual bool isInProgram() const
void merge(InstructionReferenceImpl &other)
RefMap references_
Instruction references to maintain.
void replace(Instruction &insA, Instruction &insB)
unsigned int referenceCount(Instruction &ins) const
InstructionReference createReference(Instruction &ins)
Address address() const
CodeSnippet & parent() const
TCEString name() const
Definition Procedure.hh:66