def METHOD_NAME(filename):
    funcs = {}
    with open(filename, "r", encoding="utf8") as fh:
        for line in fh:
            #                  %time      cumesec   selfsec     calls     {stuff}   name
            match = re.match(
                r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
                line)
            if match:
                pct = float(match.group(1))
                sec = float(match.group(2))
                calls = float(match.group(3))
                func = match.group(4)
                if func not in funcs:
                    funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0}
                funcs[func]['pct'] += pct
                funcs[func]['sec'] += sec
                funcs[func]['calls'] += calls
                continue
            # Older gprofs have no call column for single-call functions
            #                  %time      cumesec   selfsec      {stuff}   name
            match = re.match(
                r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
                line)
            if match:
                pct = float(match.group(1))
                sec = float(match.group(2))
                calls = 1
                func = match.group(3)
                if func not in funcs:
                    funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0}
                funcs[func]['pct'] += pct
                funcs[func]['sec'] += sec
                funcs[func]['calls'] += calls
                continue
    # Find modules
    verilated_mods = {}
    for func in funcs:
        match = re.search(r'(.*)::eval(_step)?\(', func)
        if match:
            prefix = match.group(1)
            if Args.debug:
                print("-got _eval %s   prefix=%s" % (func, prefix))
            verilated_mods[prefix] = re.compile(r'^' + prefix)
    # pprint(verilated_mods)
    # Sort by Verilog name
    vfuncs = {}
    groups = {}
    groups['type'] = collections.defaultdict(lambda: 0)
    groups['design'] = collections.defaultdict(lambda: 0)
    groups['module'] = collections.defaultdict(lambda: 0)
    for func, func_item in funcs.items():
        pct = func_item['pct']
        vfunc = func
        funcarg = re.sub(r'^.*\(', '', func)
        design = None
        for vde, vde_item in verilated_mods.items():
            if vde_item.match(func) or vde_item.match(funcarg):
                design = vde
                break
        vdesign = "-"
        prof_match = re.search(r'__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(', vfunc)
        if design and prof_match:
            linefunc = prof_match.group(1)
            lineno = int(prof_match.group(2))
            vfunc = "VBlock    %s:%d" % (linefunc, lineno)
            vdesign = design
            groups['type']["Verilog Blocks under " + design] += pct
            groups['design'][design] += pct
            groups['module'][linefunc] += pct
        elif design:
            vfunc = "VCommon   " + func
            vdesign = design
            groups['type']["Common code under " + design] += pct
            groups['design'][design] += pct
            groups['module'][design + " common code"] += pct
        elif re.match(r'(VL_[A-Z0-9_]+|_?vl_[a-zA-Z0-9_]+|Verilated)', vfunc):
            vfunc = "VLib      " + func
            groups['type']['VLib'] += pct
            groups['design']['VLib'] += pct
            groups['module']['VLib'] += pct
        elif re.match(r'^_mcount_private', vfunc):
            vfunc = "Prof      " + func
            groups['type']['Prof'] += pct
            groups['design']['Prof'] += pct
            groups['module']['Prof'] += pct
        else:
            vfunc = "C++       " + func
            groups['type']['C++'] += pct
            groups['design']['C++'] += pct
            groups['module']['C++'] += pct
        if vfunc not in vfuncs:
            vfuncs[vfunc] = func_item
            vfuncs[vfunc]['design'] = vdesign
        else:
            vfuncs[vfunc]['pct'] += func_item['pct']
            vfuncs[vfunc]['calls'] += func_item['calls']
            vfuncs[vfunc]['sec'] += func_item['sec']
    for ftype in ['type', 'design', 'module']:
        missing = 100
        for item in groups[ftype].keys():
            missing -= groups[ftype][item]
        groups[ftype]["\377Unaccounted for/rounding error"] = missing
        print("Overall summary by %s:" % ftype)
        print("  %-6s  %s" % ("% time", ftype))
        for what in sorted(groups[ftype].keys()):
            # \377 used to establish sort order
            pwhat = re.sub(r'^\377', '', what)
            print("  %6.2f  %s" % (groups[ftype][what], pwhat))
        print()
    design_width = 1
    for func, func_item in vfuncs.items():
        if design_width < len(func_item['design']):
            design_width = len(func_item['design'])
    print("Verilog code profile:")
    print("   These are split into three categories:")
    print("      C++:     Time in non-Verilated C++ code")
    print("      Prof:    Time in profile overhead")
    print("      VBlock:  Time attributable to a block in a" +
          " Verilog file and line")
    print("      VCommon: Time in a Verilated module," +
          " due to all parts of the design")
    print("      VLib:    Time in Verilated common libraries," +
          " called by the Verilated code")
    print()
    print("  %   cumulative   self              ")
    print((" time   seconds   seconds      calls   %-" + str(design_width) +
           "s  type      filename and line number") % "design")
    cume = 0
    for func in sorted(vfuncs.keys(),
                       key=lambda f: vfuncs[f]['sec'],
                       reverse=True):
        cume += vfuncs[func]['sec']
        print(("%6.2f %9.2f %8.2f %10d   %-" + str(design_width) + "s  %s") %
              (vfuncs[func]['pct'], cume, vfuncs[func]['sec'],
               vfuncs[func]['calls'], vfuncs[func]['design'], func))