Dois “bugs” do gcc

Das duas coisas que vou citar agora uma delas parece ser um bug mesmo… A outra só parece, mas não é.

O possível “bug”: A opção -fomit-frame-pointer e as opções -O1 até -O3

Se você der uma olhada na tabela mostrada neste post, verá que -fomit-frame-pointer será usado. Isso não parece ser verdadeiro, pelos meus testes. Por exemplo, compilando a função abaixo:

int f(int x)
{
  return x+x;
}

Temos:

/* Com -O3, somente: */
_f:
  push ebp
  mov ebp,esp
  mov eax,dword ptr [ebp+4]
  add eax,eax
  pop ebp
  ret

/* Com -O3 e -fomit-frame-pointer: */
_f:
  mov eax,dword ptr [esp+4]
  add eax,eax
  ret

Note que na primeira versão os códigos de prólogo e epílogo estão lá. No caso do uso explícito do -fomit-frame-pointer, a rotina tem 3 instruções a menos e usa o Stack Pointer diretamente para acessar o parâmetro da função.

Se não houver um bom motivo para o manual falar uma coisa e o compilador fazer outra, então eu considero isso como um bug.

Parece um bug, tem gosto de bug, cheira como bug, mas não é um bug…

neste post eu mostro que o compilador gera um código supostamente “errado”. Só que não está “errado”, está “otimizado”.

O detalhe é o seguinte: Algumas otimizações mudam a sequência original do código para melhorá-lo. O compilador faz isso quanto entende que não há prejuízo para a execução da rotina. No nosso caso a rotina rdtsc() é definida como inline e tem apenas uma instrução em assembly. Quando usamos a rotina fazemos o seguinte (em psudo-código):

Executa RDTSC
Preenche um bloco de 4096 bytes
Executa RDTSC

O compilador não entende que RDTSC é uma rotina “temporal”. Para ele, estamos executando duas rotinas idênticas que podem ser colocadas em sequẽncia. Assim, o compilador faz algo parecido com isso:

Executa RDTSC
Executa RDTSC
Preenche um bloco de 4096 bytes

Não é o ideal, mas quem ligou as otimizações do compilador foi o desenvolvedor (eu!).

No caso do Intel C++ Compiler, por exemplo, essa função é intrinseca. O compilador sabe que não deve otimizar dessa forma. No caso do gcc é possível que possamos dar alguma dica para que ele não otimize as chamadas a rdtsc().

Anúncios

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s