int.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/base/int.h"
  5. #include <algorithm>
  6. #include <string>
  7. namespace Carbon {
  8. auto IntStore::CanonicalBitWidth(int significant_bits) -> int {
  9. // For larger integers, we store them in as a signed APInt with a canonical
  10. // width that is the smallest multiple of the word type's bits, but no
  11. // smaller than a minimum of 64 bits to avoid spurious resizing of the most
  12. // common cases (<= 64 bits).
  13. static constexpr int WordWidth = llvm::APInt::APINT_BITS_PER_WORD;
  14. return std::max<int>(
  15. MinAPWidth, ((significant_bits + WordWidth - 1) / WordWidth) * WordWidth);
  16. }
  17. auto IntStore::CanonicalizeSigned(llvm::APInt value) -> llvm::APInt {
  18. return value.sextOrTrunc(CanonicalBitWidth(value.getSignificantBits()));
  19. }
  20. auto IntStore::CanonicalizeUnsigned(llvm::APInt value) -> llvm::APInt {
  21. // We need the width to include a zero sign bit as we canonicalize to a
  22. // signed representation.
  23. return value.zextOrTrunc(CanonicalBitWidth(value.getActiveBits() + 1));
  24. }
  25. auto IntStore::AddLarge(int64_t value) -> IntId {
  26. auto ap_id =
  27. values_.Add(llvm::APInt(CanonicalBitWidth(64), value, /*isSigned=*/true));
  28. return MakeIndexOrNone(ap_id.index);
  29. }
  30. auto IntStore::AddSignedLarge(llvm::APInt value) -> IntId {
  31. auto ap_id = values_.Add(CanonicalizeSigned(value));
  32. return MakeIndexOrNone(ap_id.index);
  33. }
  34. auto IntStore::AddUnsignedLarge(llvm::APInt value) -> IntId {
  35. auto ap_id = values_.Add(CanonicalizeUnsigned(value));
  36. return MakeIndexOrNone(ap_id.index);
  37. }
  38. auto IntStore::LookupLarge(int64_t value) const -> IntId {
  39. auto ap_id = values_.Lookup(
  40. llvm::APInt(CanonicalBitWidth(64), value, /*isSigned=*/true));
  41. return MakeIndexOrNone(ap_id.index);
  42. }
  43. auto IntStore::LookupSignedLarge(llvm::APInt value) const -> IntId {
  44. auto ap_id = values_.Lookup(CanonicalizeSigned(value));
  45. return MakeIndexOrNone(ap_id.index);
  46. }
  47. auto IntStore::OutputYaml() const -> Yaml::OutputMapping {
  48. return values_.OutputYaml();
  49. }
  50. auto IntStore::CollectMemUsage(MemUsage& mem_usage, llvm::StringRef label) const
  51. -> void {
  52. mem_usage.Collect(std::string(label), values_);
  53. }
  54. } // namespace Carbon