class_docstr: It associates pointers with the loop nest that produces
  their values and with the loop nest that consumes their values.
docstr: Get the last attribute statement which produces the variable var when
  the current attribute statement is attr.
docstr_tok: ["Get","the","last","attribute","statement","which","produces","the","variable","var","when","the","current","attribute","statement","is","attr","."]
code: def get_producer(
      self, var: tvm.tir.expr.Var, attr: tvm.tir.AttrStmt
  ) -> Optional[tvm.tir.AttrStmt]:
      """Get the last attribute statement which produces the variable var when
      the current attribute statement is attr."""
      if var not in self.allocate_variables:
          return None
  
      index = self.indices[attr]
      for i in list(reversed(range(index + 1))):
          if self.producers[i][1] == var:
              return self.producers[i][0]
      return None
  
file_path: tvm/python/tvm/relay/backend/contrib/ethosu/tir/producers_consumers.py
imports: from typing import Optional
  from collections.abc import KeysView
  import tvm
label_desc: Use image node_id 3 for calling the ProducersConsumers obj's underlying member method code with example usage: obj.get_producer(var, attr) and returns: None, None, self