nodes: 0, module; 1, function_definition; 2, function_name:_order_pases; 3, parameters; 4, block; 5, identifier:self; 6, identifier:passes; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, for_statement; 11, return_statement; 12, comment:"""Topologically sort optimization passes.
  
          This ensures that the resulting passes are run in order
          respecting before/after constraints.
  
          Args:
              passes (iterable): An iterable of pass names that should
                  be included in the optimization passes run.
          """; 13, assignment; 14, assignment; 15, identifier:opt; 16, identifier:passes; 17, block; 18, call; 19, identifier:passes; 20, call; 21, identifier:pass_deps; 22, dictionary; 23, expression_statement; 24, if_statement; 25, for_statement; 26, comment:# For passes that we are before, we may need to; 27, comment:# preemptively add them to the list early; 28, for_statement; 29, identifier:toposort_flatten; 30, argument_list; 31, identifier:set; 32, argument_list; 33, assignment; 34, comparison_operator:opt not in pass_deps; 35, block; 36, identifier:after_pass; 37, identifier:after; 38, block; 39, identifier:other; 40, identifier:before; 41, block; 42, identifier:pass_deps; 43, identifier:passes; 44, pattern_list; 45, subscript; 46, identifier:opt; 47, identifier:pass_deps; 48, expression_statement; 49, expression_statement; 50, if_statement; 51, if_statement; 52, expression_statement; 53, identifier:_; 54, identifier:before; 55, identifier:after; 56, attribute; 57, identifier:opt; 58, assignment; 59, call; 60, comparison_operator:other not in passes; 61, block; 62, comparison_operator:other not in pass_deps; 63, block; 64, call; 65, identifier:self; 66, identifier:_known_passes; 67, subscript; 68, call; 69, attribute; 70, argument_list; 71, identifier:other; 72, identifier:passes; 73, continue_statement; 74, identifier:other; 75, identifier:pass_deps; 76, expression_statement; 77, attribute; 78, argument_list; 79, identifier:pass_deps; 80, identifier:opt; 81, identifier:set; 82, argument_list; 83, subscript; 84, identifier:add; 85, identifier:after_pass; 86, assignment; 87, subscript; 88, identifier:add; 89, identifier:opt; 90, identifier:pass_deps; 91, identifier:opt; 92, subscript; 93, call; 94, identifier:pass_deps; 95, identifier:other; 96, identifier:pass_deps; 97, identifier:other; 98, identifier:set; 99, argument_list
code: def _order_pases(self, passes):
          """Topologically sort optimization passes.
  
          This ensures that the resulting passes are run in order
          respecting before/after constraints.
  
          Args:
              passes (iterable): An iterable of pass names that should
                  be included in the optimization passes run.
          """
  
          passes = set(passes)
  
          pass_deps = {}
  
          for opt in passes:
              _, before, after = self._known_passes[opt]
  
              if opt not in pass_deps:
                  pass_deps[opt] = set()
  
              for after_pass in after:
                  pass_deps[opt].add(after_pass)
  
              # For passes that we are before, we may need to
              # preemptively add them to the list early
              for other in before:
                  if other not in passes:
                      continue
  
                  if other not in pass_deps:
                      pass_deps[other] = set()
  
                  pass_deps[other].add(opt)
  
          return toposort_flatten(pass_deps)