Should all be non-breaking. Most of these changes are in the depths of type inference: reorganizations, but more importantly added tracking of values types. This preserves type information through M->F and F->M and allows extraction of it near return instructions; this should be helpful later on for inter-function optimization.
There are two new transforms. One doesn't use inference and just find explicit NIL returns and changes them to funcall-no-return to clean up the instruction graph. The other turns multiple-value-call where the numbers of values are known into M->F and funcall. Ideally this should help avoid unknown-values returns lower down.
Higher up I added a primop and AST, VALUES, for inlining calls to cl:values. Basically
Should all be non-breaking. Most of these changes are in the depths of type inference: reorganizations, but more importantly added tracking of values types. This preserves type information through M->F and F->M and allows extraction of it near return instructions; this should be helpful later on for inter-function optimization.
There are two new transforms. One doesn't use inference and just find explicit NIL returns and changes them to funcall-no-return to clean up the instruction graph. The other turns multiple-value-call where the numbers of values are known into M->F and funcall. Ideally this should help avoid unknown-values returns lower down.
Higher up I added a primop and AST, VALUES, for inlining calls to cl:values. Basically
and explicit calls will compile into an F->M instead of a funcall. Again, helps inference.