You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
;; Replace the call-as-datum with the return-values.
(cleavir-bir:replace-uses phi ucall-out)))
dummy-block))
(if (eq return-point :unknown)
:unknown
(cleavir-bir:iblock return-point))))
Here, contify only recognizes two situations. Either there are multiple calls, and the results of the call (if used) are fed into a shared phi; or, there is only one call, and the return point is the successor of the call. If the return point is the beginning of an iblock, it assumes that it is in the former situation. In this situation, in order to communicate the return values of the inlined function, that iblock's phi, assumed to be the shared results, is used.
However, it is possible to contrive things so that the return point is the beginning of an iblock even if there is only one call, and in a way such that the results of the call are actually needed. Here is the smallest example I could come up with, reduced from clasp-developers/clasp#1181:
For this code, the results of the call to cdr (which is inlined) are used in the final return value. However, the immediate successor of the call, after catch reduction, is a jump to G27058, and the return-point is then the first instruction in that iblock. This "tricks" the contifier into thinking it does not need to create a new iblock/phi. Then when it tries to delete the call, it finds that the call is still used, and the assertion in the delete function ((EVERY CLEAVIR-BIR:UNUSED-P (CLEAVIR-BIR:OUTPUTS CLEAVIR-BIR:INSTRUCTION))) fails.
The text was updated successfully, but these errors were encountered:
The above characterization misses the fact that there are also tail recursive calls. A better way to put it would be that this is sort of a consequence of not having strict CPS. We have some calls that are in a similar form - they're immediately followed by a phi using their values, as from (if x (foo y) (foo z)). But we have some calls that are instead in the middle of blocks and have their values used directly. These need different approaches since we have to turn the latter case into the former case, but the way we distinguish the cases is wrong since a call in the second form can still be immediately succeeded by a jump that doesn't use its value.
Cleavir/BIR-transformations/interpolate-function.lisp
Lines 239 to 260 in 38b03b7
Here, contify only recognizes two situations. Either there are multiple calls, and the results of the call (if used) are fed into a shared phi; or, there is only one call, and the return point is the successor of the call. If the return point is the beginning of an iblock, it assumes that it is in the former situation. In this situation, in order to communicate the return values of the inlined function, that iblock's phi, assumed to be the shared results, is used.
However, it is possible to contrive things so that the return point is the beginning of an iblock even if there is only one call, and in a way such that the results of the call are actually needed. Here is the smallest example I could come up with, reduced from clasp-developers/clasp#1181:
For this code, the results of the call to
cdr
(which is inlined) are used in the final return value. However, the immediate successor of the call, after catch reduction, is a jump to G27058, and the return-point is then the first instruction in that iblock. This "tricks" the contifier into thinking it does not need to create a new iblock/phi. Then when it tries to delete the call, it finds that the call is still used, and the assertion in the delete function ((EVERY CLEAVIR-BIR:UNUSED-P (CLEAVIR-BIR:OUTPUTS CLEAVIR-BIR:INSTRUCTION))
) fails.The text was updated successfully, but these errors were encountered: