Commit 68cfc78e by Ben Clayton

Reactor: Rework optimization flags.

Replace the old 'runOptimizations' flag on Nucleus::acquireRoutine() and Nucleus::acquireCoroutine() with a new OptimizationLevel enumerator. runOptimizations was always true, and there is already the rr::optimization extern to control the optimization passes performed. All Function and Coroutines are now passed the new vk::ReactorOptimizationLevel. This will be changed to a non-Default value in another CL. Bug: b/135609394 Change-Id: I1154da05d413b18a471a3818fbb03f356a3d0e6c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33482Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 6f8e565b
...@@ -1534,7 +1534,7 @@ namespace sw ...@@ -1534,7 +1534,7 @@ namespace sw
} }
} }
return function("BlitRoutine"); return function(vk::ReactorOptimizationLevel, "BlitRoutine");
} }
Routine *Blitter::getBlitRoutine(const State &state) Routine *Blitter::getBlitRoutine(const State &state)
...@@ -1889,7 +1889,7 @@ namespace sw ...@@ -1889,7 +1889,7 @@ namespace sw
} }
} }
return function("BlitRoutine"); return function(vk::ReactorOptimizationLevel, "BlitRoutine");
} }
void Blitter::updateBorders(vk::Image* image, const VkImageSubresourceLayers& subresourceLayers) void Blitter::updateBorders(vk::Image* image, const VkImageSubresourceLayers& subresourceLayers)
......
...@@ -238,7 +238,7 @@ namespace sw ...@@ -238,7 +238,7 @@ namespace sw
{ {
QuadRasterizer *generator = new PixelProgram(state, pipelineLayout, pixelShader, descriptorSets); QuadRasterizer *generator = new PixelProgram(state, pipelineLayout, pixelShader, descriptorSets);
generator->generate(); generator->generate();
routine = (*generator)("PixelRoutine_%0.8X", state.shaderID); routine = (*generator)(vk::ReactorOptimizationLevel, "PixelRoutine_%0.8X", state.shaderID);
delete generator; delete generator;
routineCache->add(state, routine); routineCache->add(state, routine);
......
...@@ -105,7 +105,7 @@ namespace sw ...@@ -105,7 +105,7 @@ namespace sw
{ {
VertexRoutine *generator = new VertexProgram(state, pipelineLayout, vertexShader, descriptorSets); VertexRoutine *generator = new VertexProgram(state, pipelineLayout, vertexShader, descriptorSets);
generator->generate(); generator->generate();
routine = (*generator)("VertexRoutine_%0.8X", state.shaderID); routine = (*generator)(vk::ReactorOptimizationLevel, "VertexRoutine_%0.8X", state.shaderID);
delete generator; delete generator;
routineCache->add(state, routine); routineCache->add(state, routine);
......
...@@ -453,7 +453,7 @@ namespace sw ...@@ -453,7 +453,7 @@ namespace sw
Return(1); Return(1);
} }
routine = function("SetupRoutine"); routine = function(vk::ReactorOptimizationLevel, "SetupRoutine");
} }
void SetupRoutine::setupGradient(Pointer<Byte> &primitive, Pointer<Byte> &triangle, Float4 &w012, Float4 (&m)[3], Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2, int attribute, int planeEquation, bool flat, bool perspective, int component) void SetupRoutine::setupGradient(Pointer<Byte> &primitive, Pointer<Byte> &triangle, Float4 &w012, Float4 (&m)[3], Pointer<Byte> &v0, Pointer<Byte> &v1, Pointer<Byte> &v2, int attribute, int planeEquation, bool flat, bool perspective, int component)
......
...@@ -231,7 +231,7 @@ SpirvShader::ImageSampler *SpirvShader::emitSamplerFunction(ImageInstruction ins ...@@ -231,7 +231,7 @@ SpirvShader::ImageSampler *SpirvShader::emitSamplerFunction(ImageInstruction ins
} }
} }
return (ImageSampler*)function("sampler")->getEntry(); return (ImageSampler*)function(vk::ReactorOptimizationLevel, "sampler")->getEntry();
} }
sw::TextureType SpirvShader::convertTextureType(VkImageViewType imageViewType) sw::TextureType SpirvShader::convertTextureType(VkImageViewType imageViewType)
......
...@@ -133,7 +133,7 @@ private: ...@@ -133,7 +133,7 @@ private:
// called without building a new rr::Function or rr::Coroutine. // called without building a new rr::Function or rr::Coroutine.
// While automatically called by operator(), finalize() should be called // While automatically called by operator(), finalize() should be called
// as early as possible to release the global Reactor mutex lock. // as early as possible to release the global Reactor mutex lock.
inline void finalize(); inline void finalize(OptimizationLevel optLevel = OptimizationLevel::Default);
// Starts execution of the coroutine and returns a unique_ptr to a // Starts execution of the coroutine and returns a unique_ptr to a
// Stream<> that exposes the await() function for obtaining yielded // Stream<> that exposes the await() function for obtaining yielded
...@@ -147,7 +147,7 @@ private: ...@@ -147,7 +147,7 @@ private:
}; };
template<typename Return, typename... Arguments> template<typename Return, typename... Arguments>
Coroutine<Return(Arguments...)>::Coroutine() : routine{} Coroutine<Return(Arguments...)>::Coroutine()
{ {
core.reset(new Nucleus()); core.reset(new Nucleus());
...@@ -164,11 +164,11 @@ private: ...@@ -164,11 +164,11 @@ private:
} }
template<typename Return, typename... Arguments> template<typename Return, typename... Arguments>
void Coroutine<Return(Arguments...)>::finalize() void Coroutine<Return(Arguments...)>::finalize(OptimizationLevel optLevel /* = OptimizationLevel::Default */)
{ {
if(core != nullptr) if(core != nullptr)
{ {
routine.reset(core->acquireCoroutine("coroutine", true)); routine.reset(core->acquireCoroutine("coroutine", optLevel));
core.reset(nullptr); core.reset(nullptr);
} }
} }
......
...@@ -219,7 +219,11 @@ namespace ...@@ -219,7 +219,11 @@ namespace
using ObjLayer = llvm::orc::RTDyldObjectLinkingLayer; using ObjLayer = llvm::orc::RTDyldObjectLinkingLayer;
using CompileLayer = llvm::orc::IRCompileLayer<ObjLayer, llvm::orc::SimpleCompiler>; using CompileLayer = llvm::orc::IRCompileLayer<ObjLayer, llvm::orc::SimpleCompiler>;
public: public:
JITRoutine(std::unique_ptr<llvm::Module> module, llvm::Function **funcs, size_t count) : JITRoutine(
std::unique_ptr<llvm::Module> module,
llvm::Function **funcs,
size_t count,
rr::OptimizationLevel optLevel) :
resolver(createLegacyLookupResolver( resolver(createLegacyLookupResolver(
session, session,
[&](const std::string &name) { [&](const std::string &name) {
...@@ -241,6 +245,8 @@ namespace ...@@ -241,6 +245,8 @@ namespace
targetMachine(llvm::EngineBuilder() targetMachine(llvm::EngineBuilder()
#ifdef ENABLE_RR_DEBUG_INFO #ifdef ENABLE_RR_DEBUG_INFO
.setOptLevel(llvm::CodeGenOpt::None) .setOptLevel(llvm::CodeGenOpt::None)
#else
.setOptLevel(toLLVM(optLevel))
#endif // ENABLE_RR_DEBUG_INFO #endif // ENABLE_RR_DEBUG_INFO
.setMArch(JITGlobals::get()->arch) .setMArch(JITGlobals::get()->arch)
.setMAttrs(JITGlobals::get()->mattrs) .setMAttrs(JITGlobals::get()->mattrs)
...@@ -306,6 +312,19 @@ namespace ...@@ -306,6 +312,19 @@ namespace
} }
private: private:
static ::llvm::CodeGenOpt::Level toLLVM(rr::OptimizationLevel level)
{
switch (level)
{
case rr::OptimizationLevel::None: return ::llvm::CodeGenOpt::None;
case rr::OptimizationLevel::Less: return ::llvm::CodeGenOpt::Less;
case rr::OptimizationLevel::Default: return ::llvm::CodeGenOpt::Default;
case rr::OptimizationLevel::Aggressive: return ::llvm::CodeGenOpt::Aggressive;
default: UNREACHABLE("Unknown OptimizationLevel %d", int(level));
}
return ::llvm::CodeGenOpt::Default;
}
std::shared_ptr<llvm::orc::SymbolResolver> resolver; std::shared_ptr<llvm::orc::SymbolResolver> resolver;
std::unique_ptr<llvm::TargetMachine> targetMachine; std::unique_ptr<llvm::TargetMachine> targetMachine;
llvm::orc::ExecutionSession session; llvm::orc::ExecutionSession session;
...@@ -361,10 +380,10 @@ namespace ...@@ -361,10 +380,10 @@ namespace
passManager->run(*module); passManager->run(*module);
} }
rr::Routine *acquireRoutine(llvm::Function **funcs, size_t count) rr::Routine *acquireRoutine(llvm::Function **funcs, size_t count, rr::OptimizationLevel optLevel)
{ {
ASSERT(module); ASSERT(module);
return new JITRoutine(std::move(module), funcs, count); return new JITRoutine(std::move(module), funcs, count, optLevel);
} }
llvm::LLVMContext context; llvm::LLVMContext context;
...@@ -1118,7 +1137,7 @@ namespace rr ...@@ -1118,7 +1137,7 @@ namespace rr
::codegenMutex.unlock(); ::codegenMutex.unlock();
} }
Routine *Nucleus::acquireRoutine(const char *name, bool runOptimizations) Routine *Nucleus::acquireRoutine(const char *name, OptimizationLevel optimizationLevel)
{ {
if(jit->builder->GetInsertBlock()->empty() || !jit->builder->GetInsertBlock()->back().isTerminator()) if(jit->builder->GetInsertBlock()->empty() || !jit->builder->GetInsertBlock()->back().isTerminator())
{ {
...@@ -1156,10 +1175,7 @@ namespace rr ...@@ -1156,10 +1175,7 @@ namespace rr
} }
#endif // defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG) #endif // defined(ENABLE_RR_LLVM_IR_VERIFICATION) || !defined(NDEBUG)
if(runOptimizations)
{
optimize(); optimize();
}
if(false) if(false)
{ {
...@@ -1168,7 +1184,7 @@ namespace rr ...@@ -1168,7 +1184,7 @@ namespace rr
jit->module->print(file, 0); jit->module->print(file, 0);
} }
auto routine = jit->acquireRoutine(&jit->function, 1); auto routine = jit->acquireRoutine(&jit->function, 1, optimizationLevel);
jit.reset(); jit.reset();
return routine; return routine;
...@@ -4656,7 +4672,7 @@ void Nucleus::yield(Value* val) ...@@ -4656,7 +4672,7 @@ void Nucleus::yield(Value* val)
jit->builder->SetInsertPoint(resumeBlock); jit->builder->SetInsertPoint(resumeBlock);
} }
Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations) Routine* Nucleus::acquireCoroutine(const char *name, OptimizationLevel optimizationLevel)
{ {
ASSERT_MSG(jit->coroutine.id != nullptr, "acquireCoroutine() called without a call to createCoroutine()"); ASSERT_MSG(jit->coroutine.id != nullptr, "acquireCoroutine() called without a call to createCoroutine()");
...@@ -4685,10 +4701,7 @@ Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations) ...@@ -4685,10 +4701,7 @@ Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations)
pm.add(llvm::createCoroCleanupPass()); pm.add(llvm::createCoroCleanupPass());
pm.run(*jit->module); pm.run(*jit->module);
if(runOptimizations)
{
optimize(); optimize();
}
if(false) if(false)
{ {
...@@ -4701,7 +4714,7 @@ Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations) ...@@ -4701,7 +4714,7 @@ Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations)
funcs[Nucleus::CoroutineEntryBegin] = jit->function; funcs[Nucleus::CoroutineEntryBegin] = jit->function;
funcs[Nucleus::CoroutineEntryAwait] = jit->coroutine.await; funcs[Nucleus::CoroutineEntryAwait] = jit->coroutine.await;
funcs[Nucleus::CoroutineEntryDestroy] = jit->coroutine.destroy; funcs[Nucleus::CoroutineEntryDestroy] = jit->coroutine.destroy;
Routine *routine = jit->acquireRoutine(funcs, Nucleus::CoroutineEntryCount); auto routine = jit->acquireRoutine(funcs, Nucleus::CoroutineEntryCount, optimizationLevel);
jit.reset(); jit.reset();
return routine; return routine;
......
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
#include <vector> #include <vector>
#include <atomic> #include <atomic>
#ifdef None
#undef None // b/127920555
#endif
namespace rr namespace rr
{ {
class Type; class Type;
...@@ -47,6 +51,14 @@ namespace rr ...@@ -47,6 +51,14 @@ namespace rr
extern Optimization optimization[10]; extern Optimization optimization[10];
enum class OptimizationLevel
{
None,
Less,
Default,
Aggressive,
};
class Nucleus class Nucleus
{ {
public: public:
...@@ -54,7 +66,7 @@ namespace rr ...@@ -54,7 +66,7 @@ namespace rr
virtual ~Nucleus(); virtual ~Nucleus();
Routine *acquireRoutine(const char *name, bool runOptimizations = true); Routine *acquireRoutine(const char *name, OptimizationLevel optimizationLevel);
static Value *allocateStackVariable(Type *type, int arraySize = 0); static Value *allocateStackVariable(Type *type, int arraySize = 0);
static BasicBlock *createBasicBlock(); static BasicBlock *createBasicBlock();
...@@ -81,7 +93,7 @@ namespace rr ...@@ -81,7 +93,7 @@ namespace rr
}; };
static void createCoroutine(Type *ReturnType, std::vector<Type*> &Params); static void createCoroutine(Type *ReturnType, std::vector<Type*> &Params);
Routine *acquireCoroutine(const char *name, bool runOptimizations = true); Routine *acquireCoroutine(const char *name, OptimizationLevel optimizationLevel);
static void yield(Value*); static void yield(Value*);
// Terminators // Terminators
......
...@@ -2465,6 +2465,7 @@ namespace rr ...@@ -2465,6 +2465,7 @@ namespace rr
} }
Routine *operator()(const char *name, ...); Routine *operator()(const char *name, ...);
Routine *operator()(OptimizationLevel optLevel, const char *name, ...);
protected: protected:
Nucleus *core; Nucleus *core;
...@@ -3039,7 +3040,20 @@ namespace rr ...@@ -3039,7 +3040,20 @@ namespace rr
vsnprintf(fullName, 1024, name, vararg); vsnprintf(fullName, 1024, name, vararg);
va_end(vararg); va_end(vararg);
return core->acquireRoutine(fullName, true); return core->acquireRoutine(fullName, OptimizationLevel::Default);
}
template<typename Return, typename... Arguments>
Routine *Function<Return(Arguments...)>::operator()(OptimizationLevel optLevel, const char *name, ...)
{
char fullName[1024 + 1];
va_list vararg;
va_start(vararg, name);
vsnprintf(fullName, 1024, name, vararg);
va_end(vararg);
return core->acquireRoutine(fullName, optLevel);
} }
template<class T, class S> template<class T, class S>
......
...@@ -585,7 +585,7 @@ namespace rr ...@@ -585,7 +585,7 @@ namespace rr
::codegenMutex.unlock(); ::codegenMutex.unlock();
} }
Routine *Nucleus::acquireRoutine(const char *name, bool runOptimizations) Routine *Nucleus::acquireRoutine(const char *name, OptimizationLevel optimizationLevel)
{ {
if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret) if(basicBlock->getInsts().empty() || basicBlock->getInsts().back().getKind() != Ice::Inst::Ret)
{ {
...@@ -3506,7 +3506,7 @@ namespace rr ...@@ -3506,7 +3506,7 @@ namespace rr
void FlushDebug() {} void FlushDebug() {}
void Nucleus::createCoroutine(Type *YieldType, std::vector<Type*> &Params) { UNIMPLEMENTED("createCoroutine"); } void Nucleus::createCoroutine(Type *YieldType, std::vector<Type*> &Params) { UNIMPLEMENTED("createCoroutine"); }
Routine* Nucleus::acquireCoroutine(const char *name, bool runOptimizations) { UNIMPLEMENTED("acquireCoroutine"); return nullptr; } Routine* Nucleus::acquireCoroutine(const char *name, OptimizationLevel optimizationLevel) { UNIMPLEMENTED("acquireCoroutine"); return nullptr; }
void Nucleus::yield(Value* val) { UNIMPLEMENTED("Yield"); } void Nucleus::yield(Value* val) { UNIMPLEMENTED("Yield"); }
} }
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#include "Version.h" #include "Version.h"
#include "Reactor/Nucleus.hpp" // ReactorOptimizationLevel
#include <Vulkan/VulkanPlatform.h> #include <Vulkan/VulkanPlatform.h>
namespace vk namespace vk
...@@ -77,6 +79,9 @@ enum ...@@ -77,6 +79,9 @@ enum
MAX_POINT_SIZE = 1, // Large points are not supported. If/when we turn this on, must be >= 64. MAX_POINT_SIZE = 1, // Large points are not supported. If/when we turn this on, must be >= 64.
}; };
// Optimization level to use for JIT functions.
static constexpr auto ReactorOptimizationLevel = rr::OptimizationLevel::Default;
} }
#endif // VK_CONFIG_HPP_ #endif // VK_CONFIG_HPP_
...@@ -242,7 +242,7 @@ std::shared_ptr<sw::ComputeProgram> createProgram(const vk::PipelineCache::Compu ...@@ -242,7 +242,7 @@ std::shared_ptr<sw::ComputeProgram> createProgram(const vk::PipelineCache::Compu
// TODO(b/119409619): use allocator. // TODO(b/119409619): use allocator.
auto program = std::make_shared<sw::ComputeProgram>(key.getShader(), key.getLayout(), descriptorSets); auto program = std::make_shared<sw::ComputeProgram>(key.getShader(), key.getLayout(), descriptorSets);
program->generate(); program->generate();
program->finalize(); program->finalize(vk::ReactorOptimizationLevel);
return program; return program;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment