Exemple #1
0
/*
 * Look for Jcc instructions in the main trace that
 * branch to "normal exits".  We can optimize these into the
 * SideExitJcc* instructions that can be patched in place.
 */
void optimizeSideExitJccs(IRUnit& unit) {
    auto trace = unit.main();
    FTRACE(5, "SideExitJcc:vvvvvvvvvvvvvvvvvvvvv\n");
    SCOPE_EXIT { FTRACE(5, "SideExitJcc:^^^^^^^^^^^^^^^^^^^^^\n"); };

    forEachInst(trace->blocks(), [&] (IRInstruction* inst) {
        if (!jccCanBeDirectExit(inst->op())) return;
        auto const exitBlock = inst->taken();
        if (!isNormalExit(exitBlock)) return;

        auto it = exitBlock->backIter();
        auto& reqBindJmp = *(it--);
        auto& syncABI = *it;
        assert(syncABI.op() == SyncABIRegs);

        FTRACE(5, "converting jcc ({}) to side exit\n",
               inst->id());

        auto const newOpcode = jmpToSideExitJmp(inst->op());
        SideExitJccData data;
        data.taken = reqBindJmp.extra<ReqBindJmp>()->offset;

        auto const block = inst->block();
        block->insert(block->iteratorTo(inst),
                      unit.cloneInstruction(&syncABI));

        unit.replace(
            inst,
            newOpcode,
            data,
            std::make_pair(inst->numSrcs(), inst->srcs().begin())
        );
    });
}
Exemple #2
0
/*
 * Branch is a conditional branch to a normal exit.  Convert it
 * into a SideExitJcc instruction that can be patched in place.
 */
void optimizeSideExitJcc(IRUnit& unit, IRInstruction* inst, Block* exitBlock) {
  assert(isSideExitJcc(inst, exitBlock));
  FTRACE(5, "SideExitJcc:vvvvvvvvvvvvvvvvvvvvv\n");
  SCOPE_EXIT { FTRACE(5, "SideExitJcc:^^^^^^^^^^^^^^^^^^^^^\n"); };

  auto it = exitBlock->backIter();
  auto& reqBindJmp = *(it--);
  auto& syncABI = *it;
  assert(syncABI.op() == SyncABIRegs);

  FTRACE(5, "converting jcc ({}) to side exit\n",
         inst->id());

  auto const newOpcode = jmpToSideExitJmp(inst->op());
  SideExitJccData data;
  data.taken = reqBindJmp.extra<ReqBindJmp>()->offset;
  data.trflags = reqBindJmp.extra<ReqBindJmp>()->trflags;

  auto const block = inst->block();
  block->insert(block->iteratorTo(inst),
                unit.cloneInstruction(&syncABI));

  auto next = inst->next();
  unit.replace(
    inst,
    newOpcode,
    data,
    std::make_pair(inst->numSrcs(), inst->srcs().begin())
  );
  block->push_back(unit.gen(Jmp, inst->marker(), next));
}