Skip to content

[Formal][Property Annotation] Annotate path--single-sent-fork-output#713

Draft
Basmet0 wants to merge 10 commits intoEPFL-LAP:mainfrom
Basmet0:invariant3
Draft

[Formal][Property Annotation] Annotate path--single-sent-fork-output#713
Basmet0 wants to merge 10 commits intoEPFL-LAP:mainfrom
Basmet0:invariant3

Conversation

@Basmet0
Copy link
Collaborator

@Basmet0 Basmet0 commented Jan 21, 2026

The following invariant is annotated during the HandshakeAnnotateProperties pass: Along a path without any slots, only a single fork output along that path can be in the sent state.
Approach: Start a path at a fork, follow it forwards using DFS and annotate the path at each fork.

Comment on lines +316 to +317
std::vector<std::string> names{};
std::vector<unsigned> outputs{};
Copy link
Member

Choose a reason for hiding this comment

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

Store the ops instead of names (extract the names just right before dumping them to json

Makes more sense to have an internal data structure for holding the path we need, something like:

// Stored in detail namespace since they are internal data structures for implementing algorithms
namespace detail {
/// Add the documentation here
struct BufferLessPathNode {
  Operation op;
  Value val;
};
};

Comment on lines +287 to +309
LogicalResult
HandshakeAnnotatePropertiesPass::annotatePathSingleForkSentIterate(
const std::unordered_set<std::string> &visitedSet,
const std::vector<std::string> &prevForks,
const std::vector<unsigned> &prevIdxs, Operation &curOp,
bool annotateIdxs) {
for (auto [i, res] : llvm::enumerate(curOp.getResults())) {
std::vector<unsigned> nextIdxs = prevIdxs;
if (annotateIdxs) {
nextIdxs.push_back(i);
if (failed(annotatePathSingleForkSentPushProperty(prevForks, nextIdxs))) {
return failure();
}
}
for (auto *op : res.getUsers()) {
if (failed(annotatePathSingleForkSentDecide(visitedSet, prevForks,
nextIdxs, *op))) {
return failure();
}
}
}
return success();
}
Copy link
Member

Choose a reason for hiding this comment

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

This could be inline into the code below (path enumeration algorithm shouldn't be split in half)

Comment on lines +260 to +285
LogicalResult HandshakeAnnotatePropertiesPass::annotatePathSingleForkSentDecide(
std::unordered_set<std::string> visitedSet,
const std::vector<std::string> &prevForks,
const std::vector<unsigned> &prevIdxs, Operation &curOp) {

// If this operation has been visited, there is nothing to do
std::string id = getUniqueName(&curOp).str();
if (auto iter = visitedSet.find(id); iter != visitedSet.end()) {
return success();
}
visitedSet.insert(id);

// Found a slot, which marks the end of this path
if (auto bufOp = dyn_cast<handshake::BufferLikeOpInterface>(curOp)) {
return success();
}

if (auto forkOp = dyn_cast<handshake::EagerForkLikeOpInterface>(curOp)) {
auto nextForks = prevForks;
nextForks.push_back(id);
return annotatePathSingleForkSentIterate(visitedSet, nextForks, prevIdxs,
curOp, true);
}
return annotatePathSingleForkSentIterate(visitedSet, prevForks, prevIdxs,
curOp, false);
}
Copy link
Member

Choose a reason for hiding this comment

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

Also could be inlined (so we have a full picture of the algorithm

Comment on lines +34 to +35
if (s == "PSSFO")
return FormalProperty::TYPE::PSSFO;
Copy link
Member

Choose a reason for hiding this comment

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

Could you expand all the acronyms? Very hard to read

@Jiahui17 Jiahui17 marked this pull request as draft February 10, 2026 13:08
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