def _find_defs_violators(blocks, cfg):
    """
    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    """
    defs = defaultdict(list)
    uses = defaultdict(set)
    states = dict(defs=defs, uses=uses)
    _run_block_analysis(blocks, states, _GatherDefsHandler())
    _logger.debug("defs %s", _lazy_pformat(defs))
    # Gather violators by number of definitions.
    # The violators are added by the order that they are seen and the algorithm
    # scan from the first to the last basic-block as they occur in bytecode.
    violators = OrderedSet([k for k, vs in defs.items() if len(vs) > 1])
    # Gather violators by uses not dominated by the one def
    doms = cfg.dominators()
    for k, use_blocks in uses.items():
        if k not in violators:
            for label in use_blocks:
                dom = doms[label]
                def_labels = {label for _assign, label in defs[k] }
                if not def_labels.intersection(dom):
                    violators.add(k)
                    break
    _logger.debug("SSA violators %s", _lazy_pformat(violators))
    return violators

    Returns
    -------
    res : Set[str]
        The SSA violators in a dictionary of variable names.
    
numba/core/ssa.py