LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
Compare.h
Go to the documentation of this file.
1//===-- Compare.h -----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
10#pragma once
11
12#include <mlir/IR/Operation.h>
13
14#include <concepts>
15#include <utility>
16
17namespace llzk {
18
19template <typename Op>
20concept OpComparable = requires(Op op) {
21 { op.getOperation() } -> std::convertible_to<mlir::Operation *>;
22};
23
24template <typename Op>
25concept NamedOpComparable = OpComparable<Op> && requires(Op op) {
26 { op.getName() } -> std::convertible_to<mlir::StringRef>;
27};
28
30 bool operator()(const mlir::FileLineColLoc &LHS, const mlir::FileLineColLoc &RHS) const {
31 auto filenameCmp = LHS.getFilename().compare(RHS.getFilename());
32 return filenameCmp < 0 || (filenameCmp == 0 && LHS.getLine() < RHS.getLine()) ||
33 (filenameCmp == 0 && LHS.getLine() == RHS.getLine() &&
34 LHS.getColumn() < RHS.getColumn());
35 }
36};
37
39 bool operator()(const mlir::Location &LHS, const mlir::Location &RHS) const {
40 auto lhsFileLoc = llvm::dyn_cast<mlir::FileLineColLoc>(LHS);
41 auto rhsFileLoc = llvm::dyn_cast<mlir::FileLineColLoc>(RHS);
42 if (lhsFileLoc && rhsFileLoc) {
43 return FileLineColLocComparator {}(lhsFileLoc, rhsFileLoc);
44 }
45 return mlir::hash_value(LHS) < mlir::hash_value(RHS);
46 }
47};
48
54template <OpComparable Op> mlir::FailureOr<bool> isLocationLess(const Op &l, const Op &r) {
55 mlir::Location lhsLoc = l->getLoc(), rhsLoc = r->getLoc();
56 // We cannot make judgments on unknown locations.
57 if (llvm::isa<mlir::UnknownLoc>(lhsLoc) || llvm::isa<mlir::UnknownLoc>(rhsLoc)) {
58 return mlir::failure();
59 }
60 // If we have full locations for both, then we can sort by file name, then line, then column.
61 auto lhsFileLoc = llvm::dyn_cast<mlir::FileLineColLoc>(lhsLoc);
62 auto rhsFileLoc = llvm::dyn_cast<mlir::FileLineColLoc>(rhsLoc);
63 if (lhsFileLoc && rhsFileLoc) {
64 return FileLineColLocComparator {}(lhsFileLoc, rhsFileLoc);
65 }
66 return mlir::failure();
67}
68
69template <OpComparable Op> struct OpLocationLess {
70 bool operator()(const Op &l, const Op &r) const { return isLocationLess(l, r).value_or(false); }
71};
72
75template <NamedOpComparable Op> struct NamedOpLocationLess {
76 bool operator()(const Op &l, const Op &r) const {
77 auto res = isLocationLess(l, r);
78 auto reverseRes = isLocationLess(r, l);
79 // A successful false result may mean either equal locations or that the operands are reversed.
80 // Check both directions before using the symbol name as the deterministic tie-breaker.
81 if (mlir::succeeded(res) && res.value()) {
82 return true;
83 }
84 if (mlir::succeeded(reverseRes) && reverseRes.value()) {
85 return false;
86 }
87
88 Op &lhs = const_cast<Op &>(l);
89 Op &rhs = const_cast<Op &>(r);
90 return lhs.getName().compare(rhs.getName()) < 0;
91 }
92};
93
94template <typename T, typename U> constexpr T checkedCast(U u) noexcept {
95 assert(std::in_range<T>(u) && "lossy conversion");
96 return static_cast<T>(u);
97}
98
99} // namespace llzk
constexpr T checkedCast(U u) noexcept
Definition Compare.h:94
mlir::FailureOr< bool > isLocationLess(const Op &l, const Op &r)
Compare the source locations of two operations.
Definition Compare.h:54
bool operator()(const mlir::FileLineColLoc &LHS, const mlir::FileLineColLoc &RHS) const
Definition Compare.h:30
bool operator()(const mlir::Location &LHS, const mlir::Location &RHS) const
Definition Compare.h:39
Order named operations by source location, using the symbol name to break ties or when source locatio...
Definition Compare.h:75
bool operator()(const Op &l, const Op &r) const
Definition Compare.h:76
bool operator()(const Op &l, const Op &r) const
Definition Compare.h:70