mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-30 10:42:47 +01:00
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>
|
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))...};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue