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
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 -------------------------------------------------------------------------*/
31 #include "dbuf_string.h"
33 /*-----------------------------------------------------------------*/
34 /* global variables */
40 /*-----------------------------------------------------------------*/
41 /* printSymName - prints the symbol names */
42 /*-----------------------------------------------------------------*/
44 printSymName (void *vsym
)
47 fprintf (stdout
, " %s ", sym
->name
);
51 /*-----------------------------------------------------------------*/
52 /* cnvToFcall - does the actual conversion to function call */
53 /*-----------------------------------------------------------------*/
55 cnvToFcall (iCode
* ic
, eBBlock
* ebp
)
62 char *filename
= ic
->filename
;
63 int lineno
= ic
->lineno
;
66 ip
= ic
->next
; /* insertion point */
67 /* remove it from the iCode */
68 unsetDefsAndUses (ic
);
69 remiCodeFromeBBlock (ebp
, ic
);
72 right
= IC_RIGHT (ic
);
74 if (IS_FLOAT (operandType (right
)))
101 operand
*tmp
= right
;
109 else if (IS_FIXED16X16 (operandType (right
)))
138 func
= fps16x16_lteq
;
141 func
= fps16x16_gteq
;
146 /* if float support routines NOT compiled as reentrant */
147 if (!options
.float_rent
)
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
);
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
;
166 OP_USES (left
) = bitVectSetBit (OP_USES (left
), newic
->key
);
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
);
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
);
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
);
196 newic
= newiCode (IPUSH
, right
, NULL
);
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
);
216 newic
= newiCode (IPUSH
, left
, NULL
);
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
;
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
;
237 FUNC_HASFCALL (currFunc
->type
) = 1;
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 /*-----------------------------------------------------------------*/
262 cnvToFloatCast (iCode
* ic
, eBBlock
* ebp
)
266 sym_link
*type
= copyLinkChain (operandType (IC_RIGHT (ic
)));
267 SPEC_SHORT (type
) = 0;
268 int linenno
= ic
->lineno
;
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
];
290 if (compareType (type
, fixed16x16Type
, false) == 1)
292 func
= fp16x16conv
[0][4][0];
296 if (IS_BOOLEAN (type
))
298 wassert(multypes
[0][1] == UCHARTYPE
);
299 func
= conv
[0][0][1];
306 /* if float support routines NOT compiled as reentrant */
307 if (!options
.float_rent
)
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
);
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
);
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
);
337 newic
= newiCode (IPUSH
, IC_RIGHT (ic
), NULL
);
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
);
350 newic
= newiCode (CALL
, operandFromSymbol (func
, false), NULL
);
351 IC_RESULT (newic
) = IC_RESULT (ic
);
352 newic
->parmBytes
+=bytesPushed
;
355 FUNC_HASFCALL (currFunc
->type
) = 1;
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 /*----------------------------------------------------------------------*/
384 cnvToFixed16x16Cast (iCode
* ic
, eBBlock
* ebp
)
388 sym_link
*type
= copyLinkChain (operandType (IC_RIGHT (ic
)));
389 SPEC_SHORT (type
) = 0;
390 int linenno
= ic
->lineno
;
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
];
414 /* if float support routines NOT compiled as reentrant */
415 if (!options
.float_rent
)
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
);
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
);
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
);
445 newic
= newiCode (IPUSH
, IC_RIGHT (ic
), NULL
);
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
);
458 newic
= newiCode (CALL
, operandFromSymbol (func
, false), NULL
);
459 IC_RESULT (newic
) = IC_RESULT (ic
);
460 newic
->parmBytes
+=bytesPushed
;
463 FUNC_HASFCALL (currFunc
->type
) = 1;
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 /*-----------------------------------------------------------------*/
492 cnvFromFloatCast (iCode
* ic
, eBBlock
* ebp
)
496 sym_link
*type
= copyLinkChain (operandType (IC_LEFT (ic
)));
497 SPEC_SHORT (type
) = 0;
498 char *filename
= ic
->filename
;
499 int lineno
= ic
->lineno
;
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
];
523 /* if float support routines NOT compiled as reentrant */
524 if (!options
.float_rent
)
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
);
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
);
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
);
554 newic
= newiCode (IPUSH
, IC_RIGHT (ic
), NULL
);
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
);
567 newic
= newiCode (CALL
, operandFromSymbol (func
, false), NULL
);
568 IC_RESULT (newic
) = IC_RESULT (ic
);
569 newic
->parmBytes
+=bytesPushed
;
572 FUNC_HASFCALL (currFunc
->type
) = 1;
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 /*--------------------------------------------------------------------------*/
601 cnvFromFixed16x16Cast (iCode
* ic
, eBBlock
* ebp
)
605 sym_link
*type
= copyLinkChain (operandType (IC_LEFT (ic
)));
606 SPEC_SHORT (type
) = 0;
607 char *filename
= ic
->filename
;
608 int lineno
= ic
->lineno
;
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
];
630 if (compareType (type
, floatType
, false) == 1)
632 func
= fp16x16conv
[1][4][0];
639 /* if float support routines NOT compiled as reentrant */
640 if (!options
.float_rent
)
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
);
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
);
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
);
670 newic
= newiCode (IPUSH
, IC_RIGHT (ic
), NULL
);
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
);
683 newic
= newiCode (CALL
, operandFromSymbol (func
, false), NULL
);
684 IC_RESULT (newic
) = IC_RESULT (ic
);
685 newic
->parmBytes
+=bytesPushed
;
688 FUNC_HASFCALL (currFunc
->type
) = 1;
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 */
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
;
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 */
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 /*-----------------------------------------------------------------*/
772 convilong (iCode
*ic
, eBBlock
*ebp
)
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
)))))
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
);
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.
810 iCode
*ip
= ic
->next
;
812 char *filename
= ic
->filename
;
813 int lineno
= ic
->lineno
;
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;
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
)))
846 OP_SYMBOL (left
)->type
= newIntLink ();
849 ic
->left
= operandFromValue (valCastLiteral (newIntLink(), operandLitValue (left
), operandLitValue (left
)), false);
854 OP_SYMBOL (right
)->type
= newIntLink ();
857 ic
->right
= operandFromValue (valCastLiteral (newIntLink(), operandLitValue (right
), operandLitValue (right
)), false);
859 if (func
) // Use 16x16->32 support function
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
)))
883 if (getSize (operandType (IC_RIGHT (lic
))) == 4)
885 OP_SYMBOL (left
)->type
= newLongLink ();
886 SPEC_USIGN (OP_SYMBOL (left
)->type
) = 1;
889 ic
->left
= operandFromValue (valCastLiteral (newIntLink(), operandLitValue (left
), operandLitValue (left
)), false);
894 OP_SYMBOL (right
)->type
= newCharLink ();
895 SPEC_USIGN (OP_SYMBOL (left
)->type
) = 1;
898 ic
->right
= operandFromValue (valCastLiteral (newIntLink(), operandLitValue (right
), operandLitValue (right
)), false);
900 if (func
) // Use 32x8->64 support function
908 if (getSize (leftType
) == 1 && getSize (rightType
) == 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
];
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)
946 printf ("leftType: "); printTypeChain (leftType
, 0);
947 printf ("rightType: "); printTypeChain (rightType
, 0);
948 printf ("multypes[bwd][su]: "); printTypeChain (multypes
[bwd
][su
], 0);
953 func
= muldiv
[0][bwd
][su
];
955 func
= muldiv
[1][bwd
][su
];
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
);
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");
978 // Update left and right - they might have changed due to inserted casts.
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
)
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
);
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
);
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
);
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
);
1025 /* compiled as reentrant then push */
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
);
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
);
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
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 /*-----------------------------------------------------------------*/
1102 convbuiltin (iCode
*const ic
, eBBlock
*ebp
)
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
)
1118 if (!IS_SYMOP (IC_LEFT(icc
)))
1121 ftype
= operandType (IC_LEFT(icc
));
1122 if (!IFFUNC_ISBUILTIN (ftype
))
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"));
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")))
1146 strcpy(OP_SYMBOL (IC_LEFT (icc
))->rname
, !strcmp (bif
->name
, "__builtin_memcpy") ? "___memcpy" : (!strcmp (bif
->name
, "__builtin_strncpy") ? "_strncpy" : "_memset"));
1153 /* Convert parameter passings from SEND to PUSH. */
1156 for (icc
= ic
, args
= FUNC_ARGS (nonbuiltin_memcpy
->type
); icc
->op
!= CALL
; icc
= icc
->next
, args
= args
->next
)
1159 icc
->builtinSEND
= 0;
1160 if (IS_REGPARM (args
->etype
))
1162 icc
->argreg
= SPEC_ARGREG (args
->etype
);
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
;
1184 icp
->next
= icc
->prev
;
1187 for(; icc
!= icp
; ico
= icc
, icc
= icc
->prev
)
1189 if (icc
->op
!= CALL
)
1194 /*-----------------------------------------------------------------*/
1195 /* convconvention - handle calling convention */
1196 /*-----------------------------------------------------------------*/
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
)
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
)
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
;
1226 icp
->next
= icc
->prev
;
1228 ebp
->sch
= icc
->prev
;
1231 for (; icc
!= icp
; ico
= icc
, icc
= icc
->prev
)
1233 if (icc
->op
!= CALL
&& icc
->op
!= PCALL
)
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 /*-----------------------------------------------------------------*/
1251 convertToFcall (eBBlock
** ebbs
, int count
)
1255 /* for all blocks do */
1256 for (i
= 0; i
< count
; i
++)
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 */
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
;
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
))))
1303 unsigned long litVal
= double2ul (operandLitValue (IC_RIGHT (ic
)));
1305 /* modulo by 1: no remainder */
1308 detachiCodeOperand (&ic
->left
, ic
);
1310 IC_RIGHT (ic
) = operandFromLit (0);
1313 // See if literal value is a power of 2.
1314 while (litVal
&& !(litVal
& 1))
1320 // discard lowest set bit.
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
1336 attachiCodeOperand (IC_RESULT (dic
), &IC_RIGHT (dic
), dic
);
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)
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
);
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 */
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 /*-----------------------------------------------------------------*/
1405 isPowerOf2 (unsigned long val
)
1407 while (val
&& !(val
& 1))
1414 /*-----------------------------------------------------------------*/
1415 /* miscOpt - miscellaneous optimizations */
1416 /*-----------------------------------------------------------------*/
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 */
1425 /* for all blocks do */
1426 for (i
= 0; i
< count
; ++i
)
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.
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
;
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
;
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
;
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
);
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 /*-----------------------------------------------------------------*/
1516 separateAddressSpaces (eBBlock
**ebbs
, int count
)
1520 /* for all blocks do */
1521 for (i
= 0; i
< count
; ++i
)
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
)
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
)
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
);
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
);
1570 resultaddrspace
= getAddrspace (OP_SYMBOL (result
)->type
);
1575 printf("ic %d (dcl? %d) leftaddrspace %s\n", ic
->key
, (int)(IS_DECL (OP_SYMBOL (left
)->type
)), leftaddrspace
->name
);
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
);
1582 if (ic
->op
== IPUSH
&& leftaddrspace
)
1586 source
= OP_SYMBOL (left
);
1587 newic
= newiCode ('=', 0, left
);
1588 IC_RESULT (newic
) = newop
= newiTempOperand (source
->type
, 0);
1589 IC_LEFT (ic
) = newop
;
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
)
1599 if (rightaddrspace
== resultaddrspace
)
1600 source
= OP_SYMBOL (left
);
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
;
1612 IC_RIGHT (ic
) = newop
;
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
);
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
);
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
);
1665 resultaddrspace
= getAddrspace (OP_SYMBOL (result
)->type
);
1668 addrspace
= leftaddrspace
;
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
;
1683 /*-----------------------------------------------------------------*/
1684 /* switchAddressSpaceAt - insert a bank selection instruction */
1685 /*-----------------------------------------------------------------*/
1687 switchAddressSpaceAt (iCode
*ic
, const symbol
*const addrspace
)
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
;
1700 newic
->prev
= ic
->prev
;
1702 ic
->prev
->next
= 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 /*-----------------------------------------------------------------*/
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
)
1733 /*-----------------------------------------------------------------*/
1734 /* isLocalWithoutDef - return 1 if sym might be used without a */
1735 /* defining iCode */
1736 /*-----------------------------------------------------------------*/
1738 isLocalWithoutDef (symbol
* sym
)
1743 if (IS_VOLATILE (sym
->type
))
1749 if (IS_AGGREGATE (sym
->type
))
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
;
1770 else if (OP_REQV (op
))
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. */
1779 OP_DEFS (nop
) = bitVectCopy (OP_DEFS (op
));
1781 OP_USES (nop
) = bitVectCopy (OP_USES (op
));
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 /*-----------------------------------------------------------------*/
1794 replaceRegEqv (ebbIndex
*ebbi
)
1796 eBBlock
** ebbs
= ebbi
->bbOrder
;
1797 int count
= ebbi
->count
;
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
++)
1806 if (ebbs
[i
]->noPath
)
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));
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
++)
1855 if (ebbs
[i
]->noPath
)
1858 for (ic
= ebbs
[i
]->sch
; ic
; ic
= ic
->next
)
1863 if (ic
->op
== RECEIVE
)
1865 if (OP_SYMBOL (IC_RESULT (ic
))->addrtaken
)
1866 OP_SYMBOL (IC_RESULT (ic
))->isspilt
= 1;
1870 if (IS_TRUE_SYMOP (IC_RESULT (ic
)))
1872 if (POINTER_SET (ic
))
1873 replaceRegEqvOperand (ic
, &IC_RESULT (ic
), 1, 1);
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 /*-----------------------------------------------------------------*/
1889 findReqv (symbol
* prereqv
, eBBlock
** ebbs
, int count
)
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
);
1915 /*-----------------------------------------------------------------*/
1916 /* killDeadCode - eliminates dead assignments */
1917 /*-----------------------------------------------------------------*/
1919 killDeadCode (ebbIndex
* ebbi
)
1921 eBBlock
** ebbs
= ebbi
->dfOrder
;
1922 int count
= ebbi
->count
;
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 */
1939 /* this whole process is carried on iteratively till no change */
1943 /* for all blocks do */
1944 for (i
= 0; i
< count
; i
++)
1948 /* for all instructions in the block do */
1949 for (ic
= ebbs
[i
]->sch
; ic
; ic
= ic
->next
)
1954 if (SKIP_IC (ic
) && ic
->op
!= RECEIVE
||
1957 ic
->op
== DUMMY_READ_VOLATILE
||
1958 ic
->op
== CRITICAL
||
1959 ic
->op
== ENDCRITICAL
)
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 */
1966 /* if the result is volatile then continue */
1967 if (IC_RESULT (ic
) && isOperandVolatile (IC_RESULT (ic
), FALSE
))
1970 /* if the result is a temp & isaddr then skip */
1971 if (IC_RESULT (ic
) && POINTER_SET (ic
))
1974 /* if the results address has been taken then skip */
1975 if (IS_SYMOP (IC_RESULT (ic
)) && OP_SYMBOL (IC_RESULT (ic
))->addrtaken
)
1978 if (POINTER_GET (ic
) && IS_VOLATILE (operandType (IC_LEFT (ic
))->next
)
1979 && !SPIL_LOC (IC_RESULT (ic
)))
1982 /* if the result is used in the remainder of the */
1983 /* block then skip */
1984 if (usedInRemaining (IC_RESULT (ic
), ic
->next
))
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 */
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
))
2000 /* if we are sure there are no usages */
2001 if (bitVectIsZero (OP_USES (IC_RESULT (ic
))))
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
))
2018 /* kill this one if required */
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
)
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
)))
2036 if (isOperandEqual (IC_RIGHT(ic
), IC_LEFT(ic
->next
))
2037 || isOperandEqual (IC_RIGHT(ic
), IC_RIGHT(ic
->next
)))
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
;
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
))
2076 IC_RESULT (ic
) = NULL
;
2077 newreqv
= findReqv (prereqv
, ebbs
, count
);
2080 prereqv
->reqv
= newreqv
;
2085 /* delete the result */
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 */
2098 IC_LEFT (ic
) = NULL
;
2100 IC_RIGHT (ic
) = NULL
;
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 */
2126 /*-----------------------------------------------------------------*/
2127 /* printCyclomatic - prints the cyclomatic information */
2128 /*-----------------------------------------------------------------*/
2130 printCyclomatic (eBBlock
** ebbs
, int count
)
2132 int nEdges
= elementsInSet (graphEdges
);
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 /*-----------------------------------------------------------------*/
2147 discardDeadParamReceives (eBBlock
** ebbs
, int count
)
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
)
2163 fprintf (stderr
, "discarding dead receive for %s\n",
2164 OP_SYMBOL (IC_RESULT (ic
))->name
);
2166 dummyIcode
.next
= ic
->next
;
2167 remiCodeFromeBBlock (ebbs
[i
], ic
);
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 /*-----------------------------------------------------------------*/
2181 optimizeOpWidth (eBBlock
** ebbs
, int count
)
2186 iCode
*uic
, *skipuic
;
2187 sym_link
*nextresulttype
;
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;
2202 if (ic
->op
!= LABEL
|| !ic
->next
)
2205 label
= IC_LABEL (ic
);
2208 if (ic
->op
!= '<' || !IS_ITEMP (IC_LEFT (ic
)) || bitVectnBitsOn (OP_DEFS (IC_LEFT (ic
))) != 2)
2211 oldcountertype
= operandType (IC_LEFT (ic
));
2212 if (IS_VOLATILE (oldcountertype
))
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
)))
2220 ifx
= ifxForOp (IC_RESULT (ic
), ic
);
2222 if (!ifx
|| IC_TRUE (ifx
) || i
+ 1 >= count
)
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
)
2233 (uic
->op
== CALL
|| uic
->op
== PCALL
|| uic
->op
== IFX
|| uic
->op
== LABEL
||
2234 uic
->op
== GOTO
&& IC_LABEL (uic
) != label
|| uic
->op
== INLINEASM
))
2241 // TODO: Proceed despite obstacle, but only consider array accesses before obstacle.
2242 if (obstacle
|| !uic
|| uic
->op
!= GOTO
|| IC_LABEL (uic
) != label
)
2245 const bitVect
*uses
;
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
);
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);
2266 if (uic
->op
== '+' && IS_OP_LITERAL (IC_RIGHT (uic
)) && operandLitValue (IC_RIGHT (uic
)) == 1 && isOperandEqual (IC_LEFT (uic
), IC_LEFT (ic
)))
2272 if (uic
->op
!= CAST
&& uic
->op
!= '=' && uic
->op
!= '+' && uic
->op
!= '*' && uic
->op
!= '-' && uic
->op
!= LEFT_OP
&& uic
->op
!= RIGHT_OP
&& uic
->op
!= '<')
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
))));
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);
2295 prevresult
= IC_RESULT (uic
);
2296 uic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_USES (IC_RESULT (uic
))));
2302 // Use as array index?
2303 if (uic
->op
== GET_VALUE_AT_ADDRESS
|| POINTER_SET(uic
) && isOperandEqual (IC_RESULT (uic
), prevresult
))
2307 mul
= mul_candidate
;
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
)
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
)
2332 if (uic
->op
== CAST
)
2334 if (uic
->key
== ic
->key
)
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.
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
))
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)
2386 uic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_USES (IC_RESULT (ic
))));
2391 /* Skip over assignment */
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)
2398 uic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_USES (IC_RESULT (uic
))));
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)
2409 const bitVect
*uses
;
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
))))
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;
2436 if (uic
->op
!= CAST
&& uic
->op
!= '+' && uic
->op
!= LEFT_OP
&& uic
->op
!= RIGHT_OP
)
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
)))
2447 shiftbits
= (int) operandLitValue (IC_RIGHT (ic
));
2448 resultbits
= bitsForType (operandType (IC_RESULT (uic
)));
2450 if (resultbits
+ shiftbits
> 16)
2452 else if (resultbits
+ shiftbits
> 8)
2453 nextresulttype
= newIntLink ();
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
)))
2467 nextresulttype
= newCharLink ();
2471 nextresulttype
= operandType (IC_RESULT (uic
));
2472 if (!IS_INTEGRAL (nextresulttype
) && !(IS_PTR (nextresulttype
) && NEARPTRSIZE
== 2))
2475 if (IS_PTR (nextresulttype
))
2477 nextresulttype
= newIntLink ();
2478 SPEC_USIGN (nextresulttype
) = 1;
2482 nextresulttype
= copyLinkChain (nextresulttype
);
2486 nextresultsize
= bitsForType (nextresulttype
);
2487 if (nextresultsize
>= resultsize
)
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
))
2494 /* Make op result narrower */
2495 sym
= OP_SYMBOL (IC_RESULT (ic
));
2496 sym
->type
= nextresulttype
;
2498 /* Insert casts on operands */
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
);
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
)
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. */
2559 IC_LEFT (skipuic
) = operandFromLink (copyLinkChain (operandType (IC_RESULT (skipuic
))));
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
)
2580 if (bitVectnBitsOn (OP_DEFS (op
)) != 1)
2583 iCode
*dic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_DEFS (op
)));
2587 if (dic
->op
== ADDRESS_OF
)
2591 symbol
*sym
= OP_SYMBOL (IC_LEFT (dic
));
2592 return (sym
->isstrlit
? sym
: 0);
2595 if (dic
->op
!= '=' && dic
->op
!= CAST
)
2598 op
= IC_RIGHT (dic
);
2602 /*-----------------------------------------------------------------*/
2603 /* optimizeStdLibCall - optimize calls to standard library. */
2604 /* for now we just merge adjacent calls to puts() */
2605 /*-----------------------------------------------------------------*/
2607 optimizeStdLibCall (eBBlock
** ebbs
, int count
)
2609 iCode
*ic
, *nic
, *ndic
;
2610 symbol
*strsym
, *nstrsym
, *cstrsym
;
2611 sym_link
*strlink
, *nstrlink
;
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
)
2621 if (!IS_SYMOP (ic
->left
) || strcmp (OP_SYMBOL (ic
->left
)->rname
, "_puts"))
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
)))
2631 if (IS_OP_VOLATILE (IC_RIGHT (nic
)))
2634 else if (nic
->op
== ADDRESS_OF
)
2636 if (!IS_ITEMP (IC_RESULT (nic
)))
2639 else if (nic
->op
== IPUSH
|| nic
->op
== SEND
)
2641 if (IS_OP_VOLATILE (IC_LEFT (nic
)))
2644 else // Todo: Handle more to make the optimization more general.
2647 if (!nic
|| nic
->op
!= CALL
|| nic
->prev
->op
!= IPUSH
&& nic
->prev
->op
!= SEND
)
2649 if (!IS_SYMOP (nic
->left
) || strcmp (OP_SYMBOL (nic
->left
)->rname
, "_puts"))
2652 // Check that the return values are unused
2653 if (IC_RESULT (ic
) && (!IS_ITEMP (IC_RESULT (ic
)) || bitVectnBitsOn (OP_USES (IC_RESULT (ic
)))))
2655 if (IC_RESULT (nic
) && (!IS_ITEMP (IC_RESULT (nic
)) || bitVectnBitsOn (OP_USES (IC_RESULT (nic
)))))
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
)
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
)
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
);
2695 IC_RESULT (ic
) = IC_LEFT (ic
->prev
);
2696 IC_RIGHT (ic
) = IC_LEFT (ic
->prev
);
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 /*-----------------------------------------------------------------*/
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)
2730 iCode
*uic
= hTabItemWithKey (iCodehTab
,
2731 bitVectFirstBit (OP_USES (ic
->result
)));
2732 if(!uic
|| !uic
->result
)
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
) &&
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
);
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.
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
);
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
);
2769 /* If they are the same size, they must have the same signedness */
2770 if (size2
== size1
&& SPEC_USIGN (type2
) != SPEC_USIGN (type1
))
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
)
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
))
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
))))
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
))
2797 int size3
= bitsForType (type3
);
2800 /* If they are the same size, they must have the same signedness */
2801 if (size3
== size2
&& SPEC_USIGN (type3
) != SPEC_USIGN (type2
))
2804 /* The signedness between the first and last types must match */
2805 if (SPEC_USIGN (type3
) != SPEC_USIGN (type1
))
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
);
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
);
2830 else if (ic
->op
== CAST
)
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.
2841 symbol
*sym
= OP_SYMBOL (ic
->result
);
2842 sym
->type
= copyLinkChain (type3
);
2843 sym
->etype
= getSpec (sym
->type
);
2853 /* Change the first cast to a simple assignment and */
2854 /* let the second cast do all the work */
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 /*-----------------------------------------------------------------*/
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
)
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
))
2895 if (bitVectnBitsOn (OP_USES (ic
->result
)) != 1 || bitVectnBitsOn (OP_DEFS (ic
->result
)) != 1)
2898 iCode
*uic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_USES (ic
->result
)));
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
))))
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
)
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
)
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
))
2932 if (!IS_PTR (type1
) || IS_BITFIELD(type1
->next
) || !IS_PTR (type2
) || IS_BITFIELD(type2
->next
))
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;
2949 setOperandType (op, operandType (uic->left));*/
2950 bitVectUnSetBit (OP_USES (uic
->left
), uic
->key
);
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;
2965 setOperandType (op, operandType (uic->right));*/
2966 bitVectUnSetBit (OP_USES (uic
->right
), uic
->key
);
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;
2981 setOperandType (op, operandType (uic->result));*/
2982 op
->isaddr
= uic
->result
->isaddr
;
2983 bitVectUnSetBit (OP_USES (uic
->result
), uic
->key
);
2985 bitVectSetBit (OP_USES (uic
->result
), uic
->key
);
2988 unsetDefsAndUses (ic
);
2989 remiCodeFromeBBlock (ebp
, ic
);
2994 /*-----------------------------------------------------------------*/
2995 /* optimizeNegation - remove unneeded intermediate negation */
2996 /*-----------------------------------------------------------------*/
2998 optimizeNegation (eBBlock
**ebbs
, int count
)
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)
3014 /* This use must be an ifx */
3015 uic
= hTabItemWithKey (iCodehTab
,
3016 bitVectFirstBit (OP_USES (IC_RESULT (ic
))));
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
);
3024 IC_RIGHT (ic
) = IC_RESULT (ic
);
3029 IC_FALSE (uic
) = IC_TRUE (uic
);
3034 IC_TRUE (uic
) = IC_FALSE (uic
);
3043 /* Fold pointer addition into offset of ADDRESS_OF. */
3045 offsetFoldGet (eBBlock
**ebbs
, int count
)
3051 if (!TARGET_Z80_LIKE
&& !TARGET_IS_STM8
&& !TARGET_IS_F8
)
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)
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
)))
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
);
3078 IC_RIGHT (uic
) = operandFromLit (operandLitValue (IC_RIGHT (ic
)) + operandLitValue (IC_RIGHT (uic
)));
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;
3086 IC_RIGHT (ic
) = IC_RESULT (ic
);
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() */
3097 offsetFoldUse (eBBlock
**ebbs
, int count
)
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.
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
)))
3115 /* There must be only one use of the result */
3116 if (bitVectnBitsOn (OP_USES (IC_RESULT (ic
))) != 1)
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
))
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");
3131 IC_RIGHT (uic
) = operandFromLit (operandLitValue (IC_RIGHT (uic
)) + operandLitValue (IC_RIGHT (ic
)));
3133 IC_RIGHT (uic
) = operandFromLit (operandLitValue (IC_RIGHT (uic
)) - operandLitValue (IC_RIGHT (ic
)));
3136 IC_RIGHT (ic
) = IC_LEFT (ic
);
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
)
3154 for (ic
= start_ic
; ic
; ic
= ic
->next
)
3156 start_ic
->pcount
= 1.0f
;
3159 for(i
= 0; needprop
&& i
< 24; i
++) // 24 is an arbitrary limit to reduce runtime at the cost of accuracy.
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.
3167 ic
->count
+= ic
->pcount
;
3171 iCode
*target
= hTabItemWithKey (labelDef
, IC_LABEL (ic
)->key
);
3172 target
->pcount
+= ic
->pcount
;
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;
3182 ic
->next
->pcount
+= ic
->pcount
* 3 / 4;
3186 target
->pcount
+= ic
->pcount
* 3 / 4;
3188 ic
->next
->pcount
+= ic
->pcount
/ 4;
3192 else if(ic
->op
== JUMPTABLE
)
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
;
3204 else if(ic
->op
== CALL
&& IS_SYMOP (IC_LEFT (ic
)) && IFFUNC_ISNORETURN (OP_SYMBOL (IC_LEFT (ic
))->type
))
3207 ic
->next
->pcount
+= ic
->pcount
;
3213 /*-----------------------------------------------------------------*/
3214 /* narrowRead() - Will read fewer bytes by eliminating a downcast. */
3215 /*-----------------------------------------------------------------*/
3217 narrowRead (iCode
*ic
, operand
**opp
, eBBlock
*ebp
)
3222 if (ic
->op
!= CAST
|| !IS_ITEMP (op
))
3225 if (bitVectnBitsOn (OP_USES (op
)) != 1 || bitVectnBitsOn (OP_DEFS (op
)) != 1)
3228 // get the definition
3229 if (!(dic
= hTabItemWithKey (iCodehTab
, bitVectFirstBit (OP_DEFS (op
)))))
3232 // found the definition now check if it is local
3233 if (dic
->seq
< ebp
->fSeq
|| dic
->seq
> ebp
->lSeq
)
3236 // for now handle pointer reads only
3237 if (dic
->op
!= GET_VALUE_AT_ADDRESS
|| IS_VOLATILE (operandType (IC_LEFT (dic
))->next
))
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
))
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
;
3258 /*-----------------------------------------------------------------*/
3259 /* narrowReads() - Will read fewer bytes by eliminating downcasts. */
3260 /*-----------------------------------------------------------------*/
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
)
3271 narrowRead (ic
, &(IC_RIGHT (ic
)), ebp
);
3275 /*-----------------------------------------------------------------*/
3276 /* Remove redundant temporaries (leftover from other opts) */
3277 /*-----------------------------------------------------------------*/
3279 removeRedundantTemps (iCode
*sic
)
3282 for (iCode
*ic
= sic
; ic
; ic
= ic
->next
)
3284 iCode
*pic
= ic
->prev
;
3287 if (ic
->op
!= '=' || POINTER_SET (ic
) || !IS_ITEMP (IC_RESULT (ic
)) || !IS_ITEMP (IC_RIGHT (ic
)))
3289 if (POINTER_SET (pic
) || !isOperandEqual (IC_RESULT (pic
), IC_RIGHT (ic
)))
3291 if (bitVectnBitsOn (OP_DEFS (IC_RIGHT (ic
))) != 1)
3293 if (bitVectnBitsOn (OP_USES (IC_RIGHT (ic
))) != 1)
3295 if (compareType (operandType (IC_RESULT (ic
)), operandType (IC_RIGHT (ic
)), false) != 1)
3297 if (IS_BITFIELD (operandType (IC_RESULT (pic
))))
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
);
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
);
3318 /*-----------------------------------------------------------------*/
3319 /* checkRestartAtomic - try to prove that no restartable */
3320 /* atomics implementation is used from here. */
3321 /*-----------------------------------------------------------------*/
3323 checkRestartAtomic (ebbIndex
*ebbi
)
3328 currFunc
->funcRestartAtomicSupport
= false;
3329 // if (!options.std_c11)
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 /*-----------------------------------------------------------------*/
3350 eBBlockFromiCode (iCode
*ic
)
3352 ebbIndex
*ebbi
= NULL
;
3358 /* if nothing passed then return nothing */
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
);
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
);
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 */
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
3566 // the user is on his own with naked functions...
3567 if (!IS_VOID(currFunc
->etype
) && !FUNC_ISNAKED(currFunc
->type
))
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. */
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. */
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
);
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
);