MWCC/compiler_and_linker/unsorted/UseDefChains.c

565 lines
22 KiB
C

#include "compiler/UseDefChains.h"
#include "compiler/Alias.h"
#include "compiler/BitVectors.h"
#include "compiler/CompilerTools.h"
#include "compiler/PCode.h"
#include "compiler/Registers.h"
#include "compiler/objects.h"
#include "compiler/types.h"
int number_of_Defs;
UseOrDef *Defs;
RegUseOrDef **reg_Defs[RegClassMax];
int number_of_Uses;
UseOrDef *Uses;
RegUseOrDef **reg_Uses[RegClassMax];
UseDefInfo *usedefinfo;
ObjectUseDef *objectusedefs;
ObjectUseDef *objectusedeflist;
ObjectUseDef *findobjectusedef(Object *object) {
ObjectUseDef *oud;
oud = objectusedefs;
while (oud) {
if (((unsigned long) object) < ((unsigned long) oud->object))
oud = oud->leftchild;
else if (((unsigned long) object) > ((unsigned long) oud->object))
oud = oud->rightchild;
else
return oud;
}
return NULL;
}
static void addobjectusedef(Object *object) {
ObjectUseDef **ptr;
ObjectUseDef *list;
ptr = &objectusedefs;
while (*ptr) {
if (((unsigned long) object) < ((unsigned long) (*ptr)->object))
ptr = &(*ptr)->leftchild;
else if (((unsigned long) object) > ((unsigned long) (*ptr)->object))
ptr = &(*ptr)->rightchild;
else
return;
}
list = oalloc(sizeof(ObjectUseDef));
list->leftchild = list->rightchild = NULL;
list->object = object;
list->uses = list->defs = NULL;
list->next = objectusedeflist;
objectusedeflist = list;
*ptr = list;
}
static void addaliasusedef(Alias *alias) {
AliasMember *member;
if (alias && alias != worst_case) {
if (alias->type == AliasType2) {
for (member = alias->parents; member; member = member->nextParent)
addaliasusedef(member->child);
} else {
addobjectusedef(alias->object);
}
}
}
static void addworstcase(void) {
addobjectusedef(&worst_case_obj);
}
static void precomputememoryusedefs(void) {
PCodeBlock *block;
PCode *pcode;
objectusedeflist = NULL;
objectusedefs = NULL;
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
if (pcode->flags & (fIsRead | fIsWrite)) {
if (pcode->alias) {
if (pcode->alias->type == AliasType2 || pcode->alias->size != nbytes_loaded_or_stored_by(pcode))
pcode->flags |= fIsPtrOp;
addaliasusedef(pcode->alias);
} else {
pcode->flags |= fIsPtrOp;
}
}
}
}
addworstcase();
}
static void precomputeusedefcounts(int flag) {
PCodeBlock *block;
PCode *pcode;
PCodeArg *op;
int i;
ObjectUseDef *oud;
number_of_Defs = 0;
number_of_Uses = 0;
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
if (!(pcode->flags & fIsBranch) && pcode->argCount) {
pcode->useID = number_of_Uses;
pcode->defID = number_of_Defs;
op = pcode->args;
i = pcode->argCount;
while (i--) {
if (op->kind == PCOp_REGISTER && op->data.reg.reg >= n_real_registers[op->arg]) {
if (op->data.reg.effect & EffectRead)
number_of_Uses++;
if (op->data.reg.effect & EffectWrite)
number_of_Defs++;
}
op++;
}
if (flag) {
if (pcode->flags & fIsRead) {
if (pcode->flags & fIsPtrOp) {
for (oud = objectusedeflist; oud; oud = oud->next) {
if (may_alias_object(pcode, oud->object))
number_of_Uses++;
}
} else {
number_of_Uses++;
}
} else if (pcode->flags & fIsWrite) {
if (pcode->flags & fIsPtrOp) {
for (oud = objectusedeflist; oud; oud = oud->next) {
if (may_alias_object(pcode, oud->object))
number_of_Defs++;
}
} else {
number_of_Defs++;
}
} else if (pcode->flags & fIsCall) {
for (oud = objectusedeflist; oud; oud = oud->next) {
if (
oud->object->datatype == DDATA ||
oud->object->datatype == DNONLAZYPTR ||
(oud->object->datatype == DLOCAL && (
oud->object->u.var.info->noregister ||
IS_TYPE_ARRAY(oud->object->type) ||
IS_TYPE_NONVECTOR_STRUCT(oud->object->type) ||
IS_TYPE_CLASS(oud->object->type) ||
IS_TYPE_12BYTES_MEMBERPOINTER(oud->object->type)
))
) {
number_of_Uses++;
number_of_Defs++;
}
}
}
}
}
}
}
}
static void computeusedeflists(int flag) {
ObjectUseDef *oud;
RegUseOrDef *list;
PCodeBlock *block;
PCode *pcode;
PCodeArg *op;
int i;
UseOrDef *use;
UseOrDef *def;
int useID;
int defID;
ObjectUseDef *tmp;
Object *object;
Uses = oalloc(sizeof(UseOrDef) * number_of_Uses);
Defs = oalloc(sizeof(UseOrDef) * number_of_Defs);
reg_Uses[RegClass_GPR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_GPR]);
reg_Defs[RegClass_GPR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_GPR]);
for (i = 0; i < used_virtual_registers[RegClass_GPR]; i++) {
reg_Uses[RegClass_GPR][i] = NULL;
reg_Defs[RegClass_GPR][i] = NULL;
}
reg_Uses[RegClass_FPR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_FPR]);
reg_Defs[RegClass_FPR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_FPR]);
for (i = 0; i < used_virtual_registers[RegClass_FPR]; i++) {
reg_Uses[RegClass_FPR][i] = NULL;
reg_Defs[RegClass_FPR][i] = NULL;
}
reg_Uses[RegClass_VR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_VR]);
reg_Defs[RegClass_VR] = oalloc(sizeof(RegUseOrDef *) * used_virtual_registers[RegClass_VR]);
for (i = 0; i < used_virtual_registers[RegClass_VR]; i++) {
reg_Uses[RegClass_VR][i] = NULL;
reg_Defs[RegClass_VR][i] = NULL;
}
for (block = pcbasicblocks; block; block = block->nextBlock) {
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
if (!(pcode->flags & fIsBranch) && pcode->argCount) {
use = &Uses[useID = pcode->useID];
def = &Defs[defID = pcode->defID];
op = pcode->args;
i = pcode->argCount;
while (i--) {
if (op->kind == PCOp_REGISTER && op->data.reg.reg >= n_real_registers[op->arg]) {
if (op->data.reg.effect & EffectRead) {
use->pcode = pcode;
use->v.kind = op->kind;
use->v.arg = op->arg;
use->v.u.reg = op->data.reg.reg;
list = oalloc(sizeof(RegUseOrDef));
list->id = useID;
list->next = reg_Uses[op->arg][op->data.reg.reg];
reg_Uses[op->arg][op->data.reg.reg] = list;
use++;
useID++;
}
if (op->data.reg.effect & EffectWrite) {
def->pcode = pcode;
def->v.kind = op->kind;
def->v.arg = op->arg;
def->v.u.reg = op->data.reg.reg;
list = oalloc(sizeof(RegUseOrDef));
list->id = defID;
list->next = reg_Defs[op->arg][op->data.reg.reg];
reg_Defs[op->arg][op->data.reg.reg] = list;
def++;
defID++;
}
}
op++;
}
if (flag) {
if (pcode->flags & fIsRead) {
if (pcode->flags & fIsPtrOp) {
for (oud = objectusedeflist; oud; oud = oud->next) {
if (may_alias_object(pcode, object = oud->object)) {
use->pcode = pcode;
use->v.kind = PCOp_MEMORY;
use->v.arg = 1;
use->v.u.object = object;
list = oalloc(sizeof(RegUseOrDef));
list->id = useID;
list->next = oud->uses;
oud->uses = list;
use++;
useID++;
}
}
} else {
object = pcode->alias->object;
use->pcode = pcode;
use->v.kind = PCOp_MEMORY;
use->v.arg = 0;
use->v.u.object = object;
list = oalloc(sizeof(RegUseOrDef));
list->id = useID;
tmp = findobjectusedef(object);
list->next = tmp->uses;
tmp->uses = list;
}
} else if (pcode->flags & fIsWrite) {
if (pcode->flags & fIsPtrOp) {
for (oud = objectusedeflist; oud; oud = oud->next) {
if (may_alias_object(pcode, object = oud->object)) {
def->pcode = pcode;
def->v.kind = PCOp_MEMORY;
def->v.arg = 1;
def->v.u.object = object;
list = oalloc(sizeof(RegUseOrDef));
list->id = defID;
list->next = oud->defs;
oud->defs = list;
def++;
defID++;
}
}
} else {
object = pcode->alias->object;
def->pcode = pcode;
def->v.kind = PCOp_MEMORY;
def->v.arg = 0;
def->v.u.object = object;
list = oalloc(sizeof(RegUseOrDef));
list->id = defID;
tmp = findobjectusedef(object);
list->next = tmp->defs;
tmp->defs = list;
}
} else if (pcode->flags & fIsCall) {
for (oud = objectusedeflist; oud; oud = oud->next) {
object = oud->object;
if (
object->datatype == DDATA ||
object->datatype == DNONLAZYPTR ||
(object->datatype == DLOCAL && (
object->u.var.info->noregister ||
IS_TYPE_ARRAY(object->type) ||
IS_TYPE_NONVECTOR_STRUCT(object->type) ||
IS_TYPE_CLASS(oud->object->type) ||
IS_TYPE_12BYTES_MEMBERPOINTER(object->type)
))
) {
use->pcode = pcode;
use->v.kind = PCOp_MEMORY;
use->v.arg = 1;
use->v.u.object = object;
list = oalloc(sizeof(RegUseOrDef));
list->id = useID;
list->next = oud->uses;
oud->uses = list;
def->pcode = pcode;
def->v.kind = PCOp_MEMORY;
def->v.arg = 1;
def->v.u.object = object;
use++;
useID++;
list = oalloc(sizeof(RegUseOrDef));
list->id = defID;
list->next = oud->defs;
oud->defs = list;
def++;
defID++;
}
}
}
}
}
}
}
}
static void allocateusedefinfo(void) {
UseDefInfo *info;
int i;
usedefinfo = oalloc(pcblockcount * sizeof(UseDefInfo));
for (i = 0, info = usedefinfo; i < pcblockcount; i++, info++) {
info->defvec0 = oalloc(4 * ((number_of_Defs + 31) >> 5));
info->defvec4 = oalloc(4 * ((number_of_Defs + 31) >> 5));
info->defvec8 = oalloc(4 * ((number_of_Defs + 31) >> 5));
info->defvecC = oalloc(4 * ((number_of_Defs + 31) >> 5));
info->usevec10 = oalloc(4 * ((number_of_Uses + 31) >> 5));
info->usevec14 = oalloc(4 * ((number_of_Uses + 31) >> 5));
info->usevec18 = oalloc(4 * ((number_of_Uses + 31) >> 5));
info->usevec1C = oalloc(4 * ((number_of_Uses + 31) >> 5));
}
}
static void computelocalusedefinfo(void) {
PCodeBlock *block; // r28
PCode *pcode; // r27
UInt32 *defvec0; // r26
UInt32 *defvec4; // r25
UInt32 *usevec10; // r24
UInt32 *usevec14; // r23
UseOrDef *use; // r22
UseOrDef *def; // r22
int useID; // r15
int defID; // r21
ObjectUseDef *oud; // r17
RegUseOrDef *list; // r16
UseDefInfo *info; // r15
for (block = pcbasicblocks; block; block = block->nextBlock) {
info = &usedefinfo[block->blockIndex];
defvec0 = info->defvec0;
defvec4 = info->defvec4;
usevec10 = info->usevec10;
usevec14 = info->usevec14;
bitvectorinitialize(defvec0, number_of_Defs, 0);
bitvectorinitialize(defvec4, number_of_Defs, 0);
bitvectorinitialize(usevec10, number_of_Uses, 0);
bitvectorinitialize(usevec14, number_of_Uses, 0);
bitvectorinitialize(info->defvec8, number_of_Defs, 0);
bitvectorinitialize(info->defvecC, number_of_Defs, 0);
bitvectorinitialize(info->usevec18, number_of_Uses, 0);
bitvectorinitialize(info->usevec1C, number_of_Uses, 0);
for (pcode = block->firstPCode; pcode; pcode = pcode->nextPCode) {
if (!(pcode->flags & fIsBranch) && pcode->argCount) {
for (use = &Uses[useID = pcode->useID]; useID < number_of_Uses && use->pcode == pcode; use++, useID++) {
bitvectorsetbit(useID, usevec10);
if (use->v.kind == PCOp_REGISTER) {
for (list = reg_Defs[use->v.arg][use->v.u.reg]; list; list = list->next) {
if (bitvectorgetbit(list->id, defvec0))
bitvectorclearbit(useID, usevec10);
}
} else {
for (list = findobjectusedef(use->v.u.object)->defs; list; list = list->next) {
if (uniquely_aliases(pcode, Defs[list->id].pcode)) {
if (Defs[list->id].v.arg == 0 && bitvectorgetbit(list->id, defvec0))
bitvectorclearbit(useID, usevec10);
}
}
}
}
for (def = &Defs[defID = pcode->defID]; defID < number_of_Defs && def->pcode == pcode; def++, defID++) {
if (def->v.kind == PCOp_REGISTER) {
for (list = reg_Uses[def->v.arg][def->v.u.reg]; list; list = list->next) {
if (Uses[list->id].pcode->block != block)
bitvectorsetbit(list->id, usevec14);
}
for (list = reg_Defs[def->v.arg][def->v.u.reg]; list; list = list->next) {
if (Defs[list->id].pcode->block != block)
bitvectorsetbit(list->id, defvec4);
else
bitvectorclearbit(list->id, defvec0);
}
} else if (def->v.arg == 0) {
oud = findobjectusedef(def->v.u.object);
for (list = oud->uses; list; list = list->next) {
if (may_alias(pcode, Uses[list->id].pcode)) {
if (Uses[list->id].pcode->block != block)
bitvectorsetbit(list->id, usevec14);
}
}
for (list = oud->defs; list; list = list->next) {
if (uniquely_aliases(pcode, Defs[list->id].pcode)) {
if (Defs[list->id].pcode->block != block)
bitvectorsetbit(list->id, defvec4);
else
bitvectorclearbit(list->id, defvec0);
}
}
}
bitvectorsetbit(defID, defvec0);
}
}
}
}
}
static void computeglobalusedefinfo(void) {
UseDefInfo *udi;
UInt32 *defVec0;
UInt32 *defVec4;
UInt32 *defVec8;
UInt32 *defVecC;
int bitvecsize;
int i;
int j;
int flag;
PCLink *preds;
UInt32 val;
bitvecsize = (number_of_Defs + 31) >> 5;
flag = 1;
while (flag) {
flag = 0;
for (i = 0; i < pcblockcount; i++) {
if (depthfirstordering[i]) {
udi = &usedefinfo[depthfirstordering[i]->blockIndex];
if ((preds = depthfirstordering[i]->predecessors)) {
defVec8 = udi->defvec8;
bitvectorcopy(defVec8, usedefinfo[preds->block->blockIndex].defvecC, number_of_Defs);
for (preds = preds->nextLink; preds; preds = preds->nextLink)
bitvectorunion(defVec8, usedefinfo[preds->block->blockIndex].defvecC, number_of_Defs);
}
defVecC = udi->defvecC;
defVec8 = udi->defvec8;
defVec0 = udi->defvec0;
defVec4 = udi->defvec4;
for (j = 0; j < bitvecsize; j++) {
val = *defVec0 | (*defVec8 & ~*defVec4);
if (val != *defVecC) {
*defVecC = val;
flag = 1;
}
defVec8++;
defVecC++;
defVec4++;
defVec0++;
}
}
}
}
}
static void computeglobaldefuseinfo(void) {
UseDefInfo *udi;
UInt32 *useVec10;
UInt32 *useVec14;
UInt32 *useVec18;
UInt32 *useVec1C;
int bitvecsize;
int i;
int j;
int flag;
PCLink *succs;
UInt32 val;
PCodeBlock *block;
bitvecsize = (number_of_Uses + 31) >> 5;
flag = 1;
while (flag) {
flag = 0;
i = pcblockcount;
while (i) {
if ((block = depthfirstordering[--i])) {
udi = &usedefinfo[block->blockIndex];
if ((succs = block->successors)) {
useVec1C = udi->usevec1C;
bitvectorcopy(useVec1C, usedefinfo[succs->block->blockIndex].usevec18, number_of_Uses);
for (succs = succs->nextLink; succs; succs = succs->nextLink)
bitvectorunion(useVec1C, usedefinfo[succs->block->blockIndex].usevec18, number_of_Uses);
}
useVec1C = udi->usevec1C;
useVec18 = udi->usevec18;
useVec10 = udi->usevec10;
useVec14 = udi->usevec14;
for (j = 0; j < bitvecsize; j++) {
val = *useVec10 | (*useVec1C & ~*useVec14);
if (val != *useVec18) {
*useVec18 = val;
flag = 1;
}
useVec18++;
useVec1C++;
useVec14++;
useVec10++;
}
}
}
}
}
void computeusedefchains(int flag) {
if (flag) {
gather_alias_info();
precomputememoryusedefs();
}
precomputeusedefcounts(flag);
computeusedeflists(flag);
allocateusedefinfo();
computelocalusedefinfo();
computedepthfirstordering();
computeglobalusedefinfo();
computeglobaldefuseinfo();
}