From 6b65c44d45ad2b895e139dbf60373912985947de Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 15 Nov 2012 22:23:26 +0400 Subject: [PATCH] Optimize DataFlowInfo.and() Instead of copying everything, we now only completely copy one data flow info and use another as a delegation target --- .../autocasts/DelegatingDataFlowInfo.java | 54 +++++++++++++++---- .../tests/dataFlowInfoTraversal/ManyIfs.kt | 18 +++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 ++ 3 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java index 7b496f3b6de..5b4d115302b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DelegatingDataFlowInfo.java @@ -52,6 +52,36 @@ import static org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability.NOT_NUL this.typeInfo = typeInfo; } + @NotNull + private Map getCompleteNullabilityInfo() { + Map result = Maps.newHashMap(); + DelegatingDataFlowInfo info = this; + while (info != null) { + for (Map.Entry entry : info.nullabilityInfo.entrySet()) { + DataFlowValue key = entry.getKey(); + Nullability value = entry.getValue(); + if (!result.containsKey(key)) { + result.put(key, value); + } + } + info = (DelegatingDataFlowInfo) info.parent; + } + return result; + } + + @NotNull + private ListMultimap getCompleteTypeInfo() { + ListMultimap result = newTypeInfo(); + DelegatingDataFlowInfo info = this; + while (info != null) { + for (DataFlowValue key : info.typeInfo.keySet()) { + result.putAll(key, info.typeInfo.get(key)); + } + info = (DelegatingDataFlowInfo) info.parent; + } + return result; + } + @Override @NotNull public Nullability getNullability(@NotNull DataFlowValue key) { @@ -152,27 +182,29 @@ import static org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability.NOT_NUL @Override public DataFlowInfo and(@NotNull DataFlowInfo otherInfo) { if (otherInfo == EMPTY) return this; + if (this == EMPTY) return otherInfo; + if (this == otherInfo) return this; assert otherInfo instanceof DelegatingDataFlowInfo : "Unknown DataFlowInfo type: " + otherInfo; DelegatingDataFlowInfo other = (DelegatingDataFlowInfo) otherInfo; Map nullabilityMapBuilder = Maps.newHashMap(); - nullabilityMapBuilder.putAll(nullabilityInfo); - for (Map.Entry entry : other.nullabilityInfo.entrySet()) { + for (Map.Entry entry : other.getCompleteNullabilityInfo().entrySet()) { DataFlowValue key = entry.getKey(); Nullability otherFlags = entry.getValue(); - Nullability thisFlags = nullabilityInfo.get(key); - if (thisFlags != null) { - nullabilityMapBuilder.put(key, thisFlags.and(otherFlags)); - } - else { - nullabilityMapBuilder.put(key, otherFlags); + Nullability thisFlags = getNullability(key); + Nullability flags = thisFlags.and(otherFlags); + if (flags != thisFlags) { + nullabilityMapBuilder.put(key, flags); } } - ListMultimap newTypeInfo = copyTypeInfo(); - newTypeInfo.putAll(other.typeInfo); - return new DelegatingDataFlowInfo(null, ImmutableMap.copyOf(nullabilityMapBuilder), newTypeInfo); + ListMultimap newTypeInfo = other.getCompleteTypeInfo(); + if (nullabilityMapBuilder.isEmpty() && newTypeInfo.isEmpty()) { + return this; + } + + return new DelegatingDataFlowInfo(this, ImmutableMap.copyOf(nullabilityMapBuilder), newTypeInfo); } @NotNull diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.kt new file mode 100644 index 00000000000..a9b35e8a54c --- /dev/null +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.kt @@ -0,0 +1,18 @@ +fun foo(x: Number) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + if (x is Int) { + } } } } } } } } } } } } } } } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 180cdd583b5..f8f53bfc714 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1281,6 +1281,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/IsExpression.kt"); } + @TestMetadata("ManyIfs.kt") + public void testManyIfs() throws Exception { + doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/ManyIfs.kt"); + } + @TestMetadata("MultiDeclaration.kt") public void testMultiDeclaration() throws Exception { doTest("compiler/testData/diagnostics/tests/dataFlowInfoTraversal/MultiDeclaration.kt");