[Newcompiler] How to decompile #while{True,False}

Mathieu Suen mathieusuen at yahoo.fr
Wed Sep 5 16:30:45 UTC 2007


Hi Klaus thanks :)

On Sep 5, 2007, at 6:00 PM, Klaus D. Witzel wrote:

> Hi Math,
>
> the only place I can see where one of {true. false} is not pushed  
> during IR's work is #absorbConstantConditionalJumps: which is part  
> of #optimize.
>
> IRJumpIf etc must do their work so that  
> #absorbConstantConditionalJumps: can really find things for  
> optimizing them away.
>
> Do you perhaps have a test for the cases analyzed during  
> IRMethod>>#optimize, that would shed a bit more light on the issue.

Actualy no. I thing we should build the test with mocks. May be in  
the same way that Exupery dose.
But it may be quite difficult to build them.

cheers

	Mth

>
> Cheers
> Klaus
>
> On Wed, 05 Sep 2007 14:45:58 +0200, Mathieu Suen wrote:
>
>> Hi Klaus
>>
>> Thanks
>>
>> On Sep 5, 2007, at 7:12 AM, Klaus D. Witzel wrote:
>>
>>> Hi Math,
>>>
>>> when the old decompiler decompiles #sweep: it finds
>>
>> He can find the #ifTrue:ifFalse: because he keep the push true or  
>> false.
>>
>>>
>>> [(ind := ind + 1) > list size
>>> 		ifTrue: [false]
>>> 		ifFalse: [(parts at: ind) first asLowercase = projectName
>>> 				and: [versions
>>> 						add: (parts at: ind).
>>> 					true]]] whileTrue.
>>>
>>> which is what can be expected, the inner #ifTrue:ifFalse: is  
>>> rendered as an #and: (... ifFalse: [false]).
>>>
>>> The place where a #not message send is inserted is  
>>> IRDecompiler>>#endAndOr2: (reducing the jump structures).
>>
>> Yes I know that but I don't know where the NewCompiler remove the  
>> pushConstant: true.
>> It should be somewhere where when the IRJumpIf is interpret but I  
>> cant find it.
>>
>> The old compiler don't  remove the push true:
>>
>>> 199 <14> pushTemp: 4
>>> 200 <76> pushConstant: 1
>>> 201 <B0> send: +
>>> 202 <81 44> storeIntoTemp: 4
>>> 204 <12> pushTemp: 2
>>> 205 <C2> send: size
>>> 206 <B3> send: >
>>> 207 <9A> jumpFalse: 211 "First ifTrue ifFalse"
>>>
>>> ''(ind := ind + 1) > list size  ifTrue:  [false]"
>>> 208 <72> pushConstant: false
>>> 209 <A4 15> jumpTo: 232
>>>
>>> ''(ind := ind + 1) > list size  ifFalse:  [...]"
>>> 211 <13> pushTemp: 3
>>> 212 <14> pushTemp: 4
>>> 213 <C0> send: at:
>>> 214 <83 15> send: first
>>> 216 <83 14> send: asLowercase
>>> 218 <16> pushTemp: 6
>>> 219 <B6> send: =
>>> 220 <AC 09> jumpFalse: 231   "Second ifTrue ifFalse"
>>>
>>> "(parts at: ind) first asLowercase = projectName ifTrue: [..]"
>>> 222 <17> pushTemp: 7
>>> 223 <13> pushTemp: 3
>>> 224 <14> pushTemp: 4
>>> 225 <C0> send: at:
>>> 226 <83 37> send: add:
>>> 228 <87> pop
>>> 229 <71> pushConstant: true
>>> 230 <90> jumpTo: 232
>>>
>>> "(parts at: ind) first asLowercase = projectName ifFalse: [false]"
>>> 231 <72> pushConstant: false
>>> 232 <99> jumpFalse: 235
>>
>> You can see the 208 229 and 231 bytecode. There are remove with  
>> the NewCompiler.
>> I don't think that is usefull to make dose optimization.
>>
>> 	Mth
>>
>>>
>>> HTH.
>>>
>>> Cheers
>>> Klaus
>>>
>>> On Wed, 05 Sep 2007 00:06:55 +0200, Mathieu Suen wrote:
>>>
>>>> Hi
>>>>
>>>> In a very particular case the compiler optimize the #whileTrue  
>>>> in a way that the Decompiler can't find the roght code.
>>>>
>>>> This particular case is:
>>>>
>>>> [
>>>> self somthings
>>>>
>>>> aTest
>>>> 	ifTrue:[ok anOtherThings
>>>> 		ifTrue:[here doSomthings. true]
>>>> 		ifFalse:[false]]
>>>> 	ifFalse:[false]
>>>> ] whileTrue
>>>>
>>>> The typical exemple is from  Project class>>#sweep: :
>>>>
>>>>>>>>>> 		[(ind _ ind + 1) > list size
>>>>> 			ifFalse: [(parts at: ind) first asLowercase = projectName
>>>>> 				ifTrue: [versions add: (parts at: ind).  true]
>>>>> 				ifFalse: [false]]
>>>>> 			ifTrue: [false]] whileTrue.
>>>>>>>>>
>>>> The corresponding bytecode is:
>>>>
>>>>> 199 <14> pushTemp: 4
>>>>> 200 <76> pushConstant: 1
>>>>> 201 <B0> send: +
>>>>> 202 <81 44> storeIntoTemp: 4
>>>>> 204 <12> pushTemp: 2
>>>>> 205 <C2> send: size
>>>>> 206 <B3> send: >
>>>>> 207 <A8 16> jumpTrue: 231
>>>>>
>>>>> 209 <13> pushTemp: 3
>>>>> 210 <14> pushTemp: 4
>>>>> 211 <C0> send: at:
>>>>> 212 <83 14> send: first
>>>>> 214 <83 15> send: asLowercase
>>>>> 216 <16> pushTemp: 6
>>>>> 217 <B6> send: =
>>>>> 218 <AC 0B> jumpFalse: 231
>>>>>
>>>>> 220 <17> pushTemp: 7
>>>>> 221 <13> pushTemp: 3
>>>>> 222 <14> pushTemp: 4
>>>>> 223 <C0> send: at:
>>>>> 224 <83 37> send: add:
>>>>> 226 <87> pop
>>>>> 227 <71> pushConstant: true
>>>>> 228 <99> jumpFalse: 231
>>>>>
>>>>> 229 <A3 E0> jumpTo: 199
>>>>
>>>>
>>>> So the first #ifFlase:ifTrue: has been compact to a single jump:
>>>> 207 <A8 16> jumpTrue: 231
>>>>
>>>> This avoid pushing false and make an unconditional jump to the  
>>>> end of the nearly end of the block.
>>>> We also have the same optimazation for the inner #iTrue:ifFalse:  
>>>> message (i.e. at bytecode: 218 and: 228).
>>>>
>>>> We can rewrite the code to produce the same flow :
>>>>
>>>>> [((ind _ ind + 1) > list size) not
>>>>> 			or: [(parts at: ind) first asLowercase = projectName
>>>>> 				and: [versions add: (parts at: ind)]]]] whileTrue
>>>>
>>>> This is what the decompiler found out.
>>>> But this do not produce the same bytecode:
>>>>
>>>>> 203 <14> pushTemp: 4
>>>>> 204 <76> pushConstant: 1
>>>>> 205 <B0> send: +
>>>>> 206 <81 44> storeIntoTemp: 4
>>>>> 208 <12> pushTemp: 2
>>>>> 209 <C2> send: size
>>>>> 210 <B3> send: >
>>>>> 211 <83 18> send: not
>>>>> 213 <A8 12> jumpTrue: 233
>>>>>
>>>>> 215 <13> pushTemp: 3
>>>>> 216 <14> pushTemp: 4
>>>>> 217 <C0> send: at:
>>>>> 218 <83 14> send: first
>>>>> 220 <83 15> send: asLowercase
>>>>> 222 <16> pushTemp: 6
>>>>> 223 <B6> send: =
>>>>> 224 <AC 09> jumpFalse: 235
>>>>>
>>>>> 226 <17> pushTemp: 7
>>>>> 227 <13> pushTemp: 3
>>>>> 228 <14> pushTemp: 4
>>>>> 229 <C0> send: at:
>>>>> 230 <83 37> send: add:
>>>>> 232 <99> jumpFalse: 235
>>>>>
>>>>> 233 <A3 E0> jumpTo: 203
>>>>
>>>> The only difference is in the bytecode 211 and 213:
>>>> A "send: not" is added and the jump don't have the same  
>>>> destination.
>>>>
>>>> The old compiler dose not make this smart optimization.
>>>> So I have several  question.
>>>>
>>>> Do we want the decompiler produce different bytecode (i.e.  
>>>> adding a "send: not"…)?
>>>> Should we do such optimization? (IMO I don't thinks so.)
>>>> where dose the optimization take place? I can't figure out where  
>>>> it is. I get lost inside ASTTranslator and IRTranslator.
>>>>
>>>>
>>>> Thanks
>>>>
>>>> 	Mth
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>>
>>
>>
>>
>> _____________________________________________________________________ 
>> ______
>> Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail  
>> et son interface révolutionnaire.
>> http://fr.mail.yahoo.com
>
>


	

	
		
___________________________________________________________________________ 
Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son interface révolutionnaire.
http://fr.mail.yahoo.com


More information about the Newcompiler mailing list