  This paper presents reverse-mode algorithmic differentiation (AD) based on
source code transformation, in particular of the Static Single Assignment (SSA)
form used by modern compilers. The approach can support control flow, nesting,
mutation, recursion, data structures, higher-order functions, and other
language constructs, and the output is given to an existing compiler to produce
highly efficient differentiated code. Our implementation is a new AD tool for
the Julia language, called Zygote, which presents high-level dynamic semantics
while transparently compiling adjoint code under the hood. We discuss the
benefits of this approach to both the usability and performance of AD tools.
