¿Cómo puedo generar una estructura de valores de retorno en LLVM IR que son compatibles con el C?

Con mi LLVM-juguete basado en el compilador, quiero compilar el equivalente de este código C:

struct a { long a[4]; };
struct b { long b[2]; };
struct a doStuff(struct b);

struct a myFunction(struct b v) {
  return doStuff(v);
}

Mientras que myFunction está escrito en mi juguete lenguaje de programación, doStuff es una función de C y la función de llamadas de myFunction también está escrito en C.

Por el momento, el compilador genera el código siguiente:

define { [4 x i64] } @myFunction({ [2 x i64] } %%0) {
entry:
  %%arg = alloca { [2 x i64] }
  store { [2 x i64] } %%0, { [2 x i64] }* %%arg
  %%arg1 = load { [2 x i64] }, { [2 x i64] }* %%arg
  %%call_to_doStuff = call { [2 x i64] } @doStuff({ [2 x i64] } %%arg1)
  ret { [4 x i64] } %%call_to_doStuff
}

Este código tiene éxito en llamar a doStuff, pero luego segfaults porque doStuffs argumento b sólo contiene la basura.

Cuando yo uso sonar a traducir el sobre C de traducción de myFunction, puedo ver que está utilizando una convención de llamada diferente y sret:

%%struct.a = type { [4 x i64] }
%%struct.b = type { [2 x i64] }

; Function Attrs: noinline nounwind optnone uwtable
define dso_local void @myFunction(%%struct.a* noalias sret %%0, i64 %%1, i64 %%2) #0 {
  %%4 = alloca %%struct.b, align 8
  %%5 = bitcast %%struct.b* %%4 to { i64, i64 }*
  %%6 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%5, i32 0, i32 0
  store i64 %%1, i64* %%6, align 8
  %%7 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%5, i32 0, i32 1
  store i64 %%2, i64* %%7, align 8
  %%8 = bitcast %%struct.b* %%4 to { i64, i64 }*
  %%9 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%8, i32 0, i32 0
  %%10 = load i64, i64* %%9, align 8
  %%11 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %%8, i32 0, i32 1
  %%12 = load i64, i64* %%11, align 8
  call void @doStuff(%%struct.a* sret %%0, i64 %%10, i64 %%12)
  ret void
}

declare dso_local void @doStuff(%%struct.a* sret, i64, i64) #1

Estoy en lo cierto en que mi problema está relacionado con la forma en que estructuras son devueltos? Y ¿cómo podría cambiar mi IR generador de emitir adecuada sret basado en el código? Hay un Pase para que?

(Estoy dirigidos a Linux x86_64.)

0
2019-09-19 13:46:33
fuente
0 respuestas

Vea otras preguntas sobre etiquetas