void Board::solve() { iterationsMax = 1; for( vector< Cell *>::iterator i = _board.begin(); i != _board.end(); ++i ) { set< uint8_t > p = (*i)->getPossibles(); iterationsMax *= p.size(); } cout << "Iterations MAX (overestimation): " << iterationsMax << endl; _optimize(); double iterationsMax1 = 1.; for( vector< Cell *>::iterator i = _board.begin(); i != _board.end(); ++i ) { iterationsMax1 *= (*i)->getPossibles().size(); } cout << "Iterations MAX after preoptimization (overestimation): " << iterationsMax1 << endl; // m_usingOptiBoard = _buildOptiboard(); startTime = time(0); if( m_usingOptiBoard ) { cout << "Using Optimized board" << endl; if( _solve( _optiBoard.begin() ) ) { cout << "Finish" << endl; } else { cout << "Failed" << endl; } } else { cout << "Using standard board" << endl; if( _solve( _board.begin() ) ) { cout << "Finish" << endl; } else { cout << "Failed" << endl; } } show(); }
std::unique_ptr<llvm::Module> JitCodeSpecializer::specialize_function( const std::string& root_function_name, const std::shared_ptr<const JitRuntimePointer>& runtime_this, const bool two_passes) { // The LLVMContext does not support concurrent access, so we only allow one specialization operation at a time for // each JitRepository (each bitcode repository has its own LLVMContext). std::lock_guard<std::mutex> lock(_repository.specialization_mutex()); // Initialize specialization context with the function name and an empty module SpecializationContext context; context.root_function_name = root_function_name; context.module = std::make_unique<llvm::Module>(root_function_name, *_llvm_context); context.module->setDataLayout(_compiler.data_layout()); // Locate and clone the root function from the bitcode repository const auto root_function = _repository.get_function(root_function_name); Assert(root_function, "Root function not found in repository."); context.root_function = _clone_root_function(context, *root_function); // The code specialization can run one or two specialization passes depending on its configuration. // For most simple operator pipelines, a single specialization pass should be sufficient. However, more complex // operators such as JitAggregate contain a number of loops. Properly specializing these loops requires a four-step // process: // - a specialization pass (that replaces the loop condition with a constant value) // - an optimization that includes loop unrolling // - a second specialization pass that can now specialize the unrolled loop bodies // - a final optimization pass // Run the first specialization and optimization pass context.runtime_value_map[context.root_function->arg_begin()] = runtime_this; _inline_function_calls(context); _perform_load_substitution(context); // Unroll loops only if two passes are selected _optimize(context, two_passes); // Conditionally run a second pass if (two_passes) { context.runtime_value_map.clear(); context.runtime_value_map[context.root_function->arg_begin()] = runtime_this; _inline_function_calls(context); _perform_load_substitution(context); _optimize(context, false); } return std::move(context.module); }
Filter* optimize(Filter *f) { do{ changed = 0; f = _optimize(f); }while(changed); return f; }
/** Service **/ void CommandService::on_update(const int64_t now) { Super::on_update(now); if(now - m_process_timeout_last_time >= PROCESS_TIMEOUT_TIMER) { m_process_timeout_last_time =now; _process_timeout(now); } if(now - m_optimize_last_time >= OPTIMIZE_TIMER) { m_optimize_last_time =now; _optimize(now); } }
static Filter* _optimize(Filter *f) { Filter *l; if(f == nil) return f; switch(f->op){ case '!': /* is child also a not */ if(f->l->op == '!'){ changed = 1; return f->l->l; } break; case LOR: /* are two children the same protocol? */ if(f->l->op != f->r->op || f->r->op != WORD || f->l->pr != f->r->pr || f->l->pr == nil) break; /* no optimization */ changed = 1; /* constant folding */ /* if either child is childless, just return that */ if(f->l->l == nil) return f->l; else if(f->r->l == nil) return f->r; /* move the common node up, thow away one node */ l = f->l; f->l = l->l; f->r = f->r->l; l->l = f; return l; case LAND: /* are two children the same protocol? */ if(f->l->op != f->r->op || f->r->op != WORD || f->l->pr != f->r->pr || f->l->pr == nil) break; /* no optimization */ changed = 1; /* constant folding */ /* if either child is childless, ignore it */ if(f->l->l == nil) return f->r; else if(f->r->l == nil) return f->l; /* move the common node up, thow away one node */ l = f->l; f->l = _optimize(l->l); f->r = _optimize(f->r->l); l->l = f; return l; } f->l = _optimize(f->l); f->r = _optimize(f->r); return f; }