123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- Smalltalk current createPackage: 'Compiler-Inlining' properties:
- IRAssignment subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInlinedAssignment methodsFor: 'testing'!
- isInlined
- ^ true
- ! !
- !IRInlinedAssignment methodsFor: 'visiting'!
- accept: aVisitor
- ^ aVisitor visitIRInlinedAssignment: self
- ! !
- IRClosure subclass:
- instanceVariableNames: 'assignTo'
- package: 'Compiler-Inlining'!
- !IRInlinedClosure methodsFor: 'accessing'!
- assignTo
- ^ assignTo
- !
- assignTo: aScopeVar
- assignTo := aScopeVar
- ! !
- !IRInlinedClosure methodsFor: 'testing'!
- isInlined
- ^ true
- ! !
- !IRInlinedClosure methodsFor: 'visiting'!
- accept: aVisitor
- aVisitor visitIRInlinedClosure: self
- ! !
- IRNonLocalReturn subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInlinedNonLocalReturn methodsFor: 'testing'!
- isInlined
- ^ true
- ! !
- !IRInlinedNonLocalReturn methodsFor: 'visiting'!
- accept: aVisitor
- ^ aVisitor visitIRInlinedNonLocalReturn: self
- ! !
- IRSend subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInlinedSend methodsFor: 'testing'!
- isInlined
- ^ true
- ! !
- !IRInlinedSend methodsFor: 'visiting'!
- accept: aVisitor
- aVisitor visitInlinedSend: self
- ! !
- IRInlinedSend subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInlinedIfTrue methodsFor: 'visiting'!
- accept: aVisitor
- aVisitor visitIRInlinedIfTrue: self
- ! !
- IRVisitor subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInliner methodsFor: 'testing'!
- shouldInlineAssignment: anIRAssignment
- ^ anIRAssignment isInlined not and: [
- anIRAssignment instructions last isSend and: [
- self shouldInlineSend: (anIRAssignment instructions last) ]]
- !
- shouldInlineSend: anIRSend
- ^ anIRSend isInlined not and: [
- IRSendInliner inlinedSelectors includes: anIRSend selector ]
- ! !
- !IRInliner methodsFor: 'visiting'!
- assignmentInliner
- ^ IRAssignmentInliner new
- translator: self;
- yourself
- !
- sendInliner
- ^ IRSendInliner new
- translator: self;
- yourself
- !
- visitIRAssignment: anIRAssignment
- ^ (self shouldInlineAssignment: anIRAssignment)
- ifTrue: [ self assignmentInliner inlineAssignment: anIRAssignment ]
- ifFalse: [ super visitIRAssignment: anIRAssignment ]
- !
- visitIRSend: anIRSend
- ^ (self shouldInlineSend: anIRSend)
- ifTrue: [ self sendInliner inlineSend: anIRSend ]
- ifFalse: [ super visitIRSend: anIRSend ]
- !
- visitSendNode: aNode
- aNode canBeInlined
- ifTrue: [ self sendInliner inlineSend: aNode ]
- ifFalse: [ super visitSendNode: aNode ]
- ! !
- IRJSTranslator subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !IRInliningJSTranslator methodsFor: 'visiting'!
- visitIRInlinedAssignment: anIRInlinedAssignment
- self visit: anIRInlinedAssignment instructions last
- !
- visitIRInlinedClosure: anIRInlinedClosure
- anIRInlinedClosure instructions allButLast do: [ :each | self visit: each ].
- anIRInlinedClosure assignTo ifNotNil: [
- self stream nextPutAll: anIRInlinedClosure assignTo variable alias.
- self stream nextPutAssignment ].
- self visit: anIRInlinedClosure instructions last
- !
- visitIRInlinedIfTrue: anIRInlinedIfTrue
- self stream
- nextPutIf: [ self visit: anIRInlinedIfTrue instructions first ]
- with: [ self visit: anIRInlinedIfTrue instructions last ]
- ! !
- Object subclass:
- instanceVariableNames: 'send translator'
- package: 'Compiler-Inlining'!
- !IRSendInliner commentStamp!
- I inline some message sends and block closure arguments. I heavily rely on
- !IRSendInliner methodsFor: 'accessing'!
- inlinedClosure
- ^ IRInlinedClosure new
- !
- send
- ^ send
- !
- send: anIRSend
- send := anIRSend
- !
- translator
- ^ translator
- !
- translator: anASTTranslator
- translator := anASTTranslator
- ! !
- !IRSendInliner methodsFor: 'error handling'!
- inliningError: aString
- InliningError signal: aString
- ! !
- !IRSendInliner methodsFor: 'inlining'!
- ifTrue: anIRInstruction
- | inlinedSend inlinedClosure |
- anIRInstruction isClosure ifFalse: [ self inliningError: 'Message argument should be a block' ].
- anIRInstruction arguments size = 0 ifFalse: [ self inliningError: 'Inlined block should have zero argument' ].
- inlinedClosure := self inlinedClosure.
- anIRInstruction instructions do: [ :each |
- instruction := (self translator visit: each) first.
- inlinedClosure add: instruction ].
- inlinedSend := IRInlinedIfTrue new.
- inlinedSend
- add: self send instructions first;
- add: inlinedClosure.
- self send replaceWith: inlinedSend.
- ^ inlinedSend
- !
- inlineSend: anIRSend
- self send: anIRSend.
- self perform: self send selector withArguments: self send instructions allButFirst
- ! !
- !IRSendInliner class methodsFor: 'accessing'!
- inlinedSelectors
- ^
- ! !
- IRSendInliner subclass:
- instanceVariableNames: 'assignment'
- package: 'Compiler-Inlining'!
- !IRAssignmentInliner methodsFor: 'accessing'!
- assignment
- ^ assignment
- !
- assignment: aNode
- assignment := aNode
- !
- inlinedClosure
- ^ super inlinedClosure
- assignTo: self assignment instructions first;
- yourself
- ! !
- !IRAssignmentInliner methodsFor: 'inlining'!
- inlineAssignment: anIRAssignment
- | inlinedAssignment |
- self assignment: anIRAssignment.
- inlinedAssignment := IRInlinedAssignment new.
- anIRAssignment instructions do: [ :each |
- inlinedAssignment add: each ].
- anIRAssignment replaceWith: inlinedAssignment.
- self inlineSend: inlinedAssignment instructions last.
- ^ inlinedAssignment
- ! !
- CodeGenerator subclass:
- instanceVariableNames: ''
- package: 'Compiler-Inlining'!
- !InliningCodeGenerator methodsFor: 'compiling'!
- compileNode: aNode
- | ir stream |
- self semanticAnalyzer visit: aNode.
- ir := self translator visit: aNode.
- self inliner visit: ir.
- ^ self irTranslator
- visit: ir;
- contents
- !
- inliner
- ^ IRInliner new
- !
- irTranslator
- ^ IRInliningJSTranslator new
- ! !
|