char addAfterData(void *dt,void *dt2,list *lst,char (comp)(void *dt1,void *dt2)) { node *tmpnd=searchDataNode(dt2,lst,comp); if(validateNode(tmpnd,lst)=='1') { addAfterNode(dt,tmpnd,lst); return '0'; } else return '1'; }
/*** Detect possible AddrSet of scalar access and compute access scope ***/ int analyze_scalar_access(dat_inst_t *d_inst, inf_node_t* ib) { int dbg = 0; int pos; int addr; insn_t* insn; loop_t *loop; saddr_p memblk; ts_p memTS; worklist_p tsNode,orgTS, blkNode; if (d_inst->addrExpr.varNum != 0) { printf("\nERR: not scalar access");printDataRef(stdout, d_inst); } addr = d_inst->addrExpr.k; tsNode = NULL; orgTS = NULL; loop = getIbLoop(ib); while (loop!=NULL) { if (dbg) { fprintf(dbgAddr,"\n In loop L%d, lbound %d",loop->id,loop->bound-1); fflush(dbgAddr);} memTS = (ts_p) malloc(sizeof(ts_s)); memTS->loop_id = loop->id; memTS->lw = 0; memTS->up = max(loop->bound-1,0); memTS->flag = 0; memTS->flag |= RENEWABLE; addAfterNode(memTS, &tsNode, &orgTS); //addToWorkList( &(orgTS),memTS); loop = loop->parent; } blkNode = NULL; insn = (insn_t*)(d_inst->insn); memblk = createSAddr(GET_MEM(addr),hexValue(insn->addr), 1, orgTS); addAfterNode(memblk, &blkNode, &(d_inst->addr_set)); return 0; }
void enum_regular_address(dat_inst_t* d_inst, expr_p expr, int flag, int curEq, worklist_p curTSnode, int curAddr) { int dbg = 0; int i; saddr_p smem; ts_p ts; loop_t *lp; int lb; if (curEq < expr->varNum) { ts = curTSnode->data; lp = loops[expr->value[curEq].val]; while (curTSnode) { ts = curTSnode->data; if (ts->loop_id == lp->id) break; else { ts->lw = 0; ts->up = max(lp->bound-1,0); curTSnode = curTSnode->next; } } lb = getLpBound(lp); for (i=0; i<lb; i++) { iterValue[lp->id] = i; ts->lw = i; ts->up = i; enum_regular_address(d_inst, expr, flag, curEq+1, curTSnode->next, curAddr+expr->coef[curEq]*i); } } else {//record address //if (dbg) {fprintf(dbgAddr,"\nGenerated %d",curAddr);} if (curAddr < minAddr) minAddr = curAddr; if (curAddr > maxAddr) maxAddr = curAddr; if (cachedNode(GET_MEM(curAddr))) return; lastNode = findBlkAddr(GET_MEM(curAddr), *enumAddrSet); if (lastNode) { smem = lastNode->data; if (smem->blkAddr == GET_MEM(curAddr)) { mergeTSset(smem->tsList, *enumTSset, -1); } else { goto ADD_ADDR; } } else {//add new node after lastNode ADD_ADDR: smem =createSAddr(GET_MEM(curAddr),getAddrD(d_inst),flag,*enumTSset); addAfterNode(smem, &lastNode, enumAddrSet); } } }
int main() { int i, //this represents an iterator for loop arr[] = {9,8,7,6,25,4,3,23,-11,0}, // the main array n = sizeof(arr)/sizeof(arr[0]); // the length of the array for(i = 0; i < n; ++i) { addToSinglyLinkedList( arr[ i ] ); } displaySinglyLinkedList( head ); int delval; printf("Remove Node = "); scanf("%d", &delval); removeNode( delval ); displaySinglyLinkedList( head ); head = reverse(head); printf("Revese Singly Linked List:\n"); displaySinglyLinkedList( head ); printf("After node; what value = "); int afternode, val; scanf("%d %d", &afternode, &val); addAfterNode(afternode, val); displaySinglyLinkedList( head ); printf("Insert before node; what value = "); int beforenode; scanf("%d %d", &beforenode, &val); addBeforeNode(beforenode, val); displaySinglyLinkedList( head ); sort(); return(0); };
/*** Detect possible AddrSet of unpred. access and compute access scope ***/ int analyze_unpred_access(dat_inst_t *d_inst, inf_node_t* ib) { int dbg = 0; /* A[x] -> assume array A is global array * AddrSet(A) -> obtained from symbol table * Identifying access variable: compute addr.expr, ignoring unknown elem. * Addr. Expression A[x] = A[0] + T*4, how reg. expression derive now * Not necessary correct in all cases, or more aggressive optimization * Work with array index A[x] * Not work with pointer value */ int initAddr = -1, addr; symbol_i *gVar, *var; int i; loop_t *loop; saddr_p memblk,curblk; ts_p memTS; worklist_p tsNode, orgTS, blkNode; insn_t *insn; int foundRange; expr_p exp; //create access scope for all possible address loop = getIbLoop(ib); tsNode = NULL;orgTS = NULL; while (loop!=NULL) { memTS = malloc(sizeof(ts_s)); memTS->loop_id = loop->id; memTS->lw = 0; memTS->up = max(loop->bound-1,0); memTS->flag = 0; addAfterNode(memTS, &tsNode, &orgTS); //addToWorkList( &orgTS,memTS); loop = loop->parent; } curblk = NULL; blkNode = NULL; foundRange = 0; exp = &(d_inst->addrExpr); insn = (insn_t*)(d_inst->insn); initAddr = exp->k; //locate the symbol table segment for (i=0; i<prog.num_vars; i++) { gVar = &(prog.v_info[i]); if (gVar->addr <= initAddr && initAddr < gVar->addr + gVar->size) { foundRange = 1; break; } } if (foundRange) {//unpredictable access, but find global var /*NOTE: stepSizeTable hts only 89 integer, but segment size = 1024*/ /*can set this ts some user constraint, hard code for now*/ if (strcmp(gVar->name,"stepsizeTable")==0) { gVar->size = 89*4; /*a kind of user constraint*/ } if (strcmp(gVar->name,"indexTable")==0) { gVar->size = 16*4; /*a kind of user constraint*/ } //Addr range of global var. too large --> consider unknown if (gVar->size > CACHE_SIZE) goto UNKNOWN_RANGE; if (dbg) { fprintf(dbgAddr,"\n Global var: %s [%x,%x], array sa: %x, size %d", gVar->name, gVar->addr,gVar->addr+gVar->size,initAddr,gVar->size); fflush(dbgAddr); } for (addr = gVar->addr; addr < gVar->addr+gVar->size; addr+=4) { if (curblk && GET_MEM(addr)==curblk->blkAddr) continue; memblk = createSAddr(GET_MEM(addr), hexValue(insn->addr),0,orgTS); addAfterNode(memblk, &blkNode, &(d_inst->addr_set)); curblk = memblk; } } else {//unpredictable access, unknown address range UNKNOWN_RANGE: if (dbg) { fprintf(dbgAddr,"\nUnknown addr range");fflush(dbgAddr); } memblk = createSAddr(UNKNOWN_ADDR,hexValue(insn->addr),0,orgTS); addAfterNode(memblk,&blkNode,&(d_inst->addr_set)); return 0; } return 0; }
/* analyze data reference with regular access pattern */ int analyze_regular_access(dat_inst_t *d_inst, inf_node_t *ib) { int dbg = 0; int i,j,min, tmp; int lpId, addr, flag; insn_t *insn; expr_p exp; reg_t tmpReg; ts_p ts; loop_t *lp; int lpIter[5]; worklist_p tsList, tsNode, addrSet; initReg(&tmpReg); exp = &(d_inst->addrExpr); //check if it is really regular access (no unknown parameter) for (i=0; i<exp->varNum; i++) { if (exp->value[i].t==VALUE_PARA || exp->value[i].t==VALUE_UNDEF){ analyze_unpred_access(d_inst,ib);return;} } //Sort BIV loopID in ascending order for (i=0; i<exp->varNum; i++) { min = i; for (j=i+1; j<exp->varNum; j++) { if (exp->value[j].val <= exp->value[min].val) min = j; #if 0 if (exp->coef[i] = 0 - exp->coef[j]) { exp->value[i].val = max(exp->value[i].val,exp->value[j].val); exp->coef[i] = absInt(exp->coef[i]); exp->coef[j] = 0; exp->value[j].val = 999; } #endif } if (i==min) continue;//exp->value[i] is already min if (exp->value[min].val == exp->value[i].val) { //min & i are two biv of the same loop --> merge exp->coef[i] += exp->coef[min]; exp->value[min].val = 999;exp->coef[min] =0; } else {//swap min & i cpyReg(&tmpReg, exp->value[i]); cpyReg(&(exp->value[i]), exp->value[min]); cpyReg(&(exp->value[min]), tmpReg); tmp = exp->coef[i]; exp->coef[i]=exp->coef[min]; exp->coef[min]=tmp; } } //Clear up merged register while (exp->varNum>0) { i = exp->varNum-1; if (exp->value[i].val == 999) exp->varNum--; else break; } /*To deal with j = i*/ if (dbg) {fprintf(dbgAddr,"\nSorted expr: ");printExpr(dbgAddr,exp);} //create the temporal scope for memory blocks of d_inst tsList = NULL; tsNode = NULL; lp = loops[exp->value[0].val];//inner most loop i = 0; while (lp!=NULL) { if (0) fprintf(dbgAddr,"\n In loop L%d, lbound %d",lp->id,lp->bound-1); ts = (ts_p) malloc(sizeof(ts_s)); if (lp->id == exp->value[i].val) { ts->loop_id = lp->id; ts->lw = 0; ts->up = 0; ts->flag = 0;i++; } else { ts->loop_id = lp->id; ts->lw = 0; ts->up = lp->bound; ts->flag = 0; } addAfterNode(ts, &tsNode, &tsList); //addToWorkList( &(orgTS),memTS); lp = lp->parent; } if (dbg) {fprintf(dbgAddr,"\nTemporal scope: ");printTSset(dbgAddr,tsList);} //enumerating possible memory blocks addrSet = NULL; lastNode = NULL; enumTSset = &tsList; enumAddrSet = &addrSet; flag = 0; for (i=0; i<num_tcfg_loops; i++) iterValue[i]=-1; minAddr = exp->k; maxAddr = 0; enum_regular_address(d_inst, exp, flag, 0, tsList, exp->k); d_inst->addr_set = addrSet; if (dbg) { fprintf(dbgAddr,"\nGenerated range: [%x, %x], %d elems", minAddr, maxAddr, GET_MEM(maxAddr-minAddr)); //printSAddrSet(dbgAddr,d_inst->addr_set,1); } }