Skip to content

Commit 53f5875

Browse files
author
Joshua You
committed
Merge remote-tracking branch 'origin/next' into work-graph
2 parents d4fa538 + 0d3601c commit 53f5875

116 files changed

Lines changed: 6962 additions & 3302 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/luisa/xir/passes/alias_analysis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ struct AliasAnalysisInfo {
1919
size_t queried_count{0u};
2020
};
2121

22-
// Run analysis (pre-computes base alloca for all LOCAL instructions)
22+
// The query is deliberately stateless so operand rewrites cannot leave stale
23+
// cached alias facts. These entry points are retained for pipeline/report API
24+
// compatibility.
2325
[[nodiscard]] LUISA_XIR_API AliasAnalysisInfo alias_analysis_pass_run_on_function(FunctionDefinition *def) noexcept;
2426
[[nodiscard]] LUISA_XIR_API AliasAnalysisInfo alias_analysis_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
2527

include/luisa/xir/passes/const_fold.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ class PassReport;
1010
// This pass folds constant expressions at compile time.
1111
// Arithmetic operations with all-constant operands are evaluated
1212
// and replaced with a Constant value.
13+
// Target-dependent floating-point operations such as LERP and SMOOTHSTEP are
14+
// left intact when a host evaluation would not preserve strict backend
15+
// semantics. NaN and signed-zero cases are folded only when backend behavior is
16+
// unambiguous.
1317

1418
struct ConstFoldInfo {
1519
size_t folded_inst_count{0u};

include/luisa/xir/passes/coro_cfg_distill.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ struct CoroCfgDistillResult {
7474
luisa::vector<FrameValue> frame_values;
7575
};
7676

77+
// These analysis entry points do not mutate the input, but their scope/liveness
78+
// results are supported only for unstructured CFG. Call lower_switch followed by
79+
// destructure_cfg before distilling a function that contains structured or
80+
// ambiguous control flow (including SWITCH with a null merge).
7781
[[nodiscard]] LUISA_XIR_API CoroCfgDistillResult coro_cfg_distill_pass_run_on_function(Function *f) noexcept;
7882
[[nodiscard]] LUISA_XIR_API size_t coro_cfg_distill_pass_run_on_module(Module *m) noexcept;
7983

include/luisa/xir/passes/coro_materialize.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <cstddef>
4+
35
#include <luisa/core/dll_export.h>
46
#include <luisa/core/stl/string.h>
57
#include <luisa/core/stl/unordered_map.h>
@@ -25,6 +27,14 @@ struct CoroMaterializeInfo {
2527
size_t suspend_lowered_count{0u};
2628
size_t resume_lowered_count{0u};
2729
size_t terminal_lowered_count{0u};
30+
// Coro materialization is an unstructured-CFG-only transform. A non-zero
31+
// value means the complete request was rejected before any IR was mutated.
32+
size_t structured_cfg_error_count{0u};
33+
size_t invalid_input_error_count{0u};
34+
35+
[[nodiscard]] bool succeeded() const noexcept {
36+
return structured_cfg_error_count == 0u && invalid_input_error_count == 0u;
37+
}
2838

2939
struct TransitionEdge {
3040
size_t from_scope{0u};
@@ -37,6 +47,12 @@ struct CoroMaterializeInfo {
3747
luisa::unordered_map<luisa::string, const Type *> name_to_type;
3848
};
3949

50+
// These entry points require lower_switch followed by destructure_cfg. SWITCH
51+
// is conservatively rejected even when its merge is null. Rejection is atomic:
52+
// no matching callable in the module is materialized. The split-aware overload
53+
// also rejects missing/duplicate/out-of-range scopes, duplicate/null/foreign
54+
// callables, and a frame argument that is not the callable's own reference
55+
// argument.
4056
[[nodiscard]] LUISA_XIR_API CoroMaterializeInfo coro_materialize_pass_run_on_module(Module *m) noexcept;
4157
[[nodiscard]] LUISA_XIR_API CoroMaterializeInfo coro_materialize_pass_run_on_module_with_cfg(
4258
Module *m, const CoroCfgDistillResult &cfg) noexcept;

include/luisa/xir/passes/coro_split.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,25 @@ struct CoroSplitInfo {
2828
Value *frame_argument{nullptr};
2929
};
3030
luisa::vector<Subroutine> subroutines;
31+
// Coro splitting is an unstructured-CFG-only transform. A non-zero value
32+
// means the complete request was rejected before any IR was mutated.
33+
size_t structured_cfg_error_count{0u};
34+
size_t invalid_cfg_error_count{0u};
35+
36+
[[nodiscard]] bool succeeded() const noexcept {
37+
return structured_cfg_error_count == 0u && invalid_cfg_error_count == 0u;
38+
}
3139
};
3240

41+
// Coro split does not lower structured control flow. Call lower_switch first,
42+
// then destructure_cfg, before invoking this pass. SWITCH is treated as
43+
// structured/ambiguous even when its merge is null. Module entry points are
44+
// atomic: if any coroutine definition is unsupported, no definition is split.
45+
// Explicit distilled CFG input must be non-empty and wholly owned by the module
46+
// passed to the entry point.
47+
[[nodiscard]] LUISA_XIR_API CoroSplitInfo coro_split_pass_run_on_module_info(Module *m) noexcept;
48+
// Compatibility count-only entry points return zero on rejection. Use an
49+
// Info-returning entry point when the caller must inspect error counts.
3350
[[nodiscard]] LUISA_XIR_API size_t coro_split_pass_run_on_module(Module *m) noexcept;
3451
[[nodiscard]] LUISA_XIR_API size_t coro_split_pass_run_on_module_with_cfg(
3552
Module *m, const CoroCfgDistillResult &cfg) noexcept;

include/luisa/xir/passes/destructure_cfg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ struct DestructureCFGInfo {
2020
size_t leaked_block_count{0u};
2121
};
2222

23+
// Explicitly lowers structured IF/LOOP/SIMPLE_LOOP/BREAK/CONTINUE constructs
24+
// in every block owned by the function, including disconnected regions.
25+
// SwitchInst is intentionally left for lower_switch_pass followed by this pass.
2326
[[nodiscard]] LUISA_XIR_API DestructureCFGInfo destructure_cfg_pass_run_on_function(Function *function) noexcept;
2427
[[nodiscard]] LUISA_XIR_API DestructureCFGInfo destructure_cfg_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
2528

include/luisa/xir/passes/fuse_consecutive_buffer_reads.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ struct FuseConsecutiveBufferReadsInfo {
1212
size_t fused_read_count{0u};
1313
};
1414

15+
// This pass is intentionally quarantined as a no-op. XIR typed buffer
16+
// operations require the access type to equal the buffer element type, so a
17+
// scalar-to-vector rewrite is not legal without a byte-addressed lowering and
18+
// backend-independent proofs for alignment, bounds, aliasing, and volatility.
19+
// The entry points remain available for pipeline/API compatibility and report
20+
// zero changes.
21+
1522
[[nodiscard]] LUISA_XIR_API FuseConsecutiveBufferReadsInfo
1623
fuse_consecutive_buffer_reads_pass_run_on_function(Function *function) noexcept;
1724

include/luisa/xir/passes/if_conversion.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ struct IfConversionInfo {
1212
size_t converted_diamond_count{0u};
1313
size_t hoisted_inst_count{0u};
1414
size_t replaced_phi_count{0u};
15+
size_t structured_cfg_error_count{0u};
16+
[[nodiscard]] bool succeeded() const noexcept { return structured_cfg_error_count == 0u; }
1517
};
1618

19+
// Unstructured-CFG-only: structured functions are rejected without mutation.
1720
[[nodiscard]] LUISA_XIR_API IfConversionInfo if_conversion_pass_run_on_function(Function *function) noexcept;
1821
[[nodiscard]] LUISA_XIR_API IfConversionInfo if_conversion_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
1922

include/luisa/xir/passes/inline.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@ class PassReport;
1010
struct InlineInfo {
1111
size_t inlined_call_count{0u};
1212
size_t removed_callable_count{0u};
13+
size_t skipped_recursive_callable_count{0u};
14+
size_t skipped_structured_call_count{0u};
1315
};
1416

17+
// Single-block callees can be inlined into structured callers without changing
18+
// their CFG. Multi-block inlining is unstructured-CFG-only; calls involving a
19+
// structured caller or callee are reported and left unchanged.
1520
[[nodiscard]] LUISA_XIR_API InlineInfo inline_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
1621
[[nodiscard]] LUISA_XIR_API InlineInfo inline_all_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
1722

include/luisa/xir/passes/loop_fusion.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ class PassReport;
88

99
struct LoopFusionInfo {
1010
size_t fused_loop_count{0u};
11+
size_t structured_cfg_error_count{0u};
12+
[[nodiscard]] bool succeeded() const noexcept { return structured_cfg_error_count == 0u; }
1113
};
1214

15+
// Unstructured-CFG-only: structured functions are rejected without mutation.
16+
// Plain CFG is currently accepted unchanged pending canonical-loop support.
1317
[[nodiscard]] LUISA_XIR_API LoopFusionInfo loop_fusion_pass_run_on_function(Function *function) noexcept;
1418
[[nodiscard]] LUISA_XIR_API LoopFusionInfo loop_fusion_pass_run_on_module(Module *module, PassReport *report = nullptr) noexcept;
1519

0 commit comments

Comments
 (0)