summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/ConstantPropagation.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/ConstantPropagation.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-main.tar.gz
MWCC-main.zip
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/unsorted/ConstantPropagation.c')
-rw-r--r--compiler_and_linker/unsorted/ConstantPropagation.c643
1 files changed, 0 insertions, 643 deletions
diff --git a/compiler_and_linker/unsorted/ConstantPropagation.c b/compiler_and_linker/unsorted/ConstantPropagation.c
deleted file mode 100644
index 2b40453..0000000
--- a/compiler_and_linker/unsorted/ConstantPropagation.c
+++ /dev/null
@@ -1,643 +0,0 @@
-#include "compiler/ConstantPropagation.h"
-#include "compiler/Alias.h"
-#include "compiler/BitVectors.h"
-#include "compiler/CompilerTools.h"
-#include "compiler/PCode.h"
-#include "compiler/PCodeInfo.h"
-#include "compiler/RegisterInfo.h"
-#include "compiler/StackFrame.h"
-#include "compiler/UseDefChains.h"
-#include "compiler/objects.h"
-
-int propagatedconstants;
-static int changed;
-static PCode **defininginstruction;
-static PCode **vrdefininginstruction;
-
-static void computedefininginstructions(PCodeBlock *block) {
- RegUseOrDef *list;
- PCode *instr;
- int i;
-
- for (i = 0; i < used_virtual_registers[RegClass_GPR]; i++) {
- instr = NULL;
- for (list = reg_Defs[RegClass_GPR][i]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[block->blockIndex].defvec8)) {
- if (instr == NULL) {
- instr = Defs[list->id].pcode;
- } else {
- instr = NULL;
- break;
- }
- }
- }
- defininginstruction[i] = instr;
- }
-
- for (i = 0; i < used_virtual_registers[RegClass_VR]; i++) {
- instr = NULL;
- for (list = reg_Defs[RegClass_VR][i]; list; list = list->next) {
- if (bitvectorgetbit(list->id, usedefinfo[block->blockIndex].defvec8)) {
- if (instr == NULL) {
- instr = Defs[list->id].pcode;
- } else {
- instr = NULL;
- break;
- }
- }
- }
- vrdefininginstruction[i] = instr;
- }
-}
-
-static PCode *isstackoperand(PCodeArg *op, SInt16 *resultValue, SInt16 addend) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg]) && instr->op == PC_ADDI) {
- if (
- instr->args[2].kind == PCOp_MEMORY &&
- (instr->args[1].data.reg.reg == _FP_ || instr->args[1].data.reg.reg == _CALLER_SP_) &&
- instr->args[2].data.mem.obj->datatype == DLOCAL
- )
- {
- if (can_add_displ_to_local(instr->args[2].data.mem.obj, addend)) {
- *resultValue = instr->args[2].data.mem.offset;
- return instr;
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
- } else {
- return NULL;
- }
-}
-
-static int isconstantoperand(PCodeArg *op, SInt16 *resultValue) {
- PCode *instr;
-
- if (
- (instr = defininginstruction[op->data.reg.reg]) &&
- instr->op == PC_LI &&
- instr->args[1].kind == PCOp_IMMEDIATE
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isuint16constantoperand(PCodeArg *op, SInt16 *resultValue) {
- PCode *instr;
-
- if (
- (instr = defininginstruction[op->data.reg.reg]) &&
- instr->op == PC_LI &&
- instr->args[1].kind == PCOp_IMMEDIATE &&
- FITS_IN_USHORT(instr->args[1].data.imm.value)
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isvectorconstantoperand(PCodeArg *op, SInt16 *resultValue, Opcode *resultNewOp) {
- PCode *instr;
-
- if (
- (instr = vrdefininginstruction[op->data.reg.reg]) &&
- (instr->op == PC_VSPLTISB || instr->op == PC_VSPLTISH || instr->op == PC_VSPLTISW) &&
- instr->args[1].kind == PCOp_IMMEDIATE
- )
- {
- *resultValue = instr->args[1].data.imm.value;
- *resultNewOp = instr->op;
- return 1;
- } else {
- return 0;
- }
-}
-
-static int isunsignedloadoperand(PCodeArg *op) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg])) {
- if (instr->flags & fIsRead) {
- if (instr->op >= PC_LHZ && instr->op <= PC_LHZUX)
- return 2;
- if (instr->op >= PC_LBZ && instr->op <= PC_LBZUX)
- return 1;
- } else if (instr->op == PC_RLWINM) {
- int var3 = instr->args[3].data.imm.value;
- int var4 = instr->args[4].data.imm.value;
- if (var4 == 31) {
- if (var3 == 24)
- return 1;
- if (var3 == 16)
- return 2;
- }
- }
- }
-
- return 0;
-}
-
-static int ismaskedoperand(PCodeArg *op, UInt32 *resultMask) {
- PCode *instr;
- UInt32 mask;
-
- if ((instr = defininginstruction[op->data.reg.reg]) && instr->op == PC_RLWINM) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value) {
- mask =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) &
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- } else {
- mask =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) |
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- }
- *resultMask = mask;
- return 1;
- }
-
- return 0;
-}
-
-static int issignedloadoperand(PCodeArg *op) {
- PCode *instr;
-
- if ((instr = defininginstruction[op->data.reg.reg])) {
- if (instr->flags & fIsRead) {
- if (instr->op >= PC_LHA && instr->op <= PC_LHAUX)
- return 2;
- } else if (instr->op == PC_EXTSB) {
- return 1;
- } else if (instr->op == PC_EXTSH) {
- return 2;
- }
- }
-
- return 0;
-}
-
-static void propagateconstantstoblock(PCodeBlock *block) {
- PCode *instr;
- SInt16 immAddend;
- SInt16 value1;
- SInt16 valueU16;
- Opcode newOpcode;
- SInt16 value2;
- UInt32 mask;
- UInt32 mask2;
- int loadSize;
- PCodeArg *op;
- int i;
-
- for (instr = block->firstPCode; instr; instr = instr->nextPCode) {
- switch (instr->op) {
- case PC_MR:
- if (isconstantoperand(&instr->args[1], &value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
- break;
- case PC_VMR:
- if (isvectorconstantoperand(&instr->args[1], &value1, &newOpcode)) {
- change_opcode(instr, newOpcode);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
- break;
- case PC_RLWINM:
- if (
- !(PCODE_FLAG_SET_F(instr) & fRecordBit) &&
- instr->args[2].data.imm.value == 0 &&
- instr->args[4].data.imm.value == 31
- )
- {
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (
- (instr->args[3].data.imm.value == 16 && value1 == (value1 & 0x7FFF)) ||
- (instr->args[3].data.imm.value == 24 && value1 == (value1 & 0xFF))
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
- }
-
- loadSize = isunsignedloadoperand(&instr->args[1]);
- if (
- (loadSize == 2 && instr->args[3].data.imm.value <= 16) ||
- (loadSize == 1 && instr->args[3].data.imm.value <= 24)
- )
- {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- if (ismaskedoperand(&instr->args[1], &mask)) {
- if (instr->args[3].data.imm.value <= instr->args[4].data.imm.value) {
- mask2 =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) &
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- } else {
- mask2 =
- ((instr->args[3].data.imm.value > 31) ? 0 : (0xFFFFFFFFU >> instr->args[3].data.imm.value)) |
- ~(((instr->args[4].data.imm.value + 1) > 31) ? 0 : (0xFFFFFFFFU >> (instr->args[4].data.imm.value + 1)));
- }
- if (mask == (mask & mask2)) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- }
- break;
-
- case PC_EXTSH:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- loadSize = issignedloadoperand(&instr->args[1]);
- if (loadSize == 1 || loadSize == 2) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_EXTSB:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (
- isconstantoperand(&instr->args[1], &value1) &&
- value1 >= -128 &&
- value1 <= 127
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- break;
- }
-
- loadSize = issignedloadoperand(&instr->args[1]);
- if (loadSize == 1) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_ADDI:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- immAddend = instr->args[2].data.imm.value;
- if (
- isconstantoperand(&instr->args[1], &value1) &&
- FITS_IN_SHORT(immAddend + value1)
- )
- {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend + value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- break;
-
- case PC_ADD:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[2], &value1)) {
- if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- immAddend = value1;
- }
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (instr->op == PC_ADDI || instr->op == PC_MR) {
- if (FITS_IN_SHORT(immAddend + value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend + value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- } else {
- instr->args[1] = instr->args[2];
- if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- }
- }
-
- if (changed) {
- if (instr->op == PC_MR) {
- PCode *stackInstr;
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, 0))) {
- change_opcode(instr, PC_ADDI);
- instr->flags = stackInstr->flags;
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- change_num_operands(instr, 3);
- propagatedconstants = 1;
- changed = 1;
- }
- } else if (instr->op == PC_ADDI && instr->args[2].kind == PCOp_IMMEDIATE) {
- PCode *stackInstr;
- SInt16 addend = instr->args[2].data.imm.value;
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, addend))) {
- change_opcode(instr, PC_ADDI);
- instr->flags = stackInstr->flags;
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- instr->args[2].data.imm.value = value1 + addend;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000))
- instr->alias = make_alias(instr->args[2].data.imm.obj, instr->args[2].data.imm.value, 1);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- }
- break;
-
- case PC_OR:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- value1 = 0;
- immAddend = 0;
- if (isconstantoperand(&instr->args[2], &value1)) {
- if (isuint16constantoperand(&instr->args[2], &valueU16)) {
- if (valueU16 != 0) {
- change_opcode(instr, PC_ORI);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = valueU16;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- value1 = valueU16;
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- immAddend = value1;
- }
-
- if (isconstantoperand(&instr->args[1], &value1)) {
- if (instr->op == PC_ORI || instr->op == PC_MR) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = immAddend | value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- } else if (isuint16constantoperand(&instr->args[1], &valueU16)) {
- if (valueU16 != 0) {
- change_opcode(instr, PC_ORI);
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = valueU16;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- propagatedconstants = 1;
- changed = 1;
- }
- }
- break;
-
- case PC_SUBF:
- if (PCODE_FLAG_SET_F(instr) & fRecordBit)
- break;
-
- if (isconstantoperand(&instr->args[1], &value1) && FITS_IN_SHORT(-value1)) {
- if (isconstantoperand(&instr->args[2], &value2) && FITS_IN_SHORT(value2 - value1)) {
- change_opcode(instr, PC_LI);
- instr->args[1].kind = PCOp_IMMEDIATE;
- instr->args[1].data.imm.value = value2 - value1;
- instr->args[1].data.imm.obj = NULL;
- change_num_operands(instr, 2);
- } else if (value1 == 0) {
- change_opcode(instr, PC_MR);
- instr->args[1] = instr->args[2];
- change_num_operands(instr, 2);
- } else {
- change_opcode(instr, PC_ADDI);
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = -value1;
- instr->args[2].data.imm.obj = NULL;
- }
- propagatedconstants = 1;
- changed = 1;
- value2 = value1;
- } else if (isconstantoperand(&instr->args[2], &value1) && FITS_IN_SHORT(-value1)) {
- if (value1 == 0) {
- change_opcode(instr, PC_NEG);
- change_num_operands(instr, 2);
- } else {
- instr->flags = opcodeinfo[PC_SUBFIC].flags | (instr->flags & ~opcodeinfo[PC_SUBF].flags);
- change_opcode(instr, PC_SUBFIC);
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- instr->args[3].kind = PCOp_REGISTER;
- instr->args[3].arg = RegClass_SPR;
- instr->args[3].data.reg.reg = 0;
- instr->args[3].data.reg.effect = EffectWrite;
- change_num_operands(instr, 4);
- }
- propagatedconstants = 1;
- changed = 1;
- }
-
- break;
-
- case PC_LBZ:
- case PC_LHZ:
- case PC_LHA:
- case PC_LWZ:
- case PC_STB:
- case PC_STH:
- case PC_STW:
- case PC_LFS:
- case PC_LFD:
- case PC_STFS:
- case PC_STFD:
- if (instr->args[2].kind == PCOp_IMMEDIATE) {
- PCode *stackInstr;
- SInt16 addend = instr->args[2].data.imm.value;
-
- if ((stackInstr = isstackoperand(&instr->args[1], &value1, addend))) {
- instr->args[1] = stackInstr->args[1];
- instr->args[2] = stackInstr->args[2];
- instr->args[2].data.imm.value = value1 + addend;
- if (instr->flags & (fIsRead | fIsWrite | fPCodeFlag20000 | fPCodeFlag40000))
- instr->alias = make_alias(instr->args[2].data.imm.obj, instr->args[2].data.imm.value,
- nbytes_loaded_or_stored_by(instr));
- propagatedconstants = 1;
- changed = 1;
- }
- }
- break;
-
- case PC_LBZX:
- case PC_LHZX:
- case PC_LHAX:
- case PC_LWZX:
- case PC_STBX:
- case PC_STHX:
- case PC_STWX:
- case PC_LFSX:
- case PC_LFDX:
- case PC_STFSX:
- case PC_STFDX:
- if (isconstantoperand(&instr->args[2], &value1)) {
- instr->op -= 2;
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- } else if (isconstantoperand(&instr->args[1], &value1)) {
- instr->op -= 2;
- instr->args[1] = instr->args[2];
- instr->args[2].kind = PCOp_IMMEDIATE;
- instr->args[2].data.imm.value = value1;
- instr->args[2].data.imm.obj = NULL;
- propagatedconstants = 1;
- changed = 1;
- }
-
- break;
- }
-
- for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
- if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_GPR &&
- (op->data.reg.effect & EffectWrite)
- )
- {
- defininginstruction[op->data.reg.reg] = instr;
- }
- else if (
- op->kind == PCOp_REGISTER &&
- op->arg == RegClass_VR &&
- (op->data.reg.effect & EffectWrite)
- )
- {
- vrdefininginstruction[op->data.reg.reg] = instr;
- }
- }
- }
-}
-
-void propagateconstants(void) {
- PCodeBlock *block;
- int i;
-
- propagatedconstants = 0;
- computeusedefchains(0);
- defininginstruction = galloc(sizeof(PCode *) * used_virtual_registers[RegClass_GPR]);
- vrdefininginstruction = galloc(sizeof(PCode *) * used_virtual_registers[RegClass_VR]);
-
- do {
- changed = 0;
- for (i = 0; i < pcblockcount; i++) {
- if ((block = depthfirstordering[i])) {
- computedefininginstructions(block);
- propagateconstantstoblock(block);
- }
- }
- } while (changed);
-
- freeoheap();
-}