Optimizations
The importance of optimizations
Optimizations are often the reason why compiled code runs so fast. Modern compilers have a wide range of optimizations available, some have significant performance impacts, reduce code size and make things easier for the CPU. Here is a C++ example (godbolt):
int mulByConstant(int x) {
return x * 65599;
}
The instructions generated are exactly what we imagine it to be, an imul (integer multiplication) of our input with 65599:
mulByConstant(int):
imul eax, edi, 65599
ret
Now what will happen if we wrote some very bad code that does the same thing (godbolt):
int mulByConstant(int x) {
return (x << 16) + (x << 6) - x;
// ^ ^
// x * 65536 |
// x * 64
// 65536x + 64x - 1x = 65599x
}
In this rather intimidating function we are doing the same thing (multiplying x with 65599) however instead of using a multiplication we are using bit-shifts and additions.
mulByConstant(int):
imul eax, edi, 65599
ret
The result that the compiler generated is the same as before, it looked at our arithmetic operations and understood we want to multiply by 65599. It also knows that a single imul instruction is cheaper than whatever we wanted to do:
mulByConstant(int): # using bit-shifts with no optimizations
push rbp
mov rbp, rsp
mov dword ptr [rbp - 4], edi
mov eax, dword ptr [rbp - 4]
shl eax, 16
mov ecx, dword ptr [rbp - 4]
shl ecx, 6
add eax, ecx
sub eax, dword ptr [rbp - 4]
pop rbp
ret
Optimizing Papyrus
The CK compiler does not optimizations. It only tries to convert the raw code into a .pex file, doing only the bare minimum of work required to validate the code and produce an output. This is the reason why the code produces by a decompiler like Champollion is almost identical to the original code.
The next following pages contain information on every optimization done by the Open Papyrus Compiler.