Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][aot] Enable direct call transformation where caller requires no initialization #82224

Closed
4 of 5 tasks
Tracked by #80938
kotlarmilos opened this issue Feb 16, 2023 · 4 comments
Closed
4 of 5 tasks
Tracked by #80938
Assignees
Milestone

Comments

@kotlarmilos
Copy link
Member

kotlarmilos commented Feb 16, 2023

Description

Direct call transformation emits a direct call for a patch instead of having a PLT entry. This is possible if a called method is in the same assembly and requires no initialization. In nollvm configuration, when a call is made through a PLT entry, it initializes the got slots used by the method and runs its class cctor if needed. In llvm configuration, methods initialize themselves and they can be called at any time.

The idea is to change nollvm methods to init themselves without a PLT entry. Method entry point should invoke class constructor and initialize all GOT entries used.

Tasks

@kotlarmilos kotlarmilos added this to the Future milestone Feb 16, 2023
@kotlarmilos kotlarmilos self-assigned this Feb 16, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Feb 27, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Mar 2, 2023
@kotlarmilos kotlarmilos changed the title [mono][aot] Enable direct call transformation where callee requires no initialization [mono][aot] Enable direct call transformation where caller requires no initialization Mar 2, 2023
@kotlarmilos
Copy link
Member Author

In llvm, there is mono_inited struct that indicates if a method is inited. Here is a llvm method prolog for initialization:

; Function Attrs: noinline uwtable
define hidden monocc void @HelloWorld_Program_Main_string__(i64* %arg_args) #2 gc "coreclr" !dbg !13 {
BB0:
  br label %INIT_BB1, !dbg !17

INIT_BB1:                                         ; preds = %BB0
  %is_inited = load i8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @mono_inited, i32 0, i32 0), align 1, !dbg !17
  %0 = call i8 @llvm.expect.i8(i8 %is_inited, i8 1), !dbg !17
  %1 = icmp eq i8 %0, 0, !dbg !17
  br i1 %1, label %NOTINITED_BB15, label %INITED_BB2, !dbg !17

...

NOTINITED_BB15:                                   ; preds = %INIT_BB1
  call void @mono_aot_HelloWorld_init_method(i64* bitcast ([11 x i8]* @info_HelloWorld_Program_Main_string__ to i64*)), !dbg !17
  store i8 1, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @mono_inited, i32 0, i32 0), align 1, !dbg !17
  br label %INITED_BB2, !dbg !17
}

NOTINITED_BB15 bblock invokes mono_aot_HelloWorld_init_method that uses mini_llvm_init_method runtime method to invoke .cctr and init GOT slots:

define hidden void @mono_aot_HelloWorld_init_method(i64* %0) #1 {
ENTRY:
  %1 = bitcast i64* %0 to i32*
  %2 = getelementptr i32, i32* %1, i32 0
  %method_index = load i32, i32* %2, align 4
  %3 = getelementptr [0 x i8], [0 x i8]* bitcast ([7 x i8]* @mono_inited to [0 x i8]*), i32 0, i32 %method_index
  %is_inited = load i8, i8* %3, align 1
  %4 = icmp eq i8 %is_inited, 0
  br i1 %4, label %NOT_INITED, label %INITED

INITED:                                           ; preds = %NOT_INITED, %ENTRY
  ret void

NOT_INITED:                                       ; preds = %ENTRY
  %5 = load i64*, i64** @aotconst_aot_module, align 8, !invariant.load !17
  %6 = ptrtoint i64* %5 to i64
  %7 = load void (i64, i64, i64*, i64)*, void (i64, i64, i64*, i64)** @aotconst_jit_icall_mini_llvm_init_method, align 8, !invariant.load !17
  call void %7(i64 ptrtoint (%MonoAotFileInfo* @mono_aot_file_info to i64), i64 %6, i64* %0, i64 0)
  %8 = getelementptr [0 x i8], [0 x i8]* bitcast ([7 x i8]* @mono_inited to [0 x i8]*), i32 0, i32 %method_index
  store i8 1, i8* %8, align 1
  br label %INITED
}

The same approach should be considered for nollvm methods.

/cc: @LeVladIonescu

@vargaz
Copy link
Contributor

vargaz commented Jul 14, 2023

I think these are all 9.0 issues.

@kotlarmilos
Copy link
Member Author

@LeVladIonescu @vargaz Can we try to get the implementation merged without the optimizations enabled within .NET 8 time frame?

We can move the following issues to .NET 9:

/cc: @SamMonoRT

@kotlarmilos
Copy link
Member Author

The impact is not significant enough / high effort.

@github-actions github-actions bot locked and limited conversation to collaborators Sep 9, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants