int FunctionComparator::cmpAPInts(const APInt &L, const APInt &R) const { if (int Res = cmpNumbers(L.getBitWidth(), R.getBitWidth())) return Res; if (L.ugt(R)) return 1; if (R.ugt(L)) return -1; return 0; }
/// Extract all of the characters from the number \p Num one by one and /// insert them into the string builder \p SB. static void DecodeFixedWidth(APInt &Num, std::string &SB) { uint64_t CL = Huffman::CharsetLength; // NL is the number of characters that we can hold in a 64bit number. // Each letter takes Log2(CL) bits. Doing this computation in floating- // point arithmetic could give a slightly better (more optimistic) result, // but the computation may not be constant at compile time. uint64_t NumLetters = 64 / Log2_64_Ceil(CL); assert(Num.getBitWidth() > 8 && "Not enough bits for arithmetic on this alphabet"); // Try to decode eight numbers at once. It is much faster to work with // local 64bit numbers than working with APInt. In this loop we try to // extract NL characters at once and process them using a local 64-bit // number. // Calculate CharsetLength**NumLetters (CL to the power of NL), which is the // highest numeric value that can hold NumLetters characters in a 64bit // number. Notice: this loop is optimized away and CLX is computed to a // constant integer at compile time. uint64_t CLX = 1; for (unsigned i = 0; i < NumLetters; i++) { CLX *= CL; } while (Num.ugt(CLX)) { unsigned BW = Num.getBitWidth(); APInt C = APInt(BW, CLX); APInt Quotient(1, 0), Remainder(1, 0); APInt::udivrem(Num, C, Quotient, Remainder); // Try to reduce the bitwidth of the API after the division. This can // accelerate the division operation in future iterations because the // number becomes smaller (fewer bits) with each iteration. However, // We can't reduce the number to something too small because we still // need to be able to perform the "mod charset_length" operation. Num = Quotient.zextOrTrunc(std::max(Quotient.getActiveBits(), 64u)); uint64_t Tail = Remainder.getZExtValue(); for (unsigned i = 0; i < NumLetters; i++) { SB += Huffman::Charset[Tail % CL]; Tail = Tail / CL; } } // Pop characters out of the APInt one by one. while (Num.getBoolValue()) { unsigned BW = Num.getBitWidth(); APInt C = APInt(BW, CL); APInt Quotient(1, 0), Remainder(1, 0); APInt::udivrem(Num, C, Quotient, Remainder); Num = Quotient; SB += Huffman::Charset[Remainder.getZExtValue()]; } }
/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form: /// SPF2(SPF1(A, B), C) Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C) { if (C == A || C == B) { // MAX(MAX(A, B), B) -> MAX(A, B) // MIN(MIN(a, b), a) -> MIN(a, b) if (SPF1 == SPF2) return ReplaceInstUsesWith(Outer, Inner); // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) || (SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) || (SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) || (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN)) return ReplaceInstUsesWith(Outer, C); } if (SPF1 == SPF2) { if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) { if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) { APInt ACB = CB->getValue(); APInt ACC = CC->getValue(); // MIN(MIN(A, 23), 97) -> MIN(A, 23) // MAX(MAX(A, 97), 23) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) || (SPF1 == SPF_SMIN && ACB.sle(ACC)) || (SPF1 == SPF_UMAX && ACB.uge(ACC)) || (SPF1 == SPF_SMAX && ACB.sge(ACC))) return ReplaceInstUsesWith(Outer, Inner); // MIN(MIN(A, 97), 23) -> MIN(A, 23) // MAX(MAX(A, 23), 97) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) || (SPF1 == SPF_SMIN && ACB.sgt(ACC)) || (SPF1 == SPF_UMAX && ACB.ult(ACC)) || (SPF1 == SPF_SMAX && ACB.slt(ACC))) { Outer.replaceUsesOfWith(Inner, A); return &Outer; } } } } return nullptr; }
APInt swift::constantFoldComparison(APInt lhs, APInt rhs, BuiltinValueKind ID) { bool result; switch (ID) { default: llvm_unreachable("Invalid integer compare kind"); case BuiltinValueKind::ICMP_EQ: result = lhs == rhs; break; case BuiltinValueKind::ICMP_NE: result = lhs != rhs; break; case BuiltinValueKind::ICMP_SLT: result = lhs.slt(rhs); break; case BuiltinValueKind::ICMP_SGT: result = lhs.sgt(rhs); break; case BuiltinValueKind::ICMP_SLE: result = lhs.sle(rhs); break; case BuiltinValueKind::ICMP_SGE: result = lhs.sge(rhs); break; case BuiltinValueKind::ICMP_ULT: result = lhs.ult(rhs); break; case BuiltinValueKind::ICMP_UGT: result = lhs.ugt(rhs); break; case BuiltinValueKind::ICMP_ULE: result = lhs.ule(rhs); break; case BuiltinValueKind::ICMP_UGE: result = lhs.uge(rhs); break; } return APInt(1, result); }
std::string swift::Compress::DecodeStringFromNumber(const APInt &In, EncodingKind Kind) { APInt num = In; std::string sb; if (Kind == EncodingKind::Variable) { // Keep decoding until we reach our sentinel value. // See the encoder implementation for more details. while (num.ugt(1)) { sb += Huffman::variable_decode(num); } } else { // Decode this number as a regular fixed-width sequence of characters. DecodeFixedWidth(num, sb); } return sb; }
/// Extract all of the characters from the number \p Num one by one and /// insert them into the string builder \p SB. static void DecodeFixedWidth(APInt &Num, std::string &SB) { uint64_t CL = Huffman::CharsetLength; assert(Num.getBitWidth() > 8 && "Not enough bits for arithmetic on this alphabet"); // Try to decode eight numbers at once. It is much faster to work with // local 64bit numbers than working with APInt. In this loop we try to // extract 8 characters at one and process them using a local 64bit number. // In this code we assume a worse case scenario where our alphabet is a full // 8-bit ascii. It is possible to improve this code by packing one or two // more characters into the 64bit local variable. uint64_t CL8 = CL * CL * CL * CL * CL * CL * CL * CL; while (Num.ugt(CL8)) { unsigned BW = Num.getBitWidth(); APInt C = APInt(BW, CL8); APInt Quotient(1, 0), Remainder(1, 0); APInt::udivrem(Num, C, Quotient, Remainder); // Try to reduce the bitwidth of the API after the division. This can // accelerate the division operation in future iterations because the // number becomes smaller (fewer bits) with each iteration. However, // We can't reduce the number to something too small because we still // need to be able to perform the "mod charset_length" operation. Num = Quotient.zextOrTrunc(std::max(Quotient.getActiveBits(), 64u)); uint64_t Tail = Remainder.getZExtValue(); for (int i=0; i < 8; i++) { SB += Huffman::Charset[Tail % CL]; Tail = Tail / CL; } } // Pop characters out of the APInt one by one. while (Num.getBoolValue()) { unsigned BW = Num.getBitWidth(); APInt C = APInt(BW, CL); APInt Quotient(1, 0), Remainder(1, 0); APInt::udivrem(Num, C, Quotient, Remainder); Num = Quotient; SB += Huffman::Charset[Remainder.getZExtValue()]; } }
/// MultiplyOverflows - True if the multiply can not be expressed in an int /// this size. static bool MultiplyOverflows(ConstantInt *C1, ConstantInt *C2, bool sign) { uint32_t W = C1->getBitWidth(); APInt LHSExt = C1->getValue(), RHSExt = C2->getValue(); if (sign) { LHSExt = LHSExt.sext(W * 2); RHSExt = RHSExt.sext(W * 2); } else { LHSExt = LHSExt.zext(W * 2); RHSExt = RHSExt.zext(W * 2); } APInt MulExt = LHSExt * RHSExt; if (!sign) return MulExt.ugt(APInt::getLowBitsSet(W * 2, W)); APInt Min = APInt::getSignedMinValue(W).sext(W * 2); APInt Max = APInt::getSignedMaxValue(W).sext(W * 2); return MulExt.slt(Min) || MulExt.sgt(Max); }
/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form: /// SPF2(SPF1(A, B), C) Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner, SelectPatternFlavor SPF1, Value *A, Value *B, Instruction &Outer, SelectPatternFlavor SPF2, Value *C) { if (C == A || C == B) { // MAX(MAX(A, B), B) -> MAX(A, B) // MIN(MIN(a, b), a) -> MIN(a, b) if (SPF1 == SPF2) return ReplaceInstUsesWith(Outer, Inner); // MAX(MIN(a, b), a) -> a // MIN(MAX(a, b), a) -> a if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) || (SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) || (SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) || (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN)) return ReplaceInstUsesWith(Outer, C); } if (SPF1 == SPF2) { if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) { if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) { APInt ACB = CB->getValue(); APInt ACC = CC->getValue(); // MIN(MIN(A, 23), 97) -> MIN(A, 23) // MAX(MAX(A, 97), 23) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) || (SPF1 == SPF_SMIN && ACB.sle(ACC)) || (SPF1 == SPF_UMAX && ACB.uge(ACC)) || (SPF1 == SPF_SMAX && ACB.sge(ACC))) return ReplaceInstUsesWith(Outer, Inner); // MIN(MIN(A, 97), 23) -> MIN(A, 23) // MAX(MAX(A, 23), 97) -> MAX(A, 97) if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) || (SPF1 == SPF_SMIN && ACB.sgt(ACC)) || (SPF1 == SPF_UMAX && ACB.ult(ACC)) || (SPF1 == SPF_SMAX && ACB.slt(ACC))) { Outer.replaceUsesOfWith(Inner, A); return &Outer; } } } } // ABS(ABS(X)) -> ABS(X) // NABS(NABS(X)) -> NABS(X) if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) { return ReplaceInstUsesWith(Outer, Inner); } // ABS(NABS(X)) -> ABS(X) // NABS(ABS(X)) -> NABS(X) if ((SPF1 == SPF_ABS && SPF2 == SPF_NABS) || (SPF1 == SPF_NABS && SPF2 == SPF_ABS)) { SelectInst *SI = cast<SelectInst>(Inner); Value *NewSI = Builder->CreateSelect( SI->getCondition(), SI->getFalseValue(), SI->getTrueValue()); return ReplaceInstUsesWith(Outer, NewSI); } return nullptr; }