Архитектура компилятора
Компилятор не генерирует код непосредственно из источника, он сначала компилирует его в промежуточную форму (см. интерфейс компилятора ), а затем генерирует код из промежуточной формы, включая любые оптимизации (см. серверная часть компилятора ).
Запуск процесса компиляции Visual Studio
В компиляторе сборки Visual Studio процесс (cl.exe) выполняется для компиляции нескольких исходных файлов с одинаковыми параметрами командной строки в одной команде. Компилятор сначала выполняет «компиляцию» последовательно для каждого файла (это, скорее всего, внешний интерфейс), но «Генерация кода» (возможно, внутренний) выполняется вместе для всех файлов после того, как с ними выполнена компиляция.
В этом можно убедиться, просмотрев файл cl.exe в Process Explorer.
Почему генерация кода для нескольких файлов одновременно
Я предполагаю, что генерация кода выполняется для нескольких файлов одновременно, чтобы ускорить процесс сборки, поскольку она включает в себя некоторые вещи, которые могут быть выполнены только один раз для нескольких источников, например, создание экземпляров шаблонов - для них нет смысла создавать экземпляры несколько раз, так как все экземпляры, кроме одного, будут отброшены в любом случае.
Оптимизация всей программы
Теоретически на этом этапе можно было бы выполнить некоторую оптимизацию для модуля кросс-компиляции, но это не сделано - такая оптимизация никогда не выполняется, если она не включена с / LTCG, а с LTCG генерация всего кода сделано для всей программы сразу (отсюда и название оптимизации всей программы).
Примечание: кажется, что WPO выполняется компоновщиком, поскольку он создает exe из файлов obj, но это своего рода иллюзия - файлы obj не являются реальными объектными файлами, они содержат промежуточное представление, а «компоновщик» не является реальным компоновщиком, поскольку он не только связывает существующий код, но и генерирует и оптимизирует код.