1. A method for inserting synchronization points in a software program, comprising: identifying a post-dominate first node of a control flow graph that represents the software program, wherein every path from a second node of the control flow graph passes through the post-dominate first node, wherein the post-dominate first node is a post-tail node of a loop and the second node is a pre-header node of the loop; inserting a push synchronization instruction into the second node to push a synchronization token onto a stack during execution of the software program; inserting a pop synchronization instruction into the post-dominate first node to create a first synchronization point in the software program where divergent execution threads in a thread group wait for one or more clock cycles, wherein the pop synchronization instruction causes the synchronization token to be popped from the stack during execution of the software program after all execution threads in the thread group have reached the post-dominate first node and are synchronized; inserting a push synchronization instruction into a third node within the loop that includes a conditional branch; inserting a pop synchronization instruction into a fourth node within the loop that merges the conditional branch to create a second synchronization point for the conditional branch; identifying a run away path that does not pass through the second synchronization point and connects a fifth node to a sixth node that are each within the loop; inserting a push break instruction that specifies an address of the sixth node into a seventh node that is a loop head of the loop; replacing a branch that corresponds to an edge into the sixth node with a break to the sixth node; and inserting a pop synchronization instruction in the sixth node to create a third synchronization point in the software program that synchronizes any threads taking the run away path with other threads in the thread group.