Re: explaination of some gcc functions
kernel coder wrote: hi, I'm trying to understand the backend code of gcc for MIPS architecture.I'm having some trouble while understanding following functions. I think most of these are obvious, what problems in specific are you having with them? -eric
Re: explaination of some gcc functions
I'm having trouble in understanding the term sequnce in an insn chain.get_insns() actually returns the current instruction.What does the term "sequence" mean,as the name suggests it must be a sequence of instructions ,but in an instruction chain,a single element will be an instruction ,then what is meant by sequence. When push_topmost_sequence is called ,it should push a sequence of instructions ,but an element of insn chain is a single instruction,then which sequence will be pushed. Suppose following is a sequnce of instructions. 1)entry_insns = get_insns (); 2) push_topmost_sequence (); 3) emit_insn_after (entry_insns, get_insns ()); 4) pop_topmost_sequence (); In 1) current insn is saved in entry_insns. what is happening in In 2).Is sequence differnet from insn in an insn chain ,any example will be helpful. In 3) instruction the entry_insns is being put after the instruction obtained through get_insns() .But does get_insns() also increaments the current instruction pointer.If not then shouldn't the same instruction be emitted in 3). Now again which sequnce is being poped out in 4). On 7/1/06, Eric Christopher <[EMAIL PROTECTED]> wrote: kernel coder wrote: > hi, > I'm trying to understand the backend code of gcc for MIPS > architecture.I'm having some trouble while understanding following > functions. I think most of these are obvious, what problems in specific are you having with them? -eric
Re: What happend to bootstrap-lean? (was: What happened to bubblestrap?)
Hi Paolo, since we are approaching the GCC 4.2 release, I thought I'd point out the question of bootstrap-lean again, which is still documented and which I found rather useful in some settings. On Sat, 17 Dec 2005, Gerald Pfeifer wrote: > On Fri, 16 Dec 2005, Paolo Bonzini wrote: >> Yes. "make bubblestrap" is now called simply "make". > Okay, how is "make bootstrap-lean" called these days? ;-) > > In fact, bootstrap-lean is still documented in install.texi and > makefile.texi, but it no longer seems to be present in the Makefile > machinery. Could we get this back? Also, would you mind adding some notes to gcc-4.2/changes.html, as far as changes are user visible? Thanks, Gerald
Re: Notes of the libgcc-math BOF at the summit.
On Fri, Jun 30, 2006 at 02:57:19PM +0200, Richard Guenther wrote: >Issues of providing both standard conforming and target optimized >math runtimes for GCC were discussed. Thanks for posting this. Since I wasn't able to attend the summit this year, I really appreciate seeing summaries like this. cgf
void* <-> char* aliasing rule, C standard or glitch?
Hi GCClers, I searched hard, but couldn't determine conclusively if the C standard allows to alias a void* pointer with a char* pointer. If that's not undefined behavior, then the following may be a glitch in GCC 4.1.0 when compiled with -O2. Here's the ugly minimal piece of code: /* ASSUME pointer POINTS TO AN INTEGER THAT SPECIFIES THE INCREMENT */ int increment(int *pointer) { return(*pointer); } /* INCREMENT A POINTER BY THE NUMBER OF BYTES POINTED TO = */ void *incremented(void *pointer) { int inc=increment(pointer); *((char**)&pointer)+=inc; return(pointer); } What goes wrong is that the function incremented() increments the pointer, but returns the original, non-incremented value. Here's the assembly code: Dump of assembler code for function incremented: 0x08051f80 : push %ebp 0x08051f81 : mov%esp,%ebp 0x08051f83 : push %ebx 0x08051f84 : sub$0x4,%esp 0x08051f87 : mov0x8(%ebp),%ebx 0x08051f8a :mov%ebx,(%esp) 0x08051f8d :call 0x8051f70 0x08051f92 :add%eax,0x8(%ebp) 0x08051f95 :mov%ebx,%eax ** -->> Here's the problem, line above should read mov 0x8(%ebp),%eax ** 0x08051f97 :add$0x4,%esp 0x08051f9a :pop%ebx 0x08051f9b :pop%ebp 0x08051f9c :ret 0x08051f9d :lea0x0(%esi),%esi Thanks for your time, and BTW: is there a 'better' construct for incrementing a void* pointer other than *((char**)&pointer)+=inc ? ;-) Greetings, Elmar
gcc-4.2-20060701 is now available
Snapshot gcc-4.2-20060701 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/4.2-20060701/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 4.2 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/trunk revision 115116 You'll find: gcc-4.2-20060701.tar.bz2 Complete GCC (includes all of below) gcc-core-4.2-20060701.tar.bz2 C front end and core compiler gcc-ada-4.2-20060701.tar.bz2 Ada front end and runtime gcc-fortran-4.2-20060701.tar.bz2 Fortran front end and runtime gcc-g++-4.2-20060701.tar.bz2 C++ front end and runtime gcc-java-4.2-20060701.tar.bz2 Java front end and runtime gcc-objc-4.2-20060701.tar.bz2 Objective-C front end and runtime gcc-testsuite-4.2-20060701.tar.bz2The GCC testsuite Diffs from 4.2-20060624 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-4.2 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
Re: void* <-> char* aliasing rule, C standard or glitch?
On 7/1/06, Elmar Krieger <[EMAIL PROTECTED]> wrote: I searched hard, but couldn't determine conclusively if the C standard allows to alias a void* pointer with a char* pointer. Search in the GCC documentation, under -fstrict-aliasing: http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Optimize-Options.html#index-fstrict_002daliasing-542 Gr. Steven
externs and thread local storage
Consider the following program made up of two separate files: ==> file1.c <== extern int x; int main() { x = 5; } ==> file2.c <== int __thread x = 10; This will compile, link, and run on the IA64, but will fail at link time on AMD64: % gcc file2.c file1.c /usr/bin/ld: x: TLS definition in /tmp/ccmdUAs3.o section .tdata mismatches non-TLS reference in /tmp/ccuSmPAa.o /tmp/ccuSmPAa.o: could not read symbols: Bad value collect2: ld returned 1 exit status However if the initial extern were changed to: extern __thread int x; it will also compile, link, and run on the AMD64. To further complicate matters, if the program is rewritten into a single file as follows: int __thread x; int main() { extern int x; x = 5; } it will fail at compile-time with gcc 4.1: fx.c: In function 'main': fx.c:4: error: non-thread-local declaration of 'x' follows thread-local declaration fx.c:1: error: previous declaration of 'x' was here independent of the fact that this program likely would work fine on the IA64 and perhaps some other architectures. It seems that GCC is enforcing a policy that the __thread attribute has to be added to extern declarations if the underlying variable is declared with the __thread attribute. If we viewed the __thread attribute as something like assigning a variable to a particular linkage section (which is what it does), then shouldn't that assignment be transparent to programs referencing the variable via an extern? What are the technical reasons for the front-end enforcing this restriction, when apparently some linkers will handle the TLS linkage fine? If in fact it is required that __thread be added to the extern, is the compiler simply accommodating a limitation/bug in the linker?
Re: void* <-> char* aliasing rule, C standard or glitch?
Elmar Krieger writes: > > I searched hard, but couldn't determine conclusively if the C standard > allows to alias a void* pointer with a char* pointer. > > If that's not undefined behavior, then the following may be a glitch in > GCC 4.1.0 when compiled with -O2. > > Here's the ugly minimal piece of code: > > /* ASSUME pointer POINTS TO AN INTEGER THAT SPECIFIES THE INCREMENT > */ > int increment(int *pointer) > { return(*pointer); } > > /* INCREMENT A POINTER BY THE NUMBER OF BYTES POINTED TO > = */ > void *incremented(void *pointer) > { int inc=increment(pointer); >*((char**)&pointer)+=inc; Not legal C. Do pointer = (char*)pointer + inc; Andrew.
Re: explaination of some gcc functions
On Jul 1, 2006, at 12:54 AM, kernel coder wrote: I'm having trouble in understanding the term sequnce in an insn chain.get_insns() actually returns the current instruction. I'd recommend reading the code: /* Emission of insns (adding them to the doubly-linked list). */ /* Return the first insn of the current sequence or current function. */ rtx get_insns (void) { return first_insn; } /* Specify a new insn as the first in the chain. */ void set_first_insn (rtx insn) { gcc_assert (!PREV_INSN (insn)); first_insn = insn; } /* Return the last insn emitted in current sequence or current function. */ rtx get_last_insn (void) { return last_insn; } /* Specify a new insn as the last in the chain. */ void set_last_insn (rtx insn) { gcc_assert (!NEXT_INSN (insn)); last_insn = insn; } It can help form a basis from which you can build your understanding of the code. What does the term "sequence" mean,as the name suggests it must be a sequence of instructions Ok, so you know what it means... Another way would be to read the code. If you read the code: push_topmost_sequence (void) { struct sequence_stack *stack, *top = NULL; start_sequence (); for (stack = seq_stack; stack; stack = stack->next) top = stack; first_insn = top->first; and then first_insn: #define first_insn (cfun->emit->x_first_insn) and then if you find x_first_insn: /* The ends of the doubly-linked chain of rtl for the current function. Both are reset to null at the start of rtl generation for the function. start_sequence saves both of these on `sequence_stack' and then starts a new, nested sequence of insns. */ rtx x_first_insn; rtx x_last_insn; and then you can read the comments. The term doubly linked list should help understand the term sequence. Also, if you read the code, the code can also help understand the term sequence, just M- grep sequence *.c and read it all. And lastly, to understand the term sequence you can google("sequence") and read how it is used, as our use of the term is no different that every other use of the term. but in an instruction chain,a single element will be an instruction, Unless you have a reference to a member of a container and you can find the container from the reference. I'd recommend some books on data structures and programming if your unfamiliar with data structures. When push_topmost_sequence is called ,it should push a sequence of instructions ,but an element of insn chain is a single instruction,then which sequence will be pushed. See above. In addition, another way to understand the code would be to set a breakpoint on whatever you're interested in and single step it in your favorite debugger. You can then see what it does, how it does it, what data structures are in play, the comments around that code and so on. Suppose following is a sequnce of instructions. 1)entry_insns = get_insns (); 2) push_topmost_sequence (); 3) emit_insn_after (entry_insns, get_insns ()); 4) pop_topmost_sequence (); In 1) current insn is saved in entry_insns. what is happening in In 2).Is sequence differnet from insn in an insn chain ,any example will be helpful. If you read the comments in the code: /* Put the insns after the NOTE that starts the function. If this is inside a start_sequence, make the outer-level insn chain current, so the code is placed at the start of the function. */ push_topmost_sequence (); emit_insn_before (seq, NEXT_INSN (entry_of_function ())); pop_topmost_sequence (); return temp; and: /* Put the insns after the NOTE that starts the function. If this is inside a start_sequence, make the outer-level insn chain current, so the code is placed at the start of the function. */ push_topmost_sequence (); emit_insn_after (seq, entry_of_function ()); pop_topmost_sequence (); do they help clarify things? But does get_insns() also increaments the current instruction pointer. Is is documented to do that? Is there code in the function to do that? Hint, here is everything you need to answer those questions: /* Return the first insn of the current sequence or current function. */ rtx get_insns (void) { return first_insn; } If you don't use emacs, I'd recommend it. If you don't know about M-., I'd recommend reading up on it, to use it, just go the the call of the function your interested in, such s get_insns and then hit M-., and then presto, you're there. Just be sure to do a make TAGS once. You can then read up on what it is and does. Now again which sequnce is being poped out in 4). In the idiom: push pop the pop, pops the thing on top the stack, in the above case, it would be the thing just pushed. If you don't understand that, I'd recommend an intro to CS type book, then a dara structures book, and algorithms book, then an advanced data structures b
Re: externs and thread local storage
On Jul 1, 2006, at 11:23 AM, Gary Funck wrote: To further complicate matters, if the program is rewritten into a single file as follows: int __thread x; int main() { extern int x; x = 5; } it will fail at compile-time with gcc 4.1: This sounds like a bug that should be fixed. You should only need __thread on the extern if there was not a previous declaration for it. What are the technical reasons for the front-end enforcing this restriction, None in the above case, just laziness probably.
RE: externs and thread local storage
Mike Stump wrote: > > This sounds like a bug that should be fixed. You should only need > __thread on the extern if there was not a previous declaration for it. > The compiler seems pretty determined to enforce this restriction. Same result with 'const' instead of _thread: int const x; int main() { extern int x; x = 5; } t.c: In function 'main': t.c:4: error: conflicting type qualifiers for 'x' t.c:1: error: previous declaration of 'x' was here