void CombinedPass::do_file_set_block( FileSetBlock* file_set_block ) { list<SymbolTable*> file_scope_tables; for (Iter<FileBlock*> iter = file_set_block->get_file_block_iterator(); iter.is_valid(); iter.next()) { file_scope_tables.push_back(iter.current()->get_symbol_table()); } file_scope_tables.push_back(file_set_block->get_file_set_symbol_table()); CollisionAvoider walker(get_suif_env(), file_set_block->get_external_symbol_table(), &file_scope_tables, (file_set_block->get_file_block(0))-> get_source_file_name(), true); file_set_block->walk(walker); }
/* return true if the symbol has a name crash with another symbol in * its parent (a symbol table). * This implementation just consider name crashes and ignore the symbol * type. */ static bool is_var_name_crashd_locally(const Symbol* symbol) { LString sname = symbol->get_name(); if (sname == emptyLString) return false; SymbolTable* symtab = to<SymbolTable>(symbol->get_parent()); if (!is_kind_of<VariableSymbol>(symbol)) return false; for (Iter<SymbolTableObject*> iter = symtab->get_symbol_table_object_iterator(); iter.is_valid(); iter.next()) { if (symbol == const_cast<const SymbolTableObject*>(iter.current())) continue; if (!is_kind_of<VariableSymbol>(iter.current())) continue; if (iter.current()->get_name() == sname) { return true; } } return false; }
void InstanceFieldsLayoutPass::mangle_fields( ClassType* ctype ) { BasicSymbolTable* symtab = ctype->get_group_symbol_table(); Iter<SymbolTableObject*> iter = symtab->get_symbol_table_object_iterator(); while( iter.is_valid() ) { InstanceFieldSymbol* fsym = to<InstanceFieldSymbol>( iter.current() ); if ( _verbose ) { // cout << fsym->get_name().c_str() << " -> " // << mangled_name(fsym).c_str() << endl; } symtab->change_name( fsym, mangled_name(fsym) ); iter.next(); } }
void form_worklist(Statement *s){ if(!s) return; if(is_a<IfStatement>(s)){ form_worklist((to<IfStatement>(s))->get_then_part()); form_worklist((to<IfStatement>(s))->get_else_part()); worklist->push_back(to<IfStatement>(s)); }else if(is_a<CForStatement>(s)) form_worklist((to<CForStatement>(s))->get_body()); else if(is_a<WhileStatement>(s)) form_worklist((to<WhileStatement>(s))->get_body()); else if(is_a<ScopeStatement>(s)) form_worklist((to<ScopeStatement>(s))->get_body()); else if(is_a<StatementList>(s)) for(Iter<Statement*> iter = (to<StatementList>(s))->get_statement_iterator(); iter.is_valid(); iter.next()) form_worklist(iter.current()); }
void M2c::process_sym_table(SymTable *st) { bool st_is_private = is_private(st); Iter<SymbolTableObject*> iter = st->get_symbol_table_object_iterator(); for (/* iter */; iter.is_valid(); iter.next()) { SymbolTableObject *the_sto = iter.current(); if (is_kind_of<VariableSymbol>(the_sto)) { if (is_kind_of<ParameterSymbol>(the_sto)) continue; // don't shadow an arg! VarSym *v = to<VariableSymbol>(the_sto); if (!is_global(st)) { printer->print_var_def(v, false); } else if (v->get_definition() != NULL) { postponed_vars.push_back(v); printer->print_var_def(v, true); } else { claim(is_external(v)); fprintf(out, "extern "); printer->print_sym_decl(v); fprintf(out, ";\n"); } } else if (is_kind_of<ProcedureSymbol>(the_sto)) { if (st_is_private) fputs("static ", out); printer->print_proc_decl(to<ProcedureSymbol>(the_sto)); } else if (is_kind_of<Type>(the_sto)) { if (is_kind_of<EnumeratedType>(the_sto) || (is_kind_of<GroupType>(the_sto) && to<GroupType>(the_sto)->get_is_complete())) { printer->print_type(to<Type>(the_sto)); fprintf(out, ";\n"); } } } }
void CopyPropagationPass2::RemoveFromStatementList(StatementList* parent, Statement* child) { assert(parent != NULL) ; assert(child != NULL) ; // Find the position of statement and remove it int pos = 0 ; Iter<Statement*> statementIter = parent->get_statement_iterator() ; while (statementIter.is_valid()) { if (statementIter.current() == child) { break ; } statementIter.next() ; ++pos ; } assert(parent->get_statement(pos) == child) ; parent->remove_statement(pos) ; }
void Summarize::initialize() { DefinitionBlock *db = the_file_block->get_definition_block(); max_event_id = 0; for (Iter<ProcedureDefinition*> iter = db-> get_procedure_definition_iterator(); iter.is_valid(); iter.next()) { OptUnit *unit = iter.current(); claim(is_kind_of<Cfg>(get_body(unit)), "Body is not in CFG form"); Cfg *unit_cfg = static_cast<Cfg*>(get_body(unit)); debug(5, "Procedure %s", get_name(unit).chars()); if_debug(5) fprint(stdout, unit_cfg, true, true); // layout and code for (int i = 0; i < nodes_size(unit_cfg); ++i) { CfgNode *block = get_node(unit_cfg, i); for (InstrHandle h = start(block); h != end(block); ++h) if (HaltLabelNote note = get_note(*h, k_halt)) switch (note.get_kind()) { case halt::CBR: case halt::MBR: case halt::ENTRY: case halt::EXIT: { long id = note.get_unique_id(); if (max_event_id <= id) max_event_id = id + 1; } } } } fprintf(out, "%d\n", max_event_id); }
// now requires compact and ordered. static bool is_compact(MultiWayBranchStatement *the_case) { Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); IInteger low; IInteger high; bool first = true; int count = 0; while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); if (first) { low =pair.first; high = pair.first; first = false; } else { #ifdef COMPACT_ONLY if (low > pair.first) low = pair.first; if (high < pair.first) high = pair.first; #else if (pair.first < low) return false; if (pair.first < high) return false; high = pair.first; #endif } count ++; iter.next(); } if (count == 0) return false; double density = (double)count / (high - low + 1).c_double(); return density > 0.9999999999; }
static String handle_static_statement(CPrintStyleModule *state, const SuifObject *obj) { Statement *stmt = to<Statement>(obj); // Use the iterator over // destination_vars // source ops // source variables // Use the iterator over source ops and // get the classname String return_str = "("; bool needs_comma = false; {for (Iter<VariableSymbol *> iter = stmt->get_destination_var_iterator(); iter.is_valid(); iter.next()) { VariableSymbol *var = iter.current(); if (needs_comma) { return_str += ","; } else { needs_comma = true; } String op = state->print_to_string(var); return_str += op; } } return_str += ") = "; String opname = stmt->getClassName(); return_str += String("?") + opname + "("; needs_comma = false; {for (Iter<Expression *> iter = stmt->get_source_op_iterator(); iter.is_valid(); iter.next()) { Expression *opn = iter.current(); if (needs_comma) { return_str += ","; } else { needs_comma = true; } String op = state->print_to_string(opn); return_str += op; }} return_str += ")"; needs_comma = false; {for (Iter<Statement *> iter = stmt->get_child_statement_iterator(); iter.is_valid(); iter.next()) { Statement *statement = iter.current(); if (needs_comma) { return_str += "; "; } else { needs_comma = true; } String op = state->print_to_string(statement); return_str += op; }} return_str += ";"; return(return_str); }
int tool_main(int argc, char** argv) { SetupCrashHandler(); SkCommandLineFlags::Parse(argc, argv); #if SK_ENABLE_INST_COUNT if (FLAGS_leaks) { gPrintInstCount = true; } #endif SkAutoGraphics ag; // First, parse some flags. BenchLogger logger; if (FLAGS_logFile.count()) { logger.SetLogFile(FLAGS_logFile[0]); } LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]); MultiResultsWriter writer; writer.add(&logWriter); SkAutoTDelete<JSONResultsWriter> jsonWriter; if (FLAGS_outResultsFile.count()) { jsonWriter.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0]))); writer.add(jsonWriter.get()); } // Instantiate after all the writers have been added to writer so that we // call close() before their destructors are called on the way out. CallEnd<MultiResultsWriter> ender(writer); const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF; SkTriState::State dither = SkTriState::kDefault; for (size_t i = 0; i < 3; i++) { if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) { dither = static_cast<SkTriState::State>(i); } } BenchMode benchMode = kNormal_BenchMode; for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) { if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) { benchMode = static_cast<BenchMode>(i); } } SkTDArray<int> configs; bool runDefaultConfigs = false; // Try user-given configs first. for (int i = 0; i < FLAGS_config.count(); i++) { for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++j) { if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) { *configs.append() = j; } else if (0 == strcmp(FLAGS_config[i], kDefaultsConfigStr)) { runDefaultConfigs = true; } } } // If there weren't any, fill in with defaults. if (runDefaultConfigs) { for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++i) { if (gConfigs[i].runByDefault) { *configs.append() = i; } } } // Filter out things we can't run. if (kNormal_BenchMode != benchMode) { // Non-rendering configs only run in normal mode for (int i = 0; i < configs.count(); ++i) { const Config& config = gConfigs[configs[i]]; if (Benchmark::kNonRendering_Backend == config.backend) { configs.remove(i, 1); --i; } } } #if SK_SUPPORT_GPU for (int i = 0; i < configs.count(); ++i) { const Config& config = gConfigs[configs[i]]; if (Benchmark::kGPU_Backend == config.backend) { GrContext* context = gContextFactory.get(config.contextType); if (NULL == context) { SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n", config.name); configs.remove(i); --i; continue; } if (config.sampleCount > context->getMaxSampleCount()){ SkDebugf( "Sample count (%d) for config %s is not supported. Config will be skipped.\n", config.sampleCount, config.name); configs.remove(i); --i; continue; } } } #endif // All flags should be parsed now. Report our settings. if (FLAGS_runOnce) { logger.logError("bench was run with --runOnce, so we're going to hide the times." " It's for your own good!\n"); } writer.option("mode", FLAGS_mode[0]); writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str()); writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str()); writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str()); writer.option("dither", SkTriState::Name[dither]); writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str()); writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str()); writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str()); #if defined(SK_BUILD_FOR_WIN32) writer.option("system", "WIN32"); #elif defined(SK_BUILD_FOR_MAC) writer.option("system", "MAC"); #elif defined(SK_BUILD_FOR_ANDROID) writer.option("system", "ANDROID"); #elif defined(SK_BUILD_FOR_UNIX) writer.option("system", "UNIX"); #else writer.option("system", "other"); #endif #if defined(SK_DEBUG) writer.option("build", "DEBUG"); #else writer.option("build", "RELEASE"); #endif // Set texture cache limits if non-default. for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { #if SK_SUPPORT_GPU const Config& config = gConfigs[i]; if (Benchmark::kGPU_Backend != config.backend) { continue; } GrContext* context = gContextFactory.get(config.contextType); if (NULL == context) { continue; } size_t bytes; int count; context->getResourceCacheLimits(&count, &bytes); if (-1 != FLAGS_gpuCacheBytes) { bytes = static_cast<size_t>(FLAGS_gpuCacheBytes); } if (-1 != FLAGS_gpuCacheCount) { count = FLAGS_gpuCacheCount; } context->setResourceCacheLimits(count, bytes); #endif } // Run each bench in each configuration it supports and we asked for. Iter iter; Benchmark* bench; while ((bench = iter.next()) != NULL) { SkAutoTUnref<Benchmark> benchUnref(bench); if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { continue; } bench->setForceAlpha(alpha); bench->setForceAA(FLAGS_forceAA); bench->setForceFilter(FLAGS_forceFilter); bench->setDither(dither); bench->preDraw(); bool loggedBenchName = false; for (int i = 0; i < configs.count(); ++i) { const int configIndex = configs[i]; const Config& config = gConfigs[configIndex]; if (!bench->isSuitableFor(config.backend)) { continue; } GrContext* context = NULL; #if SK_SUPPORT_GPU SkGLContextHelper* glContext = NULL; if (Benchmark::kGPU_Backend == config.backend) { context = gContextFactory.get(config.contextType); if (NULL == context) { continue; } glContext = gContextFactory.getGLContext(config.contextType); } #endif SkAutoTUnref<SkCanvas> canvas; SkAutoTUnref<SkPicture> recordFrom; SkPictureRecorder recorderTo; const SkIPoint dim = bench->getSize(); SkAutoTUnref<SkSurface> surface; if (Benchmark::kNonRendering_Backend != config.backend) { surface.reset(make_surface(config.fColorType, dim, config.backend, config.sampleCount, context)); if (!surface.get()) { logger.logError(SkStringPrintf( "Device creation failure for config %s. Will skip.\n", config.name)); continue; } switch(benchMode) { case kDeferredSilent_BenchMode: case kDeferred_BenchMode: canvas.reset(SkDeferredCanvas::Create(surface.get())); break; case kRecord_BenchMode: canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY))); break; case kPictureRecord_BenchMode: { SkPictureRecorder recorderFrom; bench->draw(1, recorderFrom.beginRecording(dim.fX, dim.fY)); recordFrom.reset(recorderFrom.endRecording()); canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY))); break; } case kNormal_BenchMode: canvas.reset(SkRef(surface->getCanvas())); break; default: SkASSERT(false); } } if (NULL != canvas) { canvas->clear(SK_ColorWHITE); if (FLAGS_clip) { perform_clip(canvas, dim.fX, dim.fY); } if (FLAGS_scale) { perform_scale(canvas, dim.fX, dim.fY); } if (FLAGS_rotate) { perform_rotate(canvas, dim.fX, dim.fY); } } if (!loggedBenchName) { loggedBenchName = true; writer.bench(bench->getName(), dim.fX, dim.fY); } #if SK_SUPPORT_GPU SkGLContextHelper* contextHelper = NULL; if (Benchmark::kGPU_Backend == config.backend) { contextHelper = gContextFactory.getGLContext(config.contextType); } BenchTimer timer(contextHelper); #else BenchTimer timer; #endif double previous = std::numeric_limits<double>::infinity(); bool converged = false; // variables used to compute loopsPerFrame double frameIntervalTime = 0.0f; int frameIntervalTotalLoops = 0; bool frameIntervalComputed = false; int loopsPerFrame = 0; int loopsPerIter = 0; if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.name); } if (!FLAGS_dryRun) { do { // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion. loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2; if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) { // If you find it takes more than a billion loops to get up to 20ms of runtime, // you've got a computer clocked at several THz or have a broken benchmark. ;) // "1B ought to be enough for anybody." logger.logError(SkStringPrintf( "\nCan't get %s %s to converge in %dms (%d loops)", bench->getName(), config.name, FLAGS_maxMs, loopsPerIter)); break; } if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) { // Clear the recorded commands so that they do not accumulate. canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY))); } timer.start(); // Inner loop that allows us to break the run into smaller // chunks (e.g. frames). This is especially useful for the GPU // as we can flush and/or swap buffers to keep the GPU from // queuing up too much work. for (int loopCount = loopsPerIter; loopCount > 0; ) { // Save and restore around each call to draw() to guarantee a pristine canvas. SkAutoCanvasRestore saveRestore(canvas, true/*also save*/); int loops; if (frameIntervalComputed && loopCount > loopsPerFrame) { loops = loopsPerFrame; loopCount -= loopsPerFrame; } else { loops = loopCount; loopCount = 0; } if (benchMode == kPictureRecord_BenchMode) { recordFrom->draw(canvas); } else { bench->draw(loops, canvas); } if (kDeferredSilent_BenchMode == benchMode) { static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush(); } else if (NULL != canvas) { canvas->flush(); } #if SK_SUPPORT_GPU // swap drawing buffers on each frame to prevent the GPU // from queuing up too much work if (NULL != glContext) { glContext->swapBuffers(); } #endif } // Stop truncated timers before GL calls complete, and stop the full timers after. timer.truncatedEnd(); #if SK_SUPPORT_GPU if (NULL != glContext) { context->flush(); SK_GL(*glContext, Finish()); } #endif timer.end(); // setup the frame interval for subsequent iterations if (!frameIntervalComputed) { frameIntervalTime += timer.fWall; frameIntervalTotalLoops += loopsPerIter; if (frameIntervalTime >= FLAGS_minMs) { frameIntervalComputed = true; loopsPerFrame = (int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs); if (loopsPerFrame < 1) { loopsPerFrame = 1; } // SkDebugf(" %s has %d loops in %f ms (normalized to %d)\n", // bench->getName(), frameIntervalTotalLoops, // timer.fWall, loopsPerFrame); } } const double current = timer.fWall / loopsPerIter; if (FLAGS_verbose && current > previous) { SkDebugf("↑"); } if (FLAGS_verbose) { SkDebugf("%.3g ", current); } converged = HasConverged(previous, current, timer.fWall); previous = current; } while (!FLAGS_runOnce && !converged); } if (FLAGS_verbose) { SkDebugf("\n"); } if (!FLAGS_dryRun && FLAGS_outDir.count() && Benchmark::kNonRendering_Backend != config.backend) { SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); if (image.get()) { saveFile(bench->getName(), config.name, FLAGS_outDir[0], image); } } if (FLAGS_runOnce) { // Let's not mislead ourselves by looking at Debug build or single iteration bench times! continue; } // Normalize to ms per 1000 iterations. const double normalize = 1000.0 / loopsPerIter; const struct { char shortName; const char* longName; double ms; } times[] = { {'w', "msecs", normalize * timer.fWall}, {'W', "Wmsecs", normalize * timer.fTruncatedWall}, {'c', "cmsecs", normalize * timer.fCpu}, {'C', "Cmsecs", normalize * timer.fTruncatedCpu}, {'g', "gmsecs", normalize * timer.fGpu}, }; writer.config(config.name); for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) { if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) { writer.timer(times[i].longName, times[i].ms); } } } } #if SK_SUPPORT_GPU gContextFactory.destroyContexts(); #endif return 0; }
void CopyPropagationPass2::CollectVariables() { assert(procDef != NULL) ; if (killMap.empty() == false) { ClearMap() ; } assert(killMap.empty() == true) ; assert(procDef != NULL) ; SymbolTable* symTab = procDef->get_symbol_table() ; Iter<SymbolTableObject*> symIter = symTab->get_symbol_table_object_iterator() ; while (symIter.is_valid()) { if (is_a<VariableSymbol>(symIter.current())) { // For each variable symbol, create a new list of statement/int pairs // and add that to the kill map list<std::pair<Statement*, int> >* assocList = new list<std::pair<Statement*, int> > ; killMap[to<VariableSymbol>(symIter.current())] = assocList ; } else if (is_a<ParameterSymbol>(symIter.current())) { // If we are compiling a module, we also have to find the argument // (which should be a struct) and collect all of those variable // symbols.. ParameterSymbol* nextParm = dynamic_cast<ParameterSymbol*>(symIter.current()) ; assert(nextParm != NULL) ; // Now check that we have a struct type DataType* parmType = nextParm->get_type()->get_base_type() ; StructType* parmStructType = dynamic_cast<StructType*>(parmType) ; if (parmStructType == NULL) { list<std::pair<Statement*, int> >* assocList = new list<std::pair<Statement*, int> > ; killMap[dynamic_cast<VariableSymbol*>(symIter.current())] = assocList ; symIter.next() ; continue ; } // Go through this symbol table, just like the parent table... SymbolTable* structSymTab = parmStructType->get_group_symbol_table() ; Iter<SymbolTableObject*> structSymIter = structSymTab->get_symbol_table_object_iterator() ; while (structSymIter.is_valid()) { // These should all be variable symbols! if (is_a<FieldSymbol>(structSymIter.current())) { // For each variable symbol, create a new list of statement/int pairs // and add that to the killMap. list<std::pair<Statement*, int> >* assocList = new list<std::pair<Statement*, int> > ; killMap[to<VariableSymbol>(structSymIter.current())] = assocList ; } else { std::cerr << "Non variable symbol inside a struct!" << std::endl ; assert(0) ; } structSymIter.next() ; } } symIter.next() ; } }
void One2MultiArrayExpressionPass::do_procedure_definition(ProcedureDefinition* proc_def) { bool kill_all = !(_preserve_one_dim->is_set()); // access all array type declarations and create corresponding multi array types SuifEnv* suif_env = proc_def->get_suif_env(); TypeBuilder* tb = (TypeBuilder*)suif_env-> get_object_factory(TypeBuilder::get_class_name()); (void) tb; // avoid warning #ifdef CONVERT_TYPES for (Iter<ArrayType> at_iter = object_iterator<ArrayType>(proc_def); at_iter.is_valid();at_iter.next()) { MultiDimArrayType* multi_type = converter->array_type2multi_array_type(&at_iter.current()); } #endif //CONVERT_TYPES // collect tops of array access chains into this list list<ArrayReferenceExpression*> ref_exprs; for (Iter<ArrayReferenceExpression> are_iter = object_iterator<ArrayReferenceExpression>(proc_def); are_iter.is_valid(); are_iter.next()) { // itself an array and parent is *not* an array ArrayReferenceExpression* are = &are_iter.current(); if((kill_all || is_kind_of<ArrayReferenceExpression>(are->get_base_array_address())) && !is_kind_of<ArrayReferenceExpression>(are->get_parent())) { //printf("%p \t", are);are->print_to_default(); ref_exprs.push_back(are); } } // for top all expressions, convert them to multi-exprs for(list<ArrayReferenceExpression*>::iterator ref_iter = ref_exprs.begin(); ref_iter != ref_exprs.end(); ref_iter++) { ArrayReferenceExpression* top_array = *ref_iter; converter->convert_array_expr2multi_array_expr(top_array); } #ifdef CONVERT_TYPES // replace the types of all array variables for (Iter<VariableSymbol> iter = object_iterator<VariableSymbol>(proc_def); iter.is_valid();iter.next()) { VariableSymbol* vd = &iter.current(); DataType *vtype = tb->unqualify_data_type(vd->get_type()); if (is_kind_of<ArrayType>(vtype)) { MultiDimArrayType* multi_type = converter->array_type2multi_array_type(to<ArrayType>(vtype)); vd->replace(vd->get_type(), tb->get_qualified_type(multi_type)); } } // remove the remaining one-dim array types converter->remove_all_one_dim_array_types(); #endif //CONVERT_TYPES // make sure no traces of single-dim arrays are left if(kill_all){ {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { // ArrayReferenceExpression* are = &iter.current(); //are->print_to_default(); printf("at %p \t", are); suif_assert_message(false, ("ARE not eliminated")); } } #ifdef CONVERT_TYPES {for(Iter<ArrayType> iter = object_iterator<ArrayType>(proc_def); iter.is_valid(); iter.next()) {suif_assert_message(false, ("ArrayType not eliminated"));}} #endif } }
Walker::ApplyStatus mdbm_c_for_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); CForStatement *c_for_stmt = to<CForStatement>(x); // if(!is_stmt_within_begin_end_hw_marks(c_for_stmt)) // return Walker::Continue; Statement *body = c_for_stmt->get_body(); if (body){ Iter<CForStatement> iter_c_for = object_iterator<CForStatement>(body); if(iter_c_for.is_valid()) return Walker::Continue; StatementList *stmt_list_body = NULL; if(is_a<StatementList>(body)) stmt_list_body = to<StatementList>(body); else{ stmt_list_body = create_statement_list(env); c_for_stmt->set_body(0); stmt_list_body->append_statement(body); c_for_stmt->set_body(stmt_list_body); } Iter<Statement*> iter = stmt_list_body->get_statement_iterator(); for( ; iter.is_valid(); iter.next()){ Statement *child_stmt = iter.current(); if(is_a<StoreVariableStatement>(child_stmt)){ Iter<LoadExpression> iter2 = object_iterator<LoadExpression>(child_stmt); if(!iter2.is_valid()) break; }else break; } MarkStatement *end_of_mem_reads_mark = create_mark_statement(env); if(iter.is_valid()) insert_statement_before(iter.current(), end_of_mem_reads_mark); else stmt_list_body->insert_statement(0, end_of_mem_reads_mark); BrickAnnote *ba = create_brick_annote(env, "end_of_mem_reads"); ba->append_brick(create_suif_object_brick(env, end_of_mem_reads_mark)); c_for_stmt->append_annote(ba); for( ; iter.is_valid(); iter.next()){ Statement *child_stmt = iter.current(); if(is_a<StoreStatement>(child_stmt)) break; } MarkStatement *beg_of_mem_writes_mark = create_mark_statement(env); if(iter.is_valid()) insert_statement_before(iter.current(), beg_of_mem_writes_mark); else stmt_list_body->append_statement(beg_of_mem_writes_mark); ba = create_brick_annote(env, "beg_of_mem_writes"); ba->append_brick(create_suif_object_brick(env, beg_of_mem_writes_mark)); c_for_stmt->append_annote(ba); } return Walker::Continue; }
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){ suif_hash_map<ParameterSymbol*, Type*> params; TypeBuilder *tb = (TypeBuilder*) get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); // collect all procedure parameters of pointer type into params list for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator(); iter.is_valid(); iter.next()) { ParameterSymbol* par_sym = iter.current(); Type* par_type = tb->unqualify_type(par_sym->get_type()); if(is_kind_of<PointerType>(par_type)){ // put NULLs into the map at first, // they will later be overwritten params[par_sym] = NULL; } } if(params.size()==0) return; // nothing to do // walk thru all AREs and look for arrays that are in the param list {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { ArrayReferenceExpression* are = &iter.current(); if(is_kind_of<UnaryExpression>(are->get_base_array_address())){ UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address()); if(ue->get_opcode() == k_convert){ if(is_kind_of<LoadVariableExpression>(ue->get_source())){ LoadVariableExpression* lve = to<LoadVariableExpression>(ue->get_source()); VariableSymbol* array = lve->get_source(); for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin(); iter!=params.end();iter++) { ParameterSymbol* par_sym = (*iter).first; if(par_sym == array){ // match! Type* array_type; suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.find(par_sym); if(iter==params.end() || (*iter).second==NULL){ //array_type = to<PointerType>(ue->get_result_type())->get_reference_type(); array_type = tb->get_qualified_type(ue->get_result_type()); params[par_sym] = array_type; //printf("%s has type ",par_sym->get_name().c_str()); //array_type->print_to_default(); }else{ array_type = params[par_sym].second; suif_assert(is_kind_of<QualifiedType>(array_type)); } array->replace(array->get_type(), array_type); remove_suif_object(ue); remove_suif_object(lve); lve->replace(lve->get_result_type(), tb->unqualify_type(array_type)); // put the LoadVar directly under ARE are->set_base_array_address(lve); //are->print_to_default(); } } } else { suif_warning(ue->get_source(), ("Expecting a LoadVariableExpression here")); } } else { suif_warning(ue, ("Disallow converts in AREs for " "things other than procedure parameters")); } } } } }
/* * layout_frame -- Assign stack frame locations to each variable that needs one. * Store the offsets in frame_map. * * A local variable needs a memory-stack location unless it is never used or it * is a memory-passed parameter. */ void CodeFinIa64::layout_frame() { debug(4, "... determine offsets from $sp for variables"); // Force max_arg_area to be a 16-byte multiple to be sure that the local- // storage area starts on a 16-byte boundary. max_arg_area = (max_arg_area + 15) & -16; // Unless this is a leaf procedure, reserve a 16-byte scratch area for // callees at the young end of the current frame. int scratch_area_size = is_leaf ? 0 : 16; // Frame_offset is the running offset of the current variable in the // local-storage area. Initialize it to the distance between the young // end of the frame and the local-storage area. frame_offset = scratch_area_size + max_arg_area; SymTable *st = cur_unit->get_symbol_table(); Iter<SymbolTableObject*> iter = st->get_symbol_table_object_iterator(); for ( ; iter.is_valid(); iter.next()) { SymbolTableObject *sto = iter.current(); if (is_kind_of<VarSym>(sto)) { VarSym *v = (VarSym*)sto; if (!is_reg_param(v) && is_a<ParameterSymbol>(v)) continue; // v's in caller's frame Map<Sym*,int>::iterator v_handle = frame_map.find(v); if (v_handle == frame_map.end()) continue; // v never used // Here v is an automatic variable, other than a stack-passed // parameter, that is actually used in the program. First, // adjust frame_offset to accommodate v'a alignment. The // frame_offset is already a multiple of four bytes. An // alignment value greater than four bytes will itself be a // multiple of four. Round frame_offset up if necessary to // satisfy that alignment constraint. TypeId v_type = get_type(v); int v_align = get_bit_alignment(v_type) >> 3; // in bytes if (v_align > 4) { claim(v_align % 4 == 0); frame_offset = ((frame_offset + v_align - 1) / v_align) * v_align; } (*v_handle).second = frame_offset; // update frame_map // Now allocate a multiple of four bytes to v. int v_size = get_bit_size(v_type) >> 3; // v's size in bytes frame_offset += (v_size + 3) & -4; } } // Compute number of bytes for registers saved in memory between locals // and the frame base. save_area_size = saved_reg_set[CLASS_GR].size() * 8 + saved_reg_set[CLASS_BR].size() * 8 + saved_reg_set[CLASS_FR].size() * 16; // The sum of local-area and save-area sizes must be a multiple of 16. // Frame_offset is now the local-area size. Pad it to make the sum a // 16-byte multiple. (Hint: save_area_size is already a multiple of 8.) claim((frame_offset & 3) == 0); // now a 4-byte multiple frame_offset = (frame_offset + (save_area_size & 15) + 15) & -16; debug(4, "... determine offsets from $sp for memory-passed parameters"); // Process parameter list in order. Set running offset param_offset for // memory-passed parameters. Also determine the highest GR arg register // used. // FIXME: does not allow for aggregates passed partly in regs and partly // in memory. int param_offset = frame_offset + save_area_size; if (param_offset < (scratch_area_size + 16)) param_offset = (scratch_area_size + 16); for (int i = 0; i < get_formal_param_count(cur_unit); i++) { VarSym *p = get_formal_param(cur_unit, i); // Each parameter consumes a multiple of 8 bytes. int p_size = get_bit_size(get_type(p)) >> 3; // in bytes p_size = (p_size + 7) & -8; if (is_reg_param(p)) { int first_reg = get_param_reg(p); if (GR_ARG0 <= first_reg && first_reg <= GR_LAST_ARG) { claim(first_reg > max_in_reg); max_in_reg = first_reg + (p_size / 8) - 1; if (max_in_reg > GR_LAST_ARG) max_in_reg = GR_LAST_ARG; } } else { claim(frame_map.count(p) == 0); frame_map[p] = param_offset; param_offset += p_size; } } // In a varargs procedure, the GR parameter registers that are not used // by named arguments must be spilled to memory adjacent to any // parameters passed in memory by the caller. So in the varargs case, // the first thing at the old end of the frame (beginning actually in // the caller's scratch area) is a varargs spill area. Note that we // increase max_in_reg to cover any reg-passed, unnamed varargs. if (is_varargs) { va_area_size = 64 - 8 * (max_in_reg - GR_STACK0 + 1); max_in_reg = GR_LAST_ARG; } else { va_area_size = 0; } // Frame size is the sum of the sizes of the scratch area, the // outgoing-arg area, the local-storage area, the callee-saves-register // area, and the register-passed-varargs area. (The first three have // already been combined in frame_offset.) The sum of frame_offset and // save_area_size is already a 16-byte multiple, but va_area_size may // not be, so pad to bring frame_size to a multiple of 16 bytes. frame_size = frame_offset + save_area_size + ((va_area_size + 15) & -16); // For a procedure that invokes va_start, bind the variable whose symbol // is stored in va_first_var to the offset from SP of the first unnamed // argument, whether passed in memory (va_area_size == 0) or in a register // that has been dumped to memory (va_area_size > 0). claim((va_first_var == NULL) == (is_varargs == false)); if (is_varargs) frame_map[va_first_var] = (va_area_size == 0) ? param_offset : (frame_size - (va_area_size - 16)); }
static void dismantle_multi_dim_array_expression( SuifEnv *env, MultiDimArrayExpression *exp, TypeBuilder *type_builder, suif_hash_map<MultiDimArrayType *,Type *> &type_map) { Expression *ref_exp = exp->get_array_address(); Type *typ = ref_exp->get_result_type(); if (is_kind_of<PointerType>(typ)) typ = to<PointerType>(typ)->get_reference_type(); if (is_kind_of<ReferenceType>(typ)) typ = to<ReferenceType>(typ)->get_reference_type(); if (is_kind_of<QualifiedType>(typ)) typ = to<QualifiedType>(typ)->get_base_type(); simple_stack<Expression *> lows; int dims; Type *rep_type; if (is_kind_of<MultiDimArrayType>(typ)) { MultiDimArrayType *mdatyp= to<MultiDimArrayType>(typ); suif_hash_map<MultiDimArrayType *,Type *>::iterator iter = type_map.find(mdatyp); kernel_assert_message(iter != type_map.end(), ("Error - type not converted")); rep_type = (*iter).second; dims = exp->get_index_count(); for (int i = dims - 1;i >=0 ; i--) { lows.push(mdatyp->get_lower_bound(i)); } } else { // this arm should never be taken, so assert kernel_assert_message(false,("This code should not have been accessed")); rep_type = typ; dims = 0; while (is_kind_of<ArrayType>(typ)) { ArrayType *atype = to<ArrayType>(typ); dims ++; lows.push(atype->get_lower_bound()); typ = to<QualifiedType>(atype->get_element_type())->get_base_type(); } } exp->replace(ref_exp,0); ref_exp->set_parent(0); int index_count = exp->get_index_count(); for (int i = 0;i < index_count;i ++) { Type *ref_type = rep_type; for (int j = 0;j <= i;j ++) { ref_type = type_builder->unqualify_type(ref_type); ref_type = to<ArrayType>(ref_type)->get_element_type(); } ref_type = type_builder->unqualify_type(ref_type); ref_type = type_builder->get_pointer_type(ref_type); Expression *index = exp->get_index(index_count - i - 1); // process nested multi dim arra expressions for (Iter<MultiDimArrayExpression> iter = object_iterator<MultiDimArrayExpression>(index); iter.is_valid(); iter.next()) { MultiDimArrayExpression *mexpr = &iter.current(); dismantle_multi_dim_array_expression(env,mexpr,type_builder,type_map); } exp->replace(index,0); index->set_parent(0); ref_exp = create_array_reference_expression( env,to<DataType>(ref_type),ref_exp, index); } exp->get_parent()->replace(exp,ref_exp); }
void audit_opnds(FILE *fp, const char *heading) { int size_reg = 0; int size_var = 0; int size_immed_integer = 0; int size_immed_string = 0; int size_addr_sym = 0; int size_addr_exp = 0; for (Iter<SymbolTableObject*> i = the_local_scope->get_symbol_table_object_iterator(); i.is_valid(); i.next()) { SymbolTableObject *sto = i.current(); if (is_kind_of<IrOpnd>(sto)) switch (static_cast<IrOpnd*>(sto)->get_kind()) { case opnd::NONE: claim(false, "Unexpected operand kind: opnd::NONE"); case opnd::REG_HARD: case opnd::REG_VIRTUAL: size_reg += sizeof(OpndReg); break; case opnd::VAR: size_var += sizeof(OpndVar); break; case opnd::IMMED_INTEGER: size_immed_integer += sizeof(OpndImmedInteger); break; case opnd::IMMED_STRING: size_immed_string += sizeof(OpndImmedString); break; case opnd::ADDR_SYM: size_addr_sym += sizeof(OpndAddrSym); break; case opnd::SYM_DISP: case opnd::INDEX_SYM_DISP: case opnd::BASE_DISP: case opnd::BASE_INDEX: case opnd::BASE_INDEX_DISP: case opnd::INDEX_SCALE_DISP: case opnd::BASE_INDEX_SCALE_DISP: size_addr_sym += sizeof(OpndAddrExp) + sizeof(IrOpnd*) * static_cast<OpndAddrExp*>(sto)->get_src_count(); break; default: claim(false, "Unknown operand kind"); } } fprintf(fp, "%s operand storage (bytes):\n", heading); fprintf(fp, " Register: %8d\n", size_reg); fprintf(fp, " Variable symbol: %8d\n", size_var); fprintf(fp, " String immediate: %8d\n", size_immed_string); fprintf(fp, " Integer immediate: %8d\n", size_immed_integer); fprintf(fp, " Address symbol: %8d\n", size_addr_sym); fprintf(fp, " Address expression:%8d\n", size_addr_exp); fprintf(fp, " %8d (total)\n", size_reg + size_var + size_immed_string + size_immed_integer + size_addr_sym + size_addr_exp); }
static void TestTLList(skiatest::Reporter* reporter) { typedef SkTLList<ListElement> ElList; typedef ElList::Iter Iter; SkRandom random; for (int i = 1; i <= 16; i *= 2) { ElList list1(i); ElList list2(i); Iter iter1; Iter iter2; Iter iter3; Iter iter4; #if SK_ENABLE_INST_COUNT SkASSERT(0 == ListElement::InstanceCount()); #endif REPORTER_ASSERT(reporter, list1.isEmpty()); REPORTER_ASSERT(reporter, NULL == iter1.init(list1, Iter::kHead_IterStart)); REPORTER_ASSERT(reporter, NULL == iter1.init(list1, Iter::kTail_IterStart)); // Try popping an empty list list1.popHead(); list1.popTail(); REPORTER_ASSERT(reporter, list1.isEmpty()); REPORTER_ASSERT(reporter, list1 == list2); // Create two identical lists, one by appending to head and the other to the tail. list1.addToHead(ListElement(1)); list2.addToTail(ListElement(1)); #if SK_ENABLE_INST_COUNT SkASSERT(2 == ListElement::InstanceCount()); #endif iter1.init(list1, Iter::kHead_IterStart); iter2.init(list1, Iter::kTail_IterStart); REPORTER_ASSERT(reporter, iter1.get()->fID == iter2.get()->fID); iter3.init(list2, Iter::kHead_IterStart); iter4.init(list2, Iter::kTail_IterStart); REPORTER_ASSERT(reporter, iter3.get()->fID == iter1.get()->fID); REPORTER_ASSERT(reporter, iter4.get()->fID == iter1.get()->fID); REPORTER_ASSERT(reporter, list1 == list2); list2.reset(); // use both before/after in-place construction on an empty list SkNEW_INSERT_IN_LLIST_BEFORE(&list2, list2.headIter(), ListElement, (1)); REPORTER_ASSERT(reporter, list2 == list1); list2.reset(); SkNEW_INSERT_IN_LLIST_AFTER(&list2, list2.tailIter(), ListElement, (1)); REPORTER_ASSERT(reporter, list2 == list1); // add an element to the second list, check that iters are still valid iter3.init(list2, Iter::kHead_IterStart); iter4.init(list2, Iter::kTail_IterStart); list2.addToHead(ListElement(2)); #if SK_ENABLE_INST_COUNT SkASSERT(3 == ListElement::InstanceCount()); #endif REPORTER_ASSERT(reporter, iter3.get()->fID == iter1.get()->fID); REPORTER_ASSERT(reporter, iter4.get()->fID == iter1.get()->fID); REPORTER_ASSERT(reporter, 1 == Iter(list2, Iter::kTail_IterStart).get()->fID); REPORTER_ASSERT(reporter, 2 == Iter(list2, Iter::kHead_IterStart).get()->fID); REPORTER_ASSERT(reporter, list1 != list2); list1.addToHead(ListElement(2)); REPORTER_ASSERT(reporter, list1 == list2); #if SK_ENABLE_INST_COUNT SkASSERT(4 == ListElement::InstanceCount()); #endif REPORTER_ASSERT(reporter, !list1.isEmpty()); list1.reset(); list2.reset(); #if SK_ENABLE_INST_COUNT SkASSERT(0 == ListElement::InstanceCount()); #endif REPORTER_ASSERT(reporter, list1.isEmpty() && list2.isEmpty()); // randomly perform insertions and deletions on a list and perform tests int count = 0; for (int j = 0; j < 100; ++j) { if (list1.isEmpty() || random.nextBiasedBool(3 * SK_Scalar1 / 4)) { int id = j; // Choose one of three ways to insert a new element: at the head, at the tail, // before a random element, after a random element int numValidMethods = 0 == count ? 2 : 4; int insertionMethod = random.nextULessThan(numValidMethods); switch (insertionMethod) { case 0: list1.addToHead(ListElement(id)); break; case 1: list1.addToTail(ListElement(id)); break; case 2: // fallthru to share code that picks random element. case 3: { int n = random.nextULessThan(list1.count()); Iter iter = list1.headIter(); // remember the elements before/after the insertion point. while (n--) { iter.next(); } Iter prev(iter); Iter next(iter); next.next(); prev.prev(); SkASSERT(NULL != iter.get()); // insert either before or after the iterator, then check that the // surrounding sequence is correct. if (2 == insertionMethod) { SkNEW_INSERT_IN_LLIST_BEFORE(&list1, iter, ListElement, (id)); Iter newItem(iter); newItem.prev(); REPORTER_ASSERT(reporter, newItem.get()->fID == id); if (NULL != next.get()) { REPORTER_ASSERT(reporter, next.prev()->fID == iter.get()->fID); } if (NULL != prev.get()) { REPORTER_ASSERT(reporter, prev.next()->fID == id); } } else { SkNEW_INSERT_IN_LLIST_AFTER(&list1, iter, ListElement, (id)); Iter newItem(iter); newItem.next(); REPORTER_ASSERT(reporter, newItem.get()->fID == id); if (NULL != next.get()) { REPORTER_ASSERT(reporter, next.prev()->fID == id); } if (NULL != prev.get()) { REPORTER_ASSERT(reporter, prev.next()->fID == iter.get()->fID); } } } } ++count; } else { // walk to a random place either forward or backwards and remove. int n = random.nextULessThan(list1.count()); Iter::IterStart start; ListElement* (Iter::*incrFunc)(); if (random.nextBool()) { start = Iter::kHead_IterStart; incrFunc = &Iter::next; } else { start = Iter::kTail_IterStart; incrFunc = &Iter::prev; } // find the element Iter iter(list1, start); while (n--) { REPORTER_ASSERT(reporter, NULL != iter.get()); (iter.*incrFunc)(); } REPORTER_ASSERT(reporter, NULL != iter.get()); // remember the prev and next elements from the element to be removed Iter prev = iter; Iter next = iter; prev.prev(); next.next(); list1.remove(iter.get()); // make sure the remembered next/prev iters still work Iter pn = prev; pn.next(); Iter np = next; np.prev(); // pn should match next unless the target node was the head, in which case prev // walked off the list. REPORTER_ASSERT(reporter, pn.get() == next.get() || NULL == prev.get()); // Similarly, np should match prev unless next originally walked off the tail. REPORTER_ASSERT(reporter, np.get() == prev.get() || NULL == next.get()); --count; } REPORTER_ASSERT(reporter, count == list1.count()); #if SK_ENABLE_INST_COUNT SkASSERT(count == ListElement::InstanceCount()); #endif } list1.reset(); #if SK_ENABLE_INST_COUNT SkASSERT(0 == ListElement::InstanceCount()); #endif } }
Statement* scope_statement_walker::dismantle_scope_statement(ScopeStatement *the_scope_stat){ ProcedureDefinition* proc_def = get_procedure_definition(the_scope_stat); Statement *body = the_scope_stat->get_body(); if(body==NULL){ the_scope_stat->print_to_default(); } body->set_parent(0); the_scope_stat->set_body(0); // This is a bug? // remove_suif_object(body); SymbolTable * symbol_table = the_scope_stat->get_symbol_table(); DefinitionBlock * definition_block = the_scope_stat->get_definition_block(); SymbolTable *new_symbol_table = proc_def->get_symbol_table(); DefinitionBlock *new_definition_block = proc_def->get_definition_block(); if (symbol_table != 0) { // start by creating a name for the symbol in the new symbol table Iter<SymbolTable::lookup_table_pair> piter = symbol_table->get_lookup_table_iterator(); while (piter.is_valid()) { indexed_list<LString,SymbolTableObject*>::pair p = piter.current(); SymbolTableObject * obj = p.second; const LString &name = p.first; new_symbol_table->add_lookup_table(name,obj); piter.next(); } // now move all symbols into the symbol table for the procedure scope // at the same time, we delete them from the current symbol table and // remove all references to this symbol table from the name list attached // to the symbol // DLH // I modifed this to build a list so we aren't iterating over // a changing object (which didn't work. and I don't expect it to) list<SymbolTableObject*> l; {for (Iter<SymbolTableObject*> iter = symbol_table->get_symbol_table_object_iterator(); iter.is_valid(); iter.next()) { l.push_back(iter.current()); }} for (list<SymbolTableObject*>::iterator iter = l.begin(); iter != l.end(); iter++) { SymbolTableObject *object = *iter; symbol_table->remove_symbol_table_object(object); rename_if_collision(object, new_symbol_table); new_symbol_table->add_symbol(object); // symbol_table->remove_all_from_lookup_table(object); // object->remove_all_from_name(symbol_table); } } if (definition_block != 0) { // move all definition block entries int i = definition_block->get_variable_definition_count(); while (i > 0){ i--; VariableDefinition *next = definition_block->remove_variable_definition(i); new_definition_block->append_variable_definition(next); } i = definition_block->get_procedure_definition_count(); while (i > 0){ i--; ProcedureDefinition *next = definition_block->remove_procedure_definition(i); new_definition_block->append_procedure_definition(next); } } the_scope_stat->get_parent()->replace(the_scope_stat, body); return body; }
void DismantleStructuredReturns::do_file_set_block( FileSetBlock* file_set_block ) { suif_map<CProcedureType *,QualifiedType *> type_map; list<ArrayReferenceExpression*> ref_exprs; SuifEnv *env = 0; TypeBuilder *tb = 0; VoidType *vt = 0; for (Iter<ProcedureSymbol> iter = object_iterator<ProcedureSymbol>(file_set_block); iter.is_valid(); iter.next()) { ProcedureSymbol *sym = &iter.current(); Type *type = sym->get_type(); if (!is_kind_of<CProcedureType>(type)) continue; CProcedureType *cp_type = to<CProcedureType>(type); type = cp_type->get_result_type(); if (!env) { env = type->get_suif_env(); tb = (TypeBuilder*) env->get_object_factory(TypeBuilder::get_class_name()); vt = tb->get_void_type(); } suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); QualifiedType *qtype; if (t_iter == type_map.end()) { if (!is_kind_of<GroupType>(type) && !is_kind_of<ArrayType>(type)) continue; qtype = tb->get_qualified_type( tb->get_pointer_type(to<DataType>(type))); cp_type->set_result_type(vt); cp_type->insert_argument(0,qtype); type_map.enter_value(cp_type,qtype); } else { qtype = (*t_iter).second; } ProcedureDefinition *def = sym->get_definition(); if (!def) continue; ParameterSymbol *par = create_parameter_symbol(env,qtype); def->get_symbol_table()->append_symbol_table_object(par); def->insert_formal_parameter(0,par); // Convert all returns into assigned and returns for (Iter<ReturnStatement> ret_iter = object_iterator<ReturnStatement>(def->get_body()); ret_iter.is_valid(); ret_iter.next()) { ReturnStatement *ret = &ret_iter.current(); Expression *retval = ret->get_return_value(); ret->set_return_value(0); retval->set_parent(0); insert_statement_before(ret, create_store_statement(env,retval,create_var_use(par))); } } // Change all calls to the new form for (Iter<CallStatement> cs_iter = object_iterator<CallStatement>(file_set_block); cs_iter.is_valid(); cs_iter.next()) { CallStatement *call = &cs_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); call->set_destination(0); } for (Iter<CallExpression> ce_iter = object_iterator<CallExpression>(file_set_block); ce_iter.is_valid(); ce_iter.next()) { CallExpression *call = &ce_iter.current(); Type *type = call->get_callee_address()->get_result_type(); Type *p_type = tb->unqualify_type(to<PointerType>(type)->get_reference_type()); if (!is_kind_of<PointerType>(p_type)) continue; p_type = tb->unqualify_type(to<PointerType>(p_type)->get_reference_type()); if (!is_kind_of<CProcedureType>(p_type)) continue; CProcedureType *cp_type = to<CProcedureType>(p_type); ; suif_map<CProcedureType *,QualifiedType *>::iterator t_iter = type_map.find(cp_type); if (t_iter == type_map.end()) continue; QualifiedType *qtype = (*t_iter).second; DataType *var_type = to<DataType>(tb->unqualify_type(to<PointerType>(qtype->get_base_type()) ->get_reference_type())); VariableSymbol *var = new_anonymous_variable(env,call,tb->get_qualified_type(var_type)); Expression *exp = create_symbol_address_expression( env, tb->get_pointer_type(var_type), var); call->insert_argument(0,exp); Statement *loc = get_expression_owner(call); call->get_parent()->replace(call,create_var_use(var)); call->set_parent(0); suif_assert(vt != 0); call->set_result_type(vt); EvalStatement *es = create_eval_statement(env); insert_statement_before(loc,es); // Would be better to turn this into a call statement es->append_expression(call); } }
static void TestTInternalLList(skiatest::Reporter* reporter) { SkTInternalLList<ListElement> list; ListElement elements[4] = { ListElement(0), ListElement(1), ListElement(2), ListElement(3), }; // list should be empty to start with check_list(list, reporter, true, 0, false, false, false, false, elements); list.addToHead(&elements[0]); check_list(list, reporter, false, 1, true, false, false, false, elements); list.addToHead(&elements[1]); list.addToHead(&elements[2]); list.addToHead(&elements[3]); check_list(list, reporter, false, 4, true, true, true, true, elements); // test out iterators typedef SkTInternalLList<ListElement>::Iter Iter; Iter iter; ListElement* cur = iter.init(list, Iter::kHead_IterStart); for (int i = 0; NULL != cur; ++i, cur = iter.next()) { REPORTER_ASSERT(reporter, cur->fID == 3-i); } cur = iter.init(list, Iter::kTail_IterStart); for (int i = 0; NULL != cur; ++i, cur = iter.prev()) { REPORTER_ASSERT(reporter, cur->fID == i); } // remove middle, frontmost then backmost list.remove(&elements[1]); list.remove(&elements[3]); list.remove(&elements[0]); check_list(list, reporter, false, 1, false, false, true, false, elements); // remove last element list.remove(&elements[2]); // list should be empty again check_list(list, reporter, true, 0, false, false, false, false, elements); // test out methods that add to the middle of the list. list.addAfter(&elements[1], NULL); check_list(list, reporter, false, 1, false, true, false, false, elements); list.remove(&elements[1]); list.addBefore(&elements[1], NULL); check_list(list, reporter, false, 1, false, true, false, false, elements); list.addBefore(&elements[0], &elements[1]); check_list(list, reporter, false, 2, true, true, false, false, elements); list.addAfter(&elements[3], &elements[1]); check_list(list, reporter, false, 3, true, true, false, true, elements); list.addBefore(&elements[2], &elements[3]); check_list(list, reporter, false, 4, true, true, true, true, elements); cur = iter.init(list, Iter::kHead_IterStart); for (int i = 0; NULL != cur; ++i, cur = iter.next()) { REPORTER_ASSERT(reporter, cur->fID == i); } }
int main (int argc, char * const argv[]) { SkAutoGraphics ag; const char* writePath = NULL; // if non-null, where we write the originals const char* readPath = NULL; // if non-null, were we read from to compare char* const* stop = argv + argc; for (++argv; argv < stop; ++argv) { if (strcmp(*argv, "-w") == 0) { argv++; if (argv < stop && **argv) { writePath = *argv; } } else if (strcmp(*argv, "-r") == 0) { argv++; if (argv < stop && **argv) { readPath = *argv; } } } Iter iter; GM* gm; while ((gm = iter.next()) != NULL) { SkISize size = gm->getISize(); SkDebugf("creating... %s [%d %d]\n", gm->shortName(), size.width(), size.height()); SkBitmap bitmap; for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { bitmap.setConfig(gRec[i].fConfig, size.width(), size.height()); bitmap.allocPixels(); bitmap.eraseColor(0); SkCanvas canvas(bitmap); gm->draw(&canvas); SkString name = make_name(gm->shortName(), gRec[i].fName); if (writePath) { SkString path = make_filename(writePath, name); bool success = write_bitmap(path, bitmap); if (!success) { fprintf(stderr, "FAILED to write %s\n", path.c_str()); } } else if (readPath) { SkString path = make_filename(readPath, name); SkBitmap orig; bool success = SkImageDecoder::DecodeFile(path.c_str(), &orig, SkBitmap::kARGB_8888_Config, SkImageDecoder::kDecodePixels_Mode, NULL); if (success) { compare(bitmap, orig, name); } else { fprintf(stderr, "FAILED to read %s\n", path.c_str()); } } } SkDELETE(gm); } return 0; }
void TransformSystemsToModules::Transform() { assert(procDef != NULL) ; // Collect all the input scalars and output scalars list<VariableSymbol*> ports ; SymbolTable* procSymTab = procDef->get_symbol_table() ; bool foundInputs = false ; bool foundOutputs = false ; for (int i = 0 ; i < procSymTab->get_symbol_table_object_count() ; ++i) { SymbolTableObject* nextObject = procSymTab->get_symbol_table_object(i) ; if (nextObject->lookup_annote_by_name("InputScalar") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString inputName = toConvert->get_name() ; inputName = inputName + "_in" ; toConvert->set_name(inputName) ; ports.push_back(toConvert) ; foundInputs = true ; } if (nextObject->lookup_annote_by_name("OutputVariable") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString outputName = toConvert->get_name() ; outputName = outputName + "_out" ; toConvert->set_name(outputName) ; ports.push_back(toConvert) ; foundOutputs = true ; } } assert(foundInputs && "Could not identify inputs. Were they removed via optimizations?") ; assert(foundOutputs && "Could not identify outputs. Were they removed via optimizations?") ; // Determine the bit size and add everything to a new symbol table int bitSize = 0 ; GroupSymbolTable* structTable = create_group_symbol_table(theEnv, procDef->get_symbol_table()) ; std::map<VariableSymbol*, FieldSymbol*> replacementFields ; bool portsRemoved = false ; // If this was actually a new style module, we should make sure to // put these in the correct order. if (isModule(procDef)) { // Go through the original symbol table and remove any parameter // symbols that originally existed SymbolTable* originalSymTab = procDef->get_symbol_table() ; Iter<SymbolTableObject*> originalIter = originalSymTab->get_symbol_table_object_iterator() ; while (originalIter.is_valid()) { SymbolTableObject* currentObj = originalIter.current() ; originalIter.next() ; if (dynamic_cast<ParameterSymbol*>(currentObj) != NULL) { originalSymTab->remove_symbol_table_object(currentObj) ; } } portsRemoved = true ; // Sort the variable symbols in parameter order. This is just an // insertion sort, so it could be done faster. list<VariableSymbol*> sortedPorts ; for (int i = 0 ; i < ports.size() ; ++i) { list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { BrickAnnote* orderAnnote = dynamic_cast<BrickAnnote*>((*portIter)-> lookup_annote_by_name("ParameterOrder")) ; if (orderAnnote == NULL) { ++portIter ; continue ; } IntegerBrick* orderBrick = dynamic_cast<IntegerBrick*>(orderAnnote->get_brick(0)) ; assert(orderBrick != NULL) ; if (orderBrick->get_value().c_int() == i) { sortedPorts.push_back(*portIter) ; break ; } ++portIter ; } } if (sortedPorts.size() != ports.size()) { OutputWarning("Warning! Analysis detected some input scalars not in" " the parameter list") ; } // Replace ports with sortedPorts ports = sortedPorts ; } list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { bitSize += (*portIter)->get_type()->get_base_type()->get_bit_size().c_int() ; LString dupeName = (*portIter)->get_name() ; // Create offset expression: IntConstant* offset = create_int_constant(theEnv, create_data_type(theEnv, IInteger(32), 0), IInteger(bitSize)) ; QualifiedType* dupeType = (*portIter)->get_type() ; // Deal with the case where reference types were passed in ReferenceType* refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; while (refType != NULL) { dupeType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(dupeType != NULL) ; refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; } // Create a new variable symbol clone FieldSymbol* dupe = create_field_symbol(theEnv, dupeType, offset, dupeName) ; structTable->append_symbol_table_object(dupe) ; // Make the connection with the duplicated symbol replacementFields[(*portIter)] = dupe ; // Remove the original variable symbol from the procedure definition // symbol table. if (!portsRemoved) { procDef->get_symbol_table()->remove_symbol_table_object(*portIter) ; } ++portIter ; } assert(bitSize != 0); StructType* moduleStruct = create_struct_type(theEnv, IInteger(bitSize), 0, // bit_alignment TempName(procDef->get_procedure_symbol()->get_name()), 0, // is_complete structTable) ; Iter<FileBlock*> fBlocks = theEnv->get_file_set_block()->get_file_block_iterator() ; assert(fBlocks.is_valid()) ; (fBlocks.current())->get_symbol_table()->append_symbol_table_object(moduleStruct) ; // This is commented out because it is in the file state block //procDef->get_symbol_table()->append_symbol_table_object(moduleStruct) ; QualifiedType* qualifiedModuleStruct = create_qualified_type(theEnv, moduleStruct, TempName(LString("qualifiedModuleStruct"))) ; procDef->get_symbol_table()->append_symbol_table_object(qualifiedModuleStruct) ; // Create an instance of this type and add it to the symbol table. ParameterSymbol* structInstance = create_parameter_symbol(theEnv, qualifiedModuleStruct, TempName(LString("structInstance"))) ; procDef->get_symbol_table()->append_symbol_table_object(structInstance) ; // Now, set up the procedure symbol to take the struct and return the // struct. assert(procDef != NULL) ; ProcedureSymbol* procSym = procDef->get_procedure_symbol() ; assert(procSym != NULL) ; ProcedureType* procType = procSym->get_type() ; assert(procType != NULL) ; CProcedureType* cProcType = dynamic_cast<CProcedureType*>(procType) ; assert(cProcType != NULL) ; // Instead of appending the struct argument, we need to replace all of the // arguments with the struct. while (cProcType->get_argument_count() > 0) { cProcType->remove_argument(0) ; } cProcType->set_result_type(moduleStruct) ; cProcType->append_argument(qualifiedModuleStruct) ; // Now go through all load variable expressions and replace them all with // field symbol values if appropriate list<LoadVariableExpression*>* allLoads = collect_objects<LoadVariableExpression>(procDef->get_body()) ; list<LoadVariableExpression*>::iterator loadIter = allLoads->begin() ; while (loadIter != allLoads->end()) { VariableSymbol* currentVariable = (*loadIter)->get_source() ; if (replacementFields.find(currentVariable) != replacementFields.end()) { (*loadIter)->set_source(replacementFields[currentVariable]) ; } ++loadIter ; } delete allLoads ; // Also replace all of the definitions with the field symbol list<StoreVariableStatement*>* allStoreVars = collect_objects<StoreVariableStatement>(procDef->get_body()) ; list<StoreVariableStatement*>::iterator storeVarIter = allStoreVars->begin(); while (storeVarIter != allStoreVars->end()) { VariableSymbol* currentDest = (*storeVarIter)->get_destination() ; if (replacementFields.find(currentDest) != replacementFields.end()) { (*storeVarIter)->set_destination(replacementFields[currentDest]) ; } ++storeVarIter ; } delete allStoreVars ; list<SymbolAddressExpression*>* allSymAddr = collect_objects<SymbolAddressExpression>(procDef->get_body()) ; list<SymbolAddressExpression*>::iterator symAddrIter = allSymAddr->begin() ; while (symAddrIter != allSymAddr->end()) { VariableSymbol* currentVar = dynamic_cast<VariableSymbol*>((*symAddrIter)->get_addressed_symbol()) ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*symAddrIter)->set_addressed_symbol(replacementFields[currentVar]) ; } ++symAddrIter ; } delete allSymAddr ; // One final for bool selects list<CallStatement*>* allCalls = collect_objects<CallStatement>(procDef->get_body()) ; list<CallStatement*>::iterator callIter = allCalls->begin() ; while(callIter != allCalls->end()) { VariableSymbol* currentVar = (*callIter)->get_destination() ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*callIter)->set_destination(replacementFields[currentVar]) ; } ++callIter ; } delete allCalls ; }
void CopyPropagationPass2::ProcessPossibleCopy(StoreVariableStatement* c) { assert(c != NULL) ; // If this isn't a straight copy, just return LoadVariableExpression* replacement = dynamic_cast<LoadVariableExpression*>(c->get_value()) ; if (replacement == NULL) { return ; } // If the variables are different types, don't propagate this away // (it is a cast) DataType* destType = c->get_destination()->get_type()->get_base_type() ; DataType* sourceType = replacement->get_source()->get_type()->get_base_type(); if (!EquivalentTypes(destType, sourceType)) { return ; } // Find all the reached uses BrickAnnote* reachedUses = to<BrickAnnote>(c->lookup_annote_by_name("reached_uses")) ; assert(reachedUses != NULL) ; // Just in case we have no reached uses, we don't want to do // dead code elimination in this pass as well... bool removable = false ; Iter<SuifBrick*> useIter = reachedUses->get_brick_iterator() ; // First verify that we are the only definition for all of our uses. // If we aren't then we can't make the replacement while(useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert (sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; if (IsOnlyDefinition(c, nextLoad) == false) { return ; } useIter.next() ; } // We also need to make sure that for each reached use, the copy is // not redefined. We do this by checking to make sure all of the // definitions associated with it in the kill map are identical. // This is a little conservative, but will make sure that no incorrect // code is created. // Get the bit vector associated with all the reaching definitions // coming into this statement BrickAnnote* inStatements = dynamic_cast<BrickAnnote*>(c->lookup_annote_by_name("in_stmts")) ; assert(inStatements != NULL) ; SuifBrick* inBrick = inStatements->get_brick(0) ; assert(inBrick != NULL) ; SuifObjectBrick* inSOB = dynamic_cast<SuifObjectBrick*>(inBrick) ; assert(inSOB != NULL) ; SuifObject* inObj = inSOB->get_object() ; assert(inObj != NULL) ; BitVector2* inBits = dynamic_cast<BitVector2*>(inObj) ; assert(inBits != NULL) ; VariableSymbol* replacementVariable = replacement->get_source() ; assert(replacementVariable != NULL) ; list<std::pair<Statement*, int> >* definitions =killMap[replacementVariable]; assert(definitions != NULL) ; list<bool> activeDefinitions ; list<std::pair<Statement*, int> >::iterator defIter = definitions->begin() ; while (defIter != definitions->end()) { activeDefinitions.push_back(inBits->isMarked((*defIter).second)) ; ++defIter ; } useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; SuifObject* loadParent = nextLoad->get_parent() ; while (dynamic_cast<Statement*>(loadParent) == NULL && loadParent != NULL) { loadParent = loadParent->get_parent() ; } assert(loadParent != NULL) ; Statement* parentStatement = dynamic_cast<Statement*>(loadParent) ; assert(parentStatement != NULL) ; BrickAnnote* parentInAnnote = dynamic_cast<BrickAnnote*> (parentStatement->lookup_annote_by_name("in_stmts")) ; assert(parentInAnnote != NULL) ; SuifBrick* parentInBrick = parentInAnnote->get_brick(0) ; assert(parentInBrick != NULL) ; SuifObjectBrick* parentInSOB = dynamic_cast<SuifObjectBrick*>(parentInBrick) ; assert(parentInSOB != NULL) ; SuifObject* parentInObj = parentInSOB->get_object() ; assert(parentInObj != NULL) ; BitVector2* parentInBits = dynamic_cast<BitVector2*>(parentInObj) ; assert(parentInBits != NULL) ; defIter = definitions->begin() ; list<bool>::iterator activeIter = activeDefinitions.begin() ; while (defIter != definitions->end()) { if ((*activeIter) != parentInBits->isMarked((*defIter).second)) { // They are different, so don't do the replacement. return ; } ++activeIter ; ++defIter ; } useIter.next() ; } // Now go through each reached use and replace it with the copy. // Each reached use should be a load variable expression. // We also have to deal with any feedback variables useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; // Keep track of if we need to handle feedback variables HandleFeedbackVariables(nextLoad, replacement->get_source()) ; nextLoad->set_source(replacement->get_source()) ; removable = true ; useIter.next() ; } if (removable) { toBeRemoved.push_back(c) ; } }