[Moore][ImportVerilog] Model $cast with dyn_cast and success flag#10156
[Moore][ImportVerilog] Model $cast with dyn_cast and success flag#10156sunhailong2001 wants to merge 1 commit intollvm:mainfrom
Conversation
|
Hey, @fabianschuiki. 😃 If my thought is accepted, I will add more tests. |
|
Hey @sunhailong2001! I love your idea of doing casting and assignment in separate operations, that's very elegant. The dynamic casting is an interesting challenge. I see a few different groups that a
Groups 1-4 are all static casts: we know at compile time whether they succeed or not. To implement these, we could directly call
Group 5 is the truly dynamic one. When we see that a WDYT? Does it make sense to separate |
|
+1 for the idea of trying to implement dynamic casts statically at compile time! Imo this could also be left for a follow-up. With regards to class-typed cast I think this work could be orthogonalised. We would likely just have to exclude |
|
That sounds like we could do almost all casting statically with the existing |
Upcasts generally go through I agree with the suggestion. I'm sure we'll get vtables materialised one of these days 🚀 |
Implement statically inferable $cast lowering through materializeConversion. Use fallible conversion to produce the $cast success flag: emit blocking assignment only on success, and return i1 true/false accordingly.
177d38b to
f97682a
Compare
| // CHECK-LABEL: func.func private @DynCastRealToInt( | ||
| // CHECK-SAME: %arg0: !moore.i32 | ||
| // CHECK-SAME: ) -> !moore.i32 { | ||
| // CHECK: [[A:%.+]] = moore.variable %arg0 : <i32> | ||
| // CHECK: [[V1:%.+]] = moore.variable : <i32> | ||
| // CHECK: [[CR:%.+]] = moore.constant_real 2.300000e+00 : f64 | ||
| // CHECK: [[REAL_TO_INT:%.+]] = moore.real_to_int [[CR]] : f64 -> i32 | ||
| // CHECK: moore.blocking_assign [[A]], [[REAL_TO_INT]] : i32 | ||
| // CHECK: [[SUCC:%.+]] = moore.constant 1 : i1 | ||
| // CHECK: [[READ:%.+]] = moore.read [[V1]] : <i32> | ||
| // CHECK: return [[READ]] : !moore.i32 | ||
| // CHECK: } | ||
|
|
||
| function int DynCastRealToInt(int a); | ||
| $cast(a, 2.3); | ||
| endfunction | ||
|
|
||
| // CHECK-LABEL: moore.coroutine private @DynCastRealToString() { | ||
| // CHECK: [[S:%.+]] = moore.variable : <string> | ||
| // CHECK: [[CR:%.+]] = moore.constant_real 2.300000e+00 : f64 | ||
| // CHECK: [[FAIL:%.+]] = moore.constant 0 : i1 | ||
| // CHECK: moore.return | ||
| // CHECK: } | ||
|
|
||
| task DynCastRealToString; | ||
| string s; | ||
| $cast(s, 2.3); | ||
| endtask |
There was a problem hiding this comment.
Really cool! 🥳 You could try to use inout a and return $cast(...); to make the pass/fail of the cast show up in the return IR op, and to treat a as a reference that can be directly assigned to (that might remove a few helper variables in the IR and make it easier to write CHECK lines.)
|
Your fallible conversion changes look fantastic @sunhailong2001! 🥳 |
This change adds
AggregateTypeandSingularType, and extends themoore.builtin.dyn_cast(CastBIOp) op with a 1-bit success flag to model $cast. And each $cast will be lowered intodyn_cast+blocking_assignops.