mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2025-02-20 10:22:41 +00:00
Change object file generation to not use the JIT engine builder
This commit is contained in:
parent
cc94381366
commit
6cc33553c2
1 changed files with 51 additions and 83 deletions
|
@ -54,8 +54,7 @@ public:
|
||||||
LLVMProgram();
|
LLVMProgram();
|
||||||
|
|
||||||
void CreateModule();
|
void CreateModule();
|
||||||
std::string GenerateAssembly(std::string cpuName);
|
std::vector<uint8_t> GenerateObjectFile(const std::string &triple, const std::string &cpuName, const std::string &features);
|
||||||
std::vector<uint8_t> GenerateObjectFile(std::string cpuName);
|
|
||||||
std::string DumpModule();
|
std::string DumpModule();
|
||||||
|
|
||||||
llvm::LLVMContext &context() { return *mContext; }
|
llvm::LLVMContext &context() { return *mContext; }
|
||||||
|
@ -70,7 +69,7 @@ private:
|
||||||
class LLVMDrawers
|
class LLVMDrawers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LLVMDrawers(const std::string &cpuName, const std::string namePostfix);
|
LLVMDrawers(const std::string &triple, const std::string &cpuName, const std::string &features, const std::string namePostfix);
|
||||||
|
|
||||||
std::vector<uint8_t> ObjectFile;
|
std::vector<uint8_t> ObjectFile;
|
||||||
|
|
||||||
|
@ -97,7 +96,7 @@ private:
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
LLVMDrawers::LLVMDrawers(const std::string &cpuName, const std::string namePostfix) : mNamePostfix(namePostfix)
|
LLVMDrawers::LLVMDrawers(const std::string &triple, const std::string &cpuName, const std::string &features, const std::string namePostfix) : mNamePostfix(namePostfix)
|
||||||
{
|
{
|
||||||
mProgram.CreateModule();
|
mProgram.CreateModule();
|
||||||
|
|
||||||
|
@ -177,7 +176,7 @@ LLVMDrawers::LLVMDrawers(const std::string &cpuName, const std::string namePostf
|
||||||
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
|
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false);
|
||||||
CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false);
|
CodegenDrawTriangle("TriStencilClose", TriDrawVariant::StencilClose, TriBlendMode::Copy, false);
|
||||||
|
|
||||||
ObjectFile = mProgram.GenerateObjectFile(cpuName);
|
ObjectFile = mProgram.GenerateObjectFile(triple, cpuName, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMDrawers::CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method)
|
void LLVMDrawers::CodegenDrawColumn(const char *name, DrawColumnVariant variant, DrawColumnMethod method)
|
||||||
|
@ -459,92 +458,57 @@ void LLVMProgram::CreateModule()
|
||||||
mModule = std::make_unique<llvm::Module>("render", context());
|
mModule = std::make_unique<llvm::Module>("render", context());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LLVMProgram::GenerateAssembly(std::string cpuName)
|
std::vector<uint8_t> LLVMProgram::GenerateObjectFile(const std::string &triple, const std::string &cpuName, const std::string &features)
|
||||||
{
|
{
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
std::string errorstring;
|
std::string errorstring;
|
||||||
|
|
||||||
llvm::Module *module = mModule.get();
|
llvm::Module *module = mModule.get();
|
||||||
EngineBuilder engineBuilder(std::move(mModule));
|
|
||||||
engineBuilder.setErrorStr(&errorstring);
|
|
||||||
engineBuilder.setOptLevel(CodeGenOpt::Aggressive);
|
|
||||||
engineBuilder.setEngineKind(EngineKind::JIT);
|
|
||||||
engineBuilder.setMCPU(cpuName);
|
|
||||||
machine = engineBuilder.selectTarget();
|
|
||||||
if (!machine)
|
|
||||||
throw Exception("Could not create LLVM target machine");
|
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
const Target *target = TargetRegistry::lookupTarget(triple, errorstring);
|
||||||
std::string targetTriple = machine->getTargetTriple();
|
Optional<Reloc::Model> relocationModel = Reloc::PIC_;
|
||||||
#else
|
CodeModel::Model codeModel = CodeModel::Model::Default;
|
||||||
std::string targetTriple = machine->getTargetTriple().getTriple();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
module->setTargetTriple(targetTriple);
|
TargetOptions options;
|
||||||
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
options.LessPreciseFPMADOption = true;
|
||||||
module->setDataLayout(new DataLayout(*machine->getSubtargetImpl()->getDataLayout()));
|
options.AllowFPOpFusion = FPOpFusion::Fast;
|
||||||
#else
|
options.Reciprocals = TargetRecip({ "all" });
|
||||||
module->setDataLayout(machine->createDataLayout());
|
options.UnsafeFPMath = true;
|
||||||
#endif
|
options.NoInfsFPMath = true;
|
||||||
|
options.NoNaNsFPMath = true;
|
||||||
|
options.HonorSignDependentRoundingFPMathOption = false;
|
||||||
|
options.NoZerosInBSS = false;
|
||||||
|
options.GuaranteedTailCallOpt = false;
|
||||||
|
options.StackAlignmentOverride = 0;
|
||||||
|
options.StackSymbolOrdering = true;
|
||||||
|
options.UseInitArray = true;
|
||||||
|
options.DataSections = false;
|
||||||
|
options.FunctionSections = false;
|
||||||
|
options.UniqueSectionNames = true;
|
||||||
|
options.EmulatedTLS = false;
|
||||||
|
options.ExceptionModel = ExceptionHandling::None;
|
||||||
|
options.JTType = JumpTable::Single; // Create a single table for all jumptable functions
|
||||||
|
options.ThreadModel = ThreadModel::POSIX;
|
||||||
|
options.EABIVersion = EABI::Default;
|
||||||
|
options.DebuggerTuning = DebuggerKind::Default;
|
||||||
|
options.DisableIntegratedAS = false;
|
||||||
|
options.MCOptions.SanitizeAddress = false;
|
||||||
|
options.MCOptions.MCRelaxAll = false; // relax all fixups in the emitted object file
|
||||||
|
options.MCOptions.MCIncrementalLinkerCompatible = false;
|
||||||
|
options.MCOptions.DwarfVersion = 0;
|
||||||
|
options.MCOptions.ShowMCInst = false;
|
||||||
|
options.MCOptions.ABIName = "";
|
||||||
|
options.MCOptions.MCFatalWarnings = false;
|
||||||
|
options.MCOptions.MCNoWarn = false;
|
||||||
|
options.MCOptions.ShowMCEncoding = false; // Show encoding in .s output
|
||||||
|
options.MCOptions.MCUseDwarfDirectory = false;
|
||||||
|
options.MCOptions.AsmVerbose = true;
|
||||||
|
options.MCOptions.PreserveAsmComments = true;
|
||||||
|
|
||||||
legacy::FunctionPassManager PerFunctionPasses(module);
|
CodeGenOpt::Level optimizationLevel = CodeGenOpt::Aggressive;
|
||||||
legacy::PassManager PerModulePasses;
|
machine = target->createTargetMachine(triple, cpuName, features, options, relocationModel, codeModel, optimizationLevel);
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 8)
|
|
||||||
PerFunctionPasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis()));
|
|
||||||
PerModulePasses.add(createTargetTransformInfoWrapperPass(machine->getTargetIRAnalysis()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SmallString<16 * 1024> str;
|
|
||||||
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
|
||||||
raw_svector_ostream vecstream(str);
|
|
||||||
formatted_raw_ostream stream(vecstream);
|
|
||||||
#else
|
|
||||||
raw_svector_ostream stream(str);
|
|
||||||
#endif
|
|
||||||
machine->addPassesToEmitFile(PerModulePasses, stream, TargetMachine::CGFT_AssemblyFile);
|
|
||||||
|
|
||||||
PassManagerBuilder passManagerBuilder;
|
|
||||||
passManagerBuilder.OptLevel = 3;
|
|
||||||
passManagerBuilder.SizeLevel = 0;
|
|
||||||
passManagerBuilder.Inliner = createFunctionInliningPass();
|
|
||||||
passManagerBuilder.SLPVectorize = true;
|
|
||||||
passManagerBuilder.LoopVectorize = true;
|
|
||||||
passManagerBuilder.LoadCombine = true;
|
|
||||||
passManagerBuilder.populateModulePassManager(PerModulePasses);
|
|
||||||
passManagerBuilder.populateFunctionPassManager(PerFunctionPasses);
|
|
||||||
|
|
||||||
// Run function passes:
|
|
||||||
PerFunctionPasses.doInitialization();
|
|
||||||
for (llvm::Function &func : *module)
|
|
||||||
{
|
|
||||||
if (!func.isDeclaration())
|
|
||||||
PerFunctionPasses.run(func);
|
|
||||||
}
|
|
||||||
PerFunctionPasses.doFinalization();
|
|
||||||
|
|
||||||
// Run module passes:
|
|
||||||
PerModulePasses.run(*module);
|
|
||||||
|
|
||||||
return str.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> LLVMProgram::GenerateObjectFile(std::string cpuName)
|
|
||||||
{
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
std::string errorstring;
|
|
||||||
|
|
||||||
llvm::Module *module = mModule.get();
|
|
||||||
EngineBuilder engineBuilder(std::move(mModule));
|
|
||||||
engineBuilder.setErrorStr(&errorstring);
|
|
||||||
engineBuilder.setOptLevel(CodeGenOpt::Aggressive);
|
|
||||||
engineBuilder.setEngineKind(EngineKind::JIT);
|
|
||||||
engineBuilder.setMCPU(cpuName);
|
|
||||||
machine = engineBuilder.selectTarget();
|
|
||||||
if (!machine)
|
|
||||||
throw Exception("Could not create LLVM target machine");
|
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
||||||
std::string targetTriple = machine->getTargetTriple();
|
std::string targetTriple = machine->getTargetTriple();
|
||||||
|
@ -599,8 +563,8 @@ std::vector<uint8_t> LLVMProgram::GenerateObjectFile(std::string cpuName)
|
||||||
PerModulePasses.run(*module);
|
PerModulePasses.run(*module);
|
||||||
|
|
||||||
// Return the resulting object file
|
// Return the resulting object file
|
||||||
stream.flush();
|
|
||||||
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
#if LLVM_VERSION_MAJOR < 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8)
|
||||||
|
stream.flush();
|
||||||
vecstream.flush();
|
vecstream.flush();
|
||||||
#endif
|
#endif
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
|
@ -673,10 +637,14 @@ int main(int argc, char **argv)
|
||||||
llvm::InitializeNativeTarget();
|
llvm::InitializeNativeTarget();
|
||||||
llvm::InitializeNativeTargetAsmPrinter();
|
llvm::InitializeNativeTargetAsmPrinter();
|
||||||
|
|
||||||
|
std::string triple = llvm::sys::getDefaultTargetTriple();
|
||||||
|
std::cout << "Target triple is " << triple << std::endl;
|
||||||
|
|
||||||
std::string cpuName = "pentium4";
|
std::string cpuName = "pentium4";
|
||||||
|
std::string features;
|
||||||
std::cout << "Compiling drawer code for " << cpuName << ".." << std::endl;
|
std::cout << "Compiling drawer code for " << cpuName << ".." << std::endl;
|
||||||
|
|
||||||
LLVMDrawers drawersSSE2(cpuName, "_SSE2");
|
LLVMDrawers drawersSSE2(triple, cpuName, features, "_SSE2");
|
||||||
|
|
||||||
file = fopen(argv[1], "wb");
|
file = fopen(argv[1], "wb");
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
|
|
Loading…
Reference in a new issue