Wie erstelle ich eine Struktur, die Werte zurückgeben, die in LLVM IR sind kompatibel mit C?

Mit meinem LLVM-basierte Spielzeug-compiler, will ich kompilieren Sie das entsprechende C-code:

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

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

Während myFunction ist geschrieben in meinem Spielzeug-Programmiersprache, doStuff ist eine C-Funktion und in der aufrufenden Funktion "myFunction " ist auch in C geschrieben.

Im moment, mein compiler generiert den folgenden code:

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
}

Mit diesem code gelingt es im Aufruf doStuff, aber dann segfaults, weil doStuffs argument b enthält nur Müll.

Wenn ich mit clang übersetzen die oben genannten C übersetzung von myFunction, kann ich sehen, dass es mit einem anderen Aufruf-Konvention und 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

Gehe ich Recht in der, dass mein problem bezieht sich auf die Art und Weise structs zurückgegeben werden? Und wie könnte ich meinen IR-generator zu emittieren ordnungsgemäße sret-code? Ist es ein Pass für, die?

(Ich bin welche auf Linux auf x86_64.)

0
2019-09-19 13:46:33
Quelle
0 Antworten

Sehen Sie sich andere Fragen zu Tags an