void BipartiteWeightedMatchingBinding::printTable(raw_ostream &out, std::string
        funcUnitType, int numOperationsToShare, int numFuncUnitsAvail, Table
        &weights) {

    std::string s;
    std::stringstream ss;

    const int firstColWidth = 50;
    ss << setw(firstColWidth) << " ";
    for (int fu = 0; fu < numFuncUnitsAvail; fu++) {
        std::string fuId = this->alloc->verilogNameFunction(this->Fp, this->Fp)
            + "_" + funcUnitType + "_" + utostr(fu);
        ss << left << setw(30) << fuId;
    }
    ss << "\n";

    for (int o = 0; o < numOperationsToShare; o++) {
        std::string instStr = getValueStr(opInstr[o]);
        limitString(instStr, 30);
        std::string opStr = instStr + " (idx: " + utostr(o) + ")";
        ss << left << setw(firstColWidth) << opStr;
        for (int fu = 0; fu < numFuncUnitsAvail; fu++) {
            ss << left << setw(30) << weights[fu][o];
        }
        ss << "\n";
    }

    ss.flush();
    out << ss.str();
}
void AccountSummaryWidget::setActiveAccount(const CAccount* account)
{
    m_account = account;

    ui->accountName->setText( limitString(QString::fromStdString(m_account->getLabel()), 35) );

    balanceChanged();

    updateExchangeRates();
}
void BipartiteWeightedMatchingBinding::UpdateAssignments(raw_ostream &out, int
        numOperationsToShare, std::string funcUnitType, int numFuncUnitsAvail,
        AssignmentInfo &assigned, Table &assignments) {
    std::string s;
    std::stringstream ss;

    // Note that assignments (and weights) are square matrices,
    // numFuncUnitsAvail x numFuncUnitsAvail
    // However, numOperationsToShare <= numFuncUnitsAvail so the iteration
    // below is within bounds
    assert(numOperationsToShare <= numFuncUnitsAvail);
    for (int fu = 0; fu < numFuncUnitsAvail; fu++) {
        for (int o = 0; o < numOperationsToShare; o++) {
            if (assignments[fu][o]) {
                Instruction *I = opInstr[o];
                std::string fuId = this->alloc->verilogNameFunction(this->Fp,
                        this->Fp) + "_" + funcUnitType + "_" + utostr(fu);
                this->BindingInstrFU[I] = fuId;

                int numOperands = 0;
                for (User::op_iterator i = I->op_begin(), e =
                        I->op_end(); i != e; ++i) {
                    Instruction *operand = dyn_cast<Instruction>(*i);
                    numOperands++;
                    if (!operand) continue;
                    if (assigned.existingOperands[fuId].find(operand) ==
                            assigned.existingOperands[fuId].end()) {
                        assigned.existingOperands[fuId].insert(operand);
                        assigned.muxInputs[fuId]++;
                    }
                }

                std::string instStr = getValueStr(opInstr[o]);
                limitString(instStr, 30);
                ss << instStr << " (idx: " << o << ") -> " << fuId <<
                    " (mux inputs: " << assigned.muxInputs[fuId] << ")\n";

                // number of operands for mem_dual_port is not 2
                //assert(numOperands == 2);
                assigned.existingInstructions[fuId].insert(I);
            }
        }
    }

    ss.flush();
    out << ss.str();
}
void BipartiteWeightedMatchingBinding::constructWeights(raw_ostream &out,
        Instruction *I, int operationIdx, std::string funcUnitType, int
        numFuncUnitsAvail, AssignmentInfo &assigned, Table &weights) {

    int existingMuxInputsFactor = 1;
    int newMuxInputsFactor = 10;
    // note: this is negative, a shared output register reduces the cost
    int outputRegisterSharableFactor = -5;


    for (int fu = 0; fu < numFuncUnitsAvail; fu++) {
        int weight = 0;
        std::string fuId = this->alloc->verilogNameFunction(this->Fp, this->Fp)
            + "_" + funcUnitType + "_" + utostr(fu);

        // check both operands
        for (User::op_iterator i = I->op_begin(), e =
                I->op_end(); i != e; ++i) {
            Instruction *operand = dyn_cast<Instruction>(*i);
            if (!operand) continue;
            if (assigned.existingOperands[fuId].find(operand) ==
                    assigned.existingOperands[fuId].end()) {
                weight += newMuxInputsFactor;
            } else {
                std::string instStr = getValueStr(I);
                limitString(instStr, 30);
                out << instStr << " can share an input with another operation "
                    "already assigned to " << fuId << "\n";
            }

        }

        bool outputRegSharable = false;
        for (set<Instruction*>::iterator i =
                assigned.existingInstructions[fuId].begin(), e =
                assigned.existingInstructions[fuId].end(); i
                != e; ++i) {
            Instruction *shared = *i;

            // check for shared output register
            if (assigned.IndependentInstructions[I].find(shared) !=
                    assigned.IndependentInstructions[I].end() ) {
                //errs() << "Shared output: " << *shared << "\n";
                outputRegSharable = true;
                break;
            }
        }

        if (outputRegSharable) {
            weight += outputRegisterSharableFactor;
            std::string instStr = getValueStr(I);
            limitString(instStr, 30);
            out << instStr << " can share an output register with another "
                "operation already assigned to " << fuId << "\n";
        }

        weight += existingMuxInputsFactor * assigned.muxInputs[fuId];

        weights[fu][operationIdx] = weight;

        //errs() << "weight " << fu << " " << operationIdx << " = " <<
        //    weights[fu][operationIdx] << "\n";
    }
}