Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
229 commits
Select commit Hold shift + click to select a range
1c71424
Add base tests
jfmengels Dec 27, 2021
6934b79
Add passing test
jfmengels Dec 28, 2021
235731d
Add passing test
jfmengels Dec 28, 2021
4883fff
Add TODO
jfmengels Dec 28, 2021
a78d616
Document the original source code
jfmengels Dec 28, 2021
0070b32
Add forTests parameter
jfmengels Dec 29, 2021
5f4c826
DEBUG
jfmengels Dec 29, 2021
c2860cb
Visit node afterwards
jfmengels Dec 29, 2021
10456a1
Add condition with dummy replacement
jfmengels Dec 29, 2021
bccaa66
Add condition for F call
jfmengels Dec 29, 2021
606b8dc
Return expression node
jfmengels Dec 29, 2021
b8a90fe
Return node itself
jfmengels Dec 29, 2021
5abe87e
Re-create initializer
jfmengels Dec 29, 2021
af905e6
Collect name
jfmengels Dec 29, 2021
af1060d
Move condition
jfmengels Dec 29, 2021
0ddbcb7
Update fn
jfmengels Dec 29, 2021
d82c81e
Add function
jfmengels Dec 29, 2021
d979ad7
Pass function name
jfmengels Dec 29, 2021
5b4c03d
Add label and while loop
jfmengels Dec 29, 2021
592f300
Use new body
jfmengels Dec 29, 2021
2c76128
Use the label
jfmengels Dec 29, 2021
7b8fdf5
Formatting
jfmengels Dec 29, 2021
31290bd
Update calls
jfmengels Dec 29, 2021
4d52467
Extract variable
jfmengels Dec 29, 2021
8487025
Use visitor
jfmengels Dec 29, 2021
c6f3e70
Visit on
jfmengels Dec 29, 2021
5d87fe8
Support if
jfmengels Dec 29, 2021
7ddbb62
Try and extract arguments
jfmengels Dec 29, 2021
c19d986
Pass parameter names
jfmengels Dec 29, 2021
718b680
Assign parameters
jfmengels Dec 29, 2021
c4ddd60
Remove forTests
jfmengels Dec 29, 2021
92e91e3
Add temporary variables
jfmengels Dec 29, 2021
b154f42
Enable tail call recursion in the transform
jfmengels Dec 29, 2021
98349f2
Update TODO
jfmengels Dec 29, 2021
3c11216
Make sure non-recursive functions are not touched
jfmengels Dec 29, 2021
d0c6545
Add failing test
jfmengels Dec 29, 2021
e5fc114
Be more explicit in condition
jfmengels Dec 29, 2021
2fbf5d6
Re-use label
jfmengels Dec 29, 2021
a8519a3
Reset when exiting function to avoid issues with functions with the s…
jfmengels Dec 29, 2021
6b252ac
Visit labeled statements
jfmengels Dec 29, 2021
72de08a
Visit while loops
jfmengels Dec 29, 2021
3ea78bf
Merge conditions
jfmengels Dec 29, 2021
0fd8a7f
Remove TODO
jfmengels Dec 29, 2021
81c5dea
Don't generate unnecessary variables
jfmengels Dec 29, 2021
3895f4a
Remove console.log
jfmengels Dec 30, 2021
5935a33
Remove unnecessary variables from test
jfmengels Dec 30, 2021
4ed258f
Add failing test
jfmengels Dec 29, 2021
11f07e9
only
jfmengels Dec 29, 2021
f752241
Fix test
jfmengels Dec 29, 2021
2bf6aad
test
jfmengels Dec 30, 2021
26aaff3
Add recursion type
jfmengels Dec 30, 2021
ac455a7
Early return
jfmengels Dec 30, 2021
2e0e072
only
jfmengels Dec 30, 2021
982fa9f
Use the recursion type
jfmengels Dec 30, 2021
d4d9f82
Visit if correctly
jfmengels Dec 30, 2021
7a1f17b
Visit other nodes as well
jfmengels Dec 30, 2021
b46334e
Add extractRecursionKindFromReturn
jfmengels Dec 30, 2021
e72029e
Consider :: recursion
jfmengels Dec 30, 2021
9d15657
Add ConsRecursion
jfmengels Dec 30, 2021
092a38e
Consider :: as ConsRecursion
jfmengels Dec 30, 2021
b4fffe8
Add TODOs
jfmengels Dec 30, 2021
73957e2
Add Recursion
jfmengels Dec 30, 2021
83e0ce0
Change the return type
jfmengels Dec 30, 2021
1964eeb
Re-use extractRecursionKindFromReturn
jfmengels Dec 30, 2021
8246fb4
Use extractRecursionKindFromReturn
jfmengels Dec 30, 2021
5197198
Remove extractCallTo
jfmengels Dec 30, 2021
4fd84bb
Fix test
jfmengels Dec 30, 2021
1e68381
Support cons recursion start
jfmengels Dec 30, 2021
d46de28
Make functionsToBeMadeRecursive contain a RecursionType
jfmengels Dec 30, 2021
70fd9a6
Add TODO
jfmengels Dec 30, 2021
e15b915
Change logic structure
jfmengels Dec 30, 2021
b1d8785
Add cons-specific declarations
jfmengels Dec 30, 2021
84bc4ed
Avoid NaN
jfmengels Dec 30, 2021
68f8528
Use recursion type
jfmengels Dec 30, 2021
58ff760
Remove functionsToBeMadeRecursive
jfmengels Dec 30, 2021
d52828b
Generate tail value assignment
jfmengels Dec 30, 2021
357abdb
Update test
jfmengels Dec 30, 2021
50e1322
Use cons
jfmengels Dec 30, 2021
3098572
Extract function
jfmengels Dec 30, 2021
a3ab52c
Add ; to the assignments
jfmengels Dec 30, 2021
3d99f7c
Move conditions
jfmengels Dec 30, 2021
1d388a1
Return the head
jfmengels Dec 30, 2021
fb87927
Set end
jfmengels Dec 30, 2021
2c6f084
Don't set the end if it's []
jfmengels Dec 30, 2021
56ba99b
Remove TODO
jfmengels Dec 30, 2021
d2635bc
Add test for filter
jfmengels Dec 30, 2021
f579a31
Visit while body
jfmengels Dec 30, 2021
3df6d87
Remove additional block
jfmengels Dec 31, 2021
bbc31bb
Support multiple conses
jfmengels Dec 31, 2021
c8e4355
Rename start/end variables
jfmengels Dec 31, 2021
6ae0bda
Reduce the number of parameter reassignments before a continue
jfmengels Dec 31, 2021
8b25bef
Update TODO
jfmengels Dec 31, 2021
1079efa
Support recursion even with boolean logical operators
jfmengels Jan 1, 2022
4788afe
Test formatting
jfmengels Jan 1, 2022
6a918b9
Add explanation comments
jfmengels Jan 1, 2022
701f93d
Add semi-colons
jfmengels Jan 1, 2022
84f8d19
Add semicolon
jfmengels Jan 1, 2022
55990c0
Add failing test
jfmengels Jan 1, 2022
d220a28
Add variant
jfmengels Jan 1, 2022
f8771ad
Add start and end variables
jfmengels Jan 1, 2022
22a52a3
Extract function
jfmengels Jan 1, 2022
f802d21
Update comment
jfmengels Jan 1, 2022
fd481f8
Update return statement
jfmengels Jan 1, 2022
4c91325
Detect recursive calls with data constructors
jfmengels Jan 2, 2022
18fe5d2
Fill array with null
jfmengels Jan 2, 2022
78127e7
Pass property from extract
jfmengels Jan 2, 2022
f4707e5
Fix comment
jfmengels Jan 2, 2022
fe5ad83
Add test
jfmengels Jan 2, 2022
0c64691
Add recursion type
jfmengels Jan 2, 2022
b9bebb0
Support switch statements
jfmengels Jan 2, 2022
8c6fd9d
Explicit loop condition
jfmengels Jan 2, 2022
af4afba
Detect multiple recursion
jfmengels Jan 2, 2022
b5adbb9
Add variables at the top
jfmengels Jan 2, 2022
7a116db
Fix determination
jfmengels Jan 2, 2022
3b14759
Consider a function to already be optimized if it has a continue stat…
jfmengels Jan 2, 2022
0eff9ee
Remove comment
jfmengels Jan 2, 2022
3ff27c3
Fix explanation comment
jfmengels Jan 2, 2022
70fc3dd
Rename function
jfmengels Jan 2, 2022
e5283aa
Fix explanation comments
jfmengels Jan 2, 2022
70173c6
Remove unnecessary condition
jfmengels Jan 2, 2022
1e83dc0
Update return statement
jfmengels Jan 2, 2022
883ba45
Visit switch statements
jfmengels Jan 2, 2022
c3f69f4
Add FunctionRecursion
jfmengels Jan 2, 2022
52641c0
Pass property from data constructor
jfmengels Jan 2, 2022
992ec8d
Use property for initial values
jfmengels Jan 2, 2022
558676a
Update TODOs
jfmengels Jan 2, 2022
797d512
Reverse order of constructors
jfmengels Jan 2, 2022
c57479c
Add missing label for boolean recursion
jfmengels Jan 2, 2022
68284d1
Remove TODOs
jfmengels Jan 3, 2022
65afae7
Update TODOs
jfmengels Jan 3, 2022
95a0692
Add benchmark CLI
jfmengels Jan 4, 2022
3e03150
TMP-TRANSFORM
jfmengels Jan 2, 2022
0385402
Add failing test
jfmengels Jan 4, 2022
bba0781
Split function
jfmengels Jan 4, 2022
f46b324
Add recursion type
jfmengels Jan 4, 2022
d6dbff9
Determine
jfmengels Jan 4, 2022
4618d52
Add declarations at the top
jfmengels Jan 4, 2022
2ec2dfa
Support recursive sums
jfmengels Jan 4, 2022
7c88dcc
Add TODOs
jfmengels Jan 4, 2022
5f9c6b0
Support multiplication recursion
jfmengels Jan 5, 2022
d0ddffe
Remove TODO
jfmengels Jan 5, 2022
62cad8d
Support arithmetic recursion on the right side
jfmengels Jan 5, 2022
dfe1cc5
Update TODOs
jfmengels Jan 6, 2022
837bd00
Split extract addition and multiplication
jfmengels Jan 7, 2022
9436692
Rename field
jfmengels Jan 7, 2022
79c019f
Rename function
jfmengels Jan 7, 2022
d94cc59
Extract function to create label and loop
jfmengels Jan 7, 2022
209a4c9
Use an exhaustive switch statement
jfmengels Jan 7, 2022
8beb6c4
Use switch statement
jfmengels Jan 7, 2022
2b0455f
Add MaybeRecursion type
jfmengels Jan 8, 2022
32db0cb
Add MaybeFunctionRecursion type
jfmengels Jan 8, 2022
1d85956
Remove NotRecursion from recursive types
jfmengels Jan 8, 2022
eb06fde
Create different expressions
jfmengels Jan 8, 2022
4083d7c
Add NotRecursive
jfmengels Jan 8, 2022
5473e94
Use type alias
jfmengels Jan 8, 2022
7e8b7cf
Remove MaybeFunctionRecursion
jfmengels Jan 8, 2022
259d544
Remove MaybeRecursion
jfmengels Jan 8, 2022
fff84ed
Remove number assignment
jfmengels Jan 8, 2022
c29aa7b
Add type annotation
jfmengels Jan 8, 2022
4b06450
Add type annotations
jfmengels Jan 8, 2022
ac32a15
Add tests around ifs and ternary
jfmengels Jan 8, 2022
4eebe51
Support ternary operators
jfmengels Jan 8, 2022
e0cc6a3
Determine whether it's a string
jfmengels Jan 8, 2022
62ef8ad
Recursively go over binary expressions
jfmengels Jan 8, 2022
809abdd
Fix test documentation
jfmengels Jan 8, 2022
1216486
Add failing test
jfmengels Jan 8, 2022
0c9508b
Remove unused operator field
jfmengels Jan 8, 2022
c08c784
Split multiply recursion into add and multiply
jfmengels Jan 8, 2022
332e701
Remove arithmeticOperation
jfmengels Jan 8, 2022
a52fe4c
Rename add recursion type
jfmengels Jan 8, 2022
177b0f4
Remove ArithmeticOperator
jfmengels Jan 8, 2022
a328066
Re-use createContinuation
jfmengels Jan 8, 2022
c32bd61
Add adding field
jfmengels Jan 8, 2022
7dd4d16
Determine whether we're adding strings or numbers
jfmengels Jan 8, 2022
2e5cd31
Default to numbers
jfmengels Jan 8, 2022
74b4645
Support string concatenation
jfmengels Jan 9, 2022
61c3ed8
Declare declarations even when there is already a while loop
jfmengels Jan 8, 2022
6f0699f
Add TODO
jfmengels Jan 9, 2022
2fa6a99
Support string concatenation with appends on both sides
jfmengels Jan 9, 2022
fa20dc6
Only switch to a multiple data constructor recursion if the propertie…
jfmengels Jan 9, 2022
0fb07d1
Assign end for cons recursion at the same time as end.b
jfmengels Jan 9, 2022
89780e0
Assign for data recursion at the same time as .property
jfmengels Jan 9, 2022
f6aded9
Use a mutable clone
jfmengels Jan 9, 2022
7916960
Fix indentation issues
jfmengels Jan 9, 2022
ebf4dd6
Add TODO
jfmengels Jan 9, 2022
03cbace
Support list concatenation recursion
jfmengels Jan 9, 2022
7ca4f02
Introduce functions when they are needed
jfmengels Jan 13, 2022
d21defc
Remove unnecessary continue support
jfmengels Jan 13, 2022
9566dee
Use a generator to visit a function's return statements
jfmengels Jan 13, 2022
59e22fb
Explicit handling of plain and boolean recursion
jfmengels Jan 15, 2022
ac30838
Separate while loop creation from declarations
jfmengels Jan 15, 2022
b25dcdf
Remove unnecessary AST exploration
jfmengels Jan 15, 2022
f729d12
Make end condition for determineRecursionType more explicit
jfmengels Jan 15, 2022
4a274e2
Add numbersConfirmed to Add recursion
jfmengels Jan 15, 2022
7a00d7c
Add module to determine type of an expression
jfmengels Jan 14, 2022
4916270
Use type inference to support list recursion
jfmengels Jan 15, 2022
a6980c8
Support updating nested ternary expressions
jfmengels Jan 15, 2022
f6b8466
Support recursion when adding to the end of a list
jfmengels Jan 15, 2022
e0742b3
Add TODO
jfmengels Jan 11, 2022
ea9943e
Detect calls to _List_fromArray as returning lists
jfmengels Jan 16, 2022
9a3ee5c
Handle all cases of list concatenation
jfmengels Jan 16, 2022
36616b3
Pass forTests to the transformer
jfmengels Jan 16, 2022
e7a570a
Add documentation for the tail recursion transformer
jfmengels Jan 15, 2022
76b30db
Add test for when we can't determine what is being concatenated
jfmengels Jan 16, 2022
1596919
Introduce a while loop even when there are already some
jfmengels Jan 16, 2022
d159786
Remove incorrect refinement of add
jfmengels Jan 16, 2022
f070c0a
Add TODO
jfmengels Jan 16, 2022
e20dde9
Remove hardcoding around left/right for addition
jfmengels Jan 16, 2022
92adfe5
Remove TODO
jfmengels Jan 16, 2022
f0f7f91
Support string concatenation when encountering _Utils_ap
jfmengels Jan 17, 2022
df00eb3
Remove completed TODO
jfmengels Jan 17, 2022
34782c9
Optimize plain recursive calls even when we can't optimize concat recurs
jfmengels Jan 17, 2022
4e18579
Move operations after the ones for the start of the list
jfmengels Jan 18, 2022
176ca2c
Add ListOperationsRecursion
jfmengels Jan 18, 2022
cbfee89
Add return statement changes
jfmengels Jan 18, 2022
b7cc743
Replace cons recursion by list operations recursion
jfmengels Jan 18, 2022
c90f8cd
Support combining cons and concat
jfmengels Jan 17, 2022
6b0a541
Support list recursion in utils append expression
jfmengels Jan 18, 2022
1170a1c
Remove TODO
jfmengels Jan 18, 2022
4b06353
Add TODO
jfmengels Jan 18, 2022
d949fde
Revert transforms disabling
jfmengels Jan 19, 2022
eac475a
Make formatting consistent in tests
jfmengels Jan 25, 2022
651058b
Add TODO
jfmengels Jan 25, 2022
5be2837
Compress the construction of cons/concat operations
jfmengels Jan 26, 2022
e4c650a
Remove unused code
jfmengels Jan 26, 2022
0e99436
Improve documentation
jfmengels Jan 26, 2022
bb3262f
Add better type to Context
jfmengels Jan 27, 2022
44e01cf
Prevent extracts from being computed twice
jfmengels Jan 29, 2022
c2bdf02
Remove usages of ts.mutable
jfmengels Feb 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions src/benchmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// This was restored from an old version of index.ts
// This is not cleaned up at all and could use some love.


// tslint:disable-next-line no-require-imports no-var-requires
import program from 'commander';
import * as path from 'path';
import * as Transform from './transform';
import { toolDefaults, benchmarkDefaults, Browser} from './types';
import { compileToStringSync } from 'node-elm-compiler';
import * as fs from 'fs';
import chalk from 'chalk';
const { version } = require('../package.json');
import * as BenchInit from './benchmark/init'
import * as Benchmark from './benchmark/benchmark';
import * as Reporting from './benchmark/reporting';
import { readFilesSync } from './fs_util';

program
.version(version)
.description(
`${chalk.yellow('Elm Optimize Level 2!')}

This applies a second level of optimization to the javascript that Elm creates.

Make sure you're familiar with Elm's built-in optimization first: ${chalk.cyan(
'https://guide.elm-lang.org/optimization/asset_size.html'
)}

Give me an Elm file, I'll compile it behind the scenes using Elm 0.19.1, and then I'll make some more optimizations!`
)
.usage('[options] <src/Main.elm>')
.option('--output <output>', 'the javascript file to create.', 'elm.js')
.option('-O3, --optimize-speed', 'Enable optimizations that likely increases asset size', false)
.option('--init-benchmark <dir>', 'Generate some files to help run benchmarks')
.option('--benchmark <dir>', 'Run the benchmark in the given directory.')
.option('--replacements <dir>', 'Replace stuff')
.parse(process.argv);

async function run(inputFilePath: string | undefined) {
const dirname = process.cwd();
let jsSource: string = '';
let elmFilePath = undefined;

const options = program.opts();
const replacements = options.replacements;
const o3Enabled = options.optimizeSpeed;

if (program.initBenchmark) {
console.log(`Initializing benchmark ${program.initBenchmark}`)
BenchInit.generate(program.initBenchmark)
process.exit(0)
}

if (program.benchmark) {
const options = {
compile: true,
gzip: true,
minify: true,
verbose: true,
assetSizes: true,
runBenchmark: [
{
browser: Browser.Chrome,
headless: true,
}
],
transforms: benchmarkDefaults(o3Enabled, replacements),
};
const report = await Benchmark.run(options, [
{
name: 'Benchmark',
dir: program.benchmark,
elmFile: 'V8/Benchmark.elm',
}
]);
console.log(Reporting.terminal(report));
// fs.writeFileSync('./results.markdown', Reporting.markdownTable(result));
process.exit(0)
}

if (inputFilePath && inputFilePath.endsWith('.js')) {
jsSource = fs.readFileSync(inputFilePath, 'utf8');
console.log('Optimizing existing JS...');
} else if (inputFilePath && inputFilePath.endsWith('.elm')) {
elmFilePath = inputFilePath;
jsSource = compileToStringSync([inputFilePath], {
output: 'output/elm.opt.js',
cwd: dirname,
optimize: true,
processOpts:
// ignore stdout
{
stdio: ['inherit', 'ignore', 'inherit'],
},
});
if (jsSource != '') {
console.log('Compiled, optimizing JS...');
} else {
process.exit(1)
}
} else {
console.error('Please provide a path to an Elm file.');
program.outputHelp();
return;
}
if (jsSource != '') {
const transformed = await Transform.transform(
dirname,
jsSource,
elmFilePath,
false,
toolDefaults(o3Enabled, replacements),
);

// Make sure all the folders up to the output file exist, if not create them.
// This mirrors elm make behavior.
const outputDirectory = path.dirname(program.output);
if (!fs.existsSync(outputDirectory)) {
fs.mkdirSync(outputDirectory, { recursive: true });
}
fs.writeFileSync(program.output, transformed);
const fileName = path.basename(inputFilePath);
console.log('Success!');
console.log('');
console.log(` ${fileName} ───> ${program.output}`);
console.log('');
}
}


run(program.args[0]).catch((e) => console.error(e));
2 changes: 2 additions & 0 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { inlineNumberToString } from './transforms/inlineNumberToString';
import { reportFunctionStatusInBenchmarks, v8Debug } from './transforms/analyze';
import { recordUpdate } from './transforms/recordUpdate';
import * as Replace from './transforms/replace';
import { createTailCallRecursionTransformer } from './transforms/tailCallRecursion';

export type Options = {
compile: boolean;
Expand Down Expand Up @@ -87,6 +88,7 @@ export const transform = async (
let inlineCtx: InlineContext | undefined;
const transformations: any[] = removeDisabled([
[transforms.replacements != null, replacementTransformer ],
[transforms.tailCallRecursion, createTailCallRecursionTransformer(false) ],
[transforms.fastCurriedFns, Replace.from_file('/../replacements/faster-function-wrappers') ],
[transforms.replaceListFunctions, Replace.from_file('/../replacements/list') ],
[transforms.replaceStringFunctions, Replace.from_file('/../replacements/string') ],
Expand Down
Loading