void Builder::processLBlockSet(WorkSpace *fw, otawa::ccg::LBlockSet *lbset) { ASSERT(fw); ASSERT(lbset); const hard::Cache *cache = hard::CACHE_CONFIGURATION(fw)->instCache(); // Create the CCG Collection *ccgs = Graph::GRAPHS(fw); if(!ccgs) { ccgs = new Collection(cache->rowCount()); fw->addProp(new DeletableProperty<Collection *>(Graph::GRAPHS, ccgs)); } Graph *ccg = new Graph; ccgs->ccgs[lbset->line()] = ccg; // Initialization for(LBlockSet::Iterator lblock(*lbset); lblock; lblock++) { Node *node = new Node(lblock); ccg->add(node); Graph::NODE(lblock) = node; } // Run the DFA Problem prob(lbset, lbset->count(), cache, fw); const CFGCollection *coll = INVOLVED_CFGS(fw); dfa::XCFGVisitor<Problem> visitor(*coll, prob); dfa::XIterativeDFA<dfa::XCFGVisitor<Problem> > engine(visitor); engine.process(); // Add the annotations from the DFA result for (CFGCollection::Iterator cfg(coll); cfg; cfg++) { for (CFG::BBIterator block(*cfg); block; block++) { dfa::XCFGVisitor<Problem>::key_t pair(*cfg, *block); dfa::BitSet *bitset = engine.in(pair); block->addProp(new DeletableProperty<dfa::BitSet *>(IN, new dfa::BitSet(*bitset))); } } // Detecting the non conflict state of each lblock BasicBlock *BB; LBlock *line; int length = lbset->count(); for(LBlockSet::Iterator lbloc(*lbset); lbloc; lbloc++) if(lbloc->id() != 0 && lbloc->id() != length - 1) { BB = lbloc->bb(); dfa::BitSet *inid = IN(BB); for(dfa::BitSet::Iterator bit(*inid); bit; bit++) line = lbset->lblock(*bit); if(cache->block(line->address()) == cache->block(lbloc->address()) && BB != line->bb()) NON_CONFLICT(lbloc) = true; } // Building the ccg edges using DFA length = lbset->count(); address_t adinst; LBlock *aux; for (CFGCollection::Iterator cfg(coll); cfg; cfg++) { for (CFG::BBIterator bb(*cfg); bb; bb++) { if ((cfg != ENTRY_CFG(fw)) || (!bb->isEntry() && !bb->isExit())) { dfa::BitSet *info = IN(bb); ASSERT(info); bool test = false; bool visit; for(BasicBlock::InstIter inst(bb); inst; inst++) { visit = false; adinst = inst->address(); for (LBlockSet::Iterator lbloc(*lbset); lbloc; lbloc++){ address_t address = lbloc->address(); // the first lblock in the BB it's a conflict if(adinst == address && !test && bb == lbloc->bb()) { for (int i = 0; i< length; i++) if (info->contains(i)) { LBlock *lblock = lbset->lblock(i); Node *node = Graph::NODE(lblock); new Edge (node, Graph::NODE(lbloc)); } aux = lbloc; test = true; visit = true; break; } if(adinst == address && !visit && bb == lbloc->bb()) { new Edge(Graph::NODE(aux), Graph::NODE(lbloc)); aux = lbloc; break; } } } } } } // build edge to LBlock end BasicBlock *exit = ENTRY_CFG(fw)->exit(); LBlock *end = lbset->lblock(length-1); dfa::BitSet *info = IN(exit); for (int i = 0; i< length; i++) if (info->contains(i)) { LBlock *ccgnode1 = lbset->lblock(i); new Edge(Graph::NODE(ccgnode1), Graph::NODE(end)); } // Build edge from 'S' till 'end' LBlock *s = lbset->lblock(0); new Edge(Graph::NODE(s), Graph::NODE(end)); // Cleanup the DFA annotations for (CFGCollection::Iterator cfg(coll); cfg; cfg++) for (CFG::BBIterator block(cfg); block; block++) block->removeProp(&IN); }
void CacheList::load_cache_prof_info(char *filename, level *lev) { int j; for (j=0; j<this->total; j++) if (list[j].last_access>=0) // reset all loaded cache items to 0, all non-load to -1 list[j].last_access=0; preload_cache(lev); // preliminary guesses at stuff to load int load_fail=1; bFILE *fp=open_file(filename,"rb"); if (!fp->open_failure()) { spec_directory sd(fp); spec_entry *se=sd.find("cache profile info"); // see if the cache profile info is in the file if (se) { fp->seek(se->offset,0); char name[255]; int tnames=0; int *fnum_remap; // remaps old filenumbers into current ones tnames=fp->read_uint16(); if (tnames) /// make sure there isn't bad info in the file { fnum_remap=(int *)malloc(sizeof(int)*tnames); int i; for (i=0; i<tnames; i++) { fp->read(name,fp->read_uint8()); fnum_remap[i]=-1; // initialize the map to no-map int j; for (j=0; j<crc_manager.total_filenames(); j++) if (!strcmp(crc_manager.get_filename(j),name)) fnum_remap[i]=j; } int tsaved = fp->read_uint32(); int *priority=(int *)malloc(tsaved*sizeof(int)); memset(priority,0xff,tsaved*sizeof(int)); // initialize to -1 int tmatches=0; sorted_id_list=(int *)malloc(sizeof(int)*total); for (j=0; j<total; j++) sorted_id_list[j]=j; qsort(sorted_id_list,total,sizeof(int),s_offset_compare); for (i=0; i<tsaved; i++) { fp->read_uint8(); // read type short file_num=fp->read_uint16(); if (file_num>=tnames) // bad data? file_num=-1; else file_num=fnum_remap[file_num]; uint32_t offset=fp->read_uint32(); // search for a match j=search(sorted_id_list,file_num,offset); if (j!=-1) { if (list[j].last_access<0) // if not loaded list[j].last_access=-2; // mark as needing loading else list[j].last_access=2; // mark as loaded and needing to stay that way priority[i]=j; tmatches++; } } free(sorted_id_list); // was used for searching, no longer needed for (j=0; j<total; j++) if (list[j].last_access==0) unmalloc(list+j); // free any cache entries that are not accessed at all in the level ful=0; int tcached=0; for (j=0; j<total; j++) // now load all of the objects until full { // stat_man->update(j*70/total+25); if (list[j].file_number>=0 && list[j].last_access==-2) { list[j].last_access=-1; if (!ful) { switch (list[j].type) { case SPEC_BACKTILE : backt(j); break; case SPEC_FORETILE : foret(j); break; case SPEC_CHARACTER : case SPEC_CHARACTER2 : fig(j); break; case SPEC_IMAGE : img(j); break; case SPEC_PARTICLE : part(j); break; case SPEC_EXTERN_SFX : sfx(j); break; case SPEC_EXTERNAL_LCACHE : lblock(j); break; case SPEC_PALETTE : ctint(j); break; } tcached++; } } } load_fail=0; // if (full()) // dprintf("Cache filled while loading\n"); if (tsaved>tmatches) tmatches=tsaved+1; last_access=tmatches+1; for (i=0; i<tsaved; i++) // reorder the last access of each cache to reflect prioirties { if (priority[i]!=-1) { if (list[priority[i]].last_access!=-1) // make sure this wasn't the last item list[priority[i]].last_access=tmatches--; } } free(priority); free(fnum_remap); } } } if (load_fail) // no cache file, go solely on above gueses { int j; for (j=0; j<total; j++) // now load all of the objects until full, don't free old stuff { // stat_man->update(j*70/total+25); if (list[j].file_number>=0 && list[j].last_access==-2) { list[j].last_access=-1; if (!ful) { switch (list[j].type) { case SPEC_BACKTILE : backt(j); break; case SPEC_FORETILE : foret(j); break; case SPEC_CHARACTER : case SPEC_CHARACTER2 : fig(j); break; case SPEC_IMAGE : img(j); break; case SPEC_PARTICLE : part(j); break; case SPEC_EXTERN_SFX : sfx(j); break; case SPEC_EXTERNAL_LCACHE : lblock(j); break; case SPEC_PALETTE : ctint(j); break; } } } } if (full()) dprintf("Cache filled while loading\n"); } delete fp; }
void EdgeCAT2Builder::processLBlockSet(otawa::CFG *cfg, LBlockSet *lbset, const hard::Cache *cache) { unsigned int line = lbset->line(); /*static double moypr = 0; static double moy = 0;*/ /* Use the results to set the categorization */ for (LBlockSet::Iterator lblock(*lbset); lblock; lblock++) { if ((lblock->id() == 0) || (lblock->id() == lbset->count() - 1)) continue; Vector<MUSTProblem::Domain*> &mustVec = *CACHE_EDGE_ACS_MUST(lblock); Vector<PERSProblem::Domain*> &persVec = *CACHE_EDGE_ACS_PERS(lblock); CATEGORY_EDGE(lblock) = new Vector<category_t>(); CATEGORY_EDGE_HEADER(lblock) = new Vector<BasicBlock*>(); BasicBlock::InIterator inedge(lblock->bb()); for (int i = 0; i < mustVec.length(); i++) { MUSTProblem::Domain *must = mustVec[i]; PERSProblem::Domain *pers = NULL; if (firstmiss_level != FML_NONE) { pers = persVec[i]; /* enter/leave context if in-edge enters or exits loops */ if (LOOP_EXIT_EDGE(inedge)) { /* find loop header of inner-most exited loop */ BasicBlock *header = inedge->source(); if (!LOOP_HEADER(header)) header = ENCLOSING_LOOP_HEADER(header); ASSERT(header && LOOP_HEADER(header)); /* now leave contexts for each loop between header and LOOP_EXIT_EDGE(inedge) (included) */ pers->leaveContext(); while (header != LOOP_EXIT_EDGE(inedge)) { pers->leaveContext(); header = ENCLOSING_LOOP_HEADER(header); ASSERT(header); } } if (LOOP_HEADER(lblock->bb()) && !BACK_EDGE(inedge)) { /* an entry edge may not enter more than one loop */ pers->enterContext(); } } BasicBlock *header = NULL; category_t cat = NOT_CLASSIFIED; BasicBlock *cat_header = NULL; if (must->contains(lblock->cacheblock())) { cat = ALWAYS_HIT; } else if (firstmiss_level != FML_NONE) { if (Dominance::isLoopHeader(lblock->bb())) header = lblock->bb(); else header = ENCLOSING_LOOP_HEADER(lblock->bb()); int bound; bool perfect_firstmiss = true; bound = 0; if ((pers->length() > 1) && (firstmiss_level == FML_INNER)) bound = pers->length() - 1; cat_header = NULL; for (int k = pers->length() - 1 ; (k >= bound) && (header != NULL); k--) { if (pers->isPersistent(lblock->cacheblock(), k)) { cat = FIRST_MISS; cat_header = header; } else perfect_firstmiss = false; header = ENCLOSING_LOOP_HEADER(header); } if ((firstmiss_level == FML_OUTER) && (perfect_firstmiss == false)) cat = ALWAYS_MISS; } /* of category condition test */ CATEGORY_EDGE(lblock)->add(cat); CATEGORY_EDGE_HEADER(lblock)->add(cat_header); inedge++; } } }