new SSA IL
Matthew Fluet
mfluet@intertrust.com
Tue, 7 Aug 2001 22:01:55 -0700 (PDT)
> * Should the common Var.t vector be lifted out of Exp.t and Transfer.t?
> It would save syntax tree space, but you lose a little bit of compile-time
> checking (like Select only taking one arg). I lean very slightly towards
> not lifting.
I'm not sure what you mean by this. I think there are enough variantes in
Exp.t and Transfer.t that don't require a Var.t vector.
> * What should be done about case branches and value carrying constructors?
> Should we stick with the current scheme, in which all selects are done
> implicitly by the case, or go back to the old scheme, in which the case just
> narrows the value and there is a separate ConSelect expression? I lean
> towards leaving as is, and revisiting the issue after the conversion is
> complete.
I agree that leaving it as is would be the right first step.
> * Should we create separate classes of labels, Handler.t and Cont.t?
> If we did this, SetHandler would now take a Handler and nontail Call would
> take a Cont. This would give the necessary hooks to the backend for
> generating the wrapper blocks, but I'm not sure if it helps anywhere else. I
> lean against doing this.
The backend is already infering where the wrapper blocks are needed. On
the other hand, if you look at the machine IL in the live-stack-slots
branch, you'll see that I am starting to make these distinctions more
explicit. They are even more explicit in the pseudo-x86 IL of the new
codegen.
The only other place that I think it helps is in know where and how to
break blocks up. In the unusedArgs pass, I introduce wrapper functions
that essentially separate the Handler or Cont label from the Jump block.
If we really made the separation explicity, then I would argue that there
are really three types of blocks: Jump blocks, Handler blocks, and Cont
blocks. Handler and Cont blocks should just immediately jump to a Jump
block (dropping and/or shuffling args as necessary). Of course, you've
got a similar issue with Case labels -- mabye there are DeCon blocks as
well. Anyways, this seems awfully complicated, so I'm not advocating it.
> structure Function:
> sig
> datatype t =
> T of {
> name: Func.t,
> args: (Var.t * Type.t) vector,
> start: Label.t, (* Must be nullary. *)
> blocks: Block.t vector,
> returns: Type.t vector
> }
> end
I like the start label. Related to my complaints about the common block
elimination, the fact that there are decs and a transfer that aren't under
a Jump.t can be kind of annoying sometimes. It also nicely allows us to
rewrite non-tail calls to self as Goto's, which is something that requires
a little hackery in backend.fun (and even more under the new codegen,
where the kind of transfer is more important).