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