当前位置: 首页>>代码示例>>C++>>正文


C++ SSATmp类代码示例

本文整理汇总了C++中SSATmp的典型用法代码示例。如果您正苦于以下问题:C++ SSATmp类的具体用法?C++ SSATmp怎么用?C++ SSATmp使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了SSATmp类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: checkRefs

void checkRefs(IRGS& env,
               int64_t entryArDelta,
               const std::vector<bool>& mask,
               const std::vector<bool>& vals,
               Offset dest) {
  auto const actRecOff = entryArDelta + offsetFromIRSP(env, BCSPOffset{0});
  auto const funcPtr = gen(env, LdARFuncPtr,
                           IRSPOffsetData { actRecOff }, sp(env));
  SSATmp* nParams = nullptr;

  for (unsigned i = 0; i < mask.size(); i += 64) {
    assertx(i < vals.size());

    uint64_t mask64 = packBitVec(mask, i);
    if (mask64 == 0) {
      continue;
    }

    if (i == 0) {
      nParams = cns(env, 64);
    } else if (!nParams || nParams->hasConstVal()) {
      nParams = gen(env, LdFuncNumParams, funcPtr);
    }

    auto const vals64 = packBitVec(vals, i);
    auto failBlock = env.irb->guardFailBlock();
    if (failBlock == nullptr) failBlock = makeExit(env, dest);
    gen(env, CheckRefs, failBlock, funcPtr, nParams,
        cns(env, i), cns(env, mask64), cns(env, vals64));
  }
}
开发者ID:LouisRenWeiWei,项目名称:hhvm,代码行数:31,代码来源:irgen-guards.cpp

示例2: hoistConditionalJumps

// If main trace ends with a conditional jump with no side-effects on exit,
// hook it to the exitTrace and make it a TraceExitType::NormalCc
static void hoistConditionalJumps(Trace* trace, IRFactory* irFactory) {
  IRInstruction::List& instList = trace->getInstructionList();
  IRInstruction::Iterator tail  = instList.end();
  IRInstruction* jccInst        = nullptr;
  IRInstruction* exitInst       = nullptr;
  IRInstruction* exitCcInst     = nullptr;
  Opcode opc = OpAdd;
  // Normally Jcc comes before a Marker
  for (int idx = 3; idx >= 0; idx--) {
    tail--; // go back to the previous instruction
    IRInstruction* inst = *tail;
    opc = inst->getOpcode();
    if (opc == ExitTrace) {
      exitInst = inst;
      continue;
    }
    if (opc == Marker) {
      continue;
    }
    if (jccCanBeDirectExit(opc)) {
      jccInst = inst;
      break;
    }
    break;
  }
  if (jccCanBeDirectExit(opc)) {
    SSATmp* dst = jccInst->getDst();
    Trace* targetTrace = jccInst->getLabel()->getParent();
    IRInstruction::List& targetInstList = targetTrace->getInstructionList();
    IRInstruction::Iterator targetInstIter = targetInstList.begin();
    targetInstIter++; // skip over label

    // Check for a NormalCc exit with no side effects
    for (IRInstruction::Iterator it = targetInstIter;
         it != targetInstList.end();
         ++it) {
      IRInstruction* instr = (*it);
      // Extend to support ExitSlow, ExitSlowNoProgress, ...
      Opcode opc = instr->getOpcode();
      if (opc == ExitTraceCc) {
        exitCcInst = instr;
        break;
      } else if (opc == Marker) {
        continue;
      } else {
        // Do not optimize if there are other instructions
        break;
      }
    }

    if (exitInst && exitCcInst) {
      // Found both exits, link them to Jcc for codegen
      assert(dst);
      exitCcInst->appendSrc(irFactory->arena(), dst);
      exitInst->appendSrc(irFactory->arena(), dst);
      // Set flag so Jcc and exits know this is active
      dst->setTCA(kIRDirectJccJmpActive);
    }
  }
}
开发者ID:beride,项目名称:hiphop-php,代码行数:62,代码来源:jumpsopts.cpp

示例3: forceAlloc

PhysReg forceAlloc(const SSATmp& tmp) {
  if (tmp.type() <= TBottom) return InvalidReg;

  auto inst = tmp.inst();
  auto opc = inst->op();

  auto const forceStkPtrs = [&] {
    switch (arch()) {
    case Arch::X64: return false;
    case Arch::ARM: return true;
    case Arch::PPC64: not_implemented(); break;
    }
    not_reached();
  }();

  if (forceStkPtrs && tmp.isA(TStkPtr)) {
    assert_flog(
      opc == DefSP ||
      opc == Mov,
      "unexpected StkPtr dest from {}",
      opcodeName(opc)
    );
    return rvmsp();
  }

  // LdContActRec and LdAFWHActRec, loading a generator's AR, is the only time
  // we have a pointer to an AR that is not in rvmfp().
  if (opc != LdContActRec && opc != LdAFWHActRec && tmp.isA(TFramePtr)) {
    return rvmfp();
  }

  return InvalidReg;
}
开发者ID:nadanomics,项目名称:hhvm,代码行数:33,代码来源:reg-alloc.cpp

示例4: assert

SSATmp* IRInstruction::modifiedStkPtr() const {
  assert(modifiesStack());
  assert(MInstrEffects::supported(this));
  SSATmp* sp = dst(hasMainDst() ? 1 : 0);
  assert(sp->isA(Type::StkPtr));
  return sp;
}
开发者ID:Halfnhav,项目名称:hiphop-php,代码行数:7,代码来源:ir-instruction.cpp

示例5: killLocalsForCall

/**
 * Called to clear out the tracked local values at a call site.
 * Calls kill all registers, so we don't want to keep locals in
 * registers across calls. We do continue tracking the types in
 * locals, however.
 */
void TraceBuilder::killLocalsForCall() {
  auto doKill = [&](smart::vector<LocalState>& locals) {
    for (auto& loc : locals) {
      SSATmp* t = loc.value;
      // should not kill DefConst, and LdConst should be replaced by DefConst
      if (!t || t->inst()->op() == DefConst) continue;

      if (t->inst()->op() == LdConst) {
        // make the new DefConst instruction
        IRInstruction* clone = t->inst()->clone(&m_irFactory);
        clone->setOpcode(DefConst);
        loc.value = clone->dst();
        continue;
      }
      assert(!t->isConst());
      loc.unsafe = true;
    }
  };

  doKill(m_locals);
  m_callerAvailableValues.clear();

  for (auto& state : m_inlineSavedStates) {
    doKill(state->locals);
    state->callerAvailableValues.clear();
  }
}
开发者ID:bnovoa,项目名称:hiphop-php,代码行数:33,代码来源:trace-builder.cpp

示例6: simplifyGuardType

SSATmp* Simplifier::simplifyGuardType(IRInstruction* inst) {
  Type type    = inst->getTypeParam();
  SSATmp*   src     = inst->getSrc(0);
  Type srcType = src->getType();
  if (srcType == type || srcType.strictSubtypeOf(type)) {
    /*
     * the type of the src is the same or more refined than type, so the
     * guard is unnecessary.
     */
    return src;
  }
  if (type.strictSubtypeOf(srcType)) {
    if (hoistGuardToLoad(src, type)) {
      return src;
    }
  } else {
    /*
     * incompatible types!  We should just generate a jump here and
     * return null.
     *
     * For now, this case should currently be impossible, but it may
     * come up later due to other optimizations.  The assert is so
     * we'll remember this spot ...
     */
    assert(0);
  }
  return nullptr;
}
开发者ID:beride,项目名称:hiphop-php,代码行数:28,代码来源:simplifier.cpp

示例7: getLocalType

/*
 * Stores a ref (boxed value) to a local. Also handles unsetting a local.
 */
void TraceBuilder::genBindLoc(uint32_t id,
                              SSATmp* newValue,
                              bool doRefCount /* = true */) {
  Type trackedType = getLocalType(id);
  SSATmp* prevValue = 0;
  if (trackedType == Type::None) {
    if (doRefCount) {
      prevValue = gen(LdLoc, Type::Gen, LocalId(id), m_fpValue);
    }
  } else {
    prevValue = getLocalValue(id);
    assert(prevValue == nullptr || prevValue->type() == trackedType);
    if (prevValue == newValue) {
      // Silent store: local already contains value being stored
      // NewValue needs to be decref'ed
      if (!trackedType.notCounted() && doRefCount) {
        gen(DecRef, prevValue);
      }
      return;
    }
    if (trackedType.maybeCounted() && !prevValue && doRefCount) {
      prevValue = gen(LdLoc, trackedType, LocalId(id), m_fpValue);
    }
  }
  bool genStoreType = true;
  if ((trackedType.isBoxed() && newValue->type().isBoxed()) ||
      (trackedType == newValue->type() && !trackedType.isString())) {
    // no need to store type with local value
    genStoreType = false;
  }
  gen(genStoreType ? StLoc : StLocNT, LocalId(id), m_fpValue, newValue);
  if (trackedType.maybeCounted() && doRefCount) {
    gen(DecRef, prevValue);
  }
}
开发者ID:mariusz-szydzik,项目名称:hiphop-php,代码行数:38,代码来源:tracebuilder.cpp

示例8: preOptimizeCheckType

SSATmp* IRBuilder::preOptimizeCheckType(IRInstruction* inst) {
  SSATmp* src  = inst->src(0);
  auto const oldType = src->type();
  auto const newType = inst->typeParam();

  if (oldType.isBoxed() && newType.isBoxed() &&
      (oldType.not(newType) || newType < oldType)) {
    /* This CheckType serves to update the inner type hint for a boxed value,
     * which requires no runtime work. This depends on the type being boxed,
     * and constraining it with DataTypeCountness will do it.  */
    constrainValue(src, DataTypeCountness);
    return gen(AssertType, newType, src);
  }

  if (oldType.not(newType)) {
    /* This check will always fail. It's probably due to an incorrect
     * prediction. Generate a Jmp, and return src because
     * following instructions may depend on the output of CheckType
     * (they'll be DCEd later). Note that we can't use convertToJmp
     * because the return value isn't nullptr, so the original
     * instruction won't be inserted into the stream. */
    gen(Jmp, inst->taken());
    return src;
  }

  if (newType >= oldType) {
    /* The type of the src is the same or more refined than type, so the guard
     * is unnecessary. */
    return src;
  }

  return nullptr;
}
开发者ID:abhiskaushik,项目名称:hhvm,代码行数:33,代码来源:ir-builder.cpp

示例9: simplifyGetCtxFwdCall

SSATmp* Simplifier::simplifyGetCtxFwdCall(IRInstruction* inst) {
  SSATmp*  srcCtx = inst->getSrc(0);
  if (srcCtx->isA(Type::Cctx)) {
    return srcCtx;
  }
  return nullptr;
}
开发者ID:Web5design,项目名称:hiphop-php,代码行数:7,代码来源:simplifier.cpp

示例10: removeUnusedSpillsAux

void LinearScan::removeUnusedSpillsAux(Trace* trace) {
  IRInstruction::List& instList = trace->getInstructionList();
  for (IRInstruction::Iterator it = instList.begin();
       it != instList.end(); ) {
    IRInstruction::Iterator next = it; ++next;
    IRInstruction* inst = *it;
    if (inst->getOpcode() == Spill && inst->getDst()->getUseCount() == 0) {
      instList.erase(it);
      SSATmp* src = inst->getSrc(0);
      if (src->decUseCount() == 0) {
        Opcode srcOpc = src->getInstruction()->getOpcode();
        // Not all instructions are able to take noreg as its dest
        // reg.  We pick LdLoc and IncRef because they occur often.
        if (srcOpc == IncRef || srcOpc == LdLoc) {
          for (int locIndex = 0;
               locIndex < src->numNeededRegs();
               ++locIndex) {
            src->setReg(InvalidReg, locIndex);
          }
        }
      }
    }
    it = next;
  }
}
开发者ID:mambaliu,项目名称:hiphop-php,代码行数:25,代码来源:linearscan.cpp

示例11: if

SSATmp* TraceBuilder::optimizeWork(IRInstruction* inst,
                                   const folly::Optional<IdomVector>& idoms) {
    // Since some of these optimizations inspect tracked state, we don't
    // perform any of them on non-main traces.
    if (m_savedTraces.size() > 0) return nullptr;

    static DEBUG_ONLY __thread int instNest = 0;
    if (debug) ++instNest;
    SCOPE_EXIT { if (debug) --instNest; };
DEBUG_ONLY auto indent = [&] { return std::string(instNest * 2, ' '); };

    FTRACE(1, "{}{}\n", indent(), inst->toString());

    // First pass of tracebuilder optimizations try to replace an
    // instruction based on tracked state before we do anything else.
    // May mutate the IRInstruction in place (and return nullptr) or
    // return an SSATmp*.
    if (SSATmp* preOpt = preOptimize(inst)) {
        FTRACE(1, "  {}preOptimize returned: {}\n",
               indent(), preOpt->inst()->toString());
        return preOpt;
    }
    if (inst->op() == Nop) return nullptr;

    // copy propagation on inst source operands
    copyProp(inst);

    SSATmp* result = nullptr;
    if (m_enableCse && inst->canCSE()) {
        result = cseLookup(inst, idoms);
        if (result) {
            // Found a dominating instruction that can be used instead of inst
            FTRACE(1, "  {}cse found: {}\n",
                   indent(), result->inst()->toString());
            assert(!inst->consumesReferences());
            if (inst->producesReference()) {
                // Replace with an IncRef
                FTRACE(1, "  {}cse of refcount-producing instruction\n", indent());
                return gen(IncRef, result);
            } else {
                return result;
            }
        }
    }

    if (m_enableSimplification) {
        result = m_simplifier.simplify(inst);
        if (result) {
            // Found a simpler instruction that can be used instead of inst
            FTRACE(1, "  {}simplification returned: {}\n",
                   indent(), result->inst()->toString());
            assert(inst->hasDst());
            return result;
        }
    }
    return nullptr;
}
开发者ID:jacano1969,项目名称:hiphop-php,代码行数:57,代码来源:trace-builder.cpp

示例12: hoistConditionalJumps

/**
 * If main trace ends with a conditional jump with no side-effects on exit,
 * hook it to the exitTrace and make it a TraceExitType::NormalCc.
 *
 * This function essentially looks for the following code pattern:
 *
 * Main Trace:
 * ----------
 * L1: // jccBlock
 *    ...
 *    Jcc ... -> L3
 * L2: // lastBlock
 *    DefLabel
 *    [Marker]
 *    ExitTrace
 *
 * Exit Trace:
 * ----------
 * L3: // targetBlock
 *   DefLabel
 *   [Marker]
 *   ExitTraceCc
 *
 * If the pattern is found, Jcc's dst operand is linked to the ExitTrace and
 * ExitTraceCc instructions and it's flagged with kIRDirectJccJmpActive.  This
 * then triggers CodeGenerator to emit a REQ_BIND_JMPCC_FIRST service request.
 *
 */
static void hoistConditionalJumps(Trace* trace, IRFactory* irFactory) {
  IRInstruction* exitInst       = nullptr;
  IRInstruction* exitCcInst     = nullptr;
  Opcode opc = OpAdd;
  // Normally Jcc comes before a Marker
  auto& blocks = trace->getBlocks();
  if (blocks.size() < 2) return;
  auto it = blocks.end();
  Block* lastBlock = *(--it);
  Block* jccBlock  = *(--it);

  IRInstruction& jccInst = *(jccBlock->back());
  if (!jccCanBeDirectExit(jccInst.getOpcode())) return;

  for (auto it = lastBlock->skipLabel(), end = lastBlock->end(); it != end;
       it++) {
    IRInstruction& inst = *it;
    opc = inst.getOpcode();
    if (opc == ExitTrace) {
      exitInst = &inst;
      break;
    }
    if (opc != Marker) {
      // Found real instruction on the last block
      return;
    }
  }
  if (exitInst) {
    SSATmp* dst = jccInst.getDst();
    Block* targetBlock = jccInst.getTaken();
    auto targetInstIter = targetBlock->skipLabel();

    // Check for a NormalCc exit with no side effects
    for (auto it = targetInstIter, end = targetBlock->end(); it != end; ++it) {
      IRInstruction* instr = &*it;
      // Extend to support ExitSlow, ExitSlowNoProgress, ...
      Opcode opc = instr->getOpcode();
      if (opc == ExitTraceCc) {
        exitCcInst = instr;
        break;
      } else if (opc != Marker) {
        // Do not optimize if there are other instructions
        break;
      }
    }

    if (exitCcInst) {
      // Found both exits, link them to Jcc for codegen
      assert(dst);
      exitCcInst->appendSrc(irFactory->arena(), dst);
      exitInst->appendSrc(irFactory->arena(), dst);
      // Set flag so Jcc and exits know this is active
      dst->setTCA(kIRDirectJccJmpActive);
    }
  }
}
开发者ID:devmario,项目名称:hiphop-php,代码行数:84,代码来源:jumpsopts.cpp

示例13: pushFreeReg

void LinearScan::freeReg(RegState* reg) {
  pushFreeReg(reg);
  // The <tmp> shouldn't be reused any more.
  SSATmp* tmp = reg->m_ssaTmp;
  int32 slotId = tmp->getSpillSlot();
  if (slotId != -1) {
    m_slots[slotId].m_latestTmp = NULL;
  }
  reg->m_ssaTmp = NULL;
}
开发者ID:mambaliu,项目名称:hiphop-php,代码行数:10,代码来源:linearscan.cpp

示例14: genLdLoc

SSATmp* TraceBuilder::genLdLocAsCell(uint32_t id, Trace* exitTrace) {
  SSATmp*    tmp = genLdLoc(id);
  Type type = tmp->type();
  assert(type.isBoxed() || type.notBoxed());
  if (!type.isBoxed()) {
    return tmp;
  }
  // Unbox tmp into a cell via a LdRef
  return gen(LdRef, type.innerType(), exitTrace, tmp);
}
开发者ID:mariusz-szydzik,项目名称:hiphop-php,代码行数:10,代码来源:tracebuilder.cpp

示例15: isUnguardedLoad

bool isUnguardedLoad(IRInstruction* inst) {
  Opcode opc = inst->getOpcode();
  SSATmp* dst = inst->getDst();
  if (!dst) return false;
  Type::Tag type = dst->getType();
  return (opc == LdStack && (type == Type::Gen || type == Type::Cell))
          || (opc == LdLoc && type == Type::Gen)
          || (opc == LdRefNR && type == Type::Cell)
          || (opc == LdMemNR && type == Type::Cell &&
              inst->getSrc(0)->getType() == Type::PtrToCell);
}
开发者ID:ezc,项目名称:hiphop-php,代码行数:11,代码来源:dce.cpp


注:本文中的SSATmp类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。