2012-04-12 1 views
5

Я просто заметил, что Clang компилирует это заявление (без какой-либо оптимизации, конечно):x86 приставной против subl

--x; /* int x; */ 

в:

addl $4294967295, %ecx  ## imm = 0xFFFFFFFF 

Почему? Есть ли преимущество использования addl вместо «очевидного» subl? Или это просто факт реализации?

Какие хитрости меня в том, что это одна:

x -= 1; 

становится:

subl $1, %eax 

Clang информация:

 
Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn) 
Target: x86_64-apple-darwin11.2.0 
Thread model: posix 
+0

Это, вероятно, только реализация и может измениться с уровнем оптимизации. Более интересно то, что он не использует 'dec', что может быть оптимизацией, потому что' dec' не изменяет столько флагов состояния, что это зависит от предыдущих инструкций. – ughoavgfhw

+0

gcc производит тот же код для 'x -' и 'x = -1', используя' subl'. Интересно, что он использует 'xorl', если я включаю' -O3'. –

+5

Нет никакого преимущества, и нет недостатка. Оба имеют 3 байта и имеют одинаковые характеристики производительности. – harold

ответ

4

Такое поведение связано с тем, как лязг обрабатывает предварительно декремент в отличие от двоичных операторов, таких как под-и-назначение. Обратите внимание, что я просто попытаюсь объяснить на уровне clang, почему вы видите это поведение. Я не знаю, почему это было выбрано таким образом, но я предполагаю, что это было просто для удобства реализации.

Все функции, ссылки на которые приведены здесь, можно найти в классе ScalarExprEmitter внутри lib/CodeGen/CGExprScalar.cpp.

до/после декремента/инкремента все обработаны таким же образом, с помощью функции EmitScalarPrePostIncDec: AN LLVM add инструкция испускается либо 1 или -1 в качестве второго аргумента, в зависимости от экспрессии являющегося приращение или декремент соответственно.

Поэтому

--x 

будет в конечном итоге, в LLVM IR, как что-то вроде

add i32 %x, -1 

, которые, вполне естественно, переводит к x86 как что-то вроде

add $0xffffffff, %ecx 

С другой стороны, двоичные операторы обрабатываются по-разному. В вашем случае,

x -= 1 

будут обработаны EmitCompoundAssign, которые в свою очередь вызывает EmitSub. Будет испускаться что-то вроде следующих LLVM IR:

sub i32 %x, 1 
+0

Спасибо за объяснение и ссылки на источники. Это то, что я искал, это имеет смысл и доказывает, что это происходит в результате внедрения. – sidyll

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

  • Нет связанных вопросов^_^