From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9287 invoked by alias); 26 May 2005 00:35:06 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 9147 invoked by uid 22791); 26 May 2005 00:34:51 -0000 Received: from sccrmhc13.comcast.net (HELO sccrmhc13.comcast.net) (204.127.202.64) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Thu, 26 May 2005 00:34:50 +0000 Received: from [10.0.1.2] (c-24-61-199-96.hsd1.nh.comcast.net[24.61.199.96]) by comcast.net (sccrmhc13) with SMTP id <200505260034370160063nj1e>; Thu, 26 May 2005 00:34:38 +0000 User-Agent: Microsoft-Entourage/11.1.0.040913 Date: Thu, 26 May 2005 08:15:00 -0000 Subject: Re: Compiling GCC with g++: a report From: Paul Schlie To: DJ Delorie CC: Message-ID: In-Reply-To: <200505252152.j4PLq8sq014808@greed.delorie.com> Mime-version: 1.0 Content-type: text/plain; charset="US-ASCII" Content-transfer-encoding: 7bit X-SW-Source: 2005-05/txt/msg01407.txt.bz2 > From: DJ Delorie >> - ok, and how does it know that it needs a 32-bit unsigned scalar? > > tm.h: #define INT_TYPE_SIZE 32 > > Combined with "unsigned int foo;" in the user's source file. > > The MI doesn't need to know that this fits in a QImode. - agreed, all it needs to know is that a int_mode operand/operator is required, which is defined to correspond to some physical mode given some name by the target. >> the world is it desirable to go go in a big circle to identify >> which mode corresponds to a type as defined by the target, rather >> than simply having the target define it directly?) > > Because on many targets, small scalars can be held in larger > registers, and large scalars (or complex or vector types) can be held > in groups of small registers. There isn't a strict mapping between C > types and hardware modes. Plus, the target might provide attributes > that alter the mode (think "__attribute__((mode(FRED)))"). - Huh?, can you provide a single example of where a char type would be mapped by the target to two different target specified modes? (as it seems that although multiple char's may be specified as being mapped to into an indexed subreg of a wider target specified mode, the middle end is responsible for identifying how and how many and smaller datum, may be packed into a vector, as defined by the target's specification of it's vector_mode, if supported at all, not the target.) >> correspondingly "well known named" types (such as bool, char, int, > > In this case, the "well known named" things are front-end types, like > "int" and "short", not back-end types, like PSImode or V4QImode. - fully agree, which is why the MI need/should never need to identify the target physical mode (given some name by the target), which corresponds to the canonical type mode name like int_mode as used by the MI until target rtl templates need to be matched. > A simple example of this type of problem is when MI uses "SImode" for > integers, on a target with 16-bit integers. SImode is wrong. Any > time you have "well known" types coming from the *target* you're > setting yourself up for this type of thing. - fully agree, no physical mode name (such as SImode) as may be defined by the target should ever be referred to by the MI portion of the compiler until target specific templates which use the target defined physical mode names need to be matched. >>> BImode in most cases, not really useful that way. >> >> - maybe we are using different terminology, as there would seem to >> be no reason that a target couldn't define that a bool was a 16-bit >> wide datum > > I didn't say anything about bools. See? You're making the same wrong > assumptions GCC makes. "bool" should be a well-known name. BImode > shouldn't. My chip has an addressing mode that addresses individual > bits, has nothing to do with the "bool" type. - sorry, I was just attempting to respond given my best guess as to your intent when you introduced BI mode into the discussion by with the above to: >>>> target_unit_mode // presumably the target's smallest addressable datum. (presuming that you meant that BI mode as presumed to the narrowest width physical mode, which I mistakenly presumed you associated with bool, but agree that the MI portion of the compiler should never presume anything about any particular target named machine physical mode.) >> (in essence, there needs to be a mechanism by which a target may >> define the it's address resolution, and alignment requirements, >> independently > > The chip I'm working on has three addressing modes, with two different > resolutions and alignments. Your assumption - that there is one > address resolution - already breaks my chip. - fully agree, the MI portion of the compiler should make no assumptions about the equality of pointer modes as may be necessary to be distinct for a particular target, but do presume that all stack pointer, function pointer, label pointer, readonly_data pointer, heap pointer, etc. references utilize a common target defined mode, which may all be mapped to the same target physical pointer mode, or different physical pointer modes (i.e. function pointers may be defined to map to WILMA mode, where label pointers may be defined to map to BARNEY mode physical target pointer modes). >>>> target_word_mode // presumably the target's largest addressable datum. >>> >>> BLKmode in all cases. Also not useful. >> >> - I hope not, as block mode operands seem to be used for moving data >> with finer granularity than the target's word-width when >> initializing char > > You said largest addressable, not largest alignment. More > assumptions. On some chips, for example, "words" may be unaligned, > but "floats" must be aligned. Your "well known name" is already > wrong. - fully agreed, my mistake in making the same incorrect assumption which GCC seems to do on occasion, as alignment should likely be an attribute of every target defined logical type -> physical mode mapping definition. >> - no?, I presume that "target_word_mode" would merely describe >> (mentioned above), an aspect of the physical target's natural memory >> access granularity, > > You're assuming the target has ONE "natural" access granularity. Just > the dichotomy between scalars and reals breaks that. > > My chip has four "natural" accessing granularities. Which would I > choose? (yes, I was stumped for UNITS_PER_WORD because it was used > for many things, and I needed different things it was used for to work > with different sized data). > > Heck, the i386 has five natural modes (QI, HI, SI/SF, DI/DF TF). Pick > one. - fully agreed, as above. >> - understood, although it would seem much easier if the MI portion simply >> identified the type of pointer it required based upon the context of the >> access which it inherently knows (which the target may map to whatever > > "inherently" is misleading. The MI has two feasible options - assume > all pointers are the same, or let the target decide. There is no > usable middle ground. - given that the target may only "decide" based on the uniqueness of the contextual of the pointer's use visible to it, it depends on the MI differentiating such uses. Which seems simpler for the MI to do explicitly by named canonical pointer modes (such as function_pointer, label_pointer, rodata_pointer, etc.) rather than leaving it up to chance that they may be discrimated as may be required by the target; which the target may define to map to the same or different physical modes as required by the target, it would seem? >> mode it desires), rather than the target having to try to figure >> out based upon the more limited tree/rtx context visible to it?) > > The tree/decl/rtx is all the MI has too. - but only needs to associate a logical type mode with a target defined physical mode when attempting to match the the target's instruction rtl definitions defined in terms of physical modes SI, DI, WILMA, etc.), it would seem? >> - understood, although hardly believe that it's a problem to require that >> a target define the logical->physical mapping required for for the 20 >> or so logically distinct type variations that the MI portion is and >> should be aware of (rather than subject the mapping to any mishandling) > > Ok, next time a new language front and is added with new data types, > you get to update all the target backends. - yes, as would always need to be done if the language's new data-type precision or representation is target dependant, as most language data-types are? >> - I do believe were just using somewhat different terminology, as the MI >> portion of the compiler does and must deal with "well known named" typed >> operations and operands. > > Does? Yes. Must? No, outside of the *language* types (not the > *target* types). - fully agree, which is why the MI need only deal with *language* type/modes and rely on the target to define their mapping to *target* types/modes. >> - sorry, I don't see; as the program code, and internal tree representation >> of that code (as you've noted below), identifies all nodes as having one >> of N canonical types (bool, char, short, int, *, [], etc.) not an >> arbitrary type, > > *Except* when you consider __attribute__ which can modify *anything* > in gcc. This is how we get vector variables, interrupt functions, > etc. - unless I misunderstand, I suspect you're mixing a few orthogonal issues: - the last first, a vector is just another canonical type, no different than bool, char, etc. and needs it's target specific attributes described by the target, and correspondingly mapped to some target defined named physical mode which the target's rtl is described using. - interrupt, no-return, etc. attributes aren't types per-se, but rather semantic modifiers which GCC has provided as a convenience to both programmers, and the middle-end architecture to enable the incremental specification of semantics in a canonical way by language front-ends, to enable the development of a language neutral middle end? - the use of GCC's __attribute__ extension directly in user code, seems to simply extend this capability to the programmer. And seemingly may be used to introduce "new" types, but only if that "new" type is defined as being physically equivalent to an existing supported type/mode known already to both the MI and the target portions of the compiler, as otherwise neither the MI or target portions of the compiler understands it relationship/conversion to/from other types, or it's corresponding target specific physical mode to use to represent the type, or operations it would seem? >> - why bother if: TYPE_MODE :: *target_type_mode, i.e: >> >> typedef struct { >> char* name; >> char* mode: >> char size: >> enum attribute {is_signed, is_unsigned, is_floating, is_void}; >> } target_type_mode; >> >> enum type_mode { >> bool_mode = &(target_type_mode){"bool", "QI", 10, is_unsinged}, >> char_mode = &(target_type_mode){"char", "QI", 10, is_unsigned}, >> uint_mode = &(target_type_mode){"uint", "HI", 17, is_unsigned}, >> ...} > > No, you're missing a lot of variability here. - like? (observing that it may be easily augmented as desired/required) >> if (TYPE_MODE(...) == char_mode) ... > > I'd rather see > > if (TYPE_MODE(...) == TYPE_MODE(...)) > > or > if (BITS_PER_MODE (TYPE_MODE (...)) <= BITS_PER_BYTE) - out of curiosity, why? (but suspect you simply like flexibility of another level of abstraction)