diff options
-rw-r--r-- | include/llvm/ADT/APInt.h | 20 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 6 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/FastISel.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 14 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 | ||||
-rw-r--r-- | lib/ExecutionEngine/ExecutionEngine.cpp | 2 | ||||
-rw-r--r-- | lib/Support/APFloat.cpp | 14 | ||||
-rw-r--r-- | lib/Support/APInt.cpp | 20 | ||||
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 2 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 3 | ||||
-rw-r--r-- | unittests/ADT/APIntTest.cpp | 4 |
12 files changed, 61 insertions, 36 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index e68e579cdf..58c9837abf 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -15,6 +15,7 @@ #ifndef LLVM_APINT_H #define LLVM_APINT_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/MathExtras.h" #include <cassert> #include <climits> @@ -176,6 +177,9 @@ class APInt { /// out-of-line slow case for inline constructor void initSlowCase(unsigned numBits, uint64_t val, bool isSigned); + /// shared code between two array constructors + void initFromArray(ArrayRef<uint64_t> array); + /// out-of-line slow case for inline copy constructor void initSlowCase(const APInt& that); @@ -230,12 +234,19 @@ public: clearUnusedBits(); } - /// Note that numWords can be smaller or larger than the corresponding bit - /// width but any extraneous bits will be dropped. + /// Note that bigVal.size() can be smaller or larger than the corresponding + /// bit width but any extraneous bits will be dropped. /// @param numBits the bit width of the constructed APInt - /// @param numWords the number of words in bigVal /// @param bigVal a sequence of words to form the initial value of the APInt /// @brief Construct an APInt of numBits width, initialized as bigVal[]. + APInt(unsigned numBits, ArrayRef<uint64_t> bigVal); + /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but + /// deprecated because this constructor is prone to ambiguity with the + /// APInt(unsigned, uint64_t, bool) constructor. + /// + /// If this overload is ever deleted, care should be taken to prevent calls + /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool) + /// constructor. APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]); /// This constructor interprets the string \arg str in the given radix. The @@ -342,7 +353,8 @@ public: if (isSingleWord()) return isUIntN(N, VAL); - return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this); + return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth()) + == (*this); } /// @brief Check if this APInt has an N-bits signed integer value. diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 3c63106e8c..29eb944d4a 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -704,17 +704,17 @@ lltok::Kind LLLexer::Lex0x() { case 'K': // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) FP80HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(80, 2, Pair)); + APFloatVal = APFloat(APInt(80, Pair)); return lltok::APFloat; case 'L': // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, 2, Pair), true); + APFloatVal = APFloat(APInt(128, Pair), true); return lltok::APFloat; case 'M': // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, 2, Pair)); + APFloatVal = APFloat(APInt(128, Pair)); return lltok::APFloat; } } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e49cecf3ba..374a0418c9 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1218,7 +1218,7 @@ bool BitcodeReader::ParseConstants() { Words[i] = DecodeSignRotatedValue(Record[i]); V = ConstantInt::get(Context, APInt(cast<IntegerType>(CurTy)->getBitWidth(), - NumWords, &Words[0])); + Words)); break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] @@ -1233,11 +1233,11 @@ bool BitcodeReader::ParseConstants() { uint64_t Rearrange[2]; Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[1] = Record[0] >> 48; - V = ConstantFP::get(Context, APFloat(APInt(80, 2, Rearrange))); + V = ConstantFP::get(Context, APFloat(APInt(80, Rearrange))); } else if (CurTy->isFP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0]), true)); + V = ConstantFP::get(Context, APFloat(APInt(128, Record), true)); else if (CurTy->isPPC_FP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0]))); + V = ConstantFP::get(Context, APFloat(APInt(128, Record))); else V = UndefValue::get(CurTy); break; diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 53809c62f8..09102ece4b 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -183,7 +183,7 @@ unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true, APFloat::rmTowardZero, &isExact); if (isExact) { - APInt IntVal(IntBitWidth, 2, x); + APInt IntVal(IntBitWidth, x); unsigned IntegerReg = getRegForValue(ConstantInt::get(V->getContext(), IntVal)); diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index e6835d87f8..acdcc4f4bd 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -879,10 +879,10 @@ void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, assert(NVT.getSizeInBits() == integerPartWidth && "Do not know how to expand this float constant!"); APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); - Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, - &C.getRawData()[1])), NVT); - Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, - &C.getRawData()[0])), NVT); + Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[1])), + NVT); + Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[0])), + NVT); } void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, @@ -1201,7 +1201,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; - const uint64_t *Parts = 0; + ArrayRef<uint64_t> Parts; switch (SrcVT.getSimpleVT().SimpleTy) { default: @@ -1218,7 +1218,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, } Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, - DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), + DAG.getConstantFP(APFloat(APInt(128, Parts)), MVT::ppcf128)); Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, DAG.getCondCode(ISD::SETLT)); @@ -1373,7 +1373,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { assert(N->getOperand(0).getValueType() == MVT::ppcf128 && "Logic only correct for ppcf128!"); const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; - APFloat APF = APFloat(APInt(128, 2, TwoE31)); + APFloat APF = APFloat(APInt(128, TwoE31)); SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X // FIXME: generated code sucks. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index b72a47d0f6..68db87d879 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2437,7 +2437,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, APFloat::rmTowardZero, &ignored); if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual break; - APInt api(VT.getSizeInBits(), 2, x); + APInt api(VT.getSizeInBits(), x); return getConstant(api, VT); } case ISD::BITCAST: diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 1b1b498f39..dee8ea8a97 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -932,7 +932,7 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, // FIXME: Will not trap if loading a signaling NaN. uint64_t y[2]; memcpy(y, Ptr, 10); - Result.IntVal = APInt(80, 2, y); + Result.IntVal = APInt(80, y); break; } default: diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index c64da6e137..b37e011546 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -2098,7 +2098,7 @@ APFloat::convertToInteger(APSInt &result, opStatus status = convertToInteger( parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact); // Keeps the original signed-ness. - result = APInt(bitWidth, (unsigned)parts.size(), parts.data()); + result = APInt(bitWidth, parts); return status; } @@ -2192,7 +2192,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, roundingMode rounding_mode) { unsigned int partCount = partCountForBits(width); - APInt api = APInt(width, partCount, parts); + APInt api = APInt(width, makeArrayRef(parts, partCount)); sign = false; if (isSigned && APInt::tcExtractBit(parts, width - 1)) { @@ -2746,7 +2746,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const words[0] = mysignificand; words[1] = ((uint64_t)(sign & 1) << 15) | (myexponent & 0x7fffLL); - return APInt(80, 2, words); + return APInt(80, words); } APInt @@ -2791,7 +2791,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const words[1] = ((uint64_t)(sign2 & 1) << 63) | ((myexponent2 & 0x7ff) << 52) | (mysignificand2 & 0xfffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -2827,7 +2827,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const ((myexponent & 0x7fff) << 48) | (mysignificand2 & 0xffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -3413,8 +3413,8 @@ void APFloat::toString(SmallVectorImpl<char> &Str, // Decompose the number into an APInt and an exponent. int exp = exponent - ((int) semantics->precision - 1); APInt significand(semantics->precision, - partCountForBits(semantics->precision), - significandParts()); + makeArrayRef(significandParts(), + partCountForBits(semantics->precision))); // Set FormatPrecision if zero. We want to do this before we // truncate trailing zeros, as those are part of the precision. diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 76265d445f..0b2536031f 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -83,25 +83,33 @@ void APInt::initSlowCase(const APInt& that) { memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE); } - -APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]) - : BitWidth(numBits), VAL(0) { +void APInt::initFromArray(ArrayRef<uint64_t> bigVal) { assert(BitWidth && "Bitwidth too small"); - assert(bigVal && "Null pointer detected!"); + assert(bigVal.data() && "Null pointer detected!"); if (isSingleWord()) VAL = bigVal[0]; else { // Get memory, cleared to 0 pVal = getClearedMemory(getNumWords()); // Calculate the number of words to copy - unsigned words = std::min<unsigned>(numWords, getNumWords()); + unsigned words = std::min<unsigned>(bigVal.size(), getNumWords()); // Copy the words from bigVal to pVal - memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + memcpy(pVal, bigVal.data(), words * APINT_WORD_SIZE); } // Make sure unused high bits are cleared clearUnusedBits(); } +APInt::APInt(unsigned numBits, ArrayRef<uint64_t> bigVal) + : BitWidth(numBits), VAL(0) { + initFromArray(bigVal); +} + +APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]) + : BitWidth(numBits), VAL(0) { + initFromArray(makeArrayRef(bigVal, numWords)); +} + APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix) : BitWidth(numbits), VAL(0) { assert(BitWidth && "Bitwidth too small"); diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 85badc8b29..a2f4f621c9 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -590,7 +590,7 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, Constant *V, uint32_t DestBitWidth = cast<IntegerType>(DestTy)->getBitWidth(); (void) V.convertToInteger(x, DestBitWidth, opc==Instruction::FPToSI, APFloat::rmTowardZero, &ignored); - APInt Val(DestBitWidth, 2, x); + APInt Val(DestBitWidth, x); return ConstantInt::get(FPC->getContext(), Val); } return 0; // Can't fold. diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 940d0fb3a9..35ba43a263 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -525,7 +525,8 @@ LLVMValueRef LLVMConstIntOfArbitraryPrecision(LLVMTypeRef IntTy, const uint64_t Words[]) { IntegerType *Ty = unwrap<IntegerType>(IntTy); return wrap(ConstantInt::get(Ty->getContext(), - APInt(Ty->getBitWidth(), NumWords, Words))); + APInt(Ty->getBitWidth(), + makeArrayRef(Words, NumWords)))); } LLVMValueRef LLVMConstIntOfString(LLVMTypeRef IntTy, const char Str[], diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 1f78cd33bd..c9b3bc51c1 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -239,6 +239,10 @@ TEST(APIntTest, fromString) { EXPECT_EQ(APInt(32, uint64_t(-32LL)), APInt(32, "-20", 16)); } +TEST(APIntTest, FromArray) { + EXPECT_EQ(APInt(32, uint64_t(1)), APInt(32, ArrayRef<uint64_t>(1))); +} + TEST(APIntTest, StringBitsNeeded2) { EXPECT_EQ(1U, APInt::getBitsNeeded( "0", 2)); EXPECT_EQ(1U, APInt::getBitsNeeded( "1", 2)); |