Skip to content

Commit

Permalink
merge main into amd-staging
Browse files Browse the repository at this point in the history
Change-Id: Ia1e630bd686c17726695b0162eff9f72aec14348
  • Loading branch information
Jenkins committed Oct 27, 2024
2 parents a427ec2 + d2e9532 commit c655c5a
Show file tree
Hide file tree
Showing 17 changed files with 550 additions and 87 deletions.
6 changes: 3 additions & 3 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
}

static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
if (!Ptr.isBlockPointer())
if (!Ptr.isStatic() || !Ptr.isBlockPointer())
return true;
return CheckConstant(S, OpPC, Ptr.getDeclDesc());
}
Expand Down Expand Up @@ -513,8 +513,8 @@ bool CheckMutable(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
return false;
}

bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK) {
static bool CheckVolatile(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
AccessKinds AK) {
assert(Ptr.isLive());

// FIXME: This check here might be kinda expensive. Maybe it would be better
Expand Down
26 changes: 10 additions & 16 deletions llvm/include/llvm/ADT/StringRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,7 @@ namespace llvm {
using const_reverse_iterator = std::reverse_iterator<const_iterator>;

private:
/// The start of the string, in an external buffer.
const char *Data = nullptr;

/// The length of the string.
size_t Length = 0;
std::string_view View;

// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
Expand All @@ -86,27 +82,25 @@ namespace llvm {

/// Construct a string ref from a cstring.
/*implicit*/ constexpr StringRef(const char *Str)
: Data(Str), Length(Str ?
: View(Str, Str ?
// GCC 7 doesn't have constexpr char_traits. Fall back to __builtin_strlen.
#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 8
__builtin_strlen(Str)
__builtin_strlen(Str)
#else
std::char_traits<char>::length(Str)
std::char_traits<char>::length(Str)
#endif
: 0) {
: 0) {
}

/// Construct a string ref from a pointer and length.
/*implicit*/ constexpr StringRef(const char *data, size_t length)
: Data(data), Length(length) {}
: View(data, length) {}

/// Construct a string ref from an std::string.
/*implicit*/ StringRef(const std::string &Str)
: Data(Str.data()), Length(Str.length()) {}
/*implicit*/ StringRef(const std::string &Str) : View(Str) {}

/// Construct a string ref from an std::string_view.
/*implicit*/ constexpr StringRef(std::string_view Str)
: Data(Str.data()), Length(Str.size()) {}
/*implicit*/ constexpr StringRef(std::string_view Str) : View(Str) {}

/// @}
/// @name Iterators
Expand Down Expand Up @@ -140,13 +134,13 @@ namespace llvm {

/// data - Get a pointer to the start of the string (which may not be null
/// terminated).
[[nodiscard]] constexpr const char *data() const { return Data; }
[[nodiscard]] constexpr const char *data() const { return View.data(); }

/// empty - Check if the string is empty.
[[nodiscard]] constexpr bool empty() const { return size() == 0; }

/// size - Get the string size.
[[nodiscard]] constexpr size_t size() const { return Length; }
[[nodiscard]] constexpr size_t size() const { return View.size(); }

/// front - Get the first character in the string.
[[nodiscard]] char front() const {
Expand Down
13 changes: 10 additions & 3 deletions llvm/include/llvm/Analysis/StructuralHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@

namespace llvm {

enum class StructuralHashOptions {
None, /// Hash with opcode only.
Detailed, /// Hash with opcode and operands.
CallTargetIgnored, /// Ignore call target operand when computing hash.
};

/// Printer pass for StructuralHashes
class StructuralHashPrinterPass
: public PassInfoMixin<StructuralHashPrinterPass> {
raw_ostream &OS;
bool EnableDetailedStructuralHash;
const StructuralHashOptions Options;

public:
explicit StructuralHashPrinterPass(raw_ostream &OS, bool Detailed)
: OS(OS), EnableDetailedStructuralHash(Detailed) {}
explicit StructuralHashPrinterPass(raw_ostream &OS,
StructuralHashOptions Options)
: OS(OS), Options(Options) {}

PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);

Expand Down
45 changes: 45 additions & 0 deletions llvm/include/llvm/IR/StructuralHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#ifndef LLVM_IR_STRUCTURALHASH_H
#define LLVM_IR_STRUCTURALHASH_H

#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StableHashing.h"
#include "llvm/IR/Instruction.h"
#include <cstdint>

namespace llvm {
Expand All @@ -35,6 +37,49 @@ stable_hash StructuralHash(const Function &F, bool DetailedHash = false);
/// composed the module hash.
stable_hash StructuralHash(const Module &M, bool DetailedHash = false);

/// The pair of an instruction index and a operand index.
using IndexPair = std::pair<unsigned, unsigned>;

/// A map from an instruction index to an instruction pointer.
using IndexInstrMap = MapVector<unsigned, Instruction *>;

/// A map from an IndexPair to a stable hash.
using IndexOperandHashMapType = DenseMap<IndexPair, stable_hash>;

/// A function that takes an instruction and an operand index and returns true
/// if the operand should be ignored in the function hash computation.
using IgnoreOperandFunc = std::function<bool(const Instruction *, unsigned)>;

struct FunctionHashInfo {
/// A hash value representing the structural content of the function
stable_hash FunctionHash;
/// A mapping from instruction indices to instruction pointers
std::unique_ptr<IndexInstrMap> IndexInstruction;
/// A mapping from pairs of instruction indices and operand indices
/// to the hashes of the operands. This can be used to analyze or
/// reconstruct the differences in ignored operands
std::unique_ptr<IndexOperandHashMapType> IndexOperandHashMap;

FunctionHashInfo(stable_hash FuntionHash,
std::unique_ptr<IndexInstrMap> IndexInstruction,
std::unique_ptr<IndexOperandHashMapType> IndexOperandHashMap)
: FunctionHash(FuntionHash),
IndexInstruction(std::move(IndexInstruction)),
IndexOperandHashMap(std::move(IndexOperandHashMap)) {}
};

/// Computes a structural hash of a given function, considering the structure
/// and content of the function's instructions while allowing for selective
/// ignoring of certain operands based on custom criteria. This hash can be used
/// to identify functions that are structurally similar or identical, which is
/// useful in optimizations, deduplication, or analysis tasks.
/// \param F The function to hash.
/// \param IgnoreOp A callable that takes an instruction and an operand index,
/// and returns true if the operand should be ignored in the hash computation.
/// \return A FunctionHashInfo structure
FunctionHashInfo StructuralHashWithDifferences(const Function &F,
IgnoreOperandFunc IgnoreOp);

} // end namespace llvm

#endif
27 changes: 23 additions & 4 deletions llvm/lib/Analysis/StructuralHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,33 @@ using namespace llvm;
PreservedAnalyses StructuralHashPrinterPass::run(Module &M,
ModuleAnalysisManager &MAM) {
OS << "Module Hash: "
<< format("%016" PRIx64, StructuralHash(M, EnableDetailedStructuralHash))
<< format("%016" PRIx64,
StructuralHash(M, Options != StructuralHashOptions::None))
<< "\n";
for (Function &F : M) {
if (F.isDeclaration())
continue;
OS << "Function " << F.getName() << " Hash: "
<< format("%016" PRIx64, StructuralHash(F, EnableDetailedStructuralHash))
<< "\n";
if (Options == StructuralHashOptions::CallTargetIgnored) {
auto IgnoreOp = [&](const Instruction *I, unsigned OpndIdx) {
return I->getOpcode() == Instruction::Call &&
isa<Constant>(I->getOperand(OpndIdx));
};
auto FuncHashInfo = StructuralHashWithDifferences(F, IgnoreOp);
OS << "Function " << F.getName()
<< " Hash: " << format("%016" PRIx64, FuncHashInfo.FunctionHash)
<< "\n";
for (auto &[IndexPair, OpndHash] : *FuncHashInfo.IndexOperandHashMap) {
auto [InstIndex, OpndIndex] = IndexPair;
OS << "\tIgnored Operand Hash: " << format("%016" PRIx64, OpndHash)
<< " at (" << InstIndex << "," << OpndIndex << ")\n";
}
} else {
OS << "Function " << F.getName() << " Hash: "
<< format(
"%016" PRIx64,
StructuralHash(F, Options == StructuralHashOptions::Detailed))
<< "\n";
}
}
return PreservedAnalyses::all();
}
Loading

0 comments on commit c655c5a

Please sign in to comment.