struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / src / SDCCgenconstprop.cc
bloba6c2b3949936131b23f992bc14f36776ea0a2e31
1 // (c) 2023-2024 Philipp Klaus Krause, philipp@colecovision.eu
2 //
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 //
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the
7 // Free Software Foundation; either version 2, or (at your option) any
8 // later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // Generalized constant propagation.
22 #undef DEBUG_GCP_ANALYSIS
23 #undef DEBUG_GCP_OPT
25 #include <map>
26 #include <set>
27 #include <queue>
28 #include <iostream>
29 #include <ios>
31 #include <boost/graph/graphviz.hpp>
33 #include "SDCCtree_dec.hpp" // We just need it for the titlewriter for debug cfg dumping.
35 extern "C"
37 #include "common.h"
40 static bool
41 operator != (const valinfo &v0, const valinfo &v1)
43 if (v0.nothing && v1.nothing)
44 return (true);
45 return (v0.nothing != v1.nothing || v0.anything != v1.anything ||
46 v0.min != v1.min || v0.max != v1.max ||
47 v0.knownbitsmask != v1.knownbitsmask);
50 struct valinfos
52 std::map <int, struct valinfo> map;
55 struct cfg_genconstprop_node
57 iCode *ic;
60 typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, cfg_genconstprop_node, struct valinfos> cfg_t;
62 // A quick-and-dirty function to get the CFG from sdcc (a simplified version of the function from SDCCralloc.hpp).
63 static void
64 create_cfg_genconstprop (cfg_t &cfg, iCode *start_ic, ebbIndex *ebbi)
66 iCode *ic;
68 std::map<int, unsigned int> key_to_index;
70 int i;
72 for (ic = start_ic, i = 0; ic; ic = ic->next, i++)
74 boost::add_vertex(cfg);
75 key_to_index[ic->key] = i;
76 cfg[i].ic = ic;
80 // Get control flow graph from sdcc.
81 for (ic = start_ic; ic; ic = ic->next)
83 if (ic->op != GOTO && ic->op != RETURN && ic->op != JUMPTABLE && ic->next)
84 boost::add_edge(key_to_index[ic->key], key_to_index[ic->next->key], cfg);
86 if (ic->op == GOTO)
87 boost::add_edge(key_to_index[ic->key], key_to_index[eBBWithEntryLabel(ebbi, ic->label)->sch->key], cfg);
88 else if (ic->op == RETURN)
89 boost::add_edge(key_to_index[ic->key], key_to_index[eBBWithEntryLabel(ebbi, returnLabel)->sch->key], cfg);
90 else if (ic->op == IFX)
91 boost::add_edge(key_to_index[ic->key], key_to_index[eBBWithEntryLabel(ebbi, IC_TRUE(ic) ? IC_TRUE(ic) : IC_FALSE(ic))->sch->key], cfg);
92 else if (ic->op == JUMPTABLE) // This can create a multigraph. We actually need those multiple edges later for correctness of the analysis.
93 for (symbol *lbl = (symbol *)(setFirstItem (IC_JTLABELS (ic))); lbl; lbl = (symbol *)(setNextItem (IC_JTLABELS (ic))))
94 boost::add_edge(key_to_index[ic->key], key_to_index[eBBWithEntryLabel(ebbi, lbl)->sch->key], cfg);
98 struct valinfo
99 getTypeValinfo (sym_link *type, bool loose)
101 struct valinfo v;
102 v.anything = true;
103 v.nothing = false;
104 // Initialize all members of v, to ensure we don't read uninitalized memory later.
105 v.min = v.max = 0ll;
106 v.knownbitsmask = 0ull;
107 v.knownbits = 0ull;
109 if (IS_BOOLEAN (type))
111 v.anything = false;
112 v.min = 0;
113 v.max = 1;
114 v.knownbitsmask = ~1ull;
115 v.knownbits = 0;
117 else if (IS_PTR (type) || IS_ARRAY (type))
119 v.anything = false;
120 v.min = 0;
121 if (IS_FUNCPTR (type))
122 v.max = (1ll << ((IFFUNC_ISBANKEDCALL (type->next) ? BFUNCPTRSIZE : FUNCPTRSIZE) * 8)) - 1;
123 else
124 v.max = (1ll << (GPTRSIZE * 8)) - 1;
125 v.knownbitsmask = ~((unsigned long long)v.max);
126 if (TARGET_IS_MCS51 && IS_PTR (type) && !IS_GENPTR (type) ||
127 TARGET_PDK_LIKE && IS_PTR (type) && (DCL_TYPE (type) == CPOINTER || DCL_TYPE (type) == POINTER))
129 int addrbits = GPTRSIZE * 8;
130 if (TARGET_IS_MCS51)
132 if (DCL_TYPE (type) == POINTER)
133 addrbits = 7;
134 else if (DCL_TYPE (type) == IPOINTER || DCL_TYPE (type) == PPOINTER)
135 addrbits = 8;
136 else
137 addrbits = 16;
139 else if (TARGET_PDK_LIKE)
140 addrbits = (DCL_TYPE (type) == CPOINTER ? 10 : 6) + TARGET_IS_PDK14 * 1 + TARGET_IS_PDK15 * 2 + TARGET_IS_PDK16 * 3;
141 else
142 wassert (0);
143 unsigned long long addrmask = ~(~0ull << addrbits);
144 v.knownbitsmask |= ~addrmask;
145 v.knownbits &= addrmask;
146 if (TARGET_IS_MCS51)
147 v.knownbits |= (unsigned long long)pointerTypeToGPByte (DCL_TYPE (type), 0, 0) << 16;
148 else if (TARGET_PDK_LIKE)
149 v.knownbits |= (DCL_TYPE (type) == CPOINTER ? 0x8000 : 0x0000);
150 else
151 wassert (0);
154 else if (IS_INTEGRAL (type) && IS_UNSIGNED (type) && bitsForType (type) < 64)
156 v.anything = false;
157 v.min = 0;
158 v.max = 0xffffffffffffffffull >> (64 - bitsForType (type));
159 v.knownbitsmask = ~(0xffffffffffffffffull >> (64 - bitsForType (type)));
160 v.knownbits = 0;
162 else if (IS_INTEGRAL (type) && !IS_UNSIGNED (type) && bitsForType (type) < 63)
164 v.anything = false;
165 v.max = 0x7fffffffffffffffull >> (64 - bitsForType (type));
166 v.min = -v.max - 1;
167 if (loose && IS_CHAR (type))
168 v.max = 0xffffffffffffffffull >> (64 - bitsForType (type)); // Use upper limit of unsigned type here, since sometimes, SDCC generates incorrect AST (using signed char, where there should be unsigned char) trying to avoid the costs of integer promotion.
169 v.knownbitsmask = ~(0xffffffffffffffffull >> (64 - bitsForType (type)));
170 v.knownbits = 0;
172 return (v);
175 static void
176 valinfoCast (struct valinfo *result, sym_link *targettype, const struct valinfo &right);
178 struct valinfo
179 getOperandValinfo (const iCode *ic, const operand *op)
181 wassert (ic);
183 struct valinfo v;
184 v.anything = true;
185 v.nothing = false;
186 v.min = v.max = 0;
187 v.knownbitsmask = 0ull;
188 v.knownbits = 0ull;
190 if (!op)
191 return (v);
193 sym_link *type = operandType (op);
195 if (IS_INTEGRAL (type) && bitsForType (type) < 64 && !IS_OP_VOLATILE (op) && // Todo: More exact check than this bits thing?
196 (IS_OP_LITERAL (op) || IS_SYMOP (op) && SPEC_CONST (type) && OP_SYMBOL_CONST (op)->ival && IS_AST_VALUE (list2expr (OP_SYMBOL_CONST (op)->ival))))
198 struct valinfo v2;
199 long long litval;
200 if (IS_OP_LITERAL (op))
201 litval = operandLitValueUll (op);
202 else
203 litval = ullFromVal (list2expr (OP_SYMBOL_CONST (op)->ival)->opval.val);
204 v2.anything = false;
205 v2.nothing = false;
206 v2.min = litval;
207 v2.max = litval;
208 v2.knownbitsmask = ~0ull;
209 v2.knownbits = litval;
210 valinfoCast (&v, type, v2); // Need to cast: ival could be out of range of type.
211 return (v);
213 else if (IS_ITEMP (op) && !IS_OP_VOLATILE (op))
215 if (ic->valinfos && ic->valinfos->map.find (op->key) != ic->valinfos->map.end ())
216 return (ic->valinfos->map[op->key]);
217 v.nothing = true;
218 v.anything = false;
219 return (v);
221 else
222 return (getTypeValinfo (type, true));
225 bool
226 valinfo_union (struct valinfo *v0, const struct valinfo v1)
228 bool change = false;
229 auto new_anything = v0->anything || v1.anything;
230 change |= (v0->anything != new_anything);
231 v0->anything = new_anything;
232 auto new_nothing = v0->nothing && v1.nothing;
233 change |= (v0->nothing != new_nothing);
234 v0->nothing = new_nothing;
235 auto new_min = std::min (v0->min, v1.min);
236 change |= (v0->min != new_min);
237 v0->min = new_min;
238 auto new_max = std::max (v0->max, v1.max);
239 change |= (v0->max != new_max);
240 v0->max = new_max;
241 auto new_knownbitsmask = v0->knownbitsmask & v1.knownbitsmask & ~(v0->knownbits ^ v1.knownbits);
242 change |= (v0->knownbitsmask != new_knownbitsmask);
243 v0->knownbitsmask = new_knownbitsmask;
244 return (change);
247 bool
248 valinfos_union (iCode *ic, int key, const struct valinfo &v)
250 if (!ic /*|| !bitVectBitValue(ic->rlive, key)*/) // Unfortunately, rlive info is inaccurate, so we can't rely on it.
251 return (false);
253 if (ic->valinfos && ic->valinfos->map.find (key) != ic->valinfos->map.end())
254 return (valinfo_union (&ic->valinfos->map[key], v));
255 else
257 if (!ic->valinfos)
258 ic->valinfos = new struct valinfos;
259 ic->valinfos->map[key] = v;
260 return (true);
264 bool
265 valinfos_unions (iCode *ic, const struct valinfos &v)
267 bool change = false;
268 for (auto i = v.map.begin(); i != v.map.end(); ++i)
269 change |= valinfos_union (ic, i->first, i->second);
270 return (change);
273 static void
274 dump_op_info (std::ostream &os, const iCode *ic, operand *op)
276 struct valinfo v = getOperandValinfo (ic, op);
277 os << "";
278 if (v.nothing)
279 os << "X";
280 if (v.anything)
281 os << "*";
282 else
283 os << "[" << v.min << ", " << v.max << "] " << v.knownbitsmask;
286 // Dump cfg.
287 static void
288 dump_cfg_genconstprop (const cfg_t &cfg, const std::string& suffix)
290 std::ofstream dump_file ((std::string (dstFileName) + ".dumpgenconstpropcfg" + suffix + (currFunc ? currFunc->rname : "__global") + ".dot").c_str());
292 std::string *name = new std::string[num_vertices (cfg)];
293 for (unsigned int i = 0; i < boost::num_vertices (cfg); i++)
295 std::ostringstream os;
296 iCode *ic = cfg[i].ic;
297 os << i << ", " << ic->key << ": (";
298 os << std::showbase << std::hex;
299 if (ic->left)
300 dump_op_info (os, ic, IC_LEFT (ic));
301 os << ", ";
302 if (ic->right)
303 dump_op_info (os, ic, IC_RIGHT (ic));
304 os << ")";
305 if (ic->resultvalinfo)
307 os << " -> ";
308 if (ic->resultvalinfo->nothing)
309 os << "X";
310 else if (ic->resultvalinfo->anything)
311 os << "*";
312 else
313 os << "[" << ic->resultvalinfo->min << ", " << ic->resultvalinfo->max << "] " << ic->resultvalinfo->knownbitsmask;
315 name[i] = os.str();
317 boost::write_graphviz(dump_file, cfg, boost::make_label_writer(name), boost::default_writer(), cfg_titlewriter((currFunc ? currFunc->rname : "__global"), " generalized constant propagation"));
319 delete[] name;
322 // Update fields of valinfo struct from each other. TODO: Make some of this work also for negative v->min.
323 static void
324 valinfoUpdate (struct valinfo *v)
326 if (v->anything || v->nothing)
327 return;
329 // Update bits from min/max.
330 if (v->min == v->max) // Fixed value.
332 v->knownbitsmask = ~0ull;
333 v->knownbits = v->min;
334 return;
336 for (int i = 0; i < 62; i++) // Leading zeroes.
338 if (v->min >= 0 && v->max < (1ll << i))
340 v->knownbitsmask |= (~0ull << i);
341 v->knownbits &= ~(~0ull << i);
345 // Update min/max from bits.
346 if (v->min >= 0)
348 unsigned long long bitmax = (v->knownbitsmask & v->knownbits) | ~v->knownbitsmask;
349 if (bitmax < (unsigned long long)(v->max))
350 v->max = bitmax;
351 unsigned long long bitmin = v->knownbitsmask & v->knownbits;
352 if (bitmin > (unsigned long long)(v->min))
353 v->min = bitmin;
357 static void
358 valinfoPlus (struct valinfo *result, sym_link *resulttype, const struct valinfo &left, const struct valinfo &right)
360 if (result->anything)
361 result->knownbitsmask = 0ull;
362 // todo: rewrite using ckd_add when we can assume host compiler has c2x support!
363 if (!left.anything && !right.anything &&
364 left.min > LLONG_MIN / 2 && right.min > LLONG_MIN / 2 &&
365 left.max < LLONG_MAX / 2 && right.max < LLONG_MAX / 2)
367 result->nothing = left.nothing || right.nothing;
368 auto min = left.min + right.min;
369 auto max = left.max + right.max;
370 if (result->anything || min >= result->min && max <= result->max)
372 result->anything = false;
373 result->min = min;
374 result->max = max;
377 if (IS_PTR (resulttype) && !left.anything && !right.anything)
379 if (TARGET_IS_MCS51)
381 result->knownbitsmask |= (left.knownbitsmask & 0xff0000ull);
382 result->knownbits = result->knownbits & ~0xff0000ull | left.knownbits & 0xff0000ull;
384 else if (TARGET_PDK_LIKE)
386 result->knownbitsmask |= (left.knownbitsmask & 0x8000ull);
387 result->knownbits = result->knownbits & ~0x8000ull | left.knownbits & 0x8000ull;
390 if (!left.anything && !right.anything &&
391 left.min >= 0 && right.min >= 0)
393 for (int i = 0; i < 61; i++) // If there are 0 bits in the same position on both sides, carry will be absorbed and not affect the following bit.
395 unsigned long long mask = (0x3ull << i);
396 if ((left.knownbitsmask & mask) != mask)
397 continue;
398 if ((right.knownbitsmask & mask) != mask)
399 continue;
400 unsigned long long mask1 = (0x1ull << i);
401 if ((left.knownbits & mask1) || (right.knownbits & mask1))
402 continue;
403 unsigned long long mask2 = (0x2ull << i);
404 if ((left.knownbits & mask2) && (right.knownbits & mask2))
405 continue;
406 result->knownbitsmask |= mask2;
407 if ((left.knownbits & mask2) || (right.knownbits & mask2))
408 result->knownbits |= mask2;
409 else
410 result->knownbits &= ~mask2;
415 static void
416 valinfoMinus (struct valinfo *result, sym_link *resulttype, const struct valinfo &left, const struct valinfo &right)
418 if (result->anything)
419 result->knownbitsmask = 0ull;
421 if (IS_PTR (resulttype) && !left.anything && !right.anything)
423 if (TARGET_IS_MCS51)
425 result->knownbitsmask |= (left.knownbitsmask & 0xff0000ull);
426 result->knownbits = result->knownbits & ~0xff0000ull | left.knownbits & 0xff0000ull;
428 else if (TARGET_PDK_LIKE)
430 result->knownbitsmask |= (left.knownbitsmask & 0x8000ull);
431 result->knownbits = result->knownbits & ~0x8000ull | left.knownbits & 0x8000ull;
434 // todo: rewrite using ckd_sub when we can assume host compiler has c2x support!
435 if (!left.anything && !right.anything &&
436 left.min > LLONG_MIN / 2 && right.min > LLONG_MIN / 2 &&
437 left.max < LLONG_MAX / 2 && right.max < LLONG_MAX / 2)
439 result->nothing = left.nothing || right.nothing;
440 auto min = left.min - right.max;
441 auto max = left.max - right.min;
442 if (result->anything || min >= result->min && max <= result->max)
444 result->anything = false;
445 result->min = min;
446 result->max = max;
451 static void
452 valinfoMult (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
454 if (result->anything)
455 result->knownbitsmask = 0ull;
457 // todo: rewrite using ckd_mul when we can assume host compiler has c2x support!
458 if (!left.anything && !right.anything &&
459 left.min >=0 && right.min >= 0 &&
460 left.max < (1ll << 31) && right.max < (1ll << 31))
462 result->nothing = left.nothing || right.nothing;
463 auto min = left.min * right.min;
464 auto max = left.max * right.max;
465 if (result->anything || min >= result->min && max <= result->max)
467 result->anything = false;
468 result->min = min;
469 result->max = max;
474 static void
475 valinfoDiv (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
477 if (result->anything)
478 result->knownbitsmask = 0ull;
480 if (!left.anything && left.min >= result->min && left.max <= result->max)
482 if (!right.anything && right.min >= 0)
484 result->min = std::min (left.min, 0ll);
485 result->max = std::max (left.max, 0ll);
488 if (!right.anything && right.min > 0 && result->max >= 0)
489 result->max /= right.min;
492 static void
493 valinfoMod (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
495 if (result->anything)
496 result->knownbitsmask = 0ull;
498 if (!left.anything && left.min >= result->min && left.max <= result->max)
500 result->min = std::min (left.min, 0ll);
501 result->max = std::max (left.max, 0ll);
503 if (!left.anything && !right.anything && left.min >= 0 && right.min >= 0 && right.max <= result->max)
504 result->max = right.max - 1;
507 static void
508 valinfoOr (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
510 if (!left.anything && !right.anything &&
511 left.min >= 0 && right.min >= 0 && !result->anything)
513 result->nothing = left.nothing || right.nothing;
514 result->min = std::max (left.min, right.min);
515 result->max = std::max (left.max, right.max);
516 long long max = std::min (left.max, right.max);
517 for(int i = 0; max > 0; i++)
519 result->max |= (1ll << i);
520 max >>= 1;
523 result->knownbitsmask = (left.knownbitsmask & right.knownbitsmask) | (left.knownbitsmask & left.knownbits) | (right.knownbitsmask & right.knownbits);
524 result->knownbits = left.knownbits | right.knownbits;
527 static void
528 valinfoAnd (struct valinfo *result, sym_link *resulttype, const struct valinfo &left_orig, const struct valinfo &right_orig)
530 // In iCode, bitwise and sometimes has operands of different type.
531 struct valinfo left, right;
532 valinfoCast (&left, resulttype, left_orig);
533 valinfoCast (&right, resulttype, right_orig);
535 if (!left.anything && !right.anything &&
536 (left.min >= 0 || right.min >= 0))
538 result->anything = false;
539 result->nothing = left.nothing || right.nothing;
540 result->min = 0;
541 if (left.min >= 0 && right.min >= 0)
542 result->max = std::min (left.max, right.max);
544 result->knownbitsmask = (left.knownbitsmask & right.knownbitsmask) | (left.knownbitsmask & ~left.knownbits) | (right.knownbitsmask & ~right.knownbits);
545 result->knownbits = left.knownbits & right.knownbits;
548 static void
549 valinfoXor (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
551 if (!left.anything && !right.anything &&
552 left.min >= 0 && right.min >= 0 && !result->anything)
554 result->nothing = left.nothing || right.nothing;
555 result->min = 0;
556 result->max = std::max (left.max, right.max);
557 long long max = std::min (left.max, right.max);
558 for(int i = 0; max > 0; i++)
560 result->max |= (1ll << i);
561 max >>= 1;
564 result->knownbitsmask = (left.knownbitsmask & right.knownbitsmask);
565 result->knownbits = left.knownbits ^ right.knownbits;
568 static void
569 valinfoGetABit (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
571 result->anything = false;
572 result->nothing = left.nothing || right.nothing;
573 if (result->max > 0)
575 result->min = 0;
576 result->max = 1;
578 result->knownbitsmask = ~1ull;
581 static void
582 valinfoLeft (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
584 if (!left.anything && !right.anything && right.min == right.max && right.max < 62)
586 result->nothing = left.nothing || right.nothing;
587 long long min, max;
588 min = left.min;
589 max = left.max;
590 for(long long r = right.max; r; r--)
592 if (min < 0 || max > (1ll << 61))
593 return;
594 min <<= 1;
595 max <<= 1;
597 if (!result->anything)
598 max = std::min (result->max, max);
599 result->anything = false;
600 result->min = min;
601 result->max = max;
603 if(!right.anything && right.min > 0 && right.min < 63)
605 result->knownbitsmask |= ~(~0ull << right.min);
606 result->knownbits &= (~0ull << right.min);
610 static void
611 valinfoRight (struct valinfo *result, const struct valinfo &left, const struct valinfo &right)
613 if (!left.anything && !right.anything &&
614 left.min >= 0 && right.min >= 0 && right.min <= 61)
616 result->nothing = left.nothing || right.nothing;
617 result->min = 0;
618 auto max = (left.max >> right.min);
619 if (result->anything || max <= result->max)
620 result->max = max;
621 result->anything = false;
622 if (right.min == right.max)
624 result->knownbitsmask = left.knownbitsmask >> right.min;
625 result->knownbits = left.knownbits >> right.min;
630 static void
631 valinfoCast (struct valinfo *result, sym_link *targettype, const struct valinfo &right)
633 *result = getTypeValinfo (targettype, false);
634 if (right.nothing)
635 result->nothing = true;
636 else if (!right.anything && (IS_INTEGRAL (targettype) || IS_GENPTR (targettype)) &&
637 (!result->anything && right.min >= result->min && right.max <= result->max || result->anything))
639 result->min = right.min;
640 result->max = right.max;
641 if (result->min >= 0)
643 result->knownbitsmask = right.knownbitsmask;
644 result->knownbits = right.knownbits;
646 else if (result->max < 0 && bitsForType (targettype) < 64)
648 unsigned long long topmask = (~0ull << bitsForType (targettype));
649 result->knownbitsmask = right.knownbitsmask | topmask;
650 result->knownbits = right.knownbits | topmask;
653 else if (!right.anything && IS_INTEGRAL (targettype) && SPEC_USIGN(targettype) && right.min == right.max)
655 result->anything = false;
656 result->min = right.min & ~result->knownbitsmask;
657 result->max = right.max & ~result->knownbitsmask;
658 result->knownbitsmask = ~0ull;
659 result->knownbits = result->min;
663 static void
664 recompute_node (cfg_t &G, unsigned int i, ebbIndex *ebbi, std::pair<std::queue<unsigned int>, std::set<unsigned int> > &todo, bool externchange, int end_it_quickly)
666 iCode *const ic = G[i].ic;
667 bool change = externchange;
669 operand *left = IC_LEFT (ic);
670 operand *right = IC_RIGHT (ic);
671 struct valinfo oldleftvalinfo = getOperandValinfo (ic, left);
672 struct valinfo oldrightvalinfo = getOperandValinfo (ic, right);
674 if (!ic->valinfos)
675 ic->valinfos = new struct valinfos;
677 // Gather incoming information.
678 typedef /*typename*/ boost::graph_traits<cfg_t>::in_edge_iterator in_iter_t;
679 in_iter_t in, in_end;
680 for (boost::tie(in, in_end) = boost::in_edges(i, G); in != in_end; ++in)
681 change |= valinfos_unions (ic, G[*in]);
683 typedef /*typename*/ boost::graph_traits<cfg_t>::out_edge_iterator out_iter_t;
684 out_iter_t out, out_end;
685 boost::tie(out, out_end) = boost::out_edges(i, G);
687 if (!change || out == out_end)
688 return;
690 symbol *resultsym;
691 if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)) && !POINTER_SET (ic))
692 resultsym = OP_SYMBOL (IC_RESULT (ic));
693 else
694 resultsym = 0;
695 struct valinfo resultvalinfo;
697 struct valinfo leftvalinfo = getOperandValinfo (ic, left);
698 struct valinfo rightvalinfo = getOperandValinfo (ic, right);
700 bool localchange = externchange || leftvalinfo != oldleftvalinfo || rightvalinfo != oldrightvalinfo;
702 switch (ic->op)
704 case IFX:
705 case JUMPTABLE:
706 for(; out != out_end; ++out)
708 G[*out] = *ic->valinfos;
709 if (todo.second.find (boost::target(*out, G)) == todo.second.end())
711 todo.first.push (boost::target(*out, G));
712 todo.second.insert (boost::target(*out, G));
715 if (ic->op == IFX && bitVectnBitsOn (OP_DEFS (ic->left)) == 1) // Propagate some info on the condition into the branches.
717 iCode *cic = (iCode *)hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (ic->left)));
718 struct valinfo v = getOperandValinfo (ic, cic->left);
719 if (cic->op == '>' && IS_ITEMP (cic->left) && !IS_OP_VOLATILE (cic->left) && IS_INTEGRAL (operandType (cic->left)) &&
720 IS_OP_LITERAL (IC_RIGHT (cic)) && !v.anything && !v.nothing && operandLitValueUll(IC_RIGHT (cic)) < +1000)
722 long long litval = operandLitValueUll (IC_RIGHT (cic));
723 struct valinfo v_true = v;
724 struct valinfo v_false = v;
725 v_true.min = std::max (v.min, litval + 1);
726 v_false.max = std::min (v.max, litval);
727 valinfoUpdate (&v_true);
728 valinfoUpdate (&v_false);
729 int key_true = IC_TRUE (ic) ? eBBWithEntryLabel(ebbi, IC_TRUE(ic))->sch->key : ic->next->key;
730 int key_false = IC_FALSE (ic) ? eBBWithEntryLabel(ebbi, IC_FALSE(ic))->sch->key : ic->next->key;
731 boost::tie(out, out_end) = boost::out_edges(i, G);
732 for(; out != out_end; ++out)
733 if (G[boost::target(*out, G)].ic->key == key_true)
734 G[*out].map[cic->left->key] = v_true;
735 else if (G[boost::target(*out, G)].ic->key == key_false)
736 G[*out].map[cic->left->key] = v_false;
738 if (cic->op == '<' && IS_ITEMP (cic->left) && !IS_OP_VOLATILE (cic->left) && IS_INTEGRAL (operandType (cic->left)) &&
739 IS_OP_LITERAL (IC_RIGHT (cic)) && !v.anything && !v.nothing && operandLitValueUll(IC_RIGHT (cic)) < 0xffffffff)
741 long long litval = operandLitValueUll (IC_RIGHT (cic));
742 struct valinfo v_true = v;
743 struct valinfo v_false = v;
744 v_true.max = std::min (v.max, litval - 1);
745 v_false.min = std::max (v.min, litval);
746 valinfoUpdate (&v_true);
747 valinfoUpdate (&v_false);
748 int key_true = IC_TRUE (ic) ? eBBWithEntryLabel(ebbi, IC_TRUE(ic))->sch->key : ic->next->key;
749 int key_false = IC_FALSE (ic) ? eBBWithEntryLabel(ebbi, IC_FALSE(ic))->sch->key : ic->next->key;
750 boost::tie(out, out_end) = boost::out_edges(i, G);
751 for(; out != out_end; ++out)
752 if (G[boost::target(*out, G)].ic->key == key_true)
753 G[*out].map[cic->left->key] = v_true;
754 else if (G[boost::target(*out, G)].ic->key == key_false)
755 G[*out].map[cic->left->key] = v_false;
758 break;
759 default:
760 G[*out] = *ic->valinfos;
761 if (ic->resultvalinfo)
762 G[*out].map[ic->result->key] = *ic->resultvalinfo;
764 if (resultsym)
765 resultvalinfo = getTypeValinfo (operandType (IC_RESULT (ic)), true);
766 else
767 resultvalinfo.anything = true;
769 #ifdef DEBUG_GCP_ANALYSIS
770 if (localchange && resultsym)
772 std::cout << "Recompute node " << i << " ic " << ic->key << "\n";
773 std::cout << "getTypeValinfo: resultvalinfo anything " << resultvalinfo.anything << " knownbitsmask 0x" << std::hex << resultvalinfo.knownbitsmask << std::dec << " min " << resultvalinfo.min << "\n";
775 #endif
777 // Just use the very rough approximation from the type info only to speed up analysis.
778 if (ic->op != '=' && ic->op != CAST && ic->op != '!' &&
779 (end_it_quickly > 1 || end_it_quickly > 0 && (ic->op == '+' || ic->op == '-')))
781 if (left && !(IS_INTEGRAL (operandType (left)) && bitsForType (operandType (left)) < 64 && IS_OP_LITERAL (left)))
782 leftvalinfo = getTypeValinfo (operandType (left), true);
783 if (right && !(IS_INTEGRAL (operandType (right)) && bitsForType (operandType (right)) < 64 && IS_OP_LITERAL (right)))
784 rightvalinfo = getTypeValinfo (operandType (right), true);
787 if (!localchange) // Input didn't change. No need to recompute result.
788 resultsym = 0;
789 else if (IS_OP_VOLATILE (ic->result)) // No point trying to find out what we write to a volatile operand. At the next use, it could be anything, anyway.
791 else if (ic->op == '!')
793 resultvalinfo.nothing = leftvalinfo.nothing;
794 resultvalinfo.anything = false;
795 resultvalinfo.min = 0;
796 resultvalinfo.max = 1;
797 resultvalinfo.knownbitsmask = ~1ull;
798 resultvalinfo.knownbits = 0ull;
799 if (!leftvalinfo.anything && (leftvalinfo.min > 0 || leftvalinfo.max < 0))
800 resultvalinfo.max = 0;
801 else if (!leftvalinfo.anything && leftvalinfo.min == 0 && leftvalinfo.max == 0)
802 resultvalinfo.min = 1;
804 else if (ic-> op == UNARYMINUS)
806 struct valinfo z;
807 z.nothing = false;
808 z.anything = false;
809 z.min = z.max = 0;
810 valinfoMinus (&resultvalinfo, operandType (ic->result), z, leftvalinfo);
812 else if (ic->op == '<' || ic->op == GE_OP)
814 resultvalinfo.nothing = leftvalinfo.nothing || rightvalinfo.nothing;
815 resultvalinfo.anything = false;
816 resultvalinfo.min = 0;
817 resultvalinfo.max = 1;
818 resultvalinfo.knownbitsmask = ~1ull;
819 resultvalinfo.knownbits = 0ull;
820 if (!leftvalinfo.anything && !rightvalinfo.anything)
822 if (leftvalinfo.max < rightvalinfo.min)
823 resultvalinfo.min = resultvalinfo.max = (ic->op == '<');
824 else if (leftvalinfo.min >= rightvalinfo.max)
825 resultvalinfo.min = resultvalinfo.max = (ic->op == GE_OP);
828 else if (ic->op == '>' || ic->op == LE_OP)
830 resultvalinfo.nothing = leftvalinfo.nothing || rightvalinfo.nothing;
831 resultvalinfo.anything = false;
832 resultvalinfo.min = 0;
833 resultvalinfo.max = 1;
834 resultvalinfo.knownbitsmask = ~1ull;
835 resultvalinfo.knownbits = 0ull;
836 if (!leftvalinfo.anything && !rightvalinfo.anything)
838 if (leftvalinfo.min > rightvalinfo.max)
839 resultvalinfo.min = resultvalinfo.max = (ic->op == '>');
840 else if (leftvalinfo.max <= rightvalinfo.min)
841 resultvalinfo.min = resultvalinfo.max = (ic->op == LE_OP);
844 else if (ic->op == NE_OP || ic->op == EQ_OP)
846 resultvalinfo.nothing = leftvalinfo.nothing || rightvalinfo.nothing;
847 resultvalinfo.anything = false;
848 resultvalinfo.min = 0;
849 resultvalinfo.max = 1;
850 resultvalinfo.knownbitsmask = ~1ull;
851 resultvalinfo.knownbits = 0ull;
852 if (!leftvalinfo.anything && !rightvalinfo.anything && leftvalinfo.min == leftvalinfo.max && rightvalinfo.min == rightvalinfo.max)
854 bool one = (leftvalinfo.min == rightvalinfo.min) ^ (ic->op == NE_OP);
855 resultvalinfo.min = one;
856 resultvalinfo.max = one;
859 else if (ic->op == '+')
860 valinfoPlus (&resultvalinfo, operandType (ic->result), leftvalinfo, rightvalinfo);
861 else if (ic->op == '-')
862 valinfoMinus (&resultvalinfo, operandType (ic->result), leftvalinfo, rightvalinfo);
863 else if (ic->op == '*')
864 valinfoMult (&resultvalinfo, leftvalinfo, rightvalinfo);
865 else if (ic->op == '/')
866 valinfoDiv (&resultvalinfo, leftvalinfo, rightvalinfo);
867 else if (ic->op == '%')
868 valinfoMod (&resultvalinfo, leftvalinfo, rightvalinfo);
869 else if (ic->op == '|')
870 valinfoOr (&resultvalinfo, leftvalinfo, rightvalinfo);
871 else if (ic->op == BITWISEAND)
872 valinfoAnd (&resultvalinfo, operandType (ic->result), leftvalinfo, rightvalinfo);
873 else if (ic->op == '^')
874 valinfoXor (&resultvalinfo, leftvalinfo, rightvalinfo);
875 else if (ic->op == GETABIT)
876 valinfoGetABit (&resultvalinfo, leftvalinfo, rightvalinfo);
877 else if (ic->op == LEFT_OP)
878 valinfoLeft (&resultvalinfo, leftvalinfo, rightvalinfo);
879 else if (ic->op == RIGHT_OP)
880 valinfoRight (&resultvalinfo, leftvalinfo, rightvalinfo);
881 else if (ic->op == '=' && !POINTER_SET (ic) || ic->op == CAST)
882 //resultvalinfo = rightvalinfo; // Doesn't work for = - sometimes = with mismatched types arrive here.
883 valinfoCast (&resultvalinfo, operandType (IC_RESULT (ic)), rightvalinfo);
885 if (resultsym)
887 valinfoUpdate (&resultvalinfo);
888 #ifdef DEBUG_GCP_ANALYSIS
889 std::cout << "resultvalinfo anything " << resultvalinfo.anything << " knownbitsmask 0x" << std::hex << resultvalinfo.knownbitsmask << " knownbits 0x" << resultvalinfo.knownbits << std::dec << " min " << resultvalinfo.min << " max " << resultvalinfo.max << "\n";
890 #endif
891 if (!ic->resultvalinfo)
892 ic->resultvalinfo = new struct valinfo;
893 *ic->resultvalinfo = resultvalinfo;
894 G[*out].map[ic->result->key] = resultvalinfo;
896 if (todo.second.find (boost::target(*out, G)) == todo.second.end())
898 todo.first.push (boost::target(*out, G));
899 todo.second.insert (boost::target(*out, G));
904 // Calculate valinfos for all iCodes in function.
905 void
906 recomputeValinfos (iCode *sic, ebbIndex *ebbi, const char *suffix)
908 #ifdef DEBUG_GCP_ANALYSIS
909 std::cout << "recomputeValinfos at " << (currFunc ? currFunc->name : "[NOFUNC]") << "\n"; std::cout.flush();
910 #endif
912 unsigned long max_rounds = 18000; // Rapidly end analysis once this number of rounds has been exceeded.
914 cfg_t G;
916 create_cfg_genconstprop(G, sic, ebbi);
918 std::pair <std::queue<unsigned int>, std::set<unsigned int> > todo; // Nodes where valinfos need to be updated. We need a pair of a queue and a set to implement a queue with uniqe entries. A plain set wouldn't work, as we'd be working on some nodes all the time while never getting to others before we reach the round limit.
920 // Process each node at least once.
921 for (unsigned int i = 0; i < boost::num_vertices (G); i++)
923 delete G[i].ic->valinfos;
924 G[i].ic->valinfos = NULL;
925 delete G[i].ic->resultvalinfo;
926 G[i].ic->resultvalinfo = NULL;
927 recompute_node (G, i, ebbi, todo, true, 0);
930 // Forward pass to get first approximation.
931 for (unsigned long round = 0; !todo.first.empty (); round++)
933 // Take next node that needs updating.
934 unsigned int i = todo.first.front ();
935 todo.first.pop ();
936 todo.second.erase (i);
938 #ifdef DEBUG_GCP_ANALYSIS
939 std::cout << "Round " << round << " node " << i << " ic " << G[i].ic->key << "\n"; std::cout.flush();
940 #endif
942 recompute_node (G, i, ebbi, todo, false, (round >= max_rounds) + (round >= max_rounds * 2));
945 // Refinement backward pass.
946 // TODO
948 if(options.dump_graphs)
949 dump_cfg_genconstprop(G, suffix);
952 // Try to replace operands by constants
953 static void
954 optimizeValinfoConst (iCode *sic)
956 #ifdef DEBUG_GCP_OPT
957 std::cout << "optimizeValinfoConst at " << (currFunc ? currFunc->name : "[NOFUNC]") << "\n"; std::cout.flush();
958 #endif
959 for (iCode *ic = sic; ic; ic = ic->next)
961 if (SKIP_IC2 (ic))
963 else
965 operand *left = IC_LEFT (ic);
966 operand *right = IC_RIGHT (ic);
967 operand *result = IC_RESULT (ic);
968 const valinfo vleft = getOperandValinfo (ic, left);
969 const valinfo vright = getOperandValinfo (ic, right);
970 if (ic->resultvalinfo && !ic->resultvalinfo->anything && ic->resultvalinfo->min == ic->resultvalinfo->max &&
971 !(ic->op == '=' && IS_OP_LITERAL (right)) && !POINTER_SET (ic))
973 const valinfo &vresult = *ic->resultvalinfo;
974 #ifdef DEBUG_GCP_OPT
975 std::cout << "Replace result at " << ic->key << ". anything " << vresult.anything << " min " << vresult.min << " max " << vresult.max << "\n";
976 #endif
977 detachiCodeOperand (&ic->left, ic);
978 detachiCodeOperand (&ic->right, ic);
979 ic->op = '=';
980 ic->right = operandFromValue (valCastLiteral (operandType (result), vresult.min, vresult.min), false);
982 else
984 if (left && IS_ITEMP (left) && !vleft.anything && vleft.min == vleft.max)
986 #ifdef DEBUG_GCP_OPT
987 std::cout << "Replace left (" << OP_SYMBOL(left)->name << "), key " << left->key << " at " << ic->key << "\n";std::cout << "anything " << vleft.anything << " min " << vleft.min << " max " << vleft.max << "\n";
988 #endif
989 attachiCodeOperand (operandFromValue (valCastLiteral (operandType (left), vleft.min, vleft.min), false), &ic->left, ic);
991 if (right && IS_ITEMP (right) && !vright.anything && vright.min == vright.max)
993 #ifdef DEBUG_GCP_OPT
994 std::cout << "Replace right at " << ic->key << "\n";std::cout << "anything " << vleft.anything << " min " << vleft.min << " max " << vleft.max << "\n";
995 #endif
996 attachiCodeOperand (operandFromValue (valCastLiteral (operandType (right), vright.min, vright.min), false), &ic->right, ic);
1004 static void
1005 reTypeOp (operand *op, sym_link *newtype)
1007 #if 0
1008 std::cout << "reType Op to "; std::cout.flush(); printTypeChain (newtype, 0);
1009 #endif
1010 if (IS_OP_LITERAL (op))
1012 op->svt.valOperand = valCastLiteral (newtype, operandLitValue (op), operandLitValueUll (op));
1013 return;
1016 // Replace at uses.
1017 bitVect *uses = bitVectCopy (OP_USES (op));
1018 for (int key = bitVectFirstBit (uses); bitVectnBitsOn (uses); bitVectUnSetBit (uses, key), key = bitVectFirstBit (uses))
1020 iCode *uic = (iCode *)hTabItemWithKey (iCodehTab, key);
1021 wassert (uic);
1022 if (isOperandEqual (op, uic->left))
1023 setOperandType (uic->left, newtype);
1024 if (isOperandEqual (op, uic->right))
1025 setOperandType (uic->right, newtype);
1026 if (POINTER_SET (uic) && isOperandEqual (op, uic->result))
1027 setOperandType (uic->result, newtype);
1029 freeBitVect (uses);
1031 // Replace at definitions.
1032 bitVect *defs = bitVectCopy (OP_DEFS (op));
1033 for (int key = bitVectFirstBit (defs); bitVectnBitsOn (defs); bitVectUnSetBit (defs, key), key = bitVectFirstBit (defs))
1035 iCode *dic = (iCode *)hTabItemWithKey (iCodehTab, key);
1036 wassert (dic && dic->result && isOperandEqual (op, dic->result));
1037 setOperandType (dic->result, newtype);
1038 if (dic->op == '=' && IS_OP_LITERAL (dic->right))
1039 reTypeOp (dic->right, newtype);
1040 else if (dic->op == CAST || dic->op == '=')
1042 dic->op = CAST;
1043 dic->left = operandFromLink (newtype);
1046 freeBitVect (defs);
1049 // todo: Remove this, use stdc_bit_width instead once we can assume C2X support on host compiler
1050 #ifndef ULLONG_WIDTH // Also a C2X feature
1051 #define ULLONG_WIDTH (CHAR_BIT * sizeof (unsigned long long))
1052 #endif
1053 unsigned int my_stdc_bit_width (unsigned long long value)
1055 unsigned int width = 0;
1056 for (int i = 0; i < ULLONG_WIDTH; i++)
1057 if (value & (1ull << i))
1058 width = (i + 1);
1059 return width;
1062 static void
1063 optimizeNarrowOpNet (iCode *ic)
1065 if (!ic || POINTER_SET(ic) || !ic->result || !ic->resultvalinfo || !IS_ITEMP (ic->result))
1066 return;
1068 std::set <operand *> net, checknet;
1069 net.insert (ic->result);
1070 checknet.insert (ic->result);
1072 struct valinfo v = *(ic->resultvalinfo);
1073 unsigned int ptropwidth = 0; // Width of pointers that an integer net is added to (only bits within address space count, not tag bits).
1075 #if 0
1076 std::cout << "optimizeNarrowOpNet at ic " << ic->key << ": " << OP_SYMBOL (ic->result)->name << "\n"; std::cout.flush();
1077 #endif
1079 while (!checknet.empty())
1081 operand *op = *checknet.begin();
1082 checknet.erase (op);
1084 if (!IS_INTEGRAL (operandType (ic->result)) && !IS_GENPTR (operandType (ic->result)))
1085 return;
1086 if (IS_OP_LITERAL (op))
1087 continue;
1088 if (!IS_ITEMP (op))
1089 return;
1091 bitVect *defs = bitVectCopy (OP_DEFS (op));
1092 for (int key = bitVectFirstBit (defs); bitVectnBitsOn (defs); bitVectUnSetBit (defs, key), key = bitVectFirstBit (defs))
1094 iCode *dic = (iCode *)hTabItemWithKey (iCodehTab, key);
1095 if (!dic || !dic->resultvalinfo) // Looks like some earlier optimization left bad data. Abort.
1096 return;
1097 if (dic->op == CAST || dic->op == '=' && !POINTER_SET (dic)) // Def ok: we could just change to suitable cast.
1099 else if (dic->op == ADDRESS_OF)
1101 else if (dic->op == '+' || dic->op == '-' || dic->op == '^' || dic->op == '|' || dic->op == BITWISEAND)
1103 wassert (isOperandEqual (dic->result, op));
1104 if (net.find(dic->left) == net.end() && IS_PTR (operandType (ic->result)) == IS_PTR (operandType (dic->left)))
1106 net.insert (dic->left);
1107 checknet.insert (dic->left);
1109 if (net.find(dic->right) == net.end() && IS_PTR (operandType (ic->result)) == IS_PTR (operandType (dic->right)))
1111 net.insert (dic->right);
1112 checknet.insert (dic->right);
1115 else
1116 return;
1117 valinfo_union (&v, *dic->resultvalinfo);
1119 freeBitVect (defs);
1121 bitVect *uses = bitVectCopy (OP_USES (op));
1122 if (!bitVectnBitsOn (uses)) // An iTemp without uses! stay away for now!
1123 return;
1124 for (int key = bitVectFirstBit (uses); bitVectnBitsOn (uses); bitVectUnSetBit (uses, key), key = bitVectFirstBit (uses))
1126 iCode *uic = (iCode *)hTabItemWithKey (iCodehTab, key);
1127 if (!uic)
1128 bitVectUnSetBit (OP_USES (op), key); // Looks like some earlier optimization didn't clean up properly. Do it now.
1129 else if (uic->op == CAST && !IS_FLOAT (operandType (uic->result)))
1130 valinfo_union (&v, getOperandValinfo (uic, uic->right));
1131 else if (uic->op == EQ_OP || uic->op == NE_OP || uic->op == '<' || uic->op == LE_OP || uic->op == '>' || uic->op == GE_OP)
1133 if (isOperandEqual (uic->left, op) && !isOperandEqual (uic->right, op))
1135 valinfo_union (&v, getOperandValinfo (uic, uic->right));
1136 if (net.find(uic->right) == net.end())
1138 net.insert (uic->right);
1139 checknet.insert (uic->right);
1142 if (!isOperandEqual (uic->left, op) && isOperandEqual (uic->right, op))
1144 valinfo_union (&v, getOperandValinfo (uic, uic->left));
1145 if (net.find(uic->left) == net.end())
1147 net.insert (uic->left);
1148 checknet.insert (uic->left);
1152 else if (uic->op == '+' || uic->op == '-' || uic->op == '^' || uic->op == '|' || uic->op == BITWISEAND)
1154 if (!IS_PTR (operandType (op)) && IS_PTR (operandType (uic->result)) && v.min < 0) // Avoid breaking the addition of signed offsets to pointers (bug #3807).
1156 unsigned int pwidth = bitsForType (operandType (uic->result));
1157 // mcs51 has 24 bit pointers, but at most 16 bits in each individual address space.
1158 if (TARGET_IS_MCS51 && pwidth > 16)
1159 pwidth = 16;
1160 if (TARGET_IS_DS390 && pwidth > 24)
1161 pwidth = 24;
1162 // The pdk ports are actually named for the maximum number of address bits in their biggest address space.
1163 else if (TARGET_IS_PDK13 && pwidth > 13)
1164 pwidth = 13;
1165 else if (TARGET_IS_PDK14 && pwidth > 14)
1166 pwidth = 14;
1167 else if (TARGET_IS_PDK15 && pwidth > 15)
1168 pwidth = 15;
1169 else if (TARGET_IS_PDK16 && pwidth > 16)
1170 pwidth = 16;
1171 if (pwidth > ptropwidth)
1172 ptropwidth = pwidth;
1174 if (isOperandEqual (uic->left, op) && !IS_PTR (operandType (uic->result)))
1176 if (net.find(uic->right) == net.end())
1178 net.insert (uic->right);
1179 checknet.insert (uic->right);
1182 if (isOperandEqual (uic->right, op) && !IS_PTR (operandType (uic->result)) )
1184 if (net.find(uic->left) == net.end())
1186 net.insert (uic->left);
1187 checknet.insert (uic->left);
1190 if (IS_PTR (operandType (ic->result)) == IS_PTR (operandType (uic->result)))
1192 if(net.find(uic->result) == net.end())
1194 net.insert (uic->result);
1195 checknet.insert (uic->result);
1199 else if ((uic->op == LEFT_OP || uic->op == RIGHT_OP || uic->op == ROT) && !isOperandEqual (uic->left, op))
1201 else if ((uic->op == LEFT_OP || uic->op == RIGHT_OP || uic->op == UNARYMINUS || uic->op == '~') && isOperandEqual (uic->left, op)) // Not ROT, since the size affects semantics.
1203 if (net.find(uic->result) == net.end())
1205 net.insert (uic->result);
1206 checknet.insert (uic->result);
1209 else if (uic->op == '!' || uic->op == IFX)
1211 else if (uic->op == GET_VALUE_AT_ADDRESS && !isOperandEqual (IS_INTEGRAL (operandType (op)) ? uic->left : uic->right, op))
1213 else if (POINTER_SET (uic) && isOperandEqual (uic->result, op))
1215 else
1216 return;
1218 freeBitVect (uses);
1221 if (v.anything)
1222 return;
1224 sym_link *newtype;
1225 if (IS_INTEGRAL (operandType (ic->result)) && v.min >= 0) // Try to use an unsigned type first - they tend to be more efficient.
1227 unsigned int width = my_stdc_bit_width (v.max);
1228 width = ((width + 7) & (-8)); // Round up to multiple of 8.
1229 if (width < 8) // If analysis showed that this is a constant 0, make it 8 bits, still, instead of 0.
1230 width = 8;
1231 if (width >= bitsForType (operandType (ic->result)))
1232 return;
1233 if (width > port->s.bitint_maxwidth)
1234 return;
1235 #if 0
1236 std::cout << "Found optimizeable unoptimized unsigned integer net! New width: " << width << "\n";
1237 #endif
1238 newtype = newBitIntLink (width);
1239 SPEC_USIGN (newtype) = true;
1241 else if (IS_INTEGRAL (operandType (ic->result)) && v.min < 0)
1243 unsigned int width = my_stdc_bit_width (v.max);
1244 if (my_stdc_bit_width (-v.min) > width)
1245 width = my_stdc_bit_width (-v.min);
1246 width++; // Add one for the "sign bit".
1247 if (ptropwidth > width)
1248 width = ptropwidth;
1249 width = ((width + 7) & (-8)); // Round up to multiple of 8.
1250 if (width >= bitsForType (operandType (ic->result)))
1251 return;
1252 if (width > port->s.bitint_maxwidth)
1253 return;
1254 #if 0
1255 std::cout << "Found optimizeable unoptimized signed integer net! New width: " << width << "\n";
1256 #endif
1257 newtype = newBitIntLink (width);
1258 SPEC_USIGN (newtype) = false;
1260 else if (IS_GENPTR (operandType (ic->result)) && v.min >= 0 && (TARGET_IS_MCS51 || TARGET_PDK_LIKE))
1262 if (TARGET_IS_MCS51 && (v.knownbitsmask & 0xff0000) != 0xff0000) // Check if we fully know the GPByte, and thus the intrinsic named address space this pointer points to.
1263 return;
1264 if (TARGET_PDK_LIKE && !(v.knownbitsmask & 0x8000)) // Check if we know the topmost bit, and thus the intrinsic named address space this pointer points to.
1265 return;
1267 newtype = copyLinkChain (operandType (ic->result));
1269 if (TARGET_IS_MCS51)
1271 int gpbyte = (v.knownbits & 0xff0000) >> 16;
1272 if (gpbyte == GPTYPE_NEAR)
1273 DCL_TYPE (newtype) = IPOINTER;
1274 else if (gpbyte == GPTYPE_XSTACK)
1275 DCL_TYPE (newtype) = PPOINTER;
1276 else if (gpbyte == GPTYPE_FAR)
1277 DCL_TYPE (newtype) = FPOINTER;
1278 else if (gpbyte == GPTYPE_CODE)
1279 DCL_TYPE (newtype) = CPOINTER;
1280 else
1282 std::cerr << "Odd gpbyte " << std::hex << gpbyte << "\n";
1283 wassert (0);
1286 else if (TARGET_PDK_LIKE)
1288 if (v.knownbits & 0x8000)
1289 DCL_TYPE (newtype) = CPOINTER;
1290 else
1291 DCL_TYPE (newtype) = POINTER;
1293 else
1294 wassert (0);
1295 #if 0
1296 std::cout << "Found optimizeable unoptimized pointer net!\n";
1297 #endif
1299 else
1300 return;
1302 for(std::set<operand *>::iterator i = net.begin(); i != net.end(); ++i)
1303 reTypeOp (*i, newtype);
1306 static void
1307 optimizeMult (iCode *ic)
1309 operand *left = IC_LEFT (ic);
1310 operand *right = IC_RIGHT (ic);
1311 operand *result = IC_RESULT (ic);
1313 sym_link *oldoptype = operandType (left);
1314 sym_link *oldresulttype = operandType (result);
1316 struct valinfo leftv = getOperandValinfo (ic, left);
1317 struct valinfo rightv = getOperandValinfo (ic, right);
1318 struct valinfo resultv = *ic->resultvalinfo;
1320 if (leftv.anything || rightv.anything || resultv.anything || leftv.min < 0 || rightv.min < 0 || leftv.max > 0xffff || rightv.max > 0xffff || resultv.max > 0xffff)
1321 return;
1323 if (!IS_INTEGRAL (oldresulttype) || bitsForType (oldoptype) <= 8 || bitsForType (oldresulttype) <= 8)
1324 return;
1326 if (bitsForType (oldresulttype) <= 16 && (leftv.max > 0xff || rightv.max > 0xff))
1327 return;
1329 if (ic->op == '*' && bitsForType (oldresulttype) <= 16)
1330 return;
1332 sym_link *newoptype;
1333 sym_link *newresulttype;
1334 if (leftv.max <= 0xff && rightv.max <= 0xff) // Use unsigned char, as that allows 8x8->16 multiplication.
1336 newoptype = newCharLink ();
1337 SPEC_USIGN (newoptype) = true;
1338 newresulttype = (resultv.max <= 0xff) ? newCharLink () : newIntLink ();
1339 SPEC_USIGN (newresulttype) = true;
1341 else
1343 newoptype = newBitIntLink (16);
1344 SPEC_USIGN (newoptype) = true;
1345 newresulttype = newBitIntLink (16);
1346 SPEC_USIGN (newresulttype) = true;
1349 prependCast (ic, left, newoptype, 0);
1350 prependCast (ic, right, newoptype, 0);
1351 appendCast (ic, newresulttype, 0);
1354 // Try to narrow operations
1355 static void
1356 optimizeValinfoNarrow (iCode *sic)
1358 #ifdef DEBUG_GCP_OPT
1359 std::cout << "optimizeValinfoNarrow at " << (currFunc ? currFunc->name : "[NOFUNC]") << "\n";
1360 #endif
1362 for (iCode *ic = sic; ic; ic = ic->next)
1363 optimizeNarrowOpNet (ic);
1365 for (iCode *ic = sic; ic; ic = ic->next)
1366 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
1367 optimizeMult (ic);
1370 // Do machine-independent optimizations based on valinfos.
1371 void
1372 optimizeValinfo (iCode *sic)
1374 optimizeValinfoConst (sic);
1375 optimizeValinfoNarrow (sic);