int ARMTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty) { assert(Ty->isIntegerTy()); unsigned Bits = Ty->getPrimitiveSizeInBits(); if (Bits == 0 || Imm.getActiveBits() >= 64) return 4; int64_t SImmVal = Imm.getSExtValue(); uint64_t ZImmVal = Imm.getZExtValue(); if (!ST->isThumb()) { if ((SImmVal >= 0 && SImmVal < 65536) || (ARM_AM::getSOImmVal(ZImmVal) != -1) || (ARM_AM::getSOImmVal(~ZImmVal) != -1)) return 1; return ST->hasV6T2Ops() ? 2 : 3; } if (ST->isThumb2()) { if ((SImmVal >= 0 && SImmVal < 65536) || (ARM_AM::getT2SOImmVal(ZImmVal) != -1) || (ARM_AM::getT2SOImmVal(~ZImmVal) != -1)) return 1; return ST->hasV6T2Ops() ? 2 : 3; } // Thumb1, any i8 imm cost 1. if (Bits == 8 || (SImmVal >= 0 && SImmVal < 256)) return 1; if ((~SImmVal < 256) || ARM_AM::isThumbImmShiftedVal(ZImmVal)) return 2; // Load from constantpool. return 3; }
/// 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; }
void BDCE::determineLiveOperandBits(const Instruction *UserI, const Instruction *I, unsigned OperandNo, const APInt &AOut, APInt &AB, APInt &KnownZero, APInt &KnownOne, APInt &KnownZero2, APInt &KnownOne2) { unsigned BitWidth = AB.getBitWidth(); // We're called once per operand, but for some instructions, we need to // compute known bits of both operands in order to determine the live bits of // either (when both operands are instructions themselves). We don't, // however, want to do this twice, so we cache the result in APInts that live // in the caller. For the two-relevant-operands case, both operand values are // provided here. auto ComputeKnownBits = [&](unsigned BitWidth, const Value *V1, const Value *V2) { const DataLayout &DL = I->getModule()->getDataLayout(); KnownZero = APInt(BitWidth, 0); KnownOne = APInt(BitWidth, 0); computeKnownBits(const_cast<Value *>(V1), KnownZero, KnownOne, DL, 0, AC, UserI, DT); if (V2) { KnownZero2 = APInt(BitWidth, 0); KnownOne2 = APInt(BitWidth, 0); computeKnownBits(const_cast<Value *>(V2), KnownZero2, KnownOne2, DL, 0, AC, UserI, DT); } }; switch (UserI->getOpcode()) { default: break; case Instruction::Call: case Instruction::Invoke: if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(UserI)) switch (II->getIntrinsicID()) { default: break; case Intrinsic::bswap: // The alive bits of the input are the swapped alive bits of // the output. AB = AOut.byteSwap(); break; case Intrinsic::ctlz: if (OperandNo == 0) { // We need some output bits, so we need all bits of the // input to the left of, and including, the leftmost bit // known to be one. ComputeKnownBits(BitWidth, I, nullptr); AB = APInt::getHighBitsSet(BitWidth, std::min(BitWidth, KnownOne.countLeadingZeros()+1)); } break; case Intrinsic::cttz: if (OperandNo == 0) { // We need some output bits, so we need all bits of the // input to the right of, and including, the rightmost bit // known to be one. ComputeKnownBits(BitWidth, I, nullptr); AB = APInt::getLowBitsSet(BitWidth, std::min(BitWidth, KnownOne.countTrailingZeros()+1)); } break; } break; case Instruction::Add: case Instruction::Sub: // Find the highest live output bit. We don't need any more input // bits than that (adds, and thus subtracts, ripple only to the // left). AB = APInt::getLowBitsSet(BitWidth, AOut.getActiveBits()); break; case Instruction::Shl: if (OperandNo == 0) if (ConstantInt *CI = dyn_cast<ConstantInt>(UserI->getOperand(1))) { uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1); AB = AOut.lshr(ShiftAmt); // If the shift is nuw/nsw, then the high bits are not dead // (because we've promised that they *must* be zero). const ShlOperator *S = cast<ShlOperator>(UserI); if (S->hasNoSignedWrap()) AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt+1); else if (S->hasNoUnsignedWrap()) AB |= APInt::getHighBitsSet(BitWidth, ShiftAmt); } break; case Instruction::LShr: if (OperandNo == 0) if (ConstantInt *CI = dyn_cast<ConstantInt>(UserI->getOperand(1))) { uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1); AB = AOut.shl(ShiftAmt); // If the shift is exact, then the low bits are not dead // (they must be zero). if (cast<LShrOperator>(UserI)->isExact()) AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt); } break; case Instruction::AShr: if (OperandNo == 0) if (ConstantInt *CI = dyn_cast<ConstantInt>(UserI->getOperand(1))) { uint64_t ShiftAmt = CI->getLimitedValue(BitWidth-1); AB = AOut.shl(ShiftAmt); // Because the high input bit is replicated into the // high-order bits of the result, if we need any of those // bits, then we must keep the highest input bit. if ((AOut & APInt::getHighBitsSet(BitWidth, ShiftAmt)) .getBoolValue()) AB.setBit(BitWidth-1); // If the shift is exact, then the low bits are not dead // (they must be zero). if (cast<AShrOperator>(UserI)->isExact()) AB |= APInt::getLowBitsSet(BitWidth, ShiftAmt); } break; case Instruction::And: AB = AOut; // For bits that are known zero, the corresponding bits in the // other operand are dead (unless they're both zero, in which // case they can't both be dead, so just mark the LHS bits as // dead). if (OperandNo == 0) { ComputeKnownBits(BitWidth, I, UserI->getOperand(1)); AB &= ~KnownZero2; } else { if (!isa<Instruction>(UserI->getOperand(0))) ComputeKnownBits(BitWidth, UserI->getOperand(0), I); AB &= ~(KnownZero & ~KnownZero2); } break; case Instruction::Or: AB = AOut; // For bits that are known one, the corresponding bits in the // other operand are dead (unless they're both one, in which // case they can't both be dead, so just mark the LHS bits as // dead). if (OperandNo == 0) { ComputeKnownBits(BitWidth, I, UserI->getOperand(1)); AB &= ~KnownOne2; } else { if (!isa<Instruction>(UserI->getOperand(0))) ComputeKnownBits(BitWidth, UserI->getOperand(0), I); AB &= ~(KnownOne & ~KnownOne2); } break; case Instruction::Xor: case Instruction::PHI: AB = AOut; break; case Instruction::Trunc: AB = AOut.zext(BitWidth); break; case Instruction::ZExt: AB = AOut.trunc(BitWidth); break; case Instruction::SExt: AB = AOut.trunc(BitWidth); // Because the high input bit is replicated into the // high-order bits of the result, if we need any of those // bits, then we must keep the highest input bit. if ((AOut & APInt::getHighBitsSet(AOut.getBitWidth(), AOut.getBitWidth() - BitWidth)) .getBoolValue()) AB.setBit(BitWidth-1); break; case Instruction::Select: if (OperandNo != 0) AB = AOut; break; } }
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; }
/* * method computeStats * * computes the statistics that require the processing to be complete. */ void llvm::RangeAnalysis::computeStats(){ for(DepGraph::iterator It = depGraph->begin(), Iend = depGraph->end(); It != Iend; It++){ GraphNode* Node = *It; bool isIntegerVariable = false; unsigned int currentBitWidth; //We only count precision statistics of VarNodes and MemNodes if (isa<OpNode>(Node)) { numOps++; continue; } if (isa<MemNode>(Node)) { numMems++; } else if (VarNode* VN = dyn_cast<VarNode>(Node)){ Value* V = VN->getValue(); if (isa<ConstantInt>(V)){ numConstants++; } else { //Only Variables are considered for bitwidth reduction isIntegerVariable = V->getType()->isIntegerTy(); numVars++; if(isIntegerVariable){ currentBitWidth = V->getType()->getPrimitiveSizeInBits(); usedBits += currentBitWidth; } } } else assert(false && "Unknown Node Type"); assert(out_state.count(Node) && "Node not found in the list of computed ranges."); Range CR = out_state[Node]; // If range is unknown, we have total needed bits if (CR.isUnknown()) { ++numUnknown; if (isIntegerVariable) needBits += currentBitWidth; continue; } // If range is empty, we have 0 needed bits if (CR.isEmpty()) { ++numEmpty; continue; } if (CR.getLower().eq(Min)) { if (CR.getUpper().eq(Max)) { ++numMaxRange; } else { ++numMinInfC; } } else if (CR.getUpper().eq(Max)) { ++numCPlusInf; } else { ++numCC; } //Compute needed bits >> only for variables if (isIntegerVariable) { unsigned ub, lb; if (CR.getLower().isNegative()) { APInt abs = CR.getLower().abs(); lb = abs.getActiveBits() + 1; } else { lb = CR.getLower().getActiveBits() + 1; } if (CR.getUpper().isNegative()) { APInt abs = CR.getUpper().abs(); ub = abs.getActiveBits() + 1; } else { ub = CR.getUpper().getActiveBits() + 1; } unsigned nBits = lb > ub ? lb : ub; // If both bounds are positive, decrement needed bits by 1 if (!CR.getLower().isNegative() && !CR.getUpper().isNegative()) { --nBits; } if (nBits < currentBitWidth) { needBits += nBits; } else { needBits += currentBitWidth; } } } double totalB = usedBits; double needB = needBits; double reduction = (double) (totalB - needB) * 100 / totalB; percentReduction = (unsigned int) reduction; }