Question about vec_extract
I have been trying to figure out when the pattern vec_extract is invoked. I understand it is invoked from extract_bit_field but I don't see how it can be invoked. For both SSE and altivec I have tried the following code (which I thought would cause vec_extract pattern to be called) but on both, it is not. Does anyone know to get vec_extract working, or is it broken in 4.0.0 and above? #define vector __attribute__((vector_size(16))) vector float t; float g(vector float t) { union { vector float vf; float f[4]; }t1; t1.vf = t; return t1.f[1]; } Thanks, Andrew Pinski PS, right now on PPC64, there are extra instructions done for the above code as the union is done in TI mode which causes us to use subregs and then spill to the stack twice. Maybe the union should be the mode of the vector, V4SF?
Re: Question about vec_extract
Andrew Pinski wrote: I have been trying to figure out when the pattern vec_extract is invoked. I understand it is invoked from extract_bit_field but I don't see how it can be invoked. For both SSE and altivec I have tried the following code (which I thought would cause vec_extract pattern to be called) but on both, it is not. Does anyone know to get vec_extract working, or is it broken in 4.0.0 and above? I think it could never be generated -- even on 3.x. Maybe if SRA could optimize such unions to VIEW_CONVERT_EXPR, you would get both: a vec_extract pattern being generated, and no need to go from V4SFmode to SFmode via TImode. Paolo
Re: gcc visibility used by moz
On Jul 12, 2006, at 10:04 AM, Tristan Wibberley wrote: This isn't "type" visibility. Shared objects don't export "types" they export "symbols". The types are defined in headers and are thus known to exist - no visibility attributes will or should change that. Actually in C++, they are exported, it is one of the "funny" things which people don't realize about C++. This is the normal ODR (one definition rule) rules which are coming into play which the visibility on the class, it is not no longer exported from the shared library. If the programmer had intended that the type should appear to not exist. it wouldn't be defined in a header #include-able by client code. The compiler should assume that the type exists and can be used if it is defined and shouldn't change attributes on other parts of the program. But that code would be invalid (though no diagnostic is required) code by the ODR rules in C++. This is the main difference between C++ and C where in C compatible types actually can have different names while in C++ they cannot and if two different types in C++ are the same name, the code is invalid (though no diagnostic is required). -- Pinski
Re: New bootstrap failure on i386-unknown-freebsd5.4
On Jul 11, 2006, at 10:58 AM, Benjamin Kosnik wrote: I don't know what to do about the ICE: it looks like Mike has a patch. My patch to fix this isn't at all obvious that it is correct to me. There are no signs that it will be reviewed anytime soon, so, I'd say please revert the patch that broke the build. :-( Not my preference, but, I'd rather have a tree that builds and a regression checker that will catch the regressions that people are putting in. :-(
RFD: language hooks in GIMPLE / lang_flag?
As was discussed at the summit, we'd like to get rid of global language callbacks so that we can safely inline from different source languages. AFAICS, this can be archived by using the space occupied by the lang_flags to store a language tag in each tree node. I.e., while the frontend does processes the source, we use the language hook from that frontend, but once everything is converted to GIMPLE, each tree node is tagged with the source language, and language hooks are looked up using this language hook in the tree node that defines the context for which langiage-specific information is needed. This assumes that after conversion to GIMPLE, we don't need any more lang_flags. Is that true?
AVR port have a problem with reload
Hi Ulrich. Few months ago I has analyzed PR19636 (avr specific bug) and found that it's a reload related problem. I has started the thread http://gcc.gnu.org/ml/gcc/2006-02/msg00213.html but nobody commented the problem. Can you comment the problem as reload maintainer ? Denis.
Re: New bootstrap failure on i386-unknown-freebsd5.4
> My patch to fix this isn't at all obvious that it is correct to me. > There are no signs that it will be reviewed anytime soon, That's because you've buried it in an SOS message about bootstrap breaking. Please post your patch on gcc-patches with a sane and descriptive subject, and put also attach it in bugzilla. > so, I'd say > please revert the patch that broke the build. :-( Not my > preference, but, I'd rather have a tree that builds and a regression > checker that will catch the regressions that people are putting in. :-( I've done something that will remove this bootstrap issue. However, I'm now more convinced than ever that actually precompiling all this stuff is quite useful, if only to catch other problems. So, once this ICE is fixed I'd like to revert my patch. best, benjamin
Re: New bootstrap failure on i386-unknown-freebsd5.4
> Benjamin Kosnik writes: >> My patch to fix this isn't at all obvious that it is correct to me. >> There are no signs that it will be reviewed anytime soon, Benjamin> That's because you've buried it in an SOS message about bootstrap Benjamin> breaking. Benjamin> Please post your patch on gcc-patches with a sane and descriptive Benjamin> subject, and put also attach it in bugzilla. I completely agree. Mike, if you want the patch noticed and reviewed, you could make it much easier for reviewers to know that a proposed patch is available. You have been a GCC developer long enough that this process should not be a mystery to you. David
Re: RFD: language hooks in GIMPLE / lang_flag?
On 7/12/06, Joern RENNECKE <[EMAIL PROTECTED]> wrote: As was discussed at the summit, we'd like to get rid of global language callbacks so that we can safely inline from different source languages. AFAICS, this can be archived by using the space occupied by the lang_flags to store a language tag in each tree node. I.e., while the frontend does processes the source, we use the language hook from that frontend, but once everything is converted to GIMPLE, each tree node is tagged with the source language, and language hooks are looked up using this language hook in the tree node that defines the context for which langiage-specific information is needed. This assumes that after conversion to GIMPLE, we don't need any more lang_flags. Is that true? I don't understand what you are exactly trying to do, but I guess you want to "virtualize" the lang-hooks? The proper way to get rid of them is to encode the information they provide in the IL, not to encode the source language in the trees. Richard.
Re: RFD: language hooks in GIMPLE / lang_flag?
> I don't understand what you are exactly trying to do, but I guess you > want to "virtualize" the lang-hooks? The proper way to get rid of them > is to encode the information they provide in the IL, not to encode the > source language in the trees. I strongly agree and was going to say so in response to the original message. I think that having language hooks apply to GIMPLE is wrong. I strongly believe that the semantics of GIMPLE ought to be defined very precisely and in a language-independent way. With the exception of debugging information, I think this is true for types too: we define what the semantics of types are independent of any particular language. For example, I've long felt that calling a lang hook to see if two types are "compatible" is quite wrong. That's relevant at the language syntactic/semantic level of validing such things as parameter lists, but to GIMPLE two types are compatible if and only if they would produce the identical RTL. So two integer types are compatible if they have the same mode, precision, and bounds. Two FIELD_DECLs are compatible if they have the same positions, aligments, sizes, and compatible types, two record types are compatible if they have the same sizes and alignment and all fields are compatible. Etc. The issue of debugging information is very different but I don't think in the scope of this particular discussion.
Re: Question about vec_extract
Andrew Pinski wrote: I have been trying to figure out when the pattern vec_extract is invoked. I looked at this when I worked on the mips simd support. In config/mips/mips-ps-3d.md I wrote ;; ??? This is only generated if we perform a vector operation that has to be ;; emulated. There is no other way to get a vector mode bitfield extract ;; currently. So it can be generated, but you have to use a vector mode that doesn't exist on the target. Which kind of defeats the purpose of having it. Anyways, I think all we need here is a little syntax to get the operation we want. Maybe a builtin function or something. -- Jim Wilson, GNU Tools Support, http://www.specifix.com
Re: gcc visibility used by moz
Daniel Jacobowitz wrote: On Wed, Jul 12, 2006 at 02:04:37AM +0100, Tristan Wibberley wrote: If the programmer had intended that the type should appear to not exist. it wouldn't be defined in a header #include-able by client code. The GCC doesn't know if the header is includable by client code; I assume that's the use Jason intended for marking classes hidden ("it belongs to this shared object and no one else can see it"). No, that's why we need programmer provided attributes. The programmer says: "the client code needs to know about the existence of this type so it can get pointers and references to instances and pass them back in later and maybe be able to call virtual member functions and access non-static members" by putting it in a header which they document should be included by client code - thus client code includes it and knows about the type. But the programmer says: "it is documented that the member functions and static members of this type should not need to be accessed outside of the shared object that I will define by use of the linker later on - nor should its constructors/destructors need to be called from outside that shared object, except maybe *this* one and *that* one. Thus the symbols used to lookup those things do not need to be exported from the shared object." In the examples above, client code that knows (via headers) that the classes exist should be able to get pointers to instances via exported functions, access any visible or virtual members, and pass the pointers back into visible functions of the shared object - or even dereference the pointers to pass by reference. So... what does it restrict, then? Is it just defaulting methods to hidden, as a strange form of access control? As above, I thought it wasn't there originally to "restrict" anything, but to remove stuff from symbol tables that the programmer knows don't need to be there, but the compiler has no way of working out - the purpose for which most annotations in C++ are there. If all code that refers to a type's name (and possibly one or more members) and that will be compiled to a different shared object file (or executable) does not need the symbols for some parts of that classes definition to be exported, then the symbols do not need to be exported from the shared object in which their instances appear. This provides a large space saving, and startup time improvement. That does not require that all symbols whose C++ prototypes say they return a pointer or reference to a "hidden" type are also hidden. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Wiki down for a few days
I'm taking the wiki down for a few days because 1. It's getting attacked again, and the current software doesn't make fixing this easy. 2. I'm currently not at home, and have a lot of meetings, so i probably won't finish converting it until i get back home. :) Sorry about this. --Dan
Re: RFD: language hooks in GIMPLE / lang_flag?
Richard Kenner wrote on 07/12/06 14:33: >> I don't understand what you are exactly trying to do, but I guess you >> want to "virtualize" the lang-hooks? The proper way to get rid of them >> is to encode the information they provide in the IL, not to encode the >> source language in the trees. > > I strongly agree and was going to say so in response to the original message. > > I think that having language hooks apply to GIMPLE is wrong. I strongly > believe that the semantics of GIMPLE ought to be defined very precisely and > in a language-independent way. With the exception of debugging information, > I think this is true for types too: we define what the semantics of types are > independent of any particular language. > > For example, I've long felt that calling a lang hook to see if two types are > "compatible" is quite wrong. That's relevant at the language > syntactic/semantic level of validing such things as parameter lists, but to > GIMPLE two types are compatible if and only if they would produce the > identical RTL. So two integer types are compatible if they have the same > mode, precision, and bounds. Two FIELD_DECLs are compatible if they have the > same positions, aligments, sizes, and compatible types, two record types are > compatible if they have the same sizes and alignment and all fields are > compatible. Etc. > > The issue of debugging information is very different but I don't think in > the scope of this particular discussion. > Yup. That's been the idea all along. We represent all the FE language semantics in GIMPLE, much like we expose ctor/dtor in C++ or EH or any of the other language mechanisms. Everything must be explicitly represented in the IL, totally independent from the input language.
Re: gcc visibility used by moz
On Wed, Jul 12, 2006 at 07:49:21PM +0100, Tristan Wibberley wrote: > No, that's why we need programmer provided attributes. The programmer says: > > "the client code needs to know about the existence of this type so it > can get pointers and references to instances and pass them back in later > and maybe be able to call virtual member functions and access non-static > members" by putting it in a header which they document should be > included by client code - thus client code includes it and knows about > the type. But the programmer says: > > "it is documented that the member functions and static members of this > type should not need to be accessed outside of the shared object that I > will define by use of the linker later on - nor should its > constructors/destructors need to be called from outside that shared > object, except maybe *this* one and *that* one. Thus the symbols used to > lookup those things do not need to be exported from the shared object." I just don't get it. Why should it matter whether a member function is virtual or not in order to be able to call it from outside this shared object? Either you can access the public members of the class, or you can't. Being able to access some of them and get link errors on others is a very strange default interpretation. -- Daniel Jacobowitz CodeSourcery
Re: gcc visibility used by moz
On Jul 12, 2006, at 11:49 AM, Tristan Wibberley wrote: "the client code needs to know about the existence of this type so it can get pointers and references to instances and pass them back in later and maybe be able to call virtual member functions and access non-static members" by putting it in a header which they document should be included by client code - thus client code includes it and knows about the type. And what do you expect the type equality operator return for two types called S?
Re: gcc visibility used by moz
Tristan Wibberley <[EMAIL PROTECTED]> writes: | Daniel Jacobowitz wrote: | > On Wed, Jul 12, 2006 at 02:04:37AM +0100, Tristan Wibberley wrote: | >> If the programmer had intended that the type should appear to not | >> exist. it wouldn't be defined in a header #include-able by client | >> code. The | > GCC doesn't know if the header is includable by client code; I assume | > that's the use Jason intended for marking classes hidden ("it belongs | > to this shared object and no one else can see it"). | | | No, that's why we need programmer provided attributes. The programmer says: | | "the client code needs to know about the existence of this type so it | can get pointers and references to instances and pass them back in | later and maybe be able to call virtual member functions and access | non-static members" by putting it in a header which they document | should be included by client code - thus client code includes it and | knows about the type. But the programmer says: It strikes as you are assuming C and C++ have a notion of module. They don't. They have the notion of "translation unit." C++ adds the notion of "One Definition Rule" to make sure Bad Things don't happen. You have to operate within that framework if you're going to touch the C++ type system in any way. -- Gaby
Re: gcc visibility used by moz
Daniel Jacobowitz <[EMAIL PROTECTED]> writes: [...] | I just don't get it. Why should it matter whether a member function is | virtual or not in order to be able to call it from outside this shared | object? Either you can access the public members of the class, or you | can't. Being able to access some of them and get link errors on others | is a very strange default interpretation. Amen. -- Gaby
Re: gcc visibility used by moz
Daniel Jacobowitz wrote: On Wed, Jul 12, 2006 at 02:04:37AM +0100, Tristan Wibberley wrote: If the programmer had intended that the type should appear to not exist. it wouldn't be defined in a header #include-able by client code. The GCC doesn't know if the header is includable by client code; I assume that's the use Jason intended for marking classes hidden ("it belongs to this shared object and no one else can see it"). No, that's why we need programmer provided attributes. The programmer says: "the client code needs to know about the existence of this type so it can get pointers and references to instances and pass them back in later and maybe be able to call virtual member functions and access non-static members" by putting it in a header which they document should be included by client code - thus client code includes it and knows about the type. But the programmer says: "it is documented that the member functions and static members of this type should not need to be accessed outside of the shared object that I will define by use of the linker later on - nor should its constructors/destructors need to be called from outside that shared object, except maybe *this* one and *that* one. Thus the symbols used to lookup those things do not need to be exported from the shared object." In the examples above, client code that knows (via headers) that the classes exist should be able to get pointers to instances via exported functions, access any visible or virtual members, and pass the pointers back into visible functions of the shared object - or even dereference the pointers to pass by reference. So... what does it restrict, then? Is it just defaulting methods to hidden, as a strange form of access control? As above, I thought it wasn't there originally to "restrict" anything, but to remove stuff from symbol tables that the programmer knows don't need to be there, but the compiler has no way of working out - the purpose for which most annotations in C++ are there. If all code that refers to a type's name (and possibly one or more members) and that will be compiled to a different shared object file (or executable) does not need the symbols for some parts of that class's definition to be exported, then the symbols do not need to be exported from the shared object in which their instances appear. This provides a large space saving, and startup time improvement. That does not require that all symbols whose C++ prototypes say they return a pointer or reference to a "hidden" type are also hidden. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: gcc visibility used by moz
Mike Stump wrote: On Jul 12, 2006, at 11:49 AM, Tristan Wibberley wrote: "the client code needs to know about the existence of this type so it can get pointers and references to instances and pass them back in later and maybe be able to call virtual member functions and access non-static members" by putting it in a header which they document should be included by client code - thus client code includes it and knows about the type. And what do you expect the type equality operator return for two types called S? I don't expect two types called S - I don't recall suggesting that multiple types with the same name should be able to exist. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: Tristan Wibberley <[EMAIL PROTECTED]> writes: | The programmer says: | | "the client code needs to know about the existence of this type so it | can get pointers and references to instances and pass them back in | later and maybe be able to call virtual member functions and access | non-static members" by putting it in a header which they document | should be included by client code - thus client code includes it and | knows about the type. But the programmer says: It strikes as you are assuming C and C++ have a notion of module. They don't. They have the notion of "translation unit." C++ adds the notion of "One Definition Rule" to make sure Bad Things don't happen. You have to operate within that framework if you're going to touch the C++ type system in any way. No but the linker does, and that's the program for which the attributes are intended. C++ doesn't even have a concept of "visibility", so C++ isn't really the matter here. The visibility attributes should simply map to the symbols used to export the thing that the visiblity attribute is applied to so the linker can pick them up as the programmer expects. I am suggesting that visibility attributes should *not* touch the C++ type system in any way. Since C++ doesn't have a notion of module a class that the C++ type system regards as hidden must be hidden from everything (in which case, you could just comment out the class definition instead) or nothing. I suggest that should be nothing, and that the linker should apply the visibility attributes to *its* notion of module. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: gcc visibility used by moz
Daniel Jacobowitz wrote: On Wed, Jul 12, 2006 at 07:49:21PM +0100, Tristan Wibberley wrote: No, that's why we need programmer provided attributes. The programmer says: "the client code needs to know about the existence of this type so it can get pointers and references to instances and pass them back in later and maybe be able to call virtual member functions and access non-static members" by putting it in a header which they document should be included by client code - thus client code includes it and knows about the type. But the programmer says: "it is documented that the member functions and static members of this type should not need to be accessed outside of the shared object that I will define by use of the linker later on - nor should its constructors/destructors need to be called from outside that shared object, except maybe *this* one and *that* one. Thus the symbols used to lookup those things do not need to be exported from the shared object." I just don't get it. Why should it matter whether a member function is virtual or not in order to be able to call it from outside this shared object? Either you can access the public members of the class, or you can't. Being able to access some of them and get link errors on others is a very strange default interpretation. Because virtual functions don't require anything to be exported from a shared object other than a function to get a pointer to an instance. From C++'s point of view, the hidden attributes should have no effect. From the linker's point of view, they document what the code that links to a shared object will not be using, and so what symbols do not need to be exported. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: gcc visibility used by moz
(copying your mail to the gcc mailing list again) Benjamin Smedberg wrote: Jason Merrill wrote: It seems that you have a different mental model of type visibility. The way I was thinking about it, if a type has hidden visibility, we can't refer to it from outside its object. Thus, it doesn't make sense for members or objects with that type to have greater visibility because even if people can call the accessor they can't do anything with the return value. You certainly can refer to an hidden-visibility object outside it's translation unit. Firstly, you should absolutely be able to pass pointers to these objects around, even if you can't call any methods on them. Secondly, you can safely call any virtual method, because the method pointers is contained in the vtable and no symbol lookup is performed. This is how all XPCOM objects are constructed: they have a pure-virtual base class (interface), and implementation class(es); both of these classes are completely hidden-visibility. Then there is an accessor method which hands out the object; client code can safely call the virtual methods. To be clear: the reason we mark the pure-virtual interface classes with hidden visibility is so that the class vtable is not exported as a weak symbol from any DSOs (I'm not sure why GCC is generating a vtable at all, since it's a pure-virtual class and cannot possibly be instantiated), as well as the automatically-generated constructor/destructor functions. However, I'm not attached to this in defiance of practical concerns. What is your model of type visibility? The type visibility is simply the visibility of the vtable/typeinfo, and the default for all member functions/data, but individual members/data can be overridden if appropriate. For instance, in my case "B" we have a class which is partially implemented in a static library that each client links against (and thus use hidden visibility), but one particularly complicated method is provided by a shared library (and therefore uses default visibility): class __attribute__ ((visibility ("hidden"))) nsID { PRBool Equals(const nsID& aOther) const; char* ToString() const; __attribute__ ((visibility ("default"))) ParseFromString(const char *aID); }; This is fairly easy to workaround, as I said, by making the class default-visibility and hiding the static-library-implemented methods. OK, you've convinced me that the compiler shouldn't override or complain about explicit visibility attributes. Do you have a problem with implicit propagation of visibility in the absence of an attribute? Specifically: Do you agree with implicitly giving template instantiations the minimum visibility of the template and arguments unless explicitly overridden? Do you agree with implicitly lowering the visibility of declarations to match their type if not explicitly set (e.g. if your CreateAClass didn't have an explicit visibility attribute)? Also, do you agree with warning about a class with greater visibility than its data members/bases? Jason
Re: gcc visibility used by moz
Jason Merrill wrote: OK, you've convinced me that the compiler shouldn't override or complain about explicit visibility attributes. Do you have a problem with implicit propagation of visibility in the absence of an attribute? Specifically: Do you agree with implicitly giving template instantiations the minimum visibility of the template and arguments unless explicitly overridden? This is not what I would naturally expect, coming from a dllimport/export mindset, but I don't think it's a problem from the mozilla POV: all of our exports are explicitly declared if/when we use hidden visibility pragmas. Is a pragma considered an explicit override? e.g. class nsIAbstract { virtual void Bar(); }; #pragma GCC visibility push(default) nsIAbstract* Getter(); #pragma GCC visibility pop Also, do you agree with warning about a class with greater visibility than its data members/bases? Sure... I would really like to disable this warning if possible, since it will be produced thousands of times in a mozilla build ;-) --BDS
Re: Different invariants about the contents of static links
Well, I agree with what you said about your example, but it's not what I am meaning. See below. Ian Lance Taylor wrote: "Rodney M. Bates" <[EMAIL PROTECTED]> writes: I don't understand this. A pointer to anywhere in an activation record (or even outside it, if outside by a fixed offset) allows access to exactly the same set of things as any other, including the value the base register holds when the activation record is current. That set is everything in the AR, using different but still fixed displacements, and nothing more, since everything else is not necessarily at a fixed displacement from the AR. OK, let me reset. It seemed to me that you were suggesting that the static link pointer should always be a constant offset from the frame pointer. No, I am not saying this. If it were so, there would be no need for a SL at all. You could just use the FP to access both local and nonlocal things. gcc doesn't work that way, though. Here is a simple counter-example. int foo (int x, int y) { int s1 () { if (--y == 0) return 0; return x + s1 (); } return s1 (); } If you compile this code, you will see that the static link pointer is passed down unchanged through the recursive calls. The frame pointer is, of course, different for each call. You can't compute the static link pointer from the frame pointer. It's completely independent. If this is not a counter-example for what you want, then I think we need a clearer explanation of what you want. Consider this slightly different example: int foo (int x, int y) { int loc; int s1 ( ) { if (--y == 0) return 0; return loc + s1 (); } loc = x; return s1 (); } I added a local variable loc to s1, and both s1 and foo access loc. When executing in foo, the frame pointer will point to a fixed spot in the activation record of foo. On i386, the FP is %ebx and it points to the dynamic link field. From there, loc is at displacement -4. Code in the body of foo will reference x at -4(FP). When we get into any instance of s1, s1's AR will contain a static link that points to the AR of foo, which is what you said. The question is where in s1's AR does the SL point to. It would make sense for it to be the same as where the frame pointer points when executing in foo, i.e., the static link would point to the dynamic link field of foo's AR. Then x could be accessed from within sl by loading the SL into some register, say REG, and referring to -4(REG). loc is at the same displacement relative to the static link in s1 as is used in foo relative to the FP. This is exactly what happens in this example, all of which makes sense to me. However, in somewhat more complicated examples, the SL value passed to s1 is not a copy of foo's FP, but instead the _value_ of the SL is a copy of foo's FP, minus 8. (I think I said this backwards in my original post.) Then loc would be accessed, from within s1, at a different displacement (+4) relative to the SL pointer, whereas the same AR field is accessed at displacement -4 relative to FP when within foo. This all executes correctly, even if it's a bit strange. But it has to take extra trouble for the code generator to keep track of two different reference addresses for the same AR and adjust SL offsets to be different from FP offsets for the same AR. I can't see any benefit. It doesn't change the set of fields a SL can access in the AR it points to a bit. Only the displacements needed change. And it wouldn't matter to me, except it's making it a lot more difficult to give gdb the ability to execute gdb-user-typed calls on nested functions and pass nested functions as parameters (where gdb has to generate static link values) and print nonlocal variables (where gdb has to know how to interpret the contents of a SL). To get the different invariant about where in an AR the SL points to, the smallest case I could get has 1) two side-by-side nested functions inside the outer function, 2) one of the nested functions has a parameter of pointer-to-function type, and 3) the other nested function is passed as the argument to said parameter. This involves building a trampoline that loads the static ancestor pointer. In this case, passing a fixed static link, constructing the static ancestor value in the trampoline, and using a static link all use the other invariant that static link values point 8 bytes lower than where a FP to the same AR points. Here is the example: int foo ( int x ) { int loc; int s1 ( int j ) { return loc + j; } int s2 ( int k, int ( * func ) ( int ) ) { return func ( k ); } loc = x; return s2 ( loc , s1 ); } When accessing parameters instead of local variables, the waters are muddied by another mechanism that also seems unnecessary to me, but I think is unrelated to my question. This is why I switched to a local variable in the examples. Ian -- Rodney M. Bates
Re: gcc visibility used by moz
Tristan Wibberley <[EMAIL PROTECTED]> writes: | Mike Stump wrote: | > On Jul 12, 2006, at 11:49 AM, Tristan Wibberley wrote: | >> "the client code needs to know about the existence of this type so | >> it can get pointers and references to instances and pass them back | >> in later and maybe be able to call virtual member functions and | >> access non-static members" by putting it in a header which they | >> document should be included by client code - thus client code | >> includes it and knows about the type. | > And what do you expect the type equality operator return for two | > types called S? | | I don't expect two types called S *you* probably don't. The C++ compiler does. | - I don't recall suggesting that | multiple types with the same name should be able to exist. then you have to consider that suggestion and come with an answer. -- Gaby
Re: gcc visibility used by moz
Tristan Wibberley <[EMAIL PROTECTED]> writes: [...] | I am suggesting that visibility attributes should *not* touch the C++ | type system in any way. But then, at the same time you're talking of polymorphic types (e.g. vtables). | Since C++ doesn't have a notion of module a | class that the C++ type system regards as hidden must be hidden from | everything (in which case, you could just comment out the class | definition instead) or nothing. That brings us back to Mike's question. We are not making progress. | I suggest that should be nothing, and | that the linker should apply the visibility attributes to *its* notion | of module. Please elaborate. -- Gaby
Re: gcc visibility used by moz
Benjamin Smedberg wrote: Jason Merrill wrote: Do you agree with implicitly giving template instantiations the minimum visibility of the template and arguments unless explicitly overridden? This is not what I would naturally expect, coming from a dllimport/export mindset, but I don't think it's a problem from the mozilla POV: all of our exports are explicitly declared if/when we use hidden visibility pragmas. Is a pragma considered an explicit override? e.g. class nsIAbstract { virtual void Bar(); }; #pragma GCC visibility push(default) nsIAbstract* Getter(); #pragma GCC visibility pop For a namespace-scope entity like this, yes (class members and template instantiations use the visibility of their class and template in preference to the current #pragma). Also, do you agree with warning about a class with greater visibility than its data members/bases? Sure... I would really like to disable this warning if possible, since it will be produced thousands of times in a mozilla build ;-) I find that surprising, since it sounds like VC++ gives the same warning about a dllexport class with a non-dllexport base. Jason
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: Tristan Wibberley <[EMAIL PROTECTED]> writes: | Mike Stump wrote: | > On Jul 12, 2006, at 11:49 AM, Tristan Wibberley wrote: | >> "the client code needs to know about the existence of this type so | >> it can get pointers and references to instances and pass them back | >> in later and maybe be able to call virtual member functions and | >> access non-static members" by putting it in a header which they | >> document should be included by client code - thus client code | >> includes it and knows about the type. | > And what do you expect the type equality operator return for two | > types called S? | | I don't expect two types called S *you* probably don't. The C++ compiler does. | - I don't recall suggesting that | multiple types with the same name should be able to exist. then you have to consider that suggestion and come with an answer. I don't see why. The point is that visibility is orthogonal to linkage; a class S with external linkage is still required by the ODR to be unique across multiple shared objects even if some of the symbols that refer to it can't be referenced from outside their defining object. The visibility restrictions place practical limits on how other objects can use the type, but that doesn't mean it isn't the same type. Jason
Re: gcc visibility used by moz
Jason Merrill <[EMAIL PROTECTED]> writes: [...] | > | - I don't recall suggesting that | > | multiple types with the same name should be able to exist. | > then you have to consider that suggestion and come with an answer. | | I don't see why. The point is that visibility is orthogonal to | linkage; a class S with external linkage is still required by the ODR | to be unique across multiple shared objects even if some of the | symbols that refer to it can't be referenced from outside their | defining object. The visibility restrictions place practical limits | on how other objects can use the type, but that doesn't mean it isn't | the same type. So, -concretely- what happens to a class S (e.g. associated type info object address, address of member functions, etc.) with external linkage, defined in multiple translation units, with say hidden visibility? -- Gaby
Re: gcc visibility used by moz
On Thu, Jul 13, 2006 at 01:36:46AM +0200, Gabriel Dos Reis wrote: > So, -concretely- what happens to a class S (e.g. associated type info object > address, address of member functions, etc.) with external linkage, > defined in multiple translation units, with say hidden visibility? Well, there are the C++ rules, and then there are the ELF rules. At the object code level we have only symbol definitions (corresponding to the addresses of member functions, virtual tables, and typeinfo). If the relevant symbols are hidden, then it's as if they aren't there, so we can violate the one-definition rule. We can have two distinct classes named S, and no one can tell. Each bit of code will see one definition of S.
Re: gcc visibility used by moz
Joe Buck <[EMAIL PROTECTED]> writes: | On Thu, Jul 13, 2006 at 01:36:46AM +0200, Gabriel Dos Reis wrote: | > So, -concretely- what happens to a class S (e.g. associated type info object | > address, address of member functions, etc.) with external linkage, | > defined in multiple translation units, with say hidden visibility? | | Well, there are the C++ rules, and then there are the ELF rules. At the | object code level we have only symbol definitions (corresponding to | the addresses of member functions, virtual tables, and typeinfo). If | the relevant symbols are hidden, then it's as if they aren't there, so | we can violate the one-definition rule. Thanks. So both notions are not as orthogonal as they may appear. Now, this being a conscious decision for ODR violation, it would probably need to be documented because then we may have typeinfo1 != typeinfo2 and yet !typeinfo1.before(typeinfo2) && !typeinfo2.before(typeinfo1) There are probably other inconsistencies to audit. | We can have two distinct | classes named S, and no one can tell. Each bit of code will see one | definition of S. -- Gaby
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: Jason Merrill <[EMAIL PROTECTED]> writes: So, -concretely- what happens to a class S (e.g. associated type info object address, address of member functions, etc.) with external linkage, defined in multiple translation units, with say hidden visibility? If it has hidden visibility then shared objects other than the one with the definition can't do much with it. They can use inline interfaces and interfaces that are explicitly overridden to have default visibility. Anything that relies on weak symbols to unify vague linkage entities across shared objects will break. It would be nice to be able to warn about such usage, but I can't think of a way to tell whether we're currently in the defining object or not, and it's not a problem if it's only used within the defining object. Jason
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: Joe Buck <[EMAIL PROTECTED]> writes: | On Thu, Jul 13, 2006 at 01:36:46AM +0200, Gabriel Dos Reis wrote: | > So, -concretely- what happens to a class S (e.g. associated type info object | > address, address of member functions, etc.) with external linkage, | > defined in multiple translation units, with say hidden visibility? | | Well, there are the C++ rules, and then there are the ELF rules. At the | object code level we have only symbol definitions (corresponding to | the addresses of member functions, virtual tables, and typeinfo). If | the relevant symbols are hidden, then it's as if they aren't there, so | we can violate the one-definition rule. Thanks. So both notions are not as orthogonal as they may appear. Now, this being a conscious decision for ODR violation, it would probably need to be documented because then we may have typeinfo1 != typeinfo2 and yet !typeinfo1.before(typeinfo2) && !typeinfo2.before(typeinfo1) There are probably other inconsistencies to audit. | We can have two distinct | classes named S, and no one can tell. Each bit of code will see one | definition of S. But I think it is important that there are three places where visibility is a factor (as a concept of "being able to see things" rather than the attribute). 1) If a class definition is not present in a given translation unit, but a class declaration is, then the translation unit may normally pass around a pointer to an instance of that class and also a reference to an instance of that class, but may not do anything else with it. 2) Until now, the visibility attribute was used for optimising symbols exported from a .so for when things will only be used within that .so (but used across its constituent .o files). Saving unnecessary runtime costs and non-volatile storage costs. This is really valuable and I'd like to see it remain available. The last is the interesting case, which it seems 2) has broken while this was being worked on. 3) For file scope functions and file scope variables, the static keyword is overloaded to indicate that their definition should be created for this translation unit such that it is a unique function or variable even if other functions or variables use the same name in both translation units. I can see that something could be desirable to define classes just for the internal behaviour of a translation unit without having to consider name conflict, but the unnamed namespace should do that shouldn't it? Which also satisfies the ODR since each unnamed namespace in separate translation units is a different one. It kind of makes sense to hide functions that take arguments or return pointers to types in the translation unit unnamed namespace (but that is so easy for the programmer to cause just by putting the prototype into the unnamed namespace that its not worth doing anything fancy other than warning since they may be trying to do some clever multi-language interoperability thing. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: Tristan Wibberley <[EMAIL PROTECTED]> writes: [...] | I am suggesting that visibility attributes should *not* touch the C++ | type system in any way. But then, at the same time you're talking of polymorphic types (e.g. vtables). vtables happen to just work with types whose associated symbols are not exported from a shared object - as long as you are not trying to construct an instance from outside the shared object. So you can call a function that *is* exported and get a pointer to a type that you know (from an included header) has some virtual functions that you can lookup with an offset relative to the pointer to the instance (an offset calculated at compile time). Thus not requiring any change in the C++ type system - nor any propagation to infer new access controls on members. | Since C++ doesn't have a notion of module a | class that the C++ type system regards as hidden must be hidden from | everything (in which case, you could just comment out the class | definition instead) or nothing. That brings us back to Mike's question. We are not making progress. | I suggest that should be nothing, and | that the linker should apply the visibility attributes to *its* notion | of module. Please elaborate. I've sent another email in reply elsewhere with a list of the three visibility concepts that I've seen (which are all mostly orthogonal). Which hopefully will make sure I'm talking about the same things as you are. -- Tristan Wibberley These opinions are my own, and do not reflect those of my employer.
Re: Question about vec_extract
Jim Wilson <[EMAIL PROTECTED]> writes: > Andrew Pinski wrote: > > I have been trying to figure out when the pattern vec_extract is > > invoked. > > I looked at this when I worked on the mips simd support. In > config/mips/mips-ps-3d.md I wrote > ;; ??? This is only generated if we perform a vector operation that > has to be > ;; emulated. There is no other way to get a vector mode bitfield extract > ;; currently. > > So it can be generated, but you have to use a vector mode that doesn't > exist on the target. Which kind of defeats the purpose of having > it. Anyways, I think all we need here is a little syntax to get the > operation we want. Maybe a builtin function or something. Personally, I think we should support operator[] for vectors. That said, I'm not happy with a builtin function. I think that we should make every effort to make union { TYPE a[COUNT]; VECTOR v; } u; u.v = v; x = u.a[0]; use vec_extract, because in the absence of operator[] that is the natural way for people to extract an element from a vector. The other natural way is ((TYPE *)&v)[0] which is technically an aliasing violation but one which gcc explicitly accepts (search for VECTOR_TYPE in get_alias_set). Although, since it is not documented, people should probably be discouraged from doing this. Ian
Re: Question about vec_extract
That said, I'm not happy with a builtin function. I think that we should make every effort to make union { TYPE a[COUNT]; VECTOR v; } u; u.v = v; x = u.a[0]; use vec_extract, because in the absence of operator[] that is the natural way for people to extract an element from a vector. Ok, I am going to extend SRA (or maybe a new pass, I don't know yet) to produce BIT_FIELD_REF which in turns calls vec_extract patterns. The other natural way is ((TYPE *)&v)[0] which is technically an aliasing violation but one which gcc explicitly accepts (search for VECTOR_TYPE in get_alias_set). Although, since it is not documented, people should probably be discouraged from doing this. This currently actually does not produce vec_extract though it might be easy to extend fold to produce BIT_FIELD_REF for this case. Thanks, Andrew Pinski
Re: gcc visibility used by moz
Tristan Wibberley <[EMAIL PROTECTED]> writes: > But I think it is important that there are three places where > visibility is a factor (as a concept of "being able to see things" > rather than the attribute). I think it would help if you wrote down the rules for the visibility attributes as applied to C++. Write it as though you were writing the gcc user manual. I'm no expert at this stuff, but I have to say that right now I don't understand what you are suggesting. Ian
A correction: Different invariants about the contents of static links]
This is repost of my slightly earlier post, with a critical and confusing misstatement corrected. Well, I agree with what you said about your example, but it's not what I am meaning. See below. Ian Lance Taylor wrote: "Rodney M. Bates" <[EMAIL PROTECTED]> writes: I don't understand this. A pointer to anywhere in an activation record (or even outside it, if outside by a fixed offset) allows access to exactly the same set of things as any other, including the value the base register holds when the activation record is current. That set is everything in the AR, using different but still fixed displacements, and nothing more, since everything else is not necessarily at a fixed displacement from the AR. OK, let me reset. It seemed to me that you were suggesting that the static link pointer should always be a constant offset from the frame pointer. No, I am not saying this. If it were so, there would be no need for a SL at all. You could just use the FP to access both local and nonlocal things. gcc doesn't work that way, though. Here is a simple counter-example. int foo (int x, int y) { int s1 () { if (--y == 0) return 0; return x + s1 (); } return s1 (); } If you compile this code, you will see that the static link pointer is passed down unchanged through the recursive calls. The frame pointer is, of course, different for each call. You can't compute the static link pointer from the frame pointer. It's completely independent. If this is not a counter-example for what you want, then I think we need a clearer explanation of what you want. Consider this slightly different example: int foo (int x, int y) { int loc; int s1 ( ) { if (--y == 0) return 0; return loc + s1 (); } loc = x; return s1 (); } I added a local variable loc to s1, and both s1 and foo access loc. When executing in foo, the frame pointer will point to a fixed spot in the activation record of foo. On i386, the FP is %ebx and it points to the dynamic link field. From there, loc is at displacement -4. Code in the body of foo will reference x at -4(FP). When we get into any instance of s1, s1's AR will contain a static link that points to the AR of foo, which is what you said. The question is where in foo's AR does the SL point to. It would make sense for it to be the same as where the frame pointer points when executing in foo, i.e., the static link would point to the dynamic link field of foo's AR. Then x could be accessed from within sl by loading the SL into some register, say REG, and referring to -4(REG). loc is at the same displacement relative to the static link in s1 as is used in foo relative to the FP. This is exactly what happens in this example, all of which makes sense to me. However, in somewhat more complicated examples, the SL value passed to s1 is not a copy of foo's FP, but instead the _value_ of the SL is a copy of foo's FP, minus 8. (I think I said this backwards in my original post.) Then loc would be accessed, from within s1, at a different displacement (+4) relative to the SL pointer, whereas the same AR field is accessed at displacement -4 relative to FP when within foo. This all executes correctly, even if it's a bit strange. But it has to take extra trouble for the code generator to keep track of two different reference addresses for the same AR and adjust SL offsets to be different from FP offsets for the same AR. I can't see any benefit. It doesn't change the set of fields a SL can access in the AR it points to a bit. Only the displacements needed change. And it wouldn't matter to me, except it's making it a lot more difficult to give gdb the ability to execute gdb-user-typed calls on nested functions and pass nested functions as parameters (where gdb has to generate static link values) and print nonlocal variables (where gdb has to know how to interpret the contents of a SL). To get the different invariant about where in an AR the SL points to, the smallest case I could get has 1) two side-by-side nested functions inside the outer function, 2) one of the nested functions has a parameter of pointer-to-function type, and 3) the other nested function is passed as the argument to said parameter. This involves building a trampoline that loads the static ancestor pointer. In this case, passing a fixed static link, constructing the static ancestor value in the trampoline, and using a static link all use the other invariant that static link values point 8 bytes lower than where a FP to the same AR points. Here is the example: int foo ( int x ) { int loc; int s1 ( int j ) { return loc + j; } int s2 ( int k, int ( * func ) ( int ) ) { return func ( k ); } loc = x; return s2 ( loc , s1 ); } When accessing parameters instead of local variables, the waters are muddied by another mechanism that also seems unnecessary to me, but I think is unrelated to my question. This is wh
Re: gcc visibility used by moz
Daniel Jacobowitz wrote: I just don't get it. Why should it matter whether a member function is virtual or not in order to be able to call it from outside this shared object? Either you can access the public members of the class, or you can't. Being able to access some of them and get link errors on others is a very strange default interpretation. It shouldn't matter. The public members of a class should all have default visibility if any do. But that's a coding standards issue. Jason
Re: gcc visibility used by moz
Gabriel Dos Reis wrote: >> Joe Buck wrote: Now, this being a conscious decision for ODR violation, it would probably need to be documented because then we may have typeinfo1 != typeinfo2 and yet !typeinfo1.before(typeinfo2) && !typeinfo2.before(typeinfo1) There are probably other inconsistencies to audit. | We can have two distinct | classes named S, and no one can tell. Each bit of code will see one | definition of S. I think that Joe's point is that IF you have two classes named S, then they're hidden away in separate shared libraries and you can't compare them, because no piece of code knows about both of them. Any class that is part of the public interface of a shared library is part of the public interface, and therefore must be unique through the program. In any case, this ODR business seems rather tangential to the discussion of visibility semantics. The primary purpose of the visibility work is limiting the number of symbols exported from a particular shared library in order to cut down on load time. Can we please focus on the semantics we want for that instead of trying to solve a theoretical problem that has been around as long as people have tried to use shared libraries with C++? Jason