Skip to content

Optimize FlatExpression node layout and child reuse semantics - #540

Closed
dadhi with Copilot wants to merge 5 commits into
masterfrom
copilot/optimize-flat-expression-representation-yet-again
Closed

dadhi with Copilot wants to merge 5 commits into
masterfrom
copilot/optimize-flat-expression-representation-yet-again

Conversation

Copilot AI commented Apr 29, 2026 •

Copy link
Copy Markdown
Contributor

FlatExpression was still paying unnecessary space and construction costs: constants used an 8-byte in-place payload, child links only modeled sibling chains, and repeatedly used nodes were eagerly cloned instead of being reused until aliasing actually occurred. This change tightens the node layout and shifts reuse/linking behavior toward first-use ownership plus explicit reference nodes on subsequent reuse.

  • ExprNode layout

    • split the old 8-byte payload into:
      • uint _data for inline constant payload or ChildIdx/ChildCount
      • uint _meta for NodeType, flags, and encoded NextIdx
    • kept ExprNode at 24 bytes while restoring direct NextIdx + NodeType storage
    • encoded NextIdx with a non-zero sentinel so index 0 remains valid
  • Constant representation

    • inline small 4-byte constants directly in node storage
      • bool, char, byte/sbyte, short/ushort, int/uint, float, and enums with those underlying sizes
    • leave larger values (for example long) boxed/out-of-line
    • retain closure-backed storage for non-inline object constants
  • Child linking / reference model

    • stop cloning nodes on first link
    • first parent sets the node’s NextIdx
    • subsequent parents get a lightweight reference node whose ChildIdx points to the declaration node
    • last child in a chain now points back to the owning parent, enabling upward traversal
  • Identity preservation

    • parameter and label flattening now reuses the original declaration node and emits reference nodes only when reused
    • reader resolves reference nodes transparently, preserving parameter/label identity on roundtrip
  • Coverage

    • added focused assertions for:
      • inline constant packing
      • reference-node creation on child reuse
      • semantic equivalence of reused-parameter expressions after roundtrip

Example of the new reuse behavior:

var fe = default(ExprTree);
var p = fe.Parameter(typeof(int), "p");
var sum = fe.Add(p, p); // first use keeps p, second use becomes a ref node
fe.RootIndex = fe.Lambda<Func<int, int>>(sum, p);

This keeps the original declaration node as the primary representation and only materializes an extra node when reuse requires alias-safe linking.

Copilot AI linked an issue Apr 29, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Optimize FlatExpression representation Optimize FlatExpression node layout and child reuse semantics Apr 29, 2026
Copilot AI requested a review from dadhi April 29, 2026 06:17

@dadhi dadhi left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ci Error: /home/runner/work/FastExpressionCompiler/FastExpressionCompiler/src/FastExpressionCompiler.LightExpression/FlatExpression.cs(1284,16): error CS0103: The name 'Unsafe' does not exist in the current context [/home/runner/work/FastExpressionCompiler/FastExpressionCompiler/src/FastExpressionCompiler.LightExpression/FastExpressionCompiler.LightExpression.csproj::TargetFramework=netstandard2.0]

Copilot AI commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

Ci Error: /home/runner/work/FastExpressionCompiler/FastExpressionCompiler/src/FastExpressionCompiler.LightExpression/FlatExpression.cs(1284,16): error CS0103: The name 'Unsafe' does not exist in the c...

Fixed in d4888d2 by replacing the Unsafe float bit-casts with an explicit-layout uint/float helper that builds on netstandard2.0. I also verified the library builds for netstandard2.0 and net8.0 and re-ran the LightExpression test harness successfully.

Copilot AI requested a review from dadhi April 29, 2026 06:32
@dadhi

dadhi commented Apr 29, 2026

Copy link
Copy Markdown
Owner

bs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants