mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 13:31:07 +00:00
Make LLVM compile and optimize for the current CPU
This commit is contained in:
parent
4f2ae42ed5
commit
d5c7a7ab76
3 changed files with 75 additions and 26 deletions
|
@ -13,36 +13,75 @@
|
|||
|
||||
RenderProgram::RenderProgram()
|
||||
{
|
||||
llvm::install_fatal_error_handler([](void *user_data, const std::string& reason, bool gen_crash_diag) {
|
||||
I_FatalError(reason.c_str());
|
||||
using namespace llvm;
|
||||
|
||||
install_fatal_error_handler([](void *user_data, const std::string& reason, bool gen_crash_diag) {
|
||||
I_FatalError("LLVM fatal error: %s", reason.c_str());
|
||||
});
|
||||
|
||||
//llvm::llvm_start_multithreaded();
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
llvm::InitializeNativeTargetAsmParser();
|
||||
|
||||
mContext = std::make_unique<llvm::LLVMContext>();
|
||||
|
||||
auto moduleOwner = std::make_unique<llvm::Module>("render", context());
|
||||
mModule = moduleOwner.get();
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
InitializeNativeTargetAsmParser();
|
||||
|
||||
std::string errorstring;
|
||||
llvm::EngineBuilder engineBuilder(std::move(moduleOwner));
|
||||
|
||||
std::string targetTriple = sys::getProcessTriple();
|
||||
std::string cpuName = sys::getHostCPUName();
|
||||
StringMap<bool> cpuFeatures;
|
||||
sys::getHostCPUFeatures(cpuFeatures);
|
||||
std::string cpuFeaturesStr;
|
||||
for (const auto &it : cpuFeatures)
|
||||
{
|
||||
if (!cpuFeaturesStr.empty())
|
||||
cpuFeaturesStr.push_back(' ');
|
||||
cpuFeaturesStr.push_back(it.getValue() ? '+' : '-');
|
||||
cpuFeaturesStr += it.getKey();
|
||||
}
|
||||
|
||||
Printf("LLVM target triple: %s\n", targetTriple.c_str());
|
||||
Printf("LLVM CPU and features: %s, %s\n", cpuName.c_str(), cpuFeaturesStr.c_str());
|
||||
|
||||
const Target *target = TargetRegistry::lookupTarget(targetTriple, errorstring);
|
||||
if (!target)
|
||||
I_FatalError("Could not find LLVM target: %s", errorstring.c_str());
|
||||
|
||||
TargetOptions opt;
|
||||
auto relocModel = Optional<Reloc::Model>(Reloc::Static);
|
||||
TargetMachine *machine = target->createTargetMachine(targetTriple, cpuName, cpuFeaturesStr, opt, relocModel, CodeModel::Default, CodeGenOpt::Aggressive);
|
||||
if (!machine)
|
||||
I_FatalError("Could not create LLVM target machine");
|
||||
|
||||
mContext = std::make_unique<LLVMContext>();
|
||||
|
||||
auto moduleOwner = std::make_unique<Module>("render", context());
|
||||
mModule = moduleOwner.get();
|
||||
mModule->setTargetTriple(targetTriple);
|
||||
mModule->setDataLayout(machine->createDataLayout());
|
||||
|
||||
EngineBuilder engineBuilder(std::move(moduleOwner));
|
||||
engineBuilder.setErrorStr(&errorstring);
|
||||
engineBuilder.setOptLevel(llvm::CodeGenOpt::Aggressive);
|
||||
engineBuilder.setRelocationModel(llvm::Reloc::Static);
|
||||
engineBuilder.setEngineKind(llvm::EngineKind::JIT);
|
||||
mEngine.reset(engineBuilder.create());
|
||||
engineBuilder.setOptLevel(CodeGenOpt::Aggressive);
|
||||
engineBuilder.setRelocationModel(Reloc::Static);
|
||||
engineBuilder.setEngineKind(EngineKind::JIT);
|
||||
mEngine.reset(engineBuilder.create(machine));
|
||||
if (!mEngine)
|
||||
I_FatalError(errorstring.c_str());
|
||||
I_FatalError("Could not create LLVM execution engine: %s", errorstring.c_str());
|
||||
|
||||
mModulePassManager = std::make_unique<legacy::PassManager>();
|
||||
mFunctionPassManager = std::make_unique<legacy::FunctionPassManager>(mModule);
|
||||
|
||||
PassManagerBuilder passManagerBuilder;
|
||||
passManagerBuilder.OptLevel = 3;
|
||||
passManagerBuilder.SizeLevel = 0;
|
||||
passManagerBuilder.Inliner = createFunctionInliningPass();
|
||||
passManagerBuilder.populateModulePassManager(*mModulePassManager.get());
|
||||
passManagerBuilder.populateFunctionPassManager(*mFunctionPassManager.get());
|
||||
}
|
||||
|
||||
RenderProgram::~RenderProgram()
|
||||
{
|
||||
mEngine.reset();
|
||||
mContext.reset();
|
||||
//llvm::llvm_stop_multithreaded();
|
||||
}
|
||||
|
||||
void *RenderProgram::PointerToFunction(const char *name)
|
||||
|
@ -57,6 +96,7 @@ FixedFunction::FixedFunction()
|
|||
{
|
||||
CodegenDrawSpan();
|
||||
mProgram.engine()->finalizeObject();
|
||||
mProgram.modulePassManager()->run(*mProgram.module());
|
||||
|
||||
DrawSpan = mProgram.GetProcAddress<void(int, uint32_t *)>("DrawSpan");
|
||||
}
|
||||
|
@ -81,12 +121,12 @@ void FixedFunction::CodegenDrawSpan()
|
|||
SSAInt index = stack_index.load();
|
||||
loop.loop_block(index < count);
|
||||
|
||||
//SSAVec4i color(255, 255, 0, 255);
|
||||
//data[index * 4].store_vec4ub(color);
|
||||
data[index * 4].store(0);
|
||||
SSAVec4i color(0, 128, 255, 255);
|
||||
data[index * 4].store_vec4ub(color);
|
||||
/*data[index * 4].store(0);
|
||||
data[index * 4 + 1].store(128);
|
||||
data[index * 4 + 2].store(255);
|
||||
data[index * 4 + 3].store(255);
|
||||
data[index * 4 + 3].store(255);*/
|
||||
stack_index.store(index + 1);
|
||||
}
|
||||
loop.end_block();
|
||||
|
@ -95,6 +135,8 @@ void FixedFunction::CodegenDrawSpan()
|
|||
|
||||
if (llvm::verifyFunction(*function.func))
|
||||
I_FatalError("verifyFunction failed for " __FUNCTION__);
|
||||
|
||||
mProgram.functionPassManager()->run(*function.func);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -26,6 +26,8 @@ public:
|
|||
llvm::LLVMContext &context() { return *mContext; }
|
||||
llvm::Module *module() { return mModule; }
|
||||
llvm::ExecutionEngine *engine() { return mEngine.get(); }
|
||||
llvm::legacy::PassManager *modulePassManager() { return mModulePassManager.get(); }
|
||||
llvm::legacy::FunctionPassManager *functionPassManager() { return mFunctionPassManager.get(); }
|
||||
|
||||
private:
|
||||
void *PointerToFunction(const char *name);
|
||||
|
@ -33,6 +35,8 @@ private:
|
|||
std::unique_ptr<llvm::LLVMContext> mContext;
|
||||
llvm::Module *mModule;
|
||||
std::unique_ptr<llvm::ExecutionEngine> mEngine;
|
||||
std::unique_ptr<llvm::legacy::PassManager> mModulePassManager;
|
||||
std::unique_ptr<llvm::legacy::FunctionPassManager> mFunctionPassManager;
|
||||
};
|
||||
|
||||
class FixedFunction
|
||||
|
|
|
@ -20,19 +20,22 @@
|
|||
#pragma warning(disable: 4291) // warning C4291: 'void *llvm::User::operator new(std::size_t,unsigned int,unsigned int)': no matching operator delete found; memory will not be freed if initialization throws an exception
|
||||
|
||||
#include <llvm/IR/DerivedTypes.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/ExecutionEngine/MCJIT.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/Attributes.h>
|
||||
#include <llvm/IR/Verifier.h>
|
||||
#include <llvm/IR/PassManager.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/Intrinsics.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/ExecutionEngine/MCJIT.h>
|
||||
#include <llvm/Analysis/Passes.h>
|
||||
#include <llvm/Transforms/Scalar.h>
|
||||
#include <llvm/Transforms/IPO.h>
|
||||
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
||||
#include <llvm/Support/TargetSelect.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/Intrinsics.h>
|
||||
#include <llvm/Support/TargetRegistry.h>
|
||||
#include <llvm/CodeGen/AsmPrinter.h>
|
||||
#include <llvm/MC/MCAsmInfo.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue