1//===-- TransformationPasses.td ------------------------*- tablegen -*-===//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
8//===----------------------------------------------------------------------===//
10#ifndef LLZK_POLYMORPHIC_TRANSFORMATION_PASSES_TD
11#define LLZK_POLYMORPHIC_TRANSFORMATION_PASSES_TD
13include "llzk/Pass/PassBase.td"
14include "mlir/IR/EnumAttr.td"
16def FlatteningCleanupModeDescription {
18 "Specifies the extent to which unused parameterized definitions (i.e. "
19 "structs or free functions within a `poly.template`) are removed during "
20 "the flattening pass.";
23def FlatteningCleanupMode
24 : I32EnumAttr<"FlatteningCleanupMode", FlatteningCleanupModeDescription.r,
26 // Unspecified: Leave the cleanup choice to the caller
27 // (defaults to `preimage` if not specified).
28 I32EnumAttrCase<"Unspecified", 0, "unspecified">,
29 // Disabled: No definitions are deleted.
30 I32EnumAttrCase<"Disabled", 1, "disabled">,
31 // Preimage: Only definitions that were replaced with
32 // concrete instantiations are deleted.
33 I32EnumAttrCase<"Preimage", 2, "preimage">,
34 // ConcreteAsRoot: All definitions that cannot be reached
35 // by a use-def chain from some concrete definition are
37 I32EnumAttrCase<"ConcreteAsRoot", 3, "concrete-as-root">,
38 // MainAsRoot: All definitions that cannot be reached by a
39 // use-def chain from the main struct are deleted.
40 I32EnumAttrCase<"MainAsRoot", 4, "main-as-root">,
42 let cppNamespace = "::llzk::polymorphic";
43 let genSpecializedAttr = 0;
46def EmptyTemplateRemovalPass : LLZKPass<"llzk-drop-empty-templates"> {
47 let summary = "Remove empty templates";
49 Performs the following transformations:
50 - Convert templates with no constant parameters or expressions into modules.
51 - Remove templates with no struct or function definitions.
55def FlatteningPass : LLZKPass<"llzk-flatten"> {
56 let summary = "Flatten structs and unroll loops";
58 Performs the following transformations:
59 - Instantiate `affine_map` parameters of StructType and ArrayType
60 to constant values using the arguments at the instantiation site
61 - Replace parameterized structs with flattened (i.e., no parameter)
62 versions of those structs based on requested return type at calls
63 to `compute()` functions and unroll loops
66 // Implementation note: These options should be kept in sync with
67 // `StructInliningFlatteningOptions` in `LLZKTransformationPassPipelines.h`.
69 [Option<"iterationLimit", "max-iter", "unsigned",
71 "Maximum number of times the pass will run if a fixpoint "
72 "is not reached earlier. Unrolling loops can provide more "
73 "opportunities for instantiating structs but the converse "
74 "is true as well. Thus, the pass will run multiple times "
75 "until no further changes can be made or the upper limit "
76 "provided in this option is reached.">,
77 Option<"cleanupMode", "cleanup",
78 "::llzk::polymorphic::FlatteningCleanupMode",
80 "::llzk::polymorphic::FlatteningCleanupMode::Unspecified",
81 FlatteningCleanupModeDescription.r, [{::llvm::cl::values(
82 clEnumValN(::llzk::polymorphic::FlatteningCleanupMode::Unspecified,
83 stringifyFlatteningCleanupMode(::llzk::polymorphic::FlatteningCleanupMode::Unspecified),
84 "Use the cleanup mode specified by the calling pipeline (defaults to `preimage` if not specified)."),
85 clEnumValN(::llzk::polymorphic::FlatteningCleanupMode::Disabled,
86 stringifyFlatteningCleanupMode(::llzk::polymorphic::FlatteningCleanupMode::Disabled),
87 "No definitions are deleted."),
88 clEnumValN(::llzk::polymorphic::FlatteningCleanupMode::Preimage,
89 stringifyFlatteningCleanupMode(::llzk::polymorphic::FlatteningCleanupMode::Preimage),
90 "Only definitions that were replaced with concrete instantiations are deleted."),
91 clEnumValN(::llzk::polymorphic::FlatteningCleanupMode::ConcreteAsRoot,
92 stringifyFlatteningCleanupMode(::llzk::polymorphic::FlatteningCleanupMode::ConcreteAsRoot),
93 "All definitions that cannot be reached by a use-def chain from some concrete definition are deleted."),
94 clEnumValN(::llzk::polymorphic::FlatteningCleanupMode::MainAsRoot,
95 stringifyFlatteningCleanupMode(::llzk::polymorphic::FlatteningCleanupMode::MainAsRoot),
96 "All definitions that cannot be reached by a use-def chain from the \"Main\" struct are deleted.")
101def WildcardArraySpecializationPass
102 : LLZKPass<"llzk-specialize-wildcard-arrays"> {
104 "Refine wildcard array casts and specialize concrete call targets";
106 Refines `poly.unifiable_cast` results when wildcard `array.type` dimensions can be replaced
107 with concrete integer sizes from the input type. Then specializes free functions, extern
108 declarations, and whole structs for calls whose wildcard array dimensions have become concrete.
110 This pass is intended to run after `llzk-flatten`. It iterates to a fixpoint so newly-refined
111 cast result types can enable further callable specialization in later iterations.
113 let options = [Option<"iterationLimit", "max-iter", "unsigned",
114 /* default */ "1000",
115 "Maximum number of iterations before the pass gives up "
116 "reaching a fixpoint.">];
119def TypeVarInferencePass : LLZKPass<"llzk-infer-tvar"> {
120 let summary = "Infer concrete function types for polymorphic type variables";
122 Infers concrete replacements for `!poly.tvar` template parameters from operations in
123 `function.def` or `poly.expr` bodies, such as `poly.unifiable_cast` between a type variable
124 and a more concrete type (which means for maximum effect you should run it before other
125 optimization passes that can remove `poly.unifiable_cast`). Rewrites affected function
126 signatures and body types, removes redundant casts, drops resolved `poly.param` declarations,
127 and updates call-site template parameter lists.
129 The pass also creates template-local instantiated versions of functions for each
130 type-variable replacement. The `llzk-flatten` pass performs similar instantiation of type
131 variables but only as part of its more extensive lowering and flattening, all of which may
132 not be desired in some cases (hence the utility of this pass).
134 This pass may result in `poly.template` containing no `poly.param` or `poly.expr`. Run
135 `llzk-drop-empty-templates` after this pass to simplify these templates.
139#endif // LLZK_POLYMORPHIC_TRANSFORMATION_PASSES_TD