llvm.org GIT mirror llvm / fad86b0
Rework the routines that convert AP[S]Int into a string. Now, instead of returning an std::string by value, it fills in a SmallString/SmallVector passed in. This significantly reduces string thrashing in some cases. More specifically, this: - Adds an operator<< and a print method for APInt that allows you to directly send them to an ostream. - Reimplements APInt::toString to be much simpler and more efficient algorithmically in addition to not thrashing strings quite as much. This speeds up llvm-dis on kc++ by 7%, and may also slightly speed up the asmprinter. This also fixes a bug I introduced into the asmwriter in a previous patch w.r.t. alias printing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@54873 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
13 changed file(s) with 179 addition(s) and 149 deletion(s). Raw diff Collapse all Expand all
115115 GenericValue GV = EE->runFunction(FibF, Args);
116116
117117 // import result of execution
118 std::cout << "Result: " << GV.IntVal.toStringUnsigned(10) << "\n";
118 std::cout << "Result: " << GV.IntVal << "\n";
119119 return 0;
120120 }
106106 GenericValue gv = EE->runFunction(FooF, noargs);
107107
108108 // Import result of execution:
109 std::cout << "Result: " << gv.IntVal.toStringUnsigned(10) << "\n";
109 std::cout << "Result: " << gv.IntVal << "\n";
110110 return 0;
111111 }
1616
1717 #include "llvm/Support/DataTypes.h"
1818 #include
19 #include
1920 #include
2021
2122 namespace llvm {
2223 class Serializer;
2324 class Deserializer;
2425 class FoldingSetNodeID;
26
27 template
28 class SmallVectorImpl;
2529
2630 /* An unsigned host type used as a single part of a multi-part
2731 bignum. */
467471 /// Performs logical negation operation on this APInt.
468472 /// @returns true if *this is zero, false otherwise.
469473 /// @brief Logical negation operator.
470 bool operator !() const;
474 bool operator!() const;
471475
472476 /// @}
473477 /// @name Assignment Operators
971975 /// @name Conversion Functions
972976 /// @{
973977
974 /// This is used internally to convert an APInt to a string.
975 /// @brief Converts an APInt to a std::string
976 std::string toString(uint8_t radix, bool wantSigned) const;
978 void print(std::ostream &OS, bool isSigned) const;
979
980 /// toString - Converts an APInt to a string and append it to Str. Str is
981 /// commonly a SmallString.
982 void toString(SmallVectorImpl &Str, unsigned Radix, bool Signed) const;
977983
978984 /// Considers the APInt to be unsigned and converts it into a string in the
979985 /// radix given. The radix can be 2, 8, 10 or 16.
980 /// @returns a character interpretation of the APInt
981 /// @brief Convert unsigned APInt to string representation.
982 std::string toStringUnsigned(uint8_t radix = 10) const {
983 return toString(radix, false);
986 void toStringUnsigned(SmallVectorImpl &Str, unsigned Radix = 10) const {
987 return toString(Str, Radix, false);
984988 }
985989
986990 /// Considers the APInt to be signed and converts it into a string in the
987991 /// radix given. The radix can be 2, 8, 10 or 16.
988 /// @returns a character interpretation of the APInt
989 /// @brief Convert signed APInt to string representation.
990 std::string toStringSigned(uint8_t radix = 10) const {
991 return toString(radix, true);
992 }
992 void toStringSigned(SmallVectorImpl &Str, unsigned Radix = 10) const {
993 return toString(Str, Radix, true);
994 }
995
996 /// toString - This returns the APInt as a std::string. Note that this is an
997 /// inefficient method. It is better to pass in a SmallVector/SmallString
998 /// to the methods above to avoid thrashing the heap for the string.
999 std::string toString(unsigned Radix, bool Signed) const;
1000
9931001
9941002 /// @returns a byte-swapped representation of this APInt Value.
9951003 APInt byteSwap() const;
12361244 return V2 != V1;
12371245 }
12381246
1247 inline std::ostream &operator<<(std::ostream &OS, const APInt &I) {
1248 I.print(OS, true);
1249 return OS;
1250 }
1251
12391252 namespace APIntOps {
12401253
12411254 /// @brief Determine the smaller of two APInts considered to be signed.
1717 #include "llvm/ADT/APInt.h"
1818
1919 namespace llvm {
20
2120
2221 class APSInt : public APInt {
2322 bool IsUnsigned;
5756 void setIsUnsigned(bool Val) { IsUnsigned = Val; }
5857 void setIsSigned(bool Val) { IsUnsigned = !Val; }
5958
60 /// This is used internally to convert an APInt to a string.
61 /// @brief Converts an APInt to a std::string
62 std::string toString(uint8_t Radix = 10) const {
59 /// toString - Append this APSInt to the specified SmallString.
60 void toString(SmallVectorImpl &Str, unsigned Radix = 10) const {
61 return APInt::toString(Str, Radix, isSigned());
62 }
63 /// toString - Converts an APInt to a std::string. This is an inefficient
64 /// method, your should prefer passing in a SmallString instead.
65 std::string toString(unsigned Radix) const {
6366 return APInt::toString(Radix, isSigned());
6467 }
68 using APInt::toString;
6569
6670 APSInt& extend(uint32_t width) {
6771 if (IsUnsigned)
234238 void Profile(FoldingSetNodeID& ID) const;
235239 };
236240
241 inline std::ostream &operator<<(std::ostream &OS, const APSInt &I) {
242 I.print(OS, I.isSigned());
243 return OS;
244 }
245
246
237247 } // end namespace llvm
238248
239249 #endif
169169 case GlobalID : return '@' + utostr(Num);
170170 case LocalName : return *Name;
171171 case GlobalName : return *Name;
172 case ConstAPInt : return ConstPoolInt->toString();
172 case ConstAPInt : return ConstPoolInt->toString(10);
173173 case ConstFPVal : return ftostr(*ConstPoolFP);
174174 case ConstNullVal : return "null";
175175 case ConstUndefVal : return "undef";
3030 #include "llvm/Target/TargetOptions.h"
3131 #include "llvm/Target/TargetRegisterInfo.h"
3232 #include "llvm/ADT/SmallPtrSet.h"
33 #include "llvm/ADT/SmallString.h"
3334 #include
3435 using namespace llvm;
3536
799800 O << "((";
800801 EmitConstantValueOnly(Op);
801802 APInt ptrMask = APInt::getAllOnesValue(TD->getABITypeSizeInBits(Ty));
802 O << ") & " << ptrMask.toStringUnsigned() << ')';
803
804 SmallString<40> S;
805 ptrMask.toStringUnsigned(S);
806 O << ") & " << S.c_str() << ')';
803807 break;
804808 }
805809 case Instruction::Add:
10571061 printDataDirective(type);
10581062 EmitConstantValueOnly(CV);
10591063 if (const ConstantInt *CI = dyn_cast(CV)) {
1060 O << "\t\t\t"
1061 << TAI->getCommentString()
1062 << " 0x" << CI->getValue().toStringUnsigned(16);
1064 SmallString<40> S;
1065 CI->getValue().toStringUnsigned(S, 16);
1066 O << "\t\t\t" << TAI->getCommentString() << " 0x" << S.c_str();
10631067 }
10641068 O << '\n';
10651069 }
10661070
1067 void
1068 AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
1071 void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
10691072 // Target doesn't support this yet!
10701073 abort();
10711074 }
49914991 }
49924992
49934993 if (const ConstantSDNode *CSDN = dyn_cast(this)) {
4994 cerr << "<" << CSDN->getAPIntValue().toStringUnsigned() << ">";
4994 cerr << "<" << CSDN->getAPIntValue() << ">";
49954995 } else if (const ConstantFPSDNode *CSDN = dyn_cast(this)) {
49964996 if (&CSDN->getValueAPF().getSemantics()==&APFloat::IEEEsingle)
49974997 cerr << "<" << CSDN->getValueAPF().convertToFloat() << ">";
1313
1414 #include "llvm/ADT/APFloat.h"
1515 #include "llvm/ADT/FoldingSet.h"
16 #include
16 #include "llvm/Support/MathExtras.h"
1717 #include
18 #include "llvm/Support/MathExtras.h"
1918
2019 using namespace llvm;
2120
1414 #define DEBUG_TYPE "apint"
1515 #include "llvm/ADT/APInt.h"
1616 #include "llvm/ADT/FoldingSet.h"
17 #include "llvm/ADT/SmallString.h"
1718 #include "llvm/Support/Debug.h"
1819 #include "llvm/Support/MathExtras.h"
19 #include <math.h>
20 #include <cmath>
2021 #include
2122 #include
2223 #include
23 #include
24
2524 using namespace llvm;
2625
2726 /// This enumeration just provides for internal constants used in this
14771476 // is 2^31 so we just set it to -1u.
14781477 uint64_t b = uint64_t(1) << 32;
14791478
1479 #if 0
14801480 DEBUG(cerr << "KnuthDiv: m=" << m << " n=" << n << '\n');
14811481 DEBUG(cerr << "KnuthDiv: original:");
14821482 DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]);
14831483 DEBUG(cerr << " by");
14841484 DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]);
14851485 DEBUG(cerr << '\n');
1486 #endif
14861487 // D1. [Normalize.] Set d = b / (v[n-1] + 1) and multiply all the digits of
14871488 // u and v by d. Note that we have taken Knuth's advice here to use a power
14881489 // of 2 value for d such that d * v[n-1] >= b/2 (b is the base). A power of
15071508 }
15081509 }
15091510 u[m+n] = u_carry;
1511 #if 0
15101512 DEBUG(cerr << "KnuthDiv: normal:");
15111513 DEBUG(for (int i = m+n; i >=0; i--) cerr << " " << std::setbase(16) << u[i]);
15121514 DEBUG(cerr << " by");
15131515 DEBUG(for (int i = n; i >0; i--) cerr << " " << std::setbase(16) << v[i-1]);
15141516 DEBUG(cerr << '\n');
1517 #endif
15151518
15161519 // D2. [Initialize j.] Set j to m. This is the loop counter over the places.
15171520 int j = m;
16351638 }
16361639 DEBUG(cerr << '\n');
16371640 }
1641 #if 0
16381642 DEBUG(cerr << std::setbase(10) << '\n');
1643 #endif
16391644 }
16401645
16411646 void APInt::divide(const APInt LHS, uint32_t lhsWords,
20002005 }
20012006 }
20022007
2003 std::string APInt::toString(uint8_t radix, bool wantSigned) const {
2004 assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
2008 void APInt::toString(SmallVectorImpl &Str, unsigned Radix,
2009 bool Signed) const {
2010 assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2) &&
20052011 "Radix should be 2, 8, 10, or 16!");
2006 static const char *const digits[] = {
2007 "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"
2008 };
2009 std::string result;
2010 uint32_t bits_used = getActiveBits();
2012
2013 // First, check for a zero value and just short circuit the logic below.
2014 if (*this == 0) {
2015 Str.push_back('0');
2016 return;
2017 }
2018
2019 static const char Digits[] = "0123456789ABCDEF";
2020
20112021 if (isSingleWord()) {
2012 char buf[65];
2013 const char *format = (radix == 10 ? (wantSigned ? "%lld" : "%llu") :
2014 (radix == 16 ? "%llX" : (radix == 8 ? "%llo" : 0)));
2015 if (format) {
2016 if (wantSigned) {
2017 int64_t sextVal = (int64_t(VAL) << (APINT_BITS_PER_WORD-BitWidth)) >>
2018 (APINT_BITS_PER_WORD-BitWidth);
2019 sprintf(buf, format, sextVal);
2020 } else
2021 sprintf(buf, format, VAL);
2022 char Buffer[65];
2023 char *BufPtr = Buffer+65;
2024
2025 uint64_t N;
2026 if (Signed) {
2027 int64_t I = getSExtValue();
2028 if (I < 0) {
2029 Str.push_back('-');
2030 I = -I;
2031 }
2032 N = I;
20222033 } else {
2023 memset(buf, 0, 65);
2024 uint64_t v = VAL;
2025 while (bits_used) {
2026 uint32_t bit = (uint32_t)v & 1;
2027 bits_used--;
2028 buf[bits_used] = digits[bit][0];
2029 v >>=1;
2030 }
2031 }
2032 result = buf;
2033 return result;
2034 }
2035
2036 if (radix != 10) {
2037 // For the 2, 8 and 16 bit cases, we can just shift instead of divide
2038 // because the number of bits per digit (1,3 and 4 respectively) divides
2039 // equaly. We just shift until there value is zero.
2040
2041 // First, check for a zero value and just short circuit the logic below.
2042 if (*this == 0)
2043 result = "0";
2044 else {
2045 APInt tmp(*this);
2046 size_t insert_at = 0;
2047 if (wantSigned && this->isNegative()) {
2048 // They want to print the signed version and it is a negative value
2049 // Flip the bits and add one to turn it into the equivalent positive
2050 // value and put a '-' in the result.
2051 tmp.flip();
2052 tmp++;
2053 result = "-";
2054 insert_at = 1;
2055 }
2056 // Just shift tmp right for each digit width until it becomes zero
2057 uint32_t shift = (radix == 16 ? 4 : (radix == 8 ? 3 : 1));
2058 uint64_t mask = radix - 1;
2059 APInt zero(tmp.getBitWidth(), 0);
2060 while (tmp.ne(zero)) {
2061 unsigned digit =
2062 (unsigned)((tmp.isSingleWord() ? tmp.VAL : tmp.pVal[0]) & mask);
2063 result.insert(insert_at, digits[digit]);
2064 tmp = tmp.lshr(shift);
2065 }
2066 }
2067 return result;
2068 }
2069
2070 APInt tmp(*this);
2071 APInt divisor(4, radix);
2072 APInt zero(tmp.getBitWidth(), 0);
2073 size_t insert_at = 0;
2074 if (wantSigned && tmp[BitWidth-1]) {
2034 N = getZExtValue();
2035 }
2036
2037 while (N) {
2038 *--BufPtr = Digits[N % Radix];
2039 N /= Radix;
2040 }
2041 Str.append(BufPtr, Buffer+65);
2042 return;
2043 }
2044
2045 APInt Tmp(*this);
2046
2047 if (Signed && isNegative()) {
20752048 // They want to print the signed version and it is a negative value
20762049 // Flip the bits and add one to turn it into the equivalent positive
20772050 // value and put a '-' in the result.
2078 tmp.flip();
2079 tmp++;
2080 result = "-";
2081 insert_at = 1;
2082 }
2083 if (tmp == zero)
2084 result = "0";
2085 else while (tmp.ne(zero)) {
2086 APInt APdigit(1,0);
2087 APInt tmp2(tmp.getBitWidth(), 0);
2088 divide(tmp, tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2,
2089 &APdigit);
2090 uint32_t digit = (uint32_t)APdigit.getZExtValue();
2091 assert(digit < radix && "divide failed");
2092 result.insert(insert_at,digits[digit]);
2093 tmp = tmp2;
2094 }
2095
2096 return result;
2097 }
2098
2099 void APInt::dump() const
2100 {
2101 cerr << "APInt(" << BitWidth << ")=" << std::setbase(16);
2102 if (isSingleWord())
2103 cerr << VAL;
2104 else for (unsigned i = getNumWords(); i > 0; i--) {
2105 cerr << pVal[i-1] << " ";
2106 }
2107 cerr << " U(" << this->toStringUnsigned(10) << ") S("
2108 << this->toStringSigned(10) << ")" << std::setbase(10);
2109 }
2051 Tmp.flip();
2052 Tmp++;
2053 Str.push_back('-');
2054 }
2055
2056 // We insert the digits backward, then reverse them to get the right order.
2057 unsigned StartDig = Str.size();
2058
2059 // For the 2, 8 and 16 bit cases, we can just shift instead of divide
2060 // because the number of bits per digit (1, 3 and 4 respectively) divides
2061 // equaly. We just shift until the value is zero.
2062 if (Radix != 10) {
2063 // Just shift tmp right for each digit width until it becomes zero
2064 unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
2065 unsigned MaskAmt = Radix - 1;
2066
2067 while (Tmp != 0) {
2068 unsigned Digit = unsigned(Tmp.getRawData()[0]) & MaskAmt;
2069 Str.push_back(Digits[Digit]);
2070 Tmp = Tmp.lshr(ShiftAmt);
2071 }
2072 } else {
2073 APInt divisor(4, 10);
2074 while (Tmp != 0) {
2075 APInt APdigit(1, 0);
2076 APInt tmp2(Tmp.getBitWidth(), 0);
2077 divide(Tmp, Tmp.getNumWords(), divisor, divisor.getNumWords(), &tmp2,
2078 &APdigit);
2079 uint32_t Digit = (uint32_t)APdigit.getZExtValue();
2080 assert(Digit < Radix && "divide failed");
2081 Str.push_back(Digits[Digit]);
2082 Tmp = tmp2;
2083 }
2084 }
2085
2086 // Reverse the digits before returning.
2087 std::reverse(Str.begin()+StartDig, Str.end());
2088 }
2089
2090 /// toString - This returns the APInt as a std::string. Note that this is an
2091 /// inefficient method. It is better to pass in a SmallVector/SmallString
2092 /// to the methods above.
2093 std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {
2094 SmallString<40> S;
2095 toString(S, Radix, Signed);
2096 return S.c_str();
2097 }
2098
2099
2100 void APInt::dump() const {
2101 SmallString<40> S, U;
2102 this->toStringUnsigned(U);
2103 this->toStringSigned(S);
2104 fprintf(stderr, "APInt(%db, %su %ss)", BitWidth, U.c_str(), S.c_str());
2105 }
2106
2107 void APInt::print(std::ostream &OS, bool isSigned) const {
2108 SmallString<40> S;
2109 this->toString(S, 10, isSigned);
2110 OS << S.c_str();
2111 }
2112
21102113
21112114 // This implements a variety of operations on a representation of
21122115 // arbitrary precision, two's-complement, bignum integer values.
462462 /// print - Print out the bounds to a stream...
463463 ///
464464 void ConstantRange::print(std::ostream &OS) const {
465 OS << "[" << Lower.toStringSigned(10) << ","
466 << Upper.toStringSigned(10) << ")";
465 OS << "[" << Lower << "," << Upper << ")";
467466 }
468467
469468 /// dump - Allow printing from a debugger easily...
732732 }
733733 if (const ConstantInt *CI = dyn_cast(CV)) {
734734 Out << "ConstantInt* " << constName << " = ConstantInt::get(APInt("
735 << cast(CI->getType())->getBitWidth() << ", "
736 << " \"" << CI->getValue().toStringSigned(10) << "\", 10));";
735 << cast(CI->getType())->getBitWidth() << ", \""
736 << CI->getValue() << "\", 10));";
737737 } else if (isa(CV)) {
738738 Out << "ConstantAggregateZero* " << constName
739739 << " = ConstantAggregateZero::get(" << typeName << ");";
143143 DOUT << "RHS: " << RHS << "\n";
144144
145145 CaseRange& Pivot = *(Begin + Mid);
146 DEBUG( DOUT << "Pivot ==> "
147 << cast(Pivot.Low)->getValue().toStringSigned(10)
148 << " -"
149 << cast(Pivot.High)->getValue().toStringSigned(10)
150 << "\n");
146 DEBUG(cerr << "Pivot ==> "
147 << cast(Pivot.Low)->getValue() << " -"
148 << cast(Pivot.High)->getValue() << "\n");
151149
152150 BasicBlock* LBranch = switchConvert(LHS.begin(), LHS.end(), Val,
153151 OrigBlock, Default);
506506 std::map &TypeTable,
507507 SlotMachine *Machine) {
508508 const int IndentSize = 4;
509 // FIXME: WHY IS INDENT STATIC??
509510 static std::string Indent = "\n";
510511 if (const ConstantInt *CI = dyn_cast(CV)) {
511 if (CI->getType() == Type::Int1Ty)
512 if (CI->getType() == Type::Int1Ty) {
512513 Out << (CI->getZExtValue() ? "true" : "false");
513 else
514 Out << CI->getValue().toStringSigned(10);
515 } else if (const ConstantFP *CFP = dyn_cast(CV)) {
514 return;
515 }
516 Out << CI->getValue();
517 return;
518 }
519
520 if (const ConstantFP *CFP = dyn_cast(CV)) {
516521 if (&CFP->getValueAPF().getSemantics() == &APFloat::IEEEdouble ||
517522 &CFP->getValueAPF().getSemantics() == &APFloat::IEEEsingle) {
518523 // We would like to output the FP constant value in exponential notation,
521526 // the value back and get the same value.
522527 //
523528 bool isDouble = &CFP->getValueAPF().getSemantics()==&APFloat::IEEEdouble;
524 double Val = (isDouble) ? CFP->getValueAPF().convertToDouble() :
525 CFP->getValueAPF().convertToFloat();
529 double Val = isDouble ? CFP->getValueAPF().convertToDouble() :
530 CFP->getValueAPF().convertToFloat();
526531 std::string StrVal = ftostr(CFP->getValueAPF());
527532
528533 // Check to make sure that the stringized number is not some string like
10531058 printType(F->getFunctionType());
10541059 Out << "* ";
10551060
1056 if (!F->hasName())
1061 if (F->hasName())
10571062 PrintLLVMName(Out, F);
10581063 else
10591064 Out << "@\"\"";