本文整理汇总了C++中RegSet类的典型用法代码示例。如果您正苦于以下问题:C++ RegSet类的具体用法?C++ RegSet怎么用?C++ RegSet使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了RegSet类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: emitCall
Vpoint emitCall(Vout& v, CppCall call, RegSet args) {
PhysReg arg0(argReg(0));
PhysReg rHostCall(rHostCallReg);
switch (call.kind()) {
case CppCall::Kind::Direct:
v << ldimm{reinterpret_cast<intptr_t>(call.address()), rHostCall};
break;
case CppCall::Kind::Virtual:
v << loadq{arg0[0], rHostCall};
v << loadq{rHostCall[call.vtableOffset()], rHostCall};
break;
case CppCall::Kind::IndirectReg:
case CppCall::Kind::IndirectVreg:
// call indirect currently not implemented. It'll be something like
// a.Br(x2a(call.getReg()))
not_implemented();
always_assert(0);
break;
case CppCall::Kind::ArrayVirt:
case CppCall::Kind::Destructor:
not_implemented();
always_assert(0);
break;
}
uint8_t argc = args.size();
args.add(rHostCall);
auto fixupAddr = v.makePoint();
v << hostcall{args, argc, fixupAddr};
return fixupAddr;
}
示例2: TRACE
void
RegAlloc::reset() {
TRACE(1, ">>> regalloc reset! <<<\n");
m_epoch = 0;
m_contToRegMap.clear();
// m_info is sparse.
for (int i = 0; i < kMaxRegs; ++i) {
m_info[i].m_epoch = 0;
m_info[i].m_pReg = PhysReg(i);
m_info[i].m_cont = RegContent();
m_info[i].m_type = KindOfInvalid;
m_info[i].m_state = RegInfo::INVALID;
}
RegSet all = m_allRegs;
PhysReg pr;
for (int i = 0; all.findFirst(pr); i++) {
all.remove(pr);
physRegToInfo(pr)->m_pReg = PhysReg(pr);
stateTransition(physRegToInfo(pr), RegInfo::FREE);
// Put the most favorable register last, so it is picked first.
m_lru[(m_numRegs - 1) - i] = pr;
}
m_branchSynced = false;
verify();
}
示例3: checkShuffle
/*
* Check that each destination register or spill slot is unique,
* and that sources have the same number or less operands than
* destinations.
*/
bool checkShuffle(const IRInstruction& inst, const RegAllocInfo& regs) {
auto n = inst.numSrcs();
assert(n == inst.extra<Shuffle>()->size);
RegSet destRegs;
std::bitset<NumPreAllocatedSpillLocs> destSlots;
auto& inst_regs = regs[inst];
for (uint32_t i = 0; i < n; ++i) {
DEBUG_ONLY auto& rs = inst_regs.src(i);
DEBUG_ONLY auto& rd = inst.extra<Shuffle>()->dests[i];
if (rd.numAllocated() == 0) continue; // dest was unused; ignore.
if (rd.spilled()) {
assert(!rs.spilled()); // no mem-mem copies
} else {
// rs could have less assigned registers/slots than rd, in these cases:
// - when rs is empty, because the source is a constant.
// - when rs has 1 register because it's untagged but rd needs 2 because
// it's a more general (tagged) type, because of a phi.
assert(rs.numWords() <= rd.numWords());
assert(rs.spilled() || rs.isFullSIMD() == rd.isFullSIMD());
}
for (int j = 0; j < rd.numAllocated(); ++j) {
if (rd.spilled()) {
assert(!destSlots.test(rd.slot(j)));
destSlots.set(rd.slot(j));
} else {
assert(!destRegs.contains(rd.reg(j))); // no duplicate dests
destRegs.add(rd.reg(j));
}
}
}
return true;
}
示例4: allocate
void Vxls::allocate(Interval* current) {
PhysReg::Map<unsigned> free_until; // 0 by default
RegSet allow;
unsigned conflict = constrain(current, allow);
allow.forEach([&](PhysReg r) { free_until[r] = conflict; });
for (auto ivl : active) {
free_until[ivl->reg] = 0;
}
for (auto ivl : inactive) {
auto until = current->nextIntersect(ivl);
free_until[ivl->reg] = std::min(until, free_until[ivl->reg]);
}
auto r = find(free_until);
auto pos = free_until[r];
if (pos >= current->end()) {
return assignReg(current, r);
}
if (pos > current->start()) {
// r is free for the first part of current
auto prev_use = current->lastUseBefore(pos);
auto min_split = std::max(prev_use, current->start() + 1);
auto max_split = pos;
assert(min_split <= max_split);
auto split_pos = std::max(min_split, max_split); // todo: find good spot
split_pos = nearestSplitBefore(split_pos);
if (split_pos > current->start()) {
auto second = current->split(split_pos, true);
pending.push(second);
return assignReg(current, r);
}
}
// must spill current or another victim
allocBlocked(current);
}
示例5: regs
RegSet PhysLoc::regs() const {
RegSet regs;
if (hasReg(0)) {
regs.add(reg(0));
if (hasReg(1)) regs.add(reg(1));
}
return regs;
}
示例6: getEffects
void getEffects(const Abi& abi, const Vinstr& i,
RegSet& uses, RegSet& across, RegSet& defs) {
uses = defs = across = RegSet();
switch (i.op) {
case Vinstr::mccall:
case Vinstr::call:
case Vinstr::callm:
case Vinstr::callr:
defs = abi.all() - abi.calleeSaved;
switch (arch()) {
case Arch::ARM:
defs.add(PhysReg(arm::rLinkReg));
defs.remove(PhysReg(arm::rVmFp));
break;
case Arch::X64:
defs.remove(reg::rbp);
break;
}
break;
case Vinstr::bindcall:
defs = abi.all();
switch (arch()) {
case Arch::ARM: break;
case Arch::X64: defs.remove(x64::rVmTl); break;
}
break;
case Vinstr::contenter:
case Vinstr::callstub:
defs = abi.all();
switch (arch()) {
case Arch::ARM: defs.remove(PhysReg(arm::rVmFp)); break;
case Arch::X64: defs -= reg::rbp | x64::rVmTl; break;
}
break;
case Vinstr::cqo:
uses = RegSet(reg::rax);
defs = reg::rax | reg::rdx;
break;
case Vinstr::idiv:
uses = defs = reg::rax | reg::rdx;
break;
case Vinstr::shlq:
case Vinstr::sarq:
across = RegSet(reg::rcx);
break;
// arm instrs
case Vinstr::hostcall:
defs = (abi.all() - abi.calleeSaved) |
RegSet(PhysReg(arm::rHostCallReg));
break;
case Vinstr::vcall:
case Vinstr::vinvoke:
case Vinstr::vcallstub:
always_assert(false && "Unsupported instruction in vxls");
default:
break;
}
}
示例7: cgCallHelper
void CodeGenerator::cgCallHelper(Vout& v,
CppCall call,
const CallDest& dstInfo,
SyncOptions sync,
ArgGroup& args) {
auto dstReg0 = dstInfo.reg0;
DEBUG_ONLY auto dstReg1 = dstInfo.reg1;
RegSet argRegs;
for (size_t i = 0; i < args.numGpArgs(); i++) {
auto const r = rarg(i);
args.gpArg(i).setDstReg(r);
argRegs.add(r);
}
always_assert_flog(
args.numStackArgs() == 0,
"Stack arguments not yet supported on ARM: `{}'",
*m_curInst
);
shuffleArgs(v, args, call);
auto syncPoint = emitCall(v, call, argRegs);
if (RuntimeOption::HHProfServerEnabled || sync != SyncOptions::kNoSyncPoint) {
recordHostCallSyncPoint(v, syncPoint);
}
auto* taken = m_curInst->taken();
if (taken && taken->isCatch()) {
assert_not_implemented(args.numStackArgs() == 0);
auto next = v.makeBlock();
v << hcunwind{syncPoint, {next, m_state.labels[taken]}};
v = next;
} else if (!m_curInst->is(Call, CallArray, ContEnter)) {
v << hcnocatch{syncPoint};
}
switch (dstInfo.type) {
case DestType::TV: CG_PUNT(cgCall-ReturnTV);
case DestType::SIMD: CG_PUNT(cgCall-ReturnSIMD);
case DestType::SSA:
case DestType::Byte:
assertx(dstReg1 == InvalidReg);
v << copy{PhysReg(vixl::x0), dstReg0};
break;
case DestType::None:
assertx(dstReg0 == InvalidReg && dstReg1 == InvalidReg);
break;
case DestType::Dbl:
assertx(dstReg1 == InvalidReg);
v << copy{PhysReg(vixl::d0), dstReg0};
break;
}
}
示例8: allocBlocked
// When all registers are in use, find a good interval to split and spill,
// which could be the current interval. When an interval is split and the
// second part is spilled, possibly split the second part again before the
// next use-pos that requires a register, and enqueue the third part.
void Vxls::allocBlocked(Interval* current) {
PhysReg::Map<unsigned> used, blocked;
RegSet allow;
unsigned conflict = constrain(current, allow); // repeated from allocate
allow.forEach([&](PhysReg r) { used[r] = blocked[r] = conflict; });
auto const cur_start = current->start();
// compute next use of active registers, so we can pick the furthest one
for (auto ivl : active) {
if (ivl->fixed()) {
blocked[ivl->reg] = used[ivl->reg] = 0;
} else {
auto use_pos = ivl->firstUseAfter(cur_start);
used[ivl->reg] = std::min(use_pos, used[ivl->reg]);
}
}
// compute next intersection/use of inactive regs to find whats free longest
for (auto ivl : inactive) {
auto intersect_pos = current->nextIntersect(ivl);
if (intersect_pos == kMaxPos) continue;
if (ivl->fixed()) {
blocked[ivl->reg] = std::min(intersect_pos, blocked[ivl->reg]);
used[ivl->reg] = std::min(blocked[ivl->reg], used[ivl->reg]);
} else {
auto use_pos = ivl->firstUseAfter(cur_start);
used[ivl->reg] = std::min(use_pos, used[ivl->reg]);
}
}
// choose the best victim register(s) to spill
auto r = find(used);
auto used_pos = used[r];
if (used_pos < current->firstUse()) {
// all other intervals are used before current's first register-use
return spill(current);
}
auto block_pos = blocked[r];
if (block_pos < current->end()) {
auto prev_use = current->lastUseBefore(block_pos);
auto min_split = std::max(prev_use, cur_start + 1);
auto max_split = block_pos;
assert(cur_start < min_split && min_split <= max_split);
auto split_pos = std::max(min_split, max_split);
split_pos = nearestSplitBefore(split_pos);
if (split_pos > current->start()) {
auto second = current->split(split_pos, true);
pending.push(second);
}
}
spillOthers(current, r);
assignReg(current, r);
}
示例9: show
std::string show(RegSet regs) {
std::ostringstream out;
auto sep = "";
out << '{';
regs.forEach([&](PhysReg r) {
out << sep << show(r);
sep = ", ";
});
out << '}';
return out.str();
}
示例10:
PhysRegSaverParity::PhysRegSaverParity(int parity, X64Assembler& as,
RegSet regs)
: m_as(as)
, m_regs(regs)
, m_adjust((parity & 0x1) == (regs.size() & 0x1) ? 8 : 0)
{
m_regs.forEach([&] (PhysReg pr) {
m_as. push (pr);
});
if (m_adjust) {
// Maintain stack evenness for SIMD compatibility.
m_as. subq (m_adjust, reg::rsp);
}
}
示例11: show
std::string show(RegSet regs) {
auto& backEnd = mcg->backEnd();
std::ostringstream out;
auto sep = "";
out << '{';
regs.forEach([&](PhysReg r) {
out << sep;
backEnd.streamPhysReg(out, r);
sep = ", ";
});
out << '}';
return out.str();
}
示例12: p
std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
const LiveIntervals *lis,
const MachineLoopInfo *loopInfo,
const RegSet &vregs) {
typedef std::vector<const LiveInterval*> LIVector;
MachineRegisterInfo *mri = &mf->getRegInfo();
const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo();
std::auto_ptr<PBQPRAProblem> p(new PBQPRAProblem());
PBQP::Graph &g = p->getGraph();
RegSet pregs;
// Collect the set of preg intervals, record that they're used in the MF.
for (LiveIntervals::const_iterator itr = lis->begin(), end = lis->end();
itr != end; ++itr) {
if (TargetRegisterInfo::isPhysicalRegister(itr->first)) {
pregs.insert(itr->first);
mri->setPhysRegUsed(itr->first);
}
}
BitVector reservedRegs = tri->getReservedRegs(*mf);
// Iterate over vregs.
for (RegSet::const_iterator vregItr = vregs.begin(), vregEnd = vregs.end();
vregItr != vregEnd; ++vregItr) {
unsigned vreg = *vregItr;
const TargetRegisterClass *trc = mri->getRegClass(vreg);
const LiveInterval *vregLI = &lis->getInterval(vreg);
// Compute an initial allowed set for the current vreg.
typedef std::vector<unsigned> VRAllowed;
VRAllowed vrAllowed;
ArrayRef<unsigned> rawOrder = trc->getRawAllocationOrder(*mf);
for (unsigned i = 0; i != rawOrder.size(); ++i) {
unsigned preg = rawOrder[i];
if (!reservedRegs.test(preg)) {
vrAllowed.push_back(preg);
}
}
// Remove any physical registers which overlap.
for (RegSet::const_iterator pregItr = pregs.begin(),
pregEnd = pregs.end();
pregItr != pregEnd; ++pregItr) {
unsigned preg = *pregItr;
const LiveInterval *pregLI = &lis->getInterval(preg);
if (pregLI->empty()) {
continue;
}
if (!vregLI->overlaps(*pregLI)) {
continue;
}
// Remove the register from the allowed set.
VRAllowed::iterator eraseItr =
std::find(vrAllowed.begin(), vrAllowed.end(), preg);
if (eraseItr != vrAllowed.end()) {
vrAllowed.erase(eraseItr);
}
// Also remove any aliases.
const unsigned *aliasItr = tri->getAliasSet(preg);
if (aliasItr != 0) {
for (; *aliasItr != 0; ++aliasItr) {
VRAllowed::iterator eraseItr =
std::find(vrAllowed.begin(), vrAllowed.end(), *aliasItr);
if (eraseItr != vrAllowed.end()) {
vrAllowed.erase(eraseItr);
}
}
}
}
// Construct the node.
PBQP::Graph::NodeItr node =
g.addNode(PBQP::Vector(vrAllowed.size() + 1, 0));
// Record the mapping and allowed set in the problem.
p->recordVReg(vreg, node, vrAllowed.begin(), vrAllowed.end());
PBQP::PBQPNum spillCost = (vregLI->weight != 0.0) ?
vregLI->weight : std::numeric_limits<PBQP::PBQPNum>::min();
addSpillCosts(g.getNodeCosts(node), spillCost);
}
for (RegSet::const_iterator vr1Itr = vregs.begin(), vrEnd = vregs.end();
vr1Itr != vrEnd; ++vr1Itr) {
unsigned vr1 = *vr1Itr;
const LiveInterval &l1 = lis->getInterval(vr1);
const PBQPRAProblem::AllowedSet &vr1Allowed = p->getAllowedSet(vr1);
for (RegSet::const_iterator vr2Itr = llvm::next(vr1Itr);
//.........这里部分代码省略.........
示例13: p
PBQPRAProblem *PBQPBuilder::build(MachineFunction *mf, const LiveIntervals *lis,
const MachineBlockFrequencyInfo *mbfi,
const RegSet &vregs) {
LiveIntervals *LIS = const_cast<LiveIntervals*>(lis);
MachineRegisterInfo *mri = &mf->getRegInfo();
const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo();
OwningPtr<PBQPRAProblem> p(new PBQPRAProblem());
PBQP::Graph &g = p->getGraph();
RegSet pregs;
// Collect the set of preg intervals, record that they're used in the MF.
for (unsigned Reg = 1, e = tri->getNumRegs(); Reg != e; ++Reg) {
if (mri->def_empty(Reg))
continue;
pregs.insert(Reg);
mri->setPhysRegUsed(Reg);
}
// Iterate over vregs.
for (RegSet::const_iterator vregItr = vregs.begin(), vregEnd = vregs.end();
vregItr != vregEnd; ++vregItr) {
unsigned vreg = *vregItr;
const TargetRegisterClass *trc = mri->getRegClass(vreg);
LiveInterval *vregLI = &LIS->getInterval(vreg);
// Record any overlaps with regmask operands.
BitVector regMaskOverlaps;
LIS->checkRegMaskInterference(*vregLI, regMaskOverlaps);
// Compute an initial allowed set for the current vreg.
typedef std::vector<unsigned> VRAllowed;
VRAllowed vrAllowed;
ArrayRef<uint16_t> rawOrder = trc->getRawAllocationOrder(*mf);
for (unsigned i = 0; i != rawOrder.size(); ++i) {
unsigned preg = rawOrder[i];
if (mri->isReserved(preg))
continue;
// vregLI crosses a regmask operand that clobbers preg.
if (!regMaskOverlaps.empty() && !regMaskOverlaps.test(preg))
continue;
// vregLI overlaps fixed regunit interference.
bool Interference = false;
for (MCRegUnitIterator Units(preg, tri); Units.isValid(); ++Units) {
if (vregLI->overlaps(LIS->getRegUnit(*Units))) {
Interference = true;
break;
}
}
if (Interference)
continue;
// preg is usable for this virtual register.
vrAllowed.push_back(preg);
}
// Construct the node.
PBQP::Graph::NodeItr node =
g.addNode(PBQP::Vector(vrAllowed.size() + 1, 0));
// Record the mapping and allowed set in the problem.
p->recordVReg(vreg, node, vrAllowed.begin(), vrAllowed.end());
PBQP::PBQPNum spillCost = (vregLI->weight != 0.0) ?
vregLI->weight : std::numeric_limits<PBQP::PBQPNum>::min();
addSpillCosts(g.getNodeCosts(node), spillCost);
}
for (RegSet::const_iterator vr1Itr = vregs.begin(), vrEnd = vregs.end();
vr1Itr != vrEnd; ++vr1Itr) {
unsigned vr1 = *vr1Itr;
const LiveInterval &l1 = lis->getInterval(vr1);
const PBQPRAProblem::AllowedSet &vr1Allowed = p->getAllowedSet(vr1);
for (RegSet::const_iterator vr2Itr = llvm::next(vr1Itr);
vr2Itr != vrEnd; ++vr2Itr) {
unsigned vr2 = *vr2Itr;
const LiveInterval &l2 = lis->getInterval(vr2);
const PBQPRAProblem::AllowedSet &vr2Allowed = p->getAllowedSet(vr2);
assert(!l2.empty() && "Empty interval in vreg set?");
if (l1.overlaps(l2)) {
PBQP::Graph::EdgeItr edge =
g.addEdge(p->getNodeForVReg(vr1), p->getNodeForVReg(vr2),
PBQP::Matrix(vr1Allowed.size()+1, vr2Allowed.size()+1, 0));
addInterferenceCosts(g.getEdgeCosts(edge), vr1Allowed, vr2Allowed, tri);
}
}
}
return p.take();
}
示例14: getEffects
void getEffects(const Abi& abi, const Vinstr& i,
RegSet& uses, RegSet& across, RegSet& defs) {
uses = defs = across = RegSet();
switch (i.op) {
case Vinstr::mccall:
case Vinstr::call:
case Vinstr::callm:
case Vinstr::callr:
defs = abi.all() - (abi.calleeSaved | rvmfp());
switch (arch()) {
case Arch::ARM: defs.add(PhysReg(arm::rLinkReg)); break;
case Arch::X64: break;
case Arch::PPC64: not_implemented(); break;
}
break;
case Vinstr::bindcall:
defs = abi.all();
switch (arch()) {
case Arch::ARM: break;
case Arch::X64: defs.remove(rvmtl()); break;
case Arch::PPC64: not_implemented(); break;
}
break;
case Vinstr::contenter:
case Vinstr::callarray:
defs = abi.all() - RegSet(rvmfp());
switch (arch()) {
case Arch::ARM: break;
case Arch::X64: defs.remove(rvmtl()); break;
case Arch::PPC64: not_implemented(); break;
}
break;
case Vinstr::callfaststub:
defs = abi.all() - abi.calleeSaved - abi.gpUnreserved;
break;
case Vinstr::cqo:
uses = RegSet(reg::rax);
defs = reg::rax | reg::rdx;
break;
case Vinstr::idiv:
uses = defs = reg::rax | reg::rdx;
break;
case Vinstr::shlq:
case Vinstr::sarq:
across = RegSet(reg::rcx);
break;
// arm instrs
case Vinstr::hostcall:
defs = (abi.all() - abi.calleeSaved) |
RegSet(PhysReg(arm::rHostCallReg));
break;
case Vinstr::vcall:
case Vinstr::vinvoke:
case Vinstr::vcallarray:
always_assert(false && "Unsupported instruction in vxls");
default:
break;
}
}
示例15: emitPops
void PhysRegSaverParity::emitPops(X64Assembler& as, RegSet regs) {
regs.forEachR([&] (PhysReg pr) {
as. pop (pr);
});
}