Replies: 1 comment
-
Application of Indexed Labels to Lightweight GenericsI just discovered the Indexed Labels in FPC Unleashed. In the Witness-Based Generics proposal above, indexed labels could be a dream for the compiler. If you have a shared implementation of a generic list, the compiler might need to handle "Special Cases" for different power-of-two sizes. Instead of bloat, it uses one shared function with an indexed label: procedure SharedGenericAdd(const Witness: PWitnessTable);
label
HandleSize[1, 2, 4, 8];
begin
{ The compiler can jump to the optimal MOV instruction based on size }
goto HandleSize[Witness.TypeSize];
HandleSize[4]:
{ Perform 32-bit optimized copy }
exit;
HandleSize[8]:
{ Perform 64-bit optimized copy }
end; |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
DISCUSSION/PROPOSAL TO FIX GENERICS
The current Generics implementation in Free Pascal (FPC) utilizes a "Template Expansion" model. While providing high performance for specific types, it results in substantial binary bloat and prolonged compilation times due to code duplication. I am asking for the consideration of a Witness-Based Lightweight Generics (WLG) system. By utilizing implicit dictionary passing (Witness Tables), the compiler could generate a single binary implementation for generic procedures, using
specializeonly as a metadata-binding instruction rather than a code-generation trigger.1. The Technical Philosophy
specialize: The keyword is retained to maintain one-pass compilation efficiency and explicit type safety, but its backend behavior is transformed from "Copy-Paste" to "Link-and-Bind."2. The Architecture
2.1 The Witness Table (Internal)
The compiler implicitly defines a structure for every
Tinvolved in a specialization.2.2 Polymorphic Implementation
The body of a generic function is compiled into a "Railed" version. Instead of knowing type
T, the machine code utilizes thePWitnessTableto manipulate memory.3. An Example
3.1 Generic Definition
The definition remains standard Pascal, ensuring no declarations exist within the function parameters.
3.2 Specialization Site
The
specializekeyword now acts as a linker directive.Compiler Action:
Integer.Byte.IntList.AddandByteList.Addto the same memory address of the shared implementation.4. Formal Considerations and Rules
Why: Generics rely on Type Identity. If the compiler allows inline type declarations in the parameter list of a generic specialization, it becomes nearly impossible to verify if two specializations are identical.
Why: In Pascal, a
constis often treated as a "true" constant (substituted at compile time). If a constant within a generic is allowed to be defined by a variable or a non-static result, it becomes a "read-only variable."var Tis unknown at compile time. Allowing for inline variables likevar x: T := ...halfway through a block, forces the compiler to perform "dynamic stack adjustment" or "deferred stack allocation." This does not make compilation impossible, but adds complexity. This is just a note for consideration.5. Verification (FPCUnit)
To prove effectiveness, the following test suite should verify that different specializations maintain data integrity while sharing logic.
6. Recovery of Legacy Performance
To ensure no performance regression for critical paths (e.g., high-performance math), I propose an attribute to opt-out of sharing:
7. Summary of Benefits
specialize.specializesyntax, providing a bridge for existing code bases while fixing the underlying "bloat" bug.Beta Was this translation helpful? Give feedback.
All reactions