On 01/07/2010 06:03 PM, Alastair Lynn wrote:> > You'll probably need to use insertvalue to construct your return value.Ah ha! The fact is I didn't really understand the significance of this part when I read it, and so didn't remember it when I needed it. OK, so I have tested it and I can now build up a struct like this %s1 = insertvalue {i32, i32} {i32 0, i32 0}, i32 1, 0 ; s1 = {1,0} %s2 = insertvalue {i32, i32} %s1, i32 2, 1 ; %s2 == {1,2} which reminds me of another thing I never understood. I can't make my code (slightly) more readable by changing that to something like %s0 = {i32 0, i32 0} %s1 = insertvalue {i32, i32} %s0, i32 1, 0 ; s1 = {1,0} %s2 = insertvalue {i32, i32} %s1, i32 2, 1 ; %s2 == {1,2} because LLVM will complain that it "expected instruction opcode" at the assignment to %s0. If there is a general way to give names to constants in that way I didn't find it. In fact, I think I tended not to use temporaries like I would variables precisely because when I tried the second alternative as the natural way to hand-code it and it didn't work, I didn't think how to phrase it so only the results of operations get named. Help me understand the underlying logic--why can one only name the results of operations? I realize that the local temporaries are notionally register variables for a machine with an infinite number of registers, but my very dim memory of real assembly was that I not only could load constants into registers but had to do so. What part of the picture am I missing here? You need an IR tutorial. Or, to speak correctly, *I* need a tutorial. :-) But I'm learning.... Dustin
Dustin Laurence wrote:> On 01/07/2010 06:03 PM, Alastair Lynn wrote: > >> You'll probably need to use insertvalue to construct your return value. >> > > Ah ha! > > The fact is I didn't really understand the significance of this part > when I read it, and so didn't remember it when I needed it. OK, so I > have tested it and I can now build up a struct like this > > %s1 = insertvalue {i32, i32} {i32 0, i32 0}, i32 1, 0 ; s1 = {1,0} > %s2 = insertvalue {i32, i32} %s1, i32 2, 1 ; %s2 == {1,2} >As a small refinement, I recommend: %s1 = insertvalue {i32, i32} undef, i32 1, 0 %s2 = insertvalue {i32, i32} %s1, i32 2, 1> which reminds me of another thing I never understood. I can't make my > code (slightly) more readable by changing that to something like > > %s0 = {i32 0, i32 0} > %s1 = insertvalue {i32, i32} %s0, i32 1, 0 ; s1 = {1,0} > %s2 = insertvalue {i32, i32} %s1, i32 2, 1 ; %s2 == {1,2} >No, there is no copy or move instruction in LLVM. Recall that the text format is 1:1 with the in-memory model of the program. A copy instruction in the IR would literally mean "go look at my operand instead", leading to logic in every optimization that checks for a CopyInst and chases the pointer. The astute reader will note that I'm lying again, but it's for your own good. ;-) "%x = bitcast i32 %y to i32" is a legal way to copy, but the intention behind a BitcastInst is that it is used to change the type. Nick> because LLVM will complain that it "expected instruction opcode" at the > assignment to %s0. If there is a general way to give names to constants > in that way I didn't find it. In fact, I think I tended not to use > temporaries like I would variables precisely because when I tried the > second alternative as the natural way to hand-code it and it didn't > work, I didn't think how to phrase it so only the results of operations > get named. > > Help me understand the underlying logic--why can one only name the > results of operations? I realize that the local temporaries are > notionally register variables for a machine with an infinite number of > registers, but my very dim memory of real assembly was that I not only > could load constants into registers but had to do so. What part of the > picture am I missing here? > > You need an IR tutorial. Or, to speak correctly, *I* need a tutorial. > :-) But I'm learning.... > > Dustin > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
On 01/08/2010 09:32 PM, Nick Lewycky wrote:> As a small refinement, I recommend: > > %s1 = insertvalue {i32, i32} undef, i32 1, 0 > %s2 = insertvalue {i32, i32} %s1, i32 2, 1Ah, excellent. I hadn't found a use for 'undef' yet, but I like that. I don't like substituting values into a literal with arbitrary values because, well, it's unlovely. Saying the values don't matter is much better. I don't think there is a place in my lexer that happens to need exactly that as one or the other members of the token structure always seems to be a literal, but your example did lead me to use undef for individual members being replaced in an insertvalue instruction.> No, there is no copy or move instruction in LLVM. Recall that the text > format is 1:1 with the in-memory model of the program. A copy > instruction in the IR would literally mean "go look at my operand > instead", leading to logic in every optimization that checks for a > CopyInst and chases the pointer.My desire to do such things is a direct consequence of my apparently odd choice to learn the IR by approaching it as a programming language. While it clearly wasn't intended for it, my first computer had three registers, only one of which was a mighty sixteen bits wide, so I've hurt worse before. :-) That said, the need to parameterize code is too great not to do something, and since LLVM isn't designed to do it I have been using CPP. Doing without even the modest abilities of CPP is simply not to be thought of. If I did enough hand-coding it would be well worth writing a custom preprocessor.> The astute reader will note that I'm lying again, but it's for your own > good. ;-) "%x = bitcast i32 %y to i32" is a legal way to copy, but the > intention behind a BitcastInst is that it is used to change the type.If I was concerned about my own good I probably wouldn't be hand-coding. :-) Dustin