Guillermo Adrián Molina writes:
In Exupery the SmallInteger addtion sequence is bitTest arg1 jumpIfSet failureBlock bitTest arg2 jumpIfSet failureBlock clearTagBit arg1 add arg1 arg2 jumpOverflow failureBlock
The failure case is a full message send.
The problem with the above code is that you have 3 branches. That is why I need jump tables, there are cases where cmov really dosn't help
There is only 3 branches and I'm hoping that they will never be taken so they should be easy to predict. That said the branches do use branch predictor resources which could cause other branches not to be predicted as well.
Before I started using exupery, I called special methods in C that implemented faster code. Every special method (and primitives) returned 1 in case of an error, and if success, returned the result object. One of this special methods was +. This is part of the code:
if(areIntegers(rcvr,arg)) { int result; asm( "movl $1,%%edx\n\t" "movl %[rcvr],%[result]\n\t" "addl %[arg],%[result]\n\t" "cmovol %%edx,%[result]" : [result] "=r" (result) : [rcvr] "r" (rcvr), [arg] "r" (arg) : "edx" ); return result; }
with this code, I've got up to 10% faster code in + intensive tests.
Do you have conditionals inside areIntegers and to check if the result is 1 indicating an error?
There are code fragments where cmov whould be helpful. Converting to a boolean comes to mind. The part of "a > b" where you're loading either true or false into the result register.
Yes, I implemented that with exupery (code for less "<"):
self addExpression: (MedMov from: (self literal: false) to: answer ). trueReg := machine createTemporaryRegister. self addExpression: (MedMov from: (self literal: true) to: trueReg ). self addExpression: (MedComparision operator: #cmp arg1: arg1 arg2: arg2). self addExpression: (MedCMov type: #cmovl from: trueReg to: answer).
This gave me an impressive improvement (up to 40-50%), when I implemented all the smallint comparissons in this way. Because, as you know, we dont need to detag before compare.
Exupery removes many of the boolean conversion sequences.
"a < b ifTrue: [x]"
First gets translated into:
(booleanToControlFlow (controlFlowToBoolean (a < b)))
Then Exupery removes the booleanToControlFlow controlFlowToBoolean sequence. The booleanToControlFlow sequence is moved to the failure case where either a or b are not SmallIntegers.
So I'm not sure if speeding up the general case will help Exupery as I'm not sure how often it's called.
Bryce