I have yet another question that I believe also stems from deep ignorance of the linkage types. How do you declare a global variable without defining it? The IR ref. clearly indicates that you can do this, but it looks like one of the many "too obvious to mention" things that I struggle with. It's easy with functions, of course: "declare @foo" in the header and "define @foo" in the module just like in C. But it turns out I have avoided having to learn to do it with variables until now, when I decided to play with invoke/unwind and see if I could make a primitive exception mechanism to unwind the stack on my recursive parser when an error is encountered. In fact I could avoid it now, but the purpose is to learn as much of the IR as possible, not use the subset of the language I already understand. To be clear: remember I'm using Stone Knives here. :-) I have to figure out how to make a global variable defined in one translation unit visible in another (with a header, just like in C). I could easily make an exception module with accessor functions, and that is likely the better software engineering solution, but again my real goal is to learn as much as possible (I don't need exceptions in the parser, either, but I want to understand them). Dustin
On Sat, Jan 9, 2010 at 12:57 PM, Dustin Laurence <dllaurence at dslextreme.com> wrote:> I have yet another question that I believe also stems from deep > ignorance of the linkage types. How do you declare a global variable > without defining it? The IR ref. clearly indicates that you can do > this, but it looks like one of the many "too obvious to mention" things > that I struggle with. It's easy with functions, of course: "declare > @foo" in the header and "define @foo" in the module just like in C. But > it turns out I have avoided having to learn to do it with variables > until now, when I decided to play with invoke/unwind and see if I could > make a primitive exception mechanism to unwind the stack on my recursive > parser when an error is encountered.The syntax isn't entirely obvious... usually, when you're wondering how to write something in IR, the easiest thing to so is write the equivalent C code, then use http://llvm.org/demo/index.cgi to see what it looks like in iR. In this case, try plugging the following snippet in: extern int x; int *y = &x; -Eli
On Jan 9, 2010, at 12:57 PM, Dustin Laurence wrote:> I have yet another question that I believe also stems from deep > ignorance of the linkage types. How do you declare a global variable > without defining it?The equivalent of "extern int G;" is: @G = external global i32 -Chris
Hello, Dustin> To be clear: remember I'm using Stone Knives here. :-)In some cases it's better to realize that it's year 2010 now. :) Just write small snippet in C and use llvm-gcc -emit-llvm to emit LLVM IR corresponding to it. You can use e.g. http://llvm.org/demo/ for this. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
On 01/09/2010 01:11 PM, Eli Friedman wrote:> The syntax isn't entirely obvious...Thanks, if it doesn't seem as stupid as I feel, I'll grovel less. :-)> ...usually, when you're wondering > how to write something in IR, the easiest thing to so is write the > equivalent C code, then use http://llvm.org/demo/index.cgi to see what > it looks like in iR.So *that's* why there is a web demo. :-) I think I've actually blocked out the C rules because I've been religiously hiding all variables behind C++ accessors for so long now. I think the last time I made a practice of declaring variables in .h files ANSI C was too newfangled to depend on compiler support. :-) In fact I wouldn't now except my goal is knowledge and I'm willing to bend design rules a bit to make sure I try new things. That is part of the motivation behind my plan to use invoke/unwind in the parser, in fact. It'll make for nicer code, but I'm so used to propagating errors back up the stack that I'm used to the pain. If I do that well enough, anytime I want to remember how to do something I can go back and see how I did it on this project. Dustin
On 01/09/2010 01:12 PM, Chris Lattner wrote:> The equivalent of "extern int G;" is: > > @G = external global i32OK, then I want to whine a little bit about how that is more obscurely hinted at than discussed. Whine, whine.... :-) Even knowing the word to search on, the only explicit application of the keyword to data is incidental to an example about structures. I think I feel less bad about having bounced that to the list. I'm amazed that the list of linkage types doesn't mention it somewhere. I tried 'common' among other things, but I admit it was a just a desperate shot in the dark before I just gave up and asked. Dustin
On 01/09/2010 01:20 PM, Anton Korobeynikov wrote:> Hello, Dustin > >> To be clear: remember I'm using Stone Knives here. :-) > In some cases it's better to realize that it's year 2010 now. :)What do you have against digital primitive living? :-) Actually, there is sort of some truth to that joking phrase. I am sort of treating this as a conceptual analog of the old days where your first task with your new 8-bit "personal computer" was to fire up the assembler and start writing your system. If people could do that I should be man enough to do something simpler like write a minimal lisp or forth in the far more congenial LLVM IR, right?> Just write small snippet in C and use llvm-gcc -emit-llvm to emit LLVM > IR corresponding to it. You can use e.g. http://llvm.org/demo/ for > this.I'll make a note to try that before giving up next time. Actually my self-imposed rules don't restrict me using any tool for understanding. It's not a cheat if I learn it well enough to apply it by hand. Kind of like writing a paper--you can (and should) steal ideas and style from Shakespeare, Isaiah, and Abraham Lincoln, you just can't steal their words. :-) In theory, I'll understand LLVM's machine model pretty well when I'm done. Dustin
On 01/09/2010 01:12 PM, Chris Lattner wrote:> The equivalent of "extern int G;" is: > > @G = external global i32Hmm. Is it really? This @foo = external global i32 @foo = global i32 5 define i32 @main(i32 %argc, i8 **%argv) { %fooVal = load i32* @foo ret i32 %fooVal } produces a "redefinition of global '@foo'" error. But this extern int x; int x = 5; int *y = &x; compiles to @x = global i32 5 ; <i32*> [#uses=1] @y = global i32* @x ; <i32**> [#uses=0] The difference is crucial, because I want to put "@foo = external global i32" in a header file that is then #included in every module where it is used, *including the defining module* (for a consistency check, and because otherwise I'd have to create extra headers that are only #included by the outside world but not the defining module). It appears that the front end is supposed to decide between external and global. In my case I actually could maintain all declarations by hand for one global word used to return exception information, but that wouldn't work for a more involved case. Is there no way to get the same effect as with define/declare for functions? There I have no problem #includeing a declaration into the same file as a definition. The alternative appears to be asking the linker to do it. The docs for "linkonce" say "This is typically used to implement inline functions, templates, or other code which must be generated in each translation unit that uses it." That sounds like my case, and it compiles, but I don't know if that's gong to get me into trouble. Dustin