glsl: Rework var alloc to not assign unused results
This commit is contained in:
		| @@ -122,11 +122,9 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | ||||
|  | ||||
| void EmitContext::SetupExtensions(std::string&) { | ||||
|     header += "#extension GL_ARB_separate_shader_objects : enable\n"; | ||||
|     if (stage != Stage::Compute) { | ||||
|         // TODO: track this usage | ||||
|         header += "#extension GL_ARB_sparse_texture2 : enable\n"; | ||||
|         header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | ||||
|     } | ||||
|     // TODO: track this usage | ||||
|     header += "#extension GL_ARB_sparse_texture2 : enable\n"; | ||||
|     header += "#extension GL_EXT_texture_shadow_lod : enable\n"; | ||||
|     if (info.uses_int64) { | ||||
|         header += "#extension GL_ARB_gpu_shader_int64 : enable\n"; | ||||
|     } | ||||
|   | ||||
| @@ -37,7 +37,13 @@ public: | ||||
|  | ||||
|     template <GlslVarType type, typename... Args> | ||||
|     void Add(const char* format_str, IR::Inst& inst, Args&&... args) { | ||||
|         code += fmt::format(format_str, var_alloc.Define(inst, type), std::forward<Args>(args)...); | ||||
|         const auto var_def{var_alloc.AddDefine(inst, type)}; | ||||
|         if (var_def.empty()) { | ||||
|             // skip assigment. | ||||
|             code += fmt::format(&format_str[3], std::forward<Args>(args)...); | ||||
|         } else { | ||||
|             code += fmt::format(format_str, var_def, std::forward<Args>(args)...); | ||||
|         } | ||||
|         // TODO: Remove this | ||||
|         code += '\n'; | ||||
|     } | ||||
|   | ||||
| @@ -11,8 +11,7 @@ | ||||
|  | ||||
| namespace Shader::Backend::GLSL { | ||||
| namespace { | ||||
| static constexpr std::string_view cas_loop{R"({}; | ||||
| for (;;){{ | ||||
| static constexpr std::string_view cas_loop{R"(for (;;){{ | ||||
|     uint old_value={}; | ||||
|     {}=atomicCompSwap({},old_value,{}({},{})); | ||||
|     if ({}==old_value){{break;}} | ||||
| @@ -22,14 +21,14 @@ void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset | ||||
|                        std::string_view value, std::string_view function) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | ||||
|     const std::string smem{fmt::format("smem[{}/4]", offset)}; | ||||
|     ctx.Add(cas_loop.data(), ret, smem, ret, smem, function, smem, value, ret); | ||||
|     ctx.Add(cas_loop.data(), smem, ret, smem, function, smem, value, ret); | ||||
| } | ||||
|  | ||||
| void SsboCasFunction(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||||
|                      const IR::Value& offset, std::string_view value, std::string_view function) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | ||||
|     const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; | ||||
|     ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret); | ||||
|     ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | ||||
| } | ||||
|  | ||||
| void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||||
| @@ -37,7 +36,7 @@ void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi | ||||
|                         std::string_view function) { | ||||
|     const std::string ssbo{fmt::format("ssbo{}[{}]", binding.U32(), offset.U32())}; | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | ||||
|     ctx.Add(cas_loop.data(), ret, ssbo, ret, ssbo, function, ssbo, value, ret); | ||||
|     ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | ||||
|     ctx.AddF32("{}=uintBitsToFloat({});", inst, ret); | ||||
| } | ||||
| } // namespace | ||||
|   | ||||
| @@ -26,7 +26,13 @@ void EmitIdentity(EmitContext&, IR::Inst& inst, const IR::Value& value) { | ||||
| } | ||||
|  | ||||
| void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value) { | ||||
|     ctx.AddU1("{}={};", inst, ctx.var_alloc.Consume(value)); | ||||
|     // Fake one usage to get a real variable out of the condition | ||||
|     inst.DestructiveAddUsage(1); | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U1)}; | ||||
|     const auto input{ctx.var_alloc.Consume(value)}; | ||||
|     if (ret != input) { | ||||
|         ctx.Add("{}={};", ret, input); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitBitCastU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst) { | ||||
|   | ||||
| @@ -9,8 +9,14 @@ | ||||
| #include "shader_recompiler/frontend/ir/value.h" | ||||
|  | ||||
| namespace Shader::Backend::GLSL { | ||||
| namespace { | ||||
| static constexpr std::string_view SWIZZLE{"xyzw"}; | ||||
|  | ||||
| void CompositeInsert(EmitContext& ctx, std::string_view result, std::string_view composite, | ||||
|                      std::string_view object, u32 index) { | ||||
|     ctx.Add("{}={};", result, composite); | ||||
|     ctx.Add("{}.{}={};", result, SWIZZLE[index], object); | ||||
| } | ||||
| } // namespace | ||||
| void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1, | ||||
|                                  std::string_view e2) { | ||||
|     ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2); | ||||
| @@ -41,19 +47,22 @@ void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_vie | ||||
|     ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x2)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x3)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertU32x4(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32x4)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructF16x2([[maybe_unused]] EmitContext& ctx, | ||||
| @@ -146,19 +155,22 @@ void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_vie | ||||
|     ctx.AddF32("{}={}.{};", inst, composite, SWIZZLE[index]); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x2)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertF32x3(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x3)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeInsertF32x4(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index) { | ||||
|     ctx.Add("{}.{}={};", composite, SWIZZLE[index], object); | ||||
| void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index) { | ||||
|     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::F32x4)}; | ||||
|     CompositeInsert(ctx, ret, composite, object, index); | ||||
| } | ||||
|  | ||||
| void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) { | ||||
|   | ||||
| @@ -26,7 +26,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& inst); | ||||
| void EmitVoid(EmitContext& ctx); | ||||
| void EmitIdentity(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | ||||
| void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value); | ||||
| void EmitReference(EmitContext&); | ||||
| void EmitReference(EmitContext& ctx, const IR::Value& value); | ||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi, const IR::Value& value); | ||||
| void EmitBranch(EmitContext& ctx, std::string_view label); | ||||
| void EmitBranchConditional(EmitContext& ctx, std::string_view condition, | ||||
| @@ -165,12 +165,12 @@ void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie | ||||
|                                u32 index); | ||||
| void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                                u32 index); | ||||
| void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertU32x4(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeInsertU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeInsertU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeConstructF16x2(EmitContext& ctx, std::string_view e1, std::string_view e2); | ||||
| void EmitCompositeConstructF16x3(EmitContext& ctx, std::string_view e1, std::string_view e2, | ||||
|                                  std::string_view e3); | ||||
| @@ -197,12 +197,12 @@ void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_vie | ||||
|                                u32 index); | ||||
| void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                                u32 index); | ||||
| void EmitCompositeInsertF32x2(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertF32x3(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertF32x4(EmitContext& ctx, std::string_view composite, std::string_view object, | ||||
|                               u32 index); | ||||
| void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite, | ||||
|                               std::string_view object, u32 index); | ||||
| void EmitCompositeConstructF64x2(EmitContext& ctx); | ||||
| void EmitCompositeConstructF64x3(EmitContext& ctx); | ||||
| void EmitCompositeConstructF64x4(EmitContext& ctx); | ||||
|   | ||||
| @@ -25,7 +25,7 @@ void EmitPhi(EmitContext& ctx, IR::Inst& phi) { | ||||
|     } | ||||
|     if (!phi.Definition<Id>().is_valid) { | ||||
|         // The phi node wasn't forward defined | ||||
|         ctx.Add("{};", ctx.var_alloc.Define(phi, phi.Arg(0).Type())); | ||||
|         ctx.var_alloc.PhiDefine(phi, phi.Arg(0).Type()); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -33,8 +33,8 @@ void EmitVoid(EmitContext& ctx) { | ||||
|     // NotImplemented(); | ||||
| } | ||||
|  | ||||
| void EmitReference(EmitContext&) { | ||||
|     // NotImplemented(); | ||||
| void EmitReference(EmitContext& ctx, const IR::Value& value) { | ||||
|     ctx.var_alloc.Consume(value); | ||||
| } | ||||
|  | ||||
| void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& value) { | ||||
| @@ -42,7 +42,7 @@ void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value& | ||||
|     const auto phi_type{phi.Arg(0).Type()}; | ||||
|     if (!phi.Definition<Id>().is_valid) { | ||||
|         // The phi node wasn't forward defined | ||||
|         ctx.Add("{};", ctx.var_alloc.Define(phi, phi_type)); | ||||
|         ctx.var_alloc.PhiDefine(phi, phi_type); | ||||
|     } | ||||
|     const auto phi_reg{ctx.var_alloc.Consume(IR::Value{&phi})}; | ||||
|     const auto val_reg{ctx.var_alloc.Consume(value)}; | ||||
|   | ||||
| @@ -110,7 +110,6 @@ std::string VarAlloc::Define(IR::Inst& inst, GlslVarType type) { | ||||
|     } else { | ||||
|         Id id{}; | ||||
|         id.type.Assign(type); | ||||
|         // id.is_null.Assign(1); | ||||
|         GetUseTracker(type).uses_temp = true; | ||||
|         inst.SetDefinition<Id>(id); | ||||
|     } | ||||
| @@ -121,6 +120,20 @@ std::string VarAlloc::Define(IR::Inst& inst, IR::Type type) { | ||||
|     return Define(inst, RegType(type)); | ||||
| } | ||||
|  | ||||
| std::string VarAlloc::PhiDefine(IR::Inst& inst, IR::Type type) { | ||||
|     return AddDefine(inst, RegType(type)); | ||||
| } | ||||
|  | ||||
| std::string VarAlloc::AddDefine(IR::Inst& inst, GlslVarType type) { | ||||
|     if (inst.HasUses()) { | ||||
|         inst.SetDefinition<Id>(Alloc(type)); | ||||
|         return Representation(inst.Definition<Id>()); | ||||
|     } else { | ||||
|         return ""; | ||||
|     } | ||||
|     return Representation(inst.Definition<Id>()); | ||||
| } | ||||
|  | ||||
| std::string VarAlloc::Consume(const IR::Value& value) { | ||||
|     return value.IsImmediate() ? MakeImm(value) : ConsumeInst(*value.InstRecursive()); | ||||
| } | ||||
| @@ -223,6 +236,8 @@ VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) { | ||||
|     switch (type) { | ||||
|     case GlslVarType::U1: | ||||
|         return var_bool; | ||||
|     case GlslVarType::F16x2: | ||||
|         return var_f16x2; | ||||
|     case GlslVarType::U32: | ||||
|         return var_u32; | ||||
|     case GlslVarType::S32: | ||||
|   | ||||
| @@ -62,9 +62,15 @@ public: | ||||
|         bool uses_temp{}; | ||||
|     }; | ||||
|  | ||||
|     /// Used for explicit usages of variables, may revert to temporaries | ||||
|     std::string Define(IR::Inst& inst, GlslVarType type); | ||||
|     std::string Define(IR::Inst& inst, IR::Type type); | ||||
|  | ||||
|     /// Used to assign variables used by the IR. May return a blank string if | ||||
|     /// the instruction's result is unused in the IR. | ||||
|     std::string AddDefine(IR::Inst& inst, GlslVarType type); | ||||
|     std::string PhiDefine(IR::Inst& inst, IR::Type type); | ||||
|  | ||||
|     std::string Consume(const IR::Value& value); | ||||
|     std::string ConsumeInst(IR::Inst& inst); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user