예제 #1
0
void
AllocationIntegrityState::dump()
{
#ifdef DEBUG
    fprintf(stderr, "Register Allocation Integrity State:\n");

    for (size_t blockIndex = 0; blockIndex < graph.numBlocks(); blockIndex++) {
        LBlock* block = graph.getBlock(blockIndex);
        MBasicBlock* mir = block->mir();

        fprintf(stderr, "\nBlock %lu", static_cast<unsigned long>(blockIndex));
        for (size_t i = 0; i < mir->numSuccessors(); i++)
            fprintf(stderr, " [successor %u]", mir->getSuccessor(i)->id());
        fprintf(stderr, "\n");

        for (size_t i = 0; i < block->numPhis(); i++) {
            const InstructionInfo& info = blocks[blockIndex].phis[i];
            LPhi* phi = block->getPhi(i);
            CodePosition input(block->getPhi(0)->id(), CodePosition::INPUT);
            CodePosition output(block->getPhi(block->numPhis() - 1)->id(), CodePosition::OUTPUT);

            fprintf(stderr, "[%u,%u Phi] [def %s] ",
                    input.bits(),
                    output.bits(),
                    phi->getDef(0)->toString());
            for (size_t j = 0; j < phi->numOperands(); j++)
                fprintf(stderr, " [use %s]", info.inputs[j].toString());
            fprintf(stderr, "\n");
        }

        for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
            LInstruction* ins = *iter;
            const InstructionInfo& info = instructions[ins->id()];

            CodePosition input(ins->id(), CodePosition::INPUT);
            CodePosition output(ins->id(), CodePosition::OUTPUT);

            fprintf(stderr, "[");
            if (input != CodePosition::MIN)
                fprintf(stderr, "%u,%u ", input.bits(), output.bits());
            fprintf(stderr, "%s]", ins->opName());

            if (ins->isMoveGroup()) {
                LMoveGroup* group = ins->toMoveGroup();
                for (int i = group->numMoves() - 1; i >= 0; i--) {
                    // Use two printfs, as LAllocation::toString is not reentrant.
                    fprintf(stderr, " [%s", group->getMove(i).from()->toString());
                    fprintf(stderr, " -> %s]", group->getMove(i).to()->toString());
                }
                fprintf(stderr, "\n");
                continue;
            }

            for (size_t i = 0; i < ins->numDefs(); i++)
                fprintf(stderr, " [def %s]", ins->getDef(i)->toString());

            for (size_t i = 0; i < ins->numTemps(); i++) {
                LDefinition* temp = ins->getTemp(i);
                if (!temp->isBogusTemp())
                    fprintf(stderr, " [temp v%u %s]", info.temps[i].virtualRegister(),
                           temp->toString());
            }

            size_t index = 0;
            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
                fprintf(stderr, " [use %s", info.inputs[index++].toString());
                if (!alloc->isConstant())
                    fprintf(stderr, " %s", alloc->toString());
                fprintf(stderr, "]");
            }

            fprintf(stderr, "\n");
        }
    }

    // Print discovered allocations at the ends of blocks, in the order they
    // were discovered.

    Vector<IntegrityItem, 20, SystemAllocPolicy> seenOrdered;
    seenOrdered.appendN(IntegrityItem(), seen.count());

    for (IntegrityItemSet::Enum iter(seen); !iter.empty(); iter.popFront()) {
        IntegrityItem item = iter.front();
        seenOrdered[item.index] = item;
    }

    if (!seenOrdered.empty()) {
        fprintf(stderr, "Intermediate Allocations:\n");

        for (size_t i = 0; i < seenOrdered.length(); i++) {
            IntegrityItem item = seenOrdered[i];
            fprintf(stderr, "  block %u reg v%u alloc %s\n",
                   item.block->mir()->id(), item.vreg, item.alloc.toString());
        }
    }

    fprintf(stderr, "\n");
#endif
}
예제 #2
0
void
RegisterAllocator::dumpInstructions()
{
#ifdef DEBUG
    fprintf(stderr, "Instructions:\n");

    for (size_t blockIndex = 0; blockIndex < graph.numBlocks(); blockIndex++) {
        LBlock* block = graph.getBlock(blockIndex);
        MBasicBlock* mir = block->mir();

        fprintf(stderr, "\nBlock %lu", static_cast<unsigned long>(blockIndex));
        for (size_t i = 0; i < mir->numSuccessors(); i++)
            fprintf(stderr, " [successor %u]", mir->getSuccessor(i)->id());
        fprintf(stderr, "\n");

        for (size_t i = 0; i < block->numPhis(); i++) {
            LPhi* phi = block->getPhi(i);

            fprintf(stderr, "[%u,%u Phi] [def %s]",
                    inputOf(phi).bits(),
                    outputOf(phi).bits(),
                    phi->getDef(0)->toString());
            for (size_t j = 0; j < phi->numOperands(); j++)
                fprintf(stderr, " [use %s]", phi->getOperand(j)->toString());
            fprintf(stderr, "\n");
        }

        for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
            LInstruction* ins = *iter;

            fprintf(stderr, "[");
            if (ins->id() != 0)
                fprintf(stderr, "%u,%u ", inputOf(ins).bits(), outputOf(ins).bits());
            fprintf(stderr, "%s]", ins->opName());

            if (ins->isMoveGroup()) {
                LMoveGroup* group = ins->toMoveGroup();
                for (int i = group->numMoves() - 1; i >= 0; i--) {
                    // Use two printfs, as LAllocation::toString is not reentant.
                    fprintf(stderr, " [%s", group->getMove(i).from()->toString());
                    fprintf(stderr, " -> %s]", group->getMove(i).to()->toString());
                }
                fprintf(stderr, "\n");
                continue;
            }

            for (size_t i = 0; i < ins->numDefs(); i++)
                fprintf(stderr, " [def %s]", ins->getDef(i)->toString());

            for (size_t i = 0; i < ins->numTemps(); i++) {
                LDefinition* temp = ins->getTemp(i);
                if (!temp->isBogusTemp())
                    fprintf(stderr, " [temp %s]", temp->toString());
            }

            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
                if (!alloc->isBogus())
                    fprintf(stderr, " [use %s]", alloc->toString());
            }

            fprintf(stderr, "\n");
        }
    }
    fprintf(stderr, "\n");
#endif // DEBUG
}
예제 #3
0
bool
AllocationIntegrityState::checkIntegrity(LBlock* block, LInstruction* ins,
                                         uint32_t vreg, LAllocation alloc, bool populateSafepoints)
{
    for (LInstructionReverseIterator iter(block->rbegin(ins)); iter != block->rend(); iter++) {
        ins = *iter;

        // Follow values through assignments in move groups. All assignments in
        // a move group are considered to happen simultaneously, so stop after
        // the first matching move is found.
        if (ins->isMoveGroup()) {
            LMoveGroup* group = ins->toMoveGroup();
            for (int i = group->numMoves() - 1; i >= 0; i--) {
                if (*group->getMove(i).to() == alloc) {
                    alloc = *group->getMove(i).from();
                    break;
                }
            }
        }

        const InstructionInfo& info = instructions[ins->id()];

        // Make sure the physical location being tracked is not clobbered by
        // another instruction, and that if the originating vreg definition is
        // found that it is writing to the tracked location.

        for (size_t i = 0; i < ins->numDefs(); i++) {
            LDefinition* def = ins->getDef(i);
            if (def->isBogusTemp())
                continue;
            if (info.outputs[i].virtualRegister() == vreg) {
                MOZ_ASSERT(*def->output() == alloc);

                // Found the original definition, done scanning.
                return true;
            } else {
                MOZ_ASSERT(*def->output() != alloc);
            }
        }

        for (size_t i = 0; i < ins->numTemps(); i++) {
            LDefinition* temp = ins->getTemp(i);
            if (!temp->isBogusTemp())
                MOZ_ASSERT(*temp->output() != alloc);
        }

        if (ins->safepoint()) {
            if (!checkSafepointAllocation(ins, vreg, alloc, populateSafepoints))
                return false;
        }
    }

    // Phis are effectless, but change the vreg we are tracking. Check if there
    // is one which produced this vreg. We need to follow back through the phi
    // inputs as it is not guaranteed the register allocator filled in physical
    // allocations for the inputs and outputs of the phis.
    for (size_t i = 0; i < block->numPhis(); i++) {
        const InstructionInfo& info = blocks[block->mir()->id()].phis[i];
        LPhi* phi = block->getPhi(i);
        if (info.outputs[0].virtualRegister() == vreg) {
            for (size_t j = 0, jend = phi->numOperands(); j < jend; j++) {
                uint32_t newvreg = info.inputs[j].toUse()->virtualRegister();
                LBlock* predecessor = block->mir()->getPredecessor(j)->lir();
                if (!addPredecessor(predecessor, newvreg, alloc))
                    return false;
            }
            return true;
        }
    }

    // No phi which defined the vreg we are tracking, follow back through all
    // predecessors with the existing vreg.
    for (size_t i = 0, iend = block->mir()->numPredecessors(); i < iend; i++) {
        LBlock* predecessor = block->mir()->getPredecessor(i)->lir();
        if (!addPredecessor(predecessor, vreg, alloc))
            return false;
    }

    return true;
}