llvm / llvm/circt

[HW] Module port accessors and modifiers bugs

Open
#6,706 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

HW
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

A long time ago, HW module op would store its inputs and outputs using a function type. This lacked the ability to intermix input and output ports the way verilog allows, and so we overhauled the system. We added a `ModuleType` which holds an array of all ports, storing the name, type, and direction of each. It seems that different parts of our code have not been updated properly with the new system.

---
In the HWModuleOpInterface, the `setInputNames` makes an assumption that the port names of inputs are stored before all outputs. When you update the input port names, it will replace replace all the existing input port names, but then effectively partially sort by port direction before commiting the names.

https://github.com/llvm/circt/blob/a3e993cb387a08e686b0df1d7f5b599bca0b3751/include/circt/Dialect/HW/HWOpInterfaces.td#L135-L140

This issue can be found in `setInputNames`, `setOutputNames`, `setAllInputAttrs`, `setAllOutputAttrs`, `setInputLocs`, `setOutputLocs`.

---

`modifyModuleArgs` is used to insert and delete ports from modules. Due to historical reasons, it treats input and output ports differently. I believe that this function will successfully modify the input and output ports as requested, but then follow up by sorting them by direction. I don't think this is on purpose, and would argue it would make sense to retain the original port order. I.e. the input and output indices should be changed in to a global port index. An ever better API here would be to change this function so that it used a single list of port modifications for both inputs and outputs.

https://github.com/llvm/circt/blob/a3e993cb387a08e686b0df1d7f5b599bca0b3751/lib/Dialect/HW/HWOps.cpp#L582

---
HWInstanceOp `getPortIdForInputId` and `getPortIdForOutputId` are wrong, and ~should just forward the question to the ModuleType~ the InstanceOp does not have enough information to properly implement these methods as is.

https://github.com/llvm/circt/blob/a3e993cb387a08e686b0df1d7f5b599bca0b3751/include/circt/Dialect/HW/HWStructure.td#L458-L462

https://github.com/llvm/circt/blob/a3e993cb387a08e686b0df1d7f5b599bca0b3751/lib/Dialect/HW/HWTypes.cpp#L825

---
This is not a bug, but this code could be faster. Using `getPortIdForInputId` and `getPortIdForOutputId` involves a serial walk through all ports. It would be faster to just walk all ports, filtering out the unneeded directions. Same issue in `getInputLocs`, `getInputLocsAttr`, `getOutputLocs`, `getOutputLocsAttr`.

https://github.com/llvm/circt/blob/a3e993cb387a08e686b0df1d7f5b599bca0b3751/include/circt/Dialect/HW/HWOpInterfaces.td#L178-L200

---

Audit the use of `HWMutableModuleLike`. Is it still needed, and can the functionality be collapsed in to the regular `HWModuleLike`?

`appendOutputs` should probably be implemented the way other methods are in this file, i.e. by lightly wrapping `modifyPorts`. It does not look like its implemented properly for all module types as is:
```
void HWModuleExternOp::appendOutputs(
ArrayRef> outputs) {}

void HWModuleGeneratedOp::appendOutputs(
ArrayRef> outputs) {}
```

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by auditing the listed accessors in include/circt/Dialect/HW/HWOpInterfaces.td and HWStructure.td, then inspect modifyModuleArgs and appendOutputs in lib/Dialect/HW/HWOps.cpp. Review the related port-ID logic in lib/Dialect/HW/HWTypes.cpp and the uses of HWMutableModuleLike. Done means port order is preserved, port-ID accessors are correct, and appendOutputs works across module types.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.