# R8 Optimization: Value Assumption

DevFeed: [R8 Optimization: Value Assumption](<https://devfeed.tech/articles/r8-optimization-value-assumption-20965.md>)

Original publisher: [Read original article](<https://jakewharton.com/r8-optimization-value-assumption/>)

Published: 2019-01-22T00:00:00Z

Content type: tutorial

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Android](<https://devfeed.tech/topics/android.md>), [Exception](<https://devfeed.tech/topics/exception.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [code](<https://devfeed.tech/tags/code.md>), [exception](<https://devfeed.tech/tags/exception.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>)

## AI overview

This article explains how R8 uses nullability range tracking for dead-code elimination and introduces a configuration flag that lets developers declare value ranges or fixed values for fields and method returns. The supplied text indicates that this can help R8 eliminate redundant checks for values such as integers, although the example is truncated.

## Source excerpt

Note: This post is part of a series on D8 and R8, Android's new dexer and optimizer, respectively. For an intro to D8 read "Android's Java 8 support". For an intro to R8 read "R8 Optimization: Staticization". The previous post (part 1, part 2) featured R8 performing data-flow analysis of variables in order to determine if they were maybe null, always null, or never null, and then potentially performing dead-code elimination based on that info. Another way to think about that optimization is that R8 tracks the use of a variable along with a range of its possible nullability. If any conditional against that range can be determined to always produce the same result, dead-code elimination removes the unused branches and the conditional disappears. Part 2 of the last post ended with an example where an args variable was passed into a first method and then checked for null before printing. System.out.println(first(args)); if (args == null) { System.out.println("null!"); } The range of nullability for args in that snippet is [null, non-null] (meaning its either null or a non-null reference). System.out.println(first(args/* [null, non-null] */)); if (args/* [null, non-null] */ == null) { System.out.println("null!"); } In this state, R8 can't do anything to the conditional because the reference might actually be null. However, if the first method checks its argument for null and throws an exception (as it did in that post), null can be eliminated as a possible value after the method call. System.out.println(first(args/* [null, non-null] */)); if (args/* [non-null] */ == null) { System.out.println("null!"); } With args only able to be a non-null reference at the time of the if check against null, the conditional will always be false and can be removed by normal dead-code elimination. System.out.println(first(args/* [null, non-null] */)); if (false) { System.out.println("null!"); } Right now this range tracking doesn't extend beyond nullability. Checking an integer for being p