2013-04-24 2 views
0

У меня есть C код, как это:Как я могу понять, когда LLVM изменил подпись функции

typedef struct { 
    int a1; 
    double a2; 
} str3; 
... 
extern void someVoidFunc(int a); 
extern str3 someStrFunc(int b); 
int main() { 
    someVoidFunc(0); 
    someStrFunc(0); 
    return 0; 
} 

В LLVM represatation это выглядит как:

%struct.str3 = type { i32, double} 
... 
call void @someVoidFunc(i32 0) 
call void @someStrFunc(%struct.str3* sret %tmp, i32 0) 
... 

Так, я не понял, почему llvm изменить подпись, и как я могу понять, какой тип действительно возвращает функцию?

+0

Я предполагаю, что это способ 'llvm' (' clang'?) Реализовать [оптимизацию возвращаемого значения] (http://en.wikipedia.org/wiki/Return_value_optimization) – Collin

+0

Я скомпилирую C-файл (в bitecode) с опцией -O0 (да, через clang) – alex

+0

Я думаю, вам придется копать, хотя код Клана, чтобы понять это наверняка, но может быть, что возвращение типы классов таким образом настолько фундаментальны, что комманды clang компилируют, что даже '-O0' не отключит его – Collin

ответ

2

Структуры, переданные по значению функциям и возвращаемые значением, являются сложным. Они сложны, потому что им требуются очень конкретные правила о том, как компилятор переводит их на сборку (платформа ABI). В то время как LLVM пытается оставаться независимой от платформы, C очень сильно зависит от платформы в этом отношении, и поэтому Clang выполняет ABI-специфическое понижение структур, переданных значениями и структурами, возвращаемыми значением, так что последующий LLVM IR->только работает.

TL; Вы выбрали очень неприятный уголок для изучения. Если вы действительно заботитесь о таких сигнатурах функций, тогда начните с просмотра AMD64 ABI (или ARM ABI), рассматривающего правила передачи структур через регистры. Если вам действительно не нравятся эти конкретные случаи использования, то найдите более простые примеры для игры.

0

Итак, как сказал @Collin это RVO. Мы можем понять, когда llvm изменил подпись на функцию по атрибуту sret. В коде мы можем обнаружить это с помощью метода hasStructRetAttr

+0

Это не RVO. RVO - совершенно другая вещь из мира C++. Эли здесь прав. –

Смежные вопросы