[llvm] r226600 - Prevent binary-tree deterioration in sparse switch statements.

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Thu Jan 22 06:16:42 PST 2015


Hi Daniel,

I've tried the exact same approach back on Sep 2014 but I got a ~4%
performance degradation in
External/SPEC/CINT2006/462_libquantum/462_libquantum. Back in the day
it would affect switch codegen in the  "quantum_objcode_run" function,
in objcode.c => jump tables and a bunch of code started to be emitted
after the patch.

Since it has been a while, much could have changed and that could no
longer apply.
Have you measured the impact of this on the test-suite?

Thanks,

On Tue, Jan 20, 2015 at 5:43 PM, Daniel Jasper <djasper at google.com> wrote:
> Author: djasper
> Date: Tue Jan 20 13:43:33 2015
> New Revision: 226600
>
> URL: http://llvm.org/viewvc/llvm-project?rev=226600&view=rev
> Log:
> Prevent binary-tree deterioration in sparse switch statements.
>
> This addresses part of llvm.org/PR22262. Specifically, it prevents
> considering the densities of sub-ranges that have fewer than
> TLI.getMinimumJumpTableEntries() elements. Those densities won't help
> jump tables.
>
> This is not a complete solution but works around the most pressing
> issue.
>
> Review: http://reviews.llvm.org/D7070
>
> Modified:
>     llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>     llvm/trunk/test/CodeGen/X86/switch-bt.ll
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=226600&r1=226599&r2=226600&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Tue Jan 20 13:43:33 2015
> @@ -2420,6 +2420,7 @@ bool SelectionDAGBuilder::handleBTSplitS
>    DEBUG(dbgs() << "Selecting best pivot: \n"
>                 << "First: " << First << ", Last: " << Last <<'\n'
>                 << "LSize: " << LSize << ", RSize: " << RSize << '\n');
> +  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
>    for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second;
>         J!=E; ++I, ++J) {
>      const APInt &LEnd = cast<ConstantInt>(I->High)->getValue();
> @@ -2429,10 +2430,16 @@ bool SelectionDAGBuilder::handleBTSplitS
>             "Invalid case distance");
>      // Use volatile double here to avoid excess precision issues on some hosts,
>      // e.g. that use 80-bit X87 registers.
> +    // Only consider the density of sub-ranges that actually have sufficient
> +    // entries to be lowered as a jump table.
>      volatile double LDensity =
> -        LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble();
> +        LSize.ult(TLI.getMinimumJumpTableEntries())
> +            ? 0.0
> +            : LSize.roundToDouble() / (LEnd - First + 1ULL).roundToDouble();
>      volatile double RDensity =
> -        RSize.roundToDouble() / (Last - RBegin + 1ULL).roundToDouble();
> +        RSize.ult(TLI.getMinimumJumpTableEntries())
> +            ? 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"
> @@ -2450,13 +2457,8 @@ bool SelectionDAGBuilder::handleBTSplitS
>      RSize -= J->size();
>    }
>
> -  const TargetLowering &TLI = DAG.getTargetLoweringInfo();
> -  if (areJTsAllowed(TLI)) {
> -    // If our case is dense we *really* should handle it earlier!
> -    assert((FMetric > 0) && "Should handle dense range earlier!");
> -  } else {
> +  if (FMetric == 0 || !areJTsAllowed(TLI))
>      Pivot = CR.Range.first + Size/2;
> -  }
>    splitSwitchCase(CR, Pivot, WorkList, SV, SwitchBB);
>    return true;
>  }
>
> Modified: llvm/trunk/test/CodeGen/X86/switch-bt.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/switch-bt.ll?rev=226600&r1=226599&r2=226600&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/switch-bt.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/switch-bt.ll Tue Jan 20 13:43:33 2015
> @@ -99,3 +99,61 @@ if.then:
>  if.end:
>    ret void
>  }
> +
> +; Ensure that optimizing for jump tables doesn't needlessly deteriorate the
> +; created binary tree search. See PR22262.
> +define void @test4(i32 %x, i32* %y) {
> +; CHECK-LABEL: test4:
> +
> +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 balanced binary switch here would start with a comparison against 39, but
> +; it is currently starting with 29 because of the density-sum heuristic.
> +; 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
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



-- 
Bruno Cardoso Lopes
http://www.brunocardoso.cc



More information about the llvm-commits mailing list