void PrologEpilogGenerator::genCode() {

    containCall = opndManager->getContainCall();

    saveRestoreRp();              // affects: mem stack, reg stack  use: 
    saveRestorePr();              // affects: mem stack, reg stack  use: 
    genAlloc();                   // affects: mem stack, reg stack  use: reg stack
    saveRestoreUnat();            // affects: mem stack             use: 
    saveRestorePreservedGr();     // affects: mem stack             use: 
    saveRestorePreservedFr();     // affects: mem stack             use:
    saveRestorePreservedBr();     // affects: mem stack             use: 
    saveRestoreSp();              // affects:                       use: mem stack

    prologInsts.splice(prologInsts.end(), allocInsts);
    prologInsts.splice(prologInsts.end(), saveSpInsts);
    prologInsts.splice(prologInsts.end(), savePfsInsts);
    prologInsts.splice(prologInsts.end(), saveUnatInsts);
    prologInsts.splice(prologInsts.end(), saveGrsInsts);
    prologInsts.splice(prologInsts.end(), saveFrsInsts);
    prologInsts.splice(prologInsts.end(), saveBrsInsts);
    prologInsts.splice(prologInsts.end(), savePrsInsts);
    prologInsts.splice(prologInsts.end(), saveRpInsts);

    epilogInsts.splice(epilogInsts.end(), restRpInsts);
    epilogInsts.splice(epilogInsts.end(), restPrsInsts);
    epilogInsts.splice(epilogInsts.end(), restBrsInsts);
    epilogInsts.splice(epilogInsts.end(), restFrsInsts);
    epilogInsts.splice(epilogInsts.end(), restGrsInsts);
    epilogInsts.splice(epilogInsts.end(), restUnatInsts);
    epilogInsts.splice(epilogInsts.end(), restPfsInsts);
    epilogInsts.splice(epilogInsts.end(), restSpInsts);

    // Print Prolog and Epilog insts
    IPF_LOG << "    Prolog:" << endl << IrPrinter::toString(prologInsts);
    IPF_LOG << "    Epilog:" << endl << IrPrinter::toString(epilogInsts) << endl;

    // Insert prolog instructions in begining of enter node
    BbNode     *enterNode  = (BbNode *)cfg.getEnterNode();
    InstVector &enterInsts = enterNode->getInsts();
    enterInsts.insert(enterInsts.begin(), prologInsts.begin(), prologInsts.end());

    // Insert epilog instructions in each epilog node (all nodes which end with "br.ret")
    for(uint16 i=0; i<epilogNodes.size(); i++) {
        InstVector &exitInsts = ((BbNode *)epilogNodes[i])->getInsts();
        exitInsts.insert(exitInsts.end()-1, epilogInsts.begin(), epilogInsts.end());
    }
}
Exemple #2
0
void IpfCfgCodeSelector::genSwitchEdges(U_32  tailNodeId, 
                                        U_32  numTargets, 
                                        U_32 *targets, 
                                        double *probs, 
                                        U_32  defaultTarget) {

    BbNode         *tailNode       = (BbNode *)nodes[tailNodeId];
    InstVector     &insts          = tailNode->getInsts();
    Inst           *switchInst     = insts.back();
    Opnd           *defTargetImm   =                   switchInst->getOpnd(POS_SWITCH_DEFAULT);
    ConstantRef    *constantRef    = (ConstantRef *)   switchInst->getOpnd(POS_SWITCH_TABLE);
    SwitchConstant *switchConstant = (SwitchConstant *)constantRef->getConstant();
    Edge           *defedge        = NULL;
    Edge           *edge           = NULL;

    bool   defadded = false;
    U_32 i        = 0;

    IPF_LOG << "    Generate Switch     tailNodeId=" << tailNodeId 
        << "; defaultTarget=" << defaultTarget << endl;

    defedge = new(mm) Edge(nodes[tailNodeId], nodes[defaultTarget], probs[defaultTarget], EDGE_BRANCH);
    defedge->insert();

    for(i=0; i<numTargets; i++) {
        if(targets[i] == defaultTarget) {
            defTargetImm->setValue(i);
            switchConstant->addEdge(defedge);
            defadded = true;
            IPF_LOG << "        default: " << i << endl;
            continue;
        }
        IPF_LOG << "        case " << i << ": " << targets[i] << endl;
        edge = new(mm) Edge(nodes[tailNodeId], nodes[targets[i]], probs[i], EDGE_BRANCH);
        edge->insert();
        switchConstant->addEdge(edge);
    }

    if (!defadded) {
        defTargetImm->setValue(i);
        switchConstant->addEdge(defedge);
        defadded = true;
        IPF_LOG << "        default: " << i << endl;
    }
}