OpenASIP 2.2
Loading...
Searching...
No Matches
ImmInfo.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2016 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 ImmInfo.cc
26 *
27 * Implementation/Declaration of ImmInfo class.
28 *
29 * Created on: 8.3.2016
30 * @author Henry Linjamäki 2016 (henry.linjamaki-no.spam-tut.fi)
31 * @note rating: red
32 */
33
34#include "ImmInfo.hh"
35
36#include <algorithm>
37
38#include "Machine.hh"
39#include "RegisterFile.hh"
40#include "Bus.hh"
41#include "ImmediateUnit.hh"
43
44#include "Operation.hh"
45#include "Operand.hh"
46
48
49#include "Exception.hh"
50#include "TCEString.hh"
51#include "MathTools.hh"
52
53/**
54 * Returns key for ImmInfo data structure.
55 */
57ImmInfo::key(const Operation& operation, int inputOperandId) {
58 return std::make_pair(operation.name().upper(), inputOperandId);
59}
61ImmInfo::key(const Operation& operation, const Operand& operand) {
62 return std::make_pair(operation.name().upper(), operand.index());
63}
64
65
66/**
67 * Returns the entry count for operation, operand pair (key).
68 */
69size_t
70ImmInfo::count(const Operation& operation, const Operand& operand) const {
71 return std::multimap<ImmInfoKey, ImmInfoValue>::count(
72 key(operation, operand));
73}
74
75
76/**
77 * Returns the entry count for operation, operand pair (key).
78 */
79size_t
80ImmInfo::count(const Operation& operation, int inputOperandId) const {
81 return count(operation, operation.operand(inputOperandId));
82}
83
84
85/**
86 * Returns the entry count by the key.
87 */
88const ImmInfoValue&
90 if (std::multimap<ImmInfoKey, ImmInfoValue>::count(key)) {
91 const_iterator it;
92 const_iterator it_largest = this->lower_bound(key);
93 const_iterator it_begin = it_largest;
94 it_begin++;
95 const_iterator it_end = this->upper_bound(key);
96 for (it = it_begin; it != it_end; it++) {
97 if (*it > *it_largest) {
98 it_largest = it;
99 }
100 }
101 assert(it_largest != it_end);
102 return it_largest->second;
103 } else {
104 THROW_EXCEPTION(InstanceNotFound, "No immediate info for key found.");
105 }
106}
107
108/**
109 * returns widest immediate bit width by the key.
110 *
111 * @param operation The operation as the part of the key.
112 * @param inputOperandId The input operand of the operation as the
113 * of the key.
114 */
115const ImmInfoValue&
117 const Operation& operation, const Operand& operand) const {
118
119 return widestImmediate(key(operation, operand));
120}
121
122/**
123 * returns widest immediate bit width by the key.
124 *
125 * @param operation The operation as the part of the key.
126 * @param inputOperandId The input operand id of the operation as the
127 * of the key.
128 */
129const ImmInfoValue&
131 const Operation& operation, int inputOperandId) const {
132
133 return widestImmediate(operation, operation.operand(inputOperandId));
134}
135
136/**
137 * returns narrowest (non-zero width) immediate bit width by the key.
138 */
139const ImmInfoValue&
141 if (std::multimap<ImmInfoKey, ImmInfoValue>::count(key)) {
142 const_iterator it;
143 const_iterator it_largest = lower_bound(key);
144 const_iterator it_begin = it_largest;
145 it_begin++;
146 const_iterator it_end = upper_bound(key);
147 for (it = it_begin; it != it_end; it++) {
148 if (*it < *it_largest) {
149 it_largest = it;
150 }
151 }
152 assert(it_largest != it_end);
153 return it_largest->second;
154 } else {
156 "No immediate info found for the key.");
157 }
158}
159
160
161/**
162 * Default constructor. Set as zero width and as zero extending.
163 */
165 : pair(0, false) {
166}
167
168
169/**
170 * Constructor with the specified immediate width and sign-extension.
171 */
172ImmInfoValue::ImmInfoValue(int immediateWidth, bool signExtending)
173 : pair(immediateWidth, signExtending) {
174}
175
176
177/**
178 * Return largest inclusive value that can be expressed as immediate.
179 */
180int64_t
182 if (second) { // is sign extending?
183 return -(1ll << (first-1));
184 } else { // is then zero extending.
185 return 0;
186 }
187}
188
189/**
190 * Return smallest inclusive value that can be expressed as immediate.
191 */
192int64_t
194 if (second) { // is sign extending?
195 return (1ll << (first-1))-1;
196 } else { // is then zero extending.
197 return (1ll << (first));
198 }
199}
200
201
202/**
203 * Returns smallest and largest number that can be transported to operation
204 * operand.
205 *
206 * The bounds are merged from multiple immediate sources. For example, if
207 * immediates can be transported from two different sources, where the one is
208 * 4 bits zero extending and the another is 3 bits sign extending, the
209 * resulting bound is [-4, 15].
210 *
211 * if destination bit width is specified, then the bounds are ...TODO
212 *
213 * @param destWidth The destination width, where the immediates are
214 * transported to. By default it is unspecified/unlimited.
215 * @return std::pair, where the first is smallest value and second is largest.
216 * If no immediate can be transported, (0, 0) is returned.
217 */
218std::pair<int64_t, int64_t>
220 const ImmInfoKey& key, int destWidth) const {
221
222 std::pair<int64_t, int64_t> result{ 0, 0 };
223
224 const_iterator it_begin = lower_bound(key);
225 const_iterator it_end = upper_bound(key);
226 const_iterator it;
227 for (it = it_begin; it != it_end; it++) {
228 if (destWidth > 0) {
229 if (it->second.width() >= destWidth) {
230 return { (-(1ll << (destWidth-1))), ((1ll << destWidth)-1) };
231 }
232 }
233
234 int64_t currLowerBound = 0;
235 int64_t currUpperBound = 0;
236 if (it->second.signExtending()) {
237 currLowerBound = -(1ll << (it->second.width()-1));
238 currUpperBound = (1ll << (it->second.width()-1))-1;
239 } else {
240 currUpperBound = (1ll << (it->second.width()))-1;
241 }
242
243 result.first = std::min(result.first, currLowerBound);
244 result.second = std::max(result.second, currUpperBound);
245 }
246
247 return result;
248}
249
250
251bool
253 const Operation& operation,
254 int inputOperandId,
255 int64_t value,
256 int /*destWidth*/) {
257
258 auto unsignedReqBits = MathTools::requiredBits(value);
259 auto signedReqBits = MathTools::requiredBitsSigned(value);
260 auto theKey = key(operation, inputOperandId);
261 const_iterator it_begin = lower_bound(theKey);
262 const_iterator it_end = upper_bound(theKey);
263 const_iterator it;
264 for (it = it_begin; it != it_end; it++) {
265 const ImmInfoValue& imm = it->second;
266 if ((imm.signExtending() && signedReqBits <= imm.width()) ||
267 (unsignedReqBits <= imm.width())) {
268 return true;
269 }
270 }
271 return false;
272}
273
274bool
276 const Operation& operation,
277 int inputOperandId,
278 int bitWidth) {
279
280 auto theKey = key(operation, inputOperandId);
281 const_iterator it_begin = lower_bound(theKey);
282 const_iterator it_end = upper_bound(theKey);
283 const_iterator it;
284 for (it = it_begin; it != it_end; it++) {
285 const ImmInfoValue& info = it->second;
286 if (bitWidth <= info.width()) return true;
287 }
288 return false;
289}
290
291/**
292 * Same as immediateValueBounds(const ImmInfoKey& key).
293 *
294 */
295std::pair<int64_t, int64_t>
297 const Operation& operation,
298 const Operand& operand,
299 int destWidth) const {
300 return immediateValueBounds(key(operation, operand), destWidth);
301}
302
303
304/**
305 * Same as immediateValueBounds(const ImmInfoKey& key).
306 *
307 */
308std::pair<int64_t, int64_t>
310 const Operation& operation,
311 int inputOperandId,
312 int destWidth) const {
313
315 operation, operation.operand(inputOperandId), destWidth);
316}
317
318/**
319 * Returns maximum immediate in bit width which can be transported to the RF.
320 *
321 * @param targetRF The target register file.
322 * @param allowSignExtension If representation of the transported immediate
323 * should not change set it to false (default).
324 */
325int
327 const TTAMachine::RegisterFile& targetRF,
328 bool allowSignExtension) {
329
330 using namespace TTAMachine;
331 using MCC = MachineConnectivityCheck;
332
333 int result = 0;
334 assert(targetRF.machine());
335 const Machine& mach = *targetRF.machine();
336
337 for (const Bus* bus : mach.busNavigator()) {
338 if (MCC::busConnectedToRF(*bus, targetRF)) {
339 int immWidth = bus->immediateWidth();
340 if (!allowSignExtension && bus->signExtends()) {
341 immWidth -= 1;
342 }
343 result = std::max(result, immWidth);
344 }
345 }
346
347 for (auto* iu : mach.immediateUnitNavigator()) {
348 for (auto* it : mach.instructionTemplateNavigator()) {
349 int supportedWidth = it->supportedWidth(*iu);
350 if (!allowSignExtension && iu->signExtends()) {
351 supportedWidth -= 1;
352 }
353 result = std::max(result, supportedWidth);
354 }
355 }
356
357 return result;
358}
359
360
#define assert(condition)
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
std::pair< std::string, int > ImmInfoKey
Definition ImmInfo.hh:53
find Finds info of the inner loops in the false
int64_t lowerBound() const
Definition ImmInfo.cc:181
int64_t upperBound() const
Definition ImmInfo.cc:193
bool signExtending() const
Definition ImmInfo.hh:75
int width() const
Definition ImmInfo.hh:71
const ImmInfoValue & widestImmediate(const ImmInfoKey &key) const
Definition ImmInfo.cc:89
static int registerImmediateLoadWidth(const TTAMachine::RegisterFile &targetRF, bool allowSignExtension=false)
Definition ImmInfo.cc:326
bool canTakeImmediate(const Operation &operation, int inputOperandId, int64_t value, int destWidth)
Definition ImmInfo.cc:252
static ImmInfoKey key(const Operation &operation, int inputOperandId)
Definition ImmInfo.cc:57
bool canTakeImmediateByWidth(const Operation &operation, int inputOperandId, int bitWidth)
Definition ImmInfo.cc:275
std::pair< int64_t, int64_t > immediateValueBounds(const ImmInfoKey &key, int destWidth) const
Definition ImmInfo.cc:219
size_t count(const ImmInfoKey &key) const
Definition ImmInfo.hh:87
const ImmInfoValue & narrowestImmediate(const ImmInfoKey &key) const
Definition ImmInfo.cc:140
static int requiredBits(unsigned long int number)
static int requiredBitsSigned(SLongWord number)
virtual int index() const
Definition Operand.cc:135
virtual TCEString name() const
Definition Operation.cc:93
virtual Operand & operand(int id) const
Definition Operation.cc:541
TCEString upper() const
Definition TCEString.cc:86
virtual Machine * machine() const
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416
virtual BusNavigator busNavigator() const
Definition Machine.cc:356