Recent

Author Topic: Inlining cast managed typed to unmanaged  (Read 372 times)

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Inlining cast managed typed to unmanaged
« on: November 22, 2020, 09:49:59 am »
Can I ask why FPC can not inline the second use, and is there a bug report for that?

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3.   function Test1(A: PChar): PChar; inline;
  4.   begin
  5.     Result := A + 1;
  6.   end;
  7.  
  8. var
  9.   S: String;
  10.   P: PChar;
  11. begin
  12.   S := 'Test';
  13.   P := Pointer(S); //Inlined
  14.   P := Test1(P);
  15.   P := Test1(Pointer(S)); //Not inlined
  16. end.                    

Thaddy

  • Hero Member
  • *****
  • Posts: 10572
Re: Inlining cast managed typed to unmanaged
« Reply #1 on: November 22, 2020, 10:02:48 am »
I think because the parameter is not const, meaning the compiler has to assume that the parameter can be changed, even without var because it is a pointer type:
Code: Pascal  [Select][+][-]
  1.  
  2.   function Test1(const A: PChar): PChar; inline;
  3.   begin
  4.     Result := A + 1;
  5.   end;
Not sure, but now the compiler should have enough information to inline the second call, since the parameter can not be changed.
 
« Last Edit: November 22, 2020, 10:16:19 am by Thaddy »

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Re: Inlining cast managed typed to unmanaged
« Reply #2 on: November 22, 2020, 10:06:17 am »
No, it is not related to that. In the mail list, it is explained by Jonas, but I do not know the reason and if there is a report that I can monitor.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2405
  • Compiler Developer
Re: Inlining cast managed typed to unmanaged
« Reply #3 on: November 22, 2020, 12:41:27 pm »
No, it is not related to that. In the mail list, it is explained by Jonas, but I do not know the reason and if there is a report that I can monitor.

Jonas explicitely mentioned the reason:

Quote
The compiler does not support inlining calls with parameters that cast a
managed type to an unmanaged type at this time.

The compiler simply does not support it. Managed types need to be handled a bit different from plain, simple types and thus special care has to be taken so that their reference counts are still correct so that no memory leak or too soon release follows.

Also I'm not aware of there being a report about this. Feel free to create one, but don't expect it to be fixed soon.

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Re: Inlining cast managed typed to unmanaged
« Reply #4 on: November 22, 2020, 01:02:54 pm »
That is a reason, but not clear to me why?
What is the difference between first putting the pointer into a variant and then passing it and passing it directly?
Both are almost the same to me, and I need a little guidance to understand the two cases' internal differences.

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Re: Inlining cast managed typed to unmanaged
« Reply #5 on: November 22, 2020, 01:06:06 pm »

Thaddy

  • Hero Member
  • *****
  • Posts: 10572
Re: Inlining cast managed typed to unmanaged
« Reply #6 on: November 22, 2020, 03:00:55 pm »
A Pchar is NOT a managed type

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Re: Inlining cast managed typed to unmanaged
« Reply #7 on: November 22, 2020, 03:03:03 pm »
Can I ask why did you assume that I meant PChar is managed?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6708
  • Debugger - SynEdit - and more
    • wiki
Re: Inlining cast managed typed to unmanaged
« Reply #8 on: November 22, 2020, 03:22:58 pm »
That is a reason, but not clear to me why?
What is the difference between first putting the pointer into a variant and then passing it and passing it directly?
Both are almost the same to me, and I need a little guidance to understand the two cases' internal differences.

I guess in this case, it may be a wrong guess by the compiler. (Only guessing).

Code: Pascal  [Select][+][-]
  1. procedure Foo(a: string); inline; begin end;
  2. ///....
  3. foo(SomeString);
There a string (a managed type) is passed. Befere SomeString is passed, the compiler needs to call inc_ref for the string. And then afterwards decref.
Apparently none of the compiler devs has ever written the code to generate the incref/decref in case of inlining.

So then I guess in your case, the compiler sees the string in the argument list and says: not possible.
Even so, you do not actually pass a string. The compiler probably just incorrectly detects it something it can not do.

--
PChar is not managed.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8894
  • FPC developer.
Re: Inlining cast managed typed to unmanaged
« Reply #9 on: November 22, 2020, 04:36:52 pm »
Normal the semantics of a procedure call means that the managed variable must be kept till after the procedure call.

If you inline a procedure call with N statements, you must somehow change that so that the compiler keeps the managed variable around till after the block of N inlined statements, and the optimization is not allowed to alter that after. It might be that the internal structures for that simply are not there.

OkobaPatino

  • Full Member
  • ***
  • Posts: 165
Re: Inlining cast managed typed to unmanaged
« Reply #10 on: November 22, 2020, 04:41:13 pm »
Thank you very much to you both. Now I have a better understanding about the case, and I hope this issue will be fixed sooner as it help to have clean and optimized code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2405
  • Compiler Developer
Re: Inlining cast managed typed to unmanaged
« Reply #11 on: November 22, 2020, 06:05:50 pm »
A Pchar is NOT a managed type

It's about converting a managed type (here AnsiString) to a simple type (here Pointer (PChar wouldn't change much except for an additional check for an empty string)) inside the parameter list of a routine.

 

TinyPortal © 2005-2018