@@ -107,6 +107,64 @@ namespace vast::conv {
107107 }
108108 };
109109
110+ struct RefineDeclType : operation_conversion_pattern< pr::Decl >
111+ {
112+ using op_t = pr::Decl;
113+ using base = operation_conversion_pattern< op_t >;
114+ using base::base;
115+
116+ using adaptor_t = typename op_t ::Adaptor;
117+
118+ static mlir_type resolve (mlir_type a, mlir_type b) {
119+ if (!a) {
120+ return b;
121+ }
122+ return a == b ? a : pr::MaybeDataType::get (a.getContext ());
123+ }
124+
125+ static mlir_type assigned_type (mlir_value value) {
126+ if (!value.getDefiningOp ()) {
127+ return value.getType ();
128+ } else if (auto cast = dyn_cast< pr::Cast >(value.getDefiningOp ())) {
129+ return assigned_type (cast.getOperand ());
130+ } else {
131+ return value.getType ();
132+ }
133+ }
134+
135+ static mlir_type assigned_type (op_t op) {
136+ mlir_type type = {};
137+ auto mod = op->template getParentOfType < core::ModuleOp >();
138+ for (auto use : core::symbol_table::get_symbol_uses (op, mod)) {
139+ if (auto ref = dyn_cast< pr::Ref >(use.getUser ())) {
140+ for (auto ref_user : ref->getUsers ()) {
141+ if (auto assign = dyn_cast< pr::Assign >(ref_user)) {
142+ type = resolve (type, assigned_type (assign.getValue ()));
143+ } else if (isa< mlir::CallOpInterface >(ref_user)) {
144+ return op.getType ();
145+ }
146+ }
147+ }
148+ }
149+ return op.getType ();
150+ }
151+
152+ logical_result matchAndRewrite (
153+ op_t op, adaptor_t adaptor, conversion_rewriter &rewriter
154+ ) const override {
155+ op->dump ();
156+ rewriter.modifyOpInPlace (op, [&] { op.setType (assigned_type (op)); });
157+ return mlir::success ();
158+ }
159+
160+ static void legalize (base_conversion_config &cfg) {
161+ cfg.target .addDynamicallyLegalOp < op_t >([](op_t op) {
162+ return !pr::is_maybedata (op.getType ())
163+ || pr::is_maybedata (assigned_type (op));
164+ });
165+ }
166+ };
167+
110168 template < typename op_t >
111169 struct DeadOpElimination : operation_conversion_pattern< op_t >
112170 {
@@ -144,6 +202,7 @@ namespace vast::conv {
144202 NoParseFold< hl::ChooseExprOp >,
145203 NoParseFold< hl::BinaryCondOp >,
146204 RefineReturn,
205+ RefineDeclType,
147206 DefinitionElimination< hl::EnumDeclOp >,
148207 DefinitionElimination< hl::StructDeclOp >,
149208 DefinitionElimination< hl::UnionDeclOp >,
0 commit comments