A system capable of compiling a source program that comprises a plurality of source operations and one or more loops and/or branches, thereby defining a non-linear sequence of execution of the source operations; wherein the system comprises: a dispatcher configured to step through the sequence including looping through the loops and/or branching at the branches, and to map each source operation to a respective function call each time encountered during the stepping through of the sequence; a trace buffer ; an interceptor configured to intercept the function calls from the dispatcher , convert each into a corresponding trace entry comprising a set of one or more trace operations, and insert the trace entries one after another into the trace buffer to thereby form a linear trace of the source program ; and a trace manager configured to transfer each of a succession of trace instances from the trace buffer to at least one compiler for compilation into corresponding compiled code, each trace instance comprising a current instance of the trace in the trace buffer or a portion thereof, the trace manager being arranged to receive back the compiled code compiled from each trace instance by the at least one compiler , and send the compiled code to at least one destination device to be executed; wherein the trace manager is configured to, for at least a first of the trace instances, collect statistics on at least one of: i) a compilation time of the compilation of the first one or more trace instances, ii) an execution time of the corresponding compiled code, iii) a frequency of repetition of one or more trace instances, iv) a memory utilization of the corresponding compiled code, and/or v) a device health of the destination device used to run the corresponding compiled code; and, based on said statistics, select which of multiple compilers to use as the at least one compiler to which at least a second of the trace instances is transferred for compilation of the at least one second trace instance by the selected compiler . a dispatcher configured to step through the sequence including looping through the loops and/or branching at the branches, and to map each source operation to a respective function call each time encountered during the stepping through of the sequence; a trace buffer ; an interceptor configured to intercept the function calls from the dispatcher , convert each into a corresponding trace entry comprising a set of one or more trace operations, and insert the trace entries one after another into the trace buffer to thereby form a linear trace of the source program ; and a trace manager configured to transfer each of a succession of trace instances from the trace buffer to at least one compiler for compilation into corresponding compiled code, each trace instance comprising a current instance of the trace in the trace buffer or a portion thereof, the trace manager being arranged to receive back the compiled code compiled from each trace instance by the at least one compiler , and send the compiled code to at least one destination device to be executed; wherein the trace manager is configured to, for at least a first of the trace instances, collect statistics on at least one of: i) a compilation time of the compilation of the first one or more trace instances, ii) an execution time of the corresponding compiled code, iii) a frequency of repetition of one or more trace instances, iv) a memory utilization of the corresponding compiled code, and/or v) a device health of the destination device used to run the corresponding compiled code; and, based on said statistics, select which of multiple compilers to use as the at least one compiler to which at least a second of the trace instances is transferred for compilation of the at least one second trace instance by the selected compiler . <EOS>