[LLVMdev] Long-Term ISel Design

David Greene dag at cray.com
Wed Mar 16 13:44:21 PDT 2011


All,

As I've done more integrating of AVX work upstream and more tuning here,
I've run across several things which are clunky in the current isel
design.  A couple examples I can remember offhand:

1. We have special target-specific operators for certain shuffles in X86,
   such as X86unpckl.  I don't completely understand why but Bruno
   indicated it was to address inefficiecies.  One of those is the need
   to check masks multiple times (once at legalize and again at isel).

2. Sometimes DAGs are legal in some contexts but not others and it is a
   pain to deal with.  A good example is VBROADCAST, where a <0,0,0,0>
   shuffle is natively supported if the source vector is in memory.
   Otherwise it's not legal and manual lowering is required.  In this
   case the legality check is doing the DAG match by hand, replicating
   what TableGen-produced code already does.

These two examples are related: we're duplicating functionality manually
that's already available automatically.

As I've been thinking about this, it strikes me that we could get rid of
the target-specific operators and a lot of other manual checks if we
just had another isel phase.  Let's say we structured things this way:

                  legalize
                     |
                     V
        manual lowering (X86ISelLowering)
                     |
                     V
         manual isel (X86ISelDAGToDAG)
                     |
                     V
    table-driven isel (.td files/X86GenDAGISel)
                     |
                     V
      manual isel (some to-be-design piece)

The idea is that we keep the existing manual pieces where they are to
clean things up for TableGen-based isel and/or handle special cases.
Maybe we consider getting rid of some in the future but that's a
separate questions.

The way things are now, if table-driven isel fails the codegen aborts.
In the above scheme we get one last chance to do manual lowering before
we give up.  This helps the shuffle mask case by turning this:

                             legalize
                                |
                                V
               check shuffle mask legality (X86ISelLowering)
                                |
                                V
       check shuffle mask legality (table-driven isel predicates)

To this:

                             legalize
                                |
                                V
              X86ISelLowering (no mask legality checks)
                                |
                                V
       check shuffle mask legality (table-driven isel predicates)
                                |
                                V
                 lower remaining shuffles manually

The advantage is that in the final stage we already know the shuffle
mask isn't implementable manually so there's no need to check for
legality.  We simply need to implement whatever X86ISelLowering would
have done in those case previously.

This also helps example 2.  In the memory-operand case we will match to
a VBROADCASTSS/D.  If we don't match we'll fall through to manual
lowering and we'll implement the reg-reg broadcast via some other
combination of shuffles.  So we more gracefully handle situations where
sometimes things are legal and sometimes they aren't depending on the
context.

Perhaps I'm repeating something that's already been discussed.

Thoughts?

                          -Dave



More information about the llvm-dev mailing list