Jump to content

Search the Community

Showing results for tags 'inlining'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Delphi Questions and Answers
    • Algorithms, Data Structures and Class Design
    • VCL
    • FMX
    • RTL and Delphi Object Pascal
    • Databases
    • Network, Cloud and Web
    • Windows API
    • Cross-platform
    • Delphi IDE and APIs
    • General Help
  • Delphi General Discussions
    • Tips / Blogs / Tutorials / Videos
    • Delphi Third-Party
    • Job Opportunities / Coder for Hire
    • I made this
  • Software Development
    • Project Planning and -Management
    • Software Testing and Quality Assurance
  • Community
    • Community Management

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Delphi-Version

Found 1 result

  1. I have the following code (Delphi Berlin): interface type TSliver = record public private case integer of 8: (Data8: int64); end; TSlice = record private FData: array [0..63] of byte; end; TSliverHelper = record helper for TSliver class function NS(const North, South: TSlice; out Changed: TSliverChanges): TSliver; static; inline; end; {$L 'C:\mydir\AVXGenerate.o'} //imported assembly generated by lazarus. procedure AVXGENERATE_TSLIVERHELPER_NS; external name 'AVXGENERATE_$$_TSLIVERHELPER_NS'; //no parameters for simplicity. implementation class function TSliverHelper.NS(const North, South: TSlice; out Changed: TSliverChanges): TSliver; {inline;} //RCX =North: PSlice //RDX =South: PSlice //R8 = Changed: PSliverChanges ((scUnchanged=0, scChanged=1, scInvalid=3)); //RAX = Result: TSliver (as Int64) begin AVXGENERATE_TSLIVERHELPER_NS; end; //asm // jmp AVXGENERATE_TSLIVERHELPER_NS; //end; The asm method works correctly, the inlined method does not. If we look at the generated code it's easy to see why this happens. a:= TSliver.NSTest(N,S,statusA); //a = -1 UnitTests.pas.877: b:= TSliver.NS(N,S, statusB); 00000000009A77CE 488D8C2480000000 lea rcx,[rsp+$0080] 00000000009A77D6 488D542440 lea rdx,[rsp+$40] 00000000009A77DB 4C8D44242E lea r8,[rsp+$2e] 00000000009A77E0 E82B5E0100 call TSliverHelper.NS 00000000009A77E5 4889442430 mov [rsp+$30],rax //b = 7 why? //Let's see what's happening in the inlined method. class function TSliverHelper.NS(const [ref] N,S: TBigRec; out status: TEnumRec): UInt64_Rec; Unit2.pas.4360: begin 00000000009BD610 55 push rbp 00000000009BD611 4883EC30 sub rsp,$30 00000000009BD615 488BEC mov rbp,rsp Unit2.pas.4361: AVXGENERATE_TSLIVERHELPER_NS; 00000000009BD618 E833350000 call AVXGENERATE_TSLIVERHELPER_NS //external asm procedure with no declared params. Unit2.pas.4362: end; //At this point RAX = result = -1, all OK 00000000009BD61D 488B4528 mov rax,[rbp+$28] //Oops, RAX gets overwritten, why? <<<<??????????????????????? 00000000009BD621 488D6530 lea rsp,[rbp+$30] 00000000009BD625 5D pop rbp 00000000009BD626 C3 ret Why does the compiler insert an assignment to RAX? I have not instructed it to do anything of the sort. Compiling this code also does not issue a warning that Result might be unassigned. Why does the compiler do this? (I know I can fix this by declaring the external proc as a function, but that's beside the point). EDIT When we redefine the external proc as a function and change the inline method as shown below, correct code gets generated. It also gives some insight what is going on: Unit2.pas.4360: begin 00000000009BD610 55 push rbp 00000000009BD611 4883EC30 sub rsp,$30 00000000009BD615 488BEC mov rbp,rsp Unit2.pas.4361: Result:= AVXGENERATE_TSLIVERHELPER_NS; 00000000009BD618 E833350000 call AVXGENERATE_TSLIVERHELPER_NS 00000000009BD61D 48894528 mov [rbp+$28],rax //pointless stack trashing Unit2.pas.4362: end; 00000000009BD621 488B4528 mov rax,[rbp+$28] //the exit code expects Result to be in the stackframe. 00000000009BD625 488D6530 lea rsp,[rbp+$30] 00000000009BD629 5D pop rbp 00000000009BD62A C3 ret The compiler is just copy pasting its exit code, regardless of the actual code in the body. Note that I've compiled the code with no stackframes
×