User:Cipscis/Assembly Optimisations
Papyrus assembly, as created by the Creation Kit's Papyrus compiler, can be optimised in numerous ways. Here is a partial list of easy optimisations that can be made systematically.
Currently these optimisations are easy enough to be made by hand, but theoretically they could also be made by an "optimiser" utility that steps into the compilation process between the compiler (which compiles Papyrus to Papyrus assembly) and the assembler (which assembles human-readable Papyrus assembly into a more compressed machine-readable form) and makes these optimisations.
Foo = Bar + 1 ; Remove extraneous ASSIGN instructions
;/
Currently:
IADD ::temp0 Bar 1
ASSIGN Foo ::temp0
Better:
IADD Foo Bar 1
/;
BoolVar = IntVar ; Convert CAST + ASSIGN to CAST alone where appropriate
;/
Currently:
CAST ::temp0 IntVar
ASSIGN BoolVar ::temp0
Better:
CAST BoolVar IntVar
/;
True && !True ; Remove extraneous CAST instructions
;/
Currently:
CAST ::temp0 True
JUMPF ::temp0 label0
NOT ::temp0 True
CAST ::temp0 ::temp0
label0:
Better:
JUMPF True label0
NOT ::temp0 True
label0:
/;
If True ; Remove extra JUMPs (and extra labels)
EndIf
;/
Currently:
JUMPF True label1
JUMP label0
label1:
label0:
Better:
JUMPF True label1
label1:
/;
If !True ; Combine NOT and JUMPF to JUMPT where appropriate (i.e. with ::temp vars)
EndIf
;/
Currently:
NOT ::temp0 True
JUMPF ::temp0 label1
JUMP label0
label1:
label0:
Better:
JUMPT True label1
JUMP label0
label1:
label0:
/;
Int Property Foo = 3 AutoReadOnly
; ...
Foo ; Optimise local AutoReadOnly property access
;/
Currently:
RETURN 3
; ...
PROPGET Foo self ::temp0
Better
ASSIGN ::temp0 3
/;
; Remove any "double jumps", where a label is right before a JUMP instruction
;/
Currently:
JUMP label1
; ...
JUMPF ::temp0 label1
; ...
label1:
JUMP label2
Better:
JUMP label2
; ...
JUMPF ::temp0 label2
; ...
JUMP label2
/;
If A && B ; Remove any "double jumps" where the same condition is checked twice in a row
EndIf
;/
Currently
CAST ::temp0 A
JUMPF ::temp0 label1
CAST ::temp0 B
label1:
JUMPF ::temp0 label2
JUMP label0
label2:
label0:
Better
CAST ::temp0 A
JUMPF ::temp0 label2
CAST ::temp0 B
label1:
JUMPF ::temp0 label2
JUMP label0
label2:
label0:
/;
If True ; Optimise out "If True", which can be used for block scope
EndIf
;/
Currently
JUMPF True label1
; Block scope
JUMP label0
label1:
label0:
Better
; Block scope
/;