emitting linkable object code

generics
cosmonaut 2021-04-22 10:27:39 -07:00
parent c2efcbd7d2
commit 28402f534a
1 changed files with 69 additions and 8 deletions

View File

@ -11,6 +11,7 @@
#include <llvm-c/Transforms/Scalar.h> #include <llvm-c/Transforms/Scalar.h>
#include <llvm-c/Transforms/Utils.h> #include <llvm-c/Transforms/Utils.h>
#include <llvm-c/TargetMachine.h> #include <llvm-c/TargetMachine.h>
#include <llvm-c/Target.h>
#include "y.tab.h" #include "y.tab.h"
#include "ast.h" #include "ast.h"
@ -480,6 +481,7 @@ static uint8_t CompileStatement(LLVMBuilderRef builder, LLVMValueRef function, N
static void CompileFunction( static void CompileFunction(
LLVMModuleRef module, LLVMModuleRef module,
char *parentStructName,
LLVMTypeRef wStructPointerType, LLVMTypeRef wStructPointerType,
Node **fieldDeclarations, Node **fieldDeclarations,
uint32_t fieldDeclarationCount, uint32_t fieldDeclarationCount,
@ -522,7 +524,12 @@ static void CompileFunction(
LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type); LLVMTypeRef returnType = WraithTypeToLLVMType(functionSignature->children[1]->type);
LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0); LLVMTypeRef functionType = LLVMFunctionType(returnType, paramTypes, paramIndex, 0);
LLVMValueRef function = LLVMAddFunction(module, functionSignature->children[0]->value.string, functionType);
char *functionName = strdup(parentStructName);
strcat(functionName, "_");
strcat(functionName, functionSignature->children[0]->value.string);
LLVMValueRef function = LLVMAddFunction(module, functionName, functionType);
free(functionName);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry");
LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMBuilderRef builder = LLVMCreateBuilder();
@ -560,6 +567,8 @@ static void CompileFunction(
} }
PopScopeFrame(scope); PopScopeFrame(scope);
LLVMDisposeBuilder(builder);
} }
static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node) static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *node)
@ -571,10 +580,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
LLVMTypeRef types[declarationCount]; LLVMTypeRef types[declarationCount];
Node *currentDeclarationNode; Node *currentDeclarationNode;
Node *fieldDeclarations[declarationCount]; Node *fieldDeclarations[declarationCount];
char *structName = node->children[0]->value.string;
PushScopeFrame(scope); PushScopeFrame(scope);
LLVMTypeRef wStruct = LLVMStructCreateNamed(context, node->children[0]->value.string); LLVMTypeRef wStruct = LLVMStructCreateNamed(context, structName);
LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */ LLVMTypeRef wStructPointerType = LLVMPointerType(wStruct, 0); /* FIXME: is this address space correct? */
/* first, build the structure definition */ /* first, build the structure definition */
@ -604,7 +614,7 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no
switch (currentDeclarationNode->syntaxKind) switch (currentDeclarationNode->syntaxKind)
{ {
case FunctionDeclaration: case FunctionDeclaration:
CompileFunction(module, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode); CompileFunction(module, structName, wStructPointerType, fieldDeclarations, fieldCount, currentDeclarationNode);
break; break;
} }
} }
@ -659,13 +669,46 @@ int main(int argc, char *argv[])
Compile(module, context, rootNode); Compile(module, context, rootNode);
/* add main call */
LLVMBuilderRef builder = LLVMCreateBuilder();
LLVMTypeRef mainFunctionType = LLVMFunctionType(LLVMInt64Type(), NULL, 0, 0);
LLVMValueRef mainFunction = LLVMAddFunction(module, "main", mainFunctionType);
LLVMBasicBlockRef entry = LLVMAppendBasicBlock(mainFunction, "entry");
LLVMPositionBuilderAtEnd(builder, entry);
LLVMValueRef wraithMainFunction = LLVMGetNamedFunction(module, "Program_Main");
LLVMValueRef mainResult = LLVMBuildCall(builder, wraithMainFunction, NULL, 0, "result");
LLVMBuildRet(builder, mainResult);
LLVMDisposeBuilder(builder);
/* verify */
char *error = NULL; char *error = NULL;
LLVMVerifyModule(module, LLVMAbortProcessAction, &error); LLVMVerifyModule(module, LLVMAbortProcessAction, &error);
/* prepare to emit assembly */
LLVMInitializeNativeTarget();
LLVMInitializeAllTargetInfos();
LLVMInitializeAllTargets();
LLVMInitializeAllTargetMCs();
LLVMInitializeAllAsmParsers();
LLVMInitializeAllAsmPrinters();
LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE); LLVMSetTarget(module, LLVM_DEFAULT_TARGET_TRIPLE);
LLVMTargetRef target;
if (LLVMGetTargetFromTriple(LLVM_DEFAULT_TARGET_TRIPLE, &target, &error) != 0)
{
fprintf(stderr, "Failed to get target!\n");
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
return 1;
}
LLVMPassManagerRef passManager = LLVMCreatePassManager(); LLVMPassManagerRef passManager = LLVMCreatePassManager();
LLVMAddInstructionCombiningPass(passManager);
//LLVMAddInstructionCombiningPass(passManager);
LLVMAddCFGSimplificationPass(passManager); LLVMAddCFGSimplificationPass(passManager);
LLVMAddReassociatePass(passManager); LLVMAddReassociatePass(passManager);
LLVMAddPromoteMemoryToRegisterPass(passManager); LLVMAddPromoteMemoryToRegisterPass(passManager);
@ -680,11 +723,29 @@ int main(int argc, char *argv[])
fprintf(stderr, "error writing bitcode to file\n"); fprintf(stderr, "error writing bitcode to file\n");
} }
LLVMMemoryBufferRef memoryBuffer = LLVMWriteBitcodeToMemoryBuffer(module); char *cpu = "generic";
LLVMCreateBinary(memoryBuffer, context, &error); char *features = "";
LLVMDisposeMessage(error);
LLVMDisposeMemoryBuffer(memoryBuffer);
LLVMTargetMachineRef targetMachine = LLVMCreateTargetMachine(
target,
LLVM_DEFAULT_TARGET_TRIPLE,
cpu,
features,
LLVMCodeGenLevelDefault,
LLVMRelocDefault,
LLVMCodeModelDefault
);
if (LLVMTargetMachineEmitToFile(targetMachine, module, "test.o", LLVMObjectFile, &error) != 0)
{
fprintf(stderr, "Failed to emit machine code!\n");
fprintf(stderr, "%s\n", error);
LLVMDisposeMessage(error);
return 1;
}
LLVMDisposeMessage(error);
LLVMDisposeTargetMachine(targetMachine);
LLVMPassManagerBuilderDispose(passManagerBuilder); LLVMPassManagerBuilderDispose(passManagerBuilder);
LLVMDisposePassManager(passManager); LLVMDisposePassManager(passManager);
LLVMDisposeModule(module); LLVMDisposeModule(module);