'run array shape analysis on the IR and save information in
array_shape_classes, class_sizes, and array_size_vars (see __init__
comments). May generate some array shape calls if necessary.'

def run(self):

    dprint_func_ir(self.func_ir, 'starting    array    analysis')
    if (config.DEBUG_ARRAY_OPT == 1):
        print('variable    types:    ', sorted(self.typemap.items()))
        print('call    types:    ', self.calltypes)
    topo_order = find_topo_order(self.func_ir.blocks)
    for label in topo_order:
        self._analyze_block(self.func_ir.blocks[label])
    self._merge_equivalent_classes()
    self._cleanup_analysis_data()
    if (config.DEBUG_ARRAY_OPT == 1):
        self.dump()
