parameters: (self, nodes)
docstring: Visit a list of statements in the Python AST
docstring_summary: Visit a list of statements in the Python AST
docstring_tokens: Visit a list of statements in the Python AST
function: def visit_body(self, nodes):
      """Visit a list of statements in the Python AST"""
  
      if len(nodes) == 0: # create a dummy statement node
        return tvm.make.Evaluate(1)
      else:
        first = nodes[0]
        rest = nodes[1:]
        has_rest = len(rest) > 0
        if (isinstance(first, ast.For) or isinstance(first, ast.If)): # imperative code block
          ir_first = self.visit(first)
          if has_rest:
            ir_rest = self.visit_body(rest)
            return tvm.make.Block(ir_first, ir_rest)
          else:
            return ir_first
        elif isinstance(first, ast.Assign):
          targets = first.targets
          value = first.value
          if isinstance(value, ast.Call):
            types = self.check_call_type(value)
            if len(types) == 2 and types[0] == "tvm": # tvm functions
              if types[1] == "compute":
                assert len(targets) == 1, "tvm.compute only has one output, instead of " + str(len(targets))
                ir = self.visit(first)
                if has_rest:
                  ir = tvm.make.Block(ir, self.visit_body(rest))
                name = targets[0].id
                if name in self.arg_list:
                  return ir
                else:
                  buffer = self.get_buffer(name)
                  assert buffer, "Internal Error: Undeclared buffer " + name
                  return tvm.make.Allocate(buffer['buffer'].data, buffer['tensor'].dtype, \
                      buffer['shape'], self.true, ir)
              elif types[1] == "placeholder":
                assert len(targets) == 1, "tvm.placeholder only has one output, instead of " + str(len(targets))
                if has_rest:
                  self.visit(first)
                  name = targets[0].id
                  buffer = self.get_buffer(name)
                  if name in self.arg_list:
                    return self.visit_body(rest)
                  else:
                    assert buffer, "Internal Error: Undeclared buffer " + name
                    return tvm.make.Allocate(buffer['buffer'].data, buffer['tensor'].dtype, \
                        buffer['shape'], self.true, self.visit_body(rest))
                else: # last statement in the body, useless tvm.placeholder
                  return tvm.make.Evaluate(1)
              else: # tvm.var  must be in arg_list
                assert len(targets) == 1, "tvm.var only has one output, instead of " + str(len(targets))
                if has_rest:
                  self.visit(first)
                  return self.visit_body(rest)
                else: # last statement in the body, useless tvm.var
                  return tvm.make.Evaluate(1)
            else: # other function calls
              ir_first = self.visit(value)
              if has_rest:
                ir_rest = self.visit_body(rest)
                return tvm.make.Block(ir_first, ir_rest)
              else:
                return ir_first
          else:
            # intermediate variable
            ir = self.visit(first)
            target, name, _type = self.get_target(targets[0])
            assert target, "Undeclared variable: " + name
            if _type == 'name':
              target['count'] += 1
            if has_rest:
              ir_rest = self.visit_body(rest)
              ir = tvm.make.Block(ir, ir_rest)
            if _type == 'name':
              if target['allocated'] == True:
                return ir
              else:
                target['count'] -= 1
                if target['count'] == 0:
                  target['allocated'] == True
                  return tvm.make.Allocate(target['var'], target['var'].dtype, [1], self.true, ir)
                else:
                  return ir
            else:
              return ir
        elif isinstance(first, ast.Call) or isinstance(first, ast.Expr):
          ir = self.visit(first)
          if isinstance(ir, tuple): # ignore return value
            ir = ir[0]
          if has_rest:
            ir_rest = self.visit_body(rest)
            return tvm.make.Block(ir, ir_rest)
          else:
            return ir
        else:
          # Not yet supported AST nodes: ClassDef, FunctionDef, Return, Print, While, With, Assert
          return self.visit_body(rest)
function_tokens: def visit_body ( self , nodes ) : if len ( nodes ) == 0 : # create a dummy statement node return tvm . make . Evaluate ( 1 ) else : first = nodes [ 0 ] rest = nodes [ 1 : ] has_rest = len ( rest ) > 0 if ( isinstance ( first , ast . For ) or isinstance ( first , ast . If ) ) : # imperative code block ir_first = self . visit ( first ) if has_rest : ir_rest = self . visit_body ( rest ) return tvm . make . Block ( ir_first , ir_rest ) else : return ir_first elif isinstance ( first , ast . Assign ) : targets = first . targets value = first . value if isinstance ( value , ast . Call ) : types = self . check_call_type ( value ) if len ( types ) == 2 and types [ 0 ] == "tvm" : # tvm functions if types [ 1 ] == "compute" : assert len ( targets ) == 1 , "tvm.compute only has one output, instead of " + str ( len ( targets ) ) ir = self . visit ( first ) if has_rest : ir = tvm . make . Block ( ir , self . visit_body ( rest ) ) name = targets [ 0 ] . id if name in self . arg_list : return ir else : buffer = self . get_buffer ( name ) assert buffer , "Internal Error: Undeclared buffer " + name return tvm . make . Allocate ( buffer [ 'buffer' ] . data , buffer [ 'tensor' ] . dtype , buffer [ 'shape' ] , self . true , ir ) elif types [ 1 ] == "placeholder" : assert len ( targets ) == 1 , "tvm.placeholder only has one output, instead of " + str ( len ( targets ) ) if has_rest : self . visit ( first ) name = targets [ 0 ] . id buffer = self . get_buffer ( name ) if name in self . arg_list : return self . visit_body ( rest ) else : assert buffer , "Internal Error: Undeclared buffer " + name return tvm . make . Allocate ( buffer [ 'buffer' ] . data , buffer [ 'tensor' ] . dtype , buffer [ 'shape' ] , self . true , self . visit_body ( rest ) ) else : # last statement in the body, useless tvm.placeholder return tvm . make . Evaluate ( 1 ) else : # tvm.var  must be in arg_list assert len ( targets ) == 1 , "tvm.var only has one output, instead of " + str ( len ( targets ) ) if has_rest : self . visit ( first ) return self . visit_body ( rest ) else : # last statement in the body, useless tvm.var return tvm . make . Evaluate ( 1 ) else : # other function calls ir_first = self . visit ( value ) if has_rest : ir_rest = self . visit_body ( rest ) return tvm . make . Block ( ir_first , ir_rest ) else : return ir_first else : # intermediate variable ir = self . visit ( first ) target , name , _type = self . get_target ( targets [ 0 ] ) assert target , "Undeclared variable: " + name if _type == 'name' : target [ 'count' ] += 1 if has_rest : ir_rest = self . visit_body ( rest ) ir = tvm . make . Block ( ir , ir_rest ) if _type == 'name' : if target [ 'allocated' ] == True : return ir else : target [ 'count' ] -= 1 if target [ 'count' ] == 0 : target [ 'allocated' ] == True return tvm . make . Allocate ( target [ 'var' ] , target [ 'var' ] . dtype , [ 1 ] , self . true , ir ) else : return ir else : return ir elif isinstance ( first , ast . Call ) or isinstance ( first , ast . Expr ) : ir = self . visit ( first ) if isinstance ( ir , tuple ) : # ignore return value ir = ir [ 0 ] if has_rest : ir_rest = self . visit_body ( rest ) return tvm . make . Block ( ir , ir_rest ) else : return ir else : # Not yet supported AST nodes: ClassDef, FunctionDef, Return, Print, While, With, Assert return self . visit_body ( rest )