static gboolean _is_store_iter_has_child(GtkTreeModel *tree_model, GtkTreeIter *iter) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); g_return_val_if_fail(iter != NULL, FALSE); self = IS_STORE(tree_model); priv = self->priv; g_return_val_if_fail(iter->stamp == priv->stamp, FALSE); g_assert(iter->user_data); /* end iter is invalid and has no entry associated with it */ if (!g_sequence_iter_is_end((GSequenceIter *)iter->user_data)) { entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)iter->user_data); ret = (g_sequence_get_length(entry->entries) > 0); } return ret; }
static gboolean _is_store_iter_parent(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); g_return_val_if_fail(child != NULL, FALSE); self = IS_STORE(tree_model); priv = self->priv; g_return_val_if_fail(child->stamp == priv->stamp, FALSE); g_assert(child->user_data); entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)child->user_data); if (entry->parent) { iter->stamp = priv->stamp; iter->user_data = entry->parent; ret = TRUE; } return ret; }
static gint _is_store_iter_n_children(GtkTreeModel *tree_model, GtkTreeIter *iter) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry; gint n; g_return_val_if_fail(IS_IS_STORE(tree_model), 0); self = IS_STORE(tree_model); priv = self->priv; if (!iter) { n = g_sequence_get_length(priv->entries); goto out; } g_return_val_if_fail(iter->stamp == priv->stamp, 0); g_assert(iter->user_data); entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)iter->user_data); n = g_sequence_get_length(entry->entries); out: return n; }
static GtkTreePath *_is_store_get_path(GtkTreeModel *tree_model, GtkTreeIter *iter) { IsStore *self; IsStorePrivate *priv; GtkTreePath *path; GSequenceIter *entry_iter; g_return_val_if_fail(IS_IS_STORE(tree_model), NULL); g_return_val_if_fail(iter != NULL, NULL); self = IS_STORE(tree_model); priv = self->priv; g_return_val_if_fail(iter->stamp == priv->stamp, NULL); g_assert(iter->user_data); path = gtk_tree_path_new(); entry_iter = (GSequenceIter *)iter->user_data; while (entry_iter != NULL) { IsStoreEntry *entry; gtk_tree_path_prepend_index(path, g_sequence_iter_get_position(entry_iter)); entry = (IsStoreEntry *)g_sequence_get(entry_iter); entry_iter = entry->parent; } return path; }
static void _is_store_get_value(GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, GValue *value) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry = NULL; g_return_if_fail(IS_IS_STORE(tree_model)); g_return_if_fail(iter != NULL); self = IS_STORE(tree_model); priv = self->priv; g_return_if_fail(iter->stamp == priv->stamp); g_assert(iter->user_data); g_value_init(value, column_types[column]); entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)iter->user_data); g_assert(entry); switch (column) { case IS_STORE_COL_NAME: g_value_set_string(value, entry->name); break; case IS_STORE_COL_LABEL: g_value_set_string(value, (entry->sensor ? is_sensor_get_label(entry->sensor) : NULL)); break; case IS_STORE_COL_IS_SENSOR: g_value_set_boolean(value, (entry->sensor != NULL)); break; case IS_STORE_COL_SENSOR: g_value_set_object(value, entry->sensor); break; case IS_STORE_COL_ENABLED: g_value_set_boolean(value, entry->enabled); break; case IS_STORE_COL_ICON: g_value_set_string(value, (entry->sensor ? is_sensor_get_icon(entry->sensor) : NULL)); break; default: g_assert_not_reached(); } }
/* * Description: * Moves an instruction from the execution stage to common data bus (if possible) * Inputs: * current_cycle: the cycle we are at * Returns: * None */ void execute_To_CDB(int current_cycle) { /* ECE552: YOUR CODE GOES HERE */ // Remove all finished stores. { int i, j; for (i = 0; i < FU_INT_SIZE; i++) { if (fuINT[i] != NULL && IS_STORE(fuINT[i]->op) && current_cycle >= FU_INT_LATENCY + fuINT[i]->tom_execute_cycle) { remove_insn(fuINT[i], reservINT, RESERV_INT_SIZE); fuINT[i] = NULL; } } } // Find oldest instruction that is ready to be broadcasted on the CDB. { int i; instruction_t* insn = NULL; for (i = 0; i < FU_INT_SIZE; i++) { if (fuINT[i] != NULL && current_cycle >= FU_INT_LATENCY + fuINT[i]->tom_execute_cycle && (insn == NULL || fuINT[i]->index < insn->index)) { insn = fuINT[i]; } } for (i = 0; i < FU_FP_SIZE; i++) { if (fuFP[i] != NULL && current_cycle >= FU_FP_LATENCY + fuFP[i]->tom_execute_cycle && (insn == NULL || fuFP[i]->index < insn->index)) { insn = fuFP[i]; } } // If instruction is found, remove it from RSs and FUs. // Then, set cycle it enters CDB and put it on the CDB. if (insn != NULL) { remove_insn(insn, reservINT, RESERV_INT_SIZE); remove_insn(insn, reservFP, RESERV_FP_SIZE); remove_insn(insn, fuINT, FU_INT_SIZE); remove_insn(insn, fuFP, FU_FP_SIZE); insn->tom_cdb_cycle = current_cycle; commonDataBus = insn; } } }
gboolean _is_store_get_iter(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) { IsStore *self; IsStorePrivate *priv; gint *indices, depth; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); g_return_val_if_fail(path != NULL, FALSE); self = IS_STORE(tree_model); priv = self->priv; indices = gtk_tree_path_get_indices(path); depth = gtk_tree_path_get_depth(path); ret = get_iter_for_indices(self, indices, depth, 0, priv->entries, iter); return ret; }
static gboolean _is_store_iter_nth_child(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent, gint n) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); self = IS_STORE(tree_model); priv = self->priv; if (!parent && (n >= 0 && n < g_sequence_get_length(priv->entries))) { iter->stamp = priv->stamp; iter->user_data = g_sequence_get_iter_at_pos(priv->entries, n); ret = TRUE; goto out; } g_return_val_if_fail(parent->stamp == priv->stamp, FALSE); g_assert(parent->user_data); entry = (IsStoreEntry *) g_sequence_get((GSequenceIter *)parent->user_data); if (entry->entries) { iter->stamp = priv->stamp; iter->user_data = g_sequence_get_iter_at_pos(entry->entries, n); ret = TRUE; } out: return ret; }
static gboolean _is_store_iter_children(GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) { IsStore *self; IsStorePrivate *priv; IsStoreEntry *entry; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); self = IS_STORE(tree_model); priv = self->priv; /* special case - return first node */ if (!parent) { GSequenceIter *seq_iter = g_sequence_get_begin_iter(priv->entries); if (seq_iter) { iter->stamp = priv->stamp; iter->user_data = seq_iter; ret = TRUE; } goto out; } g_return_val_if_fail(parent->stamp == priv->stamp, FALSE); g_assert(parent->user_data); entry = (IsStoreEntry *)g_sequence_get(parent->user_data); if (!entry->sensor) { iter->stamp = priv->stamp; iter->user_data = g_sequence_get_begin_iter(entry->entries); ret = TRUE; } out: return ret; }
static gboolean _is_store_iter_next(GtkTreeModel *tree_model, GtkTreeIter *iter) { IsStore *self; IsStorePrivate *priv; GSequenceIter *next; gboolean ret = FALSE; g_return_val_if_fail(IS_IS_STORE(tree_model), FALSE); g_return_val_if_fail(iter != NULL, FALSE); self = IS_STORE(tree_model); priv = self->priv; g_return_val_if_fail(iter->stamp == priv->stamp, FALSE); g_assert(iter->user_data); next = g_sequence_iter_next((GSequenceIter *)iter->user_data); if (!g_sequence_iter_is_end(next)) { iter->user_data = next; ret = TRUE; } return ret; }
int DeadDefElimination() /* * it will delete all the useless definitions which are dead... * will be moved to vars.c later */ { int i, k, n; int nchanges=0; INSTQ *ip, *ip0, *ipn; BBLOCK *bp; INT_BVI iv, ivds, ivvars; ILIST **ils; short *vars, *deadvars; extern INT_BVI FKO_BVTMP; extern BBLOCK *bbbase; if (!CFUSETU2D) { CalcInsOuts(bbbase); CalcAllDeadVariables(); } #if 0 fprintf(stdout, "LIL before dead code\n"); PrintInst(stdout, bbbase); fflush(stdout); #endif if (!FKO_BVTMP) FKO_BVTMP = NewBitVec(32); iv = FKO_BVTMP; ivds = NewBitVec(128); assert(ivds); ivvars = NewBitVec(128); assert(ivds); for (bp = bbbase; bp; bp=bp->down) { /*fprintf(stderr, "----blk = %d\n", bp->bnum);*/ /* * findout all the variables we need to consider for this block first */ SetVecAll(ivvars, 0); for (ip=bp->ainst1; ip; ip=ip->next) { ivvars = BitVecComb(ivvars, ivvars, ip->set, '|'); ivvars = BitVecComb(ivvars, ivvars, ip->use, '|'); } ivvars = FilterOutRegs(ivvars); vars = BitVec2Array(ivvars, 1-TNREG); #if 0 fprintf(stderr, "Print vars: "); for (i=1; i <= vars[0]; i++) fprintf(stderr, "%s ", STname[vars[i]-1]); fprintf(stderr, "\n"); #endif /* * setup an ILIST to keep track of ipset */ n = vars[0]; if (!n) { free(vars); continue; } ils = malloc(sizeof(ILIST*)*n); assert(ils); for (i=0; i < n; i++) ils[i] = NULL; /* * check all inst for dead variable inside this single block */ SetVecAll(ivds, 0); for (ip=bp->ainst1; ip; ip=ip->next) { /* * if one of the variale is set using this inst */ if (ip->set && BitVecCheckComb(ivvars, ip->set, '&') ) { /* * check whether the var is already set and not dead, it will be a * candidate for dead var then */ iv = BitVecComb(iv, ivds, ip->set, '&'); iv = FilterOutRegs(iv); if (AnyBitsSet(iv)) { k = FindInShortList(vars[0], vars+1, GetSetBitX(iv, 1)-TNREG); assert(k); /*fprintf(stderr, "***dead var = %s\n", STname[vars[k]-1]);*/ ip0 = FindFirstLILforHIL(ils[k-1]->inst); ils[k-1]->inst = NULL; /* * delete the inst seqment which previously set the var */ if (ip0) { nchanges++; while (ip0) { /*PrintThisInst(stderr, 0, ip0);*/ if (IS_STORE(ip0->inst[0])) { DelInst(ip0); break; } ip0 = DelInst(ip0); } } } /* * mark the var as being set in ivds and update the ilist to point * the inst */ ivds = BitVecComb(ivds, ivds, ip->set, '|'); #if 0 if (ip->inst[1] > 0 && !NonLocalDeref(ip->inst[1])) { i = FindInShortList(vars[0], vars+1, STpts2[ip->inst[1]-1] ); assert(i); assert(i<=n); if (ils[i-1]) ils[i-1]->inst = ip; else ils[i-1] = NewIlist(ip, NULL); } #else iv = BitVecComb(iv, ivvars, ip->set, '&'); k = FindInShortList(vars[0], vars+1, GetSetBitX(iv, 1)-TNREG); assert(k); if (ils[k-1]) ils[k-1]->inst = ip; else ils[k-1] = NewIlist(ip, NULL); #endif } /* * check for varibale being dead by its last-use in this inst * remove it form ivds since it only keep track the live variable with * active value (being set by an inst before) */ if (ip->deads && BitVecCheckComb(ivvars, ip->deads, '&')) { ivds = BitVecComb(ivds, ivds, ip->deads, '-'); } } /* * There may be an active value (has a set) but it's dead at the end of the * block and it doesn't have any last-use. That means, it doesn't have any * usage at all, there would be a last-use case otherwise. So, it's safe to * delete the set of the variable. */ iv = BitVecComb(iv, ivds, bp->outs, '-'); iv = FilterOutRegs(iv); if (AnyBitsSet(iv)) { k = FindInShortList(vars[0], vars+1, GetSetBitX(iv, 1)-TNREG); assert(k); /*fprintf(stderr, "***dead var = %s\n", STname[vars[k]-1]);*/ ip0 = FindFirstLILforHIL(ils[k-1]->inst); if (ip0) { nchanges++; while (ip0) { /*PrintThisInst(stderr, 0, ip0);*/ if (IS_STORE(ip0->inst[0])) { DelInst(ip0); break; } ip0 = DelInst(ip0); } } } /* * delete all temporaries for this block */ if (vars) free(vars); if (ils) { for (i=0; i < n; i++) { if (ils[i]) free(ils[i]); } free(ils); } } /* * delete all tempories for this function */ KillBitVec(ivds); KillBitVec(ivvars); if (nchanges) CFUSETU2D = INDEADU2D = 0; return(nchanges); }
int MinBlkPtrUpdates(BBLOCK *blk, struct ptrinfo *pi0) { int k, inc; INSTQ *ip, *ip0, *ipn; short *sp; short reg, dt; struct ptrinfo *pi; ILIST *il; /*fprintf(stderr, "----------blk=%d\n", blk->bnum);*/ for (pi=pi0; pi; pi=pi->next) { /*fprintf(stderr, "%s : %d\n", STname[pi->ptr-1], pi->flag);*/ /* * assumption: ilist in ptrinfo is correctly populated and point sequential * from up to down */ #if 0 assert(pi->ilist); ip0 = pi->ilist->inst; assert(ip0->inst[2] == ip0->prev->inst[2]); assert(IS_CONST(STflag[ip0->prev->inst[3]-1])); pi->upst = SToff[ip0->prev->inst[3]-1].i; fprintf(stderr, "init inc=%d\n", pi->upst); inc = pi->upst; #endif assert(pi->ilist); reg = -(pi->ilist->inst->inst[2]); inc = 0; for (il=pi->ilist; il; il=il->next) { ip0 = il->inst; assert(ip0->inst[2] == ip0->prev->inst[2]); assert(IS_CONST(STflag[ip0->prev->inst[3]-1])); inc += SToff[ip0->prev->inst[3]-1].i; if (il->next) ipn = il->next->inst; ipn = NULL; /* * we assume only const inc of ptr */ for (ip = ip0; ip != ipn; ip=ip->next) { dt = 0; if (IS_LOAD(ip->inst[0]) && NonLocalDeref(ip->inst[2])) dt = ip->inst[2]; else if (IS_STORE(ip->inst[0]) && NonLocalDeref(ip->inst[1])) dt = ip->inst[1]; if (dt && STpts2[dt-1] == pi->ptr) { /* * NOTE: since we are considering only const inc now, we won't have * any load of index. this assertion is to protect this assumption */ assert( (ip->prev->inst[0] == LD) && (STpts2[ip->prev->inst[2]-1])==pi->ptr ); k = -ip->prev->inst[1]; sp = UpdateDeref(ip, k, inc); if (sp) { for (k=0; k < 4; k++) ip->inst[k] = sp[k]; } else { #if 1 fprintf(stderr, "DT: <%d, %d, %d, %d>\n", SToff[dt-1].sa[0], SToff[dt-1].sa[1], SToff[dt-1].sa[2], SToff[dt-1].sa[3] ); assert(0); #else InsNewInst(blk, NULL, ip, ADD, -k, -k, STiconstlookup(inc)); #endif } } #if 0 if (IS_LOAD(ip->inst[0]) && NonLocalDeref(ip->inst[2])) { k = STpts2[ip->inst[2]-1]; if (k != pi->ptr) continue; /* * since it's const inc, there is no load of index.. so, ip->prev * should be load of ptr */ assert( (ip->prev->inst[0] == LD) && (k==STpts2[ip->prev->inst[2]-1]) ); k = -ip->prev->inst[1]; sp = UpdateDeref(ip, k, inc); if (sp) { for (k=0; k < 4; k++) ip->inst[k] = sp[k]; } else { #if 1 fprintf(stderr, "DT: <%d, %d, %d, %d>\n", SToff[ip->inst[2]-1].sa[0], SToff[ip->inst[2]-1].sa[1], SToff[ip->inst[2]-1].sa[2], SToff[ip->inst[2]-1].sa[3] ); assert(0); #else InsNewInst(blk, NULL, ip, ADD, -k, -k, STiconstlookup(inc)); #endif } } else if (IS_STORE(ip->inst[0]) && NonLocalDeref(ip->inst[1])) { k = STpts2[ip->inst[1]-1]; if (k != pi->ptr) continue; assert( (ip->prev->inst[0] == LD) && (k==STpts2[ip->prev->inst[2]-1]) ); k = -ip->prev->inst[1]; sp = UpdateDeref(ip, k, inc); if (sp) { for (k=0; k < 4; k++) ip->inst[k] = sp[k]; } else { #if 1 fprintf(stderr, "DT: <%d, %d, %d, %d>\n", SToff[ip->inst[1]-1].sa[0], SToff[ip->inst[1]-1].sa[1], SToff[ip->inst[1]-1].sa[2], SToff[ip->inst[1]-1].sa[3] ); assert(0); #else InsNewInst(blk, NULL, ip, ADD, -k, -k, STiconstlookup(inc)); #endif } } #endif } /* * delete pointer update... */ ip = ip0->prev->prev; ip = DelInst(ip); ip = DelInst(ip); ip = DelInst(ip); il->inst = NULL; } /* * add pointer update at the end of the block before branch unless we have * loop cmpflags */ ip = FindCompilerFlag(blk, CF_LOOP_PTRUPDATE ); if (!ip) { ip = FindCompilerFlag(blk, CF_LOOP_UPDATE); if (!ip) { ip = FindCompilerFlag(blk, CF_LOOP_INIT); if (!ip) { ip = blk->instN; if (IS_BRANCH(ip->inst[0])) ip = ip->prev; while (ip && !IS_STORE(ip->inst[0]) && !IS_BRANCH(ip->inst[0]) && ip->inst[0] != LABEL) { ip = ip->prev; } ip = ip->next; } } else { ip = InsNewInst(blk, NULL, ip, CMPFLAG, CF_LOOP_PTRUPDATE, 0, 0 ); ip = ip->next; } } else { ip = ip->next; } /* * inst shouldn't have any access of ptr after this point * FIXME: do we need to place a checking in case CMPFLAG got displaced??? */ InsNewInst(blk, NULL, ip, LD, -reg, SToff[pi->ptr-1].sa[2], 0 ); if (pi->flag & PTRF_INC) InsNewInst(blk, NULL, ip, ADD, -reg, -reg, STiconstlookup(inc)); else assert(0); InsNewInst(blk, NULL, ip, ST, SToff[pi->ptr-1].sa[2], -reg, 0 ); INUSETU2D = CFUSETU2D = INDEADU2D = 0; } }