mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +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()
|
RenderProgram::RenderProgram()
|
||||||
{
|
{
|
||||||
llvm::install_fatal_error_handler([](void *user_data, const std::string& reason, bool gen_crash_diag) {
|
using namespace llvm;
|
||||||
I_FatalError(reason.c_str());
|
|
||||||
|
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();
|
InitializeNativeTarget();
|
||||||
llvm::InitializeNativeTarget();
|
InitializeNativeTargetAsmPrinter();
|
||||||
llvm::InitializeNativeTargetAsmPrinter();
|
InitializeNativeTargetAsmParser();
|
||||||
llvm::InitializeNativeTargetAsmParser();
|
|
||||||
|
|
||||||
mContext = std::make_unique<llvm::LLVMContext>();
|
|
||||||
|
|
||||||
auto moduleOwner = std::make_unique<llvm::Module>("render", context());
|
|
||||||
mModule = moduleOwner.get();
|
|
||||||
|
|
||||||
std::string errorstring;
|
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.setErrorStr(&errorstring);
|
||||||
engineBuilder.setOptLevel(llvm::CodeGenOpt::Aggressive);
|
engineBuilder.setOptLevel(CodeGenOpt::Aggressive);
|
||||||
engineBuilder.setRelocationModel(llvm::Reloc::Static);
|
engineBuilder.setRelocationModel(Reloc::Static);
|
||||||
engineBuilder.setEngineKind(llvm::EngineKind::JIT);
|
engineBuilder.setEngineKind(EngineKind::JIT);
|
||||||
mEngine.reset(engineBuilder.create());
|
mEngine.reset(engineBuilder.create(machine));
|
||||||
if (!mEngine)
|
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()
|
RenderProgram::~RenderProgram()
|
||||||
{
|
{
|
||||||
mEngine.reset();
|
mEngine.reset();
|
||||||
mContext.reset();
|
mContext.reset();
|
||||||
//llvm::llvm_stop_multithreaded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *RenderProgram::PointerToFunction(const char *name)
|
void *RenderProgram::PointerToFunction(const char *name)
|
||||||
|
@ -57,6 +96,7 @@ FixedFunction::FixedFunction()
|
||||||
{
|
{
|
||||||
CodegenDrawSpan();
|
CodegenDrawSpan();
|
||||||
mProgram.engine()->finalizeObject();
|
mProgram.engine()->finalizeObject();
|
||||||
|
mProgram.modulePassManager()->run(*mProgram.module());
|
||||||
|
|
||||||
DrawSpan = mProgram.GetProcAddress<void(int, uint32_t *)>("DrawSpan");
|
DrawSpan = mProgram.GetProcAddress<void(int, uint32_t *)>("DrawSpan");
|
||||||
}
|
}
|
||||||
|
@ -81,12 +121,12 @@ void FixedFunction::CodegenDrawSpan()
|
||||||
SSAInt index = stack_index.load();
|
SSAInt index = stack_index.load();
|
||||||
loop.loop_block(index < count);
|
loop.loop_block(index < count);
|
||||||
|
|
||||||
//SSAVec4i color(255, 255, 0, 255);
|
SSAVec4i color(0, 128, 255, 255);
|
||||||
//data[index * 4].store_vec4ub(color);
|
data[index * 4].store_vec4ub(color);
|
||||||
data[index * 4].store(0);
|
/*data[index * 4].store(0);
|
||||||
data[index * 4 + 1].store(128);
|
data[index * 4 + 1].store(128);
|
||||||
data[index * 4 + 2].store(255);
|
data[index * 4 + 2].store(255);
|
||||||
data[index * 4 + 3].store(255);
|
data[index * 4 + 3].store(255);*/
|
||||||
stack_index.store(index + 1);
|
stack_index.store(index + 1);
|
||||||
}
|
}
|
||||||
loop.end_block();
|
loop.end_block();
|
||||||
|
@ -95,6 +135,8 @@ void FixedFunction::CodegenDrawSpan()
|
||||||
|
|
||||||
if (llvm::verifyFunction(*function.func))
|
if (llvm::verifyFunction(*function.func))
|
||||||
I_FatalError("verifyFunction failed for " __FUNCTION__);
|
I_FatalError("verifyFunction failed for " __FUNCTION__);
|
||||||
|
|
||||||
|
mProgram.functionPassManager()->run(*function.func);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -26,6 +26,8 @@ public:
|
||||||
llvm::LLVMContext &context() { return *mContext; }
|
llvm::LLVMContext &context() { return *mContext; }
|
||||||
llvm::Module *module() { return mModule; }
|
llvm::Module *module() { return mModule; }
|
||||||
llvm::ExecutionEngine *engine() { return mEngine.get(); }
|
llvm::ExecutionEngine *engine() { return mEngine.get(); }
|
||||||
|
llvm::legacy::PassManager *modulePassManager() { return mModulePassManager.get(); }
|
||||||
|
llvm::legacy::FunctionPassManager *functionPassManager() { return mFunctionPassManager.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *PointerToFunction(const char *name);
|
void *PointerToFunction(const char *name);
|
||||||
|
@ -33,6 +35,8 @@ private:
|
||||||
std::unique_ptr<llvm::LLVMContext> mContext;
|
std::unique_ptr<llvm::LLVMContext> mContext;
|
||||||
llvm::Module *mModule;
|
llvm::Module *mModule;
|
||||||
std::unique_ptr<llvm::ExecutionEngine> mEngine;
|
std::unique_ptr<llvm::ExecutionEngine> mEngine;
|
||||||
|
std::unique_ptr<llvm::legacy::PassManager> mModulePassManager;
|
||||||
|
std::unique_ptr<llvm::legacy::FunctionPassManager> mFunctionPassManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FixedFunction
|
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
|
#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/IR/DerivedTypes.h>
|
||||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
|
||||||
#include <llvm/ExecutionEngine/MCJIT.h>
|
|
||||||
#include <llvm/IR/LLVMContext.h>
|
#include <llvm/IR/LLVMContext.h>
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
#include <llvm/IR/Attributes.h>
|
#include <llvm/IR/Attributes.h>
|
||||||
#include <llvm/IR/Verifier.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/Analysis/Passes.h>
|
||||||
#include <llvm/Transforms/Scalar.h>
|
#include <llvm/Transforms/Scalar.h>
|
||||||
#include <llvm/Transforms/IPO.h>
|
#include <llvm/Transforms/IPO.h>
|
||||||
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
||||||
#include <llvm/Support/TargetSelect.h>
|
#include <llvm/Support/TargetSelect.h>
|
||||||
#include <llvm/IR/IRBuilder.h>
|
#include <llvm/Support/TargetRegistry.h>
|
||||||
#include <llvm/IR/Intrinsics.h>
|
|
||||||
#include <llvm/CodeGen/AsmPrinter.h>
|
#include <llvm/CodeGen/AsmPrinter.h>
|
||||||
#include <llvm/MC/MCAsmInfo.h>
|
#include <llvm/MC/MCAsmInfo.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue