Compressing makes output bigger
Describe the bug
A case where function inlining made the output bigger instead of smaller
Input code
function $parcel$export(a, b, c){a[b] = c;}
$parcel$export(module.exports, "A", function () { return A; });
$parcel$export(module.exports, "B", function () { return B; });
$parcel$export(module.exports, "C", function () { return C; });
const A = "A", B = "B", C = "C";
Config
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false
},
"target": "es2020",
"loose": false,
"minify": {
"compress": {
"arguments": false,
"arrows": true,
"booleans": true,
"booleans_as_integers": false,
"collapse_vars": true,
"comparisons": true,
"computed_props": true,
"conditionals": true,
"dead_code": true,
"directives": true,
"drop_console": false,
"drop_debugger": true,
"evaluate": true,
"expression": false,
"hoist_funs": false,
"hoist_props": true,
"hoist_vars": false,
"if_return": true,
"join_vars": true,
"keep_classnames": false,
"keep_fargs": true,
"keep_fnames": false,
"keep_infinity": false,
"loops": true,
"negate_iife": true,
"properties": true,
"reduce_funcs": false,
"reduce_vars": false,
"side_effects": true,
"switches": true,
"typeofs": true,
"unsafe": false,
"unsafe_arrows": false,
"unsafe_comps": false,
"unsafe_Function": false,
"unsafe_math": false,
"unsafe_symbols": false,
"unsafe_methods": false,
"unsafe_proto": false,
"unsafe_regexp": false,
"unsafe_undefined": false,
"unused": true,
"const_to_let": true,
"pristine_globals": true
},
"mangle": {
"toplevel": false,
"keep_classnames": false,
"keep_fnames": false,
"keep_private_props": false,
"ie8": false,
"safari10": false
}
}
},
"module": {
"type": "commonjs"
},
"minify": true,
"isModule": true
}
Playground link
https://play.swc.rs/?version=1.2.223&code=H4sIAAAAAAAAA0srzUsuyczPU1ApSCxKTs1RSa0oyC8q0UjUUUjSUUjWrE6MTopVsFVItq7lQlOSm59SmpOqB%2BEV6ygoOSrpKKTBzNPQVKhWKEotKS3KU3C0VqjVtCao3wmXfifi9Dvj0u8M0Z%2Bcn1dcouAI9A3YqU4gBshOZxDDWcmaCwCaGsxoDQEAAA%3D%3D&config=H4sIAAAAAAAAA3VUQZLjIAz8C%2Bc5ZOa0NQ%2BY276BIkY4ZDByIeGJK5W%2Fr4htiJPZm9W0REtqc1Vn6tTnVY0mEaTyRXNkc1GfiucRqEt%2BZPWmmARyJhDcJDCpBxYK0Mfh4yDHAZFgJbypwUfv5lKsw2FMQFS%2BJSkPEJkqz6SEPxJyyhIdEQOY%2BBJrQ9pHhh5SS%2B0wBDMS6MmkmlFuM8kTxh2UGaweE44PaLSePUYptmEWjNUdWqiAT9Cxn6BRpIZQIomwquQOWjjmvi8DXJgwmZAN11pwuY9Bbqx5J%2FTE2uVIT9BO6QItTa4s73QCzilunDP6uJvDN4DoDIYomgFa5h13soc90%2F3C8tHJEnmuqGy4qYrQS3Pae1c7LKohsW%2FTSmBzB6XDrhVfwV1D5C1ocE6mXZPpx3N3asWKGdHVUKZmXNvBEurNT3u0WOAF%2FBJV%2FLiOFR8Mn54xmocjhpcSA%2FAJ7Qssg2B8BpO49zI%2BozlakDGDfTjIVMJqU1k%2Bow7lb9vmLIaQHN0HPFb7yk85mNgXW14V4xhggrDf6H%2F98Asml0xlwasVN%2BPBn7YzIz7y74ftUbgVBWjzqkC2Jc%2BDTH7AeCZ1a2%2FC0oWnvyv5rv4fybKGM4cEAAA%3D
Expected behavior
Output is smaller or has same size
Actual behavior
Enabling compress makes output bigger
Version
1.2.223
Additional context
No response
Some thoughts, not actual work.
Inlining a function call is a two phase action in swc: first you replace the function ident with the actual function, then you evaluate it.
Two kinds of function would be inlined: those only used one times, and those are simple enough. The first kind of inlining is always right, but the second causes this issue. It's inlined, but evaluation failed, maybe because its arguments contain side effect(accessing global variable module) or contain function. So the solution seems to be distinguish between these two kinds of function, and bail out inlining if the latter kind is called with bad arguments.
However, is it really not impossible to evaluate this function? Maybe not, as gcc advanced mode could. If we take a look at the function body, one could see that evalution order is preseved, as a is always accessed first. However such capability doesn't seem to exist at this point in swc.
Anyway, the way to fix this issue would be long and tormenting.
I think we can adjust inline cost logic by calculating argument cost in the analyzer and by using unresolved_ctxt
If we do so, the inline cost of module.exports will be very high so it will not be inlined
No, the cost of module.exports doesn't change before and after inling unless it's referenced multiple times, which is rare as we only inline small functions
Oh, this case seems to be caused by function as a parameter would prevent iife invoke. We could optimise this easily.
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.