История изменений
Исправление SkyMaverick, (текущая версия) :
Кстати, разве у gcc когда-то был публичный промежуточный IR? Именно оформленный в стабильный язык как у LLVM, а не какие-то внутренние структуры.
Можно запустить gcc с ключом -fdump-tree-all-raw
и смотреть.
Вот, например, под катом простая программа (ну, первая, которая у меня в екзамплах валяется) и её IR (просто компиляция, без опций)
Код:
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
int
main()
{
int sock;
struct sockaddr_in *in_addr;
struct ifreq ifdata;
struct if_nameindex *ifNameIndex;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
return 1;
}
ifNameIndex = if_nameindex();
if (ifNameIndex) {
while (ifNameIndex->if_index) {
memset(&ifdata, 0, sizeof(ifdata));
strncpy(ifdata.ifr_name, ifNameIndex->if_name,
IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifdata.ifr_name,
strerror(errno));
//close(sock);
//return 1;
}
sockaddr_in
in_addr = (struct sockaddr_in *)&ifdata.ifr_addr;
printf("Интерфейс %s индекс %i IP адрес: %s\n", ifdata.ifr_name, ifNameIndex->if_index,
inet_ntoa(in_addr->sin_addr));
++ifNameIndex;
}
}
close(sock);
return 0;
}
GIMPLE, который низкоуровневый, но так-то и высокоуровневый есть
int main ()
{
struct if_nameindex * ifNameIndex;
struct ifreq ifdata;
struct sockaddr_in * in_addr;
int sock;
int D.3194;
gimple_try <GIMPLE_TRY_FINALLY,
EVAL <
gimple_call <socket, sock, 2, 2, 0>
gimple_cond <lt_expr, sock, 0, <D.3192>, <D.3193>>
gimple_label <<D.3192>>
gimple_call <__errno_location, _1>
gimple_assign <mem_ref, _2, *_1, NULL, NULL>
gimple_call <strerror, _3, _2>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x81\xd0\xbe\xd0\xba\xd0\xb5\xd1\x82, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", _3>
gimple_assign <integer_cst, D.3194, 1, NULL, NULL>
// predicted unlikely by early return (on trees) predictor.
gimple_goto <<D.3199>>
gimple_label <<D.3193>>
gimple_call <if_nameindex, ifNameIndex>
gimple_cond <ne_expr, ifNameIndex, 0B, <D.3195>, <D.3196>>
gimple_label <<D.3195>>
gimple_goto <<D.3189>>
gimple_label <<D.3190>>
gimple_call <memset, NULL, &ifdata, 0, 40>
gimple_assign <component_ref, _4, ifNameIndex->if_name, NULL, NULL>
gimple_call <strncpy, NULL, &ifdata.ifr_ifrn.ifrn_name, _4, 16>
gimple_call <ioctl, _5, sock, 35093, &ifdata>
gimple_cond <lt_expr, _5, 0, <D.3197>, <D.3198>>
gimple_label <<D.3197>>
gimple_call <__errno_location, _6>
gimple_assign <mem_ref, _7, *_6, NULL, NULL>
gimple_call <strerror, _8, _7>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x83\xd1\x87\xd0\xb8\xd1\x82\xd1\x8c IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81 \xd0\xb4\xd0\xbb\xd1\x8f %s, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", &ifdata.ifr_ifrn.ifrn_name, _8>
gimple_label <<D.3198>>
gimple_assign <addr_expr, in_addr, &ifdata.ifr_ifru.ifru_addr, NULL, NULL>
gimple_call <inet_ntoa, _9, in_addr->sin_addr>
gimple_assign <component_ref, _10, ifNameIndex->if_index, NULL, NULL>
gimple_call <printf, NULL, "\xd0\x98\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80\xd1\x84\xd0\xb5\xd0\xb9\xd1\x81 %s \xd0\xb8\xd0\xbd\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd1\x81 %i IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81: %s\n", &ifdata.ifr_ifrn.ifrn_name, _10, _9>
gimple_assign <pointer_plus_expr, ifNameIndex, ifNameIndex, 16, NULL>
gimple_label <<D.3189>>
gimple_assign <component_ref, _11, ifNameIndex->if_index, NULL, NULL>
gimple_cond <ne_expr, _11, 0, <D.3190>, <D.3188>>
gimple_label <<D.3188>>
gimple_label <<D.3196>>
gimple_call <close, NULL, sock>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
>
CLEANUP <
gimple_assign <constructor, ifdata, {CLOBBER}, NULL, NULL>
>
>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
gimple_label <<D.3199>>
gimple_return <D.3194>
}
Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.
Исправление SkyMaverick, :
Кстати, разве у gcc когда-то был публичный промежуточный IR? Именно оформленный в стабильный язык как у LLVM, а не какие-то внутренние структуры.
Можно запустить gcc с ключом -fdump-tree-all-raw
и смотреть.
Вот, например, под катом простая программа (ну, первая, которая у меня в екзамплах валяется) и её IR (просто компиляция, без опций)
Код:
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
int
main()
{
int sock;
struct sockaddr_in *in_addr;
struct ifreq ifdata;
struct if_nameindex *ifNameIndex;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
return 1;
}
ifNameIndex = if_nameindex();
if (ifNameIndex) {
while (ifNameIndex->if_index) {
memset(&ifdata, 0, sizeof(ifdata));
strncpy(ifdata.ifr_name, ifNameIndex->if_name,
IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifdata.ifr_name,
strerror(errno));
//close(sock);
//return 1;
}
sockaddr_in
in_addr = (struct sockaddr_in *)&ifdata.ifr_addr;
printf("Интерфейс %s индкес %i IP адрес: %s\n", ifdata.ifr_name, ifNameIndex->if_index,
inet_ntoa(in_addr->sin_addr));
++ifNameIndex;
}
}
close(sock);
return 0;
}
GIMPLE, который низкоуровневый, но так-то и высокоуровневый есть
int main ()
{
struct if_nameindex * ifNameIndex;
struct ifreq ifdata;
struct sockaddr_in * in_addr;
int sock;
int D.3194;
gimple_try <GIMPLE_TRY_FINALLY,
EVAL <
gimple_call <socket, sock, 2, 2, 0>
gimple_cond <lt_expr, sock, 0, <D.3192>, <D.3193>>
gimple_label <<D.3192>>
gimple_call <__errno_location, _1>
gimple_assign <mem_ref, _2, *_1, NULL, NULL>
gimple_call <strerror, _3, _2>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x81\xd0\xbe\xd0\xba\xd0\xb5\xd1\x82, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", _3>
gimple_assign <integer_cst, D.3194, 1, NULL, NULL>
// predicted unlikely by early return (on trees) predictor.
gimple_goto <<D.3199>>
gimple_label <<D.3193>>
gimple_call <if_nameindex, ifNameIndex>
gimple_cond <ne_expr, ifNameIndex, 0B, <D.3195>, <D.3196>>
gimple_label <<D.3195>>
gimple_goto <<D.3189>>
gimple_label <<D.3190>>
gimple_call <memset, NULL, &ifdata, 0, 40>
gimple_assign <component_ref, _4, ifNameIndex->if_name, NULL, NULL>
gimple_call <strncpy, NULL, &ifdata.ifr_ifrn.ifrn_name, _4, 16>
gimple_call <ioctl, _5, sock, 35093, &ifdata>
gimple_cond <lt_expr, _5, 0, <D.3197>, <D.3198>>
gimple_label <<D.3197>>
gimple_call <__errno_location, _6>
gimple_assign <mem_ref, _7, *_6, NULL, NULL>
gimple_call <strerror, _8, _7>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x83\xd1\x87\xd0\xb8\xd1\x82\xd1\x8c IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81 \xd0\xb4\xd0\xbb\xd1\x8f %s, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", &ifdata.ifr_ifrn.ifrn_name, _8>
gimple_label <<D.3198>>
gimple_assign <addr_expr, in_addr, &ifdata.ifr_ifru.ifru_addr, NULL, NULL>
gimple_call <inet_ntoa, _9, in_addr->sin_addr>
gimple_assign <component_ref, _10, ifNameIndex->if_index, NULL, NULL>
gimple_call <printf, NULL, "\xd0\x98\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80\xd1\x84\xd0\xb5\xd0\xb9\xd1\x81 %s \xd0\xb8\xd0\xbd\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd1\x81 %i IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81: %s\n", &ifdata.ifr_ifrn.ifrn_name, _10, _9>
gimple_assign <pointer_plus_expr, ifNameIndex, ifNameIndex, 16, NULL>
gimple_label <<D.3189>>
gimple_assign <component_ref, _11, ifNameIndex->if_index, NULL, NULL>
gimple_cond <ne_expr, _11, 0, <D.3190>, <D.3188>>
gimple_label <<D.3188>>
gimple_label <<D.3196>>
gimple_call <close, NULL, sock>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
>
CLEANUP <
gimple_assign <constructor, ifdata, {CLOBBER}, NULL, NULL>
>
>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
gimple_label <<D.3199>>
gimple_return <D.3194>
}
Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.
Исправление SkyMaverick, :
Кстати, разве у gcc когда-то был публичный промежуточный IR? Именно оформленный в стабильный язык как у LLVM, а не какие-то внутренние структуры.
Можно запустить gcc с ключом -fdump-tree-all-raw
и смотреть.
Вот, например, под катом простая программа (ну, первая, которая у меня в екзамплах валяется) и её IR (просто компиляция, без опций)
Код:
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
int
main()
{
int sock;
struct sockaddr_in *in_addr;
struct ifreq ifdata;
struct if_nameindex *ifNameIndex;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
return 1;
}
ifNameIndex = if_nameindex();
if (ifNameIndex) {
while (ifNameIndex->if_index) {
memset(&ifdata, 0, sizeof(ifdata));
strncpy(ifdata.ifr_name, ifNameIndex->if_name,
IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifdata.ifr_name,
strerror(errno));
//close(sock);
//return 1;
}
sockaddr_in
in_addr = (struct sockaddr_in *)&ifdata.ifr_addr;
printf("Интерфейс %s индекес %i IP адрес: %s\n", ifdata.ifr_name, ifNameIndex->if_index,
inet_ntoa(in_addr->sin_addr));
++ifNameIndex;
}
}
close(sock);
return 0;
}
GIMPLE, который низкоуровневый, но так-то и высокоуровневый есть
int main ()
{
struct if_nameindex * ifNameIndex;
struct ifreq ifdata;
struct sockaddr_in * in_addr;
int sock;
int D.3194;
gimple_try <GIMPLE_TRY_FINALLY,
EVAL <
gimple_call <socket, sock, 2, 2, 0>
gimple_cond <lt_expr, sock, 0, <D.3192>, <D.3193>>
gimple_label <<D.3192>>
gimple_call <__errno_location, _1>
gimple_assign <mem_ref, _2, *_1, NULL, NULL>
gimple_call <strerror, _3, _2>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x81\xd0\xbe\xd0\xba\xd0\xb5\xd1\x82, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", _3>
gimple_assign <integer_cst, D.3194, 1, NULL, NULL>
// predicted unlikely by early return (on trees) predictor.
gimple_goto <<D.3199>>
gimple_label <<D.3193>>
gimple_call <if_nameindex, ifNameIndex>
gimple_cond <ne_expr, ifNameIndex, 0B, <D.3195>, <D.3196>>
gimple_label <<D.3195>>
gimple_goto <<D.3189>>
gimple_label <<D.3190>>
gimple_call <memset, NULL, &ifdata, 0, 40>
gimple_assign <component_ref, _4, ifNameIndex->if_name, NULL, NULL>
gimple_call <strncpy, NULL, &ifdata.ifr_ifrn.ifrn_name, _4, 16>
gimple_call <ioctl, _5, sock, 35093, &ifdata>
gimple_cond <lt_expr, _5, 0, <D.3197>, <D.3198>>
gimple_label <<D.3197>>
gimple_call <__errno_location, _6>
gimple_assign <mem_ref, _7, *_6, NULL, NULL>
gimple_call <strerror, _8, _7>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x83\xd1\x87\xd0\xb8\xd1\x82\xd1\x8c IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81 \xd0\xb4\xd0\xbb\xd1\x8f %s, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", &ifdata.ifr_ifrn.ifrn_name, _8>
gimple_label <<D.3198>>
gimple_assign <addr_expr, in_addr, &ifdata.ifr_ifru.ifru_addr, NULL, NULL>
gimple_call <inet_ntoa, _9, in_addr->sin_addr>
gimple_assign <component_ref, _10, ifNameIndex->if_index, NULL, NULL>
gimple_call <printf, NULL, "\xd0\x98\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80\xd1\x84\xd0\xb5\xd0\xb9\xd1\x81 %s \xd0\xb8\xd0\xbd\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd1\x81 %i IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81: %s\n", &ifdata.ifr_ifrn.ifrn_name, _10, _9>
gimple_assign <pointer_plus_expr, ifNameIndex, ifNameIndex, 16, NULL>
gimple_label <<D.3189>>
gimple_assign <component_ref, _11, ifNameIndex->if_index, NULL, NULL>
gimple_cond <ne_expr, _11, 0, <D.3190>, <D.3188>>
gimple_label <<D.3188>>
gimple_label <<D.3196>>
gimple_call <close, NULL, sock>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
>
CLEANUP <
gimple_assign <constructor, ifdata, {CLOBBER}, NULL, NULL>
>
>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
gimple_label <<D.3199>>
gimple_return <D.3194>
}
Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.
Исправление SkyMaverick, :
Кстати, разве у gcc когда-то был публичный промежуточный IR? Именно оформленный в стабильный язык как у LLVM, а не какие-то внутренние структуры.
Можно запустить gcc с ключом -fdump-tree-all-raw
и смотреть.
Вот, например, под катом простая программа (ну, первая, которая у меня в екзамплах валяется) и её IR
Код:
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
int
main()
{
int sock;
struct sockaddr_in *in_addr;
struct ifreq ifdata;
struct if_nameindex *ifNameIndex;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
return 1;
}
ifNameIndex = if_nameindex();
if (ifNameIndex) {
while (ifNameIndex->if_index) {
memset(&ifdata, 0, sizeof(ifdata));
strncpy(ifdata.ifr_name, ifNameIndex->if_name,
IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifdata.ifr_name,
strerror(errno));
//close(sock);
//return 1;
}
sockaddr_in
in_addr = (struct sockaddr_in *)&ifdata.ifr_addr;
printf("Интерфейс %s индекес %i IP адрес: %s\n", ifdata.ifr_name, ifNameIndex->if_index,
inet_ntoa(in_addr->sin_addr));
++ifNameIndex;
}
}
close(sock);
return 0;
}
GIMPLE, который низкоуровневый, но так-то и высокоуровневый есть
int main ()
{
struct if_nameindex * ifNameIndex;
struct ifreq ifdata;
struct sockaddr_in * in_addr;
int sock;
int D.3194;
gimple_try <GIMPLE_TRY_FINALLY,
EVAL <
gimple_call <socket, sock, 2, 2, 0>
gimple_cond <lt_expr, sock, 0, <D.3192>, <D.3193>>
gimple_label <<D.3192>>
gimple_call <__errno_location, _1>
gimple_assign <mem_ref, _2, *_1, NULL, NULL>
gimple_call <strerror, _3, _2>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x81\xd0\xbe\xd0\xba\xd0\xb5\xd1\x82, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", _3>
gimple_assign <integer_cst, D.3194, 1, NULL, NULL>
// predicted unlikely by early return (on trees) predictor.
gimple_goto <<D.3199>>
gimple_label <<D.3193>>
gimple_call <if_nameindex, ifNameIndex>
gimple_cond <ne_expr, ifNameIndex, 0B, <D.3195>, <D.3196>>
gimple_label <<D.3195>>
gimple_goto <<D.3189>>
gimple_label <<D.3190>>
gimple_call <memset, NULL, &ifdata, 0, 40>
gimple_assign <component_ref, _4, ifNameIndex->if_name, NULL, NULL>
gimple_call <strncpy, NULL, &ifdata.ifr_ifrn.ifrn_name, _4, 16>
gimple_call <ioctl, _5, sock, 35093, &ifdata>
gimple_cond <lt_expr, _5, 0, <D.3197>, <D.3198>>
gimple_label <<D.3197>>
gimple_call <__errno_location, _6>
gimple_assign <mem_ref, _7, *_6, NULL, NULL>
gimple_call <strerror, _8, _7>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x83\xd1\x87\xd0\xb8\xd1\x82\xd1\x8c IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81 \xd0\xb4\xd0\xbb\xd1\x8f %s, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", &ifdata.ifr_ifrn.ifrn_name, _8>
gimple_label <<D.3198>>
gimple_assign <addr_expr, in_addr, &ifdata.ifr_ifru.ifru_addr, NULL, NULL>
gimple_call <inet_ntoa, _9, in_addr->sin_addr>
gimple_assign <component_ref, _10, ifNameIndex->if_index, NULL, NULL>
gimple_call <printf, NULL, "\xd0\x98\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80\xd1\x84\xd0\xb5\xd0\xb9\xd1\x81 %s \xd0\xb8\xd0\xbd\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd1\x81 %i IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81: %s\n", &ifdata.ifr_ifrn.ifrn_name, _10, _9>
gimple_assign <pointer_plus_expr, ifNameIndex, ifNameIndex, 16, NULL>
gimple_label <<D.3189>>
gimple_assign <component_ref, _11, ifNameIndex->if_index, NULL, NULL>
gimple_cond <ne_expr, _11, 0, <D.3190>, <D.3188>>
gimple_label <<D.3188>>
gimple_label <<D.3196>>
gimple_call <close, NULL, sock>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
>
CLEANUP <
gimple_assign <constructor, ifdata, {CLOBBER}, NULL, NULL>
>
>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
gimple_label <<D.3199>>
gimple_return <D.3194>
}
Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.
Исходная версия SkyMaverick, :
Кстати, разве у gcc когда-то был публичный промежуточный IR? Именно оформленный в стабильный язык как у LLVM, а не какие-то внутренние структуры.
GENERIC - синтаксическое дерево GIMPLE - собственно сам IR
Можно запустить gcc с ключом -fdump-tree-all-raw
и смотреть.
Вот, например, под катом простая программа (ну, первая, которая у меня в екзамплах валяется) и её IR
Код:
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <string.h>
#include <net/if.h>
#include <errno.h>
#include <stdio.h>
int
main()
{
int sock;
struct sockaddr_in *in_addr;
struct ifreq ifdata;
struct if_nameindex *ifNameIndex;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
printf("Не удалось открыть сокет, ошибка: %s\n", strerror(errno));
return 1;
}
ifNameIndex = if_nameindex();
if (ifNameIndex) {
while (ifNameIndex->if_index) {
memset(&ifdata, 0, sizeof(ifdata));
strncpy(ifdata.ifr_name, ifNameIndex->if_name,
IFNAMSIZ);
if (ioctl(sock, SIOCGIFADDR, &ifdata) < 0) {
printf("Не получить IP адрес для %s, ошибка: %s\n", ifdata.ifr_name,
strerror(errno));
//close(sock);
//return 1;
}
sockaddr_in
in_addr = (struct sockaddr_in *)&ifdata.ifr_addr;
printf("Интерфейс %s индекес %i IP адрес: %s\n", ifdata.ifr_name, ifNameIndex->if_index,
inet_ntoa(in_addr->sin_addr));
++ifNameIndex;
}
}
close(sock);
return 0;
}
GIMPLE, который низкоуровневый, но так-то и высокоуровневый есть
int main ()
{
struct if_nameindex * ifNameIndex;
struct ifreq ifdata;
struct sockaddr_in * in_addr;
int sock;
int D.3194;
gimple_try <GIMPLE_TRY_FINALLY,
EVAL <
gimple_call <socket, sock, 2, 2, 0>
gimple_cond <lt_expr, sock, 0, <D.3192>, <D.3193>>
gimple_label <<D.3192>>
gimple_call <__errno_location, _1>
gimple_assign <mem_ref, _2, *_1, NULL, NULL>
gimple_call <strerror, _3, _2>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xbe\xd1\x81\xd1\x8c \xd0\xbe\xd1\x82\xd0\xba\xd1\x80\xd1\x8b\xd1\x82\xd1\x8c \xd1\x81\xd0\xbe\xd0\xba\xd0\xb5\xd1\x82, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", _3>
gimple_assign <integer_cst, D.3194, 1, NULL, NULL>
// predicted unlikely by early return (on trees) predictor.
gimple_goto <<D.3199>>
gimple_label <<D.3193>>
gimple_call <if_nameindex, ifNameIndex>
gimple_cond <ne_expr, ifNameIndex, 0B, <D.3195>, <D.3196>>
gimple_label <<D.3195>>
gimple_goto <<D.3189>>
gimple_label <<D.3190>>
gimple_call <memset, NULL, &ifdata, 0, 40>
gimple_assign <component_ref, _4, ifNameIndex->if_name, NULL, NULL>
gimple_call <strncpy, NULL, &ifdata.ifr_ifrn.ifrn_name, _4, 16>
gimple_call <ioctl, _5, sock, 35093, &ifdata>
gimple_cond <lt_expr, _5, 0, <D.3197>, <D.3198>>
gimple_label <<D.3197>>
gimple_call <__errno_location, _6>
gimple_assign <mem_ref, _7, *_6, NULL, NULL>
gimple_call <strerror, _8, _7>
gimple_call <printf, NULL, "\xd0\x9d\xd0\xb5 \xd0\xbf\xd0\xbe\xd0\xbb\xd1\x83\xd1\x87\xd0\xb8\xd1\x82\xd1\x8c IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81 \xd0\xb4\xd0\xbb\xd1\x8f %s, \xd0\xbe\xd1\x88\xd0\xb8\xd0\xb1\xd0\xba\xd0\xb0: %s\n", &ifdata.ifr_ifrn.ifrn_name, _8>
gimple_label <<D.3198>>
gimple_assign <addr_expr, in_addr, &ifdata.ifr_ifru.ifru_addr, NULL, NULL>
gimple_call <inet_ntoa, _9, in_addr->sin_addr>
gimple_assign <component_ref, _10, ifNameIndex->if_index, NULL, NULL>
gimple_call <printf, NULL, "\xd0\x98\xd0\xbd\xd1\x82\xd0\xb5\xd1\x80\xd1\x84\xd0\xb5\xd0\xb9\xd1\x81 %s \xd0\xb8\xd0\xbd\xd0\xb4\xd0\xb5\xd0\xba\xd0\xb5\xd1\x81 %i IP \xd0\xb0\xd0\xb4\xd1\x80\xd0\xb5\xd1\x81: %s\n", &ifdata.ifr_ifrn.ifrn_name, _10, _9>
gimple_assign <pointer_plus_expr, ifNameIndex, ifNameIndex, 16, NULL>
gimple_label <<D.3189>>
gimple_assign <component_ref, _11, ifNameIndex->if_index, NULL, NULL>
gimple_cond <ne_expr, _11, 0, <D.3190>, <D.3188>>
gimple_label <<D.3188>>
gimple_label <<D.3196>>
gimple_call <close, NULL, sock>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
>
CLEANUP <
gimple_assign <constructor, ifdata, {CLOBBER}, NULL, NULL>
>
>
gimple_assign <integer_cst, D.3194, 0, NULL, NULL>
gimple_goto <<D.3199>>
gimple_label <<D.3199>>
gimple_return <D.3194>
}
Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.