-
Notifications
You must be signed in to change notification settings - Fork 123
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
Thunks: Add new pointer annotations to assist data layout analysis #3177
Thunks: Add new pointer annotations to assist data layout analysis #3177
Conversation
ThunkLibs/Generator/analysis.cpp
Outdated
@@ -184,9 +221,14 @@ void AnalysisAction::ParseInterface(clang::ASTContext& context) { | |||
type = type->getLocallyUnqualifiedSingleStepDesugaredType(); | |||
|
|||
if (type->isFunctionPointerType() || type->isFunctionType()) { | |||
funcptr_types.insert(type.getTypePtr()); | |||
funcptr_types["TODO_FUNC_NAME_FOR_ANNOTATED_TYPES_" + type.getAsString()] = std::pair { type.getTypePtr(), no_param_annotations }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revisit this. Adding a fixed prefix hasn't caused any problems so far, but to be on the safe side it may indeed be needed to add the full function name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually this is safe, since the type name for a function pointer type will never conflict with a function name.
We already compile both FEXCore and FEX's frontend as C++20, no reason for thunks to require anything older. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable to me with a first pass.
7660033
to
8b5d111
Compare
This reflects its purpose slightly better, particularly since future patches will add more information to this object.
Previously, two functions with the same signature would always be wrapped in the same logic. This change allows customizing one function with annotations while leaving the other one unchanged.
…back arguments This will be used later to aid automatic struct repacking.
This annotation can be used for data types that can't be repacked automatically even with custom repack annotations. With ptr_passthrough, the types are wrapped in guest_layout and passed to the host like that.
These annotations allow for a given type or parameter to be treated as "compatible" even if data layout analysis can't infer this automatically. assume_compatible_data_layout is more powerful than is_opaque, since it allows for structs containing members of a certain type to be automatically inferred as "compatible". Conversely however, is_opaque enforces that the underlying data is never accessed directly, since non-pointer uses of the type would still be detected as "incompatible".
8b5d111
to
cb215b5
Compare
Overview
This PR adds a number of annotations related to pointer struct members and pointer function parameters. This allows the data layout analysis framework added in #3156 to operate on a wider range of thunked APIs.
The initial version of the data layout analysis framework is limited to "simple" structures. "Simple" means that pointer members are only supported if they pointee-type was inferred to have compatible data layout itself. This excludes a couple of important use cases:
union
types)To handle these use cases, two new types of annotations are added (in contrast to
fex_gen_config
, which describes only functions):fex_gen_param
describes specific parameters within a functionfex_gen_type
describes types, such that the described behavior will be applied to all functions/structs they are used inImplementation
opaque_type
/assume_compatible_data_layout
annotationsThese instruct data analysis to assume the underlying data is compatible across all architectures.
assume_compatible_data_layout
can be used for both pointers and non-pointers, whereasopaque_type
ensures the type is only ever used as a pointer.Importantly, this means
assume_compatible_data_layout
can handle types embedded as non-pointers in structs. This should only be used overopaque_type
if the layout has actually been manually inspected though, of course.opaque_type
is purely a type annotation (since this property shouldn't depend on context), whereasassume_compatible_data_layout
may be used as either a type annotation or a function parameter annotation.Typical use cases are "handle types", union types, and linked list types.
ptr_passthrough
annotationThis function parameter annotation is used to force passing individual function parameters without modification to a custom host implementation (
fexgen::custom_host_impl
) even if the parameter type is known to differ between architectures. A newguest_layout
wrapper template is added to make this behavior explicit: The argument for the host function then changes in type fromT*
toguest_layout<T*>
.For example:
For now,
guest_layout
is a loaded foot gun: It provides no extra guarantees or layout conversion to deal with data layout incompatibilities. A later PR will remedy this. Even now the wrapper adds value though, because we've been using the foot gun all along but we didn't make it explicit.Typical use cases are pointers-to-pointers, function-pointer-parameters. More generally, it allows for complex manual repacking of struct arguments.
Embed annotations into the signature for Vulkan-esque function pointers
Some APIs (prominently
vkGetDeviceProcAddr
orglXGetProcAddr
) return host-function pointers to the guest. The trampolines we insert guest-side to handle this used to be unique per-signature, but additionally they now need to be unique per set-of-annotations.Since this adds up to a lot of information to carry around at compile time, this turns
template<typename Result, typename... Args> void ForIndirectCall(void*);
into this rather heavy code:Impact
Since strict mode (see #3156) is still only enabled for unit tests, impact on real libraries is limited. Functionally there should be no difference, but the generated code will look slightly different for functions using
ptr_passthrough
. Similarly, since Vulkan-esque function pointers now carry around annotation at compile-time, the callback list is slightly different.C++20 is required for the callback change due to the use of non-type template parameters. This version bump could be delayed but other features in my PR queue will also require C++20. If C++17 support is desirable, I propose temporarily requiring C++20 and restoring C++17 support once this PR series is complete.
Future
The next PR after this will add the new annotations to all of our existing thunk libraries. We'll then be able to turn on strict mode for data layout analysis unconditionally.