[PATCH] D12249: Remove the final bit test during lowering switch statement if all cases in bit test cover a contiguous range.

Cong Hou via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 21 14:01:45 PDT 2015


congh created this revision.
congh added reviewers: hfinkel, spatel, davidxl.
congh added a subscriber: llvm-commits.

When lowering switch statement, if bit tests are used then LLVM will always generates a jump to the default statement in the last bit test. However, this is not necessary when all cases in bit tests cover a contiguous range. This is because when generating the bit tests header MBB, there is a range check that guarantees cases in bit tests won't go outside of [low, high], where low and high are minimum and maximum case values in the bit tests. This patch checks if this is the case and then doesn't emit jump to default statement and hence saves a bit test and a branch.

For example, given the following IR:

define void @foo(i32 %x) {
entry:
  switch i32 %x, label %return [
    i32 0, label %bb0
    i32 2, label %bb0
    i32 4, label %bb0
    i32 1, label %bb1
    i32 3, label %bb1
    i32 5, label %bb1
  ]
bb0: tail call void @a() br label %return
bb1: tail call void @b() br label %return
return: ret void
}
declare void @a()
declare void @b()


Previously LLVM generates the following MC:


BB#0: derived from LLVM BB %entry
    Live Ins: %EDI
	CMP32ri8 %EDI, 5, %EFLAGS<imp-def>
	JA_1 <BB#3>, %EFLAGS<imp-use>
    Successors according to CFG: BB#3(16) BB#1(16)

BB#1: derived from LLVM BB %entry
    Live Ins: %EDI
    Predecessors according to CFG: BB#0
	%EAX<def> = MOV32ri 21
	BT32rr %EAX<kill>, %EDI, %EFLAGS<imp-def>
	JAE_1 <BB#2>, %EFLAGS<imp-use>
    Successors according to CFG: BB#4(48) BB#2(48)

BB#4: derived from LLVM BB %bb0
    Predecessors according to CFG: BB#1
	TAILJMPd64 <ga:@a>, <regmask>, %RSP<imp-use>, %RSP<imp-use>

BB#2: derived from LLVM BB %entry
    Live Ins: %EDI
    Predecessors according to CFG: BB#1
	%EAX<def> = MOV32ri 42
	BT32rr %EAX<kill>, %EDI<kill>, %EFLAGS<imp-def>
	JAE_1 <BB#3>, %EFLAGS<imp-use>
    Successors according to CFG: BB#5(48) BB#3(16)

BB#5: derived from LLVM BB %bb1
    Predecessors according to CFG: BB#2
	TAILJMPd64 <ga:@b>, <regmask>, %RSP<imp-use>, %RSP<imp-use>

BB#3: derived from LLVM BB %return
    Predecessors according to CFG: BB#0 BB#2
	RETQ




With this patch the MC generated is:



BB#0: derived from LLVM BB %entry
    Live Ins: %EDI
	CMP32ri8 %EDI, 5, %EFLAGS<imp-def>
	JBE_1 <BB#1>, %EFLAGS<imp-use>
    Successors according to CFG: BB#3(16) BB#1(16)

BB#3: derived from LLVM BB %return
    Predecessors according to CFG: BB#0
	RETQ

BB#1: derived from LLVM BB %entry
    Live Ins: %EDI
    Predecessors according to CFG: BB#0
	%EAX<def> = MOV32ri 21
	BT32rr %EAX<kill>, %EDI<kill>, %EFLAGS<imp-def>
	JAE_1 <BB#2>, %EFLAGS<imp-use>
    Successors according to CFG: BB#4(48) BB#2(48)

BB#4: derived from LLVM BB %bb0
    Predecessors according to CFG: BB#1
	TAILJMPd64 <ga:@a>, <regmask>, %RSP<imp-use>, %RSP<imp-use>

BB#2: derived from LLVM BB %bb1
    Predecessors according to CFG: BB#1
	TAILJMPd64 <ga:@b>, <regmask>, %RSP<imp-use>, %RSP<imp-use>


We can save one basic block with 3 instructions. 

http://reviews.llvm.org/D12249

Files:
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
  lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
  test/CodeGen/X86/switch.ll

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D12249.32861.patch
Type: text/x-patch
Size: 6493 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150821/fdb6a9d2/attachment.bin>


More information about the llvm-commits mailing list