I'm writing an ML-like language, and using LLVM as my target back end. I have one question though, and thought I'd throw it out onto the list. In my language, variables aren't mutable- once assigned, they can be shadowed, but not changed. And shadowing of variables is handled by alpha-renaming. What I mean by this that when I see: let x = 3 in ... the value of x can not be changed. It can be shadowed, like: let x = f () in let x = x + 4 in ... but one of the first things I do is rename all the variables so they're unique, so the above code might get changed into: let x_5734 = f () in let x_8643 = x_5734 + 4 in ... Now, my question is this: is there any downside to not having any stack-based local variables at all- just put everything into registers and let the register allocation code decide what needs to get spilled onto the stack? In other words, is there any problem with generating the following IR for the above code: %r17 = call i64 @f(i64 0) %r18 = add i64 %r17 4 The upside of doing this is simpler code generation, and hopefully more efficient code, as I am explicitly telling the optimizer I don't care where this variable lives. But, I'm somewhat worried that by not having any local variables at all, this may put too much pressure on the register allocator (especially for large functions). Also, how to attach debugging information to a register is something I need to figure out. Thoughts? Opinions? Is this a good way to proceed, or a bad way? Brian
It should work fine, since one of the first things LLVM does is to turn as many allocas into registers as it can via mem2reg. Reid On Mon, Feb 7, 2011 at 6:28 PM, Brian Hurt <bhurt at spnz.org> wrote:> > I'm writing an ML-like language, and using LLVM as my target back end. I > have one question though, and thought I'd throw it out onto the list. In > my language, variables aren't mutable- once assigned, they can be > shadowed, but not changed. And shadowing of variables is handled by > alpha-renaming. What I mean by this that when I see: > let x = 3 in ... > the value of x can not be changed. It can be shadowed, like: > let x = f () in > let x = x + 4 in > ... > but one of the first things I do is rename all the variables so they're > unique, so the above code might get changed into: > let x_5734 = f () in > let x_8643 = x_5734 + 4 in > ... > > Now, my question is this: is there any downside to not having any > stack-based local variables at all- just put everything into registers and > let the register allocation code decide what needs to get spilled onto the > stack? In other words, is there any problem with generating the following > IR for the above code: > %r17 = call i64 @f(i64 0) > %r18 = add i64 %r17 4 > > The upside of doing this is simpler code generation, and hopefully more > efficient code, as I am explicitly telling the optimizer I don't care > where this variable lives. > > But, I'm somewhat worried that by not having any local variables at all, > this may put too much pressure on the register allocator (especially for > large functions). Also, how to attach debugging information to a register > is something I need to figure out. > > Thoughts? Opinions? Is this a good way to proceed, or a bad way? > > Brian > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On Feb 7, 2011, at 3:28 PM, Brian Hurt wrote:> > I'm writing an ML-like language, and using LLVM as my target back end. I > have one question though, and thought I'd throw it out onto the list. In > my language, variables aren't mutable- once assigned, they can be > shadowed, but not changed. And shadowing of variables is handled by > alpha-renaming. What I mean by this that when I see: > let x = 3 in ... > the value of x can not be changed. It can be shadowed, like: > let x = f () in > let x = x + 4 in > ... > but one of the first things I do is rename all the variables so they're > unique, so the above code might get changed into: > let x_5734 = f () in > let x_8643 = x_5734 + 4 in > ... > > Now, my question is this: is there any downside to not having any > stack-based local variables at all- just put everything into registers and > let the register allocation code decide what needs to get spilled onto the > stack? In other words, is there any problem with generating the following > IR for the above code: > %r17 = call i64 @f(i64 0) > %r18 = add i64 %r17 4 > > The upside of doing this is simpler code generation, and hopefully more > efficient code, as I am explicitly telling the optimizer I don't care > where this variable lives. > > But, I'm somewhat worried that by not having any local variables at all, > this may put too much pressure on the register allocator (especially for > large functions).What Reid said, plus: the worst case of putting pressure on the register allocator is that it spills something to the stack. Forcing the use of local variables, by contrast, is basically just spilling to the stack all the time, so you're no better off than you were before. John.
Hello Brian, There is actually one potential downside to using only LLVM registers: it will (at the moment) prevent you from using any sort of moving garbage collector (copying, compacting, or generational) for your language. The reason is that LLVM's garbage collection infrastructure does not (yet) compute register maps, only stack maps, and thus does not automatically re-load potentially moved pointers after safe points. Also, IIRC debug metadata must be attached to stack slots. But these issues are not worth worrying about yet. Do the simple, clear, and obvious thing first, then change tack if it proves to be insufficient for your needs. Have fun! -- Ben On Mon, Feb 7, 2011 at 6:28 PM, Brian Hurt <bhurt at spnz.org> wrote:> > I'm writing an ML-like language, and using LLVM as my target back end. I > have one question though, and thought I'd throw it out onto the list. In > my language, variables aren't mutable- once assigned, they can be > shadowed, but not changed. And shadowing of variables is handled by > alpha-renaming. What I mean by this that when I see: > let x = 3 in ... > the value of x can not be changed. It can be shadowed, like: > let x = f () in > let x = x + 4 in > ... > but one of the first things I do is rename all the variables so they're > unique, so the above code might get changed into: > let x_5734 = f () in > let x_8643 = x_5734 + 4 in > ... > > Now, my question is this: is there any downside to not having any > stack-based local variables at all- just put everything into registers and > let the register allocation code decide what needs to get spilled onto the > stack? In other words, is there any problem with generating the following > IR for the above code: > %r17 = call i64 @f(i64 0) > %r18 = add i64 %r17 4 > > The upside of doing this is simpler code generation, and hopefully more > efficient code, as I am explicitly telling the optimizer I don't care > where this variable lives. > > But, I'm somewhat worried that by not having any local variables at all, > this may put too much pressure on the register allocator (especially for > large functions). Also, how to attach debugging information to a register > is something I need to figure out. > > Thoughts? Opinions? Is this a good way to proceed, or a bad way? > > Brian > _______________________________________________ > 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/20110208/66673963/attachment.html>
On Feb 7, 2011, at 10:05 PM, Ben Karel wrote:> Also, IIRC debug metadata must be attached to stack slots.FWIW this is was true in past but not strictly true anymore, though it is a road less travelled at -O0. One would normally use @llvm.dbg.declare intrinsic to map variable info with the stack slots. Now, you can use @llvm.dbg.value intrinsic to map variable info with a llvm register. - Devang
Apparently Analagous Threads
- [LLVMdev] Newbie Question: not using local variables
- subset() for multiple values
- [PATCH 0/4] ia64/xen: paravirtualization of hand written assembly code
- [PATCH 0/4] ia64/xen: paravirtualization of hand written assembly code
- [PATCH 0/8] RFC: ia64/xen TAKE 2: paravirtualization of hand written assembly code