mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 06:32:24 +00:00
port it to the new pass manager. All this does is extract the inner "location" class used by AA into its own full fledged type. This seems *much* cleaner as MemoryDependence and soon MemorySSA also use this heavily, and it doesn't make much sense being inside the AA infrastructure. This will also make it much easier to break apart the AA infrastructure into something that stands on its own rather than using the analysis group design. There are a few places where this makes APIs not make sense -- they were taking an AliasAnalysis pointer just to build locations. I'll try to clean those up in follow-up commits. Differential Revision: http://reviews.llvm.org/D10228 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239003 91177308-0d34-0410-b5e6-96231b3b80d8
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
|