docs: def remove_cycles(self):
          """
          Forces graph to become acyclic, removes all loop back edges and edges between overlapped loop headers and their
          successors.
          """
          # loop detection
          # only detect loops after potential graph normalization
          if not self._loop_back_edges:
              l.debug("Detecting loops...")
              self._detect_loops()
  
          l.debug("Removing cycles...")
          l.debug("There are %d loop back edges.", len(self._loop_back_edges))
          l.debug("And there are %d overlapping loop headers.", len(self._overlapped_loop_headers))
          # First break all detected loops
          for b1, b2 in self._loop_back_edges:
              if self._graph.has_edge(b1, b2):
                  l.debug("Removing loop back edge %s -> %s", b1, b2)
                  self._graph.remove_edge(b1, b2)
          # Then remove all outedges from overlapped loop headers
          for b in self._overlapped_loop_headers:
              successors = self._graph.successors(b)
              for succ in successors:
                  self._graph.remove_edge(b, succ)
                  l.debug("Removing partial loop header edge %s -> %s", b, succ)