Example #1
0
BB* BBTransform::clone(BB* src, Code* target, ClosureVersion* targetClosure) {
    std::vector<BB*> bbs;

    // Copy instructions and remember old -> new instruction map.
    std::unordered_map<Value*, Instruction*> relocation_table;
    Visitor::run(src, [&](BB* bb) {
        BB* theClone = BB::cloneInstrs(bb, target->nextBBId++, target);
        assert(bb->size() == theClone->size());
        if (bb->id >= bbs.size())
            bbs.resize(bb->id + 5);
        bbs[bb->id] = theClone;
        for (size_t i = 0; i < bb->size(); ++i)
            relocation_table[bb->at(i)] = theClone->at(i);
    });

    // Fixup CFG: next pointers of copied BB's need to be filled in.
    Visitor::run(src, [&](BB* bb) {
        bbs[bb->id]->next0 = bbs[bb->id]->next1 = nullptr;
        if (bb->next0)
            bbs[bb->id]->next0 = bbs[bb->next0->id];
        if (bb->next1)
            bbs[bb->id]->next1 = bbs[bb->next1->id];
    });

    std::unordered_map<Promise*, Promise*> promMap;
    // Relocate argument pointers using old -> new map
    BB* newEntry = bbs[src->id];
    Visitor::run(newEntry, [&](Instruction* i) {
        auto phi = Phi::Cast(i);
        if (phi) {
            for (size_t j = 0; j < phi->nargs(); ++j)
                phi->updateInputAt(j, bbs[phi->inputAt(j)->id]);
        }
        i->eachArg([&](InstrArg& arg) {
            if (arg.val()->isInstruction()) {
                assert(relocation_table.count(arg.val()));
                arg.val() = relocation_table.at(arg.val());
            }
        });
        if (auto mk = MkArg::Cast(i)) {
            Promise* p = mk->prom();
            if (p->owner != targetClosure) {
                if (promMap.count(p)) {
                    mk->updatePromise(promMap.at(p));
                } else {
                    auto c = targetClosure->createProm(p->srcPoolIdx());
                    c->entry = clone(p->entry, c, targetClosure);
                    mk->updatePromise(c);
                }
            }
        }
    });

    return newEntry;
}
Example #2
0
/* Writes the procedure's declaration (including arguments), local variables,
 * and invokes the procedure that writes the code of the given record *hli */
void Function::codeGen (std::ostream &fs)
{
    int numLoc;
    ostringstream ostr;
    //STKFRAME * args;       /* Procedure arguments              */
    //char buf[200],        /* Procedure's definition           */
    //        arg[30];         /* One argument                     */
    BB *pBB;              /* Pointer to basic block           */

    /* Write procedure/function header */
    cCode.init();
    if (flg & PROC_IS_FUNC)      /* Function */
        ostr<< "\n"<<TypeContainer::typeName(retVal.type)<<" "<<name<<" (";
    else                                /* Procedure */
        ostr<< "\nvoid "<<name<<" (";

    /* Write arguments */
    for (size_t i = 0; i < args.size(); i++)
    {
        if ( args[i].invalid )
            continue;
        ostr<<hlTypes[args[i].type]<<" "<<args[i].name;
        if (i < (args.size() - 1))
            ostr<<", ";
    }
    ostr<<")\n";

    /* Write comments */
    writeProcComments( ostr );

    /* Write local variables */
    if (! (flg & PROC_ASM))
    {
        numLoc = 0;
        for (ID &refId : localId )
        {
            /* Output only non-invalidated entries */
            if ( refId.illegal )
                continue;
            if (refId.loc == REG_FRAME)
            {
                /* Register variables are assigned to a local variable */
                if (((flg & SI_REGVAR) && (refId.id.regi == rSI)) ||
                        ((flg & DI_REGVAR) && (refId.id.regi == rDI)))
                {
                    refId.setLocalName(++numLoc);
                    ostr << "int "<<refId.name<<";\n";
                }
                /* Other registers are named when they are first used in
                     * the output C code, and appended to the proc decl. */
            }
            else if (refId.loc == STK_FRAME)
            {
                /* Name local variables and output appropriate type */
                    refId.setLocalName(++numLoc);
                ostr << TypeContainer::typeName(refId.type)<<" "<<refId.name<<";\n";
            }
        }
    }
    fs<<ostr.str();
    /* Write procedure's code */
    if (flg & PROC_ASM)		/* generate assembler */
    {
        Disassembler ds(3);
        ds.disassem(this);
    }
    else							/* generate C */
    {
        m_cfg.front()->writeCode (1, this, &numLoc, MAX, UN_INIT);
    }

    cCode.appendCode( "}\n\n");
    writeBundle (fs, cCode);
    freeBundle (&cCode);

    /* Write Live register analysis information */
    if (option.verbose)
        for (size_t i = 0; i < numBBs; i++)
        {
            pBB = m_dfsLast[i];
            if (pBB->flg & INVALID_BB)	continue;	/* skip invalid BBs */
            cout << "BB "<<i<<"\n";
            cout << "  Start = "<<pBB->begin()->loc_ip;
            cout << ", end = "<<pBB->begin()->loc_ip+pBB->size()<<"\n";
            cout << "  LiveUse = ";
            Machine_X86::writeRegVector(cout,pBB->liveUse);
            cout << "\n  Def = ";
            Machine_X86::writeRegVector(cout,pBB->def);
            cout << "\n  LiveOut = ";
            Machine_X86::writeRegVector(cout,pBB->liveOut);
            cout << "\n  LiveIn = ";
            Machine_X86::writeRegVector(cout,pBB->liveIn);
            cout <<"\n\n";
        }
}