Skip to content

IPA: Encapsulate module-level globals into IPA_Context struct#58

Open
noafroboy wants to merge 10 commits intoopen64-compiler:developfrom
noafroboy:refactor/ipa-context
Open

IPA: Encapsulate module-level globals into IPA_Context struct#58
noafroboy wants to merge 10 commits intoopen64-compiler:developfrom
noafroboy:refactor/ipa-context

Conversation

@noafroboy
Copy link
Copy Markdown
Contributor

Summary

Introduces IPA_Context, a master struct that encapsulates ~60 IPA module-level globals and ~140 config_ipa.h option globals into explicit, grouped state. This is the foundation for threading context through IPA passes instead of relying on mutable global state.

What this PR does

  • Adds three new files: ipa_context.h (context + sub-structs), ipa_options.h (options snapshot struct), ipa_context.cxx (lifecycle functions)
  • Replaces extern declarations across 20+ existing headers with #define macros redirecting to g_ipa_ctx->subsystem.field
  • Removes the corresponding global variable definitions from .cxx files
  • Wires up IPA_Context_Init/IPA_Context_Alloc at IPA entry points so the migrated macros work at runtime
  • Zero behavior change: the struct fields are zero-initialized (matching prior global defaults) and accessed via backward-compatible macros

Globals migrated (by subsystem)

Subsystem Globals Source header
Feedback FDs 5 FILE* pointers ipa_feedback.h
Struct optimization 6 globals ipa_struct_opt.h
Visualization cg_display ipc_daVinci.h
Array sections pool + trace flag ipa_section_prop.h
Field reordering 3 globals ipa_reorder.h
Class hierarchy CHG + PCG pointers ipa_chg.h, ipa_pcg.h
Common blocks table + pad count ipa_pad.h
Inline stats 13 counters/freqs ipa_inline.h, ipa_cg.h
Const propagation 3 pools + 3 counters ipa_cprop.h
Symbol merge 5 tables/maps ipc_symtab_merge.h
Call graph graph ptr + built flag ipa_cg.h
Options ~140 config_ipa.h globals config_ipa.h

Design decisions

  • void* for non-forward-declarable types: COMMON_SNODE_TBL (typedef of template), AUX_ST_TAB, etc. use void* with cast macros to avoid pulling heavy headers into ipa_context.h
  • IPA_CONTEXT_FULL_INIT guard: Options snapshot uses config_ipa.h globals only available in the main IPA target; inline and lw_inline targets use lightweight IPA_Context_Alloc only
  • Deferred migrations: IP_File_header (static-constructor pattern in init.cxx), file-static globals (steps 9-10), function parameter threading (steps 18-19)

Commits (intended for commit-by-commit review)

  • Add IPA context structs for global state encapsulation (60f8100)
  • Migrate feedback FD globals to IPA_Context (c90150c)
  • Migrate struct-opt globals to IPA_Context (3c75f4b)
  • Migrate visualization, array-section, reorder, and CHG globals (2c2ab4c)
  • Migrate common-block globals to IPA_Context (cfb9cfa)
  • Migrate inline stats and cprop globals to IPA_Context (b73dab6)
  • Rename IPA_Options fields to begin with lowercase (fca94d8)
  • Migrate merge state globals to IPA_Context (ea4d232)
  • Migrate call-graph and options-inconsistent globals to IPA_Context (05b85a5)
  • Add IPA_Context lifecycle calls at main entry points (a5ff24d)

Test plan

  • Full Docker build passes (make build + make lib) — all 3 IPA-family targets compile: ipa.so, lw_inline, opencc
  • No new compiler warnings in IPA source files
  • git diff origin/develop...HEAD shows only IPA files touched (32 files, +893 -126)
  • Reviewer verifies each #define macro matches the original extern type and semantics

🤖 Generated with Claude Code

noafroboy and others added 10 commits March 3, 2026 07:14
Add three new files that define IPA_Options and IPA_Context structs,
which will eventually replace the ~140 config_ipa.h globals and ~60
IPA module-level globals. This is the foundation for threading explicit
context through IPA passes instead of relying on mutable global state.

New files:
- ipa_options.h: IPA_Options struct mirroring all config_ipa.h externs
- ipa_context.h: IPA_Context struct with sub-structs for each subsystem
- ipa_context.cxx: Init/Fini functions (defined but never called yet)

No existing code is modified. The new code compiles but has zero
behavior change — the init/fini functions exist but nothing calls them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the 5 extern FILE* declarations in ipa_feedback.h with macros
that redirect to g_ipa_ctx->feedback.* fields. All usages of these
variables are inside #ifdef TODO blocks (dead code), so this has zero
runtime impact.

Also fix SEGMENTED_ARRAY template parameter type in ipa_context.h
(UINT, not INT32) to match the canonical definition in segmented_array.h.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 6 extern globals in ipa_struct_opt.h with #define macros
pointing to g_ipa_ctx->struct_opt.*:
- Struct_field_layout, Struct_split_count
- complete_struct_relayout_type_id and related arrays
- num_structs_with_field_pointing_to_complete_struct_relayout

Fix Field_pos forward declaration: use typedef of struct Field_pos_
since the original uses C-style typedef (not a struct tag).

Remove variable definitions from ipa_struct_opt.cxx; zero-init via
memset in IPA_Context_Init() provides equivalent defaults.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Step 4: cg_display → g_ipa_ctx->visualization.cg_display
Step 5: IPA_array_prop_pool, Trace_IPA_Sections → g_ipa_ctx->array_section.*
Step 6: merged_access, reorder_local_pool, reorder_candidate → g_ipa_ctx->reorder.*
  - reorder_candidate uses pointer indirection (*candidate_ptr) since
    REORDER_CAND can't be forward-declared by value in ipa_context.h
Step 7: IPA_Class_Hierarchy, IPA_Concurrency_Graph → g_ipa_ctx->chg.*

Also fix COMMON_SNODE_TBL forward declaration: it's a typedef of
HASH_TABLE<...>, not a class — use void* placeholder until step 8.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace IPO_Pad_Count and IPA_Common_Table externs in ipa_pad.h with
#define macros to g_ipa_ctx->common.*

IPA_Common_Table uses void* in the context struct (COMMON_SNODE_TBL is
a typedef, not forward-declarable) with lvalue-safe pointer cast:
  *(COMMON_SNODE_TBL**)&(g_ipa_ctx->common.common_table)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Step 11: Migrate inline statistics across ipa_inline.h and ipa_cg.h:
- Total_Prog_Size, Total_Inlined, Total_Not_Inlined
- Orig_Prog_Weight, Total_Dead_Function_Weight
- Orig_Prog_WN_Count, Prog_WN_Count, Total_Dead_Function_WN_Count
- Total_call_freq, Total_cycle_count, Total_cycle_count_2
- Total_Must_Inlined, Total_Must_Not_Inlined
- IPA_Graph_Undirected → g_ipa_ctx->graph_undirected

Step 12: Migrate cprop state from ipa_cprop.h:
- Ipa_cprop_pool, local_cprop_pool, Global_mem_pool
- IPA_Constant_Count, IPA_Max_Total_Clones, IPA_Num_Total_Clones

Add ipa_context.cxx to inline and lw_inline Makefiles so g_ipa_ctx
symbol is available. Guard IPA_Options_Init with IPA_CONTEXT_FULL_INIT
(defined only in main IPA target) since inline/lw_inline don't link
config_ipa.cxx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review feedback: all member fields in struct definitions
should begin with a lowercase character.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move the five extern globals from ipc_symtab_merge.h into IPA_Merge_State:
Aux_St_Tab, Aux_St_Table, Aux_Pu_Table, ST_To_INITO_Map, and
Common_Block_Elements_Map.  Each is stored as a void* pointer in the
context struct with a backward-compatible #define macro.

Value-type globals (Aux_St_Tab, Aux_St_Table, Aux_Pu_Table,
ST_To_INITO_Map) become file-static in ipc_symtab_merge.cxx with
pointers wired up in Initialize_Auxiliary_Tables().  The pointer global
Common_Block_Elements_Map uses the same (*(TYPE**)&field) pattern as
IPA_Common_Table.

The Aux_Pu_Table macro is guarded for _LIGHTWEIGHT_INLINER which
defines its own local copy in inline.cxx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the extern declarations for IPA_Call_Graph, IPA_Call_Graph_Built,
and Opt_Options_Inconsistent in ipa_cg.h with #define macros that access
the corresponding fields already present in IPA_Context since Step 1.

Remove the global definitions from ipa_cg.cxx — the context struct
fields (zero-initialized by IPA_Context_Init) provide equivalent storage.

IP_File_header migration is deferred: it has a static-constructor
initialization pattern in init.cxx that takes its address before
g_ipa_ctx is available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add IPA_Context_Alloc/Free as lightweight lifecycle functions available
in all IPA-family targets (ipa, inline, lw_inline).  Refactor
IPA_Context_Init to call IPA_Context_Alloc before snapshotting options.

Wire up the calls:
- ipa_dot_so_init(): IPA_Context_Alloc() before Initialize_Auxiliary_Tables
- ipa_driver(): IPA_Context_Init() after Process_IPA_Options (snapshots
  config_ipa.h globals with their final command-line values)
- Inliner(): IPA_Context_Alloc() before Initialize_Symbol_Tables

This makes all previously migrated context-based macros work at runtime.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant