Kaynağa Gözat

glasm: Ensure reg alloc order across compilers on GLASM

Use a struct constructor to serialize register allocation arguments to
ensure registers are allocated in the same order regardless of the
compiler used.

The A and B functions can be called in any order when passed as
arguments to "foo":

  foo(A(), B())

But the order is guaranteed for curly-braced constructor calls in
classes:

  Foo{A(), B()}

Use this to get consistent behavior.
ReinUsesLisp 5 yıl önce
ebeveyn
işleme
8c81a20ace

+ 14 - 11
src/shader_recompiler/backend/glasm/emit_glasm.cpp

@@ -128,24 +128,27 @@ auto Arg(EmitContext& ctx, const IR::Value& arg) {
     }
     }
 }
 }
 
 
-template <auto func, bool is_first_arg_inst, typename... Args>
-void InvokeCall(EmitContext& ctx, IR::Inst* inst, Args&&... args) {
-    if constexpr (is_first_arg_inst) {
-        func(ctx, *inst, args.Extract()...);
-    } else {
-        func(ctx, args.Extract()...);
+template <auto func, bool is_first_arg_inst>
+struct InvokeCall {
+    template <typename... Args>
+    InvokeCall(EmitContext& ctx, IR::Inst* inst, Args&&... args) {
+        if constexpr (is_first_arg_inst) {
+            func(ctx, *inst, args.Extract()...);
+        } else {
+            func(ctx, args.Extract()...);
+        }
     }
     }
-}
+};
 
 
 template <auto func, bool is_first_arg_inst, size_t... I>
 template <auto func, bool is_first_arg_inst, size_t... I>
 void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) {
 void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) {
     using Traits = FuncTraits<decltype(func)>;
     using Traits = FuncTraits<decltype(func)>;
     if constexpr (is_first_arg_inst) {
     if constexpr (is_first_arg_inst) {
-        InvokeCall<func, is_first_arg_inst>(
-            ctx, inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...);
+        InvokeCall<func, is_first_arg_inst>{
+            ctx, inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...};
     } else {
     } else {
-        InvokeCall<func, is_first_arg_inst>(
-            ctx, inst, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...);
+        InvokeCall<func, is_first_arg_inst>{
+            ctx, inst, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...};
     }
     }
 }
 }