@@ -29,17 +29,19 @@ internal sealed class CodeGenerator
2929 , IDisposable
3030 , IKaleidoscopeCodeGenerator < Value >
3131 {
32+ // <Initialization>
3233 public CodeGenerator ( DynamicRuntimeState globalState )
3334 {
3435 RuntimeState = globalState ;
3536 Context = new Context ( ) ;
37+ JIT = new KaleidoscopeJIT ( ) ;
3638 InitializeModuleAndPassManager ( ) ;
3739 InstructionBuilder = new InstructionBuilder ( Context ) ;
38- JIT = new KaleidoscopeJIT ( ) ;
3940 FunctionPrototypes = new PrototypeCollection ( ) ;
4041 FunctionModuleMap = new Dictionary < string , IJitModuleHandle > ( ) ;
4142 NamedValues = new ScopeStack < Value > ( ) ;
4243 }
44+ // </Initialization>
4345
4446 public bool DisableOptimizations { get ; set ; }
4547
@@ -82,7 +84,7 @@ public override Value VisitVariableExpression( [NotNull] VariableExpressionConte
8284
8385 public override Value VisitFunctionCallExpression ( [ NotNull ] FunctionCallExpressionContext context )
8486 {
85- var function = GetFunction ( context . CaleeName ) ;
87+ var function = FindCallTarget ( context . CaleeName ) ;
8688 if ( function == null )
8789 {
8890 throw new CodeGeneratorException ( $ "function '{ context . CaleeName } ' is unknown" ) ;
@@ -102,13 +104,16 @@ public override Value VisitFunctionPrototype( [NotNull] FunctionPrototypeContext
102104 return GetOrDeclareFunction ( new Prototype ( context ) ) ;
103105 }
104106
107+ // <VisitFunctionDefinition>
105108 public override Value VisitFunctionDefinition ( [ NotNull ] FunctionDefinitionContext context )
106109 {
107110 return DefineFunction ( ( Function ) context . Signature . Accept ( this )
108111 , context . BodyExpression
109112 ) . Function ;
110113 }
114+ // </VisitFunctionDefinition>
111115
116+ // <VisitTopLevelExpression>
112117 public override Value VisitTopLevelExpression ( [ NotNull ] TopLevelExpressionContext context )
113118 {
114119 var proto = new Prototype ( $ "anon_expr_{ AnonNameIndex ++ } " ) ;
@@ -118,9 +123,11 @@ public override Value VisitTopLevelExpression( [NotNull] TopLevelExpressionConte
118123
119124 var nativeFunc = JIT . GetDelegateForFunction < AnonExpressionFunc > ( proto . Identifier . Name ) ;
120125 var retVal = Context . CreateConstant ( nativeFunc ( ) ) ;
126+ FunctionModuleMap . Remove ( function . Name ) ;
121127 JIT . RemoveModule ( jitHandle ) ;
122128 return retVal ;
123129 }
130+ // </VisitTopLevelExpression>
124131
125132 public override Value VisitExpression ( [ NotNull ] ExpressionContext context )
126133 {
@@ -135,6 +142,7 @@ public override Value VisitExpression( [NotNull] ExpressionContext context )
135142 return lhs ;
136143 }
137144
145+ // <VisitConditionalExpression>
138146 public override Value VisitConditionalExpression ( [ NotNull ] ConditionalExpressionContext context )
139147 {
140148 var condition = context . Condition . Accept ( this ) ;
@@ -163,7 +171,7 @@ public override Value VisitConditionalExpression( [NotNull] ConditionalExpressio
163171
164172 InstructionBuilder . Branch ( phiMergeBlock ) ;
165173
166- // capture the insert in case generating thenExpression adds new blocks
174+ // capture the insert in case generating else adds new blocks
167175 thenBlock = InstructionBuilder . InsertBlock ;
168176
169177 // generate else block
@@ -188,24 +196,9 @@ public override Value VisitConditionalExpression( [NotNull] ConditionalExpressio
188196 phiNode . AddIncoming ( elseValue , elseBlock ) ;
189197 return phiNode ;
190198 }
199+ // </VisitConditionalExpression>
191200
192- /*
193- // Output for-loop as:
194- // ...
195- // start = startexpr
196- // goto loop
197- // loop:
198- // variable = phi [start, loopheader], [nextvariable, loopend]
199- // ...
200- // bodyexpr
201- // ...
202- // loopend:
203- // step = stepexpr
204- // nextvariable = variable + step
205- // endcond = endexpr
206- // br endcond, loop, endloop
207- // outloop:
208- */
201+ // <VisitForExpression>
209202 public override Value VisitForExpression ( [ NotNull ] ForExpressionContext context )
210203 {
211204 var function = InstructionBuilder . InsertBlock . ContainingFunction ;
@@ -297,7 +290,9 @@ public override Value VisitForExpression( [NotNull] ForExpressionContext context
297290 return Context . DoubleType . GetNullValue ( ) ;
298291 }
299292 }
293+ // </VisitForExpression>
300294
295+ // <VisitUserOperators>
301296 public override Value VisitUnaryOpExpression ( [ NotNull ] UnaryOpExpressionContext context )
302297 {
303298 // verify the operator was previously defined
@@ -308,7 +303,7 @@ public override Value VisitUnaryOpExpression( [NotNull] UnaryOpExpressionContext
308303 }
309304
310305 string calleeName = UnaryPrototypeContext . GetOperatorFunctionName ( context . OpToken ) ;
311- var function = GetFunction ( calleeName ) ;
306+ var function = FindCallTarget ( calleeName ) ;
312307 if ( function == null )
313308 {
314309 throw new CodeGeneratorException ( $ "Unknown function reference { calleeName } " ) ;
@@ -338,6 +333,7 @@ public override Value VisitUnaryPrototype( [NotNull] UnaryPrototypeContext conte
338333
339334 return GetOrDeclareFunction ( new Prototype ( context , context . Name ) ) ;
340335 }
336+ // </VisitUserOperators>
341337
342338 protected override Value DefaultResult => null ;
343339
@@ -378,6 +374,7 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
378374 case SLASH :
379375 return InstructionBuilder . FDiv ( lhs , rhs ) . RegisterName ( "divtmp" ) ;
380376
377+ // <EmitUserOperator>
381378 default :
382379 {
383380 // User defined op?
@@ -388,30 +385,37 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
388385 }
389386
390387 string calleeName = BinaryPrototypeContext . GetOperatorFunctionName ( op . Token ) ;
391- var function = GetFunction ( calleeName ) ;
388+ var function = FindCallTarget ( calleeName ) ;
392389 if ( function == null )
393390 {
394391 throw new CodeGeneratorException ( $ "Unknown function reference { calleeName } " ) ;
395392 }
396393
397394 return InstructionBuilder . Call ( function , lhs , rhs ) . RegisterName ( "calltmp" ) ;
398395 }
396+ // </EmitUserOperator>
399397 }
400398 }
401399
400+ // <InitializeModuleAndPassManager>
402401 private void InitializeModuleAndPassManager ( )
403402 {
404403 Module = Context . CreateBitcodeModule ( ) ;
404+ Module . Layout = JIT . TargetMachine . TargetData ;
405405 FunctionPassManager = new FunctionPassManager ( Module ) ;
406406 FunctionPassManager . AddInstructionCombiningPass ( )
407407 . AddReassociatePass ( )
408408 . AddGVNPass ( )
409409 . AddCFGSimplificationPass ( )
410410 . Initialize ( ) ;
411411 }
412+ // </InitializeModuleAndPassManager>
412413
413- private Function GetFunction ( string name )
414+ // <FindCallTarget>
415+ private Function FindCallTarget ( string name )
414416 {
417+ // lookup the prototype for the function to get the signature
418+ // and create a declaration in this module
415419 if ( FunctionPrototypes . TryGetValue ( name , out var signature ) )
416420 {
417421 return GetOrDeclareFunction ( signature ) ;
@@ -425,7 +429,9 @@ private Function GetFunction( string name )
425429
426430 return null ;
427431 }
432+ // </FindCallTarget>
428433
434+ // <GetOrDeclareFunction>
429435 private Function GetOrDeclareFunction ( Prototype prototype , bool isAnonymous = false )
430436 {
431437 var function = Module . GetFunction ( prototype . Identifier . Name ) ;
@@ -453,7 +459,9 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
453459
454460 return retVal ;
455461 }
462+ // </GetOrDeclareFunction>
456463
464+ // <DefineFunction>
457465 private ( Function Function , IJitModuleHandle JitHandle ) DefineFunction ( Function function , ExpressionContext body )
458466 {
459467 if ( ! function . IsDeclaration )
@@ -466,7 +474,7 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
466474 // implementation. This is needed, otherwise both the MCJIT
467475 // and OrcJit engines will resolve to the original module, despite
468476 // claims to the contrary in the official tutorial text. (Though,
469- // to be fare it may have been true in the original JIT and might
477+ // to be fair it may have been true in the original JIT and might
470478 // still be true for the interpreter)
471479 if ( FunctionModuleMap . Remove ( function . Name , out IJitModuleHandle handle ) )
472480 {
@@ -503,6 +511,7 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
503511 InitializeModuleAndPassManager ( ) ;
504512 return ( function , jitHandle ) ;
505513 }
514+ // </DefineFunction>
506515
507516 // <PrivateMembers>
508517 private readonly DynamicRuntimeState RuntimeState ;
0 commit comments