forked from cosmonaut/wraith-lang
emitting linkable object code
parent
c2efcbd7d2
commit
28402f534a
77
compiler.c
77
compiler.c
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue