Hi

In general I think they should match.  But without seeing concrete
examples of where they do not I can't comment on whether such exceptions
make sense.  For example if you adjust a DECLs alignment and then
re-layout it I'd expect you might get a non-BLKmode mode for an
aggregate in some circumstances -- but then decl and type are not 1:1
compatible (due to different alignment), but this case is clearly desired
as requiring type copies for the sake of alignment would be wasteful.

The C++ FE lays out base classes as FIELD_DECLs. In build_base_field_1 the
mode for such decls is set:

gcc/cp/class.c
4528  SET_DECL_MODE (decl, TYPE_MODE (basetype));

Before this the type of this decl is set to CLASSTYPE_AS_BASE (basetype) via a call to build_decl. Thus in general DECL_MODE (decl) != TYPE_MODE (its type)
(and it does happen e.g. TYPE_MODE (basetype) == BLKmode and
TYPE_MODE (CLASSTYPE_AS_BASE (basetype)) == DImode in the example below).

Moreover, the types of such fields are later re-set in layout_class_type to
values unrelated to both basetype and CLASSTYPE_AS_BASE (basetype):

gcc/cp/class.c
6692 /* Now that we're done with layout, give the base fields the real types.
6693 for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
6694 if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
6695     TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));

So the modes of the decl and its type don't match and we've lost the
information needed to deduce the mode of the decl.

Here is the aforementioned example:

  struct operand
  {
      virtual void gen_transform () {}
  };

  struct c_expr : public operand {};

Here is another one (demonstrates a different kind of mismatch):

  class hsa_op_base
  {
    public:
      hsa_op_base *m_next;
      unsigned m_brig_op_offset;
    protected:
      hsa_op_base (int k);
  };

  class hsa_op_reg: public hsa_op_base {};

In the latter example TYPE_MODE (CLASSTYPE_AS_BASE (basetype)) == BLKmode and
TYPE_MODE (basetype) == TImode.

To be clear: in the examples above the problem (mismatch between streamed type's mode and decl's mode if we are doing LTO) is with the implicit field in
the derived class corresponding to an instance of the base class.
--
Vlad

Reply via email to