@@ -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,6 +290,7 @@ public override Value VisitForExpression( [NotNull] ForExpressionContext context
297290 return Context . DoubleType . GetNullValue ( ) ;
298291 }
299292 }
293+ // </VisitForExpression>
300294
301295 protected override Value DefaultResult => null ;
302296
@@ -342,19 +336,25 @@ private Value EmitBinaryOperator( Value lhs, BinaryopContext op, IParseTree righ
342336 }
343337 }
344338
339+ // <InitializeModuleAndPassManager>
345340 private void InitializeModuleAndPassManager ( )
346341 {
347342 Module = Context . CreateBitcodeModule ( ) ;
343+ Module . Layout = JIT . TargetMachine . TargetData ;
348344 FunctionPassManager = new FunctionPassManager ( Module ) ;
349345 FunctionPassManager . AddInstructionCombiningPass ( )
350346 . AddReassociatePass ( )
351347 . AddGVNPass ( )
352348 . AddCFGSimplificationPass ( )
353349 . Initialize ( ) ;
354350 }
351+ // </InitializeModuleAndPassManager>
355352
356- private Function GetFunction ( string name )
353+ // <FindCallTarget>
354+ private Function FindCallTarget ( string name )
357355 {
356+ // lookup the prototype for the function to get the signature
357+ // and create a declaration in this module
358358 if ( FunctionPrototypes . TryGetValue ( name , out var signature ) )
359359 {
360360 return GetOrDeclareFunction ( signature ) ;
@@ -368,7 +368,9 @@ private Function GetFunction( string name )
368368
369369 return null ;
370370 }
371+ // </FindCallTarget>
371372
373+ // <GetOrDeclareFunction>
372374 private Function GetOrDeclareFunction ( Prototype prototype , bool isAnonymous = false )
373375 {
374376 var function = Module . GetFunction ( prototype . Identifier . Name ) ;
@@ -396,7 +398,9 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
396398
397399 return retVal ;
398400 }
401+ // </GetOrDeclareFunction>
399402
403+ // <DefineFunction>
400404 private ( Function Function , IJitModuleHandle JitHandle ) DefineFunction ( Function function , ExpressionContext body )
401405 {
402406 if ( ! function . IsDeclaration )
@@ -409,7 +413,7 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
409413 // implementation. This is needed, otherwise both the MCJIT
410414 // and OrcJit engines will resolve to the original module, despite
411415 // claims to the contrary in the official tutorial text. (Though,
412- // to be fare it may have been true in the original JIT and might
416+ // to be fair it may have been true in the original JIT and might
413417 // still be true for the interpreter)
414418 if ( FunctionModuleMap . Remove ( function . Name , out IJitModuleHandle handle ) )
415419 {
@@ -446,6 +450,7 @@ private Function GetOrDeclareFunction( Prototype prototype, bool isAnonymous = f
446450 InitializeModuleAndPassManager ( ) ;
447451 return ( function , jitHandle ) ;
448452 }
453+ // </DefineFunction>
449454
450455 // <PrivateMembers>
451456 private readonly DynamicRuntimeState RuntimeState ;
0 commit comments