Skip to content

Commit

Permalink
fix place
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander.nutz committed Sep 24, 2024
1 parent 545f69d commit 70dadb2
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 130 deletions.
277 changes: 150 additions & 127 deletions cg/x86_stupid/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,12 +931,14 @@ static vx_IrOp* emiti(vx_IrBlock* block, vx_IrOp *prev, vx_IrOp* op, FILE* file)

case VX_IR_OP_PLACE: // "var"
{
vx_IrValue valV = *vx_IrOp_param(op, VX_IR_NAME_VALUE);
// TODO: stop imm inliner from inlining val and make it move in var if in var in input
assert(valV.type == VX_IR_VAL_VAR);
vx_IrValue valV = *vx_IrOp_param(op, VX_IR_NAME_VAR);
// TODO: make it move in var if in var in input
assert(valV.type == VX_IR_VAL_VAR && "inliner fucked up (VX_IR_OP_PLACE)");

assert(block->as_root.vars[valV.var].ever_placed);

Location* loc = varData[valV.var].location;
assert(loc->type == LOC_MEM);
assert(loc->type == LOC_MEM && "register allocator fucked up (VX_IR_OP_PLACE)");

vx_IrVar out = op->outs[0].var;
Location* outLoc = varData[out].location;
Expand Down Expand Up @@ -1421,160 +1423,174 @@ void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) {
size_t stackOff = 0;

/* ======================== VAR ALLOC ===================== */
{
signed long long highestHeat = 0;
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
size_t heat = varData[var].heat;
if (heat > highestHeat) {
highestHeat = heat;
}
signed long long highestHeat = 0;
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
size_t heat = varData[var].heat;
if (heat > highestHeat) {
highestHeat = heat;
}
}

vx_IrVar* varsHotFirst = calloc(block->as_root.vars_len, sizeof(vx_IrVar));
size_t varsHotFirstLen = 0;
vx_IrVar* varsHotFirst = calloc(block->as_root.vars_len, sizeof(vx_IrVar));
size_t varsHotFirstLen = 0;

char* varsSorted = calloc(block->as_root.vars_len, sizeof(char));
if (use_rax) {
varsSorted[optLastRetFirstArg.var] = true;
}
for (size_t i = anyCalledIntArgsCount; i < block->ins_len; i ++) {
vx_IrVar var = block->ins[i].var;
varsSorted[var] = true;
}
for (; highestHeat >= 0; highestHeat --) {
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
if (varsSorted[var]) continue;
char* varsSorted = calloc(block->as_root.vars_len, sizeof(char));
if (use_rax) {
varsSorted[optLastRetFirstArg.var] = true;
}
for (size_t i = anyCalledIntArgsCount; i < block->ins_len; i ++) {
vx_IrVar var = block->ins[i].var;
varsSorted[var] = true;
}
for (; highestHeat >= 0; highestHeat --) {
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
if (varsSorted[var]) continue;

if (varData[var].heat == highestHeat) {
varsHotFirst[varsHotFirstLen ++] = var;
varsSorted[var] = true;
}
if (varData[var].heat == highestHeat) {
varsHotFirst[varsHotFirstLen ++] = var;
varsSorted[var] = true;
}
}
free(varsSorted);

size_t varId = 0;
for (size_t i = 0; i < availableRegistersCount; i ++) {
char reg = availableRegisters[i];
}
free(varsSorted);

if (varId >= varsHotFirstLen) break;
size_t varId = 0;
for (size_t i = 0; i < availableRegistersCount; i ++) {
char reg = availableRegisters[i];

for (; varId < varsHotFirstLen; varId ++) {
vx_IrVar var = varsHotFirst[varId];
if (varId >= varsHotFirstLen) break;

if (varData[var].heat == 0) {
varData[var].location = NULL;
continue;
}
for (; varId < varsHotFirstLen; varId ++) {
vx_IrVar var = varsHotFirst[varId];

vx_IrType* type = varData[var].type;
if (type == NULL) continue;
if (varData[var].heat == 0) {
varData[var].location = NULL;
continue;
}

size_t size = vx_IrType_size(type);
if (size > 8) continue;
vx_IrType* type = varData[var].type;
if (type == NULL) continue;

if (block->as_root.vars[var].ever_placed) continue;
size_t size = vx_IrType_size(type);
if (size > 8) continue;

size = widthToWidthWidth(size);
varData[var].location = gen_reg_var(size, reg);
break;
}
varId ++;
}
if (block->as_root.vars[var].ever_placed) continue;

if (optLastRetFirstArg.present) {
size_t size = vx_IrType_size(varData[optLastRetFirstArg.var].type);
size = widthToWidthWidth(size);
varData[optLastRetFirstArg.var].location = gen_reg_var(size, REG_RAX.id);
varData[var].location = gen_reg_var(size, reg);
break;
}
varId ++;
}

if (optLastRetFirstArg.present) {
size_t size = vx_IrType_size(varData[optLastRetFirstArg.var].type);
size = widthToWidthWidth(size);
varData[optLastRetFirstArg.var].location = gen_reg_var(size, REG_RAX.id);
}

char intArgRegs[6] = { REG_RDI.id, REG_RSI.id, REG_RDX.id, REG_RCX.id, REG_R8.id, REG_R9.id };

size_t id_i = 0;
size_t id_f = 0;
struct VarD {
vx_IrVar var;
Location* argLoc;
};
struct VarD * toMove = NULL;
size_t toMoveLen = 0;
for (size_t i = 0; i < block->ins_len; i ++) {
vx_IrTypedVar var = block->ins[i];
assert(var.type->kind == VX_IR_TYPE_KIND_BASE);
size_t size = vx_IrType_size(var.type);
assert(size != 0);
char intArgRegs[6] = { REG_RDI.id, REG_RSI.id, REG_RDX.id, REG_RCX.id, REG_R8.id, REG_R9.id };

size_t id_i = 0;
size_t id_f = 0;
struct VarD {
vx_IrVar var;
Location* argLoc;
};
struct VarD * toMove = NULL;
size_t toMoveLen = 0;
for (size_t i = 0; i < block->ins_len; i ++) {
vx_IrTypedVar var = block->ins[i];
assert(var.type->kind == VX_IR_TYPE_KIND_BASE);
size_t size = vx_IrType_size(var.type);
assert(size != 0);

bool move_into_stack = block->as_root.vars[var.var].ever_placed;
move_into_stack = move_into_stack && (var.type->base.isfloat ? id_f < 8 : id_i < 6);
if (move_into_stack) {
size = widthToWidthWidth(size);
Location* src;
if (var.type->base.isfloat) {
Location* loc;
if (id_f >= 8) {
loc = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
} else {
size = widthToWidthWidth(size);
loc = gen_reg_var(size, IntRegCount + id_f);
}
src = gen_reg_var(size, IntRegCount + id_f);
} else {
src = gen_reg_var(size, intArgRegs[id_i]);
}

if (id_f >= anyCalledXmmArgsCount) {
varData[var.var].location = loc;
} else {
toMove = realloc(toMove, sizeof(struct VarD) * (toMoveLen + 1));
toMove[toMoveLen ++] = (struct VarD) {
.var = var.var,
.argLoc = loc
};
}
Location* loc = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;

id_f ++;
// opposite from cases below
toMove = realloc(toMove, sizeof(struct VarD) * (toMoveLen + 1));
toMove[toMoveLen ++] = (struct VarD) {
.var = var.var,
.argLoc = src,
};
varData[var.var].location = loc;
}
else if (var.type->base.isfloat) {
Location* loc;
if (id_f >= 8) {
loc = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
} else {
Location* loc;
if (id_i >= 6) {
loc = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
} else {
size = widthToWidthWidth(size);
loc = gen_reg_var(size, intArgRegs[id_i]);
}

if (id_i >= anyCalledIntArgsCount) {
varData[var.var].location = loc;
} else {
toMove = realloc(toMove, sizeof(struct VarD) * (toMoveLen + 1));
toMove[toMoveLen ++] = (struct VarD) {
.var = var.var,
.argLoc = loc
};
}

id_i ++;
size = widthToWidthWidth(size);
loc = gen_reg_var(size, IntRegCount + id_f);
}
}

free(varsHotFirst);

for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
if (varData[var].heat == 0) {
varData[var].location = NULL;
continue;
if (id_f >= anyCalledXmmArgsCount) {
varData[var.var].location = loc;
} else {
toMove = realloc(toMove, sizeof(struct VarD) * (toMoveLen + 1));
toMove[toMoveLen ++] = (struct VarD) {
.var = var.var,
.argLoc = loc
};
}

if (varData[var].location) continue;
if (varData[var].type == NULL) continue;
id_f ++;
}
else {
Location* loc;
if (id_i >= 6) {
loc = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
} else {
size = widthToWidthWidth(size);
loc = gen_reg_var(size, intArgRegs[id_i]);
}

size_t size = vx_IrType_size(varData[var].type);
varData[var].location = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
if (id_i >= anyCalledIntArgsCount) {
varData[var.var].location = loc;
} else {
toMove = realloc(toMove, sizeof(struct VarD) * (toMoveLen + 1));
toMove[toMoveLen ++] = (struct VarD) {
.var = var.var,
.argLoc = loc
};
}

id_i ++;
}
}

free(varsHotFirst);

for (size_t i = 0; i < toMoveLen; i ++) {
Location* dst = varData[toMove[i].var].location;
Location* src = toMove[i].argLoc;
emiti_move(src, dst, false, out);
for (vx_IrVar var = 0; var < block->as_root.vars_len; var ++) {
if (varData[var].heat == 0) {
varData[var].location = NULL;
continue;
}

free(toMove);
if (varData[var].location) continue;
if (varData[var].type == NULL) continue;

size_t size = vx_IrType_size(varData[var].type);
varData[var].location = gen_stack_var(size, stackOff);
stackOff += size;
anyPlaced = true;
}

bool needProlog = (stackOff > 0 && !is_leaf) ||
Expand All @@ -1598,6 +1614,13 @@ void vx_cg_x86stupid_gen(vx_IrBlock* block, FILE* out) {
}
}

for (size_t i = 0; i < toMoveLen; i ++) {
Location* dst = varData[toMove[i].var].location;
Location* src = toMove[i].argLoc;
emiti_move(src, dst, false, out);
}
free(toMove);

vx_IrOp* op = block->first;
vx_IrOp* prev = NULL;

Expand Down
8 changes: 8 additions & 0 deletions ir/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ void vx_IrBlock_llir_fix_decl(vx_IrBlock *root) {
}
}
}

for (vx_IrOp* op = root->first; op; op = op->next) {
if (op->id == VX_IR_OP_PLACE) {
vx_IrValue val = *vx_IrOp_param(op, VX_IR_NAME_VAR);
assert(val.type == VX_IR_VAL_VAR && "inliner fucked up (VX_IR_OP_PLACE)");
root->as_root.vars[val.var].ever_placed = true;
}
}
}

void vx_IrOp_warn(vx_IrOp *op, const char *optMsg0, const char *optMsg1) {
Expand Down
7 changes: 4 additions & 3 deletions ir/opt/inline_vars.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ static bool vx_IrView_substitute_var__trav(vx_IrOp *op, void *dataIn) {
}
}

for (size_t i = 0; i < op->params_len; i ++)
if (op->params[i].val.type == VX_IR_VAL_VAR && op->params[i].val.var == data->old)
op->params[i].val = data->new;
if (op->id != VX_IR_OP_PLACE)
for (size_t i = 0; i < op->params_len; i ++)
if (op->params[i].val.type == VX_IR_VAL_VAR && op->params[i].val.var == data->old)
op->params[i].val = data->new;

return false;
}
Expand Down

0 comments on commit 70dadb2

Please sign in to comment.