[PATCH] Prevent binary-tree deterioration in sparse trees.

Daniel Jasper djasper at google.com
Tue Jan 20 10:23:06 PST 2015


Hi chandlerc,

This address part of llvm.org/PR22262. Specifically, it prevents counting a single element as having a density of 1 and thereby outweighing all other split points.

This is not a complete solution but works around the most pressing issue.

http://reviews.llvm.org/D7070

Files:
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  test/CodeGen/X86/switch-jump-table.ll

Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2430,9 +2430,11 @@
     // Use volatile double here to avoid excess precision issues on some hosts,
     // e.g. that use 80-bit X87 registers.
     volatile double LDensity =
-        LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble();
+        LEnd == First ? 0.0 : LSize.roundToDouble() /
+                                  (LEnd - First + 1ULL).roundToDouble();
     volatile double RDensity =
-        RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble();
+        Last == RBegin ? 0.0 : RSize.roundToDouble() /
+                                   (Last - RBegin + 1ULL).roundToDouble();
     volatile double Metric = Range.logBase2() * (LDensity + RDensity);
     // Should always split in some non-trivial place
     DEBUG(dbgs() <<"=>Step\n"
Index: test/CodeGen/X86/switch-jump-table.ll
===================================================================
--- test/CodeGen/X86/switch-jump-table.ll
+++ test/CodeGen/X86/switch-jump-table.ll
@@ -50,3 +50,59 @@
 ; CHECK-NEXT: .long  .LBB0_5
 ; CHECK-NOT: .long
 }
+
+; Ensure that optimizing for jump tables doesn't needlessly deteriorate the
+; created binary tree search. See PR22262.
+define void @test(i32 %x, i32* %y) {
+; CHECK-LABEL: test:
+
+entry:
+  switch i32 %x, label %sw.default [
+    i32 10, label %sw.bb
+    i32 20, label %sw.bb1
+    i32 30, label %sw.bb2
+    i32 40, label %sw.bb3
+    i32 50, label %sw.bb4
+    i32 60, label %sw.bb5
+  ]
+sw.bb:
+  store i32 1, i32* %y
+  br label %sw.epilog
+sw.bb1:
+  store i32 2, i32* %y
+  br label %sw.epilog
+sw.bb2:
+  store i32 3, i32* %y
+  br label %sw.epilog
+sw.bb3:
+  store i32 4, i32* %y
+  br label %sw.epilog
+sw.bb4:
+  store i32 5, i32* %y
+  br label %sw.epilog
+sw.bb5:
+  store i32 6, i32* %y
+  br label %sw.epilog
+sw.default:
+  store i32 7, i32* %y
+  br label %sw.epilog
+sw.epilog:
+  ret void
+; The correct binary switch here would start with a comparison against 39.
+; CHECK: cmpl $29
+; CHECK: jg
+; CHECK: cmpl $10
+; CHECK: jne
+; CHECK: cmpl $49
+; CHECK: jg
+; CHECK: cmpl $30
+; CHECK: jne
+; CHECK: cmpl $20
+; CHECK: jne
+; CHECK: cmpl $50
+; CHECK: jne
+; CHECK: cmpl $40
+; CHECK: jne
+; CHECK: cmpl $60
+; CHECK: jne
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D7070.18443.patch
Type: text/x-patch
Size: 2431 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150120/5046d52e/attachment.bin>


More information about the llvm-commits mailing list