Pas2js optimizations: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Pas2js optimizations
| Old | New | Line | |
|---|---|---|---|
| 1 | + | # Overview | |
| 2 | + | ||
| 3 | + | This page describes existing optimizations for the [[pas2js]] transpiler as well as feature requests. | |
| 4 | + | ||
| 5 | + | # Generated JavaScript | |
| 6 | + | ||
| 7 | + | ## Existing optimizations | |
| 8 | + | ||
| 9 | + | - -O-: Disable all optimizations | |
| 10 | + | - -O1 : Level 1 optimizations (quick and debugger friendly) | |
| 11 | + | - -O2 : Level 2 optimizations, slow and not debugger friendly | |
| 12 | + | - -OoEnumNumbers\[-\]: write enum value as number instead of name. Default in -O1. | |
| 13 | + | - -OoRemoveNotUsedPrivates\[-\]: Default is enabled | |
| 14 | + | - -OoRemoveNotUsedDeclarations\[-\]: Default enabled for programs with -Jc | |
| 15 | + | - -OoShortRefGlobals\[-\]: Insert JS local var for types from other units and modules. Default enabled in -O2 | |
| 16 | + | - omit unneeded brackets in associative operations (a\|\|b)\|\|(c\|\|d), (a&&b)&&(c&&d), (a\|b)\|c, (a&b)&c, (a^b)^c, (a+b)+c, (a-b)-c, (a*b)*c | |
| 17 | + | - Use {\$modeswitch OmitRTTI} to treat published sections as public and thus remove them by WPO. Published section provide RTTI, so the compiler cannot know at compile time if a published identifier is needed, so it keeps it. | |
| 18 | + | ||
| 19 | + | ## Feature requests | |
| 20 | + | ||
| 21 | + | There are some predefined sets of optimizations. At the moment there is only -O1, but eventually there will be *-O2, -O3, -O4* similar to FPC. Each optimization can be enabled/disabled separately via some corresponding -Oo flag. | |
| 22 | + | ||
| 23 | + | - -O1 : Level 1 optimizations, fast and debugger friendly | |
| 24 | + | - -O2 : Level 2 optimizations, slow and not debugger friendly | |
| 25 | + | - -O3 : Level 3 optimizations, slow and might break special code | |
| 26 | + | - -O4 : Level 4 optimizations, very slow and/or only for rare cases | |
| 27 | + | ||
| 28 | + | Specific optimizations: | |
| 29 | + | ||
| 30 | + | - move rtl.js functions to system.pp and let the WPO decide if they are needed | |
| 31 | + | - add \$mod only if needed | |
| 32 | + | - add Self only if needed | |
| 33 | + | - use a number for small sets instead of JS objects | |
| 34 | + | - shortcut for test if a set is empty a=\[\] a\<\>\[\] | |
| 35 | + | - SetLength(scope.a,l) -\> read scope only once, same for Include, Exclude, Inc, Dec, +=, -=, *=, /= | |
| 36 | + | - ECMAScript6: use *const* for local const | |
| 37 | + | - add an option to let WPO omit all published members not used at compile time | |
| 38 | + | - procedure message modifier: only use message methods which message parameter type is used. | |
| 39 | + | - omit implicit "return Result" if last statement is return. issue 35860 | |
| 40 | + | - WPO: omit empty overrides | |
| 41 | + | - -O1: shortcut: a in \[b\] -\> a=b | |
| 42 | + | - -O1: shortcut: \[a\]*b=\[\] -\> not (a in b) | |
| 43 | + | - -O1: shortcut: \[a\]*b\<\>\[\] -\> a in b | |
| 44 | + | - -O1: combine multiple var a=0,b=0 | |
| 45 | + | - -O1: init a local var with the first assignment | |
| 46 | + | - -O1: skip clone array for new array and arraysetlength | |
| 47 | + | - -O1/-O2: autoinline | |
| 48 | + | - -O1: replace constant expression with result, e.g. b:=1+2 -\> b:=3 | |
| 49 | + | - -O1: create constants for set literals in expressions \[lit,lit\] | |
| 50 | + | - -O1: only in WPO: omit constant definition if all references were replaced by literal | |
| 51 | + | - -O1: no function Result var when assigned only once, e.g. Result = 3; return Result; -\> return 3; | |
| 52 | + | - -O1: by reference: create getter/setter object only once | |
| 53 | + | - -O1: pass array element by reference: when index is constant, use that directly (i.e. no temporary variable) | |
| 54 | + | - -O1: var/out argument: create accessor as var outside loops and combine multiple to one | |
| 55 | + | - -O1: \$mod.\$rtti\["name"\] -\> \$mod.\$rtti.name | |
| 56 | + | - -O2: replace constant with literal only if reference is longer, e.g. use pas.mymath.tau instead of 6.2831853071795862. | |
| 57 | + | - -O2: compressed format: omit spaces and line breaks in JavaScript | |
| 58 | + | - -O2: inline -Si | |
| 59 | + | - -O2: case-of with 6+ elements as binary tree | |
| 60 | + | - -O2: case-of using JS operators Case1?Statement1:Case2?:Statement2:Else | |
| 61 | + | - -O2: insert local/unit vars for types in same unit | |
| 62 | + | - -O2: insert local/unit vars for static functions | |
| 63 | + | - -O2: {\$optimization removeemptyprocs} as FPC | |
| 64 | + | - -O2: skip dead code If(false){...} | |
| 65 | + | - -O2: simplify: *"abc" + ("" + expr)* to *("abc" + expr)* | |
| 66 | + | - -O2: simplify: *a = (b)* with b not a function declaration to *a = b* | |
| 67 | + | - -O2: combine *var a = v; var b = t;* to *var a=v, b=t;* | |
| 68 | + | - -O2: replace multiple reads (writes) of a variable with a getter (setter). | |
| 69 | + | - -O2: CSE | |
| 70 | + | - -O3: DFA | |
| 71 | + | - -O3: shorten local identifiers: rename identifiers, often used identifiers should get the shortest names, might break asm-blocks. | |
| 72 | + | - -O3: shorten global identifiers: requires WPO, might break asm-blocks and foreign JS accessing the Pascal generated code. | |
| 73 | + | ||
| 74 | + | # Compiler itself | |
| 75 | + | ||
| 76 | + | The compiler was deliberately with the following design policies: | |
| 77 | + | ||
| 78 | + | - Modular fashion. Each part has its own test suite and is used by other projects. | |
| 79 | + | - Can be used in a library, i.e. no restart or recreate required to compile another program. Simply call Reset. It reuses files from cache if fileage has not changed. | |
| 80 | + | - Can be used without a filesystem, i.e. in a browser | |
| 81 | + | - Threadsafe, i.e. the compilation can run in a thread. Compiling a program with multiple threads is planned. | |
| 82 | + | - Easy maintenance has higher priority than high speed and low memory usage | |
| 83 | + | ||
| 84 | + | --- | |
| 85 | + | *From the Free Pascal wiki, page "Pas2js optimizations", as it stood on 2021-03-09 after a change by Mattias2, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 86 | + | Category: Pas2js |
