Skip to content

Commit cb7e4c7

Browse files
committed
pr: Refine decl types
1 parent 438e71d commit cb7e4c7

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

lib/vast/Conversion/Parser/Refine.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)