本文整理汇总了C++中IRInstruction类的典型用法代码示例。如果您正苦于以下问题:C++ IRInstruction类的具体用法?C++ IRInstruction怎么用?C++ IRInstruction使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了IRInstruction类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
void TraceBuilder::appendInstruction(IRInstruction* inst) {
if (m_curWhere) {
// We have a specific position to insert instructions.
assert(!inst->isBlockEnd());
auto& it = m_curWhere.get();
it = m_curBlock->insert(it, inst);
++it;
return;
}
Block* block = m_curTrace->back();
if (!block->empty()) {
IRInstruction* prev = block->back();
if (prev->isBlockEnd()) {
// start a new block
Block* next = m_irFactory.defBlock(m_curFunc->getValFunc());
m_curTrace->push_back(next);
if (!prev->isTerminal()) {
// new block is reachable from old block so link it.
block->setNext(next);
}
block = next;
}
}
appendInstruction(inst, block);
updateTrackedState(inst);
}
示例2: elimUnconditionalJump
// If main trace ends with an unconditional jump, and the target is not
// reached by any other branch, then copy the target of the jump to the
// end of the trace
static void elimUnconditionalJump(Trace* trace, IRFactory* irFactory) {
boost::dynamic_bitset<> isJoin(irFactory->numLabels());
boost::dynamic_bitset<> havePred(irFactory->numLabels());
IRInstruction::List& instList = trace->getInstructionList();
for (IRInstruction* inst : instList) {
if (inst->isControlFlowInstruction()) {
auto id = inst->getLabel()->getLabelId();
isJoin[id] = havePred[id];
havePred[id] = 1;
}
}
IRInstruction::Iterator lastInst = instList.end();
--lastInst; // go back to the last instruction
IRInstruction* jmp = *lastInst;
if (jmp->getOpcode() == Jmp_ && !isJoin[jmp->getLabel()->getLabelId()]) {
Trace* targetTrace = jmp->getLabel()->getParent();
IRInstruction::List& targetInstList = targetTrace->getInstructionList();
IRInstruction::Iterator instIter = targetInstList.begin();
instIter++; // skip over label
// update the parent trace of the moved instructions
for (IRInstruction::Iterator it = instIter;
it != targetInstList.end();
++it) {
(*it)->setParent(trace);
}
instList.splice(lastInst, targetInstList, instIter, targetInstList.end());
// delete the jump instruction
instList.erase(lastInst);
}
}
示例3: 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);
}
});
}
示例4: 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();
}
}
示例5: TODO
void LinearScan::collectInfo(BlockList::iterator it, IRTrace* trace) {
m_natives.clear();
m_uses.reset(); // TODO(#2536764): serious time sink
while (it != m_blocks.end()) {
Block* block = *it++;
bool offTrace = block->trace() != trace;
if (offTrace) {
if (!trace->isMain()) return;
int lastId = block->trace()->data();
for (IRInstruction& inst : *block) {
for (auto* src : inst.srcs()) {
if (lastId > m_uses[src].lastUse) {
m_uses[src].lastUse = lastId;
}
}
}
} else {
for (IRInstruction& inst : *block) {
for (auto* src : inst.srcs()) {
m_uses[src].lastUse = m_linear[inst];
}
if (inst.isNative()) m_natives.push_back(&inst);
}
IRInstruction* jmp = block->back();
if (jmp->op() == Jmp_ && jmp->numSrcs() != 0) {
for (SSATmp* src : jmp->srcs()) {
m_jmps[src].push_back(jmp);
}
}
}
}
}
示例6: genBlock
static void genBlock(IRUnit& unit, CodeBlock& cb, CodeBlock& stubsCode,
MCGenerator* mcg, CodegenState& state, Block* block,
std::vector<TransBCMapping>* bcMap) {
FTRACE(6, "genBlock: {}\n", block->id());
std::unique_ptr<CodeGenerator> cg(mcg->backEnd().newCodeGenerator(unit, cb,
stubsCode,
mcg,
state));
BCMarker prevMarker;
for (IRInstruction& instr : *block) {
IRInstruction* inst = &instr;
// If we're on the first instruction of the block or we have a new
// marker since the last instruction, update the bc mapping.
if ((!prevMarker.valid() || inst->marker() != prevMarker) &&
(mcg->tx().isTransDBEnabled() ||
RuntimeOption::EvalJitUseVtuneAPI) && bcMap) {
bcMap->push_back(TransBCMapping{inst->marker().func()->unit()->md5(),
inst->marker().bcOff(),
cb.frontier(),
stubsCode.frontier()});
prevMarker = inst->marker();
}
auto* addr = cg->cgInst(inst);
if (state.asmInfo && addr) {
state.asmInfo->updateForInstruction(inst, addr, cb.frontier());
}
}
}
示例7: genBlock
static void genBlock(IRUnit& unit, CodeBlock& cb, CodeBlock& coldCode,
CodeBlock& frozenCode,
CodegenState& state, Block* block,
std::vector<TransBCMapping>* bcMap) {
FTRACE(6, "genBlock: {}\n", block->id());
std::unique_ptr<CodeGenerator> cg(mcg->backEnd().newCodeGenerator(unit, cb,
coldCode,
frozenCode,
state));
for (IRInstruction& instr : *block) {
IRInstruction* inst = &instr;
if (instr.is(EndGuards)) state.pastGuards = true;
if (bcMap && state.pastGuards &&
(mcg->tx().isTransDBEnabled() || RuntimeOption::EvalJitUseVtuneAPI)) {
// Don't insert an entry in bcMap if the marker corresponds to last entry
// in there.
if (bcMap->empty() ||
bcMap->back().md5 != inst->marker().func()->unit()->md5() ||
bcMap->back().bcStart != inst->marker().bcOff()) {
bcMap->push_back(TransBCMapping{
inst->marker().func()->unit()->md5(),
inst->marker().bcOff(),
mcg->cgFixups().m_tletMain->frontier(),
mcg->cgFixups().m_tletCold->frontier(),
mcg->cgFixups().m_tletFrozen->frontier()});
}
}
auto* start = cb.frontier();
cg->cgInst(inst);
if (state.asmInfo && start < cb.frontier()) {
state.asmInfo->updateForInstruction(inst, start, cb.frontier());
}
}
}
示例8: assert
void TraceBuilder::appendInstruction(IRInstruction* inst) {
if (m_curWhere) {
// We have a specific position to insert instructions.
assert(!inst->isBlockEnd());
auto& it = m_curWhere.get();
it = m_curBlock->insert(it, inst);
++it;
return;
}
Block* block = m_curTrace->back();
if (!block->empty()) {
IRInstruction* prev = &block->back();
if (prev->isBlockEnd()) {
// start a new block
Block* next = m_unit.defBlock();
FTRACE(2, "lazily adding B{}\n", next->id());
m_curTrace->push_back(next);
if (!prev->isTerminal()) {
// new block is reachable from old block so link it.
block->setNext(next);
next->setHint(block->hint());
}
block = next;
}
}
appendInstruction(inst, block);
if (m_savedTraces.empty()) {
// We don't track state on non-main traces for now. t2982555
m_state.update(inst);
}
}
示例9: 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;
}
}
示例10: insertRefCountAsserts
/*
* Insert a DbgAssertRefCount instruction after each place we produce
* a refcounted value. The value must be something we can safely dereference
* to check the _count field.
*/
static void insertRefCountAsserts(IRInstruction& inst, IRUnit& unit) {
for (SSATmp& dst : inst.dsts()) {
Type t = dst.type();
if (t <= (Type::Counted | Type::StaticStr | Type::StaticArr)) {
insertAfter(&inst, unit.gen(DbgAssertRefCount, inst.marker(), &dst));
}
}
}
示例11: always_assert
MethodBlock* MethodBlock::if_else_testz(IROpcode if_op,
Location test,
MethodBlock** true_block) {
always_assert(OPCODE_IF_EQZ <= if_op && if_op <= OPCODE_IF_LEZ);
IRInstruction* op = new IRInstruction(if_op);
op->set_src(0, test.get_reg());
return make_if_else_block(op, true_block);
}
示例12: insertRefCountAsserts
/*
* Insert a DbgAssertRefCount instruction after each place we produce
* a refcounted value. The value must be something we can safely dereference
* to check the _count field.
*/
static void insertRefCountAsserts(IRInstruction& inst, IRFactory& factory) {
for (SSATmp& dst : inst.dsts()) {
Type t = dst.type();
if (t.subtypeOf(Type::Counted | Type::StaticStr | Type::StaticArr)) {
insertAfter(&inst, factory.gen(DbgAssertRefCount, inst.marker(), &dst));
}
}
}
示例13: inst
IRInstruction* IRUnit::defLabel(unsigned numDst, BCMarker marker) {
IRInstruction inst(DefLabel, marker);
IRInstruction* label = cloneInstruction(&inst);
if (numDst > 0) {
SSATmp* dsts = (SSATmp*) m_arena.alloc(numDst * sizeof(SSATmp));
for (unsigned i = 0; i < numDst; ++i) {
new (&dsts[i]) SSATmp(m_nextOpndId++, label);
}
label->setDsts(numDst, dsts);
}
return label;
}
示例14: createSpillSlot
// Create a spill slot for <tmp>.
uint32_t LinearScan::createSpillSlot(SSATmp* tmp) {
uint32_t slotId = m_slots.size();
tmp->setSpillSlot(slotId);
IRInstruction* spillInst = m_irFactory->gen(Spill, tmp);
SSATmp* spillTmp = spillInst->getDst();
SlotInfo si;
si.m_spillTmp = spillTmp;
si.m_latestReload = tmp;
m_slots.push_back(si);
// The spill slot inherits the last use ID of the spilled tmp.
si.m_spillTmp->setLastUseId(tmp->getLastUseId());
return slotId;
}
示例15: spillValueCells
SSATmp* Simplifier::simplifyCall(IRInstruction* inst) {
auto spillVals = inst->getSrcs().subpiece(3);
IRInstruction* spillStack = m_tb->getSp()->getInstruction();
if (spillStack->getOpcode() != SpillStack) {
return nullptr;
}
SSATmp* sp = spillStack->getSrc(0);
int baseOffset = spillStack->getSrc(1)->getValInt() -
spillValueCells(spillStack);
auto const numSpillSrcs = spillVals.size();
for (int32_t i = 0; i < numSpillSrcs; i++) {
const int64_t offset = -(i + 1) + baseOffset;
assert(spillVals[i]->getType() != Type::ActRec);
IRInstruction* srcInst = spillVals[i]->getInstruction();
// If our value came from a LdStack on the same sp and offset,
// we don't need to spill it.
if (srcInst->getOpcode() == LdStack && srcInst->getSrc(0) == sp &&
srcInst->getSrc(1)->getValInt() == offset) {
spillVals[i] = m_tb->genDefNone();
}
}
// Note: although the instruction might have been modified above, we still
// need to return nullptr so that it gets cloned later if it's stack-allocated
return nullptr;
}