Do not create a HBoundType when the instruction is non-null.
We don't need to refine the type after a null check, if the
instruction is known non null or null. As a side effect, this
avoids replacing HLoadClass instructions with HBoundType instructions.
bug:22116987
(cherry picked from commit 3abd437507f8ba30a238a52c273c9944dcb9d5a1)
Change-Id: I5e56de293554534195ade9770b7d1e4b078d685b
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 04c3963..2cffe02 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -3709,6 +3709,7 @@
uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
uint16_t GetTypeIndex() const { return type_index_; }
bool IsReferrersClass() const { return is_referrers_class_; }
+ bool CanBeNull() const OVERRIDE { return false; }
bool NeedsEnvironment() const OVERRIDE {
// Will call runtime and load the class if the class is not loaded yet.
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 3d6606b..68316c2 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -99,6 +99,12 @@
return;
}
+ if (!obj->CanBeNull() || obj->IsNullConstant()) {
+ // Null check is dead code and will be removed by DCE.
+ return;
+ }
+ DCHECK(!obj->IsLoadClass()) << "We should not replace HLoadClass instructions";
+
// We only need to bound the type if we have uses in the relevant block.
// So start with null and create the HBoundType lazily, only if it's needed.
HBoundType* bound_type = nullptr;
@@ -160,6 +166,7 @@
// input.
return;
}
+ DCHECK(!obj->IsLoadClass()) << "We should not replace HLoadClass instructions";
for (HUseIterator<HInstruction*> it(obj->GetUses()); !it.Done(); it.Advance()) {
HInstruction* user = it.Current()->GetUser();
if (instanceOfTrueBlock->Dominates(user->GetBlock())) {
diff --git a/test/519-bound-load-class/src/Main.java b/test/519-bound-load-class/src/Main.java
index 41bb951..cddeb09 100644
--- a/test/519-bound-load-class/src/Main.java
+++ b/test/519-bound-load-class/src/Main.java
@@ -16,9 +16,24 @@
public class Main {
public static void main(String[] args) {
+ testInstanceOf();
+ try {
+ testNull();
+ throw new Error("Expected ClassClastException");
+ } catch (ClassCastException e) { /* ignore */ }
+ }
+
+ public static void testInstanceOf() {
Object o = Main.class;
if (o instanceof Main) {
System.out.println((Main)o);
}
}
+
+ public static void testNull() {
+ Object o = Main.class;
+ if (o != null) {
+ System.out.println((Main)o);
+ }
+ }
}