LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 926 - sdisel switch lowering can be improved
Summary: sdisel switch lowering can be improved
Status: CONFIRMED
Alias: None
Product: libraries
Classification: Unclassified
Component: Common Code Generator Code (show other bugs)
Version: 1.8
Hardware: All All
: P enhancement
Assignee: Unassigned LLVM Bugs
URL:
Keywords: code-quality
Depends on:
Blocks:
 
Reported: 2006-09-27 01:35 PDT by Chris Lattner
Modified: 2010-12-02 01:15 PST (History)
3 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lattner 2006-09-27 01:35:15 PDT
First, the trivial thing: a switch lowered to a series of conditional branches always results in an explicit 
"fallthrough" uncond branch to the next block from the initial block.  This is probably a minor book-
keeping bug:

        cmpl $6, %eax
        jl LBB1_20      #entry
***   jmp LBB1_15     #entry
LBB1_15:        #entry


More significantly, we should change the heuristic of the switch lowering a bit.  Specifically, right now, 
at the top level, we decide whether to lower the switch to a series of branches or to a table jump.  I 
think we should always go through the "branch sequence" code path, but make it a bit more 
sophisticated.

In particular, the worklist should start out with a single record with all the case ranges on it.  Each time 
through the loop, a range is popped off.  If the range satisfies the conditions for a tbljmp, emit one.  
Otherwise, split in half and emit a branch to choose between the two.

This would allow us to handle switches with dense portions that are spread out (e.g. 0...100  + 
2000...2100) as two separate tbljump pieces.

This would also make it more natural to plug in other heuristics.  For example, perlbmk has a switch 
that looks like this:
        switch uint %tmp158, label %bb336 [
                 uint 0, label %bb338
                 uint 1, label %bb338
                 uint 2, label %bb338
                 uint 3, label %bb338
                 uint 4, label %bb338
                 uint 5, label %bb338
                 uint 6, label %bb338
                 uint 7, label %bb
                 uint 8, label %bb338
                 uint 9, label %bb322
                 uint 10, label %bb324
                 uint 11, label %bb326
                 uint 12, label %bb328
                 uint 13, label %bb330
                 uint 14, label %bb332
                 uint 15, label %bb334
...

When emitted as a branch tree, the leaves end up doing lots of work to discriminate between the 0->6 
cases, when they all go to the same place.

Another nice xform is to do the "shift/and" technique for switches.

-Chris
Comment 1 Bill Wendling 2006-10-19 18:36:04 PDT
Fixed the first, easy part where it creates a "jmp" to the next block.

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061016/038759.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20061016/038760.html

The more interesting bit is yet to be done.
Comment 2 Chris Lattner 2006-11-28 22:26:30 PST
Another fun thing we could do:
http://www.cs.princeton.edu/software/lcc/doc/mrst.pdf
Comment 3 Anton Korobeynikov 2007-02-28 12:51:59 PST
LLVM-to-LLVM pass implemented in:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070226/045250.html
Comment 4 Anton Korobeynikov 2007-03-20 11:29:02 PDT
Mine.

First part here:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070319/046002.html
Comment 7 Chris Lattner 2010-12-02 01:15:24 PST
What is left on this old bug?