mirror of
https://github.com/jessicanataliagta/PSPRecomp
synced 2026-09-26 08:41:08 -04:00
otimizações round 12
otimizações round 12
This commit is contained in:
@@ -311,12 +311,12 @@ public:
|
||||
return run_starvation_boundary(ctx);
|
||||
}
|
||||
|
||||
// Tier-2 hot-leaf lowering keeps the scheduler accounting that an ordinary
|
||||
// cross-unit generated call would have performed, while allowing trivial
|
||||
// leaf accessors to be emitted directly in their measured caller. No HLE
|
||||
// or PSP ownership switch can occur inside those leaf bodies, so only the
|
||||
// starvation safe-point cadence needs to be preserved here.
|
||||
[[nodiscard]] PSPRECOMP_RUNTIME_FORCEINLINE bool account_inlined_generated_leaf(
|
||||
// Account one logical outer generated dispatch that was deliberately
|
||||
// removed by a profile-guided superblock. Publishing the destination PC
|
||||
// before calling this helper is mandatory: a starvation boundary may switch
|
||||
// PSP ownership at exactly the same point where the unfused outer dispatcher
|
||||
// used to run.
|
||||
[[nodiscard]] PSPRECOMP_RUNTIME_FORCEINLINE bool account_inlined_dispatch_boundary(
|
||||
AllegrexContext &ctx) {
|
||||
const std::uint64_t starvation_interval = g_runtime_starvation_interval_fast;
|
||||
if (starvation_interval == 0u) return true;
|
||||
@@ -324,6 +324,14 @@ public:
|
||||
return run_starvation_boundary(ctx);
|
||||
}
|
||||
|
||||
// Tier-2 hot-leaf lowering keeps the scheduler accounting that an ordinary
|
||||
// cross-unit generated call would have performed, while allowing trivial
|
||||
// leaf accessors to be emitted directly in their measured caller.
|
||||
[[nodiscard]] PSPRECOMP_RUNTIME_FORCEINLINE bool account_inlined_generated_leaf(
|
||||
AllegrexContext &ctx) {
|
||||
return account_inlined_dispatch_boundary(ctx);
|
||||
}
|
||||
|
||||
// Tier-2 profile-guided superblocks can fuse a cross-unit edge into a local
|
||||
// C++ goto. The guest-visible control flow is unchanged, but the ordinary
|
||||
// invoke_chained_direct() native frame no longer exists. These helpers keep
|
||||
|
||||
@@ -167,6 +167,7 @@ set(VCS_TIER2_CLUSTER_SOURCES
|
||||
host/vcs_tier2_cluster_physics.cpp
|
||||
host/vcs_tier2_cluster_world.cpp
|
||||
host/vcs_tier2_cluster_edge43.cpp
|
||||
host/vcs_tier2_cluster_collisionloop.cpp
|
||||
)
|
||||
if(MSVC)
|
||||
set_source_files_properties(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "psprecomp/runtime.hpp"
|
||||
#include "generated_units.hpp"
|
||||
#include "vcs_tier2_superblocks.hpp"
|
||||
#include <bit>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
@@ -8398,6 +8399,12 @@ L_0889BF84:
|
||||
ctx.fpr[24] = std::bit_cast<float>(ctx.gpr[4]);
|
||||
goto L_0889BFC0;
|
||||
L_0889BFC0:
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_BEGIN
|
||||
if (vcs::tier2_cluster_enabled(vcs::Tier2ClusterId::CollisionLoop) && rt.memory().direct_fastmem_enabled()) {
|
||||
vcs::tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889BFC0u);
|
||||
return;
|
||||
}
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_END
|
||||
ctx.gpr[18] = (aot_mem.aot_load32(ctx.gpr[30] + static_cast<std::uint32_t>(0)));
|
||||
ctx.gpr[30] = (aot_mem.aot_load32(ctx.gpr[30] + static_cast<std::uint32_t>(8)));
|
||||
ctx.gpr[4] = (aot_mem.aot_load16(ctx.gpr[18] + static_cast<std::uint32_t>(84)));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "psprecomp/runtime.hpp"
|
||||
#include "generated_units.hpp"
|
||||
#include "vcs_tier2_superblocks.hpp"
|
||||
#include <bit>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
@@ -1025,6 +1026,12 @@ LOCAL_DISPATCH:
|
||||
}
|
||||
}
|
||||
L_0889C000:
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_BEGIN
|
||||
if (vcs::tier2_cluster_enabled(vcs::Tier2ClusterId::CollisionLoop) && rt.memory().direct_fastmem_enabled()) {
|
||||
vcs::tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889C000u);
|
||||
return;
|
||||
}
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_END
|
||||
{ const bool branch_taken = ctx.gpr[4] == 0u;
|
||||
// nop
|
||||
if (branch_taken) {
|
||||
@@ -1912,6 +1919,12 @@ L_0889C5B0:
|
||||
aot_mem.aot_store32(ctx.gpr[4] + static_cast<std::uint32_t>(0), ctx.gpr[18]);
|
||||
goto L_0889C5B8;
|
||||
L_0889C5B8:
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_BEGIN
|
||||
if (vcs::tier2_cluster_enabled(vcs::Tier2ClusterId::CollisionLoop) && rt.memory().direct_fastmem_enabled()) {
|
||||
vcs::tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889C5B8u);
|
||||
return;
|
||||
}
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_END
|
||||
{ const bool branch_taken = ctx.gpr[30] != 0u;
|
||||
// nop
|
||||
if (branch_taken) {
|
||||
|
||||
@@ -9533,6 +9533,12 @@ L_088B3FCC:
|
||||
ctx.gpr[4] = (ctx.gpr[20] | 0u);
|
||||
goto L_088B1780;
|
||||
L_088B3FFC:
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_BEGIN
|
||||
if (vcs::tier2_cluster_enabled(vcs::Tier2ClusterId::Edge43) && rt.memory().direct_fastmem_enabled()) {
|
||||
vcs::tier2_superblock_edge43(rt, ctx, aot_mem, 0x088B3FFCu);
|
||||
return;
|
||||
}
|
||||
// TIER2_SUPERBLOCK_V2_HOOK_END
|
||||
if (ctx.gpr[2] == 0u) {
|
||||
ctx.gpr[4] = (aot_mem.aot_load32(ctx.gpr[29] + static_cast<std::uint32_t>(48)));
|
||||
(void)rt.invoke_chained_direct<&recomp_unit_0044_entry, 44u, 9u, 0x088B40F8u>(ctx, &aot_mem); return;
|
||||
|
||||
@@ -65,7 +65,7 @@ void runtime_log_initialize(const VcsConfiguration &configuration) {
|
||||
return;
|
||||
}
|
||||
s.file << "VCSNative runtime log\n";
|
||||
s.file << "stage=correctness-v8.2.7a-internal-save-repro-gate-2026-08-18\n";
|
||||
s.file << "stage=perf-v8.3-cpu-boundary-fusion-2026-08-18\n";
|
||||
s.file << "config=" << configuration.source_path.string() << '\n';
|
||||
s.file << "started=" << timestamp_now() << '\n';
|
||||
s.file << "perf_telemetry=" << (configuration.diagnostics.perf_telemetry ? 1 : 0)
|
||||
@@ -81,16 +81,16 @@ void runtime_log_initialize(const VcsConfiguration &configuration) {
|
||||
<< " chain_telemetry_compiled=0\n";
|
||||
#endif
|
||||
s.file << "tier2_superblocks=" << (tier2_superblocks_enabled() ? 1 : 0)
|
||||
<< " version=4 clusters=7 mask=0x" << std::hex << tier2_cluster_mask() << std::dec
|
||||
<< " hot_blocks=1060 static_fused_calls=36 static_fused_tail=13 hooks=25"
|
||||
<< " version=4 clusters=8 mask=0x" << std::hex << tier2_cluster_mask() << std::dec
|
||||
<< " hot_blocks=1139 static_fused_calls=36 static_fused_tail=18 static_pc_fused=1 hooks=29"
|
||||
<< " entity_leaf_inline_sites=13 geometry_inline_leaf_sites=0 direct_generated_leaf_sites=5"
|
||||
<< " unwind_fix=1 reentry_guard=1 dataflow=1 vfpu_block32=133 mem_runs=35 mem_words=287"
|
||||
<< " append32=51 advance32=89 simd_mat4=4 simd_matvec=19"
|
||||
<< " gpr_shadow_clusters=4 gpr_shadow_regs=24 gpr_shadow_occurrences=3461 geometry_shadow=0"
|
||||
<< " perf_layer=8 cpu_lean_revision=2 correctness_revision=8271 recovery_from_821=1"
|
||||
<< " unwind_fix=1 reentry_guard=1 dataflow=1 vfpu_block32=153 mem_runs=39 mem_words=299"
|
||||
<< " append32=51 advance32=89 simd_mat4=4 simd_matvec=21"
|
||||
<< " gpr_shadow_clusters=5 gpr_shadow_regs=30 gpr_shadow_occurrences=3841 geometry_shadow=0"
|
||||
<< " perf_layer=9 cpu_lean_revision=3 correctness_revision=8271 recovery_from_821=1 cpu_boundary_fusion=1 edge43_continuation_fused=1 collisionloop_blocks=78 collisionloop_static_pc_fused=1 collisionloop_scheduler_accounting=1"
|
||||
<< " save_transaction=1 save_lifecycle_v82=1 sas_endflag_latched=1 sas_loop_history_restore=1"
|
||||
<< " atrac_virtual_source=1 atrac_stall_diag=1 atrac_stream_resident_status=1 atrac_nonloop_resident=-2 atrac_loop_resident=-3 output2_success_zero=1 output2_master_watermark=1 output2_late_catchup=0 save_repro_checkpoint=1 save_repro_trace=1 save_repro_hotkey_f8=1 save_repro_trace_hotkey_f10=1 save_repro_auto_restore=1 save_repro_dispatch_sample_stride=64 save_repro_passive_until_f8=1 save_repro_hle_hotpath=0 save_repro_ui_hotkeys=1 save_repro_f10_async_fallback=1 save_repro_collector_partial_bundle=1 save_repro_internal_ini_gate=1 save_repro_default_enabled=0 save_exitdelete_semantics=1 save_repro_legacy_exitdelete_repair=1 save_partition_reuse=1 news_atrac_v825_guard=1 runtime_chain_telemetry_default=0 arch_fastmem=1 aot_direct_fastmem_default=1"
|
||||
<< " tier2_direct_fastmem=1 tier2_direct_mem_sites=1969 tier2_deep_telemetry_default=0 geometry_fusion_rollback=1"
|
||||
<< " tier2_direct_fastmem=1 tier2_direct_mem_sites=2115 tier2_deep_telemetry_default=0 geometry_fusion_rollback=1"
|
||||
<< " entity_leaf_inline=1 entity_leaf_scheduler_accounting=1 entity_leaf_resume_pc_fix=1"
|
||||
<< " ge_async_default=0 parallel_vertex_decode_default=0"
|
||||
<< " v5_vfpu_fast_quarantined=1 native_vfpu_088b1780_v4=1"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,7 @@ TIER2_FUSED_RETURN_DISPATCH:
|
||||
case 0x088B1C2Cu: goto SB_L_088B1C2C;
|
||||
case 0x088B1C40u: goto SB_L_088B1C40;
|
||||
case 0x088B3FCCu: goto SB_L_088B3FCC;
|
||||
case 0x088B3FFCu: goto SB_L_088B3FFC;
|
||||
case 0x088B4004u: goto SB_L_088B4004;
|
||||
case 0x088B4018u: goto SB_L_088B4018;
|
||||
case 0x088B4020u: goto SB_L_088B4020;
|
||||
@@ -142,6 +143,7 @@ TIER2_LOCAL_DISPATCH_U0043:
|
||||
case 0x088B1C2Cu: goto SB_L_088B1C2C;
|
||||
case 0x088B1C40u: goto SB_L_088B1C40;
|
||||
case 0x088B3FCCu: goto SB_L_088B3FCC;
|
||||
case 0x088B3FFCu: goto SB_L_088B3FFC;
|
||||
default:
|
||||
ctx.pc = local_pc;
|
||||
TIER2_SB_RETURN();
|
||||
@@ -209,6 +211,7 @@ TIER2_LOCAL_DISPATCH_U0044:
|
||||
TIER2_ENTRY_DISPATCH:
|
||||
switch (entry_pc) {
|
||||
case 0x088B3FCCu: goto SB_L_088B3FCC;
|
||||
case 0x088B3FFCu: goto SB_L_088B3FFC;
|
||||
case 0x088B4004u: goto SB_L_088B4004;
|
||||
case 0x088B40F8u: goto SB_L_088B40F8;
|
||||
default:
|
||||
@@ -584,6 +587,24 @@ SB_L_088B3FCC:
|
||||
tier2_gpr_4 = (ctx.gpr[20] | 0u);
|
||||
goto SB_L_088B1780;
|
||||
|
||||
SB_L_088B3FFC:
|
||||
if (ctx.gpr[2] == 0u) {
|
||||
tier2_gpr_4 = (tier2_mem.aot_load32(tier2_gpr_29 + static_cast<std::uint32_t>(48)));
|
||||
if (!rt.tier2_enter_fused_transfer<44u, 0x088B40F8u>(ctx)) {
|
||||
ctx.pc = 0x088B40F8u;
|
||||
TIER2_SB_RETURN();
|
||||
}
|
||||
++tier2_pending_transfers;
|
||||
++tier2_stats.fused_tail_edges;
|
||||
goto SB_L_088B40F8;
|
||||
}
|
||||
if (!rt.tier2_enter_fused_transfer<44u, 0x088B4004u>(ctx)) {
|
||||
ctx.pc = 0x088B4004u;
|
||||
TIER2_SB_RETURN();
|
||||
}
|
||||
++tier2_pending_transfers;
|
||||
++tier2_stats.fused_tail_edges;
|
||||
goto SB_L_088B4004;
|
||||
SB_L_088B4004:
|
||||
tier2_gpr_17 = (static_cast<std::uint32_t>(static_cast<std::int32_t>(static_cast<std::int16_t>(tier2_mem.aot_load16(ctx.gpr[18] + static_cast<std::uint32_t>(6))))));
|
||||
tier2_gpr_4 = (static_cast<std::uint32_t>(static_cast<std::int32_t>(static_cast<std::int16_t>(tier2_mem.aot_load16(ctx.gpr[18] + static_cast<std::uint32_t>(14))))));
|
||||
|
||||
@@ -63,6 +63,7 @@ const char *tier2_cluster_name(Tier2ClusterId id) noexcept {
|
||||
case Tier2ClusterId::Physics: return "physics";
|
||||
case Tier2ClusterId::World: return "world";
|
||||
case Tier2ClusterId::Edge43: return "edge43";
|
||||
case Tier2ClusterId::CollisionLoop: return "collisionloop";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ enum class Tier2ClusterId : std::uint32_t {
|
||||
Physics = 4u, // 0129 hot transform/physics function
|
||||
World = 5u, // 0157/0158 dominant world/streaming hot functions
|
||||
Edge43 = 6u, // 0043/0044 cross-unit boundary
|
||||
Count = 7u,
|
||||
CollisionLoop = 7u, // 0037/0038 measured generated-boundary loop
|
||||
Count = 8u,
|
||||
};
|
||||
|
||||
constexpr std::size_t kTier2ClusterCount = static_cast<std::size_t>(Tier2ClusterId::Count);
|
||||
@@ -135,5 +136,7 @@ void tier2_superblock_world(psprecomp::Runtime &, psprecomp::AllegrexContext &,
|
||||
psprecomp::GuestMemory::AotFastView &, std::uint32_t entry_pc);
|
||||
void tier2_superblock_edge43(psprecomp::Runtime &, psprecomp::AllegrexContext &,
|
||||
psprecomp::GuestMemory::AotFastView &, std::uint32_t entry_pc);
|
||||
void tier2_superblock_collisionloop(psprecomp::Runtime &, psprecomp::AllegrexContext &,
|
||||
psprecomp::GuestMemory::AotFastView &, std::uint32_t entry_pc);
|
||||
|
||||
} // namespace vcs
|
||||
|
||||
@@ -18,16 +18,16 @@ def need(cond, msg):
|
||||
raise SystemExit(1)
|
||||
print('PASS:', msg)
|
||||
|
||||
need(('stage=correctness-v8.2.7-save-thread-lifecycle-fix-2026-08-18' in log) or ('stage=correctness-v8.2.7a-internal-save-repro-gate-2026-08-18' in log), 'V8.2.7/V8.2.7A runtime stage')
|
||||
need(('correctness_revision=827 ' in log) or ('correctness_revision=8271 ' in log), 'V8.2.7/V8.2.7A correctness revision')
|
||||
need(any(stage in log for stage in ('stage=correctness-v8.2.7-save-thread-lifecycle-fix-2026-08-18', 'stage=correctness-v8.2.7a-internal-save-repro-gate-2026-08-18', 'stage=perf-v8.3-cpu-boundary-fusion-2026-08-18')), 'V8.2.7 lifecycle fix preserved in current runtime stage')
|
||||
need(('correctness_revision=827 ' in log) or ('correctness_revision=8271 ' in log), 'V8.2.7/V8.2.7A correctness revision preserved')
|
||||
need('save_exitdelete_semantics=1' in log and 'save_repro_legacy_exitdelete_repair=1' in log and 'save_partition_reuse=1' in log,
|
||||
'ExitDelete/partition fix and migration metadata')
|
||||
need('atrac_stream_resident_status=1' in log and 'atrac_nonloop_resident=-2' in log and
|
||||
'atrac_loop_resident=-3' in log and 'news_atrac_v825_guard=1' in log,
|
||||
'working V8.2.5 NEWS semantics preserved')
|
||||
need('output2_late_catchup=0' in log, 'rejected Output2 pacing experiment remains disabled')
|
||||
need('hot_blocks=1060' in log and 'static_fused_calls=36' in log and 'geometry_fusion_rollback=1' in log,
|
||||
'V8.2 CPU/Tier2 shape preserved')
|
||||
need('static_fused_calls=36' in log and 'geometry_fusion_rollback=1' in log and 'geometry_inline_leaf_sites=0' in log,
|
||||
'V8.2 Geometry rollback and conservative fusion shape preserved')
|
||||
|
||||
# Core correctness: ExitThread remains dormant/Completed, ExitDelete actually
|
||||
# destroys the object and releases its stack.
|
||||
|
||||
@@ -19,8 +19,9 @@ def need(cond, msg):
|
||||
raise SystemExit(1)
|
||||
print('PASS:', msg)
|
||||
|
||||
need('stage=correctness-v8.2.7a-internal-save-repro-gate-2026-08-18' in log,
|
||||
'V8.2.7A runtime stage')
|
||||
need(any(stage in log for stage in ('stage=correctness-v8.2.7a-internal-save-repro-gate-2026-08-18',
|
||||
'stage=perf-v8.3-cpu-boundary-fusion-2026-08-18')),
|
||||
'V8.2.7A gate preserved in current runtime stage')
|
||||
need('correctness_revision=8271' in log, 'V8.2.7A correctness revision')
|
||||
need('save_repro_internal_ini_gate=1' in log and 'save_repro_default_enabled=0' in log,
|
||||
'internal-only gate metadata')
|
||||
@@ -56,7 +57,7 @@ for token, label in [
|
||||
('atrac_nonloop_resident=-2', 'NEWS non-loop ATRAC sentinel preserved'),
|
||||
('atrac_loop_resident=-3', 'NEWS loop ATRAC sentinel preserved'),
|
||||
('output2_late_catchup=0', 'rejected Output2 pacing remains off'),
|
||||
('hot_blocks=1060', 'V8.2 CPU shape preserved'),
|
||||
('geometry_fusion_rollback=1', 'V8.2 Geometry rollback preserved'),
|
||||
('geometry_fusion_rollback=1', 'Geometry rollback preserved'),
|
||||
]:
|
||||
need(token in log, label)
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
|
||||
root = Path(__file__).resolve().parents[3]
|
||||
profile = root / 'profiles' / 'vcs'
|
||||
host = profile / 'host'
|
||||
tools = profile / 'tools'
|
||||
gen = profile / 'generated'
|
||||
|
||||
generator = (tools / 'build_tier2_superblocks.py').read_text(encoding='utf-8')
|
||||
hpp = (host / 'vcs_tier2_superblocks.hpp').read_text(encoding='utf-8')
|
||||
common = (host / 'vcs_tier2_superblocks.cpp').read_text(encoding='utf-8')
|
||||
cmake = (profile / 'CMakeLists.txt').read_text(encoding='utf-8')
|
||||
log = (host / 'vcs_runtime_log.cpp').read_text(encoding='utf-8')
|
||||
collision = (host / 'vcs_tier2_cluster_collisionloop.cpp').read_text(encoding='utf-8')
|
||||
edge = (host / 'vcs_tier2_cluster_edge43.cpp').read_text(encoding='utf-8')
|
||||
u37 = (gen / 'generated_unit_0037.cpp').read_text(encoding='utf-8')
|
||||
u38 = (gen / 'generated_unit_0038.cpp').read_text(encoding='utf-8')
|
||||
u43 = (gen / 'generated_unit_0043.cpp').read_text(encoding='utf-8')
|
||||
geometry = (host / 'vcs_tier2_cluster_geometry.cpp').read_text(encoding='utf-8')
|
||||
world = (host / 'vcs_tier2_cluster_world.cpp').read_text(encoding='utf-8')
|
||||
runtime_hpp = (root / 'include' / 'psprecomp' / 'runtime.hpp').read_text(encoding='utf-8')
|
||||
|
||||
def need(cond, msg):
|
||||
if not cond:
|
||||
print('FAIL:', msg)
|
||||
raise SystemExit(1)
|
||||
print('PASS:', msg)
|
||||
|
||||
need('stage=perf-v8.3-cpu-boundary-fusion-2026-08-18' in log, 'V8.3 runtime stage')
|
||||
need('perf_layer=9 cpu_lean_revision=3 correctness_revision=8271' in log,
|
||||
'performance revision advances without changing protected correctness revision')
|
||||
need('clusters=8' in log and 'hot_blocks=1139' in log and 'static_fused_calls=36' in log and
|
||||
'static_fused_tail=18' in log and 'static_pc_fused=1' in log,
|
||||
'generated Tier-2 V8.3 shape matches audited generator output')
|
||||
need('cpu_boundary_fusion=1' in log and 'edge43_continuation_fused=1' in log and
|
||||
'collisionloop_blocks=78' in log and 'collisionloop_static_pc_fused=1' in log and 'collisionloop_scheduler_accounting=1' in log,
|
||||
'boundary-fusion metadata present')
|
||||
|
||||
need('fuse_static_pc_returns: bool = False' in generator and 'STATIC_PC_RETURN_RE' in generator,
|
||||
'static PC return fusion is explicit and opt-in')
|
||||
need("key='collisionloop'" in generator and 'fuse_static_pc_returns=True' in generator,
|
||||
'only dedicated collision-loop cluster opts into generated-boundary fusion')
|
||||
need(generator.count('fuse_static_pc_returns=True') == 1,
|
||||
'legacy Tier-2 clusters cannot silently change boundary semantics')
|
||||
need('37: [(0x0889BFC0, 0x0889C000)]' in generator and
|
||||
'38: [(0x0889C000, 0x0889C5C0)]' in generator,
|
||||
'collision-loop window remains narrowly bounded to units 0037/0038')
|
||||
need('seeds={43: [0x088B3FCC, 0x088B3FFC]' in generator,
|
||||
'Edge43 includes measured missing continuation 0x088B3FFC')
|
||||
|
||||
need('account_inlined_dispatch_boundary' in runtime_hpp and 'return account_inlined_dispatch_boundary(ctx);' in runtime_hpp,
|
||||
'generic inlined-dispatch accounting preserves starvation cadence and backs leaf accounting')
|
||||
|
||||
need('CollisionLoop = 7u' in hpp and 'Count = 8u' in hpp and
|
||||
'tier2_superblock_collisionloop' in hpp,
|
||||
'eighth cluster is registered in Tier-2 ABI')
|
||||
need('case Tier2ClusterId::CollisionLoop: return "collisionloop";' in common,
|
||||
'collision-loop cluster has runtime identity')
|
||||
need('host/vcs_tier2_cluster_collisionloop.cpp' in cmake,
|
||||
'collision-loop translation unit is compiled')
|
||||
|
||||
need('SB_L_0889BFC0:' in collision and 'SB_L_0889C000:' in collision and
|
||||
'account_inlined_dispatch_boundary(ctx)' in collision and 'goto SB_L_0889C000;' in collision,
|
||||
'unit0037 -> unit0038 boundary is local while retaining outer-dispatch scheduler accounting')
|
||||
need('goto SB_L_0889BFC0;' in collision,
|
||||
'hot loop closes back into unit0037 without outer Runtime dispatch')
|
||||
need('tier2_enter_fused_transfer<37u, 0x0889BFC0u>' in collision and
|
||||
'tier2_complete_shadow(tier2_static_pending_)' in collision,
|
||||
'real tail-call frames unwind before the fused outer boundary, preserving accounting order')
|
||||
need('tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889BFC0u)' in u37 and
|
||||
'tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889C000u)' in u38 and
|
||||
'tier2_superblock_collisionloop(rt, ctx, aot_mem, 0x0889C5B8u)' in u38,
|
||||
'measured loop entry hooks are installed')
|
||||
|
||||
need('SB_L_088B3FFC:' in edge and 'case 0x088B3FFCu: goto SB_L_088B3FFC;' in edge,
|
||||
'Edge43 local-return dispatch owns the missing continuation')
|
||||
need('tier2_enter_fused_transfer<44u, 0x088B40F8u>' in edge and
|
||||
'tier2_enter_fused_transfer<44u, 0x088B4004u>' in edge,
|
||||
'Edge43 continuation flows directly into selected unit0044 targets')
|
||||
need('tier2_superblock_edge43(rt, ctx, aot_mem, 0x088B3FFCu)' in u43,
|
||||
'0x088B3FFC outer-entry hook is installed for measured fallback cases')
|
||||
|
||||
# Guard against repeating V8 broad geometry/world expansion.
|
||||
need(geometry.count('\nSB_L_') == 379, 'Geometry remains exactly 379 selected blocks')
|
||||
need(world.count('\nSB_L_') == 402, 'World remains exactly 402 selected blocks')
|
||||
need(len(collision.splitlines()) == 1363, 'new collision-loop body stays small (1363 lines)')
|
||||
need(len(edge.splitlines()) == 949, 'Edge43 expansion stays small (949 lines)')
|
||||
|
||||
# Current correctness regression guards.
|
||||
for token, label in [
|
||||
('correctness_revision=8271', 'Save lifecycle correctness revision'),
|
||||
('save_exitdelete_semantics=1', 'ExitDelete lifecycle fix'),
|
||||
('save_partition_reuse=1', 'partition-memory reuse fix'),
|
||||
('save_repro_internal_ini_gate=1', 'internal SAVE_REPRO gate'),
|
||||
('save_repro_default_enabled=0', 'SAVE_REPRO disabled by default'),
|
||||
('atrac_nonloop_resident=-2', 'NEWS non-loop ATRAC resident sentinel'),
|
||||
('atrac_loop_resident=-3', 'NEWS loop ATRAC resident sentinel'),
|
||||
('output2_late_catchup=0', 'rejected Output2 pacing remains off'),
|
||||
('geometry_fusion_rollback=1', 'rejected V8 Geometry expansion remains rolled back'),
|
||||
('ge_async_default=0', 'GE async remains quarantined'),
|
||||
('parallel_vertex_decode_default=0', 'parallel vertex decode remains quarantined'),
|
||||
]:
|
||||
need(token in log, label)
|
||||
|
||||
print('V8.3 CPU BOUNDARY FUSION audit PASS')
|
||||
@@ -39,6 +39,11 @@ TAIL_CALL_RE = re.compile(
|
||||
r'(?P<indent>[ \t]*)\(void\)rt\.invoke_chained_direct<&recomp_unit_(?P<target_name>\d+)_entry, '
|
||||
r'(?P<target_unit>\d+)u, (?P<entry>\d+)u, (?P<target_pc>0x[0-9A-F]+)u>'
|
||||
r'\(ctx, &aot_mem\); return;')
|
||||
# Artificial generated-unit partition boundaries are not guest calls.
|
||||
STATIC_PC_RETURN_RE = re.compile(
|
||||
r'(?P<indent>[ \t]*)ctx\.pc = (?P<target>0x[0-9A-F]+)u; return;')
|
||||
|
||||
|
||||
LOCAL_DISPATCH_SEQUENCE_RE = re.compile(
|
||||
r'(?P<indent>[ \t]*)local_pc = (?P<local_expr>[^;]+);\n'
|
||||
r'(?P=indent)if \(\+\+local_transfers < 256u\) \{ entry_id = 0u; goto LOCAL_DISPATCH; \}\n'
|
||||
@@ -132,6 +137,10 @@ class Cluster:
|
||||
expand_cross_units: bool = False
|
||||
hooks: Dict[int, List[int]] = dataclasses.field(default_factory=dict)
|
||||
max_blocks: int = 700
|
||||
# Opt-in fusion for plain generated corpus boundaries of the form
|
||||
# `ctx.pc = constant; return;`. Disabled for all legacy clusters.
|
||||
# These boundaries are not guest calls and therefore add no scheduler frame.
|
||||
fuse_static_pc_returns: bool = False
|
||||
|
||||
|
||||
CLUSTERS: List[Cluster] = [
|
||||
@@ -190,10 +199,26 @@ CLUSTERS: List[Cluster] = [
|
||||
),
|
||||
Cluster(
|
||||
key='edge43', enum_name='Edge43', function='tier2_superblock_edge43',
|
||||
seeds={43: [0x088B3FCC], 44: [0x088B4004, 0x088B40F8]},
|
||||
# Include the measured $ra continuation; omitting 0x088B3FFC forced an
|
||||
# outer Runtime dispatch immediately before unit 0044.
|
||||
seeds={43: [0x088B3FCC, 0x088B3FFC], 44: [0x088B4004, 0x088B40F8]},
|
||||
expand_cross_units=True,
|
||||
hooks={43: [0x088B3FCC], 44: [0x088B4004, 0x088B40F8]},
|
||||
max_blocks=100,
|
||||
hooks={43: [0x088B3FCC, 0x088B3FFC], 44: [0x088B4004, 0x088B40F8]},
|
||||
max_blocks=110,
|
||||
),
|
||||
Cluster(
|
||||
key='collisionloop', enum_name='CollisionLoop', function='tier2_superblock_collisionloop',
|
||||
seeds={},
|
||||
# Small measured loop straddling generated units 0037/0038. Keep the
|
||||
# footprint intentionally bounded to avoid the rejected V8 Geometry bloat.
|
||||
windows={
|
||||
37: [(0x0889BFC0, 0x0889C000)],
|
||||
38: [(0x0889C000, 0x0889C5C0)],
|
||||
},
|
||||
expand_cross_units=True,
|
||||
hooks={37: [0x0889BFC0], 38: [0x0889C000, 0x0889C5B8]},
|
||||
max_blocks=140,
|
||||
fuse_static_pc_returns=True,
|
||||
),
|
||||
]
|
||||
|
||||
@@ -640,7 +665,8 @@ def selected_pc_owner(selected: Mapping[int, Set[int]]) -> Dict[int, int]:
|
||||
|
||||
def transform_block(block: str, source_unit: int, selected: Mapping[int, Set[int]],
|
||||
sources: Mapping[int, UnitSource], stats: MutableMapping[str, int],
|
||||
fused_continuations: MutableMapping[Tuple[int, int], int]) -> str:
|
||||
fused_continuations: MutableMapping[Tuple[int, int], int],
|
||||
fuse_static_pc_returns: bool = False) -> str:
|
||||
pc_owner = selected_pc_owner(selected)
|
||||
selected_all = set(pc_owner)
|
||||
text = re.sub(r'\bL_([0-9A-F]{8})\b', r'SB_L_\1', block)
|
||||
@@ -754,6 +780,37 @@ def transform_block(block: str, source_unit: int, selected: Mapping[int, Set[int
|
||||
|
||||
text = TAIL_CALL_RE.sub(tail_repl, text)
|
||||
|
||||
# Fuse only opted-in plain constant-PC returns whose destination is already
|
||||
# selected in the same superblock. No tier2_enter/complete call is needed:
|
||||
# the original edge is merely an artificial generated-file boundary.
|
||||
if fuse_static_pc_returns:
|
||||
def static_pc_repl(m: re.Match[str]) -> str:
|
||||
target = int(m.group('target'), 16)
|
||||
if target not in selected_all:
|
||||
return m.group(0)
|
||||
stats['static_pc_fused'] += 1
|
||||
indent = m.group('indent')
|
||||
return (
|
||||
f'{indent}// Generated corpus boundary: unwind any logical tail-call frames first,\n'
|
||||
f'{indent}// then account the outer dispatch that this local edge removes.\n'
|
||||
f'{indent}if (tier2_pending_transfers != 0u) {{\n'
|
||||
f'{indent} const std::uint32_t tier2_static_pending_ = tier2_pending_transfers;\n'
|
||||
f'{indent} tier2_pending_transfers = 0u;\n'
|
||||
f'{indent} if (!tier2_complete_shadow(tier2_static_pending_)) {{\n'
|
||||
f'{indent} tier2_gpr_shadow_valid = false;\n'
|
||||
f'{indent} TIER2_SB_RETURN();\n'
|
||||
f'{indent} }}\n'
|
||||
f'{indent}}}\n'
|
||||
f'{indent}ctx.pc = 0x{target:08X}u;\n'
|
||||
f'{indent}TIER2_GPR_SYNC_OUT();\n'
|
||||
f'{indent}if (!rt.account_inlined_dispatch_boundary(ctx)) {{\n'
|
||||
f'{indent} tier2_gpr_shadow_valid = false;\n'
|
||||
f'{indent} TIER2_SB_RETURN();\n'
|
||||
f'{indent}}}\n'
|
||||
f'{indent}TIER2_GPR_SYNC_IN();\n'
|
||||
f'{indent}goto SB_L_{target:08X};')
|
||||
text = STATIC_PC_RETURN_RE.sub(static_pc_repl, text)
|
||||
|
||||
# Standard generated indirect/local return path. The shared unit-specific
|
||||
# dispatcher below recognizes a fused-call continuation and performs exactly
|
||||
# one logical chain unwind before resuming the caller.
|
||||
@@ -798,7 +855,8 @@ def emit_cluster(cluster: Cluster, selected: Mapping[int, Set[int]],
|
||||
for pc in src.ordered_pcs:
|
||||
if pc not in selected[unit]:
|
||||
continue
|
||||
chunks.append(transform_block(src.blocks[pc], unit, selected, sources, stats, continuations))
|
||||
chunks.append(transform_block(src.blocks[pc], unit, selected, sources, stats, continuations,
|
||||
cluster.fuse_static_pc_returns))
|
||||
|
||||
# Entry hooks are intentionally narrower than the selected closure: only
|
||||
# measured roots pay the extra branch into Tier-2.
|
||||
@@ -998,6 +1056,8 @@ TIER2_ENTRY_DISPATCH:
|
||||
stats['lines'] = len(cpp.splitlines())
|
||||
stats['units'] = len(selected)
|
||||
stats['hooks'] = sum(len(v) for v in cluster.hooks.values())
|
||||
if cluster.fuse_static_pc_returns and stats.get('fused_calls', 0) != 0:
|
||||
raise RuntimeError(f'{cluster.key}: static PC-return fusion currently requires zero fused JAL calls')
|
||||
return path, stats
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user