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:
2022-05-26 21:30:57 +02:00
parent bac33a2a14
commit d9a4e8085b
5 changed files with 50 additions and 13 deletions

View File

@@ -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)

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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));

View File

@@ -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]);
};