本文整理汇总了C++中APInt::zextOrTrunc方法的典型用法代码示例。如果您正苦于以下问题:C++ APInt::zextOrTrunc方法的具体用法?C++ APInt::zextOrTrunc怎么用?C++ APInt::zextOrTrunc使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类APInt
的用法示例。
在下文中一共展示了APInt::zextOrTrunc方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: fromBitPattern
EnumPayload EnumPayload::fromBitPattern(IRGenModule &IGM,
APInt bitPattern,
EnumPayloadSchema schema) {
EnumPayload result;
schema.forEachType(IGM, [&](llvm::Type *type) {
unsigned bitSize = IGM.DataLayout.getTypeSizeInBits(type);
llvm::IntegerType *intTy
= llvm::IntegerType::get(IGM.getLLVMContext(), bitSize);
// Take some bits off of the bottom of the pattern.
auto bits = bitPattern.zextOrTrunc(bitSize);
auto val = llvm::ConstantInt::get(intTy, bits);
if (val->getType() != type) {
if (type->isPointerTy())
val = llvm::ConstantExpr::getIntToPtr(val, type);
else
val = llvm::ConstantExpr::getBitCast(val, type);
}
result.PayloadValues.push_back(val);
// Shift the remaining bits down.
bitPattern = bitPattern.lshr(bitSize);
});
return result;
}
示例2: CheckedZextOrTrunc
/// When we're compiling N-bit code, and the user uses parameters that are
/// greater than N bits (e.g. uint64_t on a 32-bit build), we can run into
/// trouble with APInt size issues. This function handles resizing + overflow
/// checks for us. Check and zext or trunc \p I depending on IntTyBits and
/// I's value.
bool ObjectSizeOffsetVisitor::CheckedZextOrTrunc(APInt &I) {
// More bits than we can handle. Checking the bit width isn't necessary, but
// it's faster than checking active bits, and should give `false` in the
// vast majority of cases.
if (I.getBitWidth() > IntTyBits && I.getActiveBits() > IntTyBits)
return false;
if (I.getBitWidth() != IntTyBits)
I = I.zextOrTrunc(IntTyBits);
return true;
}
示例3: getPayloadType
void
EnumPayload::emitApplyAndMask(IRGenFunction &IGF, APInt mask) {
// Early exit if the mask has no effect.
if (mask.isAllOnesValue())
return;
auto &DL = IGF.IGM.DataLayout;
for (auto &pv : PayloadValues) {
auto payloadTy = getPayloadType(pv);
unsigned size = DL.getTypeSizeInBits(payloadTy);
// Break off a chunk of the mask.
auto maskPiece = mask.zextOrTrunc(size);
mask = mask.lshr(size);
// If this piece is all ones, it has no effect.
if (maskPiece.isAllOnesValue())
continue;
// If the payload value is vacant, the mask can't change it.
if (pv.is<llvm::Type *>())
continue;
// If this piece is zero, it wipes out the chunk entirely, and we can
// drop it.
if (maskPiece == 0) {
pv = payloadTy;
continue;
}
// Otherwise, apply the mask to the existing value.
auto v = pv.get<llvm::Value*>();
auto payloadIntTy = llvm::IntegerType::get(IGF.IGM.getLLVMContext(), size);
auto maskConstant = llvm::ConstantInt::get(payloadIntTy, maskPiece);
v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
v = IGF.Builder.CreateAnd(v, maskConstant);
v = IGF.Builder.CreateBitOrPointerCast(v, payloadTy);
pv = v;
}
}
示例4: ComputeMaskedBits
//.........这里部分代码省略.........
}
case Instruction::Select:
ComputeMaskedBits(I->getOperand(2), Mask, KnownZero, KnownOne, TD, Depth+1);
ComputeMaskedBits(I->getOperand(1), Mask, KnownZero2, KnownOne2, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?");
// Only known if known in both the LHS and RHS.
KnownOne &= KnownOne2;
KnownZero &= KnownZero2;
return;
case Instruction::FPTrunc:
case Instruction::FPExt:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::SIToFP:
case Instruction::UIToFP:
return; // Can't work with floating point.
case Instruction::PtrToInt:
case Instruction::IntToPtr:
// We can't handle these if we don't know the pointer size.
if (!TD) return;
// FALL THROUGH and handle them the same as zext/trunc.
case Instruction::ZExt:
case Instruction::Trunc: {
// Note that we handle pointer operands here because of inttoptr/ptrtoint
// which fall through here.
const Type *SrcTy = I->getOperand(0)->getType();
unsigned SrcBitWidth = TD ?
TD->getTypeSizeInBits(SrcTy) :
SrcTy->getPrimitiveSizeInBits();
APInt MaskIn(Mask);
MaskIn.zextOrTrunc(SrcBitWidth);
KnownZero.zextOrTrunc(SrcBitWidth);
KnownOne.zextOrTrunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
KnownZero.zextOrTrunc(BitWidth);
KnownOne.zextOrTrunc(BitWidth);
// Any top bits are known to be zero.
if (BitWidth > SrcBitWidth)
KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth);
return;
}
case Instruction::BitCast: {
const Type *SrcTy = I->getOperand(0)->getType();
if (SrcTy->isInteger() || isa<PointerType>(SrcTy)) {
ComputeMaskedBits(I->getOperand(0), Mask, KnownZero, KnownOne, TD,
Depth+1);
return;
}
break;
}
case Instruction::SExt: {
// Compute the bits in the result that are not present in the input.
const IntegerType *SrcTy = cast<IntegerType>(I->getOperand(0)->getType());
unsigned SrcBitWidth = SrcTy->getBitWidth();
APInt MaskIn(Mask);
MaskIn.trunc(SrcBitWidth);
KnownZero.trunc(SrcBitWidth);
KnownOne.trunc(SrcBitWidth);
ComputeMaskedBits(I->getOperand(0), MaskIn, KnownZero, KnownOne, TD,
Depth+1);
assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");
示例5: emitSubSwitch
static void emitSubSwitch(IRGenFunction &IGF,
MutableArrayRef<EnumPayload::LazyValue> values,
APInt mask,
MutableArrayRef<std::pair<APInt, llvm::BasicBlock *>> cases,
SwitchDefaultDest dflt) {
recur:
assert(!values.empty() && "didn't exit out when exhausting all values?!");
assert(!cases.empty() && "switching with no cases?!");
auto &DL = IGF.IGM.DataLayout;
auto &pv = values.front();
values = values.slice(1);
auto payloadTy = getPayloadType(pv);
unsigned size = DL.getTypeSizeInBits(payloadTy);
// Grab a chunk of the mask.
auto maskPiece = mask.zextOrTrunc(size);
mask = mask.lshr(size);
// If the piece is zero, this doesn't affect the switch. We can just move
// forward and recur.
if (maskPiece == 0) {
for (auto &casePair : cases)
casePair.first = casePair.first.lshr(size);
goto recur;
}
// Force the value we will test.
auto v = forcePayloadValue(pv);
auto payloadIntTy = llvm::IntegerType::get(IGF.IGM.getLLVMContext(), size);
// Need to coerce to integer for 'icmp eq' if it's not already an integer
// or pointer. (Switching or masking will also require a cast to integer.)
if (!isa<llvm::IntegerType>(v->getType())
&& !isa<llvm::PointerType>(v->getType()))
v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
// Apply the mask if it's interesting.
if (!maskPiece.isAllOnesValue()) {
v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
auto maskConstant = llvm::ConstantInt::get(payloadIntTy, maskPiece);
v = IGF.Builder.CreateAnd(v, maskConstant);
}
// Gather the values we will switch over for this payload chunk.
// FIXME: std::map is lame. Should hash APInts.
std::map<APInt, SmallVector<std::pair<APInt, llvm::BasicBlock*>, 2>, ult>
subCases;
for (auto casePair : cases) {
// Grab a chunk of the value.
auto valuePiece = casePair.first.zextOrTrunc(size);
// Index the case according to this chunk.
subCases[valuePiece].push_back({std::move(casePair.first).lshr(size),
casePair.second});
}
bool needsAdditionalCases = !values.empty() && mask != 0;
SmallVector<std::pair<llvm::BasicBlock *, decltype(cases)>, 2> recursiveCases;
auto blockForCases
= [&](MutableArrayRef<std::pair<APInt, llvm::BasicBlock*>> cases)
-> llvm::BasicBlock *
{
// If we need to recur, emit a new block.
if (needsAdditionalCases) {
auto newBB = IGF.createBasicBlock("");
recursiveCases.push_back({newBB, cases});
return newBB;
}
// Otherwise, we can jump directly to the ultimate destination.
assert(cases.size() == 1 && "more than one case for final destination?!");
return cases.front().second;
};
// If there's only one case, do a cond_br.
if (subCases.size() == 1) {
auto &subCase = *subCases.begin();
llvm::BasicBlock *block = blockForCases(subCase.second);
// If the default case is unreachable, we don't need to conditionally
// branch.
if (dflt.getInt()) {
IGF.Builder.CreateBr(block);
goto next;
}
auto &valuePiece = subCase.first;
llvm::Value *valueConstant = llvm::ConstantInt::get(payloadIntTy,
valuePiece);
valueConstant = IGF.Builder.CreateBitOrPointerCast(valueConstant,
v->getType());
auto cmp = IGF.Builder.CreateICmpEQ(v, valueConstant);
IGF.Builder.CreateCondBr(cmp, block, dflt.getPointer());
goto next;
}
// Otherwise, do a switch.
{
v = IGF.Builder.CreateBitOrPointerCast(v, payloadIntTy);
//.........这里部分代码省略.........
示例6: APInt
APInt
swift::Compress::EncodeStringAsNumber(StringRef In, EncodingKind Kind) {
// Allocate enough space for the first character plus one bit which is the
// stop bit for variable length encoding.
unsigned BW = (1 + Huffman::LongestEncodingLength);
APInt num = APInt(BW, 0);
// We set the high bit to zero in order to support encoding
// of chars that start with zero (for variable length encoding).
if (Kind == EncodingKind::Variable) {
num = ++num;
}
// Encode variable-length strings.
if (Kind == EncodingKind::Variable) {
size_t num_bits = 0;
size_t bits = 0;
// Append the characters in the string in reverse. This will allow
// us to decode by appending to a string and not prepending.
for (int i = In.size() - 1; i >= 0; i--) {
char ch = In[i];
// The local variables 'bits' and 'num_bits' are used as a small
// bitstream. Keep accumulating bits into them until they overflow.
// At that point move them into the APInt.
uint64_t local_bits;
uint64_t local_num_bits;
// Find the huffman encoding of the character.
Huffman::variable_encode(local_bits, local_num_bits, ch);
// Add the encoded character into our bitstream.
num_bits += local_num_bits;
bits = (bits << local_num_bits) + local_bits;
// Check if there is enough room for another word. If not, flush
// the local bitstream into the APInt.
if (num_bits >= (64 - Huffman::LongestEncodingLength)) {
// Make room for the new bits and add the bits.
num = num.zext(num.getBitWidth() + num_bits);
num = num.shl(num_bits); num = num + bits;
num_bits = 0; bits = 0;
}
}
// Flush the local bitstream into the APInt number.
if (num_bits) {
num = num.zext(num.getBitWidth() + num_bits);
num = num.shl(num_bits); num = num + bits;
num_bits = 0; bits = 0;
}
// Make sure that we have a minimal word size to be able to perform
// calculations on our alphabet.
return num.zextOrSelf(std::max(64u, num.getBitWidth()));
}
// Encode fixed width strings.
for (int i = In.size() - 1; i >= 0; i--) {
char ch = In[i];
// Extend the number and create room for encoding another character.
unsigned MinBits = num.getActiveBits() + Huffman::LongestEncodingLength;
num = num.zextOrTrunc(std::max(64u, MinBits));
EncodeFixedWidth(num, ch);
}
return num;
}