mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[ADT] Remove APInt/APSInt toString() std::string variants
<string> is currently the highest impact header in a clang+llvm build: https://commondatastorage.googleapis.com/chromium-browser-clang/llvm-include-analysis.html One of the most common places this is being included is the APInt.h header, which needs it for an old toString() implementation that returns std::string - an inefficient method compared to the SmallString versions that it actually wraps. This patch replaces these APInt/APSInt methods with a pair of llvm::toString() helpers inside StringExtras.h, adjusts users accordingly and removes the <string> from APInt.h - I was hoping that more of these users could be converted to use the SmallString methods, but it appears that most end up creating a std::string anyhow. I avoided trying to use the raw_ostream << operators as well as I didn't want to lose having the integer radix explicit in the code. Differential Revision: https://reviews.llvm.org/D103888
This commit is contained in:
parent
13db9330f8
commit
165132af1b
@ -20,7 +20,6 @@
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class FoldingSetNodeID;
|
||||
@ -1753,13 +1752,6 @@ public:
|
||||
toString(Str, Radix, true, false);
|
||||
}
|
||||
|
||||
/// Return the APInt as a std::string.
|
||||
///
|
||||
/// Note that this is an inefficient method. It is better to pass in a
|
||||
/// SmallVector/SmallString to the methods above to avoid thrashing the heap
|
||||
/// for the string.
|
||||
std::string toString(unsigned Radix, bool Signed) const;
|
||||
|
||||
/// \returns a byte-swapped representation of this APInt Value.
|
||||
APInt byteSwap() const;
|
||||
|
||||
|
@ -82,11 +82,6 @@ public:
|
||||
void toString(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
|
||||
APInt::toString(Str, Radix, isSigned());
|
||||
}
|
||||
/// Converts an APInt to a std::string. This is an inefficient
|
||||
/// method; you should prefer passing in a SmallString instead.
|
||||
std::string toString(unsigned Radix) const {
|
||||
return APInt::toString(Radix, isSigned());
|
||||
}
|
||||
using APInt::toString;
|
||||
|
||||
/// Get the correctly-extended \c int64_t value.
|
||||
|
@ -13,6 +13,7 @@
|
||||
#ifndef LLVM_ADT_STRINGEXTRAS_H
|
||||
#define LLVM_ADT_STRINGEXTRAS_H
|
||||
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -296,6 +297,17 @@ inline std::string itostr(int64_t X) {
|
||||
return utostr(static_cast<uint64_t>(X));
|
||||
}
|
||||
|
||||
inline std::string toString(const APInt &I, unsigned Radix, bool Signed,
|
||||
bool formatAsCLiteral = false) {
|
||||
SmallString<40> S;
|
||||
I.toString(S, Radix, Signed, formatAsCLiteral);
|
||||
return std::string(S.str());
|
||||
}
|
||||
|
||||
inline std::string toString(const APSInt &I, unsigned Radix) {
|
||||
return toString(I, Radix, I.isSigned());
|
||||
}
|
||||
|
||||
/// StrInStrNoCase - Portable version of strcasestr. Locates the first
|
||||
/// occurrence of string 's1' in string 's2', ignoring case. Returns
|
||||
/// the offset of s2 in s1 or npos if s2 cannot be found.
|
||||
|
@ -88,10 +88,10 @@ LLVM_ATTRIBUTE_UNUSED static void
|
||||
dumpResult(const MachineInstr &MI, const KnownBits &Known, unsigned Depth) {
|
||||
dbgs() << "[" << Depth << "] Compute known bits: " << MI << "[" << Depth
|
||||
<< "] Computed for: " << MI << "[" << Depth << "] Known: 0x"
|
||||
<< (Known.Zero | Known.One).toString(16, false) << "\n"
|
||||
<< "[" << Depth << "] Zero: 0x" << Known.Zero.toString(16, false)
|
||||
<< toString(Known.Zero | Known.One, 16, false) << "\n"
|
||||
<< "[" << Depth << "] Zero: 0x" << toString(Known.Zero, 16, false)
|
||||
<< "\n"
|
||||
<< "[" << Depth << "] One: 0x" << Known.One.toString(16, false)
|
||||
<< "[" << Depth << "] One: 0x" << toString(Known.One, 16, false)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
|
@ -1930,7 +1930,7 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
|
||||
|
||||
static std::string APIntToHexString(const APInt &AI) {
|
||||
unsigned Width = (AI.getBitWidth() / 8) * 2;
|
||||
std::string HexString = AI.toString(16, /*Signed=*/false);
|
||||
std::string HexString = toString(AI, 16, /*Signed=*/false);
|
||||
llvm::transform(HexString, HexString.begin(), tolower);
|
||||
unsigned Size = HexString.size();
|
||||
assert(Width >= Size && "hex string is too large!");
|
||||
|
@ -2281,14 +2281,6 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
|
||||
std::reverse(Str.begin()+StartDig, Str.end());
|
||||
}
|
||||
|
||||
/// Returns the APInt as a std::string. Note that this is an inefficient method.
|
||||
/// It is better to pass in a SmallVector/SmallString to the methods above.
|
||||
std::string APInt::toString(unsigned Radix = 10, bool Signed = true) const {
|
||||
SmallString<40> S;
|
||||
toString(S, Radix, Signed, /* formatAsCLiteral = */false);
|
||||
return std::string(S.str());
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
LLVM_DUMP_METHOD void APInt::dump() const {
|
||||
SmallString<40> S, U;
|
||||
|
@ -2167,7 +2167,7 @@ static void addConstantComments(const MachineInstr *MI,
|
||||
const MachineOperand &DstOp = MI->getOperand(0);
|
||||
CS << X86ATTInstPrinter::getRegisterName(DstOp.getReg()) << " = ";
|
||||
if (auto *CF = dyn_cast<ConstantFP>(C)) {
|
||||
CS << "0x" << CF->getValueAPF().bitcastToAPInt().toString(16, false);
|
||||
CS << "0x" << toString(CF->getValueAPF().bitcastToAPInt(), 16, false);
|
||||
OutStreamer.AddComment(CS.str());
|
||||
}
|
||||
}
|
||||
|
@ -585,7 +585,7 @@ struct OpenMPOpt {
|
||||
return ORA << "OpenMP ICV " << ore::NV("OpenMPICV", ICVInfo.Name)
|
||||
<< " Value: "
|
||||
<< (ICVInfo.InitValue
|
||||
? ICVInfo.InitValue->getValue().toString(10, true)
|
||||
? toString(ICVInfo.InitValue->getValue(), 10, true)
|
||||
: "IMPLEMENTATION_DEFINED");
|
||||
};
|
||||
|
||||
|
@ -255,7 +255,7 @@ template <> struct ScalarTraits<exegesis::RegisterValue> {
|
||||
raw_ostream &Out) {
|
||||
YamlContext &Context = getTypedContext(Ctx);
|
||||
Out << Context.getRegName(RV.Register) << "=0x"
|
||||
<< RV.Value.toString(kRadix, kSigned);
|
||||
<< toString(RV.Value, kRadix, kSigned);
|
||||
}
|
||||
|
||||
static StringRef input(StringRef String, void *Ctx,
|
||||
|
@ -559,7 +559,7 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
|
||||
P.format(" `{0}`", Constant.Name);
|
||||
AutoIndent Indent(P, 7);
|
||||
P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type),
|
||||
Constant.Value.toString(10));
|
||||
toString(Constant.Value, 10));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
|
||||
Error MinimalTypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
|
||||
EnumeratorRecord &Enum) {
|
||||
P.format(" [{0} = {1}]", Enum.Name,
|
||||
Enum.Value.toString(10, Enum.Value.isSigned()));
|
||||
toString(Enum.Value, 10, Enum.Value.isSigned()));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
@ -1461,7 +1461,10 @@ TEST(APIntTest, mul_clear) {
|
||||
APInt ValC(65, 0);
|
||||
ValC = ValA * ValB;
|
||||
ValA *= ValB;
|
||||
EXPECT_EQ(ValA.toString(10, false), ValC.toString(10, false));
|
||||
SmallString<16> StrA, StrC;
|
||||
ValA.toString(StrA, 10, false);
|
||||
ValC.toString(StrC, 10, false);
|
||||
EXPECT_EQ(std::string(StrA), std::string(StrC));
|
||||
}
|
||||
|
||||
TEST(APIntTest, Rotate) {
|
||||
|
@ -229,3 +229,48 @@ TEST(StringExtrasTest, ListSeparator) {
|
||||
S = LS2;
|
||||
EXPECT_EQ(S, " ");
|
||||
}
|
||||
|
||||
TEST(StringExtrasTest, toStringAPInt) {
|
||||
bool isSigned;
|
||||
|
||||
EXPECT_EQ(toString(APInt(8, 0), 2, true, true), "0b0");
|
||||
EXPECT_EQ(toString(APInt(8, 0), 8, true, true), "00");
|
||||
EXPECT_EQ(toString(APInt(8, 0), 10, true, true), "0");
|
||||
EXPECT_EQ(toString(APInt(8, 0), 16, true, true), "0x0");
|
||||
EXPECT_EQ(toString(APInt(8, 0), 36, true, false), "0");
|
||||
|
||||
isSigned = false;
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "0b11111111");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "0377");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "255");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "0xFF");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "73");
|
||||
|
||||
isSigned = true;
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 2, isSigned, true), "-0b1");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 8, isSigned, true), "-01");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 10, isSigned, true), "-1");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 16, isSigned, true), "-0x1");
|
||||
EXPECT_EQ(toString(APInt(8, 255, isSigned), 36, isSigned, false), "-1");
|
||||
}
|
||||
|
||||
TEST(StringExtrasTest, toStringAPSInt) {
|
||||
bool isUnsigned;
|
||||
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 2), "0");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 8), "0");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 10), "0");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 0), false), 16), "0");
|
||||
|
||||
isUnsigned = true;
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "11111111");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "377");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "255");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "FF");
|
||||
|
||||
isUnsigned = false;
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 2), "-1");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 8), "-1");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 10), "-1");
|
||||
EXPECT_EQ(toString(APSInt(APInt(8, 255), isUnsigned), 16), "-1");
|
||||
}
|
Loading…
Reference in New Issue
Block a user