static void dump_var_mapping(const GoughGraph &g, const string &base, const Grey &grey) { stringstream ss; ss << grey.dumpPath << "gough_" << base << "_vars.txt"; FILE *f = fopen(ss.str().c_str(), "w"); for (auto v : vertices_range(g)) { set<const GoughSSAVar *> used = uses(g[v]); if (g[v].vars.empty() && used.empty()) { continue; } fprintf(f, "%s\n", dump_name(g[v]).c_str()); for (u32 i = 0; i < g[v].vars.size(); i++) { const GoughSSAVar *vp = g[v].vars[i].get(); fprintf(f, "\t%u: slot %u\n", i, vp->slot); } if (!used.empty()) { fprintf(f, "\tuses:"); vector<u32> used_id; for (const GoughSSAVar *var : used) { used_id.push_back(var->slot); } for (const u32 &id : used_id) { fprintf(f, " %u", id); } fprintf(f, "\n"); } } for (const auto &e : edges_range(g)) { set<const GoughSSAVar *> used = uses(g[e]); if (g[e].vars.empty() && used.empty()) { continue; } fprintf(f, "%s\n", dump_name(g, e).c_str()); for (u32 i = 0; i < g[e].vars.size(); i++) { const GoughSSAVar *vp = g[e].vars[i].get(); fprintf(f, "\t%u: slot %u\n", i, vp->slot); } if (!used.empty()) { fprintf(f, "\tuses:"); vector<u32> used_id; for (const GoughSSAVar *var : used) { used_id.push_back(var->slot); } for (const u32 &id : used_id) { fprintf(f, " %u", id); } fprintf(f, "\n"); } } fclose(f); }
static Symbol spillee(Symbol set, unsigned mask[], Node here) { Symbol bestreg = NULL; int bestdist = -1, i; assert(set); if (!set->x.wildcard) bestreg = set; else { for (i = 31; i >= 0; i--) { Symbol ri = set->x.wildcard[i]; if ( ri != NULL && ri->x.lastuse && (ri->x.regnode->mask&tmask[ri->x.regnode->set]&mask[ri->x.regnode->set]) ) { Regnode rn = ri->x.regnode; Node q = here; int dist = 0; for (; q && !uses(q, rn); q = q->x.next) dist++; if (q && dist > bestdist) { bestdist = dist; bestreg = ri; } } } } assert(bestreg); /* Must be able to spill something. Reconfigure the register allocator to ensure that we can allocate a register for all nodes without spilling the node's necessary input regs. */ assert(bestreg->x.regnode->vbl == NULL); /* Can't spill register variables because the reload site might be in other blocks. Reconfigure the register allocator to ensure that this register is never allocated to a variable. */ return bestreg; }
/*** Função que confere a parte de declarações ***/ int declaracoes() { if(nome()) { if(uses()) { if(constantes()) { if(variaveis()) { if(procedimentos()) { return 1; } else return 0; } else return 0; } else return 0; } else return 0; } else return 0; }
bool Decompressor::decompress(const CompressorResult& input, void* const out, uint64_t pvpOut[4], const uint64_t flags) { LBASSERT(uses(input.compressor)); LBASSERT(!input.chunks.empty()); if (!uses(input.compressor) || input.chunks.empty()) return false; const size_t num = input.chunks.size(); const void** in = static_cast<const void**>(alloca(num * sizeof(void*))); uint64_t* inSizes = static_cast<uint64_t*>(alloca(num * sizeof(uint64_t))); for (size_t i = 0; i < num; ++i) { in[i] = input.chunks[i].data; inSizes[i] = input.chunks[i].getNumBytes(); } impl_->plugin->decompress(impl_->instance, impl_->info.name, in, inSizes, unsigned(num), out, pvpOut, flags); return true; }
void fuseConsecutiveTransposes(std::shared_ptr<Graph>& graph) { for(auto n : graph->nodes()) { if (n->kind() == kTranspose && n->input()->node()->kind() == kTranspose) { auto origInput = n->input(); n->is_(kperm, composeTransposes(origInput->node()->is(kperm), n->is(kperm))); n->replaceInput(0, origInput->node()->input()); if (origInput->uses().size() == 0) { origInput->node()->destroy(); } continue; } } }
/* * Branch fusion: * Analyze blocks one at a time, looking for the sequence: * * setcc cc, f1 => b * ... * testb b, b => f2 * ... * jcc E|NE, f2 * * If found, and f2 is only used by the jcc, then change the code to: * * setcc cc, f1 => b * ... * nop * ... * jcc !cc|cc, f1 * * Later, vasm-dead will clean up the nop, and the setcc if b became dead. * * During the search, any other instruction that has a status flag result * will reset the pattern matcher. No instruction can "kill" flags, * since flags are SSA variables. However the transformation we want to * make extends the setcc flags lifetime, and we don't want it to overlap * another flag's lifetime. */ void fuseBranches(Vunit& unit) { auto blocks = sortBlocks(unit); jit::vector<unsigned> uses(unit.next_vr); for (auto b : blocks) { for (auto& inst : unit.blocks[b].code) { visitUses(unit, inst, [&](Vreg r) { uses[r]++; }); } } bool should_print = false; for (auto b : blocks) { auto& code = unit.blocks[b].code; ConditionCode cc; Vreg setcc_flags, setcc_dest, testb_flags; unsigned testb_index; for (unsigned i = 0, n = code.size(); i < n; ++i) { if (code[i].op == Vinstr::setcc) { cc = code[i].setcc_.cc; setcc_flags = code[i].setcc_.sf; setcc_dest = code[i].setcc_.d; continue; } if (setcc_flags.isValid() && match_testb(code[i], setcc_dest) && uses[code[i].testb_.sf] == 1) { testb_flags = code[i].testb_.sf; testb_index = i; continue; } if (match_jcc(code[i], testb_flags)) { code[testb_index] = nop{}; // erase the testb auto& jcc = code[i].jcc_; jcc.cc = jcc.cc == CC_NE ? cc : ccNegate(cc); jcc.sf = setcc_flags; should_print = true; continue; } if (setcc_flags.isValid() && sets_flags(code[i])) { setcc_flags = testb_flags = Vreg{}; } } } if (should_print) { printUnit(kVasmFusionLevel, "after vasm-fusion", unit); } }
static void rewrite_def(const Def* def, Rewriter& rewriter) { if (rewriter.old2new.count(def) || def->isa_continuation()) return; for (auto op : def->ops()) rewrite_def(op, rewriter); auto new_type = rewrite_type(def->world(), def->type()); if (new_type != def->type()) { auto primop = def->as<PrimOp>(); Array<const Def*> ops(def->num_ops()); for (size_t i = 0; i < def->num_ops(); ++i) ops[i] = rewriter.instantiate(def->op(i)); rewriter.old2new[primop] = primop->rebuild(ops, new_type); for (auto use : primop->uses()) rewrite_def(use.def(), rewriter); } else { rewriter.instantiate(def); } }
void fuseTransposeIntoGemm(std::shared_ptr<Graph>& graph) { static const std::vector<int64_t> simpleTransPerm({1,0}); for(auto n : graph->nodes()) { if (n->kind() == kGemm) { for (size_t i : {0,1}) { auto inp = n->inputs()[i]; auto trans = i == 0 ? ktransA : ktransB; if (inp->node()->kind() == kTranspose && inp->node()->is(kperm) == simpleTransPerm) { n->replaceInput(i, inp->node()->input()); n->i_(trans, n->hasAttribute(trans) ? !n->i(trans) : 1); if (inp->uses().size() == 0) { inp->node()->destroy(); } } } } } }
PeepHoleOpt::Changed PeepHoleOpt::handleInst_CMP(Inst* inst) { assert(inst->getMnemonic()==Mnemonic_CMP); Inst::Opnds uses(inst, Inst::OpndRole_Explicit | Inst::OpndRole_Use); Opnd* src1 = inst->getOpnd(uses.begin()); Opnd* src2 = inst->getOpnd(uses.next(uses.begin())); assert(src1!=NULL && src2!=NULL); if (isImm(src1)) { Opnd* tmp = src1; src1 = src2; src2 = tmp; } if (isImm(src2) && isReg(src1) && (int)src2->getImmValue() == 0) { if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> CMP with 0"<<std::endl; irManager->newInst(Mnemonic_TEST, src1, src1)->insertAfter(inst); inst->unlink(); return Changed_Inst; } return Changed_Nothing; }
char* ConnectionManager_impl::connect(const CF::ConnectionManager::EndpointRequest& usesEndpoint, const CF::ConnectionManager::EndpointRequest& providesEndpoint, const char* requesterId, const char* connectionId) { // If no connection ID was given, generate one std::string _connectionId = connectionId; if (_connectionId.empty()) { _connectionId = ossie::generateUUID(); } std::auto_ptr<ossie::Endpoint> uses(requestToEndpoint(usesEndpoint)); std::auto_ptr<ossie::Endpoint> provides(requestToEndpoint(providesEndpoint)); ossie::ConnectionNode connection(uses.release(), provides.release(), _connectionId, requesterId, ""); try { connection.connect(_domainManager->_connectionManager); } catch (ossie::InvalidConnection &e){ std::ostringstream err; err << "Unable to create a connection: "<<e.what(); throw (CF::Port::InvalidPort(1, err.str().c_str())); } std::string connectionRecordId = _domainManager->_connectionManager.restoreConnection(requesterId, connection); return CORBA::string_dup(connectionRecordId.c_str()); }
static void douser(int fd, struct fs *super, char *name) { ino_t inode, maxino; struct user *usr, *usrs; union dinode *dp; int n; maxino = super->fs_ncg * super->fs_ipg - 1; for (inode = 0; inode < maxino; inode++) { errno = 0; if ((dp = get_inode(fd,super,inode)) && !isfree(super, dp)) uses(DIP(super, dp, di_uid), estimate ? virtualblocks(super, dp) : actualblocks(super, dp), DIP(super, dp, di_atime)); else if (errno) { err(1, "%s", name); } } if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) errx(1, "allocate users"); bcopy(users,usrs,nusers * sizeof(struct user)); sortusers(usrs); for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { printf("%5d",SIZE(usr->space)); if (count) printf("\t%5ld",usr->count); printf("\t%-8s",usr->name); if (unused) printf("\t%5d\t%5d\t%5d", SIZE(usr->spc30), SIZE(usr->spc60), SIZE(usr->spc90)); printf("\n"); } free(usrs); }
void User::dropAllReferences() { for (auto &U : uses()) U.set(nullptr); }
// Note that, when parsing file names and arguments, paths are interpreted // to be relative to the applications working directory. void parser::parse_dag (void) { dag_ = boost::shared_ptr <dag> (new dag (scheduler_file_)); std::cout << "parsing " << dag_file_ << std::endl; try { ticpp::Document doc (dag_file_); doc.LoadFile (); // get the top adag element ticpp::Element * adag = doc.FirstChildElement ("adag"); // list nodes ticpp::Iterator <ticpp::Element> job ("job"); // we parse jobs twice. On the first run, we add all nodes. On the // second run, we add all edges (connected nodes are known now). for ( job = job.begin (adag); job != job.end (); job++ ) { node_description nd; std::string s_id = job->GetAttribute ("id"); std::string s_name = job->GetAttribute ("name"); nd.set_attribute ("Executable", s_name); // get args ticpp::Element * args = job->FirstChildElement ("argument"); if ( args ) { // iterate over args, if we have them ticpp::Iterator <ticpp::Node> arg; std::vector <std::string> s_args; for ( arg = arg.begin (args); arg != arg.end (); arg++ ) { if ( arg->Type () == TiXmlNode::ELEMENT ) { ticpp::Element * elem = arg->ToElement (); std::string s_file = elem->GetAttribute ("file"); s_args.push_back (s_file); } else if ( arg->Type () == TiXmlNode::TEXT ) { std::stringstream ss; ss << *arg; std::string tmp = ss.str (); if ( tmp.size () ) { std::vector <std::string> s_tmp = split (tmp); for ( unsigned int j = 0; j < s_tmp.size (); j++ ) { if ( s_tmp [j] == "." ) { s_args.push_back (s_tmp[j]); } else { s_args.push_back (s_tmp[j]); } } } } } nd.set_vector_attribute ("Arguments", s_args); } boost::shared_ptr <node> n = dag_->create_node (nd, s_id); dag_->add_node (s_id, n); } // second run: we have input and output files specified for each jobs. // Find pairs, and add as edges std::vector <std::pair <std::string, std::string> > inputs; std::vector <std::pair <std::string, std::string> > outputs; for ( job = job.begin (adag); job != job.end (); job++ ) { std::string s_id = job->GetAttribute ("id"); std::string s_name = job->GetAttribute ("name"); ticpp::Iterator <ticpp::Element> uses ("uses"); for ( uses = uses.begin (job.Get ()); uses != uses.end (); uses++ ) { std::string s_file = uses->GetAttribute ("file"); std::string s_link = uses->GetAttribute ("link"); std::string s_transfer = uses->GetAttribute ("transfer"); if ( s_link == "input" ) { inputs.push_back (std::pair <std::string, std::string> (s_file, s_id)); } else if ( s_link == "output" ) { outputs.push_back (std::pair <std::string, std::string> (s_file, s_id)); } else { std::cerr << "cannot handle link type " << s_link << std::endl; } } } // iterate over inputs, and find outputs which produce them. inputs not // produced by some outputting node are assumed to be staged in from // a data src (INPUT). Also, data which are produced but not consumed // by another node are to be staged to an data sink (OUTPUT). In both // cases, we simply add edges with empty src/tgt nodes, and leave it to // the scheduler to interprete that correctly. // first, iterate over inputs, and add edges for those inputs which are // produced by another node, and also for those which need to be staged // in. for ( unsigned int i = 0; i < inputs.size (); i++ ) { std::string file = inputs[i].first; std::string i_node = inputs[i].second; std::string o_node = ""; // std::cout << " --- checking inputs: " << file << std::endl; // for each input file, find output node for ( unsigned int j = 0; j < outputs.size (); j++ ) { if ( outputs[j].first == file ) { o_node = outputs[j].second; // stop loop j = inputs.size (); } } if ( o_node == "" ) { // std::cout << " --- needs to be staged to node " << i_node << std::endl; saga::url loc (file); loc.set_scheme ("any"); boost::shared_ptr <edge> e = dag_->create_edge (loc); // std::cout << " e 1 " << file << " : " << "INPUT->" << o_node << std::endl; dag_->add_edge (e, "INPUT", i_node); } else if ( o_node != i_node ) { saga::url loc (file); loc.set_scheme ("any"); boost::shared_ptr <edge> e = dag_->create_edge (loc); // std::cout << " e 3: " << file << " : " << o_node << "->" << i_node << std::endl; dag_->add_edge (e, o_node, i_node); } } // inputs have been iterated above - now iterate over outputs, and look // for remaining ones which do not have a partner. for ( unsigned int k = 0; k < outputs.size (); k++ ) { std::string file = outputs[k].first; std::string i_node = ""; std::string o_node = outputs[k].second; // for each output node, find the input node for ( unsigned int l = 0; l < inputs.size (); l++ ) { if ( inputs[l].first == file ) { i_node = inputs[l].second; // stop loop l = inputs.size (); } } if ( i_node == "" ) { // will stage data out to data sink saga::url loc (file); loc.set_scheme ("any"); boost::shared_ptr <edge> e = dag_->create_edge (loc); // std::cout << " e 1 " << file << " : " << o_node << "-> OUTPUT " << std::endl; dag_->add_edge (e, o_node, "OUTPUT"); } } } catch ( const ticpp::Exception & e ) { std::cout << e.what () << std::endl; } std::cout << "parsing " << dag_file_ << " done" << std::endl; }
OBJECT InsertSym(FULL_CHAR *str, unsigned char xtype, FILE_POS *xfpos, unsigned char xprecedence, BOOLEAN xindefinite, BOOLEAN xrecursive, unsigned xpredefined, OBJECT xenclosing, OBJECT xbody) { register int sum, rlen; register unsigned char *x; OBJECT p, q, s, tmp, link, entry, plink; int len; debug3(DST, DD, "InsertSym( %s, %s, in %s )", Image(xtype), str, SymName(xenclosing)); if( !LexLegalName(str) ) Error(29, 3, "invalid symbol name %s", WARN, xfpos, str); New(s, xtype); FposCopy(fpos(s), *xfpos); has_body(s) = FALSE; filter(s) = nilobj; use_invocation(s) = nilobj; imports(s) = nilobj; imports_encl(s) = FALSE; right_assoc(s) = TRUE; precedence(s) = xprecedence; indefinite(s) = xindefinite; recursive(s) = xrecursive; predefined(s) = xpredefined; enclosing(s) = xenclosing; sym_body(s) = xbody; base_uses(s) = nilobj; uses(s) = nilobj; marker(s) = nilobj; cross_sym(s) = nilobj; is_extern_target(s) = FALSE; uses_extern_target(s)= FALSE; visible(s) = FALSE; uses_galley(s) = FALSE; horiz_galley(s) = ROWM; has_compulsory(s) = 0; is_compulsory(s) = FALSE; uses_count(s) = 0; dirty(s) = FALSE; if( enclosing(s) != nilobj && type(enclosing(s)) == NPAR ) dirty(s) = dirty(enclosing(s)) = TRUE; has_par(s) = FALSE; has_lpar(s) = FALSE; has_rpar(s) = FALSE; if( is_par(type(s)) ) has_par(enclosing(s)) = TRUE; if( type(s) == LPAR ) has_lpar(enclosing(s)) = TRUE; if( type(s) == RPAR ) has_rpar(enclosing(s)) = TRUE; /* assign a code letter between a and z to any NPAR symbol */ if( type(s) == NPAR ) { if( LastDown(enclosing(s)) != enclosing(s) ) { Child(tmp, LastDown(enclosing(s))); if( type(tmp) == NPAR ) { if( npar_code(tmp) == 'z' || npar_code(tmp) == ' ' ) npar_code(s) = ' '; else npar_code(s) = npar_code(tmp)+1; } else npar_code(s) = 'a'; } else npar_code(s) = 'a'; } has_target(s) = FALSE; force_target(s) = FALSE; if( !StringEqual(str, KW_TARGET) ) is_target(s) = FALSE; else { is_target(s) = has_target(enclosing(s)) = TRUE; /* if @Target is found after @Key, take note of external target */ if( has_key(enclosing(s)) && xbody != nilobj && is_cross(type(xbody)) ) { if( LastDown(xbody) != Down(xbody) ) { OBJECT sym; Child(sym, Down(xbody)); if( type(sym) == CLOSURE ) { is_extern_target(actual(sym)) = TRUE; uses_extern_target(actual(sym)) = TRUE; } } } } has_tag(s) = is_tag(s) = FALSE; has_key(s) = is_key(s) = FALSE; has_optimize(s) = is_optimize(s) = FALSE; has_merge(s) = is_merge(s) = FALSE; has_enclose(s) = is_enclose(s) = FALSE; if( enclosing(s) != nilobj && type(enclosing(s)) == LOCAL ) { if( StringEqual(str, KW_TAG) ) is_tag(s) = has_tag(enclosing(s)) = dirty(enclosing(s)) = TRUE; if( StringEqual(str, KW_OPTIMIZE) ) is_optimize(s) = has_optimize(enclosing(s)) = TRUE; if( StringEqual(str, KW_KEY) ) { is_key(s) = has_key(enclosing(s)) = dirty(enclosing(s)) = TRUE; /* if @Key is found after @Target, take note of external target */ for( link=Down(enclosing(s)); link!=enclosing(s); link=NextDown(link) ) { Child(p, link); if( is_target(p) && sym_body(p)!=nilobj && is_cross(type(sym_body(p))) ) { OBJECT sym; Child(sym, Down(sym_body(p))); if( type(sym) == CLOSURE ) { is_extern_target(actual(sym)) = TRUE; uses_extern_target(actual(sym)) = TRUE; } } } } if( StringEqual(str, KW_MERGE) ) is_merge(s) = has_merge(enclosing(s)) = TRUE; if( StringEqual(str, KW_ENCLOSE) ) is_enclose(s) = has_enclose(enclosing(s)) = TRUE; } if( StringEqual(str, KW_FILTER) ) { if( type(s) != LOCAL || enclosing(s) == StartSym ) Error(29, 4, "%s must be a local definition", WARN, &fpos(s), str); else if( !has_rpar(enclosing(s)) ) Error(29, 14, "%s must lie within a symbol with a right parameter", WARN, &fpos(s), KW_FILTER); else { filter(enclosing(s)) = s; precedence(enclosing(s)) = FILTER_PREC; } } if( type(s) == RPAR && has_body(enclosing(s)) && (is_tag(s) || is_key(s) || is_optimize(s)) ) Error(29, 5, "a body parameter may not be named %s", WARN, &fpos(s), str); if( type(s) == RPAR && has_target(enclosing(s)) && (is_tag(s) || is_key(s) || is_optimize(s)) ) Error(29, 6, "the right parameter of a galley may not be called %s", WARN, &fpos(s), str); len = StringLength(str); hash(str, len, sum); ifdebug(DST, D, sym_spread[sum]++; sym_count++); entry = (OBJECT) &symtab[sum]; for( plink = Down(entry); plink != entry; plink = NextDown(plink) ) { Child(p, plink); if( length(p) == len && StringEqual(str, string(p)) ) { for( link = Down(p); link != p; link = NextDown(link) ) { Child(q, link); if( enclosing(s) == enclosing(q) ) { Error(29, 7, "symbol %s previously defined at%s", WARN, &fpos(s), str, EchoFilePos(&fpos(q)) ); if( AltErrorFormat ) { Error(29, 13, "symbol %s previously defined here", WARN, &fpos(q), str); } break; } } goto wrapup; } } /* need a new OBJECT as well as s */ NewWord(p, WORD, len, xfpos); length(p) = len; StringCopy(string(p), str); Link(entry, p); wrapup: Link(p, s); if( enclosing(s) != nilobj ) Link(enclosing(s), s); debug2(DST, DD, "InsertSym Link(%s, %s) and returning.", SymName(enclosing(s)), SymName(s)); return s; } /* end InsertSym */
PeepHoleOpt::Changed PeepHoleOpt::handleInst_MUL(Inst* inst) { assert((inst->getMnemonic() == Mnemonic_IMUL) || (inst->getMnemonic() == Mnemonic_MUL)); if (inst->getForm() == Inst::Form_Native) { return Changed_Nothing; } Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); Opnd* dst1 = inst->getOpnd(defs.begin()); Opnd* dst2 = NULL; if ((inst->getMnemonic() == Mnemonic_IMUL) && (defs.next(defs.begin()) != defs.end())){ return Changed_Nothing; } else { //inst->getMnemonic() == Mnemonic_MUL dst2 = inst->getOpnd(defs.next(defs.begin())); if (defs.next(defs.next(defs.begin()))!=defs.end()) return Changed_Nothing; } Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Opnd* src1= inst->getOpnd(uses.begin()); Opnd* src2= inst->getOpnd(uses.next(uses.begin())); if (inst->getMnemonic() == Mnemonic_IMUL) assert(src1!=NULL && src2!=NULL && dst1!=NULL); else //inst->getMnemonic() == Mnemonic_MUL assert(src1!=NULL && src2!=NULL && dst1!=NULL && dst2!=NULL); if (isImm(src1)) { Opnd* tmp = src1; src1 = src2; src2 = tmp; } if (isImm(src2) && irManager->getTypeSize(src2->getType()) <=32) { int immVal = (int)src2->getImmValue(); if (immVal == 0) { if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 0"<<std::endl; if (inst->getMnemonic() == Mnemonic_IMUL) { irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src2)->insertAfter(inst); } else { //inst->getMnemonic() == Mnemonic_MUL irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src2)->insertAfter(inst); irManager->newCopyPseudoInst(Mnemonic_MOV, dst2, src2)->insertAfter(inst); } inst->unlink(); return Changed_Inst; } else if (immVal == 1) { if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 1"<<std::endl; if (inst->getMnemonic() == Mnemonic_IMUL) { irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src1)->insertAfter(inst); } else { //inst->getMnemonic() == Mnemonic_MUL Opnd* zero = irManager->newImmOpnd(dst1->getType(), 0); irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, zero)->insertAfter(inst); irManager->newCopyPseudoInst(Mnemonic_MOV, dst2, src1)->insertAfter(inst); } inst->unlink(); return Changed_Inst; } else if (immVal == 2) { if (inst->getMnemonic() == Mnemonic_IMUL) { if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 2"<<std::endl; irManager->newInstEx(Mnemonic_ADD, 1, dst1, src1, src1)->insertAfter(inst); inst->unlink(); return Changed_Inst; } } else { if (inst->getMnemonic() == Mnemonic_IMUL) { int minBit=getMinBit(immVal); int maxBit=getMaxBit(immVal); if (minBit == maxBit) { assert(minBit>=2); if (Log::isEnabled()) Log::out()<<"I"<<inst->getId()<<" -> MUL with 2^"<<minBit<<std::endl; Type* immType = irManager->getTypeManager().getUInt8Type(); irManager->newCopyPseudoInst(Mnemonic_MOV, dst1, src1)->insertBefore(inst); irManager->newInst(Mnemonic_SHL, dst1, irManager->newImmOpnd(immType, minBit))->insertBefore(inst); inst->unlink(); return Changed_Inst; } } } } return Changed_Nothing; }
void CCDReader4qxml::ports (DOMElement* element) throw(CCDReadException) { DOMNode* child = element->getFirstChild(); while (child != 0) { if (child->getNodeType() == DOMNode::ELEMENT_NODE) { // // source // if (!XMLString::compareString(child->getNodeName(), X("source"))) { source((DOMElement*)child); } // // sink // else if (!XMLString::compareString(child->getNodeName(), X("sink"))) { sink( (DOMElement*) child); } // // uses // else if (!XMLString::compareString(child->getNodeName(), X("uses"))) { uses( (DOMElement*) child); } // // provides // else if (!XMLString::compareString(child->getNodeName(), X("provides"))) { provides( (DOMElement*) child); } // // emits // else if (!XMLString::compareString(child->getNodeName(), X("emits"))) { emits( (DOMElement*) child); } // // publishes // else if (!XMLString::compareString(child->getNodeName(), X("publishes"))) { publishes( (DOMElement*) child); } // // consumes // else if (!XMLString::compareString(child->getNodeName(), X("consumes"))) { consumes( (DOMElement*) child); } } // get next child child = child->getNextSibling(); } }
/** * The algorithm finds conditional instruction (=condInst) first, then * corresponding CMP instruction (=cmpInst) and arithmetic instruction (=inst) * which affects flags in the same way as CMP. Combination is considered as * available to be reduced if there are no instructions between CMP and * arithmetic instruction which influence to flags or CMP operands. * * Also it transforms some conditional instruction to make them more suitable * for optimizations */ void RCE::runImpl() { Inst * inst, * cmpInst, *condInst; Opnd * cmpOp = NULL; cmpInst = condInst = NULL; const Nodes& nodes = irManager->getFlowGraph()->getNodesPostOrder(); for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; if (node->isBlockNode()) { if(node->isEmpty()) { continue; } cmpInst = NULL; Inst* prevInst = NULL; for(inst = (Inst*)node->getLastInst(); inst != NULL; inst = prevInst) { prevInst = inst->getPrevInst(); //find conditional instruction Mnemonic baseMnem = getBaseConditionMnemonic(inst->getMnemonic()); if (baseMnem != Mnemonic_NULL) { condInst = condInst ? NULL : inst; cmpInst = NULL; } else if (condInst) { //find CMP instruction corresponds to conditional instruction if(inst->getMnemonic() == Mnemonic_CMP || inst->getMnemonic() == Mnemonic_UCOMISD || inst->getMnemonic() == Mnemonic_UCOMISS) { if (cmpInst) { //this comparison is redundant because of overrided by cmpInst inst->unlink(); continue; } cmpInst = inst; U_32 defCount = inst->getOpndCount(Inst::OpndRole_InstLevel|Inst::OpndRole_Def); if(inst->getOpnd(defCount+1)->isPlacedIn(OpndKind_Imm)) { //try to change conditional instruction to make combination available to optimize cmpOp = inst->getOpnd(defCount); Inst * newCondInst = NULL; Mnemonic mnem; int64 val = inst->getOpnd(defCount+1)->getImmValue(); if (val == 0) { continue; } else if (val == 1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_L){ mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_L)) + Mnemonic(ConditionMnemonic_LE)); } else if (val == -1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_G) { mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_G)) + Mnemonic(ConditionMnemonic_GE)); } else if (val == -1 && ConditionMnemonic(condInst->getMnemonic()-getBaseConditionMnemonic(condInst->getMnemonic())) == ConditionMnemonic_B) { mnem = Mnemonic((condInst->getMnemonic() - Mnemonic(ConditionMnemonic_B)) + Mnemonic(ConditionMnemonic_BE)); } else { continue; } //replace old conditional instruction if (condInst->hasKind(Inst::Kind_BranchInst)) { BranchInst* br = (BranchInst*)condInst; newCondInst = irManager->newBranchInst(mnem,br->getTrueTarget(), br->getFalseTarget(), condInst->getOpnd(0)); } else { Mnemonic condMnem = getBaseConditionMnemonic(condInst->getMnemonic()); Inst::Opnds defs(condInst,Inst::OpndRole_Def|Inst::OpndRole_Explicit); if (condMnem == Mnemonic_CMOVcc) { Inst::Opnds uses(condInst,Inst::OpndRole_Use|Inst::OpndRole_Explicit); newCondInst = irManager->newInst(mnem, condInst->getOpnd(defs.begin()), inst->getOpnd(uses.begin())); } else if (condMnem == Mnemonic_SETcc) { newCondInst = irManager->newInst(mnem, condInst->getOpnd(defs.begin())); } else { assert(0); continue; } } newCondInst->insertAfter(condInst); condInst->unlink(); condInst = newCondInst; inst->setOpnd(defCount+1, irManager->newImmOpnd(inst->getOpnd(defCount+1)->getType(),0)); } //find flags affected instruction precedes cmpInst } else if (instAffectsFlagsAsCmpInst(inst, condInst)) { if (cmpInst) { if (isSuitableToRemove(inst, condInst, cmpInst, cmpOp)) { cmpInst->unlink(); } } condInst = NULL; // do not optimize cmpInst any more in this block } else { if (inst->getOpndCount(Inst::OpndRole_Implicit|Inst::OpndRole_Def) || inst->getMnemonic() == Mnemonic_CALL) { // instruction affects flags, skip optimizing cmpInst condInst = NULL; } else { //check for moving cmpInst operands if ((inst->getMnemonic() == Mnemonic_MOV) && (inst->getOpnd(0) == cmpOp)) { cmpOp = inst->getOpnd(1); } } } }//end if/else by condInst }//end for() by Insts }//end if BasicBlock }//end for() by Nodes }
PeepHoleOpt::Changed PeepHoleOpt::handleInst_ALU(Inst* inst) { // The normal form is 'OPERATION left opnd, right operand' // except for NOT operation. const Mnemonic mnemonic = inst->getMnemonic(); if (mnemonic == Mnemonic_NOT) { // No optimizations this time return Changed_Nothing; } // Only these mnemonics have the majestic name of ALUs. assert(mnemonic == Mnemonic_ADD || mnemonic == Mnemonic_SUB || mnemonic == Mnemonic_ADC || mnemonic == Mnemonic_SBB || mnemonic == Mnemonic_OR || mnemonic == Mnemonic_XOR || mnemonic == Mnemonic_AND || mnemonic == Mnemonic_CMP || mnemonic == Mnemonic_TEST); if (mnemonic == Mnemonic_AND) { Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); Opnd* dst = inst->getOpnd(defs.begin()); Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Opnd* src1= inst->getOpnd(uses.begin()); Opnd* src2= inst->getOpnd(uses.next(uses.begin())); Opnd *newopnd2; // test can work only with operands having equal sizes if (isImm(src2) && src2->getSize() != src1->getSize()) newopnd2 = irManager->newImmOpnd(src1->getType(), src2->getImmValue()); else newopnd2 = src2; if (!isMem(dst) && !isMem(src1) && !isMem(src2)) { BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount()); irManager->updateLivenessInfo(); irManager->getLiveAtExit(inst->getNode(), ls); for (Inst* i = (Inst*)inst->getNode()->getLastInst(); i!=inst; i = i->getPrevInst()) { irManager->updateLiveness(i, ls); } bool dstNotUsed = !ls.getBit(dst->getId()); if (dstNotUsed) { // what: AND opnd1, opnd2 => TEST opnd1, opnd2 // nb: applicable if opnd1 will not be used further if (inst->getForm() == Inst::Form_Extended) irManager->newInstEx(Mnemonic_TEST, 0, src1, newopnd2)->insertAfter(inst); else irManager->newInst(Mnemonic_TEST, src1, newopnd2)->insertAfter(inst); inst->unlink(); return Changed_Inst; } } } else if (mnemonic == Mnemonic_ADD) { /* Change "dst=src+0" to "MOV dst, src" if there is another ADD inst followed in the same BB. */ Inst::Opnds defs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); Opnd* dst = inst->getOpnd(defs.begin()); Inst::Opnds uses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Opnd* src1= inst->getOpnd(uses.begin()); Opnd* src2= inst->getOpnd(uses.next(uses.begin())); bool src1IsZero = false; bool src2IsZero = false; if (src1->isPlacedIn(OpndKind_Imm) && (src1->getImmValue() == 0)) src1IsZero = true; if (src2->isPlacedIn(OpndKind_Imm) && (src2->getImmValue() == 0)) src2IsZero = true; bool anotherADD = false; Inst *iter = inst->getNextInst(); while (iter != NULL) { if (iter->getMnemonic() == Mnemonic_ADC) break; if (iter->getMnemonic() == Mnemonic_ADD) { anotherADD = true; break; } iter = iter->getNextInst();; } if (anotherADD) { if (src1IsZero) { irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src2)->insertAfter(inst); inst->unlink(); return Changed_Inst; } else if (src2IsZero) { irManager->newCopyPseudoInst(Mnemonic_MOV, dst, src1)->insertAfter(inst); inst->unlink(); return Changed_Inst; } } } return Changed_Nothing; }