LINUX.ORG.RU

История изменений

Исправление 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>
}

Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.

Исправление 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>
}

Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.

Исправление 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>
}

Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.

Исправление 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>
}

Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.

Исходная версия 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>
}

Там дальше и последующие шаги трансляции можно посмотреть в остальных сгенерированных файлах.