Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to config redex pass #727

Open
123zhangmiao opened this issue Oct 17, 2022 · 10 comments
Open

how to config redex pass #727

123zhangmiao opened this issue Oct 17, 2022 · 10 comments

Comments

@123zhangmiao
Copy link

123zhangmiao commented Oct 17, 2022

How to configure a set of universal pass refers to the good optimization effect that can be achieved by using this set of pass Settings for different apps, how to know and avoid the potential risks of each pass, and what are the standards for measuring the optimization effect.

@thezhangwei
Copy link
Contributor

Hi, the aggressive.config is a good starting point. Please let us know if run into issues with that. We do plan to keep the config information more updated in the future.

@123zhangmiao
Copy link
Author

123zhangmiao commented Oct 18, 2022

Running RemoveEmptyClassesPass...
RemoveEmptyClassesPass 1 (run) completed in 0.0 seconds

If I get a log like the one above, I can delete the pass RemoveEmptyClassesPass right?

The other question is, what is the basis for removing or adding pass.
Looking forward to reply!

@thezhangwei
Copy link
Contributor

If I get a log like the one above, I can delete the pass RemoveEmptyClassesPass right?

It seems like it doesn't do much but it could be input dependent. It might find empty classes to remove for some other inputs. You don't necessarily have to prune passes even if they don't seem to do much for now. It's not taking much time to run anyways, it seems.

You can always add other passes to the passes list and see what they do. Usually the default config for that pass would work. You can also run one pass multiple times by replicating it in the passes list. Hopefully that helps.

@123zhangmiao
Copy link
Author

How do I see what a pass does? What are the criteria for whether a pass is valuable?

@123zhangmiao
Copy link
Author

As you said, default.config is a way to make sure that every pass works, aggressive.config is a good place to start. What should I choose if I want to have a pass configuration that is universal and works for different inputs? Please answer my confusion. My requirement is to have a common pass configuration to optimize different APKs. I would also like to know the criteria to measure the effectiveness of each pass optimization, as well as the overall config optimization. After all, the optimization of redex tool is determined by configuring pass. Do you agree with me?

@123zhangmiao
Copy link
Author

123zhangmiao commented Oct 19, 2022

When used aggressive.config, the following error occurs

File "/tmp/redex.TGskxX/redex.py", line 956, in prepare_redex
config_dict = json.loads(remove_comments(lines))
File "/usr/local/Cellar/[email protected]/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/init.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/local/Cellar/[email protected]/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/local/Cellar/[email protected]/3.9.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9/json/decoder.py", line 353, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 21 column 7 (char 257)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/tmp/redex.TGskxX/redex.py", line 1262, in
with_temp_cleanup(lambda: run_redex(args), args.always_clean_up)
File "/private/tmp/redex.TGskxX/pyredex/utils.py", line 62, in with_temp_cleanup
fn()
File "/tmp/redex.TGskxX/redex.py", line 1262, in
with_temp_cleanup(lambda: run_redex(args), args.always_clean_up)
File "/tmp/redex.TGskxX/redex.py", line 1238, in run_redex
state = prepare_redex(args)
File "/tmp/redex.TGskxX/redex.py", line 958, in prepare_redex
raise ValueError(
ValueError: Invalid JSON in ReDex config file: redex-test/aggressive.config

aggressive.config is as follows:
{
"redex" : {
"passes" : [
"RemoveUnreachablePass",
"StripDebugInfoPass",
"AccessMarkingPass",
"MethodDevirtualizationPass",
"ReBindRefsPass",
"ResultPropagationPass",
"BridgeSynthInlinePass,"
"FinalInlinePass",
"DelSuperPass",
"UnreferencedInterfacesPass",
"SingleImplPass",
"CommonSubexpressionEliminationPass", # Run once just before MethodInlinePass
"MethodInlinePass",
"PeepholePass",
"ConstantPropagationPass",
"LocalDcePass",
"AnnoKillPass",
"DelInitPass",
"RemoveUnreachablePass",
"ReorderInterfacesDeclPass",
"RemoveEmptyClassesPass",
"SingleImplPass",
"InterDexPass",
"CommonSubexpressionEliminationPass", # Run a second time after all method inlining is done
"RemoveGotosPass",
"DedupBlocksPass",
"UpCodeMotionPass",
"RegAllocPass",
"CopyPropagationPass",
"LocalDcePass",
"DedupBlocksPass",
"ReduceGotosPass" # This pass should come at the very end, after all other code transformations that might add gotos
]
},
"RegAllocPass" : {
"live_range_splitting": false
},
"inliner": {
"throws": true,
"multiple_callers": true,
"no_inline_annos" : [
"Lcom/fasterxml/jackson/databind/annotation/JsonDeserialize;"
],
"blocklist": [],
"caller_blocklist": []
},
"FinalInlinePass" : {
"propagate_static_finals": true,
"replace_encodable_clinits": true,
"blocklist_types" : []
},
"AnnoKillPass" : {
"keep_annos": [
"Landroid/view/ViewDebug$CapturedViewProperty;",
"Landroid/view/ViewDebug$ExportedProperty;",
"Landroid/webkit/JavascriptInterface;",
"Landroid/widget/RemoteViews$RemoteView;",
"Lcom/google/android/gms/common/annotation/KeepName;"
],
"kill_annos" : [
"Lcom/google/inject/BindingAnnotation;"
],
"force_kill_annos" : [
"Ldalvik/annotation/EnclosingClass;",
"Ldalvik/annotation/EnclosingMethod;",
"Ldalvik/annotation/InnerClass;",
"Ldalvik/annotation/MemberClasses;",
"Ldalvik/annotation/Throws;"
]
},
"CopyPropagationPass" : {
"eliminate_const_literals": false,
"full_method_analysis": true
},
"MethodDevirtualizationPass" : {
"staticize_vmethods_not_using_this" : true,
"staticize_dmethods_not_using_this" : true
},
"StripDebugInfoPass" : {
"drop_all_dbg_info" : false,
"drop_local_variables" : true,
"drop_line_numbers" : false,
"drop_src_files" : true,
"use_allowlist" : false,
"cls_allowlist" : [],
"method_allowlist" : [],
"drop_prologue_end" : true,
"drop_epilogue_begin" : true,
"drop_all_dbg_info_if_empty" : true
},
"PeepholePass" : {
"disabled_peepholes": [
"Replace_PutGet",
"Replace_PutGetWide",
"Replace_PutGetObject",
"Replace_PutGetShort",
"Replace_PutGetChar",
"Replace_PutGetByte",
"Replace_PutGetBoolean"
]
},
"keep_packages": [
"Lcom/fasterxml/jackson/",
"Lcom/google/dexmaker/mockito/"
],
"debug_info_kind": "no_custom_symbolication",
"method_move_map" : "redex-moved-methods-map.txt",
"string_sort_mode" : "class_order",
"bytecode_sort_mode" : ["method_similarity_order", "class_order"],
"ir_type_checker": {
"run_after_each_pass" : false,
"verify_moves" : false
}
}

@123zhangmiao
Copy link
Author

@thezhangwei hi~Can you answer my questions above?

@thezhangwei
Copy link
Contributor

How do I see what a pass does? What are the criteria for whether a pass is valuable?

We have docs for the passes: https://github.com/facebook/redex/blob/main/docs/passes.md
Each pass will collect some metrics and put them into the redex-stats.txt file. You can inspect the file to see how effective they are for your input. Note that it's input dependent.

facebook-github-bot pushed a commit that referenced this issue Nov 1, 2022
Summary:
Fix the invalid json.

github issue: #727

Reviewed By: ssj933

Differential Revision: D40875833

fbshipit-source-id: b8139977df4ab23704793e7258f83a9566b0cfde
@thezhangwei
Copy link
Contributor

The json error was fixed in 52e44ae.

@NTillmann
Copy link
Contributor

What are the criteria for whether a pass is valuable?

In general, most passes work towards reducing the final size. Some passes don't do all of the cleanup work and would require a RemoveUnreachablePass to run after to actually remove newly unreachable classes/methods/fields.

Some passes are geared towards improving performance while regressing size, e.g. PerfMethodInlinePass.

Some passes are necessary to produce valid dexes, e.g. InterDexPass and RegAllocPass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants