Control-flow analysis discovers the flow of control within code by building basic blocks and a control-flow graph (CFG). It identifies loops by computing dominators. Basic blocks are sequences of straight-line code with a single entry and exit. A CFG represents control flow with nodes for basic blocks and edges for control transfers. Loops are detected by finding natural loops defined by back edges where the target dominates the source.