Single Static Assignment Optimization
Introduction
In compiler design, static single assignment form (often abbreviated as SSA form or SSA) is an intermediate representation (IR) in which every variable is assigned exactly once.
An SSA-based compiler modifies the program representation so that every time a variable is assigned in the original program, a new version of the variable is created.
A new version of the variable is distinguished (renamed) by subscripting the variable name with its version number or an index, so that every definition of each variable in a program becomes unique.
At a joining point of the control flow graph where two or more different definitions of a variable meet, a hypothetical function called a phi-function is inserted so that these multiple definitions are merged.
In mikroBasic PRO for dsPIC, SSA's main goal is in allocating local variables into the RX space (instead onto the frame).
To do that, SSA has to make an alias and data flow analysis of the Control Flow Graph.
Besides these savings, there are a number of compiler optimization algorithms enhanced by the use of SSA, like :
- Constant Propagation
- Dead Code Elimination
- Global Value Numbering
- Register Allocation
Changes that SSA brings is also in the way in which routine parameters are passed. When the SSA is enabled, parameters are passed through a part of the RX space which is reserved exclusively for this purpose (W10-W13 for dsPIC).
Allocating local variables and parameters in RX space has its true meaning for those architectures with hardware frame.
Enabling SSA optimization in compiler is done by checking box from the Output Settings Menu.
Lets consider a trivial case :
program Example sub procedure SSA_Test(dim y as integer, dim k as integer) if (y+k) then asm nop end asm end if end sub main: SSA_Test(5,5) end.
With SSA enabled, sub procedure SSA_Test
this example is consisted of 3 asm instructions :
;Example.mbas,29 :: if (y+k) then 0x0100 0x45000B ADD W10, W11, W0 0x0102 0x320001 BRA Z L__SSA_Test2 L__SSA_Test6: ;Example.mbas,31 :: nop 0x0104 0x000000 NOP
Without SSA enabled, sub procedure SSA_Test
this example is consisted of 5 asm instructions :
;Example.mbas,29 :: if (y+k) then 0x0102 0x97B8CE MOV [W14-8], W1 0x0104 0x57006A SUB W14, #10, W0 0x0106 0x408010 ADD W1, [W0], W0 0x0108 0x320001 BRA Z L__SSA_Test2 L__SSA_Test6: ;Example.mbas,31 :: nop 0x010A 0x000000 NOP
Proper Coding Recommendations
To get the maximum out of the SSA, user should regard the following rules during the coding process :
- Routines should not contain too many parameters (not more than 4 words).
- Don't change the value of the parameter in the function body (it is better to use a new local variable).
- If the
function1
parameters are passed asfunction2
parameters, then parameter order should remain the same :sub procedure f2(dim a as integer, dim b as integer) end sub sub procedure f1(dim x as integer, dim y as integer) ' routine call f2(x,y) ' x->a and y->b (1 to 1 and 2 to 2) is far more efficient than : f2(y,x) ' y->a and x->b (1 to 2 and 2 to 1) end sub
- Large amount of nested loops and complex structures as its members should be avoided.
- When writing a code in assembly, keep in mind that there are registers reserved exclusively for routine parameters.
- Using
goto
andlabel
statements in nested loops should be avoided. - Obtaining address of the local variable with the global pointer and using it to alter the variable's address should be avoided.

mcl
files compiled with or without SSA enabled are fully compatible and can be used and mixed without any restrictions, except pointers to functions.- Functions, functions declarations and pointers that may point to these functions must be compiled with the same option, either SSA enabled or disabled. If this is not the case, compiler will report an error.
Asm code and SSA optimization
If converting code from an earlier version of the compiler, which consists of mixed asm code with the Basic code, keep in mind that the generated code can substantially differ when SSA optimization option is enabled or disabled.
This is due to the fact that SSA optimization uses certain working registers to store routine parameters (W10-W13), rather than storing them onto the function frame.
Because of this, user must be very careful when writing asm code as existing values in the working registers used by SSA optimization can be overwritten.
To avoid this, it is recommended that user includes desired asm code in a separate routine.
Debugging Notes
SSA also influences the code debugging in such a way that the local variables will be available in the Watch Window
only in those parts of the procedure where they have useful value (eg. on entering the procedure, variable isn't available until its definition).
Variables can be allocated in one part of the procedure in register W4, and in another part of the procedure in register W2, if the optimizer estimates that it is better that way.
That means that the local variable has no static address.
Warning Messages Enhancement
Besides the smaller code, SSA also deals with the intensive code analysis, which in turn has the consequence in enhancing the warning messages.
For example, compiler will warn the user that the uninitialized variable is used :
sub procedure SSA_Test() dim y as char if (y) then ' Variable y might not have been initialized asm nop end asm end if end sub main: SSA_Test() end.
What do you think about this topic ? Send us feedback!