summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/SpillCode.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/SpillCode.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz
MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/SpillCode.c')
-rw-r--r--compiler_and_linker/unsorted/SpillCode.c452
1 files changed, 0 insertions, 452 deletions
diff --git a/compiler_and_linker/unsorted/SpillCode.c b/compiler_and_linker/unsorted/SpillCode.c
deleted file mode 100644
index 69e7e43..0000000
--- a/compiler_and_linker/unsorted/SpillCode.c
+++ /dev/null
@@ -1,452 +0,0 @@
-#include "compiler/SpillCode.h"
-#include "compiler/CError.h"
-#include "compiler/CMachine.h"
-#include "compiler/CParser.h"
-#include "compiler/CodeGen.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/Coloring.h"
-#include "compiler/InterferenceGraph.h"
-#include "compiler/Operands.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeUtilities.h"
-#include "compiler/Registers.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/objects.h"
-
-static int last_unused_vreg_before_spilling;
-static short rTEMP_for_VR_spill;
-
-void estimatespillcosts(void) {
- PCodeBlock *block;
- PCode *instr;
- IGNode *node;
- PCodeArg *op;
- int i;
- int weight;
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- if (copts.optimizesize)
- weight = 1;
- else
- weight = block->loopWeight;
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_READ_ANY_REGISTER(op, coloring_class)) {
- node = interferencegraph[op->data.reg.reg];
- if (node->instr8 || copts.optimizesize)
- node->spillCost += weight;
- else
- node->spillCost += weight * 2;
- }
- op++;
- }
-
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (PC_OP_IS_WRITE_ANY_REGISTER(op, coloring_class)) {
- node = interferencegraph[op->data.reg.reg];
- if (node->instr8 || (instr->flags & fIsArgInit))
- node->spillCost -= weight;
- else
- node->spillCost += weight;
- }
- op++;
- }
- }
- }
-}
-
-static Object *makespilltemporary(Type *type) {
- Object *obj = lalloc(sizeof(Object));
- memclrw(obj, sizeof(Object));
-
- obj->otype = OT_OBJECT;
- obj->access = ACCESSPUBLIC;
- obj->datatype = DLOCAL;
- obj->type = type;
- obj->name = CParser_GetUniqueName();
- obj->u.var.info = CodeGen_GetNewVarInfo();
- obj->u.var.uid = 0;
-
- return obj;
-}
-
-static PCode *rematerialize_spilled_register(short reg, IGNode *node) {
- PCode *instr = copypcode(node->instr8);
-
- CError_ASSERT(128, instr->args[0].kind == PCOp_REGISTER);
-
- instr->args[0].data.reg.reg = reg;
- return instr;
-}
-
-static void insert_load_spilled_register(PCode *instr, short reg, IGNode *node) {
- Type *type;
- Opcode opcode;
- Object *object;
- PCode *newInstr;
- PCode *newInstr2;
- SInt32 offset;
- Operand operand;
-
- type = node->spillTemporary->type;
- switch (coloring_class) {
- case RegClass_CRFIELD:
- case RegClass_GPR:
- switch (type->size) {
- case 1:
- opcode = PC_LBZ;
- break;
- case 2:
- opcode = is_unsigned(type) ? PC_LHZ : PC_LHA;
- break;
- case 4:
- opcode = PC_LWZ;
- break;
- case 8:
- opcode = PC_LWZ;
- break;
- default:
- CError_FATAL(187);
- }
-
- memclrw(&operand, sizeof(Operand));
- operand.optype = OpndType_Symbol;
- operand.object = node->spillTemporary;
- CError_ASSERT(222, node->spillTemporary->datatype == DLOCAL);
-
- coerce_to_addressable(&operand);
-
- CError_ASSERT(233, operand.optype == OpndType_GPR_ImmOffset);
-
- CError_ASSERT(237, node->spillTemporary->datatype == DLOCAL);
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
- insertpcodebefore(instr, makepcode(opcode, reg, operand.reg, operand.object, operand.immOffset + offset));
- break;
-
- case RegClass_FPR:
- CError_ASSERT(253, node->spillTemporary->datatype == DLOCAL);
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
-
- object = node->spillTemporary;
- insertpcodebefore(
- instr,
- makepcode(
- (type->size == 8) ? PC_LFD : PC_LFS,
- reg,
- local_base_register(object),
- object,
- offset
- )
- );
- break;
-
- case RegClass_VR:
- CError_ASSERT(320, node->spillTemporary->datatype == DLOCAL);
-
- object = node->spillTemporary;
- newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
- newInstr2 = makepcode(PC_LVX, reg, 0, rTEMP_for_VR_spill);
- insertpcodebefore(instr, newInstr);
- insertpcodeafter(newInstr, newInstr2);
- break;
-
- default:
- CError_FATAL(333);
- }
-}
-
-static void insert_store_spilled_register(PCode *instr, Boolean flag, short reg, IGNode *node) {
- Object *object; // r31
- Opcode opcode; // r30
- SInt32 offset; // r26
- PCode *newInstr2; // r26
- PCode *newInstr; // r25
- Type *type; // r25
-
- object = node->spillTemporary;
- type = object->type;
-
- switch (coloring_class) {
- case RegClass_CRFIELD:
- case RegClass_GPR:
- switch (type->size) {
- case 1:
- opcode = PC_STB;
- break;
- case 2:
- opcode = PC_STH;
- break;
- case 4:
- opcode = PC_STW;
- break;
- case 8:
- opcode = PC_STW;
- break;
- default:
- CError_FATAL(391);
- }
-
- if (node->flags & fPairLow)
- offset = low_offset;
- else if (node->flags & fPairHigh)
- offset = high_offset;
- else
- offset = 0;
-
- newInstr = makepcode(opcode, reg, local_base_register(object), object, offset);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
-
- break;
-
- case RegClass_FPR:
- newInstr = makepcode((type->size == 8) ? PC_STFD : PC_STFS, reg, local_base_register(object), object, 0);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
-
- break;
-
- case RegClass_VR:
- newInstr = makepcode(PC_ADDI, rTEMP_for_VR_spill, local_base_register(object), object, 0);
- newInstr2 = makepcode(PC_STVX, reg, 0, rTEMP_for_VR_spill);
- if (flag)
- insertpcodebefore(instr, newInstr);
- else
- insertpcodeafter(instr, newInstr);
- insertpcodeafter(newInstr, newInstr2);
-
- break;
-
- default:
- CError_FATAL(527);
- }
-}
-
-static void spillinstruction(PCodeBlock *block, PCode *instr) {
- int reg;
- int reg2;
- int regs;
- IGNode *node;
- PCodeArg *op;
- int i;
- PCodeArg *op2;
- int j;
- int readCounter;
- int writeCounter;
- Boolean flag;
-
- regs = used_virtual_registers[coloring_class];
- flag = 0;
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- CError_ASSERT(563, instr->block != NULL);
-
- if (
- PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
- (reg = op->data.reg.reg) < regs &&
- ((node = interferencegraph[op->data.reg.reg])->flags & fSpilled)
- )
- {
- reg2 = used_virtual_registers[coloring_class]++;
- readCounter = 0;
- writeCounter = 0;
-
- for (j = i, op2 = op; j < instr->argCount; j++, op2++) {
- if (PC_OP_IS_REGISTER(op2, coloring_class, reg)) {
- if (op2->data.reg.effect & EffectRead)
- readCounter++;
- if (op2->data.reg.effect & EffectWrite)
- writeCounter++;
- op2->data.reg.reg = reg2;
- op2->data.reg.effect |= Effect40;
- }
- }
-
- if (readCounter) {
- if (node->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(reg2, node));
- else
- insert_load_spilled_register(instr, reg2, node);
- }
-
- if (writeCounter) {
- if (node->instr8 || (instr->flags & fIsArgInit))
- flag = 1;
- else
- insert_store_spilled_register(instr, 0, reg2, node);
- }
- }
- }
-
- if (flag)
- deletepcode(instr);
-}
-
-static void spillcopy(PCodeBlock *block, PCode *instr) {
- IGNode *node1;
- IGNode *node2;
- int reg;
-
- node1 = interferencegraph[instr->args[1].data.reg.reg];
- node2 = interferencegraph[instr->args[0].data.reg.reg];
-
- if (node1->flags & fSpilled) {
- if (node2->flags & fSpilled) {
- reg = used_virtual_registers[coloring_class]++;
- if (node1->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(reg, node1));
- else
- insert_load_spilled_register(instr, reg, node1);
- insert_store_spilled_register(instr, 1, reg, node2);
- } else {
- if (node1->instr8)
- insertpcodebefore(instr, rematerialize_spilled_register(instr->args[0].data.reg.reg, node1));
- else
- insert_load_spilled_register(instr, instr->args[0].data.reg.reg, node1);
- }
- } else {
- insert_store_spilled_register(instr, 1, instr->args[1].data.reg.reg, node2);
- }
-
- deletepcode(instr);
-}
-
-static void spillcall(PCodeBlock *block, PCode *instr) {
- PCodeArg *opSrc;
- PCodeArg *opDst;
- int opCount;
- int volatileCount;
- int i;
-
- opCount = instr->argCount;
- volatileCount = branch_count_volatiles();
-
- opDst = instr->args + volatileCount;
- opSrc = instr->args + volatileCount;
- for (i = volatileCount; i < opCount; i++) {
- if (
- PC_OP_IS_ANY_REGISTER(opSrc, coloring_class) &&
- opSrc->data.reg.reg >= n_real_registers[coloring_class] &&
- (interferencegraph[opSrc->data.reg.reg]->flags & fSpilled)
- )
- {
- instr->argCount--;
- } else {
- *opDst = *opSrc;
- opDst++;
- }
- opSrc++;
- }
-
- spillinstruction(block, instr);
-}
-
-static void assign_spill_locations(void) {
- UInt32 i;
- IGNode *node;
- Type *type;
-
- last_unused_vreg_before_spilling = used_virtual_registers[coloring_class];
- for (i = n_real_registers[coloring_class]; i < last_unused_vreg_before_spilling; i++) {
- node = interferencegraph[i];
- if (node->flags & fCoalesced)
- continue;
- if (!(node->flags & fSpilled))
- continue;
-
- if (!node->spillTemporary) {
- switch (coloring_class) {
- case RegClass_GPR:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_CRFIELD:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_FPR:
- type = TYPE(&stunsignedlong);
- break;
- case RegClass_VR:
- type = TYPE(&stvectorunsignedchar);
- break;
- default:
- CError_FATAL(771);
- }
-
- node->spillTemporary = makespilltemporary(type);
- }
-
- if (node->spillTemporary->datatype == DLOCAL && !(node->spillTemporary->u.var.info->flags & VarInfoFlag1))
- assign_local_memory(node->spillTemporary);
-
- if (node->flags & fPairHigh)
- Registers_GetVarInfo(node->spillTemporary)->regHi = Register0;
- else
- Registers_GetVarInfo(node->spillTemporary)->reg = Register0;
- }
-}
-
-void insertspillcode(void) {
- PCodeBlock *block;
- PCode *instr;
- PCode *nextInstr;
- PCodeArg *op;
- UInt32 i;
- int flag;
-
- rTEMP_for_VR_spill = 0;
- assign_spill_locations();
-
- for (block = pcbasicblocks; block; block = block->nextBlock) {
- for (instr = block->firstPCode; instr; instr = nextInstr) {
- nextInstr = instr->nextPCode;
- flag = 0;
- op = instr->args;
- i = instr->argCount;
- while (i--) {
- if (
- PC_OP_IS_ANY_REGISTER(op, coloring_class) &&
- op->data.reg.reg < last_unused_vreg_before_spilling &&
- (interferencegraph[op->data.reg.reg]->flags & fSpilled)
- )
- {
- flag = 1;
- break;
- }
- op++;
- }
-
- if (flag) {
- if (coloring_class == RegClass_VR && rTEMP_for_VR_spill == 0)
- rTEMP_for_VR_spill = used_virtual_registers[RegClass_GPR]++;
-
- if (instr->flags & fIsMove)
- spillcopy(block, instr);
- else if (instr->flags & fIsCall)
- spillcall(block, instr);
- else
- spillinstruction(block, instr);
- }
- }
- }
-}