diff options
author | David Robillard <d@drobilla.net> | 2010-12-09 00:29:04 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2010-12-09 00:29:04 +0000 |
commit | 82dc3a0291d993b5a1dd803aae8d166f263d7da2 (patch) | |
tree | d2406fa0005650bf7cb8a878cffde648450631c5 /src/llvm.cpp | |
parent | 9505e74e3a46eb0b5b1d2e0cce4d9a5092ebedc9 (diff) | |
download | resp-82dc3a0291d993b5a1dd803aae8d166f263d7da2.tar.gz resp-82dc3a0291d993b5a1dd803aae8d166f263d7da2.tar.bz2 resp-82dc3a0291d993b5a1dd803aae8d166f263d7da2.zip |
Tidy.
git-svn-id: http://svn.drobilla.net/resp/resp@319 ad02d1e2-f140-0410-9f75-f8b11f17cedd
Diffstat (limited to 'src/llvm.cpp')
-rw-r--r-- | src/llvm.cpp | 214 |
1 files changed, 107 insertions, 107 deletions
diff --git a/src/llvm.cpp b/src/llvm.cpp index eeb584c..df755b3 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -83,114 +83,25 @@ struct LLVMEngine : public Engine { inline Value* llVal(CVal v) { return static_cast<Value*>(v); } inline Function* llFunc(CFunc f) { return static_cast<Function*>(f); } - - const Type* - llType(const AType* t) - { - if (t == NULL) { - return NULL; - } else if (t->kind == AType::PRIM) { - if (t->head()->str() == "Nothing") return Type::getVoidTy(context); - if (t->head()->str() == "Bool") return Type::getInt1Ty(context); - if (t->head()->str() == "Int") return Type::getInt32Ty(context); - if (t->head()->str() == "Float") return Type::getFloatTy(context); - if (t->head()->str() == "String") return PointerType::get(Type::getInt8Ty(context), NULL); - if (t->head()->str() == "Quote") return PointerType::get(Type::getInt8Ty(context), NULL); - throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'"); - } else if (t->kind == AType::EXPR && t->head()->str() == "Fn") { - AType::const_iterator i = t->begin(); - const ATuple* protT = (*++i)->to_tuple(); - const AType* retT = (*++i)->as_type(); - if (!llType(retT)) - return NULL; - - vector<const Type*> cprot; - FOREACHP(ATuple::const_iterator, i, protT) { - const Type* lt = llType((*i)->to_type()); - if (!lt) - return NULL; - cprot.push_back(lt); - } - - return PointerType::get(FunctionType::get(llType(retT), cprot, false), 0); - } else if (t->kind == AType::EXPR && isupper(t->head()->str()[0])) { - vector<const Type*> ctypes; - ctypes.push_back(PointerType::get(Type::getInt8Ty(context), NULL)); // RTTI - for (AType::const_iterator i = t->iter_at(1); i != t->end(); ++i) { - const Type* lt = llType((*i)->to_type()); - if (!lt) - return NULL; - ctypes.push_back(lt); - } - - return PointerType::get(StructType::get(context, ctypes, false), 0); - } else if (t->kind == AType::NAME) { - assert(false); - } - assert(false); - return PointerType::get(Type::getInt8Ty(context), NULL); - } + const Type* llType(const AType* t); CFunc startFunction( - CEnv& cenv, const std::string& name, const ATuple* args, const AType* type) - { - const AType* argsT = type->prot()->as_type(); - const AType* retT = type->list_last()->as_type(); - - Function::LinkageTypes linkage = Function::ExternalLinkage; - - vector<const Type*> cprot; - FOREACHP(ATuple::const_iterator, i, argsT) { - const AType* at = (*i)->as_type(); - THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ") - + at->str()) - cprot.push_back(llType(at)); - } - - THROW_IF(!llType(retT), Cursor(), - (format("return has non-concrete type `%1%'") % retT->str()).str()); + CEnv& cenv, const std::string& name, const ATuple* args, const AType* type); - const string llName = (name == "") ? cenv.penv.gensymstr("_fn") : name; - - FunctionType* fT = FunctionType::get(llType(retT), cprot, false); - Function* f = Function::Create(fT, linkage, llName, module); - - // Note f->getName() may be different from llName - // however LLVM chooses to mangle is fine, we keep a pointer - - // Set argument names in generated code - Function::arg_iterator a = f->arg_begin(); - for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i) - a->setName((*i)->as_symbol()->cppstr); + void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f); - BasicBlock* bb = BasicBlock::Create(context, "entry", f); - builder.SetInsertPoint(bb); + void finishFunction(CEnv& cenv, CFunc f, CVal ret); - return f; + void eraseFunction(CEnv& cenv, CFunc f) { + if (f) + llFunc(f)->eraseFromParent(); } - - void pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc f); void appendBlock(LLVMEngine* engine, Function* function, BasicBlock* block) { function->getBasicBlockList().push_back(block); engine->builder.SetInsertPoint(block); } - void finishFunction(CEnv& cenv, CFunc f, CVal ret) { - builder.CreateRet(llVal(ret)); - if (verifyFunction(*static_cast<Function*>(f), llvm::PrintMessageAction)) { - module->dump(); - throw Error(Cursor(), "Broken module"); - } - if (cenv.args.find("-g") == cenv.args.end()) - opt->run(*static_cast<Function*>(f)); - } - - void eraseFunction(CEnv& cenv, CFunc f) { - if (f) - llFunc(f)->eraseFromParent(); - } - CVal compileCall(CEnv& cenv, CFunc f, const AType* funcT, const vector<CVal>& args) { vector<Value*> llArgs(*reinterpret_cast<const vector<Value*>*>(&args)); Value* closure = builder.CreateBitCast(llArgs[0], @@ -220,14 +131,9 @@ struct LLVMEngine : public Engine { IfBranches branches; }; - IfState - compileIfStart(CEnv& cenv); - - void - compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then); - - CVal - compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type); + IfState compileIfStart(CEnv& cenv); + void compileIfBranch(CEnv& cenv, IfState state, CVal condV, const AST* then); + CVal compileIfEnd(CEnv& cenv, IfState state, CVal elseV, const AType* type); void writeModule(CEnv& cenv, std::ostream& os) { AssemblyAnnotationWriter writer; @@ -286,9 +192,52 @@ resp_new_llvm_engine() return new LLVMEngine(); } -/*************************************************************************** - * Code Generation * - ***************************************************************************/ +const Type* +LLVMEngine::llType(const AType* t) +{ + if (t == NULL) { + return NULL; + } else if (t->kind == AType::PRIM) { + if (t->head()->str() == "Nothing") return Type::getVoidTy(context); + if (t->head()->str() == "Bool") return Type::getInt1Ty(context); + if (t->head()->str() == "Int") return Type::getInt32Ty(context); + if (t->head()->str() == "Float") return Type::getFloatTy(context); + if (t->head()->str() == "String") return PointerType::get(Type::getInt8Ty(context), NULL); + if (t->head()->str() == "Quote") return PointerType::get(Type::getInt8Ty(context), NULL); + throw Error(t->loc, string("Unknown primitive type `") + t->str() + "'"); + } else if (t->kind == AType::EXPR && t->head()->str() == "Fn") { + AType::const_iterator i = t->begin(); + const ATuple* protT = (*++i)->to_tuple(); + const AType* retT = (*++i)->as_type(); + if (!llType(retT)) + return NULL; + + vector<const Type*> cprot; + FOREACHP(ATuple::const_iterator, i, protT) { + const Type* lt = llType((*i)->to_type()); + if (!lt) + return NULL; + cprot.push_back(lt); + } + + return PointerType::get(FunctionType::get(llType(retT), cprot, false), 0); + } else if (t->kind == AType::EXPR && isupper(t->head()->str()[0])) { + vector<const Type*> ctypes; + ctypes.push_back(PointerType::get(Type::getInt8Ty(context), NULL)); // RTTI + for (AType::const_iterator i = t->iter_at(1); i != t->end(); ++i) { + const Type* lt = llType((*i)->to_type()); + if (!lt) + return NULL; + ctypes.push_back(lt); + } + + return PointerType::get(StructType::get(context, ctypes, false), 0); + } else if (t->kind == AType::NAME) { + assert(false); + } + assert(false); + return PointerType::get(Type::getInt8Ty(context), NULL); +} /** Convert a size in bits to bytes, rounding up as necessary */ static inline size_t @@ -351,6 +300,45 @@ LLVMEngine::compileString(CEnv& cenv, const char* str) return builder.CreateGlobalStringPtr(str); } +CFunc +LLVMEngine::startFunction( + CEnv& cenv, const std::string& name, const ATuple* args, const AType* type) +{ + const AType* argsT = type->prot()->as_type(); + const AType* retT = type->list_last()->as_type(); + + Function::LinkageTypes linkage = Function::ExternalLinkage; + + vector<const Type*> cprot; + FOREACHP(ATuple::const_iterator, i, argsT) { + const AType* at = (*i)->as_type(); + THROW_IF(!llType(at), Cursor(), string("non-concrete parameter :: ") + + at->str()) + cprot.push_back(llType(at)); + } + + THROW_IF(!llType(retT), Cursor(), + (format("return has non-concrete type `%1%'") % retT->str()).str()); + + const string llName = (name == "") ? cenv.penv.gensymstr("_fn") : name; + + FunctionType* fT = FunctionType::get(llType(retT), cprot, false); + Function* f = Function::Create(fT, linkage, llName, module); + + // Note f->getName() may be different from llName + // however LLVM chooses to mangle is fine, we keep a pointer + + // Set argument names in generated code + Function::arg_iterator a = f->arg_begin(); + for (ATuple::const_iterator i = args->begin(); i != args->end(); ++a, ++i) + a->setName((*i)->as_symbol()->cppstr); + + BasicBlock* bb = BasicBlock::Create(context, "entry", f); + builder.SetInsertPoint(bb); + + return f; +} + void LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, CFunc cfunc) { @@ -371,6 +359,18 @@ LLVMEngine::pushFunctionArgs(CEnv& cenv, const ATuple* prot, const AType* type, } } +void +LLVMEngine::finishFunction(CEnv& cenv, CFunc f, CVal ret) +{ + builder.CreateRet(llVal(ret)); + if (verifyFunction(*static_cast<Function*>(f), llvm::PrintMessageAction)) { + module->dump(); + throw Error(Cursor(), "Broken module"); + } + if (cenv.args.find("-g") == cenv.args.end()) + opt->run(*static_cast<Function*>(f)); +} + IfState LLVMEngine::compileIfStart(CEnv& cenv) { |