forked from cosmonaut/wraith-lang
				
			optimize struct field reads
							parent
							
								
									180583d772
								
							
						
					
					
						commit
						48d049b6c9
					
				
							
								
								
									
										82
									
								
								compiler.c
								
								
								
								
							
							
						
						
									
										82
									
								
								compiler.c
								
								
								
								
							|  | @ -19,7 +19,9 @@ typedef struct StructFieldMapValue | |||
|     char *name; | ||||
|     LLVMValueRef value; | ||||
|     LLVMValueRef valuePointer; | ||||
|     uint32_t index; | ||||
|     uint8_t needsWrite; | ||||
|     uint8_t needsRead; | ||||
| } StructFieldMapValue; | ||||
| 
 | ||||
| typedef struct StructFieldMap | ||||
|  | @ -41,7 +43,7 @@ static void AddStruct(LLVMValueRef wStructPointer) | |||
|     structFieldMapCount += 1; | ||||
| } | ||||
| 
 | ||||
| static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index) | ||||
| static void AddStructFieldName(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name, uint32_t index) | ||||
| { | ||||
|     uint32_t i, fieldCount; | ||||
| 
 | ||||
|  | @ -51,18 +53,13 @@ static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, | |||
|         { | ||||
|             fieldCount = structFieldMaps[i].fieldCount; | ||||
| 
 | ||||
|             LLVMValueRef elementPointer = LLVMBuildStructGEP( | ||||
|                 builder, | ||||
|                 wStructPointer, | ||||
|                 fieldCount, | ||||
|                 "ptr" | ||||
|             ); | ||||
| 
 | ||||
|             structFieldMaps[i].fields = realloc(structFieldMaps[i].fields, sizeof(StructFieldMapValue) * (fieldCount + 1)); | ||||
|             structFieldMaps[i].fields[fieldCount].name = strdup(name); | ||||
|             structFieldMaps[i].fields[fieldCount].value = LLVMBuildLoad(builder, elementPointer, name); | ||||
|             structFieldMaps[i].fields[fieldCount].valuePointer = elementPointer; | ||||
|             structFieldMaps[i].fields[fieldCount].value = NULL; | ||||
|             structFieldMaps[i].fields[fieldCount].valuePointer = NULL; | ||||
|             structFieldMaps[i].fields[fieldCount].index = index; | ||||
|             structFieldMaps[i].fields[fieldCount].needsWrite = 0; | ||||
|             structFieldMaps[i].fields[fieldCount].needsRead = 1; | ||||
|             structFieldMaps[i].fieldCount += 1; | ||||
| 
 | ||||
|             break; | ||||
|  | @ -70,6 +67,44 @@ static void AddStructField(LLVMBuilderRef builder, LLVMValueRef wStructPointer, | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef CheckStructFieldAndLoad(LLVMBuilderRef builder, LLVMValueRef wStructPointer, char *name) | ||||
| { | ||||
|     uint32_t i, j; | ||||
| 
 | ||||
|     for (i = 0; i < structFieldMapCount; i += 1) | ||||
|     { | ||||
|         if (structFieldMaps[i].structPointer == wStructPointer) | ||||
|         { | ||||
|             for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) | ||||
|             { | ||||
|                 if (strcmp(structFieldMaps[i].fields[j].name, name) == 0) | ||||
|                 { | ||||
|                     if (structFieldMaps[i].fields[j].needsRead) | ||||
|                     { | ||||
|                         char *ptrName = strdup(name); | ||||
|                         strcat(ptrName, "_ptr"); | ||||
|                         LLVMValueRef elementPointer = LLVMBuildStructGEP( | ||||
|                             builder, | ||||
|                             wStructPointer, | ||||
|                             structFieldMaps[i].fields[j].index, | ||||
|                             ptrName | ||||
|                         ); | ||||
|                         free(ptrName); | ||||
| 
 | ||||
|                         structFieldMaps[i].fields[j].value = LLVMBuildLoad(builder, elementPointer, name); | ||||
|                         structFieldMaps[i].fields[j].valuePointer = elementPointer; | ||||
|                         structFieldMaps[i].fields[j].needsRead = 0; | ||||
|                     } | ||||
| 
 | ||||
|                     return structFieldMaps[i].fields[j].value; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| static void MarkStructFieldForWrite(LLVMValueRef wStructPointer, LLVMValueRef value) | ||||
| { | ||||
|     uint32_t i, j; | ||||
|  | @ -168,9 +203,10 @@ static void AddNamedVariable(char *name, LLVMValueRef variable) | |||
|     namedVariableCount += 1; | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef FindVariableByName(LLVMValueRef wStructValue, LLVMBuilderRef builder, char *name) | ||||
| static LLVMValueRef FindVariableByName(LLVMBuilderRef builder, LLVMValueRef wStructValue, char *name) | ||||
| { | ||||
|     uint32_t i, j; | ||||
|     LLVMValueRef searchResult; | ||||
| 
 | ||||
|     /* first, search scoped vars */ | ||||
|     for (i = 0; i < namedVariableCount; i += 1) | ||||
|  | @ -182,22 +218,14 @@ static LLVMValueRef FindVariableByName(LLVMValueRef wStructValue, LLVMBuilderRef | |||
|     } | ||||
| 
 | ||||
|     /* if none exist, search struct vars */ | ||||
|     for (i = 0; i < structFieldMapCount; i += 1) | ||||
|     searchResult = CheckStructFieldAndLoad(builder, wStructValue, name); | ||||
| 
 | ||||
|     if (searchResult == NULL) | ||||
|     { | ||||
|         if (structFieldMaps[i].structPointer == wStructValue) | ||||
|         { | ||||
|             for (j = 0; j < structFieldMaps[i].fieldCount; j += 1) | ||||
|             { | ||||
|                 if (strcmp(structFieldMaps[i].fields[j].name, name) == 0) | ||||
|                 { | ||||
|                     return structFieldMaps[i].fields[j].value; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         fprintf(stderr, "Identifier not found!"); | ||||
|     } | ||||
| 
 | ||||
|     fprintf(stderr, "Identifier not found!"); | ||||
|     return NULL; | ||||
|     return searchResult; | ||||
| } | ||||
| 
 | ||||
| static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) | ||||
|  | @ -267,7 +295,7 @@ static LLVMValueRef CompileFunctionCallExpression( | |||
|         args[i] = CompileExpression(wStructValue, builder, function, expression->children[1]->children[i]); | ||||
|     } | ||||
| 
 | ||||
|     return LLVMBuildCall(builder, FindVariableByName(wStructValue, builder, expression->children[0]->value.string), args, argumentCount, "tmp"); | ||||
|     return LLVMBuildCall(builder, FindVariableByName(builder, wStructValue, expression->children[0]->value.string), args, argumentCount, "tmp"); | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef CompileExpression( | ||||
|  | @ -287,7 +315,7 @@ static LLVMValueRef CompileExpression( | |||
|             return CompileFunctionCallExpression(wStructValue, builder, function, expression); | ||||
| 
 | ||||
|         case Identifier: | ||||
|             return FindVariableByName(wStructValue, builder, expression->value.string); | ||||
|             return FindVariableByName(builder, wStructValue, expression->value.string); | ||||
| 
 | ||||
|         case Number: | ||||
|             return CompileNumber(expression); | ||||
|  | @ -380,7 +408,7 @@ static void CompileFunction( | |||
| 
 | ||||
|     for (i = 0; i < fieldDeclarationCount; i += 1) | ||||
|     { | ||||
|         AddStructField(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i); | ||||
|         AddStructFieldName(builder, wStructPointer, fieldDeclarations[i]->children[1]->value.string, i); | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < functionBody->childCount; i += 1) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue