Aquí hay un archivo C simple con una definición de enumeración y una mainfunción:
enum days {MON, TUE, WED, THU};
int main() {
enum days d;
d = WED;
return 0;
}
Se transmite al siguiente LLVM IR:
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 0, i32* %1, align 4
store i32 2, i32* %2, align 4
ret i32 0
}
%2evidentemente es la dvariable, a la que se le asignan 2. ¿A qué %1corresponde si se devuelve cero directamente?
c
llvm
llvm-codegen
macleginn
fuente
fuente

clang-9 -S -emit-llvm simple.cmain( godbolt.org/z/kEtS-s ). El enlace muestra cómo se asigna el ensamblado a la fuentemain, la misteriosa variable adicional desaparece. Curiosamente, también desaparece si omite lareturndeclaración por completo (que es legalmainen C y equivalente areturn 0;).mainloint main(int argc, char **argv)que vesargcy loargvcopias en la pila, pero la misteriosa variable cero sigue ahí además de ellas.Respuestas:
Este
%1registro fue generado por clang para manejar múltiples declaraciones de retorno en una función . Imagine que tiene una función para calcular el factorial de un entero. En lugar de escribirlo asíProbablemente harías esto
¿Por qué? Porque Clang insertará esa
resultvariable que contiene el valor de retorno para usted. Hurra. Ese es el propósito exacto de eso%1. Mire el ir para una versión ligeramente modificada de su código.Código modificado,
IR
Ahora lo ves
%1haciéndose útil, ¿eh? Como los otros han señalado, para las funciones con una sola declaración de retorno, esta variable probablemente será eliminada por uno de los pasos de optimización de llvm.fuente
¿Por qué importa esto? ¿Cuál es el problema real?
Creo que la respuesta más profunda que está buscando podría ser: la arquitectura de LLVM se basa en interfaces bastante simples y muchos pases. Las interfaces tienen que generar el código correcto, pero no tiene que ser un buen código. Pueden hacer lo más simple que funciona.
En este caso, Clang genera un par de instrucciones que resultan no ser utilizadas para nada. Eso generalmente no es un problema, porque alguna parte de LLVM eliminará las instrucciones superfluas. Clang confía en que eso suceda. Clang no necesita evitar emitir código muerto; su implementación puede centrarse en la corrección, simplicidad, comprobabilidad, etc.
fuente
Porque Clang se hace con análisis de sintaxis, pero LLVM ni siquiera ha comenzado con la optimización.
El front-end de Clang ha generado IR (representación intermedia) y no código de máquina. Esas variables son SSA (Asignaciones estáticas individuales); aún no están vinculados a registros y, en realidad, después de la optimización, nunca lo serán porque son redundantes.
Ese código es una representación algo literal de la fuente. Es lo que golpea a LLVM para su optimización. Básicamente, LLVM comienza con eso y se optimiza a partir de ahí. De hecho, para la versión 10 y x86_64, llc -O2 eventualmente generará:
fuente