| //===- AllocToken.cpp - Allocation Token Calculation ----------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Definition of AllocToken modes and shared calculation of stateless token IDs. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/Support/AllocToken.h" |
| #include "llvm/ADT/StringSwitch.h" |
| #include "llvm/Support/ErrorHandling.h" |
| #include "llvm/Support/SipHash.h" |
| |
| using namespace llvm; |
| |
| std::optional<AllocTokenMode> |
| llvm::getAllocTokenModeFromString(StringRef Name) { |
| return StringSwitch<std::optional<AllocTokenMode>>(Name) |
| .Case("increment", AllocTokenMode::Increment) |
| .Case("random", AllocTokenMode::Random) |
| .Case("typehash", AllocTokenMode::TypeHash) |
| .Case("typehashpointersplit", AllocTokenMode::TypeHashPointerSplit) |
| .Case("default", DefaultAllocTokenMode) |
| .Default(std::nullopt); |
| } |
| |
| StringRef llvm::getAllocTokenModeAsString(AllocTokenMode Mode) { |
| switch (Mode) { |
| case AllocTokenMode::Increment: |
| return "increment"; |
| case AllocTokenMode::Random: |
| return "random"; |
| case AllocTokenMode::TypeHash: |
| return "typehash"; |
| case AllocTokenMode::TypeHashPointerSplit: |
| return "typehashpointersplit"; |
| } |
| llvm_unreachable("Unknown AllocTokenMode"); |
| } |
| |
| static uint64_t getStableHash(const AllocTokenMetadata &Metadata, |
| uint64_t MaxTokens) { |
| return getStableSipHash(Metadata.TypeName) % MaxTokens; |
| } |
| |
| std::optional<uint64_t> llvm::getAllocToken(AllocTokenMode Mode, |
| const AllocTokenMetadata &Metadata, |
| uint64_t MaxTokens) { |
| assert(MaxTokens && "Must provide non-zero max tokens"); |
| |
| switch (Mode) { |
| case AllocTokenMode::Increment: |
| case AllocTokenMode::Random: |
| // Stateful modes cannot be implemented as a pure function. |
| return std::nullopt; |
| |
| case AllocTokenMode::TypeHash: |
| return getStableHash(Metadata, MaxTokens); |
| |
| case AllocTokenMode::TypeHashPointerSplit: { |
| if (MaxTokens == 1) |
| return 0; |
| const uint64_t HalfTokens = MaxTokens / 2; |
| uint64_t Hash = getStableHash(Metadata, HalfTokens); |
| if (Metadata.ContainsPointer) |
| Hash += HalfTokens; |
| return Hash; |
| } |
| } |
| |
| llvm_unreachable(""); |
| } |