diff options
Diffstat (limited to 'compiler_and_linker/unsorted/SpillCode.c')
-rw-r--r-- | compiler_and_linker/unsorted/SpillCode.c | 452 |
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); - } - } - } -} |