Example #1
0
// 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;
}
Example #2
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]);
}
Example #3
0
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;
}
Example #4
0
/* 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();
}
Example #6
0
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;
}
Example #7
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();
}
Example #8
0
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);
}
Example #9
0
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);
}
Example #10
0
/// 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();
}
Example #11
0
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];
}
Example #14
0
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);
        }
    }
}
Example #15
0
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;
}
Example #16
0
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";);