September 05, 2012
I had some more time to investigate gdc's issue #120, the problem which prevents gdc from working properly on ARM without disabling certain optimization flags. I found a way to work-around the issue in the backend, but it leads to lots of code duplication. And the duplicated code must be kept in sync with code in the DMD frontend, so I think this issue really needs to be fixed in the DMD frontend.

Here's the gdc backend hack for reference (excluding the ModuleInfo/TypeInfo fixes which requires duplicating the genmoduleinfo function): https://github.com/jpf91/GDC/commits/fix120

The problem always occurs if a variable declarations type size is smaller than it's initializer size. In theory setting the type size to the same size as the initializer is enough to make it work on ARM. But there's a problem: In the cases where this issue occurs the type size is not static and must be calculated. For the ModuleInfo example the calculation code is quite long (genmoduleinfo) and we'd have to duplicate that code and keep it in sync. Also simply adjusting the type size doesn't fix the missing debug info.



So these are the cases where this problems occurs and what I think would be the proper fixes, would be great to get some feedback on this:

static arrays when the initializer is smaller than the array

GCC can't deal with different element sizes in one array. DMD adds the
padding at the
end of the array as one big element, which causes issues for gdc. This
can be fixed
easily in gdc, but the fix could also be applied to the upstream DMD
frontend as it
shouldn't cause problems for dmd/ldc either.
See:
https://github.com/jpf91/GDC/commit/802d049f9b9bb457e9dd01fa9213ba2f6012f66f

ClassInfo:

The ClassInfo is always typed as object_.d/TypeInfo_Class but the
initializer is set to TypeInfo_Class + a static array of struct
Interface + a static array of function pointers (vtable entries). This
extra data is used for the "Interface[] interfaces" member in
TypeInfo_Class.
In ClassDeclaration::toObjFile the interfaces array (
https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L640 )
is currently referenced using dtxoff (
https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L552 ).
Is there a specific reason to implement it like this?
Can we change it to output a own symbol for the interfaces array(module
scope), then make the symbol static so it has no visible name outside of
the object file and then reference it? This would not only fix the arm
bugs, it also allows to put out proper debug information for this
interfaces array.
The remaining vtable pointer array should get it's own static symbol as
well. (Or probably the interfaces array and the vtable
array(s) should be combined into one struct which should get it's own
static symbol?)

TypeInfoStruct:

This is typed as the TypeInfo struct in object_.d, but the initializer
additionally contains the name data of the struct. See
TypeInfoStructDeclaration::toDt (
https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/typinf.c#L714 ).
Can we use a own static symbol for the name?
(probably more TypeInfo is affected, I'll have to check this)

ModuleInfo:

This seems to be the most difficult part. It has no common type at all,
the size always differs. GDC currently types it as object, althought
it's a struct...
It would be great if we could create a StructDeclaration/VarDeclaration
for it and use the same code paths that are used for all
StructDeclarations instead of the Module::genmoduleinfo(
https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L53 )
function. We probably want to somehow avoid the TypeInfo for this struct
though.

-- 
Johannes Pfau

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

September 05, 2012
These changes sound worthwhile.



On 9/5/2012 8:15 AM, Johannes Pfau wrote:
> I had some more time to investigate gdc's issue #120, the problem which
> prevents gdc from working properly on ARM without disabling certain
> optimization flags. I found a way to work-around the issue in the
> backend, but it leads to lots of code duplication. And the duplicated
> code must be kept in sync with code in the DMD frontend, so I think this
> issue really needs to be fixed in the DMD frontend.
>
> Here's the gdc backend hack for reference (excluding the
> ModuleInfo/TypeInfo fixes which requires duplicating the genmoduleinfo
> function): https://github.com/jpf91/GDC/commits/fix120
>
> The problem always occurs if a variable declarations type size is
> smaller than it's initializer size. In theory setting the type size to
> the same size as the initializer is enough to make it work on ARM. But
> there's a problem: In the cases where this issue occurs the type size is
> not static and must be calculated. For the ModuleInfo example the
> calculation code is quite long (genmoduleinfo) and we'd have to
> duplicate that code and keep it in sync. Also simply adjusting the type
> size doesn't fix the missing debug info.
>
>
>
> So these are the cases where this problems occurs and what I think would
> be the proper fixes, would be great to get some feedback on this:
>
> static arrays when the initializer is smaller than the array
>
> GCC can't deal with different element sizes in one array. DMD adds the
> padding at the
> end of the array as one big element, which causes issues for gdc. This
> can be fixed
> easily in gdc, but the fix could also be applied to the upstream DMD
> frontend as it
> shouldn't cause problems for dmd/ldc either.
> See:
> https://github.com/jpf91/GDC/commit/802d049f9b9bb457e9dd01fa9213ba2f6012f66f
>
> ClassInfo:
>
> The ClassInfo is always typed as object_.d/TypeInfo_Class but the
> initializer is set to TypeInfo_Class + a static array of struct
> Interface + a static array of function pointers (vtable entries). This
> extra data is used for the "Interface[] interfaces" member in
> TypeInfo_Class.
> In ClassDeclaration::toObjFile the interfaces array (
> https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L640 )
> is currently referenced using dtxoff (
> https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L552 ).
> Is there a specific reason to implement it like this?
> Can we change it to output a own symbol for the interfaces array(module
> scope), then make the symbol static so it has no visible name outside of
> the object file and then reference it? This would not only fix the arm
> bugs, it also allows to put out proper debug information for this
> interfaces array.
> The remaining vtable pointer array should get it's own static symbol as
> well. (Or probably the interfaces array and the vtable
> array(s) should be combined into one struct which should get it's own
> static symbol?)
>
> TypeInfoStruct:
>
> This is typed as the TypeInfo struct in object_.d, but the initializer
> additionally contains the name data of the struct. See
> TypeInfoStructDeclaration::toDt (
> https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/typinf.c#L714 ).
> Can we use a own static symbol for the name?
> (probably more TypeInfo is affected, I'll have to check this)
>
> ModuleInfo:
>
> This seems to be the most difficult part. It has no common type at all,
> the size always differs. GDC currently types it as object, althought
> it's a struct...
> It would be great if we could create a StructDeclaration/VarDeclaration
> for it and use the same code paths that are used for all
> StructDeclarations instead of the Module::genmoduleinfo(
> https://github.com/jpf91/GDC/blob/fix120/gcc/d/dfrontend/toobj.c#L53 )
> function. We probably want to somehow avoid the TypeInfo for this struct
> though.
>


_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals