mirror of
https://github.com/open-goal/jak-project
synced 2026-07-08 06:30:44 -04:00
allow aliasing of registers in variables if we explictly ask for it (#711)
This commit is contained in:
@@ -180,4 +180,5 @@
|
||||
- Fields with type `(inline-array thing)` can now be set in statics.
|
||||
- `meters`, `degrees`, and `seconds` types have been added.
|
||||
- Bitfields with `symbol` fields used in an immediate `(new 'static ...)` can now define the symbol in the `new` form.
|
||||
- Bitfields with `float` fields used in an immediate `(new 'static ...)` in code can use a non-constant floating point value.
|
||||
- Bitfields with `float` fields used in an immediate `(new 'static ...)` in code can use a non-constant floating point value.
|
||||
- Multiple variables assigned to the same register using `:reg` in `rlet` (or overlapping with `self` in a behavior) will now be merged to a single variable instead of causing a compiler error. Variables will have their own type, but they will all be an alias of the same exact register.
|
||||
@@ -302,6 +302,11 @@ StackVarAddrVal* FunctionEnv::allocate_aligned_stack_variable(const TypeSpec& ts
|
||||
return result;
|
||||
}
|
||||
|
||||
RegVal* FunctionEnv::push_reg_val(std::unique_ptr<RegVal> in) {
|
||||
m_iregs.push_back(std::move(in));
|
||||
return m_iregs.back().get();
|
||||
}
|
||||
|
||||
///////////////////
|
||||
// LexicalEnv
|
||||
///////////////////
|
||||
|
||||
@@ -208,6 +208,8 @@ class FunctionEnv : public DeclareEnv {
|
||||
|
||||
const std::vector<std::unique_ptr<RegVal>>& reg_vals() const { return m_iregs; }
|
||||
|
||||
RegVal* push_reg_val(std::unique_ptr<RegVal> in);
|
||||
|
||||
int segment = -1;
|
||||
std::string method_of_type_name = "#f";
|
||||
bool is_asm_func = false;
|
||||
|
||||
@@ -75,21 +75,48 @@ Val* Compiler::compile_rlet(const goos::Object& form, const goos::Object& rest,
|
||||
}
|
||||
|
||||
// alloc a register:
|
||||
auto new_place_reg = env->make_ireg(ts, register_class);
|
||||
new_place_reg->mark_as_settable();
|
||||
|
||||
RegVal* new_place_reg = nullptr;
|
||||
if (def_args.has_named("reg")) {
|
||||
IRegConstraint constraint;
|
||||
constraint.ireg = new_place_reg->ireg();
|
||||
constraint.contrain_everywhere = true;
|
||||
constraint.desired_register = parse_register(def_args.named.at("reg"));
|
||||
if (def_args.has_named("reset-here") &&
|
||||
get_true_or_false(form, def_args.get_named("reset-here"))) {
|
||||
reset_regs.push_back(new_place_reg);
|
||||
auto desired_register = parse_register(def_args.named.at("reg"));
|
||||
// we want to see if we already created a variable for this register, and reuse it.
|
||||
for (auto& constr : fenv->constraints()) {
|
||||
if (constr.desired_register == desired_register && constr.contrain_everywhere) {
|
||||
auto reg_val_ptr = std::make_unique<RegVal>(constr.ireg, ts);
|
||||
new_place_reg = fenv->push_reg_val(std::move(reg_val_ptr));
|
||||
new_place_reg->mark_as_settable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
new_place_reg->set_rlet_constraint(constraint.desired_register);
|
||||
constraints.push_back(constraint);
|
||||
if (!new_place_reg) {
|
||||
for (auto& constr : constraints) {
|
||||
if (constr.desired_register == desired_register && constr.contrain_everywhere) {
|
||||
auto reg_val_ptr = std::make_unique<RegVal>(constr.ireg, ts);
|
||||
new_place_reg = fenv->push_reg_val(std::move(reg_val_ptr));
|
||||
new_place_reg->mark_as_settable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_place_reg) {
|
||||
new_place_reg = env->make_ireg(ts, register_class);
|
||||
new_place_reg->mark_as_settable();
|
||||
|
||||
if (def_args.has_named("reg")) {
|
||||
IRegConstraint constraint;
|
||||
constraint.ireg = new_place_reg->ireg();
|
||||
constraint.contrain_everywhere = true;
|
||||
constraint.desired_register = parse_register(def_args.named.at("reg"));
|
||||
if (def_args.has_named("reset-here") &&
|
||||
get_true_or_false(form, def_args.get_named("reset-here"))) {
|
||||
reset_regs.push_back(new_place_reg);
|
||||
}
|
||||
|
||||
new_place_reg->set_rlet_constraint(constraint.desired_register);
|
||||
constraints.push_back(constraint);
|
||||
}
|
||||
}
|
||||
|
||||
lenv->vars[new_place_name.as_symbol()->name] = new_place_reg;
|
||||
|
||||
Reference in New Issue
Block a user