[SV] Use SymbolOpUserInterface to speed up verifiers

This change moves two InferfaceInstanceOp and GetModportOp to use the
symbol user op interface when checking the referenced operation. This
significantly reduces the cost of verifying this.
This commit is contained in:
Andrew Young 2024-11-01 23:44:51 -07:00
parent cb90e658ab
commit 1fd4c9ec11
2 changed files with 16 additions and 9 deletions

View File

@ -212,7 +212,8 @@ def ModportType : SVType<"Modport"> {
def InterfaceInstanceOp : SVOp<"interface.instance", [
HasCustomSSAName,
DeclareOpInterfaceMethods<InnerSymbol, ["getTargetResultIndex"]>
DeclareOpInterfaceMethods<InnerSymbol, ["getTargetResultIndex"]>,
DeclareOpInterfaceMethods<SymbolUserOpInterface>
]> {
let summary = "Instantiate an interface";
let description = [{
@ -259,7 +260,9 @@ def InterfaceInstanceOp : SVOp<"interface.instance", [
}];
}
def GetModportOp: SVOp<"modport.get", [Pure]> {
def GetModportOp: SVOp<"modport.get", [Pure,
DeclareOpInterfaceMethods<SymbolUserOpInterface>
]> {
let summary = "Get a modport out of an interface instance";
let description = [{
Use this to extract a modport view to an instantiated interface. For
@ -278,8 +281,6 @@ def GetModportOp: SVOp<"modport.get", [Pure]> {
let assemblyFormat =
"$iface $field attr-dict `:` qualified(type($iface)) `->` qualified(type($result))";
let hasVerifier = 1;
let builders = [
OpBuilder<(ins "Value":$value, "::llvm::StringRef":$field)>
];

View File

@ -1456,14 +1456,18 @@ void InterfaceInstanceOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
LogicalResult InterfaceInstanceOp::verify() {
if (getName().empty())
return emitOpError("requires non-empty name");
return success();
}
LogicalResult
InterfaceInstanceOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
auto *symtable = SymbolTable::getNearestSymbolTable(*this);
if (!symtable)
return emitError("sv.interface.instance must exist within a region "
"which has a symbol table.");
auto ifaceTy = getType();
auto referencedOp =
SymbolTable::lookupSymbolIn(symtable, ifaceTy.getInterface());
auto *referencedOp =
symbolTable.lookupSymbolIn(symtable, ifaceTy.getInterface());
if (!referencedOp)
return emitError("Symbol not found: ") << ifaceTy.getInterface() << ".";
if (!isa<InterfaceOp>(referencedOp))
@ -1474,14 +1478,16 @@ LogicalResult InterfaceInstanceOp::verify() {
/// Ensure that the symbol being instantiated exists and is an
/// InterfaceModportOp.
LogicalResult GetModportOp::verify() {
LogicalResult
GetModportOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
auto *symtable = SymbolTable::getNearestSymbolTable(*this);
if (!symtable)
return emitError("sv.interface.instance must exist within a region "
"which has a symbol table.");
auto ifaceTy = getType();
auto referencedOp =
SymbolTable::lookupSymbolIn(symtable, ifaceTy.getModport());
auto *referencedOp =
symbolTable.lookupSymbolIn(symtable, ifaceTy.getModport());
if (!referencedOp)
return emitError("Symbol not found: ") << ifaceTy.getModport() << ".";
if (!isa<InterfaceModportOp>(referencedOp))