Compiler works even better now; we're missing a few functions at runtime, but at least the module appears to generate correctly
This commit is contained in:
@@ -14,7 +14,7 @@ if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/vendor/llvm/llvm/CMakeLists.txt")
|
||||
message(STATUS "Using vendored LLVM")
|
||||
set(LLVM_ENABLE_PROJECTS "" CACHE STRING "" FORCE)
|
||||
set(LLVM_ENABLE_RUNTIMES "" CACHE STRING "" FORCE)
|
||||
set(LLVM_BUILD_TOOLS NO CACHE BOOL "" FORCE)
|
||||
set(LLVM_BUILD_TOOLS YES CACHE BOOL "" FORCE)
|
||||
|
||||
set(LLVM_TARGETS_TO_BUILD "X86;ARM;AArch64" CACHE STRING "" FORCE)
|
||||
set(LLVM_INCLUDE_BENCHMARKS NO CACHE BOOL "" FORCE)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <llvm/Support/Error.h>
|
||||
#include "bluebell.hpp"
|
||||
#include "pre-compiler.hpp"
|
||||
#include "compiler.hpp"
|
||||
@@ -47,6 +49,13 @@ int main(int argc, char** argv) {
|
||||
|
||||
auto shader = pre_compile_shader(shader_src.str());
|
||||
Compiler compiler;
|
||||
compiler.compile(*shader);
|
||||
auto module = compiler.compile(*shader);
|
||||
if (!module) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to build module";
|
||||
}
|
||||
Runtime runtime;
|
||||
if(auto err = runtime.set_module(std::move(module.getValue()))) {
|
||||
report_fatal_error(std::move(err), false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#include "compiler.hpp"
|
||||
#include <llvm/Bitcode/BitcodeWriter.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
@@ -855,6 +856,7 @@ public:
|
||||
finish_tgv();
|
||||
auto ftype = types[OP_WORD(3)];
|
||||
auto ftype_llvm = (llvm::FunctionType*)ftype->get_llvm_type();
|
||||
BOOST_LOG_TRIVIAL(debug) << "Vivifying function for OpFunction";
|
||||
cur_function = vivify_function(ftype_llvm, OP_WORD(1));
|
||||
if (!cur_function->function->empty()) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Started assembling into " << cur_function->function->getName().str()
|
||||
@@ -889,7 +891,8 @@ public:
|
||||
types[OP_WORD(0)]->get_llvm_type(),
|
||||
arg_types,
|
||||
false);
|
||||
auto fn = vivify_function(ftype, OP_WORD(3));
|
||||
BOOST_LOG_TRIVIAL(debug) << "Vivifying function for OpFunctionCall";
|
||||
auto fn = vivify_function(ftype, OP_WORD(2));
|
||||
put_value(rid, builder->CreateCall(fn->function, arg_values));
|
||||
break;
|
||||
}
|
||||
@@ -1317,13 +1320,22 @@ Compiler::Compiler() {
|
||||
}
|
||||
|
||||
llvm::Optional<llvm::orc::ThreadSafeModule> Compiler::compile(std::vector<uint32_t> &spv_module) {
|
||||
std::error_code err_code;
|
||||
auto impl = std::make_unique<CompilerImpl>();
|
||||
auto ret = impl->process_module(spv_module);
|
||||
impl->generate_support();
|
||||
|
||||
llvm::verifyModule(*impl->module);
|
||||
llvm::raw_fd_ostream bc_stream("shader.bc", err_code);
|
||||
if (err_code) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to write bitcode";
|
||||
} else {
|
||||
llvm::WriteBitcodeToFile(*impl->module, bc_stream);
|
||||
bc_stream.flush();
|
||||
bc_stream.close();
|
||||
}
|
||||
|
||||
impl->module->print(llvm::outs(), nullptr, false, true);
|
||||
// impl->module->print(llvm::outs(), nullptr, false, true);
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Optimizing";
|
||||
// start generating machine code
|
||||
@@ -1358,10 +1370,17 @@ llvm::Optional<llvm::orc::ThreadSafeModule> Compiler::compile(std::vector<uint32
|
||||
// pass.add(llvm::createLICMPass());
|
||||
|
||||
pass_builder.populateModulePassManager(pass);
|
||||
llvm::raw_fd_ostream bc_opt_stream("shader.opt.bc", err_code);
|
||||
if (err_code) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to write optimized bitcode";
|
||||
} else {
|
||||
llvm::WriteBitcodeToFile(*impl->module, bc_opt_stream);
|
||||
bc_opt_stream.flush();
|
||||
bc_opt_stream.close();
|
||||
}
|
||||
|
||||
// add output to object file
|
||||
std::error_code err_code;
|
||||
llvm::raw_fd_ostream objfile("shader.o", err_code);
|
||||
llvm::raw_fd_ostream asfile("shader.s", err_code);
|
||||
if (err_code) {
|
||||
BOOST_LOG_TRIVIAL(error) << "Failed to open object file: " << err_code.message();
|
||||
|
||||
@@ -1375,7 +1394,6 @@ llvm::Optional<llvm::orc::ThreadSafeModule> Compiler::compile(std::vector<uint32
|
||||
}
|
||||
pass.run(*impl->module);
|
||||
objfile.flush();
|
||||
asfile.flush();
|
||||
|
||||
// impl->module->print(llvm::outs(), nullptr, false, true);
|
||||
return {llvm::orc::ThreadSafeModule(std::move(impl->module),
|
||||
@@ -1385,7 +1403,7 @@ llvm::Optional<llvm::orc::ThreadSafeModule> Compiler::compile(std::vector<uint32
|
||||
Compiler::~Compiler() = default;
|
||||
|
||||
FunctionContext::FunctionContext(struct CompilerImpl &compiler, llvm::FunctionType *ftype, uint32_t id) {
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Creating function for id " << id;
|
||||
bool is_ep = false;
|
||||
std::string name;
|
||||
auto linkage = llvm::Function::ExternalLinkage;
|
||||
@@ -1393,13 +1411,16 @@ FunctionContext::FunctionContext(struct CompilerImpl &compiler, llvm::FunctionTy
|
||||
if (ep.second->func_id == id) {
|
||||
is_ep = true;
|
||||
name = ep.second->name;
|
||||
linkage = llvm::Function::ExternalLinkage;
|
||||
// The entry point is not *actually* being used as an entry point; we use a wrapper to stuff and unload
|
||||
// the context using details known only at compile-time
|
||||
// linkage = llvm::Function::ExternalLinkage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (name.empty()) {
|
||||
auto it = compiler.value_names.find(id);
|
||||
if (it != compiler.value_names.end()) {
|
||||
BOOST_LOG_TRIVIAL(debug) << "Name based on value_names";
|
||||
name = it->second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
#include <llvm/Transforms/IPO.h>
|
||||
#include <llvm/Transforms/Utils.h>
|
||||
#include <llvm/ExecutionEngine/Orc/LLJIT.h>
|
||||
#include <cmath>
|
||||
|
||||
// we need libm, so import it
|
||||
struct RuntimeImpl {
|
||||
|
||||
std::unique_ptr<llvm::legacy::PassManager> passManager;
|
||||
@@ -47,9 +49,13 @@ struct RuntimeImpl {
|
||||
if (auto err = jit->addIRModule(std::move(mod))) {
|
||||
return err;
|
||||
}
|
||||
auto sym = jit->lookup("setup");
|
||||
llvm::JITEvaluatedSymbol get_context_size;
|
||||
|
||||
float foo = cosf(0.);
|
||||
|
||||
if (auto err = jit->lookup("get_context_size").moveInto(get_context_size)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
@@ -58,6 +64,7 @@ struct RuntimeImpl {
|
||||
Runtime::Runtime(): impl(std::make_unique<RuntimeImpl>()) {
|
||||
|
||||
}
|
||||
Runtime::~Runtime() = default;
|
||||
|
||||
llvm::Error Runtime::set_module(llvm::orc::ThreadSafeModule module) {
|
||||
return impl->setModule(std::move(module));
|
||||
|
||||
@@ -26,10 +26,10 @@ class Runtime {
|
||||
// the compiler will construct this from its internals
|
||||
friend class Compiler;
|
||||
std::unique_ptr<struct RuntimeImpl> impl;
|
||||
protected:
|
||||
Runtime();
|
||||
|
||||
public:
|
||||
Runtime();
|
||||
~Runtime();
|
||||
|
||||
llvm::Error set_module(llvm::orc::ThreadSafeModule module);
|
||||
void render_frame(const Uniforms &uniforms, float buf[32][32][3]);
|
||||
};
|
||||
Reference in New Issue
Block a user