* * *

Author Topic: Error: Impossible to overload assignment for equal types  (Read 331 times)

SonnyBoyXXl

  • New member
  • *
  • Posts: 25
Error: Impossible to overload assignment for equal types
« on: December 07, 2017, 12:04:26 am »
Good evening,
how is the assigment of equal types solved in FPC interally?
I'm working on the DirectX Math unit and the assigment of Matrix or Vectors looks e.q. like this
Quote
inline XMFLOAT4X3& XMFLOAT4X3::operator=
(
    const XMFLOAT4X3& Float4x3
)
{
    XMVECTOR V1 = XMLoadFloat4((const XMFLOAT4*)&Float4x3._11);
    XMVECTOR V2 = XMLoadFloat4((const XMFLOAT4*)&Float4x3._22);
    XMVECTOR V3 = XMLoadFloat4((const XMFLOAT4*)&Float4x3._33);

    XMStoreFloat4((XMFLOAT4*)&_11, V1);
    XMStoreFloat4((XMFLOAT4*)&_22, V2);
    XMStoreFloat4((XMFLOAT4*)&_33, V3);

    return *this;
}

The XMLoadFloat4 and XMStoreFloat4 are using SSE/AVX op codes, so should be very fast.

But if I define a assigment operator like this:
Code: Pascal  [Select]
  1. operator := (a : TXMFLOAT4X3) b : TXMFLOAT4X3;
  2.  

I get the error message: Impossible to overload assignment for equal types.
So my question is: how is the assigment handeld in FPC internally? MemCopy? which should be slower then SSE ops I think.
And is it possible to do that overload somehow. C++ can handle this, so I think Pascal can do this also :)
class operator Implicit or Explicit also dont work.

thx

Mr.Madguy

  • Full Member
  • ***
  • Posts: 214
Re: Error: Impossible to overload assignment for equal types
« Reply #1 on: December 07, 2017, 10:22:09 am »
People should never ask such questions, because there is easy and standard way to find it out: View->Debug windows->Assembler

Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. {$ASMMODE INTEL}
  8.  
  9. uses
  10.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
  11.  
  12. type
  13.   TVector = array[0..3] of Single;
  14.   TMatrix = record
  15.     Vectors:array[0..3] of TVector;
  16.   end;
  17.  
  18.  
  19.   { TForm1 }
  20.  
  21.   TForm1 = class(TForm)
  22.     procedure FormCreate(Sender: TObject);
  23.   private
  24.     { private declarations }
  25.   public
  26.     { public declarations }
  27.   end;
  28.  
  29. var
  30.   Form1: TForm1;
  31.   Matrix1:TMatrix;
  32.   Matrix2:TMatrix;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.FormCreate(Sender: TObject);
  41. begin
  42.   {Needed to set breakpoint in release mode!}
  43.   asm
  44.     INT 3
  45.   end;
  46.   Matrix1 := Matrix2;
  47. end;
  48.  
  49. end.
  50.  

Both Debug and Release mode give this result:

64bit:
Code: [Select]
lea    rdi,[rip+0x21a18e]
lea    rsi,[rip+0x21a1c7]
movabs rcx,0x8
rep movs QWORD PTR es:[rdi],QWORD PTR ds:[rsi]

32bit (I don't know, how to enable SSE support, but I tried different target processors):
Code: [Select]
mov    edi,0x5915d0
mov    esi,0x591610
mov    ecx,0x10
rep movs DWORD PTR es:[edi],DWORD PTR ds:[esi]

I.e. it's simple data copying via REP MOVS instruction - no SSE is used.
« Last Edit: December 07, 2017, 11:03:52 am by Mr.Madguy »
Completely overhauling DynamicData 1.0 on it's way to 2.0
Crazy unit testing

SonnyBoyXXl

  • New member
  • *
  • Posts: 25
Re: Error: Impossible to overload assignment for equal types
« Reply #2 on: December 07, 2017, 02:26:22 pm »
Hi Mr. Madguy,

thank you, but
1) I think all questions are allowed and
2) sorry, but your answer is not the answer to my question. Cause my question is HOW to override the behavior that a assigment can not be overriden and therefore I think we must look deeper inside the FPC compiler itself.
3) that FPC can not make use of SSE in that case is normal, cause how should the compiler know that this type of code it is handling is a vector operation and therefor a SIMD op code will be more performant? Look at the discussion about optimization possibilities of the different C/C++ compilers. Each compiler gives other results, more or less optimized.

4) the error is raised in fpcsrc/compiler/pdecsub.pas by calling equal_defs, so this would be the point of improvement (?)  :D


Mr.Madguy

  • Full Member
  • ***
  • Posts: 214
Re: Error: Impossible to overload assignment for equal types
« Reply #3 on: December 08, 2017, 09:44:33 am »
First question was:
So my question is: how is the assigment handeld in FPC internally? MemCopy? which should be slower then SSE ops I think.
I answered to this question.

Answer for other questions is obvious - you need to modify FPC sources to do it. I can't help with this. But this error shouldn't be generated during parsing. I think, it should be generated during type check pass.
« Last Edit: December 08, 2017, 10:55:38 am by Mr.Madguy »
Completely overhauling DynamicData 1.0 on it's way to 2.0
Crazy unit testing

Thaddy

  • Hero Member
  • *****
  • Posts: 4741
Re: Error: Impossible to overload assignment for equal types
« Reply #4 on: December 08, 2017, 11:34:39 am »
1. Note that assignment operators for equal type are always handled by the compiler by necessity. Hence can not overload.
2. Note that if you build FPC from source you can force it to use AVX/SSE etc.: Specify e.g. for AVX2: OPT='-CfAVX2'  as a make command line option.
That will build FPC, the RTL and all packages optimized for the specified floating point model.
After you do that, you will see that the moves are optimized and AVX2 code is used for moves.
Note that your code will not work on machines that do not support AVX2 anymore. That's the reason the default is rather conservative.
But then again: SSE2 can be specified instead of AVX2 and is both conservative and will speed up moves.
« Last Edit: December 08, 2017, 11:40:46 am by Thaddy »
"Logically, no number of positive outcomes at the level of experimental testing can confirm a scientific theory, but a single counterexample is logically decisive."

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus