Chris Lattner wrote:> On May 5, 2009, at 8:09 PM, Talin wrote: > > >> I wanted to mention, by the way, that my need/desire for this hasn't >> gone away :) >> >> And my wish list still includes support for something like uintptr_t >> - a >> primitive integer type that is defined to always be the same size as a >> pointer, however large or small that may be on different platforms. >> (So >> that the frontend doesn't need to know how big a pointer is and can >> generate the same IR that works on both 32-bit and 64-bit platforms.) >> > > Why not just use a pointer, such as i8*? >Suppose I have an STL-like container that has a 'begin' and 'end' pointer. Now I want to find the size() of the container. Since you cannot subtract pointers in LLVM IR, you have to cast them to an integer type first. But what integer type do you cast them to? I suppose you could simply always cast them to i64, and hope that the backend will generate efficient code for the subtraction, but I have no way of knowing this. Now, I'm going to anticipate what I think will be your next argument, which is that at some point I must know the size of the result since I am assigning the result of size() to some interger variable eventually. Which is true, however, if the size of that eventual variable is smaller than a pointer, then I want to check it for overflow before I do the assignment. I don't want to just do a blind bitcast and have the top bits be lopped off. The problem of checking for overflow when assigning from an integer of unknown size to an integer of known size is left as an exercise for the reader.> -Chris >
The TargetData class gives you the size of the pointer. (getPointerSize and getPointerSizeInBits). Can it help you ? On Wed, May 6, 2009 at 6:55 AM, Talin <viridia at gmail.com> wrote:> Chris Lattner wrote: > > On May 5, 2009, at 8:09 PM, Talin wrote: > > > > > >> I wanted to mention, by the way, that my need/desire for this hasn't > >> gone away :) > >> > >> And my wish list still includes support for something like uintptr_t > >> - a > >> primitive integer type that is defined to always be the same size as a > >> pointer, however large or small that may be on different platforms. > >> (So > >> that the frontend doesn't need to know how big a pointer is and can > >> generate the same IR that works on both 32-bit and 64-bit platforms.) > >> > > > > Why not just use a pointer, such as i8*? > > > Suppose I have an STL-like container that has a 'begin' and 'end' > pointer. Now I want to find the size() of the container. Since you > cannot subtract pointers in LLVM IR, you have to cast them to an integer > type first. But what integer type do you cast them to? I suppose you > could simply always cast them to i64, and hope that the backend will > generate efficient code for the subtraction, but I have no way of > knowing this. > > Now, I'm going to anticipate what I think will be your next argument, > which is that at some point I must know the size of the result since I > am assigning the result of size() to some interger variable eventually. > Which is true, however, if the size of that eventual variable is smaller > than a pointer, then I want to check it for overflow before I do the > assignment. I don't want to just do a blind bitcast and have the top > bits be lopped off. > > The problem of checking for overflow when assigning from an integer of > unknown size to an integer of known size is left as an exercise for the > reader. > > -Chris > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090506/6db3c5cf/attachment.html>
On Tue, May 5, 2009 at 9:55 PM, Talin <viridia at gmail.com> wrote:> Chris Lattner wrote: >> On May 5, 2009, at 8:09 PM, Talin wrote: >> >> >>> I wanted to mention, by the way, that my need/desire for this hasn't >>> gone away :) >>> >>> And my wish list still includes support for something like uintptr_t >>> - a >>> primitive integer type that is defined to always be the same size as a >>> pointer, however large or small that may be on different platforms. >>> (So >>> that the frontend doesn't need to know how big a pointer is and can >>> generate the same IR that works on both 32-bit and 64-bit platforms.) >>> >> >> Why not just use a pointer, such as i8*? >> > Suppose I have an STL-like container that has a 'begin' and 'end' > pointer. Now I want to find the size() of the container. Since you > cannot subtract pointers in LLVM IR, you have to cast them to an integer > type first. But what integer type do you cast them to? I suppose you > could simply always cast them to i64, and hope that the backend will > generate efficient code for the subtraction, but I have no way of > knowing this.OT, and I don't have any deep insights, but: Nick and I recently added IRBuilder::CreatePtrDiff() to do this subtraction for you. It returns an i64. I believe the target-aware optimization passes keep track of which bits may be set in any integer, which would let them generate efficient code for the subtraction, but I don't know exactly which optimizations would do that. You can, of course, check an i64 for overflow when casting to i16, or whatever, and I'd hope the bit-aware optimizations would convert the overflow check to 'false' if you weren't actually truncating.> Now, I'm going to anticipate what I think will be your next argument, > which is that at some point I must know the size of the result since I > am assigning the result of size() to some interger variable eventually. > Which is true, however, if the size of that eventual variable is smaller > than a pointer, then I want to check it for overflow before I do the > assignment. I don't want to just do a blind bitcast and have the top > bits be lopped off. > > The problem of checking for overflow when assigning from an integer of > unknown size to an integer of known size is left as an exercise for the > reader. >> -Chris
On May 5, 2009, at 9:55 PM, Talin wrote:>>> (So >>> that the frontend doesn't need to know how big a pointer is and can >>> generate the same IR that works on both 32-bit and 64-bit >>> platforms.) >>> >> >> Why not just use a pointer, such as i8*? >> > Suppose I have an STL-like container that has a 'begin' and 'end' > pointer. Now I want to find the size() of the container. Since you > cannot subtract pointers in LLVM IR, you have to cast them to an > integer > type first. But what integer type do you cast them to? I suppose you > could simply always cast them to i64, and hope that the backend will > generate efficient code for the subtraction, but I have no way of > knowing this.What do you intend to do with this size? At some point you have to do an operation that depends on the size. The problem with adding an intptr_t is that at some point you have to convert it to another datatype, and you don't know whether it will be a zext/trunc/bitcast etc.> Now, I'm going to anticipate what I think will be your next argument, > which is that at some point I must know the size of the result since I > am assigning the result of size() to some interger variable > eventually.yes :)> Which is true, however, if the size of that eventual variable is > smaller > than a pointer, then I want to check it for overflow before I do the > assignment. I don't want to just do a blind bitcast and have the top > bits be lopped off.But you don't know if it will be smaller or larger. -Chris
On Fri, May 8, 2009 at 12:25 PM, Chris Lattner <clattner at apple.com> wrote:> On May 5, 2009, at 9:55 PM, Talin wrote: >> Suppose I have an STL-like container that has a 'begin' and 'end' >> pointer. Now I want to find the size() of the container. Since you >> cannot subtract pointers in LLVM IR, you have to cast them to an >> integer >> type first. But what integer type do you cast them to? I suppose you >> could simply always cast them to i64, and hope that the backend will >> generate efficient code for the subtraction, but I have no way of >> knowing this. > > What do you intend to do with this size? At some point you have to do > an operation that depends on the size. The problem with adding an > intptr_t is that at some point you have to convert it to another > datatype, and you don't know whether it will be a zext/trunc/bitcast > etc.You may want to feed it back into GEP. If size() for the container is the first step in calculating a pivot point for qsort, then as long as GEP takes in intptr_t you are set. In fact, if intptr_t existed, it would be all a GEP or malloc had to take and those instructions wouldn't need the current bi-version approach (nor any other thing that takes a size, like the mem* intrinsics). I would go so far as to say that ptr->int and int->ptr cases should only be possible to an intptr type, and then the target knowledge which currently is embedded in the ptr cast is embedded in the int cast if you need to cast to a known size. Andrew