Simply put, it's a pointer-sized integer. I'm blatantly stealing this idea from .NET, where IntPtr (a pointer-sized integer) is a basic type. In my front end, I had considered just using a pointer for intp behind-the-scenes and doing conversion to/from int64 when I wanted to do arithmetic on them, but pointers and integers don't always align the same way. So what I really want is a way to represent in IR that a certain parameter/struct member is a pointer-sized integer. Now that optimizations work without target data, I think we're tantalizingly close to a situation where useful, target-independent IR files are a real possibility. intp is one of the remaining pieces of that puzzle; lots of native code expects an integer parameter/struct member sized the same as a pointer. It makes sense for sizes and offsets to be represented this way, and in a lot of cases, they are represented this way, and in IR a lot more would be represented this way if such a type existed. Also, having this type present will tend over time to reduce the number of casts to/from int64 appearing in bitcode that have to be stripped out, slightly speeding up optimizations and codegen. The ramifications that I see: 1. Conversions to/from other integer types: right now, integer type conversions are always explicity specified as either a trunc, a sext, or a zext. Since the size of intp is not known at IR generation time, you can't know whether a conversion to/from intp truncates or extends. 2. The usual ramifications of adding a new type: IR generation/analysis, optimizations, and codegen all have to be updated to deal with the existence of the new type. The changes should be minor; it's an integer type with all of the supported operations of integer types, with the only difference being that its size cannot be determined without target data.
I've asked for this as well. A workaround that I have considered, but haven't had time to explore yet, is to actually store such integers as pointers, and then bitcast to int64 to do actual math operations and GEPs. While this might sound inefficient on 32-bit platforms, I believe that LLVM's optimizers can take notice of the fact that you aren't using the upper bits and therefore degrade to the less expensive 32-bit operations. Clearly this is an ugly hack (especially in the obscurity of the IR code generated), but I haven't come up with anything better so far. Kenneth Uildriks wrote:> Simply put, it's a pointer-sized integer. I'm blatantly stealing this > idea from .NET, where IntPtr (a pointer-sized integer) is a basic > type. > > In my front end, I had considered just using a pointer for intp > behind-the-scenes and doing conversion to/from int64 when I wanted to > do arithmetic on them, but pointers and integers don't always align > the same way. So what I really want is a way to represent in IR that > a certain parameter/struct member is a pointer-sized integer. > > Now that optimizations work without target data, I think we're > tantalizingly close to a situation where useful, target-independent IR > files are a real possibility. intp is one of the remaining pieces of > that puzzle; lots of native code expects an integer parameter/struct > member sized the same as a pointer. It makes sense for sizes and > offsets to be represented this way, and in a lot of cases, they are > represented this way, and in IR a lot more would be represented this > way if such a type existed. > > Also, having this type present will tend over time to reduce the > number of casts to/from int64 appearing in bitcode that have to be > stripped out, slightly speeding up optimizations and codegen. > > The ramifications that I see: > > 1. Conversions to/from other integer types: right now, integer type > conversions are always explicity specified as either a trunc, a sext, > or a zext. Since the size of intp is not known at IR generation time, > you can't know whether a conversion to/from intp truncates or extends. > > 2. The usual ramifications of adding a new type: IR > generation/analysis, optimizations, and codegen all have to be updated > to deal with the existence of the new type. The changes should be > minor; it's an integer type with all of the supported operations of > integer types, with the only difference being that its size cannot be > determined without target data. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Talin
On Tue, Nov 10, 2009 at 12:35 AM, Talin <viridia at gmail.com> wrote:> A workaround that I have considered, but haven't had time to explore yet, is > to actually store such integers as pointers, and then bitcast to int64 to do > actual math operations and GEPs. While this might sound inefficient on > 32-bit platforms, I believe that LLVM's optimizers can take notice of the > fact that you aren't using the upper bits and therefore degrade to the less > expensive 32-bit operations.The trouble with that is that the alignment of pointers is not necessarily the same as the alignment of pointer-sized integers.
2009/11/9 Kenneth Uildriks <kennethuil at gmail.com>:> > 1. Conversions to/from other integer types: right now, integer type > conversions are always explicity specified as either a trunc, a sext, > or a zext. Since the size of intp is not known at IR generation time, > you can't know whether a conversion to/from intp truncates or extends. >Now that there are arbitrary-sized integers, couldn't you zext to i256 then trunc down again, and later let the folder simplify as appropriate?
On Tue, Nov 10, 2009 at 8:10 AM, me22 <me22.ca at gmail.com> wrote:> 2009/11/9 Kenneth Uildriks <kennethuil at gmail.com>: >> >> 1. Conversions to/from other integer types: right now, integer type >> conversions are always explicity specified as either a trunc, a sext, >> or a zext. Since the size of intp is not known at IR generation time, >> you can't know whether a conversion to/from intp truncates or extends. >> > > Now that there are arbitrary-sized integers, couldn't you zext to i256 > then trunc down again, and later let the folder simplify as > appropriate?I suppose that would work, but I wouldn't like to see two cast instructions for every conversion. Perhaps every conversion to/from intp could be represented as a zext, whether or not it actually performs an extension. Is there anything in LLVM that depends on a zext actually increasing the size of the integer?
On 10 Nov., 15:10, me22 <me22... at gmail.com> wrote:> 2009/11/9 Kenneth Uildriks <kenneth... at gmail.com>: > > > > > 1. Conversions to/from other integer types: right now, integer type > > conversions are always explicity specified as either a trunc, a sext, > > or a zext. Since the size of intp is not known at IR generation time, > > you can't know whether a conversion to/from intp truncates or extends. > > Now that there are arbitrary-sized integers, couldn't you zext to i256 > then trunc down again, and later let the folder simplify as > appropriate?This is not correct, because i256 occupies too much space in structures, etc. This question came up in the past, and I half-jokingly suggested "i0" as the interger type that can store a null-pointer, and thus every pointer. i0 could be a type alias which gets resolved at the time when sizeof (void*) is first known. But as a nice bonus, conversions between i0 and T* could be omitted. Just my 2 cents. Gabor> > _______________________________________________ > LLVM Developers mailing list > LLVM... at cs.uiuc.edu http://llvm.cs.uiuc.eduhttp://lists.cs.uiuc.edu/mailman/listinfo/llvmdev