mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
138 lines
4.8 KiB
C
138 lines
4.8 KiB
C
|
//===- MemoryLocation.h - Memory location descriptions ----------*- C++ -*-===//
|
||
|
//
|
||
|
// The LLVM Compiler Infrastructure
|
||
|
//
|
||
|
// This file is distributed under the University of Illinois Open Source
|
||
|
// License. See LICENSE.TXT for details.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
/// \file
|
||
|
/// This file provides utility analysis objects describing memory locations.
|
||
|
/// These are used both by the Alias Analysis infrastructure and more
|
||
|
/// specialized memory analysis layers.
|
||
|
///
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef LLVM_ANALYSIS_MEMORYLOCATION_H
|
||
|
#define LLVM_ANALYSIS_MEMORYLOCATION_H
|
||
|
|
||
|
#include "llvm/ADT/DenseMap.h"
|
||
|
#include "llvm/IR/CallSite.h"
|
||
|
#include "llvm/IR/Metadata.h"
|
||
|
|
||
|
namespace llvm {
|
||
|
|
||
|
class LoadInst;
|
||
|
class StoreInst;
|
||
|
class MemTransferInst;
|
||
|
class MemIntrinsic;
|
||
|
|
||
|
/// Representation for a specific memory location.
|
||
|
///
|
||
|
/// This abstraction can be used to represent a specific location in memory.
|
||
|
/// The goal of the location is to represent enough information to describe
|
||
|
/// abstract aliasing, modification, and reference behaviors of whatever
|
||
|
/// value(s) are stored in memory at the particular location.
|
||
|
///
|
||
|
/// The primary user of this interface is LLVM's Alias Analysis, but other
|
||
|
/// memory analyses such as MemoryDependence can use it as well.
|
||
|
class MemoryLocation {
|
||
|
public:
|
||
|
/// UnknownSize - This is a special value which can be used with the
|
||
|
/// size arguments in alias queries to indicate that the caller does not
|
||
|
/// know the sizes of the potential memory references.
|
||
|
enum : uint64_t { UnknownSize = ~UINT64_C(0) };
|
||
|
|
||
|
/// The address of the start of the location.
|
||
|
const Value *Ptr;
|
||
|
|
||
|
/// The maximum size of the location, in address-units, or
|
||
|
/// UnknownSize if the size is not known.
|
||
|
///
|
||
|
/// Note that an unknown size does not mean the pointer aliases the entire
|
||
|
/// virtual address space, because there are restrictions on stepping out of
|
||
|
/// one object and into another. See
|
||
|
/// http://llvm.org/docs/LangRef.html#pointeraliasing
|
||
|
uint64_t Size;
|
||
|
|
||
|
/// The metadata nodes which describes the aliasing of the location (each
|
||
|
/// member is null if that kind of information is unavailable).
|
||
|
AAMDNodes AATags;
|
||
|
|
||
|
/// Return a location with information about the memory reference by the given
|
||
|
/// instruction.
|
||
|
static MemoryLocation get(const LoadInst *LI);
|
||
|
static MemoryLocation get(const StoreInst *SI);
|
||
|
static MemoryLocation get(const VAArgInst *VI);
|
||
|
static MemoryLocation get(const AtomicCmpXchgInst *CXI);
|
||
|
static MemoryLocation get(const AtomicRMWInst *RMWI);
|
||
|
static MemoryLocation get(const Instruction *Inst) {
|
||
|
if (auto *I = dyn_cast<LoadInst>(Inst))
|
||
|
return get(I);
|
||
|
else if (auto *I = dyn_cast<StoreInst>(Inst))
|
||
|
return get(I);
|
||
|
else if (auto *I = dyn_cast<VAArgInst>(Inst))
|
||
|
return get(I);
|
||
|
else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst))
|
||
|
return get(I);
|
||
|
else if (auto *I = dyn_cast<AtomicRMWInst>(Inst))
|
||
|
return get(I);
|
||
|
llvm_unreachable("unsupported memory instruction");
|
||
|
}
|
||
|
|
||
|
/// Return a location representing the source of a memory transfer.
|
||
|
static MemoryLocation getForSource(const MemTransferInst *MTI);
|
||
|
|
||
|
/// Return a location representing the destination of a memory set or
|
||
|
/// transfer.
|
||
|
static MemoryLocation getForDest(const MemIntrinsic *MI);
|
||
|
|
||
|
explicit MemoryLocation(const Value *Ptr = nullptr,
|
||
|
uint64_t Size = UnknownSize,
|
||
|
const AAMDNodes &AATags = AAMDNodes())
|
||
|
: Ptr(Ptr), Size(Size), AATags(AATags) {}
|
||
|
|
||
|
MemoryLocation getWithNewPtr(const Value *NewPtr) const {
|
||
|
MemoryLocation Copy(*this);
|
||
|
Copy.Ptr = NewPtr;
|
||
|
return Copy;
|
||
|
}
|
||
|
|
||
|
MemoryLocation getWithNewSize(uint64_t NewSize) const {
|
||
|
MemoryLocation Copy(*this);
|
||
|
Copy.Size = NewSize;
|
||
|
return Copy;
|
||
|
}
|
||
|
|
||
|
MemoryLocation getWithoutAATags() const {
|
||
|
MemoryLocation Copy(*this);
|
||
|
Copy.AATags = AAMDNodes();
|
||
|
return Copy;
|
||
|
}
|
||
|
|
||
|
bool operator==(const MemoryLocation &Other) const {
|
||
|
return Ptr == Other.Ptr && Size == Other.Size && AATags == Other.AATags;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// Specialize DenseMapInfo for MemoryLocation.
|
||
|
template <> struct DenseMapInfo<MemoryLocation> {
|
||
|
static inline MemoryLocation getEmptyKey() {
|
||
|
return MemoryLocation(DenseMapInfo<const Value *>::getEmptyKey(), 0);
|
||
|
}
|
||
|
static inline MemoryLocation getTombstoneKey() {
|
||
|
return MemoryLocation(DenseMapInfo<const Value *>::getTombstoneKey(), 0);
|
||
|
}
|
||
|
static unsigned getHashValue(const MemoryLocation &Val) {
|
||
|
return DenseMapInfo<const Value *>::getHashValue(Val.Ptr) ^
|
||
|
DenseMapInfo<uint64_t>::getHashValue(Val.Size) ^
|
||
|
DenseMapInfo<AAMDNodes>::getHashValue(Val.AATags);
|
||
|
}
|
||
|
static bool isEqual(const MemoryLocation &LHS, const MemoryLocation &RHS) {
|
||
|
return LHS == RHS;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#endif
|