Skip to content

SSA is upon us... #33

@pfalcon

Description

@pfalcon

So, I pushed initial support for conversion to SSA, e.g. tests: 72a047e . To remind, I wanted to postpone introduction of SSA, to not fall into common trap when people treat as some magic device, without good understanding of the frontier where it really becomes needed, how to deal with it, what drawbacks it has, etc.

All this time I (in the background) pumped up my understanding and well, now I hoped I grasped the essence of its construction, that the one true SSA is the maximal SSA, its construction is simple and devoid of any arcane knowledge, and any other form is nothing but implementation-level optimizations, and they're thus strictly optional.

Going beyond construction is definitely on next TODOs, but first syntax for phi functions need to be set. How it's done currently (examples above) is in a textbook way, where phi just takes list of values, in the same order as predecessors (and that order is of course stable in ScratchABlock, partly exactly because of anticipation of phi() introduction).

That should work pretty well for intermediate output, but of course barely suitable as input, where predecessors aren't so explicit, and their order shouldn't have to be clear/stable either. And the input case is of course important (interoperability with LLVM is definitely on the table).

So, there're two facets of it:

  1. External syntax, i.e. how it's rendered in PseudoC source program.
    This can be as simple as normal C fuction syntax, e.g. phi(label1, $r0_1, label2, $r0_2), or something fancier, e.g. phi(label1: $r0_1, label2: $r0_2). Of course, something fancier is definitely not compatible with C syntax, and staying within its bounds is the aim of PseudoC. But then phi() is not an executable function, so having not a C syntax is somehow not completely crazy idea.
  2. Internal syntax, i.e. should there be bblock addresses retained as arguments of phi's EXPR, or not? Common sense says it's superfluous, because in internal representation, there's no ambiguity. But perhaps as a debugging measure still may be useful?

For reference, LLVM's syntax:

%indvar = phi i32 [ 0, %LoopHeader ], [ %nextindvar, %Loop ]

That order of bblock addr vs value I don't like. The most important thing in phi is not value, but the fact that it depends on predecessor block, so it would rather go first.

$indvar = phi(LoopHeader, 0, Loop, $nextindvar)
$indvar = phi(LoopHeader: 0, Loop: $nextindvar)

Well, to make it more C-like, and still preserve pair-ness, could do:

$indvar = phi((LoopHeader, 0), (Loop, $nextindvar))

Well, that's still not really a valid C syntax. Then could do:

$indvar = phi(_(LoopHeader, 0), _(Loop, $nextindvar))

But that's really going down the rabbit hole...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions