Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / src / SDCCopt.c
blob81b20797319a34871bd084151a9453bf4816651b
1 /*-------------------------------------------------------------------------
2 SDCCopt.c - calls all the optimizations routines and does some of the
3 hackier transformations, these include translating iCodes
4 to function calls and replacing local variables with their
5 register equivalents etc. Also contains the driver routine
6 for dead code elimination
8 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
10 This program is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 In other words, you are welcome to use, share and improve this program.
25 You are forbidden to forbid anyone else to use, share and improve
26 what you give them. Help stamp out software-hoarding!
27 -------------------------------------------------------------------------*/
29 #include <math.h>
30 #include "common.h"
31 #include "dbuf_string.h"
33 /*-----------------------------------------------------------------*/
34 /* global variables */
35 int cseDefNum = 0;
37 char flowChanged = 0;
40 /*-----------------------------------------------------------------*/
41 /* printSymName - prints the symbol names */
42 /*-----------------------------------------------------------------*/
43 int
44 printSymName (void *vsym)
46 symbol *sym = vsym;
47 fprintf (stdout, " %s ", sym->name);
48 return 0;
51 /*-----------------------------------------------------------------*/
52 /* cnvToFcall - does the actual conversion to function call */
53 /*-----------------------------------------------------------------*/
54 static void
55 cnvToFcall (iCode * ic, eBBlock * ebp)
57 iCode *ip;
58 iCode *newic;
59 operand *left;
60 operand *right;
61 symbol *func = NULL;
62 char *filename = ic->filename;
63 int lineno = ic->lineno;
64 int bytesPushed=0;
66 ip = ic->next; /* insertion point */
67 /* remove it from the iCode */
68 unsetDefsAndUses (ic);
69 remiCodeFromeBBlock (ebp, ic);
71 left = IC_LEFT (ic);
72 right = IC_RIGHT (ic);
74 if (IS_FLOAT (operandType (right)))
76 switch (ic->op)
78 case '+':
79 func = fsadd;
80 break;
81 case '-':
82 func = fssub;
83 break;
84 case '/':
85 func = fsdiv;
86 break;
87 case '*':
88 func = fsmul;
89 break;
90 case EQ_OP:
91 func = fseq;
92 break;
93 case NE_OP:
94 func = fsneq;
95 break;
96 case '<':
97 func = fslt;
98 break;
99 case '>':
101 operand *tmp = right;
102 right = left;
103 left = tmp;
104 func = fslt;
105 break;
109 else if (IS_FIXED16X16 (operandType (right)))
111 switch (ic->op)
113 case '+':
114 func = fps16x16_add;
115 break;
116 case '-':
117 func = fps16x16_sub;
118 break;
119 case '/':
120 func = fps16x16_div;
121 break;
122 case '*':
123 func = fps16x16_mul;
124 break;
125 case EQ_OP:
126 func = fps16x16_eq;
127 break;
128 case NE_OP:
129 func = fps16x16_neq;
130 break;
131 case '<':
132 func = fps16x16_lt;
133 break;
134 case '>':
135 func = fps16x16_gt;
136 break;
137 case LE_OP:
138 func = fps16x16_lteq;
139 break;
140 case GE_OP:
141 func = fps16x16_gteq;
142 break;
146 /* if float support routines NOT compiled as reentrant */
147 if (!options.float_rent)
149 /* first one */
150 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
152 newic = newiCode (SEND, left, NULL);
153 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
155 else
157 newic = newiCode ('=', NULL, left);
158 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
161 hTabAddItem (&iCodehTab, newic->key, newic);
162 addiCodeToeBBlock (ebp, newic, ip);
163 newic->filename = filename;
164 newic->lineno = lineno;
165 if (IS_SYMOP (left))
166 OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
168 /* second one */
169 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
171 newic = newiCode (SEND, right, NULL);
172 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
174 else
176 newic = newiCode ('=', NULL, right);
177 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next, false);
179 hTabAddItem (&iCodehTab, newic->key, newic);
180 addiCodeToeBBlock (ebp, newic, ip);
181 newic->filename = filename;
182 newic->lineno = lineno;
183 if (IS_SYMOP (right))
184 OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
186 else
188 /* push right */
189 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
191 newic = newiCode (SEND, right, NULL);
192 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
194 else
196 newic = newiCode (IPUSH, right, NULL);
197 newic->parmPush = 1;
198 bytesPushed += getSize(operandType(right)) + (getSize(operandType(right)) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
201 hTabAddItem (&iCodehTab, newic->key, newic);
202 addiCodeToeBBlock (ebp, newic, ip);
203 newic->filename = filename;
204 newic->lineno = lineno;
205 if (IS_SYMOP (right))
206 OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
208 /* insert push left */
209 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
211 newic = newiCode (SEND, left, NULL);
212 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
214 else
216 newic = newiCode (IPUSH, left, NULL);
217 newic->parmPush = 1;
218 bytesPushed += getSize(operandType(left)) + (getSize(operandType(left)) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
220 hTabAddItem (&iCodehTab, newic->key, newic);
221 addiCodeToeBBlock (ebp, newic, ip);
222 newic->filename = filename;
223 newic->lineno = lineno;
224 if (IS_SYMOP (left))
225 OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
227 /* insert the call */
228 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
229 IC_RESULT (newic) = IC_RESULT (ic);
230 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
231 OP_DEFS (IC_RESULT (newic)) = bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
232 newic->filename = filename;
233 newic->lineno = lineno;
234 newic->parmBytes += bytesPushed;
235 ebp->hasFcall = 1;
236 if (currFunc)
237 FUNC_HASFCALL (currFunc->type) = 1;
239 if (TARGET_PIC_LIKE)
241 /* normally these functions aren't marked external, so we can use their
242 * _extern field to mark as already added to symbol table */
244 if (!SPEC_EXTR(func->etype))
246 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
248 SPEC_EXTR(func->etype) = 1;
249 seg = SPEC_OCLS( func->etype );
250 addSet(&seg->syms, func);
254 hTabAddItem (&iCodehTab, newic->key, newic);
255 addiCodeToeBBlock (ebp, newic, ip);
258 /*-----------------------------------------------------------------*/
259 /* cnvToFloatCast - converts casts to floats to function calls */
260 /*-----------------------------------------------------------------*/
261 static void
262 cnvToFloatCast (iCode * ic, eBBlock * ebp)
264 iCode *ip, *newic;
265 symbol *func = NULL;
266 sym_link *type = copyLinkChain (operandType (IC_RIGHT (ic)));
267 SPEC_SHORT (type) = 0;
268 int linenno = ic->lineno;
269 int bwd, su;
270 int bytesPushed=0;
272 ip = ic->next;
273 /* remove it from the iCode */
274 unsetDefsAndUses (ic);
275 remiCodeFromeBBlock (ebp, ic);
277 /* depending on the type */
278 for (bwd = 0; bwd < 4; bwd++)
280 for (su = 0; su < 2; su++)
282 if (compareType (type, multypes[bwd][su], false) == 1)
284 func = conv[0][bwd][su];
285 goto found;
290 if (compareType (type, fixed16x16Type, false) == 1)
292 func = fp16x16conv[0][4][0];
293 goto found;
296 if (IS_BOOLEAN (type))
298 wassert(multypes[0][1] == UCHARTYPE);
299 func = conv[0][0][1];
300 goto found;
303 assert (0);
304 found:
306 /* if float support routines NOT compiled as reentrant */
307 if (!options.float_rent)
309 /* first one */
310 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
312 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
313 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
315 else
317 newic = newiCode ('=', NULL, IC_RIGHT (ic));
318 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
320 hTabAddItem (&iCodehTab, newic->key, newic);
321 addiCodeToeBBlock (ebp, newic, ip);
322 newic->filename = filename;
323 newic->lineno = linenno;
324 if (IS_SYMOP (IC_RIGHT (ic)))
325 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
327 else
329 /* push the left */
330 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
332 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
333 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
335 else
337 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
338 newic->parmPush = 1;
339 bytesPushed += getSize(operandType(IC_RIGHT(ic))) + (getSize(operandType(IC_RIGHT(ic))) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
341 hTabAddItem (&iCodehTab, newic->key, newic);
342 addiCodeToeBBlock (ebp, newic, ip);
343 newic->filename = filename;
344 newic->lineno = linenno;
345 if (IS_SYMOP (IC_RIGHT (ic)))
346 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
349 /* make the call */
350 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
351 IC_RESULT (newic) = IC_RESULT (ic);
352 newic->parmBytes+=bytesPushed;
353 ebp->hasFcall = 1;
354 if (currFunc)
355 FUNC_HASFCALL (currFunc->type) = 1;
357 if (TARGET_PIC_LIKE)
359 /* normally these functions aren't marked external, so we can use their
360 * _extern field to marked as already added to symbol table */
362 if (!SPEC_EXTR(func->etype))
364 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
366 SPEC_EXTR(func->etype) = 1;
367 seg = SPEC_OCLS( func->etype );
368 addSet(&seg->syms, func);
372 hTabAddItem (&iCodehTab, newic->key, newic);
373 addiCodeToeBBlock (ebp, newic, ip);
374 newic->filename = filename;
375 newic->lineno = linenno;
376 if (IS_SYMOP (IC_RESULT (ic)))
377 OP_DEFS (IC_RESULT (ic)) = bitVectSetBit (OP_DEFS (IC_RESULT (ic)), newic->key);
380 /*----------------------------------------------------------------------*/
381 /* cnvToFixed16x16Cast - converts casts to fixed16x16 to function calls */
382 /*----------------------------------------------------------------------*/
383 static void
384 cnvToFixed16x16Cast (iCode * ic, eBBlock * ebp)
386 iCode *ip, *newic;
387 symbol *func = NULL;
388 sym_link *type = copyLinkChain (operandType (IC_RIGHT (ic)));
389 SPEC_SHORT (type) = 0;
390 int linenno = ic->lineno;
391 int bwd, su;
392 int bytesPushed=0;
394 ip = ic->next;
395 /* remove it from the iCode */
396 unsetDefsAndUses (ic);
397 remiCodeFromeBBlock (ebp, ic);
399 /* depending on the type */
400 for (bwd = 0; bwd < 4; bwd++)
402 for (su = 0; su < 2; su++)
404 if (compareType (type, multypes[bwd][su], false) == 1)
406 func = fp16x16conv[0][bwd][su];
407 goto found;
411 assert (0);
412 found:
414 /* if float support routines NOT compiled as reentrant */
415 if (!options.float_rent)
417 /* first one */
418 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
420 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
421 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
423 else
425 newic = newiCode ('=', NULL, IC_RIGHT (ic));
426 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
428 hTabAddItem (&iCodehTab, newic->key, newic);
429 addiCodeToeBBlock (ebp, newic, ip);
430 newic->filename = filename;
431 newic->lineno = linenno;
432 if (IS_SYMOP (IC_RIGHT (ic)))
433 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
435 else
437 /* push the left */
438 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
440 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
441 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
443 else
445 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
446 newic->parmPush = 1;
447 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
449 hTabAddItem (&iCodehTab, newic->key, newic);
450 addiCodeToeBBlock (ebp, newic, ip);
451 newic->filename = filename;
452 newic->lineno = linenno;
453 if (IS_SYMOP (IC_RIGHT (ic)))
454 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
457 /* make the call */
458 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
459 IC_RESULT (newic) = IC_RESULT (ic);
460 newic->parmBytes+=bytesPushed;
461 ebp->hasFcall = 1;
462 if (currFunc)
463 FUNC_HASFCALL (currFunc->type) = 1;
465 if (TARGET_PIC_LIKE)
467 /* normally these functions aren't marked external, so we can use their
468 * _extern field to marked as already added to symbol table */
470 if (!SPEC_EXTR(func->etype))
472 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
474 SPEC_EXTR(func->etype) = 1;
475 seg = SPEC_OCLS( func->etype );
476 addSet(&seg->syms, func);
480 hTabAddItem (&iCodehTab, newic->key, newic);
481 addiCodeToeBBlock (ebp, newic, ip);
482 newic->filename = filename;
483 newic->lineno = linenno;
484 if (IS_SYMOP (IC_RESULT (ic)))
485 OP_DEFS (IC_RESULT (ic)) = bitVectSetBit (OP_DEFS (IC_RESULT (ic)), newic->key);
488 /*-----------------------------------------------------------------*/
489 /* cnvFromFloatCast - converts casts From floats to function calls */
490 /*-----------------------------------------------------------------*/
491 static void
492 cnvFromFloatCast (iCode * ic, eBBlock * ebp)
494 iCode *ip, *newic;
495 symbol *func = NULL;
496 sym_link *type = copyLinkChain (operandType (IC_LEFT (ic)));
497 SPEC_SHORT (type) = 0;
498 char *filename = ic->filename;
499 int lineno = ic->lineno;
500 int bwd, su;
501 int bytesPushed=0;
503 ip = ic->next;
504 /* remove it from the iCode */
505 unsetDefsAndUses (ic);
506 remiCodeFromeBBlock (ebp, ic);
508 /* depending on the type */
509 for (bwd = 0; bwd < 4; bwd++)
511 for (su = 0; su < 2; su++)
513 if (compareType (type, multypes[bwd][su], false) == 1)
515 func = conv[1][bwd][su];
516 goto found;
520 assert (0);
521 found:
523 /* if float support routines NOT compiled as reentrant */
524 if (!options.float_rent)
526 /* first one */
527 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
529 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
530 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
532 else
534 newic = newiCode ('=', NULL, IC_RIGHT (ic));
535 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
537 hTabAddItem (&iCodehTab, newic->key, newic);
538 addiCodeToeBBlock (ebp, newic, ip);
539 newic->filename = filename;
540 newic->lineno = lineno;
541 if (IS_SYMOP (IC_RIGHT (ic)))
542 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
544 else
546 /* push the left */
547 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
549 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
550 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
552 else
554 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
555 newic->parmPush = 1;
556 bytesPushed += getSize(operandType(IC_RIGHT(ic))) + (getSize(operandType(IC_RIGHT(ic))) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
558 hTabAddItem (&iCodehTab, newic->key, newic);
559 addiCodeToeBBlock (ebp, newic, ip);
560 newic->filename = filename;
561 newic->lineno = lineno;
562 if (IS_SYMOP (IC_RIGHT (ic)))
563 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
566 /* make the call */
567 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
568 IC_RESULT (newic) = IC_RESULT (ic);
569 newic->parmBytes+=bytesPushed;
570 ebp->hasFcall = 1;
571 if (currFunc)
572 FUNC_HASFCALL (currFunc->type) = 1;
574 if (TARGET_PIC_LIKE)
576 /* normally these functions aren't marked external, so we can use their
577 * _extern field to marked as already added to symbol table */
579 if (!SPEC_EXTR(func->etype))
581 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
583 SPEC_EXTR(func->etype) = 1;
584 seg = SPEC_OCLS( func->etype );
585 addSet(&seg->syms, func);
589 hTabAddItem (&iCodehTab, newic->key, newic);
590 addiCodeToeBBlock (ebp, newic, ip);
591 newic->filename = filename;
592 newic->lineno = lineno;
593 if (IS_SYMOP (IC_RESULT (ic)))
594 OP_DEFS (IC_RESULT (ic)) = bitVectSetBit (OP_DEFS (IC_RESULT (ic)), newic->key);
597 /*--------------------------------------------------------------------------*/
598 /* cnvFromFixed16x16Cast - converts casts from fixed16x16 to function calls */
599 /*--------------------------------------------------------------------------*/
600 static void
601 cnvFromFixed16x16Cast (iCode * ic, eBBlock * ebp)
603 iCode *ip, *newic;
604 symbol *func = NULL;
605 sym_link *type = copyLinkChain (operandType (IC_LEFT (ic)));
606 SPEC_SHORT (type) = 0;
607 char *filename = ic->filename;
608 int lineno = ic->lineno;
609 int bwd, su;
610 int bytesPushed=0;
612 ip = ic->next;
613 /* remove it from the iCode */
614 unsetDefsAndUses (ic);
615 remiCodeFromeBBlock (ebp, ic);
617 /* depending on the type */
618 for (bwd = 0; bwd < 4; bwd++)
620 for (su = 0; su < 2; su++)
622 if (compareType (type, multypes[bwd][su], false) == 1)
624 func = fp16x16conv[1][bwd][su];
625 goto found;
630 if (compareType (type, floatType, false) == 1)
632 func = fp16x16conv[1][4][0];
633 goto found;
636 assert (0);
637 found:
639 /* if float support routines NOT compiled as reentrant */
640 if (!options.float_rent)
642 /* first one */
643 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
645 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
646 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
648 else
650 newic = newiCode ('=', NULL, IC_RIGHT (ic));
651 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
653 hTabAddItem (&iCodehTab, newic->key, newic);
654 addiCodeToeBBlock (ebp, newic, ip);
655 newic->filename = filename;
656 newic->lineno = lineno;
657 if (IS_SYMOP (IC_RIGHT (ic)))
658 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
660 else
662 /* push the left */
663 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
665 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
666 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
668 else
670 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
671 newic->parmPush = 1;
672 bytesPushed += getSize(operandType(IC_RIGHT(ic)));
674 hTabAddItem (&iCodehTab, newic->key, newic);
675 addiCodeToeBBlock (ebp, newic, ip);
676 newic->filename = filename;
677 newic->lineno = lineno;
678 if (IS_SYMOP (IC_RIGHT (ic)))
679 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
682 /* make the call */
683 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
684 IC_RESULT (newic) = IC_RESULT (ic);
685 newic->parmBytes+=bytesPushed;
686 ebp->hasFcall = 1;
687 if (currFunc)
688 FUNC_HASFCALL (currFunc->type) = 1;
690 if (TARGET_PIC_LIKE)
692 /* normally these functions aren't marked external, so we can use their
693 * _extern field to marked as already added to symbol table */
695 if (!SPEC_EXTR(func->etype))
697 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
699 SPEC_EXTR(func->etype) = 1;
700 seg = SPEC_OCLS( func->etype );
701 addSet(&seg->syms, func);
705 hTabAddItem (&iCodehTab, newic->key, newic);
706 addiCodeToeBBlock (ebp, newic, ip);
707 newic->filename = filename;
708 newic->lineno = lineno;
709 if (IS_SYMOP (IC_RESULT (ic)))
710 OP_DEFS (IC_RESULT (ic)) = bitVectSetBit (OP_DEFS (IC_RESULT (ic)), newic->key);
713 extern operand *geniCodeRValue (operand *, bool);
715 /* Insert a cast of operand op of ic to type type */
716 void
717 prependCast (iCode *ic, operand *op, sym_link *type, eBBlock *ebb)
719 if (IS_OP_LITERAL (op))
721 operand *newop = operandFromValue (valCastLiteral (type, operandLitValue (op), operandLitValue (op)), false);
722 if (isOperandEqual (op, IC_LEFT (ic)))
723 IC_LEFT (ic) = newop;
724 if (isOperandEqual (op, IC_RIGHT (ic)))
725 IC_RIGHT (ic) = newop;
726 return;
729 iCode *newic = newiCode (CAST, operandFromLink (type), op);
730 hTabAddItem (&iCodehTab, newic->key, newic);
732 IC_RESULT (newic) = newiTempOperand (type, 0);
733 bitVectSetBit (OP_USES (op), newic->key);
734 OP_DEFS (IC_RESULT (newic)) = bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
735 bitVectUnSetBit (OP_USES (op), ic->key);
736 OP_USES (IC_RESULT (newic)) = bitVectSetBit (OP_USES (IC_RESULT (newic)), ic->key);
737 newic->filename = ic->filename;
738 newic->lineno = ic->lineno;
740 addiCodeToeBBlock (ebb, newic, ic);
742 if (isOperandEqual (op, IC_LEFT (ic)))
743 IC_LEFT (ic) = IC_RESULT (newic);
745 if (isOperandEqual (op, IC_RIGHT (ic)))
746 IC_RIGHT (ic) = IC_RESULT (newic);
749 /* Insert a cast of result of ic from type type */
750 void
751 appendCast (iCode *ic, sym_link *type, eBBlock *ebb)
753 iCode *newic = newiCode (CAST, operandFromLink (operandType (IC_RESULT (ic))), 0);
754 hTabAddItem (&iCodehTab, newic->key, newic);
756 IC_RESULT (newic) = IC_RESULT (ic);
757 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
758 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), newic->key);
759 IC_RESULT (ic) = newiTempOperand (type, 0);
760 IC_RIGHT (newic) = operandFromOperand (IC_RESULT (ic));
761 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
762 bitVectSetBit (OP_USES (IC_RESULT (ic)), newic->key);
763 newic->filename = ic->filename;
764 newic->lineno = ic->lineno;
765 addiCodeToeBBlock (ebb, newic, ic->next);
768 /*-----------------------------------------------------------------*/
769 /* convilong - converts int or long mults or divs to fcalls */
770 /*-----------------------------------------------------------------*/
771 static void
772 convilong (iCode *ic, eBBlock *ebp)
774 int op = ic->op;
776 // Use basic type multiplication function for _BitInt
777 if ((op == '*' || op == '/' || op == '%' || op == LEFT_OP || op == RIGHT_OP) &&
778 (IS_BITINT (operandType (IC_LEFT (ic))) || IS_BITINT (operandType (IC_RIGHT (ic)))))
780 // Try 16x16->16
781 if (IS_BITINT (operandType (IC_LEFT (ic))) && SPEC_BITINTWIDTH (operandType (IC_LEFT (ic))) <= 16 &&
782 IS_BITINT (operandType (IC_RIGHT (ic))) && SPEC_BITINTWIDTH (operandType (IC_RIGHT (ic))) <= 16)
784 prependCast (ic, IC_LEFT (ic), newIntLink(), ebp);
785 if (op != LEFT_OP && op != RIGHT_OP)
786 prependCast (ic, IC_RIGHT (ic), newIntLink(), ebp);
787 appendCast (ic, newIntLink(), ebp);
789 // Try 32x32->32
790 else if (IS_BITINT (operandType (IC_LEFT (ic))) && SPEC_BITINTWIDTH (operandType (IC_LEFT (ic))) <= 32 &&
791 IS_BITINT (operandType (IC_RIGHT (ic))) && SPEC_BITINTWIDTH (operandType (IC_RIGHT (ic))) <= 32)
793 prependCast (ic, IC_LEFT (ic), newLongLink(), ebp);
794 if (op != LEFT_OP && op != RIGHT_OP)
795 prependCast (ic, IC_RIGHT (ic), newLongLink(), ebp);
796 appendCast (ic, newLongLink(), ebp);
798 else // Fall back to 64x64->64.
800 prependCast (ic, IC_LEFT (ic), newLongLongLink(), ebp);
801 if (op != LEFT_OP && op != RIGHT_OP)
802 prependCast (ic, IC_RIGHT (ic), newLongLongLink(), ebp);
803 appendCast (ic, newLongLongLink(), ebp);
805 if ((op == '*' || op == '/' || op == '%') && port->hasNativeMulFor && port->hasNativeMulFor (ic, operandType (IC_LEFT (ic)), operandType (IC_RIGHT (ic)))) // Avoid introducing calls to non-existing support functions.
806 return;
809 symbol *func = NULL;
810 iCode *ip = ic->next;
811 iCode *newic;
812 char *filename = ic->filename;
813 int lineno = ic->lineno;
814 int bwd;
815 int su;
816 int bytesPushed=0;
817 operand *left;
818 operand *right;
819 sym_link *leftType = copyLinkChain (operandType (IC_LEFT (ic)));
820 sym_link *rightType = copyLinkChain (operandType (IC_RIGHT (ic)));
821 SPEC_SHORT (leftType) = 0;
822 SPEC_SHORT (rightType) = 0;
824 left = ic->left;
825 right = ic->right;
827 // Special case: 16x16->32 multiplication.
828 if (op == '*' && (muls16tos32[0] || muls16tos32[1] || port->hasNativeMulFor) &&
829 (IS_SYMOP (left) && bitVectnBitsOn (OP_DEFS (left)) == 1 && bitVectnBitsOn (OP_USES (left)) == 1 || IS_OP_LITERAL (left) && operandLitValue (left) < 32768 && operandLitValue (left) >= -32768) &&
830 (IS_SYMOP (right) && bitVectnBitsOn (OP_DEFS (right)) == 1 && bitVectnBitsOn (OP_USES (right)) == 1 || IS_OP_LITERAL (right) && operandLitValue (right) < 32768 && operandLitValue (right) >= -32768) &&
831 getSize (leftType) == 4 && getSize (rightType) == 4)
833 iCode *lic = IS_SYMOP (left) ? hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (left))) : 0;
834 iCode *ric = IS_SYMOP (right) ? hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (right))) : 0;
836 if ((!lic || lic->op == CAST && IS_INTEGRAL (operandType (lic->right)) && getSize (operandType (lic->right)) == 2 && SPEC_USIGN (operandType (lic->right)) == SPEC_USIGN (operandType (left))) &&
837 (!ric || ric->op == CAST && IS_INTEGRAL (operandType (ric->right)) && getSize (operandType (ric->right)) == 2 && SPEC_USIGN (operandType (ric->right)) == SPEC_USIGN (operandType (right))))
839 func = muls16tos32[SPEC_USIGN (operandType (left))];
841 if (func || port->hasNativeMulFor && lic && ric && port->hasNativeMulFor (ic, operandType (lic->right), operandType (ric->right)))
843 if (lic)
845 lic->op = '=';
846 OP_SYMBOL (left)->type = newIntLink ();
848 else
849 ic->left = operandFromValue (valCastLiteral (newIntLink(), operandLitValue (left), operandLitValue (left)), false);
851 if (ric)
853 ric->op = '=';
854 OP_SYMBOL (right)->type = newIntLink ();
856 else
857 ic->right = operandFromValue (valCastLiteral (newIntLink(), operandLitValue (right), operandLitValue (right)), false);
859 if (func) // Use 16x16->32 support function
860 goto found;
861 else // Native
862 return;
866 if (op == '*' && (mulu32u8tou64 || port->hasNativeMulFor) &&
867 (IS_SYMOP (left) && bitVectnBitsOn (OP_DEFS (left)) == 1 && bitVectnBitsOn (OP_USES (left)) == 1 /*|| IS_OP_LITERAL (left) && operandLitValue (left) < 256 && operandLitValue (left) >= 0*/) &&
868 (IS_SYMOP (right) && bitVectnBitsOn (OP_DEFS (right)) == 1 && bitVectnBitsOn (OP_USES (right)) == 1 /*|| IS_OP_LITERAL (right) && operandLitValue (right) < 256 && operandLitValue (right) >= 0*/) &&
869 getSize (leftType) == 8 && getSize (rightType) == 8)
871 iCode *lic = IS_SYMOP (left) ? hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (left))) : 0;
872 iCode *ric = IS_SYMOP (right) ? hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (right))) : 0;
874 if ((lic && lic->op == CAST && IS_INTEGRAL (operandType (lic->right)) && getSize (operandType (lic->right)) <= 4 && SPEC_USIGN (operandType (lic->right))) && // Todo: Allow !lic / !ric for literal operands?
875 (ric && ric->op == CAST && IS_INTEGRAL (operandType (ric->right)) && getSize (operandType (ric->right)) <= 1 && SPEC_USIGN (operandType (ric->right))))
877 func = mulu32u8tou64;
879 if (func || port->hasNativeMulFor && lic && ric && port->hasNativeMulFor (ic, operandType (lic->right), operandType (ric->right)))
881 if (lic)
883 if (getSize (operandType (IC_RIGHT (lic))) == 4)
884 lic->op = '=';
885 OP_SYMBOL (left)->type = newLongLink ();
886 SPEC_USIGN (OP_SYMBOL (left)->type) = 1;
888 else
889 ic->left = operandFromValue (valCastLiteral (newIntLink(), operandLitValue (left), operandLitValue (left)), false);
891 if (ric)
893 ric->op = '=';
894 OP_SYMBOL (right)->type = newCharLink ();
895 SPEC_USIGN (OP_SYMBOL (left)->type) = 1;
897 else
898 ic->right = operandFromValue (valCastLiteral (newIntLink(), operandLitValue (right), operandLitValue (right)), false);
900 if (func) // Use 32x8->64 support function
901 goto found;
902 else // Native
903 return;
908 if (getSize (leftType) == 1 && getSize (rightType) == 1)
910 int muldivmod;
912 if (op == '*')
913 muldivmod = 0;
914 else if (op == '/')
915 muldivmod = 1;
916 else if (op == '%')
917 muldivmod = 2;
918 else
919 muldivmod = -1;
921 for (su = 0; su < 4 && muldivmod >= 0; su++)
923 if ((compareType (leftType, multypes[0][su%2], false) == 1) &&
924 (compareType (rightType, multypes[0][su/2], false) == 1))
926 func = muldiv[muldivmod][0][su];
927 goto found;
932 /* depending on the type */
933 for (bwd = 0; bwd < 4; bwd++)
935 for (su = 0; su < 2; su++)
937 if (compareType (leftType, multypes[bwd][su], false) == 1)
939 if ((op=='*' || op=='/' || op=='%'))
941 int ret = compareType (rightType, multypes[bwd][su], false);
942 if (ret != 1 && isOperandLiteral (right) && SPEC_NOUN (multypes[bwd][su]) == V_CHAR && operandLitValue (right) >= 0 && operandLitValue (right) <= 127)
944 else if (ret != 1)
946 printf ("leftType: "); printTypeChain (leftType, 0);
947 printf ("rightType: "); printTypeChain (rightType, 0);
948 printf ("multypes[bwd][su]: "); printTypeChain (multypes[bwd][su], 0);
949 assert(0);
952 if (op == '*')
953 func = muldiv[0][bwd][su];
954 else if (op == '/')
955 func = muldiv[1][bwd][su];
956 else if (op == '%')
957 func = muldiv[2][bwd][su];
958 else if (op == RIGHT_OP)
960 func = rlrr[1][bwd][su];
961 prependCast (ic, IC_RIGHT (ic), FUNC_ARGS(func->type)->next->type, ebp);
963 else if (op == LEFT_OP)
965 func = rlrr[0][bwd][su];
966 prependCast (ic, IC_RIGHT (ic), FUNC_ARGS(func->type)->next->type, ebp);
968 else
969 assert (0);
970 goto found;
974 werrorfl (filename, lineno, E_INVALID_OP, "mul/div/shift");
975 fprintf (stderr, "ic %d op %d leftType: ", ic->key, op); printTypeChain (leftType, stderr); fprintf (stderr, "\n");
976 return;
977 found:
978 // Update left and right - they might have changed due to inserted casts.
979 left = IC_LEFT (ic);
980 right = IC_RIGHT (ic);
981 unsetDefsAndUses (ic);
982 remiCodeFromeBBlock (ebp, ic);
984 /* if int & long support routines NOT compiled as reentrant */
985 if (!options.intlong_rent)
987 /* first one */
988 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
990 newic = newiCode (SEND, IC_LEFT (ic), NULL);
991 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
993 else
995 newic = newiCode ('=', NULL, IC_LEFT (ic));
996 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type), false);
998 hTabAddItem (&iCodehTab, newic->key, newic);
999 addiCodeToeBBlock (ebp, newic, ip);
1000 newic->filename = filename;
1001 newic->lineno = lineno;
1002 if (IS_SYMOP (left))
1003 OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
1005 /* second one */
1006 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
1008 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
1009 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
1011 else
1013 newic = newiCode ('=', NULL, IC_RIGHT (ic));
1014 IC_RESULT (newic) = operandFromValue (FUNC_ARGS(func->type)->next, false);
1016 hTabAddItem (&iCodehTab, newic->key, newic);
1017 addiCodeToeBBlock (ebp, newic, ip);
1018 newic->filename = filename;
1019 newic->lineno = lineno;
1020 if (IS_SYMOP (right))
1021 OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
1023 else
1025 /* compiled as reentrant then push */
1026 /* push right */
1027 if (IS_REGPARM (FUNC_ARGS(func->type)->next->etype))
1029 newic = newiCode (SEND, IC_RIGHT (ic), NULL);
1030 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->next->etype);
1032 else
1034 newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
1035 newic->parmPush = 1;
1037 bytesPushed += getSize(operandType(IC_RIGHT(ic))) + (getSize(operandType(IC_RIGHT(ic))) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
1039 hTabAddItem (&iCodehTab, newic->key, newic);
1040 addiCodeToeBBlock (ebp, newic, ip);
1041 newic->filename = filename;
1042 newic->lineno = lineno;
1043 if (IS_SYMOP (right))
1044 OP_USES (right) = bitVectSetBit (OP_USES (right), newic->key);
1046 /* insert push left */
1047 if (IS_REGPARM (FUNC_ARGS(func->type)->etype))
1049 newic = newiCode (SEND, IC_LEFT (ic), NULL);
1050 newic->argreg = SPEC_ARGREG(FUNC_ARGS(func->type)->etype);
1052 else
1054 newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
1055 newic->parmPush = 1;
1057 bytesPushed += getSize(operandType(IC_LEFT(ic))) + (getSize(operandType(IC_LEFT(ic))) % 2 && TARGET_PDK_LIKE); // pdk requires stack to be even-aligned
1059 hTabAddItem (&iCodehTab, newic->key, newic);
1060 addiCodeToeBBlock (ebp, newic, ip);
1061 newic->filename = filename;
1062 newic->lineno = lineno;
1063 if (IS_SYMOP (left))
1064 OP_USES (left) = bitVectSetBit (OP_USES (left), newic->key);
1067 /* for the result */
1068 newic = newiCode (CALL, operandFromSymbol (func, false), NULL);
1069 IC_RESULT (newic) = IC_RESULT (ic);
1070 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
1071 OP_DEFS (IC_RESULT (newic)) = bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
1072 newic->filename = filename;
1073 newic->lineno = lineno;
1074 newic->parmBytes+=bytesPushed; // to clear the stack after the call
1075 ebp->hasFcall = 1;
1076 if (currFunc)
1077 FUNC_HASFCALL (currFunc->type) = 1;
1079 if (TARGET_PIC_LIKE)
1081 /* normally these functions aren't marked external, so we can use their
1082 * _extern field to marked as already added to symbol table */
1084 if (!SPEC_EXTR(func->etype))
1086 memmap *seg = SPEC_OCLS(OP_SYMBOL(IC_LEFT(newic))->etype);
1088 SPEC_EXTR(func->etype) = 1;
1089 seg = SPEC_OCLS( func->etype );
1090 addSet(&seg->syms, func);
1094 hTabAddItem (&iCodehTab, newic->key, newic);
1095 addiCodeToeBBlock (ebp, newic, ip);
1098 /*-----------------------------------------------------------------*/
1099 /* convertbuiltin - maybe convert some builtins back */
1100 /*-----------------------------------------------------------------*/
1101 static void
1102 convbuiltin (iCode *const ic, eBBlock *ebp)
1104 sym_link *ftype;
1105 symbol *bif;
1106 int stack;
1108 iCode *icc = ic, *icp = ic->prev, *ico = NULL;
1109 iCode *lastparam = ic;
1110 while (icc->op != CALL)
1112 if (icc->op != SEND || !icc->builtinSEND)
1113 return;
1114 lastparam = icc;
1115 icc = icc->next;
1118 if (!IS_SYMOP (IC_LEFT(icc)))
1119 return;
1121 ftype = operandType (IC_LEFT(icc));
1122 if (!IFFUNC_ISBUILTIN (ftype))
1123 return;
1125 bif = OP_SYMBOL (IC_LEFT (icc));
1127 /* Now we can be sure to have found a builtin function. */
1129 if ((!strcmp (bif->name, "__builtin_memcpy") || !strcmp (bif->name, "__builtin_strncpy") || !strcmp (bif->name, "__builtin_memset")) &&
1130 IS_OP_LITERAL (IC_LEFT (lastparam)) && !operandLitValue (IC_LEFT (lastparam)))
1132 /* We have a builtin that does nothing. */
1133 /* TODO: Eliminate it, convert any SEND of volatile into DUMMY_READ_VOLATILE. */
1134 /* For now just convert back to call to make sure any volatiles are read. */
1136 strcpy(OP_SYMBOL (IC_LEFT (icc))->rname, !strcmp (bif->name, "__builtin_memcpy") ? "___memcpy" : (!strcmp (bif->name, "__builtin_strncpy") ? "_strncpy" : "_memset"));
1137 goto convert;
1140 if ((TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_RABBIT || TARGET_IS_EZ80_Z80 || TARGET_IS_Z80N || TARGET_IS_R800) && (!strcmp (bif->name, "__builtin_memcpy") || !strcmp (bif->name, "__builtin_strncpy") || !strcmp (bif->name, "__builtin_memset")))
1142 /* Replace iff return value is used or last parameter is not an integer constant (except for memcpy, where non-integers can be handled). */
1143 if (bitVectIsZero (OP_USES (IC_RESULT (icc))) && (IS_OP_LITERAL (IC_LEFT (lastparam)) || !strcmp (bif->name, "__builtin_memcpy")))
1144 return;
1146 strcpy(OP_SYMBOL (IC_LEFT (icc))->rname, !strcmp (bif->name, "__builtin_memcpy") ? "___memcpy" : (!strcmp (bif->name, "__builtin_strncpy") ? "_strncpy" : "_memset"));
1147 goto convert;
1150 return;
1152 convert:
1153 /* Convert parameter passings from SEND to PUSH. */
1154 stack = 0;
1155 struct value *args;
1156 for (icc = ic, args = FUNC_ARGS (nonbuiltin_memcpy->type); icc->op != CALL; icc = icc->next, args = args->next)
1158 wassert (args);
1159 icc->builtinSEND = 0;
1160 if (IS_REGPARM (args->etype))
1162 icc->argreg = SPEC_ARGREG (args->etype);
1164 else
1166 icc->op = IPUSH;
1167 icc->parmPush = 1;
1168 stack += getSize (operandType (IC_LEFT (icc)));
1171 icc->parmBytes = stack;
1173 /* Reverse parameters. */
1174 for (icc = ic; icc->op != CALL; icc = icc->next)
1176 if (icc->next->op != CALL)
1177 icc->prev = icc->next;
1178 else
1179 icc->prev = icp;
1181 if(icc != ic)
1183 if(icp)
1184 icp->next = icc->prev;
1185 icc->prev = ic;
1187 for(; icc != icp; ico = icc, icc = icc->prev)
1189 if (icc->op != CALL)
1190 icc->next = ico;
1194 /*-----------------------------------------------------------------*/
1195 /* convconvention - handle calling convention */
1196 /*-----------------------------------------------------------------*/
1197 static void
1198 convconvention (iCode *ic, eBBlock *ebp)
1200 iCode *icc, *icp, *ico = NULL;
1202 assert (ic->op == CALL || ic->op == PCALL);
1204 sym_link *ftype = operandType (IC_LEFT (ic));
1205 if (ic->op == PCALL)
1206 ftype =ftype->next;
1208 // Small-C passed stack parameters left-to-right.
1209 if (FUNC_ISSMALLC (ftype))
1211 for (icc = ic->prev; icc && icc->op == IPUSH; icc = icc->prev)
1212 ic = icc;
1213 icp = icc;
1215 /* Reverse parameters. */
1216 for (icc = ic; icc->op != CALL && icc->op != PCALL; icc = icc->next)
1218 if (icc->next->op != CALL && icc->next->op != PCALL)
1219 icc->prev = icc->next;
1220 else
1221 icc->prev = icp;
1223 if (icc != ic)
1225 if (icp)
1226 icp->next = icc->prev;
1227 else
1228 ebp->sch = icc->prev;
1229 icc->prev = ic;
1231 for (; icc != icp; ico = icc, icc = icc->prev)
1233 if (icc->op != CALL && icc->op != PCALL)
1234 icc->next = ico;
1237 else if (FUNC_ISRAISONANCE (ftype) || FUNC_ISIAR (ftype) || FUNC_ISCOSMIC (ftype) || FUNC_ISZ88DK_FASTCALL (ftype))
1239 else // SDCC calling convention
1241 // Use default ABI version if no ABI version is explicitly requested.
1242 if (FUNC_SDCCCALL (ftype) < 0)
1243 FUNC_SDCCCALL (ftype) = options.sdcccall;
1247 /*-----------------------------------------------------------------*/
1248 /* convertToFcall - converts some operations to fcalls */
1249 /*-----------------------------------------------------------------*/
1250 static void
1251 convertToFcall (eBBlock ** ebbs, int count)
1253 int i;
1255 /* for all blocks do */
1256 for (i = 0; i < count; i++)
1258 iCode *ic;
1260 /* for all instructions in the block do */
1261 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1263 /* floating point operations are
1264 converted to function calls */
1265 if ((IS_CONDITIONAL (ic) || IS_ARITHMETIC_OP (ic)) &&
1266 (IS_FLOAT (operandType (IC_RIGHT (ic))) || IS_FIXED( operandType (IC_RIGHT (ic)))))
1268 cnvToFcall (ic, ebbs[i]);
1271 /* casting is a little different */
1272 if (ic->op == CAST)
1274 if (IS_FLOAT (operandType (IC_RIGHT (ic))))
1275 cnvFromFloatCast (ic, ebbs[i]);
1276 else if (IS_FLOAT (operandType (IC_LEFT (ic))))
1277 cnvToFloatCast (ic, ebbs[i]);
1278 if (IS_FIXED16X16 (operandType (IC_RIGHT (ic))))
1279 cnvFromFixed16x16Cast (ic, ebbs[i]);
1280 else if (IS_FIXED16X16 (operandType (IC_LEFT (ic))))
1281 cnvToFixed16x16Cast (ic, ebbs[i]);
1284 // Easy special case which avoids function call: modulo by a literal power
1285 // of two can be replaced by a bitwise AND.
1286 if (ic->op == '%' && isOperandLiteral (IC_RIGHT(ic)))
1288 bool us = IS_UNSIGNED (operandType (IC_LEFT(ic)));
1289 bool upcast = FALSE;
1290 iCode *dic = NULL;
1292 // Chek if left really is just an upcasted unsigned value.
1293 if (!us && IS_SYMOP (IC_LEFT(ic)) && bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) == 1)
1295 dic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (IC_LEFT (ic))));
1297 if (dic && dic->op == CAST && IS_UNSIGNED (operandType (IC_RIGHT (dic))) && getSize (operandType (IC_RIGHT (dic))) < getSize (operandType (IC_RESULT (dic))))
1298 us = upcast = true;
1301 if (us)
1303 unsigned long litVal = double2ul (operandLitValue (IC_RIGHT (ic)));
1305 /* modulo by 1: no remainder */
1306 if (litVal == 1)
1308 detachiCodeOperand (&ic->left, ic);
1309 ic->op = '=';
1310 IC_RIGHT (ic) = operandFromLit (0);
1311 continue;
1313 // See if literal value is a power of 2.
1314 while (litVal && !(litVal & 1))
1316 litVal >>= 1;
1318 if (litVal)
1320 // discard lowest set bit.
1321 litVal >>= 1;
1324 if (!litVal)
1326 ic->op = BITWISEAND;
1327 IC_RIGHT(ic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) - 1);
1328 if (upcast && IS_CHAR (operandType (IC_RIGHT (dic)))
1329 && bitVectnBitsOn (OP_USES (IC_LEFT (ic))) == 1)
1331 // Use precasted value
1332 attachiCodeOperand (IC_RIGHT (dic), &IC_LEFT (ic), ic);
1333 // Change cast to assignmnent to self to avoid
1334 // reading IC_RIGHT (dic) twice in case it
1335 // was volatile
1336 attachiCodeOperand (IC_RESULT (dic), &IC_RIGHT (dic), dic);
1337 dic->op = '=';
1338 // If upcast from char, maybe there's a
1339 // corresponding downcast to char that could
1340 // be eliminated too
1341 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1)
1343 iCode *uic;
1344 uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (ic))));
1345 if (uic->op == CAST && IS_CHAR (operandType (IC_RESULT (uic))))\
1347 attachiCodeOperand (IC_RESULT (uic), &IC_RESULT (ic), ic);
1348 attachiCodeOperand (IC_RESULT (uic), &IC_RIGHT (uic), uic);
1349 uic->op = '=';
1353 continue;
1359 /* if long / int mult or divide or mod */
1360 if (ic->op == '*' || ic->op == '/' || ic->op == '%')
1362 sym_link *leftType = operandType (IC_LEFT (ic));
1364 if (IS_INTEGRAL (leftType))
1366 sym_link *rightType = operandType (IC_RIGHT (ic));
1368 if (port->hasNativeMulFor != NULL &&
1369 port->hasNativeMulFor (ic, leftType, rightType))
1371 /* Leave as native */
1373 else
1375 convilong (ic, ebbs[i]);
1380 if (ic->op == ROT || ic->op == LEFT_OP || ic->op == RIGHT_OP)
1382 sym_link *type = operandType (IC_LEFT (ic));
1384 if (IS_INTEGRAL (type) && getSize (type) > (unsigned)port->support.shift && port->support.shift >= 0)
1386 convilong (ic, ebbs[i]);
1389 if (ic->op == SEND && ic->builtinSEND)
1391 convbuiltin (ic, ebbs[i]);
1393 if (ic->op == CALL || ic->op == PCALL)
1395 convconvention (ic, ebbs[i]);
1401 /*-----------------------------------------------------------------*/
1402 /* isPowerOf2 - test if val is power of 2 */
1403 /*-----------------------------------------------------------------*/
1404 bool
1405 isPowerOf2 (unsigned long val)
1407 while (val && !(val & 1))
1409 val >>= 1;
1411 return val == 1;
1414 /*-----------------------------------------------------------------*/
1415 /* miscOpt - miscellaneous optimizations */
1416 /*-----------------------------------------------------------------*/
1417 static void
1418 miscOpt (eBBlock ** ebbs, int count)
1420 /* Borut: disabled optimization of comparison unsigned with 2^n literal
1421 * since it is broken; see bug #2165 Broken comparison */
1422 #if 0
1423 int i;
1425 /* for all blocks do */
1426 for (i = 0; i < count; ++i)
1428 iCode *ic;
1430 /* for all instructions in the block do */
1431 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1433 /* patch ID: 2702889 - Summary of all uncommitted changes I applied on "my" SDCC */
1434 /* MB: This seems rather incomplete.
1435 MB: What if using <= or >= ?
1436 Borut: Currently <= and >= are transformed to > and < on all targets.
1437 Transformation depends on lt_nge, gt_nle, bool le_ngt,
1438 ge_nlt, ne_neq and eq_nne members of PORT structure.
1439 MB: Why do we need IFX in the first case and not in the second ?
1440 Borutr: Because the result of comparison is logically negated,
1441 so in case of IFX the jump logic is inverted for '<' and '<='.
1442 TODO: The logical negation of the result should be implemented
1443 for '<' and '<=' in case when the following instruction is not IFX.
1444 Philipp: Added the test for ifx in the second case, too:
1445 We want 0 or 1 as a result, the bitwise and won't do, unless we add a cast to bool.
1447 switch (ic->op)
1449 case '<':
1450 case LE_OP:
1451 case '>':
1452 case GE_OP:
1453 /* Only if the the right operand is literal and left operand is unsigned */
1454 if (isOperandLiteral (IC_RIGHT (ic)) && IS_UNSIGNED (operandType (IC_LEFT (ic))))
1456 unsigned litVal = ulFromVal (OP_VALUE (IC_RIGHT (ic)));
1458 /* Only if the literal value is greater than 255 and a power of 2 */
1459 if (litVal >= 255 &&
1460 (isPowerOf2 (litVal) && (ic->op == '<' || ic->op == GE_OP) ||
1461 isPowerOf2 (litVal + 1) && (ic->op == '>' || ic->op == LE_OP)))
1463 iCode *ic_nxt = ic->next;
1465 switch (ic->op)
1467 case LE_OP:
1468 ++litVal;
1469 /* fall through */
1470 case '<':
1471 /* Only if the next instruction is IFX */
1472 if (ic_nxt && (ic_nxt->op == IFX) && (ic->eBBlockNum == ic_nxt->eBBlockNum))
1474 int AndMaskVal = 0 - litVal;
1475 symbol *TrueLabel;
1477 /* set op to bitwise and */
1478 ic->op = BITWISEAND;
1479 IC_RIGHT (ic) = operandFromLit (AndMaskVal);
1481 /* invert jump logic */
1482 TrueLabel = IC_TRUE (ic_nxt);
1483 IC_TRUE (ic_nxt) = IC_FALSE (ic_nxt);
1484 IC_FALSE (ic_nxt) = TrueLabel;
1486 break;
1488 case '>':
1489 ++litVal;
1490 /* fall through */
1491 case GE_OP:
1492 if (ic_nxt && (ic_nxt->op == IFX) && (ic->eBBlockNum == ic_nxt->eBBlockNum))
1494 int AndMaskVal = 0 - litVal;
1496 ic->op = BITWISEAND;
1497 IC_RIGHT (ic) = operandFromLit (AndMaskVal);
1499 break;
1500 } /* switch */
1501 } /* if */
1502 } /* if */
1503 } /* switch */
1504 } /* for */
1505 } /* for */
1506 #endif
1509 /*-----------------------------------------------------------------*/
1510 /* separateAddressSpaces - enforce restrictions on bank switching */
1511 /* Operands of a single iCode must be in at most one */
1512 /* named address space. Use temporaries and additional assignments */
1513 /* to enforce the rule. */
1514 /*-----------------------------------------------------------------*/
1515 static void
1516 separateAddressSpaces (eBBlock **ebbs, int count)
1518 int i;
1520 /* for all blocks do */
1521 for (i = 0; i < count; ++i)
1523 iCode *ic;
1524 symbol *source;
1526 /* Skip this block if not reachable; other routines may have */
1527 /* also skipped it, so these iCodes may be undercooked. */
1528 if (ebbs[i]->noPath)
1529 continue;
1531 /* for all instructions in the block do */
1532 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1534 iCode *iic = 0, *newic = 0;
1535 operand *left, *right, *result;
1536 const symbol *leftaddrspace = 0, *rightaddrspace = 0, *resultaddrspace = 0;
1538 /* JUMPTABLE and IFX do not have left/right/result operands. */
1539 /* However, they only have a single operand so they cannot */
1540 /* have more than one address space to worry about. */
1541 if (ic->op == JUMPTABLE || ic->op == IFX)
1542 continue;
1544 left = IC_LEFT (ic);
1545 right = IC_RIGHT (ic);
1546 result = IC_RESULT (ic);
1548 /*printf ("Looking at ic %d, op %d\n", ic->key, (int)(ic->op));*/
1550 if (left && ic->op != ADDRESS_OF && IS_SYMOP (left))
1552 if (POINTER_GET (ic))
1554 assert (!(IS_DECL (OP_SYMBOL (left)->type) && DCL_PTR_ADDRSPACE (OP_SYMBOL (left)->type)));
1555 leftaddrspace = getAddrspace (OP_SYMBOL (left)->type->next);
1557 else
1558 leftaddrspace = getAddrspace (OP_SYMBOL (left)->type);
1560 if (right && IS_SYMOP (right))
1561 rightaddrspace = getAddrspace (OP_SYMBOL (right)->type);
1562 if (result && IS_SYMOP (result))
1564 if (POINTER_SET (ic))
1566 assert (!(IS_DECL (OP_SYMBOL (result)->type) && DCL_PTR_ADDRSPACE (OP_SYMBOL (result)->type)));
1567 resultaddrspace = getAddrspace (OP_SYMBOL (result)->type->next);
1569 else
1570 resultaddrspace = getAddrspace (OP_SYMBOL (result)->type);
1573 #if 0
1574 if (leftaddrspace)
1575 printf("ic %d (dcl? %d) leftaddrspace %s\n", ic->key, (int)(IS_DECL (OP_SYMBOL (left)->type)), leftaddrspace->name);
1576 if (rightaddrspace)
1577 printf("ic %d (dcl? %d) rightaddrspace %s\n", ic->key, (int)(IS_DECL (OP_SYMBOL (right)->type)), rightaddrspace->name);
1578 if (resultaddrspace)
1579 printf("ic %d (dcl? %d) resultaddrspace %s\n", ic->key, (int)(IS_DECL (OP_SYMBOL (result)->type)), resultaddrspace->name);
1580 #endif
1582 if (ic->op == IPUSH && leftaddrspace)
1584 operand *newop;
1586 source = OP_SYMBOL (left);
1587 newic = newiCode ('=', 0, left);
1588 IC_RESULT (newic) = newop = newiTempOperand (source->type, 0);
1589 IC_LEFT (ic) = newop;
1590 leftaddrspace = 0;
1591 for (iic = ic; iic->prev && iic->prev->op == IPUSH; iic = iic->prev);
1593 else if (leftaddrspace && rightaddrspace && leftaddrspace != rightaddrspace ||
1594 resultaddrspace && rightaddrspace && resultaddrspace != rightaddrspace ||
1595 resultaddrspace && leftaddrspace && resultaddrspace != leftaddrspace)
1597 operand *newop;
1599 if (rightaddrspace == resultaddrspace)
1600 source = OP_SYMBOL (left);
1601 else
1602 source = OP_SYMBOL (right);
1603 newic = newiCode ('=', 0, rightaddrspace == resultaddrspace ? left : right);
1604 IC_RESULT (newic) = newop = newiTempOperand (source->type, 0);
1605 if (rightaddrspace == resultaddrspace)
1607 IC_LEFT (ic) = newop;
1608 leftaddrspace = 0;
1610 else
1612 IC_RIGHT (ic) = newop;
1613 rightaddrspace = 0;
1615 iic = ic;
1618 if (newic)
1620 newic->filename = ic->filename;
1621 newic->lineno = ic->lineno;
1622 hTabAddItem (&iCodehTab, newic->key, newic);
1623 addiCodeToeBBlock (ebbs[i], newic, iic);
1626 assert (!leftaddrspace || !resultaddrspace || leftaddrspace == resultaddrspace);
1627 assert (!rightaddrspace || !resultaddrspace || rightaddrspace == resultaddrspace);
1632 const symbol *
1633 getAddrspaceiCode (const iCode *ic)
1635 operand *left, *right, *result;
1636 const symbol *leftaddrspace = 0, *rightaddrspace = 0, *resultaddrspace = 0;
1637 const symbol *addrspace;
1639 left = IC_LEFT (ic);
1640 right = IC_RIGHT (ic);
1641 result = IC_RESULT (ic);
1643 /* Previous transformations in separateAddressSpaces() should
1644 ensure that at most one addressspace occurs in each iCode. */
1645 if (left && ic->op != ADDRESS_OF && IS_SYMOP (left))
1647 if (POINTER_GET (ic))
1649 assert (!(IS_DECL (OP_SYMBOL (left)->type) && DCL_PTR_ADDRSPACE (OP_SYMBOL (left)->type)));
1650 leftaddrspace = getAddrspace (OP_SYMBOL (left)->type->next);
1652 else
1653 leftaddrspace = getAddrspace (OP_SYMBOL (left)->type);
1655 if (right && IS_SYMOP (right))
1656 rightaddrspace = getAddrspace (OP_SYMBOL (right)->type);
1657 if (result && IS_SYMOP (result))
1659 if (POINTER_SET (ic))
1661 assert (!(IS_DECL (OP_SYMBOL (result)->type) && DCL_PTR_ADDRSPACE (OP_SYMBOL (result)->type)));
1662 resultaddrspace = getAddrspace (OP_SYMBOL (result)->type->next);
1664 else
1665 resultaddrspace = getAddrspace (OP_SYMBOL (result)->type);
1668 addrspace = leftaddrspace;
1669 if (rightaddrspace)
1671 wassertl (!addrspace || addrspace == rightaddrspace, "Multiple named address spaces in icode.");
1672 addrspace = rightaddrspace;
1674 if (resultaddrspace)
1676 wassertl (!addrspace || addrspace == resultaddrspace, "Multiple named address spaces in icode.");
1677 addrspace = resultaddrspace;
1680 return (addrspace);
1683 /*-----------------------------------------------------------------*/
1684 /* switchAddressSpaceAt - insert a bank selection instruction */
1685 /*-----------------------------------------------------------------*/
1686 void
1687 switchAddressSpaceAt (iCode *ic, const symbol *const addrspace)
1689 iCode *newic;
1690 const symbol *const laddrspace = getAddrspaceiCode (ic);
1691 wassertl(!laddrspace || laddrspace == addrspace, "Switching to invalid address space.");
1693 newic = newiCode (CALL, operandFromSymbol (addrspace->addressmod[0], false), 0);
1695 IC_RESULT (newic) = newiTempOperand (newVoidLink (), 1);
1696 newic->filename = ic->filename;
1697 newic->lineno = ic->lineno;
1699 newic->next = ic;
1700 newic->prev = ic->prev;
1701 if (ic->prev)
1702 ic->prev->next = newic;
1703 ic->prev = newic;
1706 /*-----------------------------------------------------------------*/
1707 /* switchAddressSpaces - insert instructions for bank switching */
1708 /* This is just a fallback, in case the optimal approach fails - */
1709 /* improbable, but possible depending on sdcc options and code. */
1710 /*-----------------------------------------------------------------*/
1711 static void
1712 switchAddressSpaces (iCode *ic)
1714 const symbol *oldaddrspace = 0;
1716 for (; ic; ic = ic->next)
1718 const symbol *const addrspace = getAddrspaceiCode (ic);
1720 if (addrspace && addrspace != oldaddrspace)
1722 switchAddressSpaceAt (ic, addrspace);
1724 oldaddrspace = addrspace;
1727 /* Address space might not be preserved over these. */
1728 if (ic->op == LABEL || ic->op == CALL || ic->op == PCALL)
1729 oldaddrspace = 0;
1733 /*-----------------------------------------------------------------*/
1734 /* isLocalWithoutDef - return 1 if sym might be used without a */
1735 /* defining iCode */
1736 /*-----------------------------------------------------------------*/
1737 static int
1738 isLocalWithoutDef (symbol * sym)
1740 if (!IS_AUTO (sym))
1741 return 0;
1743 if (IS_VOLATILE (sym->type))
1744 return 0;
1746 if (sym->_isparm)
1747 return 0;
1749 if (IS_AGGREGATE (sym->type))
1750 return 0;
1752 if (sym->addrtaken)
1753 return 0;
1755 return !sym->defs;
1758 static void
1759 replaceRegEqvOperand (iCode * ic, operand ** opp, int force_isaddr, int new_isaddr)
1761 operand * op = *opp;
1762 symbol * sym = OP_SYMBOL (op);
1764 if (isLocalWithoutDef (sym))
1766 werrorfl (ic->filename, ic->lineno, W_LOCAL_NOINIT, sym->name);
1767 OP_REQV (op) = NULL;
1768 sym->allocreq = 1;
1770 else if (OP_REQV (op))
1772 operand * nop;
1774 nop = operandFromOperand (OP_REQV (op));
1776 /* Copy def/use info from true symbol to register equivalent */
1777 /* but only if this hasn't been done already. */
1778 if (!OP_DEFS (nop))
1779 OP_DEFS (nop) = bitVectCopy (OP_DEFS (op));
1780 if (!OP_USES (nop))
1781 OP_USES (nop) = bitVectCopy (OP_USES (op));
1783 if (force_isaddr)
1784 nop->isaddr = new_isaddr;
1786 *opp = nop; /* Replace true sym operand with reg equiv */
1790 /*-----------------------------------------------------------------*/
1791 /* replaceRegEqv - replace all local variables with their reqv */
1792 /*-----------------------------------------------------------------*/
1793 static void
1794 replaceRegEqv (ebbIndex *ebbi)
1796 eBBlock ** ebbs = ebbi->bbOrder;
1797 int count = ebbi->count;
1798 int i;
1800 /* Reset all the def/use info (Otherwise there may be stale def/use */
1801 /* info if a variable is also used in a previous functions) */
1802 for (i = 0; i < count; i++)
1804 iCode *ic;
1806 if (ebbs[i]->noPath)
1807 continue;
1809 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1811 // Convert struct / union to pointer.
1812 if(ic->op != ADDRESS_OF && ic->op != RETURN && ic->op != CALL && ic->op != PCALL)
1814 if (ic->left && IS_AGGREGATE (operandType (ic->left)))
1815 setOperandType (ic->left, aggrToPtr (operandType (ic->left), false));
1816 if (ic->right && IS_AGGREGATE (operandType (ic->right)))
1817 setOperandType (ic->right, aggrToPtr (operandType (ic->right), false));
1818 if (ic->result && IS_AGGREGATE (operandType (ic->result)))
1819 setOperandType (ic->result, aggrToPtr (operandType (ic->result), false));
1822 if (SKIP_IC2 (ic))
1823 continue;
1825 if (IS_TRUE_SYMOP (IC_RESULT (ic)))
1827 OP_DEFS (IC_RESULT (ic)) = NULL;
1828 OP_USES (IC_RESULT (ic)) = NULL;
1831 if (IS_TRUE_SYMOP (IC_RIGHT (ic)))
1833 OP_DEFS (IC_RIGHT (ic)) = NULL;
1834 OP_USES (IC_RIGHT (ic)) = NULL;
1837 if (IS_TRUE_SYMOP (IC_LEFT (ic)))
1839 OP_DEFS (IC_LEFT (ic)) = NULL;
1840 OP_USES (IC_LEFT (ic)) = NULL;
1845 /* Update the symbols' def bitvector so we know if there is */
1846 /* a defining iCode or not. Only replace a local variable */
1847 /* with its register equivalent if there is a defining iCode; */
1848 /* otherwise, the port's register allocater may choke. */
1849 cseAllBlocks (ebbi, TRUE);
1851 for (i = 0; i < count; i++)
1853 iCode *ic;
1855 if (ebbs[i]->noPath)
1856 continue;
1858 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1860 if (SKIP_IC2 (ic))
1861 continue;
1863 if (ic->op == RECEIVE)
1865 if (OP_SYMBOL (IC_RESULT (ic))->addrtaken)
1866 OP_SYMBOL (IC_RESULT (ic))->isspilt = 1;
1869 /* general case */
1870 if (IS_TRUE_SYMOP (IC_RESULT (ic)))
1872 if (POINTER_SET (ic))
1873 replaceRegEqvOperand (ic, &IC_RESULT (ic), 1, 1);
1874 else
1875 replaceRegEqvOperand (ic, &IC_RESULT (ic), 0, 0);
1877 if (IS_TRUE_SYMOP (IC_RIGHT (ic)))
1878 replaceRegEqvOperand (ic, &IC_RIGHT (ic), 1, 0);
1879 if (IS_TRUE_SYMOP (IC_LEFT (ic)))
1880 replaceRegEqvOperand (ic, &IC_LEFT (ic), 1, 0);
1885 /*-----------------------------------------------------------------*/
1886 /* findReqv - search for a register equivalent */
1887 /*-----------------------------------------------------------------*/
1888 operand *
1889 findReqv (symbol * prereqv, eBBlock ** ebbs, int count)
1891 int i;
1892 iCode * ic;
1894 /* for all blocks do */
1895 for (i=0; i<count; i++)
1897 /* for all instructions in the block do */
1898 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1900 if (IS_ITEMP (IC_LEFT (ic))
1901 && OP_SYMBOL (IC_LEFT (ic))->prereqv == prereqv)
1902 return IC_LEFT (ic);
1903 if (IS_ITEMP (IC_RIGHT (ic))
1904 && OP_SYMBOL (IC_RIGHT (ic))->prereqv == prereqv)
1905 return IC_RIGHT (ic);
1906 if (IS_ITEMP (IC_RESULT (ic))
1907 && OP_SYMBOL (IC_RESULT (ic))->prereqv == prereqv)
1908 return IC_RESULT (ic);
1912 return NULL;
1915 /*-----------------------------------------------------------------*/
1916 /* killDeadCode - eliminates dead assignments */
1917 /*-----------------------------------------------------------------*/
1919 killDeadCode (ebbIndex * ebbi)
1921 eBBlock ** ebbs = ebbi->dfOrder;
1922 int count = ebbi->count;
1923 int change = 1;
1924 int gchange = 0;
1925 int i = 0;
1927 /* basic algorithm :- */
1928 /* first the exclusion rules :- */
1929 /* 1. if result is a global or volatile then skip */
1930 /* 2. if assignment and result is a temp & isaddr then skip */
1931 /* since this means array & pointer access, will be taken */
1932 /* care of by alias analysis. */
1933 /* 3. if the result is used in the remainder of the block skip */
1934 /* 4. if this definition does not reach the end of the block */
1935 /* i.e. the result is not present in the outExprs then KILL */
1936 /* 5. if it reaches the end of block & is used by some success */
1937 /* or then skip */
1938 /* else KILL */
1939 /* this whole process is carried on iteratively till no change */
1942 change = 0;
1943 /* for all blocks do */
1944 for (i = 0; i < count; i++)
1946 iCode *ic;
1948 /* for all instructions in the block do */
1949 for (ic = ebbs[i]->sch; ic; ic = ic->next)
1951 int kill, j;
1952 kill = 0;
1954 if (SKIP_IC (ic) && ic->op != RECEIVE ||
1955 ic->op == IFX ||
1956 ic->op == RETURN ||
1957 ic->op == DUMMY_READ_VOLATILE ||
1958 ic->op == CRITICAL ||
1959 ic->op == ENDCRITICAL)
1960 continue;
1962 /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
1963 /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
1964 /* valid. */
1966 /* if the result is volatile then continue */
1967 if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
1968 continue;
1970 /* if the result is a temp & isaddr then skip */
1971 if (IC_RESULT (ic) && POINTER_SET (ic))
1972 continue;
1974 /* if the results address has been taken then skip */
1975 if (IS_SYMOP (IC_RESULT (ic)) && OP_SYMBOL (IC_RESULT (ic))->addrtaken)
1976 continue;
1978 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next)
1979 && !SPIL_LOC (IC_RESULT (ic)))
1980 continue;
1982 /* if the result is used in the remainder of the */
1983 /* block then skip */
1984 if (usedInRemaining (IC_RESULT (ic), ic->next))
1985 continue;
1987 /* does this definition reach the end of the block
1988 or the usage is zero then we can kill */
1989 if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
1990 kill = 1; /* if not we can kill it */
1991 else
1993 /* if this is a global variable or function parameter */
1994 /* we cannot kill anyway */
1995 if (isOperandGlobal (IC_RESULT (ic)) ||
1996 (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
1997 !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
1998 continue;
2000 /* if we are sure there are no usages */
2001 if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
2003 kill = 1;
2004 goto kill;
2007 /* reset visited flag */
2008 for (j = 0; j < count; ebbs[j++]->visited = 0);
2010 /* find out if this definition is alive */
2011 if (applyToSet (ebbs[i]->succList, isDefAlive, ic))
2012 continue;
2014 kill = 1;
2017 kill:
2018 /* kill this one if required */
2019 if (kill)
2021 bool volLeft = IS_SYMOP (IC_LEFT (ic))
2022 && isOperandVolatile (IC_LEFT (ic), FALSE);
2023 bool volRight = IS_SYMOP (IC_RIGHT (ic))
2024 && isOperandVolatile (IC_RIGHT (ic), FALSE);
2026 /* a dead address-of operation should die, even if volatile */
2027 if (ic->op == ADDRESS_OF)
2028 volLeft = FALSE;
2030 if (ic->next && ic->seqPoint == ic->next->seqPoint
2031 && (ic->next->op == '+' || ic->next->op == '-'))
2033 if (isOperandEqual (IC_LEFT(ic), IC_LEFT(ic->next))
2034 || isOperandEqual (IC_LEFT(ic), IC_RIGHT(ic->next)))
2035 volLeft = FALSE;
2036 if (isOperandEqual (IC_RIGHT(ic), IC_LEFT(ic->next))
2037 || isOperandEqual (IC_RIGHT(ic), IC_RIGHT(ic->next)))
2038 volRight = FALSE;
2041 if (POINTER_GET (ic) && IS_VOLATILE (operandType (IC_LEFT (ic))->next))
2043 if (SPIL_LOC (IC_RESULT (ic)))
2045 bitVectUnSetBit (OP_DEFS (ic->result), ic->key);
2046 IC_RESULT (ic) = newiTempFromOp (IC_RESULT (ic));
2047 SPIL_LOC (IC_RESULT (ic)) = NULL;
2049 continue;
2052 change = 1;
2053 gchange++;
2055 /* now delete from defUseSet */
2056 deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
2057 bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
2059 /* and defset of the block */
2060 bitVectUnSetBit (ebbs[i]->defSet, ic->key);
2062 /* If this is the last of a register equivalent, */
2063 /* look for a successor register equivalent. */
2064 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2065 if (IS_ITEMP (IC_RESULT (ic))
2066 && OP_SYMBOL (IC_RESULT (ic))->isreqv
2067 && bitVectIsZero (OP_DEFS (IC_RESULT (ic))))
2069 symbol * resultsym = OP_SYMBOL (IC_RESULT (ic));
2070 symbol * prereqv = resultsym->prereqv;
2072 if (prereqv && prereqv->reqv && (OP_SYMBOL (prereqv->reqv) == resultsym))
2074 operand * newreqv;
2076 IC_RESULT (ic) = NULL;
2077 newreqv = findReqv (prereqv, ebbs, count);
2078 if (newreqv)
2080 prereqv->reqv = newreqv;
2085 /* delete the result */
2086 if (IC_RESULT (ic))
2087 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
2088 IC_RESULT (ic) = NULL;
2090 if (volLeft || volRight)
2092 /* something is volatile, so keep the iCode */
2093 /* and change the operator instead */
2094 ic->op = DUMMY_READ_VOLATILE;
2096 /* keep only the volatile operands */
2097 if (!volLeft)
2098 IC_LEFT (ic) = NULL;
2099 if (!volRight)
2100 IC_RIGHT (ic) = NULL;
2102 else
2104 /* nothing is volatile, eliminate the iCode */
2105 unsetDefsAndUses (ic);
2106 remiCodeFromeBBlock (ebbs[i], ic);
2108 /* for the left & right remove the usage */
2109 if (IS_SYMOP (ic->left) && OP_SYMBOL (ic->left)->isstrlit)
2110 freeStringSymbol (OP_SYMBOL (ic->left));
2111 if (IS_SYMOP (ic->right) && OP_SYMBOL (ic->right)->isstrlit)
2112 freeStringSymbol (OP_SYMBOL (ic->right));
2115 } /* end of all instructions */
2117 if (!ebbs[i]->sch && !ebbs[i]->noPath)
2118 disconBBlock (ebbs[i], ebbi);
2119 } /* end of for all blocks */
2120 } /* end of do */
2121 while (change);
2123 return gchange;
2126 /*-----------------------------------------------------------------*/
2127 /* printCyclomatic - prints the cyclomatic information */
2128 /*-----------------------------------------------------------------*/
2129 static void
2130 printCyclomatic (eBBlock ** ebbs, int count)
2132 int nEdges = elementsInSet (graphEdges);
2133 int i, nNodes = 0;
2135 for (i = 0; i < count; i++)
2136 nNodes += (!ebbs[i]->noPath);
2138 /* print the information */
2139 werror (I_CYCLOMATIC, currFunc->name, nEdges, nNodes, nEdges - nNodes + 2);
2142 /*-----------------------------------------------------------------*/
2143 /* discardDeadParamReceives - remove any RECEIVE opcodes which */
2144 /* refer to dead variables. */
2145 /*-----------------------------------------------------------------*/
2146 static void
2147 discardDeadParamReceives (eBBlock ** ebbs, int count)
2149 int i;
2150 iCode *ic;
2151 iCode dummyIcode;
2153 for (i = 0; i < count; i++)
2155 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2157 if (ic->op == RECEIVE)
2159 if (IC_RESULT (ic) && OP_SYMBOL (IC_RESULT (ic))
2160 && !OP_SYMBOL (IC_RESULT (ic))->used)
2162 #if 0
2163 fprintf (stderr, "discarding dead receive for %s\n",
2164 OP_SYMBOL (IC_RESULT (ic))->name);
2165 #endif
2166 dummyIcode.next = ic->next;
2167 remiCodeFromeBBlock (ebbs[i], ic);
2168 ic = &dummyIcode;
2175 /*-----------------------------------------------------------------*/
2176 /* optimizeOpWidth - reduce operation width. */
2177 /* Wide arithmetic operations where the result is cast to narrow */
2178 /* type can be optimized by doing the casts on the operands */
2179 /*-----------------------------------------------------------------*/
2180 static int
2181 optimizeOpWidth (eBBlock ** ebbs, int count)
2183 int i;
2184 int change = 0;
2185 iCode *ic, *newic;
2186 iCode *uic, *skipuic;
2187 sym_link *nextresulttype;
2188 symbol *sym;
2189 int resultsize, nextresultsize;
2191 // Wide loop counter
2192 for (i = 0; i < count; i++)
2194 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2196 sym_link *newcountertype, *oldcountertype;
2197 const symbol *label;
2198 const iCode *ifx, *inc = 0, *obstacle = 0;
2199 iCode *mul = 0;
2200 bool found = false;
2202 if (ic->op != LABEL || !ic->next)
2203 continue;
2205 label = IC_LABEL (ic);
2206 ic = ic->next;
2208 if (ic->op != '<' || !IS_ITEMP (IC_LEFT (ic)) || bitVectnBitsOn (OP_DEFS (IC_LEFT (ic))) != 2)
2209 continue;
2211 oldcountertype = operandType (IC_LEFT (ic));
2212 if (IS_VOLATILE (oldcountertype))
2213 continue;
2215 // Only try to narrow wide counters.
2216 // TODO: Handle signed types as well, maybe even transform int to unsigned int?
2217 if (!IS_INTEGRAL(oldcountertype) || bitsForType (oldcountertype) <= 8 || TARGET_IS_DS390 || TARGET_IS_DS400 || (!SPEC_USIGN (oldcountertype)))
2218 continue;
2220 ifx = ifxForOp (IC_RESULT (ic), ic);
2222 if (!ifx || IC_TRUE (ifx) || i + 1 >= count)
2223 continue;
2225 /* For now we handle only loops that have no complex control flow inside them and where
2226 the loop is entered and left through ifx only */
2227 for (uic = ebbs[i + 1]->sch; uic; uic = uic->next)
2229 if (uic->op == GOTO && IC_LABEL (uic) == label)
2230 break;
2232 if (!obstacle &&
2233 (uic->op == CALL || uic->op == PCALL || uic->op == IFX || uic->op == LABEL ||
2234 uic->op == GOTO && IC_LABEL (uic) != label || uic->op == INLINEASM))
2236 obstacle = uic;
2237 break;
2241 // TODO: Proceed despite obstacle, but only consider array accesses before obstacle.
2242 if (obstacle || !uic || uic->op != GOTO || IC_LABEL (uic) != label)
2243 continue;
2245 const bitVect *uses;
2246 int bit;
2248 uses = bitVectCopy (OP_USES (IC_LEFT (ic)));
2249 for (bit = bitVectFirstBit (uses); bitVectnBitsOn (uses); bitVectUnSetBit (uses, bit), bit = bitVectFirstBit (uses))
2251 operand *prevresult = IC_LEFT(ic);
2252 operand *mulotherop = 0;
2253 iCode *mul_candidate = 0;
2254 uic = hTabItemWithKey (iCodehTab, bit);
2256 if (!uic)
2258 /* This iCode has been deleted but is still */
2259 /* referenced. This shouldn't happen if everything */
2260 /* else is managing OP_USES properly, but better */
2261 /* to ignore the problem than crash. */
2262 //printf ("%s used in iCode %d, but iCode missing\n", OP_SYMBOL (IC_LEFT (ic))->name, bit);
2263 continue;
2266 if (uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic)) && operandLitValue (IC_RIGHT (uic)) == 1 && isOperandEqual (IC_LEFT (uic), IC_LEFT (ic)))
2268 inc = uic;
2269 continue;
2272 if (uic->op != CAST && uic->op != '=' && uic->op != '+' && uic->op != '*' && uic->op != '-' && uic->op != LEFT_OP && uic->op != RIGHT_OP && uic->op != '<')
2274 found = false;
2275 break;
2278 if (uic && uic->op == '*')
2280 mulotherop = isOperandEqual (IC_LEFT (ic), IC_LEFT (uic)) ? IC_RIGHT (uic) : IC_LEFT (uic);
2281 if (isOperandEqual (IC_RIGHT (ic), mulotherop))
2283 mul_candidate = uic;
2284 uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (uic))));
2288 for (int i = 0;
2289 i < 8 && uic &&
2290 (uic->op == CAST && bitsForType (operandType (IC_RESULT (uic))) >= 16 ||
2291 uic->op == '=' || uic->op == '+' || uic->op == LEFT_OP ||
2292 uic->op == '*' && IS_OP_LITERAL (IC_RIGHT (uic)) && operandLitValue (IC_RIGHT (uic)) >= 1);
2293 i++)
2295 prevresult = IC_RESULT (uic);
2296 uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (uic))));
2299 if (!uic)
2300 continue;
2302 // Use as array index?
2303 if (uic->op == GET_VALUE_AT_ADDRESS || POINTER_SET(uic) && isOperandEqual (IC_RESULT (uic), prevresult))
2305 found = true;
2306 if (mul_candidate)
2307 mul = mul_candidate;
2311 if (!found || !inc)
2312 continue;
2314 /* All backends (except ds390 / ds400) have an array size limit smaller than 2^16. Thus if the loop counter ever goes outside
2315 the range of a 16-bit type, the array access would result in undefined behaviour. We can thus replace the loop
2316 counter by a 16-bit type. If we found a squaring multiplication, we can even use an 8-bit type*/
2317 if (bitsForType (oldcountertype) <= 16 && !mul)
2318 continue;
2320 newcountertype = mul ? newCharLink () : newIntLink ();
2321 SPEC_USIGN (newcountertype) = 1;
2322 OP_SYMBOL (IC_LEFT (ic))->type = newcountertype;
2323 OP_SYMBOL (IC_RESULT (inc))->type = newcountertype;
2325 uses = bitVectCopy (OP_USES (IC_LEFT (ic)));
2326 for (bit = bitVectFirstBit (uses); bitVectnBitsOn (uses); bitVectUnSetBit (uses, bit), bit = bitVectFirstBit (uses))
2328 uic = hTabItemWithKey (iCodehTab, bit);
2330 if (uic == inc || uic == mul)
2331 continue;
2332 if (uic->op == CAST)
2333 continue;
2334 if (uic->key == ic->key)
2335 continue;
2336 if (uic->op == '=')
2338 uic->op = CAST;
2339 continue;
2342 // Need to insert cast.
2343 prependCast (uic, IC_LEFT (ic), oldcountertype, ebbs[i + 1]);
2346 // Insert cast for comparison.
2347 prependCast (ic, IC_RIGHT (ic), newcountertype, ebbs[i]);
2349 // Bonus: Can narrow a multiplication in the loop.
2350 if (mul)
2352 prependCast (mul, IC_LEFT (mul), newcountertype, ebbs[i + 1]);
2353 prependCast (mul, IC_RIGHT (mul), newcountertype, ebbs[i + 1]);
2354 nextresulttype = newIntLink();
2355 SPEC_USIGN (nextresulttype) = 1;
2356 appendCast(mul, nextresulttype, ebbs[i + 1]);
2361 // Operation followed by cast
2362 for (i = 0; i < count; i++)
2364 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2366 if ( (ic->op == CAST || ic->op == '+' || ic->op == '-' || ic->op == UNARYMINUS || ic->op == '*' ||
2367 ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == BITWISEAND || ic->op == '|' || ic->op == '^') &&
2368 IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)) )
2370 sym_link *resulttype = operandType (IC_RESULT (ic));
2372 if (!IS_INTEGRAL (resulttype) ||
2373 ic->op != CAST && !(IS_SYMOP (IC_LEFT (ic)) ||
2374 IS_OP_LITERAL (IC_LEFT (ic))) ||
2375 !(IS_SYMOP (IC_RIGHT (ic)) || IS_OP_LITERAL (IC_RIGHT (ic)) || ic->op == UNARYMINUS))
2377 continue;
2380 resultsize = bitsForType (resulttype);
2382 /* There must be only one use of this first result */
2383 if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) != 1 || bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
2384 continue;
2386 uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (ic))));
2388 if (!uic)
2389 continue;
2391 /* Skip over assignment */
2392 skipuic = NULL;
2393 if (uic->op == '=' && IS_ITEMP (IC_RESULT (uic)) &&
2394 bitVectnBitsOn (OP_DEFS (IC_RESULT (uic))) == 1 && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1 && bitVectnBitsOn (OP_USES (IC_RESULT (uic))) == 1 &&
2395 compareType (operandType (IC_RESULT (ic)), operandType (IC_RESULT (uic)), false) == 1)
2397 skipuic = uic;
2398 uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (uic))));
2399 if (!uic)
2400 continue;
2403 /* Try to handle a few cases where the result has multiple uses */
2404 else if (ic->op == '*' && bitsForType (operandType (IC_RESULT (ic))) > 16 && uic->op == '=' &&
2405 bitVectnBitsOn (OP_DEFS (IC_RESULT (uic))) == 1 && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1 && bitVectnBitsOn (OP_USES (IC_RESULT (uic))) > 1 &&
2406 compareType (operandType (IC_RESULT (ic)), operandType (IC_RESULT (uic)), false) == 1)
2408 bool ok = true;
2409 const bitVect *uses;
2410 int bit;
2412 uses = bitVectCopy (OP_USES (IC_RESULT (uic)));
2413 for (bit = bitVectFirstBit(uses); bitVectnBitsOn (uses); bitVectUnSetBit(uses, bit), bit = bitVectFirstBit(uses))
2415 iCode *uuic = hTabItemWithKey (iCodehTab, bit);
2416 if (uuic->op != CAST || bitsForType (operandType (IC_RESULT (uuic))) > 16 || IS_BOOLEAN (operandType (IC_RESULT (uuic))))
2418 ok = false;
2419 break;
2423 if (!ok)
2424 continue;
2426 nextresulttype = newIntLink ();
2427 SPEC_USIGN (nextresulttype) = 1;
2428 sym = OP_SYMBOL (IC_RESULT (uic));
2429 sym->type = nextresulttype;
2431 nextresulttype = newIntLink ();
2432 SPEC_USIGN (nextresulttype) = 1;
2433 goto optimize;
2436 if (uic->op != CAST && uic->op != '+' && uic->op != LEFT_OP && uic->op != RIGHT_OP)
2437 continue;
2439 /* Special handling since we might need more bits in the operand than in the result */
2440 if (ic->op == RIGHT_OP)
2442 int shiftbits, resultbits;
2444 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
2445 continue;
2447 shiftbits = (int) operandLitValue (IC_RIGHT (ic));
2448 resultbits = bitsForType (operandType (IC_RESULT (uic)));
2450 if (resultbits + shiftbits > 16)
2451 continue;
2452 else if (resultbits + shiftbits > 8)
2453 nextresulttype = newIntLink ();
2454 else
2455 nextresulttype = newCharLink ();
2456 SPEC_USIGN (nextresulttype) = 1;
2458 /* It must be a cast to another integer type that */
2459 /* has fewer bits */
2460 else if (uic->op == LEFT_OP || uic->op == RIGHT_OP)
2462 /* Since shifting by the width of an operand or more is undefined behaviour, and no type is wider than 256 bits,
2463 we can optimize when the result is used as right operand to a shift. */
2464 if (!isOperandEqual (IC_RESULT (ic), IC_RIGHT (uic)) || isOperandEqual (IC_RESULT (ic), IC_LEFT (uic)))
2465 continue;
2467 nextresulttype = newCharLink ();
2469 else
2471 nextresulttype = operandType (IC_RESULT (uic));
2472 if (!IS_INTEGRAL (nextresulttype) && !(IS_PTR (nextresulttype) && NEARPTRSIZE == 2))
2473 continue;
2475 if (IS_PTR (nextresulttype))
2477 nextresulttype = newIntLink ();
2478 SPEC_USIGN (nextresulttype) = 1;
2480 else
2482 nextresulttype = copyLinkChain (nextresulttype);
2486 nextresultsize = bitsForType (nextresulttype);
2487 if (nextresultsize >= resultsize)
2488 continue;
2489 /* Cast to bool and bool-like types must be preserved to ensure that all nonzero values are correctly cast to true */
2490 if (uic->op == CAST && IS_BOOLEAN (nextresulttype))
2491 continue;
2493 optimize:
2494 /* Make op result narrower */
2495 sym = OP_SYMBOL (IC_RESULT (ic));
2496 sym->type = nextresulttype;
2498 /* Insert casts on operands */
2499 if (ic->op != CAST)
2501 sym_link *clefttype = copyLinkChain (nextresulttype);
2502 SPEC_VOLATILE (clefttype) = IS_OP_VOLATILE (IC_LEFT (ic));
2503 sym_link *crighttype = copyLinkChain (nextresulttype);
2504 SPEC_VOLATILE (crighttype) = IS_OP_VOLATILE (IC_RIGHT (ic));
2506 if (IS_SYMOP (IC_LEFT (ic)))
2508 newic = newiCode (CAST, operandFromLink (clefttype), IC_LEFT (ic));
2509 hTabAddItem (&iCodehTab, newic->key, newic);
2510 bitVectSetBit (OP_USES (IC_LEFT (ic)), newic->key);
2511 IC_RESULT (newic) = newiTempOperand (clefttype, 0);
2512 OP_DEFS (IC_RESULT (newic)) = bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
2513 bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2514 IC_LEFT (ic) = operandFromOperand (IC_RESULT (newic));
2515 OP_USES (IC_LEFT (ic)) = bitVectSetBit (OP_USES (IC_LEFT (ic)), ic->key);
2516 newic->filename = ic->filename;
2517 newic->lineno = ic->lineno;
2518 addiCodeToeBBlock (ebbs[i], newic, ic);
2520 else
2522 wassert (IS_OP_LITERAL (IC_LEFT (ic)));
2523 IC_LEFT (ic) = operandFromValue (valCastLiteral (clefttype, operandLitValue (IC_LEFT (ic)), operandLitValue (IC_LEFT (ic))), false);
2525 if (ic->op != LEFT_OP && IS_SYMOP (IC_RIGHT (ic)))
2527 newic = newiCode (CAST, operandFromLink (crighttype), IC_RIGHT (ic));
2528 hTabAddItem (&iCodehTab, newic->key, newic);
2529 bitVectSetBit (OP_USES (IC_RIGHT (ic)), newic->key);
2530 IC_RESULT (newic) = newiTempOperand (crighttype, 0);
2531 OP_DEFS (IC_RESULT (newic)) = bitVectSetBit (OP_DEFS (IC_RESULT (newic)), newic->key);
2532 bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2533 IC_RIGHT (ic) = operandFromOperand (IC_RESULT (newic));
2534 OP_USES (IC_RIGHT (ic)) = bitVectSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
2535 newic->filename = ic->filename;
2536 newic->lineno = ic->lineno;
2537 addiCodeToeBBlock (ebbs[i], newic, ic);
2539 else if (ic->op != LEFT_OP && ic->op != UNARYMINUS)
2541 wassert (IS_OP_LITERAL (IC_RIGHT (ic)));
2542 IC_RIGHT (ic) = operandFromValue (valCastLiteral (crighttype, operandLitValue (IC_RIGHT (ic)), operandLitValue (IC_RIGHT (ic))), false);
2545 if (uic->op == CAST && ic->op != RIGHT_OP)
2547 uic->op = '=';
2548 if (skipuic)
2549 attachiCodeOperand (skipuic->right, &uic->right, uic);
2551 if (skipuic && skipuic->op == '=' &&
2552 compareType (operandType (IC_RESULT (skipuic)), operandType (IC_RIGHT (skipuic)), false) != 1)
2554 /* Because of the type change, this assignment */
2555 /* is now really a cast, so make it official. */
2556 /* Later optimizeCastCast() will decide if this */
2557 /* is safe to remove completely. */
2558 skipuic->op = CAST;
2559 IC_LEFT (skipuic) = operandFromLink (copyLinkChain (operandType (IC_RESULT (skipuic))));
2561 change++;
2566 return change;
2569 /*-----------------------------------------------------------------*/
2570 /* Go back a chain of assignments / casts to try to find a string */
2571 /* literal symbol that op really is. */
2572 /*-----------------------------------------------------------------*/
2573 static symbol *findStrLitDef (operand *op, iCode **def)
2575 for(;;)
2577 if (!IS_ITEMP (op))
2578 return (0);
2580 if (bitVectnBitsOn (OP_DEFS (op)) != 1)
2581 return (0);
2583 iCode *dic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (op)));
2585 wassert (dic);
2587 if (dic->op == ADDRESS_OF)
2589 if (def)
2590 *def = dic;
2591 symbol *sym = OP_SYMBOL (IC_LEFT (dic));
2592 return (sym->isstrlit ? sym : 0);
2595 if (dic->op != '=' && dic->op != CAST)
2596 return (0);
2598 op = IC_RIGHT (dic);
2602 /*-----------------------------------------------------------------*/
2603 /* optimizeStdLibCall - optimize calls to standard library. */
2604 /* for now we just merge adjacent calls to puts() */
2605 /*-----------------------------------------------------------------*/
2606 static void
2607 optimizeStdLibCall (eBBlock ** ebbs, int count)
2609 iCode *ic, *nic, *ndic;
2610 symbol *strsym, *nstrsym, *cstrsym;
2611 sym_link *strlink, *nstrlink;
2612 size_t replacecost;
2614 for (int i = 0; i < count; i++)
2616 for (ic = ebbs[i]->sch; ic; ic = ic->next)
2618 // Look for call to puts().
2619 if (ic->op != CALL || !ic->prev || ic->prev->op != IPUSH && ic->prev->op != SEND)
2620 continue;
2621 if (!IS_SYMOP (ic->left) || strcmp (OP_SYMBOL (ic->left)->rname, "_puts"))
2622 continue;
2624 // Look for following call to puts().
2625 for (nic = ic->next; nic; nic = nic->next)
2627 if (nic->op == '=' && !POINTER_SET (ic) || nic->op == CAST)
2629 if (!IS_ITEMP (IC_RESULT (nic)))
2630 break;
2631 if (IS_OP_VOLATILE (IC_RIGHT (nic)))
2632 break;
2634 else if (nic->op == ADDRESS_OF)
2636 if (!IS_ITEMP (IC_RESULT (nic)))
2637 break;
2639 else if (nic->op == IPUSH || nic->op == SEND)
2641 if (IS_OP_VOLATILE (IC_LEFT (nic)))
2642 break;
2644 else // Todo: Handle more to make the optimization more general.
2645 break;
2647 if (!nic || nic->op != CALL || nic->prev->op != IPUSH && nic->prev->op != SEND)
2648 continue;
2649 if (!IS_SYMOP (nic->left) || strcmp (OP_SYMBOL (nic->left)->rname, "_puts"))
2650 continue;
2652 // Check that the return values are unused
2653 if (IC_RESULT (ic) && (!IS_ITEMP (IC_RESULT (ic)) || bitVectnBitsOn (OP_USES (IC_RESULT (ic)))))
2654 continue;
2655 if (IC_RESULT (nic) && (!IS_ITEMP (IC_RESULT (nic)) || bitVectnBitsOn (OP_USES (IC_RESULT (nic)))))
2656 continue;
2658 // Check that their parameters are string literals
2659 strsym = findStrLitDef (IC_LEFT (ic->prev), 0);
2660 nstrsym = findStrLitDef (IC_LEFT (nic->prev), &ndic);
2661 if (!strsym || !nstrsym)
2662 continue;
2663 strlink = strsym->etype;
2664 nstrlink = nstrsym->etype;
2666 // Calculate the cost of doing the replacement in bytes of string literal
2667 replacecost = 1; // For '\n'
2668 if (strsym->isstrlit > 1)
2669 replacecost += strlen (SPEC_CVAL (strlink).v_char);
2670 if (nstrsym->isstrlit > 1)
2671 replacecost += strlen (SPEC_CVAL (nstrlink).v_char);
2673 // Doing the replacement saves at least 6 bytes of call overhead (assuming pointers are 16 bits).
2674 if (replacecost > 7 - optimize.codeSize + 4 * optimize.codeSpeed)
2675 continue;
2677 // Combine strings
2678 struct dbuf_s dbuf;
2679 dbuf_init (&dbuf, 3);
2680 dbuf_append_str(&dbuf, SPEC_CVAL (strlink).v_char);
2681 dbuf_append_str(&dbuf, "\n");
2682 dbuf_append_str(&dbuf, SPEC_CVAL (nstrlink).v_char);
2683 cstrsym = stringToSymbol (rawStrVal (dbuf_c_str (&dbuf), dbuf_get_length (&dbuf) + 1))->sym;
2684 freeStringSymbol (nstrsym);
2685 dbuf_destroy (&dbuf);
2687 // Make second call print the combined string (which allows further optimization with subsequent calls)
2688 IC_LEFT (ndic)->key = cstrsym->key = ++operandKey;
2689 IC_LEFT (ndic)->svt.symOperand = cstrsym;
2691 // Change unused call to assignments to self to mark it for dead-code elimination.
2692 bitVectSetBit (OP_USES (IC_LEFT (ic->prev)), ic->key);
2693 bitVectSetBit (OP_DEFS (IC_LEFT (ic->prev)), ic->prev->key);
2694 ic->op = '=';
2695 IC_RESULT (ic) = IC_LEFT (ic->prev);
2696 IC_RIGHT (ic) = IC_LEFT (ic->prev);
2697 IC_LEFT (ic) = 0;
2698 ic->prev->op = '=';
2699 IC_RESULT (ic->prev) = IC_LEFT (ic->prev);
2700 IC_RIGHT (ic->prev) = IC_LEFT (ic->prev);
2701 IC_LEFT (ic->prev) = 0;
2706 /*-----------------------------------------------------------------*/
2707 /* optimizeCastCast - remove unneeded intermediate casts. */
2708 /* Integer promotion may cast (un)signed char to int and then */
2709 /* recast the int to (un)signed long. If the signedness of the */
2710 /* char and long are the same, the cast can be safely performed in */
2711 /* a single step. */
2712 /*-----------------------------------------------------------------*/
2713 static void
2714 optimizeCastCast (eBBlock **ebbs, int count)
2716 for (int i = 0; i < count; i++)
2718 for (iCode *ic = ebbs[i]->sch; ic; ic = ic->next)
2720 if ((ic->op == CAST || ic->op == '=' || ic->op == '+' || ic->op == ADDRESS_OF) && ic->result && IS_ITEMP (ic->result))
2722 sym_link *type1 = operandType ((ic->op == CAST || ic->op == '=')? ic->right : ic->left);
2723 sym_link *type2 = operandType (ic->result);
2725 /* There must be only one use of this first result */
2726 if (bitVectnBitsOn (OP_USES (ic->result)) != 1 ||
2727 bitVectnBitsOn (OP_DEFS (ic->result)) != 1)
2728 continue;
2730 iCode *uic = hTabItemWithKey (iCodehTab,
2731 bitVectFirstBit (OP_USES (ic->result)));
2732 if(!uic || !uic->result)
2733 continue;
2735 sym_link *type3 = operandType (uic->result);
2736 if (ic->op == ADDRESS_OF && uic->op == CAST &&
2737 IS_PTR (type2) && IS_PTR (type3) && getAddrspace (type2) == getAddrspace (type3) && sclsFromPtr (type2) == sclsFromPtr (type3) &&
2738 ic->next == uic)
2740 bitVectUnSetBit (OP_DEFS (ic->result), ic->key);
2741 IC_RESULT (ic) = IC_RESULT (uic);
2742 bitVectSetBit (OP_DEFS (ic->result), ic->key);
2743 unsetDefsAndUses (uic);
2744 remiCodeFromeBBlock (ebbs[i], uic);
2745 continue;
2747 else if (ic->op == '=' && !POINTER_SET(ic) && uic->op == CAST && ic->next == uic)
2749 if (IS_PTR (type1) && IS_PTR (type2))
2751 else if (IS_INTEGRAL (type1) && IS_INTEGRAL (type2) && SPEC_USIGN (type1) == SPEC_USIGN (type2))
2753 else // Sometimes we encounter weird assignments that change sign. E.g. signed char -> unsigned char -> int would break if we try to optimize.
2754 continue;
2755 bitVectUnSetBit (OP_USES (uic->right), uic->key);
2756 uic->right = ic->right;
2757 if (IS_SYMOP (uic->right))
2758 bitVectSetBit (OP_USES (uic->right), uic->key);
2759 unsetDefsAndUses (ic);
2760 remiCodeFromeBBlock (ebbs[i], ic);
2761 continue;
2763 else if (ic->op == CAST && IS_INTEGRAL (type1) && IS_INTEGRAL (type2) && IS_INTEGRAL (type3))
2765 int size1 = bitsForType (type1);
2766 int size2 = bitsForType (type2);
2767 if (size2 < size1)
2768 continue;
2769 /* If they are the same size, they must have the same signedness */
2770 if (size2 == size1 && SPEC_USIGN (type2) != SPEC_USIGN (type1))
2771 continue;
2773 /* Cast to bool must be preserved to ensure that all nonzero values are correctly cast to true */
2774 if (SPEC_NOUN (type2) == V_BOOL && SPEC_NOUN(type3) != V_BOOL)
2775 continue;
2776 /* Similarly for signed->unsigned->signed widening casts to ensure that negative values end up as nonnegative ones in the end. */
2777 if (!SPEC_USIGN (type1) && SPEC_USIGN (type2) && !SPEC_USIGN (type3) && bitsForType (type3) > bitsForType (type2))
2778 continue;
2780 /* Special case: Second use is a bit test */
2781 if (uic->op == BITWISEAND && IS_OP_LITERAL (uic->right) && ifxForOp (uic->result, uic))
2783 unsigned long long mask = operandLitValueUll (IC_RIGHT (uic));
2785 /* Signed cast might set bits above the width of type1 */
2786 if (!SPEC_USIGN (type1) && (mask >> (bitsForType (type1))))
2787 continue;
2789 IC_RIGHT (uic) = operandFromValue (valCastLiteral (type1, operandLitValue (uic->right), operandLitValue (uic->right)), false);
2791 else if (uic->op == CAST) /* Otherwise this use must be a second cast */
2793 /* It must be a cast to another integer type that */
2794 /* has no loss of bits */
2795 if (!IS_INTEGRAL (type3))
2796 continue;
2797 int size3 = bitsForType (type3);
2798 if (size3 < size1)
2799 continue;
2800 /* If they are the same size, they must have the same signedness */
2801 if (size3 == size2 && SPEC_USIGN (type3) != SPEC_USIGN (type2))
2802 continue;
2804 /* The signedness between the first and last types must match */
2805 if (SPEC_USIGN (type3) != SPEC_USIGN (type1))
2806 continue;
2808 else
2809 continue;
2811 else if (IS_PTR (type1) && IS_PTR (type2))
2813 if (ic->op == CAST && uic->op == CAST)
2815 else if(uic->op == '+' && IS_PTR(type3) &&
2816 getAddrspace (type1) == getAddrspace (type3) && sclsFromPtr (type1) == sclsFromPtr (type3) &&
2817 (ic->op == CAST || ic->op == '+' && IS_OP_LITERAL (ic->right) && IS_OP_LITERAL (uic->right)))
2819 if (ic->next == uic && isOperandEqual (ic->result, uic->left)) // Eliminate ic competely.
2821 bitVectUnSetBit (OP_USES (uic->left), uic->key);
2822 uic->left = ic->op == CAST ? ic->right : ic->left;
2823 bitVectSetBit (OP_USES (uic->left), uic->key);
2824 if (ic->op == '+')
2825 uic->right = operandFromValue (valPlus (valPlus (constIntVal ("0ll"), OP_VALUE (ic->right), false), OP_VALUE (uic->right), true), false);
2826 unsetDefsAndUses (ic);
2827 remiCodeFromeBBlock (ebbs[i], ic);
2828 continue;
2830 else if (ic->op == CAST)
2832 else
2833 continue;
2835 else if(ic->op == '+' && uic->op == CAST && IS_PTR(type3) &&
2836 getAddrspace (type1) == getAddrspace (type3) && sclsFromPtr (type1) == sclsFromPtr (type3))
2838 // Change cast to assignment, change pointer type at addition.
2839 uic->op = '=';
2840 uic->left = NULL;
2841 symbol *sym = OP_SYMBOL (ic->result);
2842 sym->type = copyLinkChain (type3);
2843 sym->etype = getSpec (sym->type);
2844 continue;
2846 else
2847 continue;
2849 else
2850 continue;
2853 /* Change the first cast to a simple assignment and */
2854 /* let the second cast do all the work */
2855 ic->op = '=';
2856 ic->left= NULL;
2858 symbol *sym = OP_SYMBOL (ic->result);
2859 sym->type = copyLinkChain (type1);
2860 sym->etype = getSpec (sym->type);
2866 /*-----------------------------------------------------------------*/
2867 /* optimizeFinalCast - remove unneeded intermediate casts. */
2868 /* Backends can handle wrong types onmany pointers in poiner write */
2869 /* and read. Exploit this to optimize out some casts. Typically */
2870 /* done late (i.e. just before register allocation). */
2871 /*-----------------------------------------------------------------*/
2872 static void
2873 optimizeFinalCast (ebbIndex *ebbi)
2875 // Apparently this triggers a bug in the mcs51 and ds390 backends.
2876 // Some regression tests fail, including gcc-torture-execute-pr38236;
2877 // looking into that one for -mmcs51 --model-small , register allocation
2878 // puts the result of a 16-bit read from e generic pointer into dptr,
2879 // which codegen can't handle (it genrated code where dpl is overwritten by
2880 // the lower byte of the result, then used as pointer once more).
2881 // This also triggers a pic16 bug resulting in invalid asm code being generated.
2882 if (TARGET_MCS51_LIKE || TARGET_IS_PIC16)
2883 return;
2885 for (int i = 0; i < ebbi->count; i++)
2887 eBBlock **ebbs = ebbi->bbOrder;
2888 eBBlock *ebp = ebbs[i];
2890 for (iCode *ic = ebp->sch; ic; ic = ic->next)
2892 if (ic->op != CAST || !IS_ITEMP (ic->result))
2893 continue;
2895 if (bitVectnBitsOn (OP_USES (ic->result)) != 1 || bitVectnBitsOn (OP_DEFS (ic->result)) != 1)
2896 continue;
2898 iCode *uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (ic->result)));
2899 if(!uic ||
2900 uic->op != GET_VALUE_AT_ADDRESS && !(POINTER_SET(uic) && !isOperandEqual (ic->result, uic->left) && !isOperandEqual (ic->result, uic->right) && (IS_ITEMP (ic->right) || IS_OP_LITERAL (ic->right))))
2901 continue;
2903 // For now only handle a use that follows immediately or nearly immediately.
2904 if (ic->next && ic->next->op != LABEL && !POINTER_SET(ic->next) &&
2905 (!IS_ITEMP (ic->right) || !bitVectBitValue (OP_DEFS (ic->right), ic->next->key)) &&
2906 uic == ic->next->next &&
2907 (!ic->next->result || IS_ITEMP (ic->next->result)))
2909 else if (uic != ic->next)
2910 continue;
2912 // Not all backends can handle multiple global operands in all operations well.
2913 if (IS_OP_GLOBAL (uic->result) && IS_OP_GLOBAL (ic->right) &&
2914 !TARGET_Z80_LIKE && !TARGET_IS_STM8 && !TARGET_IS_F8)
2915 continue;
2917 if (ic->op == CAST)
2919 sym_link *type1 = operandType (ic->right);
2920 sym_link *type2 = operandType (ic->left);
2922 if (IS_INTEGRAL (type1) && IS_INTEGRAL (type2) &&
2923 SPEC_NOUN (type1) == SPEC_NOUN (type2) && bitsForType (type1) == bitsForType (type2))
2925 else if (IS_PTR (type1) && IS_PTR (type2) &&
2926 sclsFromPtr (type1) == sclsFromPtr (type2) &&
2927 getAddrspace (type1) == getAddrspace (type2))
2929 else
2930 continue;
2932 if (!IS_PTR (type1) || IS_BITFIELD(type1->next) || !IS_PTR (type2) || IS_BITFIELD(type2->next))
2933 continue;
2936 // Introducinvg the duplicate smbol in the commented-out parts below would fix the type.
2937 // But the current backends won't propagate the rematerialization flag in their register allocators correctly if there are multiple symbols for the same iTemp.
2938 if (isOperandEqual (ic->result, uic->left))
2940 operand *op = operandFromOperand (ic->right);
2941 /*if (IS_SYMOP (op))
2943 symbol *sym = copySymbol (OP_SYMBOL(op));
2944 sym->type = copyLinkChain (operandType (uic->left));
2945 sym->etype = getSpec (sym->type);
2946 OP_SYMBOL (op) = sym;
2948 else
2949 setOperandType (op, operandType (uic->left));*/
2950 bitVectUnSetBit (OP_USES (uic->left), uic->key);
2951 uic->left = op;
2952 bitVectSetBit (OP_USES (uic->left), uic->key);
2954 if (isOperandEqual (ic->result, uic->right))
2956 operand *op = operandFromOperand (ic->right);
2957 /*if (IS_SYMOP (op))
2959 symbol *sym = copySymbol (OP_SYMBOL(op));
2960 sym->type = copyLinkChain (operandType (uic->right));
2961 sym->etype = getSpec (sym->type);
2962 OP_SYMBOL (op) = sym;
2964 else
2965 setOperandType (op, operandType (uic->right));*/
2966 bitVectUnSetBit (OP_USES (uic->right), uic->key);
2967 uic->right = op;
2968 bitVectSetBit (OP_USES (uic->right), uic->key);
2970 if (POINTER_SET (uic) && isOperandEqual (ic->result, uic->result))
2972 operand *op = operandFromOperand (ic->right);
2973 /*if (IS_SYMOP (op))
2975 symbol *sym = copySymbol (OP_SYMBOL(op));
2976 sym->type = copyLinkChain (operandType (uic->result));
2977 sym->etype = getSpec (sym->type);
2978 OP_SYMBOL (op) = sym;
2980 else
2981 setOperandType (op, operandType (uic->result));*/
2982 op->isaddr = uic->result->isaddr;
2983 bitVectUnSetBit (OP_USES (uic->result), uic->key);
2984 uic->result = op;
2985 bitVectSetBit (OP_USES (uic->result), uic->key);
2988 unsetDefsAndUses (ic);
2989 remiCodeFromeBBlock (ebp, ic);
2994 /*-----------------------------------------------------------------*/
2995 /* optimizeNegation - remove unneeded intermediate negation */
2996 /*-----------------------------------------------------------------*/
2997 static void
2998 optimizeNegation (eBBlock **ebbs, int count)
3000 int i;
3001 iCode *ic;
3002 iCode *uic;
3004 for (i = 0; i < count; i++)
3006 for (ic = ebbs[i]->sch; ic; ic = ic->next)
3008 if (ic->op == '!' && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
3010 /* There must be only one use of this first result */
3011 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
3012 continue;
3014 /* This use must be an ifx */
3015 uic = hTabItemWithKey (iCodehTab,
3016 bitVectFirstBit (OP_USES (IC_RESULT (ic))));
3017 if (!uic)
3018 continue;
3019 /* Todo: Optimize case where use is another negation */
3020 else if(uic->op == IFX) /* Remove negation by inverting jump targets */
3022 IC_LEFT (uic) = IC_LEFT (ic);
3023 IC_LEFT (ic) = 0;
3024 IC_RIGHT (ic) = IC_RESULT (ic);
3025 ic->op = '=';
3027 if (IC_TRUE (uic))
3029 IC_FALSE (uic) = IC_TRUE (uic);
3030 IC_TRUE (uic) = 0;
3032 else
3034 IC_TRUE (uic) = IC_FALSE (uic);
3035 IC_FALSE (uic) = 0;
3043 /* Fold pointer addition into offset of ADDRESS_OF. */
3044 static void
3045 offsetFoldGet (eBBlock **ebbs, int count)
3047 int i;
3048 iCode *ic;
3049 iCode *uic;
3051 if (!TARGET_Z80_LIKE && !TARGET_IS_STM8 && !TARGET_IS_F8)
3052 return;
3054 for (i = 0; i < count; i++)
3056 for (ic = ebbs[i]->sch; ic; ic = ic->next)
3058 if (ic->op == ADDRESS_OF && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
3060 /* There must be only one use of the result */
3061 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
3062 continue;
3064 /* This use must be an addition / subtraction */
3065 uic = hTabItemWithKey (iCodehTab,
3066 bitVectFirstBit (OP_USES (IC_RESULT (ic))));
3068 if (uic->op != '+' && uic->op != '-' || !IS_OP_LITERAL (IC_RIGHT (uic)))
3069 continue;
3071 /* Historically ADDRESS_OF didn't have a right operand */
3072 wassertl (IC_RIGHT (ic), "ADDRESS_OF without right operand");
3073 wassertl (IS_OP_LITERAL (IC_RIGHT (ic)), "ADDRESS_OF with non-literal right operand");
3075 bitVectUnSetBit (OP_SYMBOL (IC_RESULT (ic))->uses, uic->key);
3077 if (uic->op == '+')
3078 IC_RIGHT (uic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) + operandLitValue (IC_RIGHT (uic)));
3079 else
3080 IC_RIGHT (uic) = operandFromLit (operandLitValue (IC_RIGHT (ic)) - operandLitValue (IC_RIGHT (uic)));
3081 IC_LEFT (uic) = operandFromOperand (IC_LEFT(ic));
3082 uic->op = ADDRESS_OF;
3083 IC_LEFT (uic)->isaddr = 1;
3085 ic->op = '=';
3086 IC_RIGHT (ic) = IC_RESULT (ic);
3087 IC_LEFT (ic) = 0;
3088 SET_ISADDR (IC_RESULT (ic), 0);
3094 /* Fold pointer addition into offset of GET_VALUE_AT_ADDRESS. */
3095 /* The hc08-related ports do a similar thing in hc08/ralloc.c, packPointerOp() */
3096 static void
3097 offsetFoldUse (eBBlock **ebbs, int count)
3099 int i;
3100 iCode *ic;
3101 iCode *uic;
3103 if (!(TARGET_Z80_LIKE && !TARGET_IS_SM83) && !TARGET_IS_STM8 && !TARGET_IS_F8) // All z80-related targets except sm83 support non-zero right operand. stm8 also supports it.
3104 return;
3106 for (i = 0; i < count; i++)
3108 for (ic = ebbs[i]->sch; ic; ic = ic->next)
3110 if ((ic->op == '+' || ic->op == '-') && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)))
3112 if (!IS_OP_LITERAL (IC_RIGHT (ic)))
3113 continue;
3115 /* There must be only one use of the result */
3116 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) != 1)
3117 continue;
3119 /* This use must be a GET_VALUE_AT_ADDRESS */
3120 uic = hTabItemWithKey (iCodehTab,
3121 bitVectFirstBit (OP_USES (IC_RESULT (ic))));
3123 if (!POINTER_GET (uic))
3124 continue;
3126 /* Historically GET_VALUE_AT_ADDRESS didn't have a right operand */
3127 wassertl (IC_RIGHT (uic), "GET_VALUE_AT_ADDRESS without right operand");
3128 wassertl (IS_OP_LITERAL (IC_RIGHT (uic)), "GET_VALUE_AT_ADDRESS with non-literal right operand");
3130 if (ic->op == '+')
3131 IC_RIGHT (uic) = operandFromLit (operandLitValue (IC_RIGHT (uic)) + operandLitValue (IC_RIGHT (ic)));
3132 else
3133 IC_RIGHT (uic) = operandFromLit (operandLitValue (IC_RIGHT (uic)) - operandLitValue (IC_RIGHT (ic)));
3135 ic->op = '=';
3136 IC_RIGHT (ic) = IC_LEFT (ic);
3137 IC_LEFT (ic) = 0;
3138 SET_ISADDR (IC_RESULT (ic), 0);
3144 /*-----------------------------------------------------------------*/
3145 /* guessCounts - Guess execution counts for iCodes */
3146 /* Needs ic->seq assigned (typically done by computeLiveRanges() */
3147 /*-----------------------------------------------------------------*/
3148 void guessCounts (iCode *start_ic, ebbIndex *ebbi)
3150 iCode *ic;
3151 int i;
3152 bool needprop;
3154 for (ic = start_ic; ic; ic = ic->next)
3155 ic->count = 0;
3156 start_ic->pcount = 1.0f;
3157 needprop = TRUE;
3159 for(i = 0; needprop && i < 24; i++) // 24 is an arbitrary limit to reduce runtime at the cost of accuracy.
3161 needprop = FALSE;
3162 for (ic = start_ic; ic; ic = ic->next)
3164 if(ic->pcount <= 0.01) // 0.01 is an arbitrary limit to reduce runtime at the cost of accuracy.
3165 continue;
3167 ic->count += ic->pcount;
3169 if (ic->op == GOTO)
3171 iCode *target = hTabItemWithKey (labelDef, IC_LABEL (ic)->key);
3172 target->pcount += ic->pcount;
3173 needprop = TRUE;
3175 else if(ic->op == IFX) // Use a classic, simple branch prediction. Works well for typical loops.
3177 iCode *target = hTabItemWithKey (labelDef, (IC_TRUE (ic) ? IC_TRUE (ic) : IC_FALSE (ic))->key);
3178 if(target->seq >= ic->seq)
3180 target->pcount += ic->pcount / 4;
3181 if(ic->next)
3182 ic->next->pcount += ic->pcount * 3 / 4;
3184 else
3186 target->pcount += ic->pcount * 3 / 4;
3187 if(ic->next)
3188 ic->next->pcount += ic->pcount / 4;
3190 needprop = TRUE;
3192 else if(ic->op == JUMPTABLE)
3194 symbol *label;
3195 int n = elementsInSet (IC_JTLABELS (ic));
3197 for (label = setFirstItem (IC_JTLABELS (ic)); label; label = setNextItem (IC_JTLABELS (ic)))
3199 iCode *target = hTabItemWithKey (labelDef, label->key);
3200 target->pcount += ic->pcount / n;
3202 needprop = TRUE;
3204 else if(ic->op == CALL && IS_SYMOP (IC_LEFT (ic)) && IFFUNC_ISNORETURN (OP_SYMBOL (IC_LEFT (ic))->type))
3206 else if (ic->next)
3207 ic->next->pcount += ic->pcount;
3208 ic->pcount = 0.0f;
3213 /*-----------------------------------------------------------------*/
3214 /* narrowRead() - Will read fewer bytes by eliminating a downcast. */
3215 /*-----------------------------------------------------------------*/
3216 static int
3217 narrowRead (iCode *ic, operand **opp, eBBlock *ebp)
3219 iCode *dic;
3220 operand *op = *opp;
3222 if (ic->op != CAST || !IS_ITEMP (op))
3223 return 0;
3225 if (bitVectnBitsOn (OP_USES (op)) != 1 || bitVectnBitsOn (OP_DEFS (op)) != 1)
3226 return 0;
3228 // get the definition
3229 if (!(dic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_DEFS (op)))))
3230 return 0;
3232 // found the definition now check if it is local
3233 if (dic->seq < ebp->fSeq || dic->seq > ebp->lSeq)
3234 return 0;
3236 // for now handle pointer reads only
3237 if (dic->op != GET_VALUE_AT_ADDRESS || IS_VOLATILE (operandType (IC_LEFT (dic))->next))
3238 return 0;
3240 sym_link *resulttype = operandType (IC_RESULT (ic));
3241 sym_link *righttype = operandType (IC_RIGHT (ic));
3243 if (IS_BOOL (resulttype) || getSize (resulttype) >= getSize (righttype))
3244 return 0;
3246 // Narrow read
3247 if (!port->little_endian)
3249 int offset = getSize (righttype) - getSize (resulttype);
3250 IC_RIGHT (dic) = operandFromLit (operandLitValue (IC_RIGHT (dic)) + offset);
3252 OP_SYMBOL (IC_RESULT (dic))->type = resulttype;
3253 ic->op = '=';
3255 return 1;
3258 /*-----------------------------------------------------------------*/
3259 /* narrowReads() - Will read fewer bytes by eliminating downcasts. */
3260 /*-----------------------------------------------------------------*/
3261 static void
3262 narrowReads(ebbIndex *ebbi)
3264 for (int i = 0; i < ebbi->count; i++)
3266 eBBlock **ebbs = ebbi->bbOrder;
3267 eBBlock *ebp = ebbs[i];
3269 for (iCode *ic = ebp->sch; ic; ic = ic->next)
3270 if (ic->op == CAST)
3271 narrowRead (ic, &(IC_RIGHT (ic)), ebp);
3275 /*-----------------------------------------------------------------*/
3276 /* Remove redundant temporaries (leftover from other opts) */
3277 /*-----------------------------------------------------------------*/
3279 removeRedundantTemps (iCode *sic)
3281 int change = 0;
3282 for (iCode *ic = sic; ic; ic = ic->next)
3284 iCode *pic = ic->prev;
3285 if (!pic)
3286 continue;
3287 if (ic->op != '=' || POINTER_SET (ic) || !IS_ITEMP (IC_RESULT (ic)) || !IS_ITEMP (IC_RIGHT (ic)))
3288 continue;
3289 if (POINTER_SET (pic) || !isOperandEqual (IC_RESULT (pic), IC_RIGHT (ic)))
3290 continue;
3291 if (bitVectnBitsOn (OP_DEFS (IC_RIGHT (ic))) != 1)
3292 continue;
3293 if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic))) != 1)
3294 continue;
3295 if (compareType (operandType (IC_RESULT (ic)), operandType (IC_RIGHT (ic)), false) != 1)
3296 continue;
3297 if (IS_BITFIELD (operandType (IC_RESULT (pic))))
3298 continue;
3300 #if 0
3301 printf ("removeRedundantTemps: in %s optimized out ic %d: %s = %s\n", (currFunc ? currFunc->name : "NO_FUNCTION"), ic->key, OP_SYMBOL (IC_RESULT (ic))->name, OP_SYMBOL (IC_RIGHT (ic))->name);
3302 #endif
3304 bitVectUnSetBit (OP_DEFS (IC_RESULT (pic)), pic->key);
3305 IC_RESULT (pic) = IC_RESULT (ic);
3306 bitVectSetBit (OP_DEFS (IC_RESULT (pic)), pic->key);
3308 // Assignment to self will get optimized out later
3309 bitVectUnSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
3310 IC_RESULT (ic) = IC_RIGHT (ic);
3311 bitVectSetBit (OP_DEFS (IC_RESULT (ic)), ic->key);
3313 change++;
3315 return (change);
3318 /*-----------------------------------------------------------------*/
3319 /* checkRestartAtomic - try to prove that no restartable */
3320 /* atomics implementation is used from here. */
3321 /*-----------------------------------------------------------------*/
3322 void
3323 checkRestartAtomic (ebbIndex *ebbi)
3325 if (!currFunc)
3326 return;
3328 currFunc->funcRestartAtomicSupport = false;
3329 // if (!options.std_c11)
3330 // return;
3332 for (int i = 0; i < ebbi->count; i++)
3334 eBBlock **ebbs = ebbi->bbOrder;
3335 const eBBlock *ebp = ebbs[i];
3337 for (const iCode *ic = ebp->sch; ic; ic = ic->next)
3338 if (ic->op == CALL && !IS_OP_LITERAL (ic->left))
3339 currFunc->funcRestartAtomicSupport |= OP_SYMBOL(ic->left)->funcRestartAtomicSupport;
3340 else if (ic->op == CALL || ic->op == PCALL || ic->op == INLINEASM)
3341 currFunc->funcRestartAtomicSupport = true;
3345 /*-----------------------------------------------------------------*/
3346 /* eBBlockFromiCode - creates extended basic blocks from iCode */
3347 /* will return an array of eBBlock pointers */
3348 /*-----------------------------------------------------------------*/
3349 eBBlock **
3350 eBBlockFromiCode (iCode *ic)
3352 ebbIndex *ebbi = NULL;
3353 int change = 1;
3354 int lchange = 0;
3355 int kchange = 0;
3356 hTab *loops;
3358 /* if nothing passed then return nothing */
3359 if (!ic)
3360 return NULL;
3362 eBBNum = 0;
3364 /* optimize the chain for labels & gotos
3365 this will eliminate redundant labels and
3366 will change jump to jumps by jumps */
3367 ic = iCodeLabelOptimize (ic);
3369 /* break it down into basic blocks */
3370 ebbi = iCodeBreakDown (ic);
3371 /* hash the iCode keys so that we can quickly index */
3372 /* them in the rest of the optimization steps */
3373 setToNull ((void *) &iCodehTab);
3374 iCodehTab = newHashTable (iCodeKey);
3375 hashiCodeKeys (ebbi->bbOrder, ebbi->count);
3377 /* compute the control flow */
3378 computeControlFlow (ebbi);
3380 /* dumpraw if asked for */
3381 if (options.dump_i_code)
3382 dumpEbbsToFileExt (DUMP_RAW0, ebbi);
3384 /* replace the local variables with their
3385 register equivalents : the liveRange computation
3386 along with the register allocation will determine
3387 if it finally stays in the registers */
3388 replaceRegEqv (ebbi);
3390 /* create loop regions */
3391 loops = createLoopRegions (ebbi);
3393 /* dumpraw if asked for */
3394 if (options.dump_i_code)
3395 dumpEbbsToFileExt (DUMP_RAW1, ebbi);
3397 if (!optimize.noStdLibCall)
3398 optimizeStdLibCall (ebbi->bbOrder, ebbi->count);
3400 optimizeCastCast (ebbi->bbOrder, ebbi->count);
3401 while (optimizeOpWidth (ebbi->bbOrder, ebbi->count))
3402 optimizeCastCast (ebbi->bbOrder, ebbi->count);
3403 optimizeNegation (ebbi->bbOrder, ebbi->count);
3405 /* Burn the corpses, so the dead may rest in peace,
3406 safe from cse necromancy */
3407 computeDataFlow (ebbi);
3408 killDeadCode (ebbi);
3410 /* do common subexpression elimination for each block */
3411 change = cseAllBlocks (ebbi, FALSE);
3413 /* dumpraw if asked for */
3414 if (options.dump_i_code)
3415 dumpEbbsToFileExt (DUMP_CSE, ebbi);
3417 // optimizeCastCast (ebbi->bbOrder, ebbi->count); TODO: Enable after fixing GCSE issue. GCSE messes up some pointer types, triggered by this, resulting in the bitfields.c test failing for some targets.
3419 /* compute the data flow */
3420 computeDataFlow (ebbi);
3422 /* dumpraw if asked for */
3423 if (options.dump_i_code)
3424 dumpEbbsToFileExt (DUMP_DFLOW, ebbi);
3426 /* global common subexpression elimination */
3427 if (optimize.global_cse)
3429 change += cseAllBlocks (ebbi, FALSE);
3430 if (options.dump_i_code)
3431 dumpEbbsToFileExt (DUMP_GCSE, ebbi);
3433 else
3435 // compute the dataflow only
3436 assert(cseAllBlocks (ebbi, TRUE)==0);
3439 /* kill dead code */
3440 kchange = killDeadCode (ebbi);
3442 if (options.dump_i_code)
3443 dumpEbbsToFileExt (DUMP_DEADCODE, ebbi);
3445 // We want to eliminate some unnecessary short-lived temporaries now -
3446 // Before they will get lifted out of loops, and have their life-ranges
3447 // extended across multiple blocks.
3448 optimizeCastCast (ebbi->bbOrder, ebbi->count);
3450 /* do loop optimizations */
3451 change += (lchange = loopOptimizations (loops, ebbi));
3452 if (options.dump_i_code)
3453 dumpEbbsToFileExt (DUMP_LOOP, ebbi);
3455 /* recompute the data flow and apply global cse again
3456 if loops optimizations or dead code caused a change:
3457 loops will brings out of the loop which then may be
3458 available for use in the later blocks: dead code
3459 elimination could potentially disconnect some blocks
3460 conditional flow may be efected so we need to apply
3461 subexpression once more */
3462 if (lchange || kchange)
3464 computeDataFlow (ebbi);
3465 change += cseAllBlocks (ebbi, FALSE);
3466 if (options.dump_i_code)
3467 dumpEbbsToFileExt (DUMP_LOOPG, ebbi);
3469 /* if loop optimizations caused a change then do
3470 dead code elimination once more : this will
3471 get rid of the extra assignments to the induction
3472 variables created during loop optimizations */
3473 killDeadCode (ebbi);
3475 if (options.dump_i_code)
3476 dumpEbbsToFileExt (DUMP_LOOPD, ebbi);
3479 offsetFoldGet (ebbi->bbOrder, ebbi->count);
3480 optimizeCastCast (ebbi->bbOrder, ebbi->count);
3481 computeControlFlow (ebbi);
3482 loops = createLoopRegions (ebbi);
3483 computeDataFlow (ebbi);
3484 computeLiveRanges (ebbi->bbOrder, ebbi->count, true);
3486 // Generalized constant propagation - do it here a first time before the first call to computeLiveRanges to ensure uninitalized variables are still recognized as such.
3487 if (optimize.genconstprop)
3489 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3490 recomputeValinfos (ic, ebbi, "_0");
3491 optimizeValinfo (ic);
3492 freeeBBlockData (ebbi);
3493 ebbi = iCodeBreakDown (ic);
3494 computeControlFlow (ebbi);
3495 loops = createLoopRegions (ebbi);
3496 computeDataFlow (ebbi);
3499 // lospre
3500 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, false);
3501 while (optimizeOpWidth (ebbi->bbOrder, ebbi->count))
3502 optimizeCastCast (ebbi->bbOrder, ebbi->count);
3503 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, false); // Recompute again before killing dead code, since dead code elimination needs updated ic->seq - the old ones might have been invalidated in optimizeOpWidth above.
3504 killDeadCode (ebbi); // Ensure lospre doesn't resurrect dead code.
3505 adjustIChain (ebbi->bbOrder, ebbi->count);
3506 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3507 shortenLiveRanges (ic, ebbi);
3508 guessCounts (ic, ebbi);
3509 if (optimize.lospre && (TARGET_Z80_LIKE || TARGET_HC08_LIKE || TARGET_IS_STM8 || TARGET_IS_F8)) /* For mcs51, we get a code size regression with lospre enabled, since the backend can't deal well with the added temporaries */
3511 lospre (ic, ebbi);
3512 if (options.dump_i_code)
3513 dumpEbbsToFileExt (DUMP_LOSPRE, ebbi);
3515 /* GCSE, lospre and maybe other optimizations sometimes create temporaries that have non-connected live ranges, which is bad (e.g. for offsetFoldUse and register allocation). Split them. */
3516 freeeBBlockData (ebbi);
3517 ebbi = iCodeBreakDown (ic);
3518 computeControlFlow (ebbi);
3519 loops = createLoopRegions (ebbi);
3520 computeDataFlow (ebbi);
3521 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, false);
3522 adjustIChain (ebbi->bbOrder, ebbi->count);
3523 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3524 separateLiveRanges (ic, ebbi);
3527 removeRedundantTemps (ic); // Remove some now-redundant leftovers iTemps that can confuse later optimizations.
3529 /* Break down again and redo some steps to not confuse live range analysis later. */
3530 freeeBBlockData (ebbi);
3531 ebbi = iCodeBreakDown (ic);
3532 computeControlFlow (ebbi);
3533 loops = createLoopRegions (ebbi);
3534 computeDataFlow (ebbi);
3535 killDeadCode (ebbi);
3536 offsetFoldUse (ebbi->bbOrder, ebbi->count);
3537 killDeadCode (ebbi);
3539 /* sort it back by block number */
3540 //qsort (ebbs, saveCount, sizeof (eBBlock *), bbNumCompare);
3542 /* enforce restrictions on acesses to named address spaces */
3543 separateAddressSpaces (ebbi->bbOrder, ebbi->count);
3545 /* insert bank switching instructions. Do it here, before the
3546 other support routines, since we can assume that there is no
3547 bank switching happening in those other support routines
3548 (but assume that it can happen in other functions) */
3549 adjustIChain (ebbi->bbOrder, ebbi->count);
3550 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3551 if (!currFunc || switchAddressSpacesOptimally (ic, ebbi))
3552 switchAddressSpaces (ic); /* Fallback. Very unlikely to be triggered, unless --max-allocs-per-node is set to very small values or very weird control-flow graphs */
3554 /* Break down again and redo some steps to not confuse live range analysis. */
3555 freeeBBlockData (ebbi);
3556 ebbi = iCodeBreakDown (ic);
3557 computeControlFlow (ebbi);
3558 loops = createLoopRegions (ebbi);
3559 computeDataFlow (ebbi);
3561 if (!options.lessPedantic)
3563 // this is a good place to check missing return values
3564 if (currFunc)
3566 // the user is on his own with naked functions...
3567 if (!IS_VOID(currFunc->etype) && !FUNC_ISNAKED(currFunc->type))
3569 eBBlock *bp;
3570 // make sure all predecessors of the last block end in a return
3571 for (bp=setFirstItem(ebbi->bbOrder[ebbi->count-1]->predList);
3573 bp=setNextItem(ebbi->bbOrder[ebbi->count-1]->predList))
3575 if (bp->ech->op != RETURN)
3577 werrorfl (bp->ech->filename, bp->ech->lineno, W_VOID_FUNC, currFunc->name);
3584 /* if cyclomatic info requested then print it */
3585 if (options.cyclomatic)
3586 printCyclomatic (ebbi->bbOrder, ebbi->count);
3588 /* convert operations with support routines
3589 written in C to function calls : I am doing
3590 this at this point since I want all the
3591 operations to be as they are for optimizations */
3592 convertToFcall (ebbi->bbOrder, ebbi->count);
3593 adjustIChain (ebbi->bbOrder, ebbi->count); // Fix ebb->sch pointers potentially messed up by convertToFcall.
3595 /* miscellaneous optimizations */
3596 miscOpt (ebbi->bbOrder, ebbi->count);
3598 // Generalized constant propagation - second time.
3599 if (optimize.genconstprop)
3601 computeControlFlow (ebbi);
3602 loops = createLoopRegions (ebbi);
3603 computeDataFlow (ebbi);
3604 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, false);
3605 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3606 recomputeValinfos (ic, ebbi, "_1");
3607 optimizeValinfo (ic);
3608 freeeBBlockData (ebbi);
3609 ebbi = iCodeBreakDown (ic);
3610 computeControlFlow (ebbi);
3611 loops = createLoopRegions (ebbi);
3612 computeDataFlow (ebbi);
3613 killDeadCode (ebbi);
3614 if (options.dump_i_code)
3615 dumpEbbsToFileExt (DUMP_GENCONSTPROP, ebbi);
3618 optimizeFinalCast (ebbi);
3620 /* Split any live-ranges that became non-connected in dead code elimination. */
3621 change = 0;
3624 adjustIChain (ebbi->bbOrder, ebbi->count);
3625 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, false);
3626 ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbi->bbOrder, ebbi->count));
3627 change = separateLiveRanges (ic, ebbi);
3628 removeRedundantTemps (ic); // Remove some now-redundant leftovers iTemps that can confuse later optimizations.
3629 freeeBBlockData (ebbi);
3630 ebbi = iCodeBreakDown (ic);
3631 computeControlFlow (ebbi);
3632 loops = createLoopRegions (ebbi);
3633 computeDataFlow (ebbi);
3634 killDeadCode (ebbi); /* iCodeLabelOptimize() above might result in dead code, when both branches of an ifx go to the same destination. */
3636 while (change);
3638 /* compute the live ranges */
3639 recomputeLiveRanges (ebbi->bbOrder, ebbi->count, true);
3641 if (options.dump_i_code)
3642 dumpEbbsToFileExt (DUMP_RANGE, ebbi);
3644 /* Now that we have the live ranges, discard parameter
3645 * receives for unused parameters.
3647 discardDeadParamReceives (ebbi->bbOrder, ebbi->count);
3649 narrowReads (ebbi);
3651 checkRestartAtomic (ebbi);
3653 /* allocate registers & generate code */
3654 if (!options.syntax_only)
3655 port->assignRegisters (ebbi);
3657 /* throw away blocks */
3658 setToNull ((void *) &graphEdges);
3659 freeeBBlockData (ebbi);
3661 return NULL;