feat(tvix/eval): optimise tail calls in emitted chunks
When the last instruction in a chunk is OpCall, make it an OpTailCall instead. Change-Id: I2c80a06ee85e4abf545887b1a79b6d8b5e6123e9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6458 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
		
							parent
							
								
									2e018a50a7
								
							
						
					
					
						commit
						6bbe7589c5
					
				
					 1 changed files with 20 additions and 2 deletions
				
			
		|  | @ -900,7 +900,11 @@ impl Compiler<'_, '_> { | |||
| 
 | ||||
|         // Pop the lambda context back off, and emit the finished
 | ||||
|         // lambda as a constant.
 | ||||
|         let compiled = self.contexts.pop().unwrap(); | ||||
|         let mut compiled = self.contexts.pop().unwrap(); | ||||
| 
 | ||||
|         // Check if tail-call optimisation is possible and perform it.
 | ||||
|         optimise_tail_call(&mut compiled.lambda.chunk); | ||||
| 
 | ||||
|         let lambda = Rc::new(compiled.lambda); | ||||
|         self.observer.observe_compiled_lambda(&lambda); | ||||
| 
 | ||||
|  | @ -947,7 +951,8 @@ impl Compiler<'_, '_> { | |||
|         content(self, node, slot); | ||||
|         self.end_scope(node); | ||||
| 
 | ||||
|         let thunk = self.contexts.pop().unwrap(); | ||||
|         let mut thunk = self.contexts.pop().unwrap(); | ||||
|         optimise_tail_call(&mut thunk.lambda.chunk); | ||||
|         let lambda = Rc::new(thunk.lambda); | ||||
|         self.observer.observe_compiled_thunk(&lambda); | ||||
| 
 | ||||
|  | @ -1304,6 +1309,19 @@ impl Compiler<'_, '_> { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Perform tail-call optimisation if the last call within a
 | ||||
| /// compiled chunk is another call.
 | ||||
| fn optimise_tail_call(chunk: &mut Chunk) { | ||||
|     let last_op = chunk | ||||
|         .code | ||||
|         .last_mut() | ||||
|         .expect("compiler bug: chunk should never be empty"); | ||||
| 
 | ||||
|     if matches!(last_op, OpCode::OpCall) { | ||||
|         *last_op = OpCode::OpTailCall; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Prepare the full set of globals from additional globals supplied
 | ||||
| /// by the caller of the compiler, as well as the built-in globals
 | ||||
| /// that are always part of the language.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue