// Returns s1 \ s2, or equiv. all elements of s1 not in s2. vector<LPEdge> setDif(vector<LPEdge> s1, vector<LPEdge> s2) { vector<LPEdge> dif; for (unsigned i = 0; i < s1.size(); i++) { if (!isMem(s1[i], s2)) dif.push_back(s1[i]); } return dif; }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { const invFile* inv = *(invFile**) mxGetData(prhs[0]); int* q_words = mxGetPr(prhs[1]); // int num_q_words = mxGetNumberOfElements(prhs[1]); //printf("%d\n",num_q_words); // int sum = 0; int* count = (int*)malloc(sizeof(int)*num_q_words); int** matrix_cand = (int**)malloc(sizeof(int*)*num_q_words); mwSize dims[2]; int *list_cand, *count_cand, *count_cand_tmp, *pOutId, *pOutVal; int sum_vote = 0; double* num_vote = 0; int num_cand = 0; int i = 0, j = 0; for (i = 0; i < num_q_words; i++) { int w = q_words[i]; if(inv->flag[w] == 1) { int* list_im_id = inv->inv_file[w]; matrix_cand[i] = list_im_id; count[i] = inv->size_pw[w]; sum += count[i]; } } // list candidate return list_cand = (int*)malloc(sizeof(int)*sum); count_cand = (int*)malloc(sizeof(int)*sum); //printf("num_qw: %d\n", num_q_words); for(i=0; i < num_q_words; i++) { if (inv->flag[q_words[i]] == 1) { //printf("%d ",i); for(j=0; j < count[i]; j++) { int x = matrix_cand[i][j] + 1; //printf("[%d-%d---%d]\n",i,j,x); int pos = isMem(x, list_cand, num_cand); if(pos == -1) { list_cand[num_cand] = x; count_cand[num_cand] = 1; //if (matrix_cand[i][j] > 5063 || matrix_cand[i][j] <= 0) printf("[%d-%d] %d\n",i, j,matrix_cand[i][j]); //printf("numcand: %d", num_cand); num_cand++; } else { count_cand[pos]++; } } } } // // dims[0] = 1; dims[1] = num_cand; // reduce count cand // count_cand_tmp = 0; // for(i = 0; i < num_cand; i++) // count_cand_tmp[i] = count_cand[i]; // count_cand = count_cand_tmp; // plhs[0] = mxCreateDoubleScalar(0); // // num_vote = mxGetPr(plhs[0]); plhs[0] = mxCreateNumericArray(2, dims, mxUINT32_CLASS, mxREAL); pOutId = (int*)mxGetData(plhs[0]); plhs[1] = mxCreateNumericArray(2, dims, mxUINT32_CLASS, mxREAL); pOutVal = (int*)mxGetData(plhs[1]); // // // quicksort(list_cand, count_cand, 0, num_cand-1); // // for(i = 0; i < num_cand; i++) { pOutId[i] = list_cand[i]; pOutVal[i] = count_cand[i]; } }
const char *Operand::string() const { static char string[256]; if(isVoid(type)) { return 0; } else if(isImm(type)) { if(reference) { return reference; } else { if(value <= 127 && value >= -128) { snprintf(string, 255, "0x%0.2X", value & 0xFF); } else if(value <= 32767 && value -32768) { snprintf(string, 255, "0x%0.4X", value & 0xFFFF); } else { snprintf(string, 255, "0x%0.8X", value); } } } else if(isReg(type)) { return regName(); } else if(isMem(type)) { switch(type) { case OPERAND_MEM8: snprintf(string, 255, "byte ptr ["); break; case OPERAND_MEM16: snprintf(string, 255, "word ptr ["); break; case OPERAND_MEM32: snprintf(string, 255, "dword ptr ["); break; case OPERAND_MEM64: snprintf(string, 255, "qword ptr ["); break; case OPERAND_MEM128: snprintf(string, 255, "xmmword ptr ["); break; case OPERAND_MEM: default: snprintf(string, 255, "byte ptr ["); } if(baseReg != Encoding::REG_UNKNOWN) { snprintf(string, 255, "%s%s", string, regName()); if(indexReg != Encoding::REG_UNKNOWN) { snprintf(string, 255, "%s+", string); } } if(indexReg != Encoding::REG_UNKNOWN) { snprintf(string, 255, "%s%s", string, indexName()); } switch(scale) { case 0: case 1: break; case 2: snprintf(string, 255, "%s*2", string); break; case 4: snprintf(string, 255, "%s*4", string); break; case 8: snprintf(string, 255, "%s*8", string); break; default: throw INTERNAL_ERROR; } if(displacement) { if(baseReg != Encoding::REG_UNKNOWN || indexReg != Encoding::REG_UNKNOWN) { snprintf(string, 255, "%s+", string); } if(reference) { snprintf(string, 255, "%s%s", string, reference); } else { if(displacement <= 32767 && displacement >= -32768) { snprintf(string, 255, "%s%d", string, displacement); } else { snprintf(string, 255, "%s0x%0.8X", string, displacement); } } } snprintf(string, 255, "%s]", string); } else { throw INTERNAL_ERROR; } return strlwr(string); }
bool Operand::isMem(const Operand &operand) { return isMem(operand.type); }
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; }
PeepHoleOpt::Changed PeepHoleOpt::handleInst_MOV(Inst* inst) { Node* node = inst->getNode(); if (((BasicBlock*)node)->getLayoutSucc() == NULL) { Inst *next = inst->getNextInst(); Node *currNode = node; bool methodMarkerOccur = false; MethodMarkerPseudoInst* methodMarker = NULL; // ignoring instructions that have no effect and saving method markers to correct them during optimizations while (next == NULL || next->getKind() == Inst::Kind_MethodEndPseudoInst || next->getMnemonic() == Mnemonic_JMP) { if (next == NULL) { currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode(); if (currNode->getKind() == Node::Kind_Exit) return Changed_Nothing; next = (Inst*) currNode->getFirstInst(); } else { if (next->getKind() == Inst::Kind_MethodEndPseudoInst) { //max 1 saved method marker if (methodMarkerOccur) { return Changed_Nothing; } methodMarker = (MethodMarkerPseudoInst*)next; methodMarkerOccur = true; } next = next->getNextInst(); } } Inst *jump = next->getNextInst(); bool step1 = true; currNode = node; while (currNode != next->getNode()) { currNode = currNode->getOutEdge(Edge::Kind_Unconditional)->getTargetNode(); if (currNode->getInDegree()!=1) { step1 = false; break; } } // step1: // --------------------------------------------- // MOV opnd, opnd2 MOV opnd3, opnd2 // MOV opnd3, opnd -> // --------------------------------------------- // nb: applicable if opnd will not be used further if (step1 && next->getMnemonic() == Mnemonic_MOV) { Opnd *movopnd1, *movopnd2, *nextmovopnd1, *nextmovopnd2; bool isInstCopyPseudo = (inst->getKind() == Inst::Kind_CopyPseudoInst); if (isInstCopyPseudo) { movopnd1 = inst->getOpnd(0); movopnd2 = inst->getOpnd(1); } else { Inst::Opnds movuses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Inst::Opnds movdefs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); movopnd1 = inst->getOpnd(movdefs.begin()); movopnd2 = inst->getOpnd(movuses.begin()); } bool isNextCopyPseudo = (next->getKind() == Inst::Kind_CopyPseudoInst); if (isNextCopyPseudo) { nextmovopnd1 = next->getOpnd(0); nextmovopnd2 = next->getOpnd(1); } else { Inst::Opnds nextmovuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Inst::Opnds nextmovdefs(next, Inst::OpndRole_Explicit|Inst::OpndRole_Def); nextmovopnd1 = next->getOpnd(nextmovdefs.begin()); nextmovopnd2 = next->getOpnd(nextmovuses.begin()); } if (movopnd1->getId() == nextmovopnd2->getId() && !isMem(movopnd2) && !isMem(nextmovopnd1) && !isMem(movopnd1) ) { BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount()); irManager->updateLivenessInfo(); irManager->getLiveAtExit(next->getNode(), ls); for (Inst* i = (Inst*)next->getNode()->getLastInst(); i!=next; i = i->getPrevInst()) { irManager->updateLiveness(i, ls); } bool dstNotUsed = !ls.getBit(movopnd1->getId()); if (dstNotUsed) { if (isInstCopyPseudo && isNextCopyPseudo) irManager->newCopyPseudoInst(Mnemonic_MOV, nextmovopnd1, movopnd2)->insertAfter(inst); else irManager->newInst(Mnemonic_MOV, nextmovopnd1, movopnd2)->insertAfter(inst); inst->unlink(); next->unlink(); return Changed_Node; } } } // step2: // -------------------------------------------------------------- // MOV opnd, 0/1 Jmp smwh/BB1 Jmp smwh/BB1 // CMP opnd, 0 -> CMP opnd, 0 v // Jcc smwh Jcc smwh // BB1: BB1: // -------------------------------------------------------------- // nb: applicable if opnd will not be used further if (next->getMnemonic() == Mnemonic_CMP && jump!= NULL && (jump->getMnemonic() == Mnemonic_JE || jump->getMnemonic() == Mnemonic_JNE)) { Opnd *movopnd1, *movopnd2; if (inst->getKind() == Inst::Kind_CopyPseudoInst) { movopnd1 = inst->getOpnd(0); movopnd2 = inst->getOpnd(1); } else { Inst::Opnds movuses(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Inst::Opnds movdefs(inst, Inst::OpndRole_Explicit|Inst::OpndRole_Def); movopnd1 = inst->getOpnd(movdefs.begin()); movopnd2 = inst->getOpnd(movuses.begin()); } Inst::Opnds cmpuses(next, Inst::OpndRole_Explicit|Inst::OpndRole_Use); Opnd* cmpopnd1 = next->getOpnd(cmpuses.begin()); Opnd* cmpopnd2 = next->getOpnd(cmpuses.next(cmpuses.begin())); if (isImm(movopnd2) && (movopnd2->getImmValue() == 0 || movopnd2->getImmValue() == 1) && movopnd1->getId() == cmpopnd1->getId() && isImm(cmpopnd2) && cmpopnd2->getImmValue() == 0) { BitSet ls(irManager->getMemoryManager(), irManager->getOpndCount()); irManager->updateLivenessInfo(); irManager->getLiveAtExit(jump->getNode(), ls); bool opndNotUsed = !ls.getBit(movopnd1->getId()); if (opndNotUsed) { ControlFlowGraph* cfg = irManager->getFlowGraph(); Node* destination = ((BranchInst*)jump)->getTrueTarget(); if ((jump->getMnemonic() == Mnemonic_JNE || movopnd2->getImmValue() == 1) && !(jump->getMnemonic() == Mnemonic_JNE && movopnd2->getImmValue() == 1)) { destination = ((BranchInst*)jump)->getFalseTarget(); } if (node->getId() != next->getNode()->getId()) { if (methodMarkerOccur) { inst->getNode()->appendInst(irManager->newMethodEndPseudoInst(methodMarker->getMethodDesc())); } inst->unlink(); Edge *outEdge = node->getOutEdge(Edge::Kind_Unconditional); cfg->replaceEdgeTarget(outEdge, destination, true); cfg->purgeUnreachableNodes(); // previous successor may become unreachable } else { cfg->removeEdge(node->getOutEdge(Edge::Kind_True)); cfg->removeEdge(node->getOutEdge(Edge::Kind_False)); cfg->addEdge(node, destination); inst->unlink(); next->unlink(); jump->unlink(); } return Changed_Node; } } } } return Changed_Nothing; }
PeepHoleOpt::Changed PeepHoleOpt::handleInst_SSEMov(Inst* inst) { assert(inst->getMnemonic() == Mnemonic_MOVSS || inst->getMnemonic() == Mnemonic_MOVSD); const bool isDouble = inst->getMnemonic() == Mnemonic_MOVSD; if (inst->getOpndCount() != 2) { // Expected only MOVSS/SD a, b assert(false); return Changed_Nothing; } Opnd* dst = inst->getOpnd(0); Opnd* src = inst->getOpnd(1); // // if (isReg(dst) && equals(src, dst)) { // what: same register moved around // why: useless thing inst->unlink(); return Changed_Inst; } // // if (isReg(dst) && isMem(src)) { /* what: MOVSS/MOVSD xmmreg, [zero constant from memory] => PXOR xmmreg, xmmreg why: shorter instruction; no memory access => faster nb: only works with 64 XMMs */ bool isZeroConstant = false; if (isDouble) { isZeroConstant = isFPConst(src, (double)0); } else { isZeroConstant = isFPConst(src, (float)0); } if (isZeroConstant) { // PXOR only accepts double registers, convert dst dst = convertToXmmReg64(dst); Inst* ii = irManager->newInst(Mnemonic_PXOR, dst, dst); replaceInst(inst, ii); return Changed_Inst; } // // fall through to process more // || // vv } // ~ movss xmm, 0 => pxor xmm,xmm if (isReg(dst) && isReg(src)) { /*what: MOVSS/MOVSD reg, reg => MOVQ reg, reg why: MOVSD has latency=6, MOVSS has latency=4, MOVQ's latency=2 nb: MOVQ only works with 64 xmms */ dst = convertToXmmReg64(dst); src = convertToXmmReg64(src); Inst* ii = irManager->newInst(Mnemonic_MOVQ, dst, src); replaceInst(inst, ii); return Changed_Inst; } // We just handled 'both regs' case above, the only possible variant: assert((isReg(dst)&&isMem(src)) || (isReg(src)&&isMem(dst))); if (false && isDouble) { //FIXME: MOVQ with memory gets encoded badly - need to fix in encoder /* what: MOVSD => MOVQ why: faster (? actually, I hope so. Need to double check) nb: only for xmm64 */ Inst* ii = irManager->newInst(Mnemonic_MOVQ, dst, src); replaceInst(inst, ii); return Changed_Inst; } return Changed_Nothing; }
huReturn hookUp(const vector<SplitEdge> &g, int s, vector<SplitEdge> &bIn, int k, vector<vector<int>> &Y, historyIndex &h) { if (cG(s, g) != 0) { cout << "cG(s) problem in hookup" << endl; throw logic_error(""); } vector<SplitEdge> H = g; vector<SplitEdge> G1 = g; vector<SplitEdge> B = bIn; vector<SplitEdge> B1; vector<vector<int>> XS; int maxNodeInd = getMaxNodeInd(G1); for (int i = 0; i < maxNodeInd; i++) XS.push_back(vector<int>()); for (int i = 0; i < maxNodeInd; i++) XS[i].push_back(i); //cout << "About to enter while loop" << endl; while (getNumUsedNodes(H) >= 4) { vector<int> ma = maOrderingHeap(H, s); int v = ma[ma.size() - 2]; int w = ma[ma.size() - 1]; if (v == s || w == s) throw logic_error("SET WAS V - S, S FOUND"); vector<int> X1; H = combineVertices(H, v, w); H = compress(H); XS[v] = setUnion(XS[v], XS[w]); if (XS[w].size() == 0) { cout << "Error: W, " << w << " was merged twice. Quitting" << endl; throw logic_error(""); } XS[w] = vector<int>(); if (cG(v, H) < k) { int numToGet = (int)ceil(.5*(double(k) - double(cG(G1, XS[v])))); vector<SplitEdge> GX = inducedSubgraph(G1, XS[v]); vector<SplitEdge> delB; int added = 0; for (unsigned i = 0; i < GX.size(); i++) { SplitEdge e = SplitEdge(GX[i].end0, GX[i].end1, GX[i].weight, GX[i].orig0, GX[i].orig1); if (isMem(e, B)) { int bW = B[indexOfEdge(B, e.end0, e.end1)].weight; if (bW < e.weight) e.weight = bW; if (e.weight > (numToGet - added)) { e.weight = numToGet - added; } added += e.weight; delB.push_back(e); } if (added == numToGet) break; } if (added != numToGet) { cout << "Error: GX did not contain " << numToGet << " entries in B. Quitting." << endl; throw logic_error(""); } if (!isSubset(delB, B)) { cout << "ERROR: delB is not a subset of B." << endl; cout << "B:" << endl; output(B); cout << "delB:" << endl; output(delB); cout << "This was the GX to choose from:" << endl; output(GX); cout << "V: " << v << endl; cout << "W: " << w << endl; cout << "S: " << s << endl; throw logic_error(""); } B = setRemove(delB, B); B = removeZeroWeighted(B); B1 = setUnion(delB, B1); H = removeZeroWeighted(H); G1 = hookUpHelper(s, G1, delB, h); G1 = removeZeroWeighted(G1); H = removeZeroWeighted(H); bool addedFromXSinH = false; numToGet *= 2; for (unsigned i = 0; i < H.size(); i++) { SplitEdge tester = SplitEdge(s, v, 0, 0, 0); if (equals(tester, H[i])) { //cout << "Increasing weight in hookUp in H between " << H[i].end0 << " and " << H[i].end1 << "from " << H[i].weight << " to " << H[i].weight + numToGet << endl; H[i].weight += numToGet; addedFromXSinH = true; break; } } if (!addedFromXSinH && numToGet != 0) { //cout << "Creating edge in hookUp in H between " << s << " and " << v << " with weight " << numToGet << endl; SplitEdge e(s, v, numToGet, s, v); H.push_back(e); } vector<vector<int>> newY; for (unsigned i = 0; i < Y.size(); i++) { if (!isProperSubset(Y[i], XS[v])) newY.push_back(Y[i]); } bool foundX1inY = false; for (unsigned i = 0; i < newY.size(); i++) { if (setsEqual(newY[i], XS[v])) foundX1inY = true; } if (!foundX1inY) newY.push_back(XS[v]); Y = newY; } } huReturn ret; ret.BP = B1; ret.G1 = G1; ret.Y = Y; return ret; }
bool share_mem (Instruction *I) { return ( isMem(I) && LEGUP_CONFIG->getParameterInt("DUAL_PORT_BINDING") && !LEGUP_CONFIG->getParameterInt("PARALLEL_LOCAL_RAMS") ); }
int64 RegOpnd::getValue() { if (isMem() == false) return value; if (value >= S_OUTARG_BASE) return value; return value - S_BASE; }