[llvm-dev] [IR question] Switching on pointers

mats petersson via llvm-dev llvm-dev at lists.llvm.org
Tue May 16 09:45:49 PDT 2017


On 15 May 2017 at 17:29, Benoit Vey via llvm-dev <llvm-dev at lists.llvm.org>
wrote:

> Hi.
>
> First of all, some context. I'm trying to implement a new functionality in
> an LLVM-based compiler and I need to take various actions based on the
> value of a given pointer, the possible values being the addresses of
> various global constants. I tried to use a `switch` instruction but I
> encountered several problems.
>
> The "ideal switch" I'd like to have would look something like this (with
> way more cases):
>
>     ; ModuleID = 'module'
>     source_filename = "module"
>
>     @var0 = global i32 0
>     @var1 = global i32 0
>
>     define i32 @func(i32*) {
>     entry:
>       switch i32* %0, label %unreachable [
>         i32* @var0, label %var0
>         i32* @var1, label %var1
>       ]
>
>     var0:                                             ; preds = %entry
>       br label %post
>
>     var1:                                             ; preds = %entry
>       br label %post
>
>     unreachable:                                      ; preds = %entry
>       unreachable
>
>     post:                                             ; preds = %var1,
> %var0
>       %1 = phi i32 [ 0, %var0 ], [ 1, %var1 ]
>       ret i32 %1
>     }
>
> This example is impossible because a `switch` cannot have pointer
> operands. So I tried with `ptrtoint`, turning the `switch` into this:
>
>       %1 = ptrtoint i32* %0 to i64
>       switch i64 %1, label %unreachable [
>         i64 ptrtoint (i32* @var0 to i64), label %var0
>         i64 ptrtoint (i32* @var1 to i64), label %var1
>       ]
>
> I'm a bit baffled by that one. According to the documentation the address
> of a global value is a constant, yet this `switch` is impossible because
> the result of the `ptrtoint` isn't a constant integer.
>
> At that point, I don't really know how to proceed. My questions are:
>
> - Why is `switch` restricted to integers?
> - What is the result of a constant `ptrtoint` and why isn't it a constant
> integer?
> - Is there a way to switch on pointers despite these restrictions?
>
> Thanks.
>
> ----------------------------------------------------------------
> This message was sent using IMP, the Internet Messaging Program.
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>

Aside from the obvious answer of "the switch needs compile time constants"
(what I call "true constants" - they are constants that the LLVM compiler
knows the actual value of, not constants as in "won't change during the
execution of the program", such as variable and function addresses), it
should be noted that unless the compiler & linker can be certain that for
example the var0 and var1 address are "next to each other", this sort of
construct will not benefit from any "switch" optimisation, it will be
exactly like a switch with large, non-close values: an if/else if/else ...
chain - probably not even able to do any cleverness of building a tree of
which comes first [in a generic case of this, at the very least]. So if you
have a case where you need to resolve a language construct where you can
switch on a reference to a variable referring to a particular variable,
then you probably have to make it into a compare + branch - or perhaps have
a table and iterate over the choices. Even if LLVM knew how to do this, it
wouldn't be possible to produce anything noticeably better [at least I
can't think of anything - if anyone has some clever ways to solve this kind
of problem, I would appreciate a comment...]

I still would like to hear from Benoit as to what the goal is here. I'm
only guessing that it's a language where you can do something like "ref =
var0; ... switch(ref) case var0: ... ; case var1: ... " or some such. Not
that I know for sure what language that is.

--
Mats
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170516/0427015d/attachment.html>


More information about the llvm-dev mailing list