簡體   English   中英

阻止clang擴展聚合類型的參數?

[英]Prevent clang from expanding arguments that are aggregate types?

我正在使用clang為一些C代碼吐出優化的LLVM IR,我遇到了麻煩。 我假設,如果我只傳遞函數一次鏗鏘一聲(聲明必要的依賴項),結果LLVM例程的函數簽名將與我傳入的函數一致(即相同的數量)具有相同類型的參數)。 這在大多數情況下都有效,除了聚合類型的情況。 例如:

以下C代碼

struct A {
    double x;
    int y;
};

int f(struct A a) {
    return a.y;
}

結果在以下LLVM中

; Function Attrs: nounwind readnone uwtable
define i32 @f(double %a.coerce0, i32 %a.coerce1) #0 {
entry:
  ret i32 %a.coerce1
}

結構已經擴展為連續的參數,因此函數現在看起來接受兩個參數而不是一個。 有沒有辦法防止這種擴張? 即使它是某種向前聲明結構的方式,以便clang不會知道它的組成字段以擴展它?

謝謝您的幫助!

此行為由AMD64 ABI (x86 64位體系結構的應用程序二進制接口)指定。 它在ABI中指定,以便不同編譯器編譯的函數可以互操作。 出於同樣的原因,它不能在不違反ABI的情況下進行更改,這意味着該函數的所有客戶端都需要知道如何調用它。

ABI要求在以下情況下以這種方式拆分聚合對象:

  • 聚合對象的大小不超過16個字節

  • 在C ++的情況下,聚合對象是“POD”(普通舊數據)。

否則,參數將通過地址傳遞(盡管仍需要復制)。

因此,您可以通過使類型更大來抵消聚合類型的分解,但對於使用該類型的每個翻譯單元必須是可見的。

您也可以通過void *傳遞內容並將內存轉換為您想要的結構,但更好的問題是為什么您要避免讓前端執行一些基於類型的降低它需要執行的操作(ABI答案)以上)。 FWIW我們也可以在后端執行此操作,但它需要前端類型信息才能正確執行降低,並且對於llvm和clang來說是一個很大的變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM