Skip to content

Conversation

@Scheremo
Copy link
Contributor

@Scheremo Scheremo commented Oct 24, 2025

  • New IR ops

    • moore.class.property_ref: yields a !moore.ref<T> to a class property.
    • moore.class.upcast: converts a derived class handle to one of its base class handles (zero-cost).
  • Class handle utilities

    • Added Context::isSameOrDerivedFrom() and getAncestorClassWithProperty() for inheritance and field lookup.
    • Added verifiers for both new ops ensuring valid symbols & types.
  • ImportVerilog/Expressions.cpp:

    • Added implicit handle upcasting (maybeUpcastHandle).
    • Added lowering for t.a reads/writes via moore.class.property_ref.
    • Emits moore.class.upcast when accessing inherited fields.
  • Added coverage for:

    • Property read/write (t.a, t.a = x).
    • Implicit upcast from derived -> base before member access.

@Scheremo Scheremo force-pushed the pr-moore-class-memberaccess branch 20 times, most recently from 008177b to 7ea2c46 Compare October 28, 2025 19:27
@Scheremo Scheremo marked this pull request as ready for review October 28, 2025 19:29
Copy link
Contributor

@fabianschuiki fabianschuiki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, modulo the O(N²) behavior thanks to MLIR's SymbolTables.

let arguments = (ins ClassHandleType:$instance);
let results = (outs ClassHandleType:$result);
let assemblyFormat =
"$instance `:` type($instance) `to` type($result) attr-dict";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it would make sense to constrain the upcast op to only perform a single layer of upcasting; basically a class to one of its immediate base classes. This would potentially simplify lowering of the op, since you can just perform a single projection on the class pointer and the vtable pointer. The frontend could then insert multiple upcast ops if needed. WDYT?

Copy link
Contributor Author

@Scheremo Scheremo Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my original thought was to have "multi-step" upcasts for a few reasons:

  1. I think it looks neater 😄
  2. System Verilog only allows single-inheritance from base classes, (but multiple "inheritance" for interfaces - however all of their fields must be virtual and there is no shadowing, so vtable resolution shouldn't produce the diamond inheritance problem) so the upcast path is unique, there's no diamond inheritance problem.
  3. My idea was to translate upcasts into literal no-ops; we practically only need the instance's RTTI to decide on the vtable pointer for dispatch, and since we can rely on objects only having single inheritance, the class pointer upcast is straight-forward. We can just construct the object layout to append properties to its data structure for each level of inheritance.

Maybe I'm missing something but I believe multi-step upcasting is safe. I think your solution works equally well, but since we don't have multiple inheritance we should be able to skip it; thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! I think the approach you have in this PR is great!

@Scheremo Scheremo force-pushed the pr-moore-class-memberaccess branch from 3a0ef15 to a2aedcc Compare October 28, 2025 19:49
- **New IR ops**
  - `moore.class.property_ref`: yields a `!moore.ref<T>` to a class property.
  - `moore.class.upcast`: converts a derived class handle to one of its base class handles (zero-cost).

- **Class handle utilities**
  - Added `Context::isSameOrDerivedFrom()` and `getAncestorClassWithProperty()` for inheritance and field lookup.
  - Added verifiers for both new ops ensuring valid symbols & types.

- `ImportVerilog/Expressions.cpp`:
  - Added implicit handle upcasting (`maybeUpcastHandle`).
  - Added lowering for `t.a` reads/writes via `moore.class.property_ref`.
  - Emits `moore.class.upcast` when accessing inherited fields.

- Added coverage for:
  - Property read/write (`t.a`, `t.a = x`).
  - Implicit upcast from derived -> base before member access.
@Scheremo Scheremo force-pushed the pr-moore-class-memberaccess branch from a2aedcc to 4cb203b Compare October 28, 2025 19:55
@Scheremo Scheremo merged commit feb38f6 into llvm:main Oct 28, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants