Mindcode allows you to alter some compiler options in the source code using special #set
commands.
The basic syntax is:
#set option = value;
Some of these options can be alternatively specified as parameters of the command line compiler.
Supported compiler options are described below.
Use the target
option to specify the Mindcode version:
#set target = ML6;
Possible values for this option are:
ML6
: compile for Mindcode Logic version 6ML7S
: compile for Mindcode Logic version 7 standard processorsML7W
: compile for Mindcode Logic version 7 world processorML7AS
: compile for Mindcode Logic version 7 (revision A) standard processorsML7AW
: compile for Mindcode Logic version 7 (revision A) world processorML8AS
: compile for Mindcode Logic version 8 (revision A) standard processorsML8AW
: compile for Mindcode Logic version 8 (revision A) world processor
This option controls the way remarks, generated through the remark() function,
are propagated to the compiled code. Remarks are written into the compiled code as print
instructions. Possible values
of the remarks
option are:
none
: remarks are suppressed in the compiled code - they do not appear there at all.passive
: remarks are included in the compiled code, but a jump is generated in front each block of continuous remarks, so that the print statement themselves aren't executed. This is the default value.active
: remarks are included in the compiled code and are executed, producing actual output to the text buffer.
Passive remarks can be used for putting instructions or comments in the compiled code, or to mark a specific portion of the code. Remarks in a loop may help identifying individual iterations when the loop is unrolled, for example.
Active remarks can be used to easily add debugging output to a program that can be deactivated using a compiler option (potentially through a command line switch without modifying the source code).
Use the goal
option to specify whether Mindcode should prefer to generate smaller code, or faster code.
Possible values are:
size
: Mindcode tries to generate smaller code.speed
: Mindcode can generate additional instructions, if it makes the resulting code faster while adhering to the 1000 instructions limit. When several possible optimizations of this kind are available, the ones having the best effect (highest speedup per additional instruction generated) are selected until the instruction limit is reached.auto
: the default value. At this moment the setting is identical tospeed
.
The Vars screen of the Mindustry processor shows all variables and their values, but the variables are displayed in the order in which they were created. This typically results in a very chaotic order of variables, where variables defined by the user are mixed with temporary variables, making it quite difficult to find a specific variable in sufficiently large programs.
This option can be used to make variables be displayed in a Mindustry processor in a well-defined order. Mindcode compiler ensures that by prepending a special block at the beginning of the program which creates user-defined variables in a specific order without altering their value. (The packcolor
instruction is used, which can read - and therefore create - up to four variables per instruction. The result is not stored anywhere so that the variable-ordering code block doesn't change values of any variables, and therefore the behavior of the program remains unaltered, except for possible difference in timing.)
The value assigned to the sort-variables directive is a list of variable categories:
linked
: variables representing linked blocks,params
: variables representing program parameters,globals
: global variables,main
: main variables,locals
: local variables,all
: user variables that aren't matched by any other specified category,none
: no variables at all. Can be used as a#set sort-variables=none;
, ensuring that no variable ordering will be performed.
It is possible to use the directive without specifying any value at all (#set sort-variables;
). In this case, the categories will be processed in the order above.
When processing the directive, the categories are processed in the given order, with all variables in a category sorted alphabetically. This defines the resulting order of variables.
Note on the linked
category: when a block is linked into the processor, a variable of that name is removed from the variable list. By putting the linked
variables first, it is very easy to see which linked blocks used by the program are not linked under their proper names.
The number of variables being sorted is limited by the instruction limit. Should the resulting program size exceeds the instruction limit, some or all variables will remain unordered.
This option has been added to support future enhancements of Mindcode. Setting the option doesn't have any effect at this moment.
This option allows to change the instruction limit used by speed optimization. The speed optimization strives not to exceed this instruction limit. In some cases, the optimization cost estimates are too conservative - some optimizations applied together may lead to code reductions that are not known to individual optimizers considering each optimization in isolation. In these cases, increasing the instruction limit might allow more optimizations to be performed. When the resulting code exceeds 1000 instructions, it is not usable in Mindustry processors and the option should be decreased or set back to 1000. (A new feature, which would perform this trial-and-error optimization automatically, is planned.)
The limit only affects the optimization for speed. The option has no effect on code generated by the compiler or optimizers which do not work in the speed optimization mode, and doesn't help reduce the code size generated outside the optimization for speed mechanism.
It is also possible to decrease the instruction limit, if you wish so. The valid range for this compiler option is 1 to 100,000 for the command-line tool, and 1 to 1,500 for the web application.
Important
Setting the limit to a very high value can have severe impact on the performance of the compiler. High values of the instruction limit might cause the code compilation to take minutes or even hours to complete.
Use the optimization
option to set the optimization level of the compiler:
#set optimization = basic;
Possible values for this option are:
none
basic
advanced
experimental
The none
setting deactivates all optimizations. The basic
setting performs most of the available optimizations.
The advanced
optimizations performs all the available optimizations, even those that might take more time, or
which make changes that are potentially risky or make understanding of the resulting mlog code more difficult.
The experimental
level is used for new optimizations that are still being evaluated, or for optimizations that might alter the meaning of existing code. Optimizations performed on the experimental level will typically be migrated to advanced or basic levels eventually.
The default optimization level for the web application compiler is basic
, for the command line compiler it is
advanced
.
Use the passes
option to set the maximum number of optimization passes to be done:
#set passes = 10;
The default value is 3 for the web application and 25 for the command line tool. The number of optimization passes can be limited to a value between 1 and 1000 (inclusive).
A more complex code can usually benefit from more optimization passes. On the other hand, each optimization pass can take some time to complete. Limiting the total number can prevent optimization from taking too much time or consuming too many resources (this is a consideration for the web application).
It is possible to set the level of individual optimization tasks. Every optimization is assigned a name, and this name can be used in the compiler directive like this:
#set dead-code-elimination = advanced;
Not all optimizations support the advanced
level. For those the level advanced
is the same as basic
.
The complete list of available optimizations, including the option name for setting the level of given optimization
and availability of the advanced optimization level is:
Optimization | Option name | Advanced |
---|---|---|
Temporary Variables Elimination | temp-variables-elimination | N |
Case Expression Optimization | case-expression-optimization | N |
Dead Code Elimination | dead-code-elimination | Y |
Jump Normalization | jump-normalization | N |
Jump Optimization | jump-optimization | N |
Single Step Elimination | single-step-elimination | Y |
Expression Optimization | expression-optimization | Y |
If Expression Optimization | if-expression-optimization | N |
Data Flow Optimization | data-flow-optimization | Y |
Loop Hoisting | loop-hoisting | Y |
Loop Optimization | loop-optimization | N |
Loop Unrolling | loop-unrolling | Y |
Function Inlining | function-inlining | Y |
Case Switching | case-switching | N |
Return Optimization | case-switching | N |
Jump Straightening | return-optimization | N |
Jump Threading | jump-threading | Y |
Unreachable Code Elimination | unreachable-code-elimination | Y |
Stack Optimization | stack-optimization | N |
Print Merging | print-merging | Y |
This table doesn't track which optimizations provide some functionality on the experimental
level. This information is available in the individual optimizations documentation.
You normally shouldn't need to deactivate any optimization, but if there was a bug in some of the optimizers, deactivating it might allow you to use Mindcode until a fix is available.
In particular, some optimizers expect to work on code that was already processed by different optimizations, so turning off some optimizations might render other optimizations ineffective. This is not a bug.