本文整理汇总了C++中IRInstruction::dst方法的典型用法代码示例。如果您正苦于以下问题:C++ IRInstruction::dst方法的具体用法?C++ IRInstruction::dst怎么用?C++ IRInstruction::dst使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类IRInstruction
的用法示例。
在下文中一共展示了IRInstruction::dst方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getJmpPreColor
// This function attempts to find a pre-coloring hint from two
// different sources: If tmp comes from a DefLabel, it will scan up to
// the SSATmps providing values to incoming Jmp_s to look for a
// hint. If tmp is consumed by a Jmp_, look for other incoming Jmp_s
// to its destination and see if any of them have already been given a
// register. If all of these fail, let normal register allocation
// proceed unhinted.
RegNumber LinearScan::getJmpPreColor(SSATmp* tmp, uint32_t regIndex,
bool isReload) {
IRInstruction* srcInst = tmp->inst();
const JmpList& jmps = m_jmps[tmp];
if (isReload && (srcInst->op() == DefLabel || !jmps.empty())) {
// If we're precoloring a Reload of a temp that we'd normally find
// a hint for, just return the register allocated to the spilled
// temp.
auto reg = m_allocInfo[tmp].reg(regIndex);
assert(reg != reg::noreg);
return reg;
}
if (srcInst->op() == DefLabel) {
// Figure out which dst of the label is tmp
for (unsigned i = 0, n = srcInst->numDsts(); i < n; ++i) {
if (srcInst->dst(i) == tmp) {
auto reg = findLabelSrcReg(m_allocInfo, srcInst, i, regIndex);
// Until we handle loops, it's a bug to try and allocate a
// register to a DefLabel's dest before all of its incoming
// Jmp_s have had their srcs allocated, unless the incoming
// block is unreachable.
const DEBUG_ONLY bool unreachable =
std::find(m_blocks.begin(), m_blocks.end(),
srcInst->block()) == m_blocks.end();
always_assert(reg != reg::noreg || unreachable);
return reg;
}
}
not_reached();
}
// If srcInst wasn't a label, check if tmp is used by any Jmp_
// instructions. If it is, trace to the Jmp_'s label and use the
// same procedure as above.
for (unsigned ji = 0, jn = jmps.size(); ji < jn; ++ji) {
IRInstruction* jmp = jmps[ji];
IRInstruction* label = jmp->taken()->front();
// Figure out which src of the Jmp_ is tmp
for (unsigned si = 0, sn = jmp->numSrcs(); si < sn; ++si) {
SSATmp* src = jmp->src(si);
if (tmp == src) {
// For now, a DefLabel should never have a register assigned
// to it before any of its incoming Jmp_ instructions.
always_assert(m_allocInfo[label->dst(si)].reg(regIndex) ==
reg::noreg);
auto reg = findLabelSrcReg(m_allocInfo, label, si, regIndex);
if (reg != reg::noreg) return reg;
}
}
}
return reg::noreg;
}
示例2: insertAsserts
/*
* Insert asserts at various points in the IR.
* TODO: t2137231 Insert DbgAssertPtr at points that use or produces a GenPtr
*/
static void insertAsserts(IRTrace* trace, IRFactory& factory) {
forEachTraceBlock(trace, [&](Block* block) {
for (auto it = block->begin(), end = block->end(); it != end; ) {
IRInstruction& inst = *it;
++it;
if (inst.op() == SpillStack) {
insertSpillStackAsserts(inst, factory);
continue;
}
if (inst.op() == Call) {
SSATmp* sp = inst.dst();
IRInstruction* addr = factory.gen(LdStackAddr,
inst.marker(),
Type::PtrToGen,
StackOffset(0),
sp);
insertAfter(&inst, addr);
insertAfter(addr, factory.gen(DbgAssertPtr, inst.marker(),
addr->dst()));
continue;
}
if (!inst.isBlockEnd()) insertRefCountAsserts(inst, factory);
}
});
}
示例3: 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();
}
}
示例4: insertSpillStackAsserts
/*
* Insert a DbgAssertTv instruction for each stack location stored to by
* a SpillStack instruction.
*/
static void insertSpillStackAsserts(IRInstruction& inst, IRFactory* factory) {
SSATmp* sp = inst.dst();
auto const vals = inst.srcs().subpiece(2);
auto* block = inst.block();
auto pos = block->iteratorTo(&inst); ++pos;
for (unsigned i = 0, n = vals.size(); i < n; ++i) {
Type t = vals[i]->type();
if (t.subtypeOf(Type::Gen)) {
IRInstruction* addr = factory->gen(LdStackAddr,
Type::PtrToGen,
StackOffset(i),
sp);
block->insert(pos, addr);
IRInstruction* check = factory->gen(DbgAssertPtr, addr->dst());
block->insert(pos, check);
}
}
}
示例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() {
for (auto& loc : m_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;
}
}
示例6: killLocals
/**
* 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::killLocals() {
for (uint32_t i = 0; i < m_localValues.size(); i++) {
SSATmp* t = m_localValues[i];
// 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);
m_localValues[i] = clone->dst();
continue;
}
assert(!t->isConst());
m_localValues[i] = nullptr;
}
}
示例7: insertAsserts
/*
* Insert asserts at various points in the IR.
* TODO: t2137231 Insert DbgAssertPtr at points that use or produces a GenPtr
*/
static void insertAsserts(IRUnit& unit) {
postorderWalk(unit, [&](Block* block) {
for (auto it = block->begin(), end = block->end(); it != end; ) {
IRInstruction& inst = *it;
++it;
if (inst.op() == SpillStack) {
insertSpillStackAsserts(inst, unit);
continue;
}
if (inst.op() == Call) {
SSATmp* sp = inst.dst();
IRInstruction* addr = unit.gen(LdStackAddr,
inst.marker(),
Type::PtrToGen,
StackOffset(0),
sp);
insertAfter(&inst, addr);
insertAfter(addr, unit.gen(DbgAssertPtr, inst.marker(), addr->dst()));
continue;
}
if (!inst.isBlockEnd()) insertRefCountAsserts(inst, unit);
}
});
}
示例8: allocRegToInstruction
void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
IRInstruction* inst = &*it;
dumpIR<IRInstruction, kExtraLevel>(inst, "allocating to instruction");
// Reload all source operands if necessary.
// Mark registers as unpinned.
for (int regNo = 0; regNo < kNumRegs; ++regNo) {
m_regs[regNo].m_pinned = false;
}
smart::vector<bool> needsReloading(inst->numSrcs(), true);
for (uint32_t i = 0; i < inst->numSrcs(); ++i) {
SSATmp* tmp = inst->src(i);
int32_t slotId = m_spillSlots[tmp];
if (slotId == -1) {
needsReloading[i] = false;
} else if ((tmp = m_slots[slotId].latestReload)) {
needsReloading[i] = false;
inst->setSrc(i, tmp);
}
if (!needsReloading[i]) {
for (int i = 0, n = m_allocInfo[tmp].numAllocatedRegs(); i < n; ++i) {
m_regs[int(m_allocInfo[tmp].reg(i))].m_pinned = true;
}
}
}
for (uint32_t i = 0; i < inst->numSrcs(); ++i) {
if (needsReloading[i]) {
SSATmp* tmp = inst->src(i);
int32_t slotId = m_spillSlots[tmp];
// <tmp> is spilled, and not reloaded.
// Therefore, We need to reload the value into a new SSATmp.
// Insert the Reload instruction.
SSATmp* spillTmp = m_slots[slotId].spillTmp;
IRInstruction* reload = m_unit.gen(Reload, inst->marker(),
spillTmp);
inst->block()->insert(it, reload);
// Create <reloadTmp> which inherits <tmp>'s slot ID and
// <spillTmp>'s last use ID.
// Replace <tmp> with <reloadTmp> in <inst>.
SSATmp* reloadTmp = reload->dst();
m_uses[reloadTmp].lastUse = m_uses[spillTmp].lastUse;
m_spillSlots[reloadTmp] = slotId;
inst->setSrc(i, reloadTmp);
// reloadTmp and tmp share the same type. Since it was spilled, it
// must be using its entire needed-count of registers.
assert(reloadTmp->type() == tmp->type());
for (int locIndex = 0; locIndex < tmp->numNeededRegs();) {
locIndex += allocRegToTmp(reloadTmp, locIndex);
}
// Remember this reload tmp in case we can reuse it in later blocks.
m_slots[slotId].latestReload = reloadTmp;
dumpIR<IRInstruction, kExtraLevel>(reload, "created reload");
}
}
freeRegsAtId(m_linear[inst]);
// Update next native.
if (nextNative() == inst) {
assert(!m_natives.empty());
m_natives.pop_front();
computePreColoringHint();
}
Range<SSATmp*> dsts = inst->dsts();
if (dsts.empty()) return;
Opcode opc = inst->op();
if (opc == DefMIStateBase) {
assert(dsts[0].isA(Type::PtrToCell));
assignRegToTmp(&m_regs[int(rsp)], &dsts[0], 0);
return;
}
for (SSATmp& dst : dsts) {
for (int numAllocated = 0, n = dst.numNeededRegs(); numAllocated < n; ) {
// LdRaw, loading a generator's embedded AR, is the only time we have a
// pointer to an AR that is not in rVmFp.
const bool abnormalFramePtr =
(opc == LdRaw &&
inst->src(1)->getValInt() == RawMemSlot::ContARPtr);
// Note that the point of StashGeneratorSP is to save a StkPtr
// somewhere other than rVmSp. (TODO(#2288359): make rbx not
// special.)
const bool abnormalStkPtr = opc == StashGeneratorSP;
if (!abnormalStkPtr && dst.isA(Type::StkPtr)) {
assert(opc == DefSP ||
opc == ReDefSP ||
opc == ReDefGeneratorSP ||
opc == PassSP ||
opc == DefInlineSP ||
opc == Call ||
opc == CallArray ||
opc == SpillStack ||
opc == SpillFrame ||
opc == CufIterSpillFrame ||
opc == ExceptionBarrier ||
//.........这里部分代码省略.........
示例9: memory_effects_impl
//.........这里部分代码省略.........
AUnknown,
stack_kills | AMIStateTempBase | AMIStateBase
};
}
/*
* DefInlineFP has some special treatment here.
*
* It's logically `publishing' a pointer to a pre-live ActRec, making it
* live. It doesn't actually load from this ActRec, but after it's done this
* the set of things that can load from it is large enough that the easiest
* way to model this is to consider it as a load on behalf of `publishing'
* the ActRec. Once it's published, it's a live activation record, and
* doesn't get written to as if it were a stack slot anymore (we've
* effectively converted AStack locations into a frame until the
* InlineReturn).
*
* TODO(#3634984): Additionally, DefInlineFP is marking may-load on all the
* locals of the outer frame. This is probably not necessary anymore, but we
* added it originally because a store sinking prototype needed to know it
* can't push StLocs past a DefInlineFP, because of reserved registers.
* Right now it's just here because we need to think about and test it before
* removing that set.
*/
case DefInlineFP:
return may_load_store_kill(
AFrameAny | inline_fp_frame(&inst),
/*
* This prevents stack slots from the caller from being sunk into the
* callee. Note that some of these stack slots overlap with the frame
* locals of the callee-- those slots are inacessible in the inlined
* call as frame and stack locations may not alias.
*/
stack_below(inst.dst(), 0),
/*
* While not required for correctness adding these slots to the kill set
* will hopefully avoid some extra stores.
*/
stack_below(inst.dst(), 0)
);
case InlineReturn:
return ReturnEffects { stack_below(inst.src(0), 2) | AMIStateAny };
case InlineReturnNoFrame:
return ReturnEffects {
AliasClass(AStack {
inst.extra<InlineReturnNoFrame>()->frameOffset.offset,
std::numeric_limits<int32_t>::max()
}) | AMIStateAny
};
case InterpOne:
return interp_one_effects(inst);
case InterpOneCF:
return ExitEffects {
AUnknown,
stack_below(inst.src(1), -inst.marker().spOff().offset - 1) | AMIStateAny
};
case NativeImpl:
return UnknownEffects {};
// NB: on the failure path, these C++ helpers do a fixup and read frame
// locals before they throw. They can also invoke the user error handler and
// go do whatever they want to non-frame locations.