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.
This commit is contained in:
parent
c917290497
commit
8c81a20ace
1 changed files with 14 additions and 11 deletions
|
@ -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) {
|
||||
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>
|
||||
void Invoke(EmitContext& ctx, IR::Inst* inst, std::index_sequence<I...>) {
|
||||
using Traits = FuncTraits<decltype(func)>;
|
||||
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 {
|
||||
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))...};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue