Skip to content
Snippets Groups Projects
Commit 8c81a20a authored by ReinUsesLisp's avatar ReinUsesLisp Committed by ameerj
Browse files

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.
parent c9172904
No related branches found
No related tags found
No related merge requests found
...@@ -128,24 +128,27 @@ auto Arg(EmitContext& ctx, const IR::Value& arg) { ...@@ -128,24 +128,27 @@ auto Arg(EmitContext& ctx, const IR::Value& arg) {
} }
} }
template <auto func, bool is_first_arg_inst, typename... Args> template <auto func, bool is_first_arg_inst>
void InvokeCall(EmitContext& ctx, IR::Inst* inst, Args&&... args) { struct InvokeCall {
if constexpr (is_first_arg_inst) { template <typename... Args>
func(ctx, *inst, args.Extract()...); InvokeCall(EmitContext& ctx, IR::Inst* inst, Args&&... args) {
} else { if constexpr (is_first_arg_inst) {
func(ctx, args.Extract()...); 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>( InvokeCall<func, is_first_arg_inst>{
ctx, inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...); ctx, inst, Arg<typename Traits::template ArgType<I + 2>>(ctx, inst->Arg(I))...};
} else { } else {
InvokeCall<func, is_first_arg_inst>( InvokeCall<func, is_first_arg_inst>{
ctx, inst, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...); ctx, inst, Arg<typename Traits::template ArgType<I + 1>>(ctx, inst->Arg(I))...};
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment