> From: DJ Delorie <[EMAIL PROTECTED]>
> 
>>   where then the target may declare class machine_mode
>>   target_int_mode ("HI", 16),
> 
> This is where we disagree.  The *target* shouldn't map types to modes.
> The *MI* should map types to modes. The target just creates the modes
> it supports and describes them. The MI looks them up by description
> (NOT NAME).  If the MI needs a 32 bit unsigned scalar, it does
> lookup_mode(32, M_SCALAR, M_UNSIGNED) and uses whatever gets returned.

- ok, and how does it know that it needs a 32-bit unsigned scalar?
  Answer: because it wants to know what mode it needs to specify for
  for an operation on a particular type which has those characteristics
  as defined by the targets definition of an int for example. (so why in
  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?)

> The fact that you're still trying to assign a "well known name" to a
> given type/mode/whatever means you haven't gotten away from the (to
> me) fundamental problem, that MI chooses modes according to what
> they're *for* instead of according to what they *are*.

- unless I misunderstand (which I admittedly may), the MI portion of
  the code is and should be based on manipulating data structures which
  correspond to user programs which are digested down to a canonical
  representation of "well known named" operators with operands of
  correspondingly "well known named" types (such as bool, char, int,
  float); who's sizes are defined by the target. So it would seem to
  stand to reason that the MI portion of GCC does and should restrict
  itself to well known "type" modes, which are defined to be mapped to
  physical modes as defined by the target? please see below)

>>   target_unit_mode // presumably the target's smallest addressable datum.
> 
> 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
  while being able to address memory with a 4-bit wide granularity.
  (in essence, there needs to be a mechanism by which a target may define
   the it's address resolution, and alignment requirements, independently
   of it's specified type sizes, if not this way, then some other)

>>   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
  array and/or struct members (which need not be aligned to the width of
  of the target's widest naturally addressable datum, but it's smallest?)

>>   as there seems no valid reason for the target neutral portion of the
>>   compiler to ever refer to XXmode under any circumstance?
> 
> Ah, but in your case it *is* aware, it just calls it
> "target_word_mode" instead of "SImode" with all the same problems with
> assumptions.

- no?, I presume that "target_word_mode" would merely describe (mentioned
  above), an aspect of the physical target's natural memory access
  granularity, without having any presumed relationship to any particular
  separately defined target "type" mode such as it's target_int_mode for
  example.

>>   where correspondingly the MI portions of GCC utilizes the appropriate
>>   pointer mode as a function of the type of access being performed,
> 
> In my case, the target has to check the attributes of the
> function/data to decide what kind of pointer to use.  Again, "MI
> assuming" that all function pointers are the same is WRONG.

- 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
  mode it desires), rather than the target having to try to figure out based
  upon the more limited tree/rtx context visible to it?) thereby also
  exposing more potential opportunities for MI optimization to the middle
  end it would seem?

>> - understood, although I honestly don't believe there are that many, and
>>   it eliminates any possible confusion, and a host of other #defines.
> 
> My current port supports maybe 4-5 hard modes.  There are 19
> machine_modes defined.  That's about 4x as many as I really need to
> define, and that doesn't even include synthetic vector modes and such.

- 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)

>> - as you've noted, all the information GCC MI portion needs to "do the
>>   right thing" already exists scattered in various target definitions,
>>   but it hasn't prevented mode assumptions from being made, and XXmodes
>>   being hard-coded into the MI sources on occasion; which is the only
>>   reason that I thought that by forcing target_TYPE_mode's to be the
>>   only thing available, GCC would indirectly be forced to always to the
>>   "right thing"?
> 
> The less available the better, true.  But target_*_modes don't need to
> be available either.  If you use a query/lookup API, MI can assume
> there are a *lot* of machine modes (one for each variable, one for
> each function, one for each C data type, etc), and let the target map
> them to available modes.

- 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.

> targetm.modes.set_mode_for_decl(decl);
> 
> See?  This allows for a custom mode just for the given decl (it might
> be a 17 bit ternary value in a DSP), doesn't make assumptions about
> available machine modes, and MI can provide a naive default hook for
> targets that do "the usual thing".

- 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, (where these canonical types need only be mapped to
  target supported/named/defined modes upon code generation, it would seem?)

> if (!TYPE_MODE (TREE_TYPE (decl)))
>  TYPE_MODE (TREE_TYPE (decl)) = find_mode_for_type (TREE_TYPE (decl));
> DECL_MODE (decl) = TYPE_MODE (TREE_TYPE (decl));

- 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;

  where the target defines:

  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},
       ...}

  thereby the MI portion need only do stuff like:
  
  if (TYPE_MODE(...) == char_mode) ...

  -or-
 
  if(TYPE_MODE(...)->size < word_mode->.size) ...

  where when required for target template mapping, mode names may be
  extracted via. TYPE_MODE(...)->mode, thereby the MI remains fully
  abstracted, and never needs to be aware or manipulate physical modes
  as named and utilized by the target it would seem?

> or something like that.  Caching is OK if you cache it the right way
> (with a type, not in a global "this is a pointer" variable).

(but recognize we're likely looking a things from different perspectives)


Reply via email to