@@ -613,6 +613,58 @@ static inline LogicalResult errorIfShapeNotSizeOne(Operation *op, Type type) {
613613 return shapeAdaptor.getNumElements () == 1 ? success () : failure ();
614614}
615615
616+ // Returns the first declaration point prior to this operation or failure if
617+ // not found.
618+ static FailureOr<tosa::VariableOp> findVariableDecl (Operation *op,
619+ StringRef symName) {
620+ ModuleOp module = op->getParentOfType <ModuleOp>();
621+ tosa::VariableOp varOp = nullptr ;
622+
623+ // TODO: Adopt SymbolTable trait to Varible ops.
624+ // Currently, the variable's definition point is searched via walk(),
625+ // starting from the top-level ModuleOp and stopping at the point of use. Once
626+ // TOSA control flow and variable extensions reach the complete state, may
627+ // leverage MLIR's Symbol Table functionality to look up symbol and enhance
628+ // the search to a TOSA specific graph traversal over the IR structure.
629+ module .walk ([&](Operation *tempOp) {
630+ // Reach this op itself.
631+ if (tempOp == op) {
632+ return WalkResult::interrupt ();
633+ }
634+
635+ if (auto tosaOp = dyn_cast<tosa::VariableOp>(tempOp)) {
636+ if (symName == tosaOp.getName ()) {
637+ varOp = tosaOp;
638+ return WalkResult::interrupt ();
639+ }
640+ }
641+
642+ return WalkResult::advance ();
643+ });
644+
645+ if (varOp)
646+ return varOp;
647+
648+ return failure ();
649+ }
650+
651+ template <typename T>
652+ static LogicalResult verifyVariableOpErrorIf (T op, Type type, StringRef name) {
653+ StringRef symName = op.getName ();
654+ FailureOr<tosa::VariableOp> varOp = findVariableDecl (op, symName);
655+ if (failed (varOp))
656+ return op->emitOpError (" '" )
657+ << symName << " ' has not been declared by 'tosa.variable'" ;
658+
659+ // Verify type and shape
660+ Type varType = cast<tosa::VariableOp>(varOp.value ()).getType ();
661+ if (errorIfTypeOrShapeMismatch (op, type, name, varType, " the input tensor" )
662+ .failed ())
663+ return failure ();
664+
665+ return success ();
666+ }
667+
616668// verify that inType and outType have same element types
617669template <typename T>
618670static LogicalResult verifySameElementTypes (T op, Type inType, Type outType) {
@@ -3660,6 +3712,32 @@ LogicalResult tosa::SelectOp::verify() {
36603712 return success ();
36613713}
36623714
3715+ LogicalResult tosa::VariableOp::verify () {
3716+ StringRef symName = getName ();
3717+ FailureOr<tosa::VariableOp> varOp = findVariableDecl (*this , symName);
3718+ if (succeeded (varOp))
3719+ return emitOpError (" illegal to have multiple declaration of '" )
3720+ << symName << " '" ;
3721+
3722+ return success ();
3723+ }
3724+
3725+ LogicalResult tosa::VariableReadOp::verify () {
3726+ if (verifyVariableOpErrorIf (*this , getOutput1 ().getType (), " 'output1'" )
3727+ .failed ())
3728+ return failure ();
3729+
3730+ return success ();
3731+ }
3732+
3733+ LogicalResult tosa::VariableWriteOp::verify () {
3734+ if (verifyVariableOpErrorIf (*this , getInput1 ().getType (), " 'input1'" )
3735+ .failed ())
3736+ return failure ();
3737+
3738+ return success ();
3739+ }
3740+
36633741// parse and print of WhileOp refer to the implementation of SCF dialect.
36643742ParseResult WhileOp::parse (OpAsmParser &parser, OperationState &result) {
36653743 SmallVector<OpAsmParser::Argument, 4 > regionArgs;
0 commit comments