From a057947ab22991419b2b33da79d5e65898087d13 Mon Sep 17 00:00:00 2001 From: David Leopoldseder Date: Thu, 21 Mar 2024 10:24:09 +0100 Subject: [PATCH] Add -Os to native image --- .../compiler/asm/amd64/AMD64Assembler.java | 4 +- .../compiler/core/common/GraalOptions.java | 8 +++ .../graal/compiler/core/phases/HighTier.java | 5 +- .../graal/compiler/core/phases/MidTier.java | 9 ++- .../compiler/nodes/PrefetchAllocateNode.java | 5 +- .../native-image/BuildOptions.md | 2 +- .../native-image/BuildOutput.md | 3 +- .../OptimizationsAndPerformance.md | 1 + substratevm/CHANGELOG.md | 1 + .../core/graal/llvm/LLVMToolchainUtils.java | 2 +- .../com/oracle/svm/core/SubstrateOptions.java | 72 ++++++++++++++++++- .../svm/hosted/NativeImageGenerator.java | 10 ++- .../svm/hosted/image/NativeImageViaCC.java | 6 ++ vm/mx.vm/mx_vm_benchmark.py | 6 +- 14 files changed, 117 insertions(+), 17 deletions(-) diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java index 112214a30a53..48447123620a 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java @@ -131,14 +131,14 @@ public AMD64Assembler(TargetDescription target) { public AMD64Assembler(TargetDescription target, OptionValues optionValues) { super(target); - useBranchesWithin32ByteBoundary = Options.UseBranchesWithin32ByteBoundary.getValue(optionValues); + useBranchesWithin32ByteBoundary = !GraalOptions.ReduceCodeSize.getValue(optionValues) && Options.UseBranchesWithin32ByteBoundary.getValue(optionValues); optimizeLongJumps = GraalOptions.OptimizeLongJumps.getValue(optionValues); } public AMD64Assembler(TargetDescription target, OptionValues optionValues, boolean hasIntelJccErratum) { super(target); if (Options.UseBranchesWithin32ByteBoundary.hasBeenSet(optionValues)) { - useBranchesWithin32ByteBoundary = Options.UseBranchesWithin32ByteBoundary.getValue(optionValues); + useBranchesWithin32ByteBoundary = !GraalOptions.ReduceCodeSize.getValue(optionValues) && Options.UseBranchesWithin32ByteBoundary.getValue(optionValues); } else { useBranchesWithin32ByteBoundary = hasIntelJccErratum; } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java index 8be3d5090c20..46ad0b73fa99 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java @@ -38,6 +38,10 @@ public final class GraalOptions { @Option(help = "Uses compiler intrinsifications.", type = OptionType.Expert) public static final OptionKey Intrinsify = new OptionKey<>(true); + + @Option(help = "", type = OptionType.Debug) + public static final OptionKey ReduceCodeSize = new OptionKey<>(true); + @Option(help = "Rewrite signed comparisons to unsigned ones if the result is equal.", type = OptionType.Debug) public static final OptionKey PreferUnsignedComparison = new OptionKey<>(true); @@ -317,4 +321,8 @@ public final class GraalOptions { @Option(help = "AMD64 only: Replace forward jumps (jmp, jcc) with equivalent but smaller instructions if the actual jump displacement fits in one byte.", type = OptionType.Expert) public static final OptionKey OptimizeLongJumps = new OptionKey<>(false); + + @Option(help = "Optimize integer division operation by using various mathematical foundations to " + + " express it in faster, equivalent, arithmetic.", type = OptionType.Expert) + public static final OptionKey OptimizeDiv = new OptionKey<>(true); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/HighTier.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/HighTier.java index 9bd262a2d04d..0ad3f29e0e30 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/HighTier.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/HighTier.java @@ -87,7 +87,10 @@ public HighTier(OptionValues options) { } LoopPolicies loopPolicies = createLoopPolicies(options); - appendPhase(new LoopFullUnrollPhase(canonicalizer, loopPolicies)); + + if (GraalOptions.FullUnroll.getValue(options)) { + appendPhase(new LoopFullUnrollPhase(canonicalizer, loopPolicies)); + } if (GraalOptions.LoopPeeling.getValue(options)) { appendPhase(new LoopPeelingPhase(loopPolicies, canonicalizer)); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/MidTier.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/MidTier.java index 5126b9cabf97..17b80da4b114 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/MidTier.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/MidTier.java @@ -88,7 +88,10 @@ public MidTier(OptionValues options) { appendPhase(new VerifyHeapAtReturnPhase()); } - appendPhase(new LoopFullUnrollPhase(canonicalizer, createLoopPolicies(options))); + if (GraalOptions.FullUnroll.getValue(options)) { + appendPhase(new LoopFullUnrollPhase(canonicalizer, createLoopPolicies(options))); + } + appendPhase(new RemoveValueProxyPhase(canonicalizer)); appendPhase(new LoopSafepointInsertionPhase()); @@ -99,7 +102,9 @@ public MidTier(OptionValues options) { appendPhase(new IterativeConditionalEliminationPhase(canonicalizer, false)); } - appendPhase(new OptimizeDivPhase(canonicalizer)); + if (GraalOptions.OptimizeDiv.getValue(options)) { + appendPhase(new OptimizeDivPhase(canonicalizer)); + } appendPhase(new FrameStateAssignmentPhase()); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PrefetchAllocateNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PrefetchAllocateNode.java index 6ee19074db6c..8ccf0192305e 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PrefetchAllocateNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PrefetchAllocateNode.java @@ -29,6 +29,7 @@ import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_2; import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_2; +import jdk.graal.compiler.core.common.GraalOptions; import jdk.graal.compiler.core.common.type.StampFactory; import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.nodeinfo.NodeInfo; @@ -50,7 +51,9 @@ public PrefetchAllocateNode(ValueNode address) { @Override public void generate(NodeLIRBuilderTool gen) { - gen.getLIRGeneratorTool().emitPrefetchAllocate(gen.operand(address)); + if (!GraalOptions.ReduceCodeSize.getValue(this.getOptions())) { + gen.getLIRGeneratorTool().emitPrefetchAllocate(gen.operand(address)); + } } @NodeIntrinsic diff --git a/docs/reference-manual/native-image/BuildOptions.md b/docs/reference-manual/native-image/BuildOptions.md index 1514266d6c7d..7ef4c57a4ea4 100644 --- a/docs/reference-manual/native-image/BuildOptions.md +++ b/docs/reference-manual/native-image/BuildOptions.md @@ -76,7 +76,7 @@ Run `native-image --help` for help on build options. * `--target`: select the compilation target for `native-image` (in the `-` format). It defaults to host's OS-architecture pair. * `--trace-class-initialization`: provide a comma-separated list of fully-qualified class names that a class initialization is traced for * `--trace-object-instantiation`: provide a comma-separated list of fully-qualified class names that an object instantiation is traced for -* `-O`: control code optimizations where available variants are: `b` - optimize for fastest build time, `0` - no optimizations, `1` - basic optimizations, `2` - aggressive optimizations, `3` - all optimizations for best performance (enabled automatically with the Profile-guided optimization) +* `-O`: control code optimizations where available variants are: `b` - optimize for fastest build time, `s` - optimize for size, `0` - no optimizations, `1` - basic optimizations, `2` - aggressive optimizations, `3` - all optimizations for best performance (enabled automatically with Profile-Guided Optimizations) * `-da`, `-da[:[packagename]|:[classname]`, `disableassertions[:[packagename]|:[classname]`: disable assertions with specified granularity at run time * `-dsa`, `-disablesystemassertions`: disable assertions in all system classes at run time * `-ea`, `-ea[:[packagename]|:[classname]`, `enableassertions[:[packagename]|:[classname]`: enable assertions with specified granularity at run time diff --git a/docs/reference-manual/native-image/BuildOutput.md b/docs/reference-manual/native-image/BuildOutput.md index 3be5628f2a19..3268063e06e7 100644 --- a/docs/reference-manual/native-image/BuildOutput.md +++ b/docs/reference-manual/native-image/BuildOutput.md @@ -91,7 +91,8 @@ Please report version and vendor when you [file issues](https://github.com/oracl The selected optimization level and targeted machine type used by the Graal compiler. The optimization level can be controlled with the `-O` option and defaults to `2`, which enables aggressive optimizations. Use `-Ob` to enable quick build mode, which speeds up the [compilation stage](#stage-compiling). -This is useful during development, or when peak throughput is less important and you would like to optimize for size. +This is useful during development to reduce image build time. +Use `-Os` to optimize for size. The targeted machine type can be selected with the `-march` option and defaults to `x86-64-v3` on AMD64 and `armv8-a` on AArch64. See [here](#recommendation-cpu) for recommendations on how to use this option. diff --git a/docs/reference-manual/native-image/OptimizationsAndPerformance.md b/docs/reference-manual/native-image/OptimizationsAndPerformance.md index ccd439d241c0..a908fbd300cc 100644 --- a/docs/reference-manual/native-image/OptimizationsAndPerformance.md +++ b/docs/reference-manual/native-image/OptimizationsAndPerformance.md @@ -18,6 +18,7 @@ The following table provides an overview of the different optimization levels an | Level | Optimizations | Use Cases | |:---:|:---:|---| | `-Ob` | Reduced | Quick build mode: Speeds up builds during development by avoiding time-consuming optimizations. This can also reduce file size sometimes. | +| `-Os` | Reduced | Optimize for size: `-Os` enables all `-O2` optimizations except those that can increase code or image size significantly. Typically creates the smallest possible images at the cost of reduced performance. | | `-O0` | None | Typically used together with `-g` to improve the debugging experience. | | `-O1` | Basic | Trades performance for reduced file size and build time. Oracle GraalVM's `-O1` is somewhat comparable to `-O2` in GraalVM Community Edition. | | `-O2` | Advanced | **Default:** Aims for good performance at a reasonable file size. | diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index e36b7bb69681..f9ba4dddc225 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -24,6 +24,7 @@ This changelog summarizes major changes to GraalVM Native Image. * (GR-53359) Provide the `.debug_gdb_scripts` section that triggers auto-loading of `svmhelpers.py` in GDB. Remove single and double quotes from `ClassLoader.nameAndId` in the debuginfo. * (GR-47365) Include dynamic proxy metadata in the reflection metadata with the syntax `"type": { "proxy": [] }`. This allows members of proxy classes to be accessed reflectively. `proxy-config.json` is now deprecated but will still be honored. * (GR-18214) In-place compacting garbage collection for the Serial GC old generation with `-H:+CompactingOldGen`. +* (GR-52844) Add `Os` a new optimization mode to configure the optimizer in a way to get the smallest code size. ## GraalVM for JDK 22 (Internal Version 24.0.0) * (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics. diff --git a/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMToolchainUtils.java b/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMToolchainUtils.java index b10092fff482..c73ef135d593 100644 --- a/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMToolchainUtils.java +++ b/substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMToolchainUtils.java @@ -110,7 +110,7 @@ public static void llvmCompile(DebugContext debug, String outputPath, String inp private static int optimizationLevel() { return switch (SubstrateOptions.optimizationLevel()) { - case O0, BUILD_TIME -> 0; + case O0, BUILD_TIME, SIZE -> 0; case O1 -> 1; case O2 -> 2; case O3 -> 3; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java index b556c679a058..42e2ac91022f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java @@ -71,6 +71,7 @@ import jdk.graal.compiler.options.OptionStability; import jdk.graal.compiler.options.OptionType; import jdk.graal.compiler.options.OptionValues; +import jdk.graal.compiler.phases.common.DeadCodeEliminationPhase; import jdk.internal.misc.Unsafe; public class SubstrateOptions { @@ -233,7 +234,8 @@ public enum OptimizationLevel { O1("Basic optimizations", "1"), O2("Advanced optimizations", "2"), O3("All optimizations for best performance", "3"), - BUILD_TIME("Optimize for fastest build time", "b"); + BUILD_TIME("Optimize for fastest build time", "b"), + SIZE("Optimize for size", "s"); private final String description; private final String optionSwitch; @@ -268,7 +270,7 @@ public boolean isOneOf(OptimizationLevel... levels) { } @APIOption(name = "-O", valueSeparator = APIOption.NO_SEPARATOR)// - @Option(help = "Control code optimizations: b - optimize for fastest build time, " + + @Option(help = "Control code optimizations: b - optimize for fastest build time, s - optimize for size, " + "0 - no optimizations, 1 - basic optimizations, 2 - advanced optimizations, 3 - all optimizations for best performance.", type = OptionType.User)// public static final HostedOptionKey Optimize = new HostedOptionKey<>("2") { @@ -290,6 +292,11 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol SubstrateOptions.ReduceImplicitExceptionStackTraceInformation.update(values, newLevel == OptimizationLevel.O3); GraalOptions.OptimizeLongJumps.update(values, !newLevel.isOneOf(OptimizationLevel.O0, OptimizationLevel.BUILD_TIME)); + + if (newLevel == OptimizationLevel.SIZE) { + configureOs(values); + } + if (optimizeValueUpdateHandler != null) { optimizeValueUpdateHandler.onValueUpdate(values, newLevel); } @@ -297,6 +304,55 @@ protected void onValueUpdate(EconomicMap, Object> values, String ol } }; + public static void configureOs(EconomicMap, Object> values) { + enable(GraalOptions.ReduceCodeSize, values); + enable(ReduceImplicitExceptionStackTraceInformation, values); + enable(GraalOptions.OptimizeLongJumps, values); + + /* + * Remove all loop optimizations that can increase code size, i.e., duplicate a loop body + * somehow. + */ + disable(GraalOptions.LoopPeeling, values); + disable(GraalOptions.LoopUnswitch, values); + disable(GraalOptions.FullUnroll, values); + disable(GraalOptions.PartialUnroll, values); + + /* + * Do not align loop headers to further reduce code size. + */ + GraalOptions.LoopHeaderAlignment.update(values, 0); + GraalOptions.IsolatedLoopHeaderAlignment.update(values, 0); + + /* + * Do not run PEA - it can fan out allocations too much. + */ + disable(GraalOptions.PartialEscapeAnalysis, values); + + /* + * Do not fan out division. + */ + disable(GraalOptions.OptimizeDiv, values); + + /* + * Do more conditional elimination. + */ + GraalOptions.ConditionalEliminationMaxIterations.update(values, 10); + + /* + * Every dead code elimination should be non-optional + */ + disable(DeadCodeEliminationPhase.Options.ReduceDCE, values); + } + + public static void disable(OptionKey key, EconomicMap, Object> values) { + key.update(values, false); + } + + public static void enable(OptionKey key, EconomicMap, Object> values) { + key.update(values, true); + } + /** * Only allows 'b' or positive numeric optimization levels, throws a user error otherwise. */ @@ -304,6 +360,9 @@ private static OptimizationLevel parseOptimizationLevel(String value) { if (value.equals("b")) { return OptimizationLevel.BUILD_TIME; } + if (value.equals("s")) { + return OptimizationLevel.SIZE; + } int intLevel; try { @@ -335,11 +394,20 @@ public static boolean useEconomyCompilerConfig(OptionValues options) { return "b".equals(Optimize.getValue(options)); } + public static boolean useCodeSizeCompilerConfig(OptionValues options) { + return "s".equals(Optimize.getValue(options)); + } + @Fold public static boolean useEconomyCompilerConfig() { return useEconomyCompilerConfig(HostedOptionValues.singleton()); } + @Fold + public static boolean useCodeSizeCompilerConfig() { + return useCodeSizeCompilerConfig(HostedOptionValues.singleton()); + } + @Fold public static boolean isMaximumOptimizationLevel() { return optimizationLevel() == OptimizationLevel.O3; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java index e2938db1e891..f8ffc8ebd656 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java @@ -1581,17 +1581,21 @@ private static boolean checkInvocationPluginMethods(SubstrateReplacements replac return true; } - public static Suites createSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, boolean hosted) { + public static Suites createSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, boolean hosted, OptionValues optionsToUse) { SubstrateBackend backend = runtimeConfig.getBackendForNormalMethod(); Suites suites; if (hosted) { - suites = GraalConfiguration.hostedInstance().createSuites(HostedOptionValues.singleton(), hosted, ConfigurationValues.getTarget().arch); + suites = GraalConfiguration.hostedInstance().createSuites(optionsToUse == null ? HostedOptionValues.singleton() : optionsToUse, hosted, ConfigurationValues.getTarget().arch); } else { - suites = GraalConfiguration.runtimeInstance().createSuites(RuntimeOptionValues.singleton(), hosted, ConfigurationValues.getTarget().arch); + suites = GraalConfiguration.runtimeInstance().createSuites(optionsToUse == null ? RuntimeOptionValues.singleton() : optionsToUse, hosted, ConfigurationValues.getTarget().arch); } return modifySuites(backend, suites, featureHandler, hosted, false); } + public static Suites createSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, boolean hosted) { + return createSuites(featureHandler, runtimeConfig, hosted, null); + } + public static Suites createFirstTierSuites(FeatureHandler featureHandler, RuntimeConfiguration runtimeConfig, boolean hosted) { SubstrateBackend backend = runtimeConfig.getBackendForNormalMethod(); Suites suites; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageViaCC.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageViaCC.java index 1ad8e3e63929..c3f9f2a8e16a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageViaCC.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageViaCC.java @@ -47,6 +47,7 @@ import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.util.InterruptImageBuilding; +import com.oracle.svm.hosted.DeadlockWatchdog; import com.oracle.svm.hosted.FeatureImpl.BeforeImageWriteAccessImpl; import com.oracle.svm.hosted.NativeImageOptions; import com.oracle.svm.hosted.c.NativeLibraries; @@ -138,6 +139,11 @@ private void runLinkerCommand(String imageName, LinkerInvocation inv, List lines; try (InputStream inputStream = linkerProcess.getInputStream()) { + /* + * The linker can be slow, record activity just before so that we have the full + * watchdog interval available. + */ + DeadlockWatchdog.singleton().recordActivity(); lines = FileUtils.readAllLines(inputStream); FileUtils.traceCommandOutput(lines); } diff --git a/vm/mx.vm/mx_vm_benchmark.py b/vm/mx.vm/mx_vm_benchmark.py index ad00e3f54dcc..7c66a2b82895 100644 --- a/vm/mx.vm/mx_vm_benchmark.py +++ b/vm/mx.vm/mx_vm_benchmark.py @@ -552,7 +552,7 @@ def _configure_from_name(self, config_name): # This defines the allowed config names for NativeImageVM. The ones registered will be available via --jvm-config rule = r'^(?Pnative-architecture-)?(?Pstring-inlining-)?(?Pgate-)?(?Pupx-)?(?Pquickbuild-)?(?Pg1gc-)?(?Pllvm-)?(?Ppgo-|pgo-ctx-insens-|pgo-sampler-)?(?Pinline-)?' \ r'(?Pinsens-|allocsens-|1obj-|2obj1h-|3obj2h-|4obj3h-)?(?Pno-inline-)?(?Pjdk-profiles-collect-|adopted-jdk-pgo-)?' \ - r'(?Pprofile-inference-feature-extraction-|profile-inference-pgo-)?(?Psafepoint-sampler-|async-sampler-)?(?PO0-|O1-|O2-|O3-)?(?Pce-|ee-)?$' + r'(?Pprofile-inference-feature-extraction-|profile-inference-pgo-)?(?Psafepoint-sampler-|async-sampler-)?(?PO0-|O1-|O2-|O3-|Os-)?(?Pce-|ee-)?$' mx.logv(f"== Registering configuration: {config_name}") match_name = f"{config_name}-" # adding trailing dash to simplify the regex @@ -679,7 +679,7 @@ def generate_profiling_package_prefixes(): if matching.group("optimization_level") is not None: olevel = matching.group("optimization_level")[:-1] mx.logv(f"GraalVM optimization level is set to: {olevel}") - if olevel in ["O0", "O1", "O2", "O3"]: + if olevel in ["O0", "O1", "O2", "O3", "Os"]: self.optimization_level = olevel else: mx.abort(f"Unknown configuration for optimization level: {olevel}") @@ -1801,7 +1801,7 @@ def register_graalvm_vms(): mx_polybenchmarks_benchmark.polybenchmark_vm_registry.add_vm(PolyBenchVm(host_vm_name, "native", [], ["--native"])) mx_polybenchmarks_benchmark.rules = polybenchmark_rules - optimization_levels = ['O0', 'O1', 'O2', 'O3'] + optimization_levels = ['O0', 'O1', 'O2', 'O3', 'Os'] # Inlining before analysis is done by default analysis_context_sensitivity = ['insens', 'allocsens', '1obj', '2obj1h', '3obj2h', '4obj3h']