Skip to content

Improve binary size of generated code #908

Closed
@treiher

Description

@treiher

Potential improvements:

  • Enable pragma Restrictions (No_Exceptions)
  • Enable pragma Restrictions (No_Secondary_Stack)

The code size will be calculated by the size of the .text section of the generated binary minus the size of the .text section of a reference binary that is built from an empty main procedure.

Important compiler switches:

  • -ffunction-sections, -fdata-sections, -Wl,-gc-sections
  • -Os
  • -gnatp
  • -fno-inline / -gnatd.8 (for GNAT 22.1, not needed for 23.0w)
  • -fno-early-inlining

Improvements in the code generator:

  • Group case statements with identical branches into a single case

  • Group if-else statements with identical branches into a single expression

  • Replace case statements that use exceptions with assertions (at least if many/all branches are equal)

  • Replace case statements that generate boolean values with single boolean expressions

  • Rewrite case statements in expression functions that return case based enum values as regular functions with single returns

  • Remove code duplications in RFLX_Generic_Types (merge Insert functions)

(Part 1)

  • Remove exceptions and enforce pragma Restrictions (No_Exceptions)
  • Inline Set_Field_Value_* into Set_*
  • Simplify Incomplete_Message and Initialized by using quantified expressions (no effect on binary size, but maybe positive effect on proof time)
  • Simplify Valid_Length
  • Simplify Path_Condition
  • Improve Field_Size
  • Split first part of Set_* functions
  • Defer dereferencing of buffer pointers for Extract and Insert
  • Simplify Composite_Field

(Part 2)

  • Remove duplicated finalization code for session states

(Part 3)

  • Use common integer type (e.g., U64) in context for representing field values to prevent need for variant records (i.e. Field_Dependent_Value) and therefore case statements

(Part 4)

(Part 5)

  • Move Has_Buffer of Verify into precondition

(Part 6)

  • Replace RFLX_Exception variable with gotos. Currently this variable is used to stay inside a block and call Update on the buffer at the end of that block before jumping via the goto. However it seems to be more size efficient to call the Update and jump directly.
  • Replace the pattern Available_Field (Ctx, Field) >= Field_Size (Ctx, Field) with separate function.

(Part 7)

  • Some scalar fields that do not affect the path through the message (e.g. long lists of flags) should be settable with less checks.
    • For message aggregates:
      • Check Available_Space once (Message.size must consider message path)
      • Do not check Valid_Next

(Ideas for messages)

(Ideas for sessions)

(Rejected ideas)

  • Add Inline_Always to RFLX.RFLX_Generic_Types.(Insert|Insert_LE|Extract|Extract_LE) (no effect when using 23.0w)
  • Split Get_Field_Value, Set_Field_Value and Verify into separate functions (negative impact for Get_Field_Value and Verify)
  • Refactor Successor and Valid_Predecessor (negative impact)
  • Remove duplication in Valid, Invalid and Incomplete for fields and cursors (slight negative impact on binary size)
  • Remove duplications in Field_Condition, Path_Condition and (Structural_|)Valid_Message by adding Link_Condition function (no impact on binary size)
  • Add precalculation of Val.Fld to Set

Metadata

Metadata

Assignees

Labels

generatorRelated to generator package (SPARK code generation)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions