// Compare VirtRegMap::getRegAllocPref(). AllocationOrder::AllocationOrder(unsigned VirtReg, const VirtRegMap &VRM, const BitVector &ReservedRegs) : Pos(0), Reserved(ReservedRegs) { const TargetRegisterClass *RC = VRM.getRegInfo().getRegClass(VirtReg); std::pair<unsigned, unsigned> HintPair = VRM.getRegInfo().getRegAllocationHint(VirtReg); // HintPair.second is a register, phys or virt. Hint = HintPair.second; // Translate to physreg, or 0 if not assigned yet. if (TargetRegisterInfo::isVirtualRegister(Hint)) Hint = VRM.getPhys(Hint); // The remaining allocation order may depend on the hint. tie(Begin, End) = VRM.getTargetRegInfo() .getAllocationOrder(RC, HintPair.first, Hint, VRM.getMachineFunction()); // Target-dependent hints require resolution. if (HintPair.first) Hint = VRM.getTargetRegInfo().ResolveRegAllocHint(HintPair.first, Hint, VRM.getMachineFunction()); // The hint must be a valid physreg for allocation. if (Hint && (!TargetRegisterInfo::isPhysicalRegister(Hint) || !RC->contains(Hint) || ReservedRegs.test(Hint))) Hint = 0; }
/// getAllocatableSetForRC - Toggle the bits that represent allocatable /// registers for the specific register class. static void getAllocatableSetForRC(const MachineFunction &MF, const TargetRegisterClass *RC, BitVector &R){ assert(RC->isAllocatable() && "invalid for nonallocatable sets"); ArrayRef<MCPhysReg> Order = RC->getRawAllocationOrder(MF); for (unsigned i = 0; i != Order.size(); ++i) R.set(Order[i]); }
bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const { // Check Reg and all aliased Registers. for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) if (RegSet.test(*AI)) return true; return false; }
/* do the huffman-decoding */ static int rsf_huffman_decoder(BitVector& bv, struct huffcodetab const* h, // ptr to huffman code record /* unsigned */ int *x, // returns decoded x value /* unsigned */ int *y, // returns decoded y value int* v, int* w) { HUFFBITS level; unsigned point = 0; int error = 1; level = dmask; *x = *y = *v = *w = 0; if (h->val == NULL) return 2; /* table 0 needs no bits */ if (h->treelen == 0) return 0; /* Lookup in Huffman table. */ do { if (h->val[point][0]==0) { /*end of tree*/ *x = h->val[point][1] >> 4; *y = h->val[point][1] & 0xf; error = 0; break; } if (bv.get1Bit()) { while (h->val[point][1] >= MXOFF) point += h->val[point][1]; point += h->val[point][1]; } else { while (h->val[point][0] >= MXOFF) point += h->val[point][0]; point += h->val[point][0]; } level >>= 1; } while (level || (point < h->treelen) );
void TLUserData::write(TLFrame& dest, size_t& wp) const { // Stuff we don't support... assert(!mUDHI); assert(mDCS==0); unsigned numChar = strlen(mData); dest.writeField(wp,numChar,8); // This tail() works because UD is always the last field in the PDU. BitVector chars = dest.tail(wp); chars.zero(); for (unsigned i=0; i<numChar; i++) { char gsm = encodeGSMChar(mData[i]); dest.writeFieldReversed(wp,gsm,7); } chars.LSB8MSB(); }
void BitVector::operator&=(const BitVector& other) { int length = MIN(WordLength(), other.WordLength()); for (int w = 0; w < length; ++w) array_[w] &= other.array_[w]; for (int w = WordLength() - 1; w >= length; --w) array_[w] = 0; }
void print(io::Output& out, const BitVector& v) { t::uint32 w = 0; int c = 0; for(int i = 0; i < v.size(); i++) { if(v.bit(i)) w |= 1 << c; c++; if(c == 31) { out << ' ' << io::hex(w).width(8).pad('0').right(); w = 0; c = 0; } } if(c) out << ' ' << io::hex(w).width(8).pad('0').right(); }
void LLVMOutputStyle::dumpBitVector(StringRef Name, const BitVector &V) { std::vector<uint32_t> Vec; for (uint32_t I = 0, E = V.size(); I != E; ++I) if (V[I]) Vec.push_back(I); P.printList(Name, Vec); }
void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { LLVM_DEBUG(dbgs() << "Determine Callee Saves: " << MF.getName() << "\n"); TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); SavedRegs.set(ARC::BLINK); }
/// Given a specified llvm.global_ctors list, remove the listed elements. static void removeGlobalCtors(GlobalVariable *GCL, const BitVector &CtorsToRemove) { // Filter out the initializer elements to remove. ConstantArray *OldCA = cast<ConstantArray>(GCL->getInitializer()); SmallVector<Constant *, 10> CAList; for (unsigned I = 0, E = OldCA->getNumOperands(); I < E; ++I) if (!CtorsToRemove.test(I)) CAList.push_back(OldCA->getOperand(I)); // Create the new array initializer. ArrayType *ATy = ArrayType::get(OldCA->getType()->getElementType(), CAList.size()); Constant *CA = ConstantArray::get(ATy, CAList); // If we didn't change the number of elements, don't create a new GV. if (CA->getType() == OldCA->getType()) { GCL->setInitializer(CA); return; } // Create the new global and insert it next to the existing list. GlobalVariable *NGV = new GlobalVariable(CA->getType(), GCL->isConstant(), GCL->getLinkage(), CA, "", GCL->getThreadLocalMode()); GCL->getParent()->getGlobalList().insert(GCL->getIterator(), NGV); NGV->takeName(GCL); // Nuke the old list, replacing any uses with the new one. if (!GCL->use_empty()) { Constant *V = NGV; if (V->getType() != GCL->getType()) V = ConstantExpr::getBitCast(V, GCL->getType()); GCL->replaceAllUsesWith(V); } GCL->eraseFromParent(); }
unsigned int DecodeTree::decode(const BitVector& vector,unsigned int *position) { if(root == NULL) { std::cerr<<"DecodeTree need initialize first"<<std::endl; exit(1); } TreeNode *ptr=root; unsigned int index=*position; //unsigned int i; //for(i=0;i<vector.length();i++) //{ //if(ptr!=NULL) //vector.test(index)?(ptr=ptr->right_child):(ptr=ptr->left_child); //else //return UINT_MAX; //} while(ptr != NULL && ptr->info == UINT_MAX) { vector.test(index++)?(ptr=ptr->right_child):(ptr=ptr->left_child); } if(ptr == NULL) { std::cerr<<"decode error"<<std::endl; exit(1); } *position=index; return ptr->info; }
int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C, MachineBasicBlock &MBB) { RegScavenger RS; RS.enterBasicBlock(&MBB); RS.forward(MachineBasicBlock::iterator(G->getStart())); // Can we find an appropriate register that is available throughout the life // of the chain? unsigned RegClassID = G->getStart()->getDesc().OpInfo[0].RegClass; BitVector AvailableRegs = RS.getRegsAvailable(TRI->getRegClass(RegClassID)); for (MachineBasicBlock::iterator I = G->getStart(), E = G->getEnd(); I != E; ++I) { RS.forward(I); AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID)); // Remove any registers clobbered by a regmask or any def register that is // immediately dead. for (auto J : I->operands()) { if (J.isRegMask()) AvailableRegs.clearBitsNotInMask(J.getRegMask()); if (J.isReg() && J.isDef()) { MCRegAliasIterator AI(J.getReg(), TRI, /*IncludeSelf=*/true); if (J.isDead()) for (; AI.isValid(); ++AI) AvailableRegs.reset(*AI); #ifndef NDEBUG else for (; AI.isValid(); ++AI) assert(!AvailableRegs[*AI] && "Non-dead def should have been removed by now!"); #endif } } } // Make sure we allocate in-order, to get the cheapest registers first. auto Ord = RCI.getOrder(TRI->getRegClass(RegClassID)); for (auto Reg : Ord) { if (!AvailableRegs[Reg]) continue; if (C == getColor(Reg)) return Reg; } return -1; }
void BitVector::mergeSlow(const BitVector& other) { if (other.isInline()) { ASSERT(!isInline()); *bits() |= cleanseInlineBits(other.m_bitsOrPointer); return; } ensureSize(other.size()); ASSERT(!isInline()); ASSERT(!other.isInline()); OutOfLineBits* a = outOfLineBits(); const OutOfLineBits* b = other.outOfLineBits(); for (unsigned i = a->numWords(); i--;) a->bits()[i] |= b->bits()[i]; }
void LinearScanMD::LegalizeConstantUse(IR::Instr * instr, IR::Opnd * opnd) { Assert(opnd->IsAddrOpnd() || opnd->IsIntConstOpnd()); intptr_t value = opnd->IsAddrOpnd() ? (intptr_t)opnd->AsAddrOpnd()->m_address : opnd->AsIntConstOpnd()->GetValue(); if (value == 0 && instr->m_opcode == Js::OpCode::MOV && !instr->GetDst()->IsRegOpnd() && TySize[opnd->GetType()] >= 4) { Assert(this->linearScan->instrUseRegs.IsEmpty()); // MOV doesn't have an imm8 encoding for 32-bit/64-bit assignment, so if we have a register available, // we should hoist it and generate xor reg, reg and MOV dst, reg BitVector regsBv; regsBv.Copy(this->linearScan->activeRegs); regsBv.Or(this->linearScan->callSetupRegs); regsBv.ComplimentAll(); regsBv.And(this->linearScan->int32Regs); regsBv.Minus(this->linearScan->tempRegs); // Avoid tempRegs BVIndex regIndex = regsBv.GetNextBit(); if (regIndex != BVInvalidIndex) { instr->HoistSrc1(Js::OpCode::MOV, (RegNum)regIndex); this->linearScan->instrUseRegs.Set(regIndex); this->func->m_regsUsed.Set(regIndex); // If we are in a loop, we need to mark the register being used by the loop so that // reload to that register will not be hoisted out of the loop this->linearScan->RecordLoopUse(nullptr, (RegNum)regIndex); } } }
int testBackWord () { commentator.start ("Testing back_word", __FUNCTION__); bool pass = true; std::ostream &error = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR); static const int n = 3 * WordTraits<BitVector<Endianness>::word_type>::bits; static const int k = 16; BitVector<Endianness> v (n); BitVector<Endianness>::word_iterator w; size_t offset; unsigned int flip = 0; for (offset = 0; offset < WordTraits<BitVector<Endianness>::word_type>::bits; ++offset, flip = 1 - flip) { BitSubvector<BitVector<Endianness>::iterator> vp1 (v.begin () + offset, v.begin () + (offset + k)); BitSubvector<BitVector<Endianness>::const_iterator> vp2 (v.begin () + offset, v.begin () + (offset + WordTraits<BitVector<Endianness>::word_type>::bits)); vp1.back_word () = pattern[flip]; BitVector<Endianness>::word_type check = pattern[flip] & Endianness::mask_left (k); if (vp1.back_word () != check) { error << "ERROR: error at offset " << std::dec << offset << " (rereading back_word)" << std::endl; error << "ERROR: Pattern should be " << std::hex << check << std::endl; error << "ERROR: Detected " << std::hex << vp1.back_word () << std::endl; pass = false; } if (vp2.front_word () != check) { error << "ERROR: error at offset " << std::dec << offset << " (checking against a const subvector)" << std::endl; error << "ERROR: Pattern should be " << std::hex << check << std::endl; error << "ERROR: Detected " << std::hex << vp2.front_word () << std::endl; pass = false; } } commentator.stop (MSG_STATUS (pass)); return pass; }
void AArch64FrameLowering::determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const { // All calls are tail calls in GHC calling conv, and functions have no // prologue/epilogue. if (MF.getFunction()->getCallingConv() == CallingConv::GHC) return; TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>( MF.getSubtarget().getRegisterInfo()); AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); unsigned UnspilledCSGPR = AArch64::NoRegister; unsigned UnspilledCSGPRPaired = AArch64::NoRegister; // The frame record needs to be created by saving the appropriate registers if (hasFP(MF)) { SavedRegs.set(AArch64::FP); SavedRegs.set(AArch64::LR); } unsigned BasePointerReg = AArch64::NoRegister; if (RegInfo->hasBasePointer(MF)) BasePointerReg = RegInfo->getBaseRegister(); bool ExtraCSSpill = false; const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF); // Figure out which callee-saved registers to save/restore. for (unsigned i = 0; CSRegs[i]; ++i) { const unsigned Reg = CSRegs[i]; // Add the base pointer register to SavedRegs if it is callee-save. if (Reg == BasePointerReg) SavedRegs.set(Reg); bool RegUsed = SavedRegs.test(Reg); unsigned PairedReg = CSRegs[i ^ 1]; if (!RegUsed) { if (AArch64::GPR64RegClass.contains(Reg) && !RegInfo->isReservedReg(MF, Reg)) { UnspilledCSGPR = Reg; UnspilledCSGPRPaired = PairedReg; } continue; } // MachO's compact unwind format relies on all registers being stored in // pairs. // FIXME: the usual format is actually better if unwinding isn't needed. if (produceCompactUnwindFrame(MF) && !SavedRegs.test(PairedReg)) { SavedRegs.set(PairedReg); ExtraCSSpill = true; } } DEBUG(dbgs() << "*** determineCalleeSaves\nUsed CSRs:"; for (int Reg = SavedRegs.find_first(); Reg != -1; Reg = SavedRegs.find_next(Reg)) dbgs() << ' ' << PrintReg(Reg, RegInfo); dbgs() << "\n";);