CFLAliasAnalysis.h [plain text]
#ifndef LLVM_ANALYSIS_CFLALIASANALYSIS_H
#define LLVM_ANALYSIS_CFLALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include <forward_list>
namespace llvm {
class CFLAAResult : public AAResultBase<CFLAAResult> {
friend AAResultBase<CFLAAResult>;
struct FunctionInfo;
public:
explicit CFLAAResult();
CFLAAResult(CFLAAResult &&Arg);
bool invalidate(Function &, const PreservedAnalyses &) { return false; }
void scan(Function *Fn);
void evict(Function *Fn);
const Optional<FunctionInfo> &ensureCached(Function *Fn);
AliasResult query(const MemoryLocation &LocA, const MemoryLocation &LocB);
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB) {
if (LocA.Ptr == LocB.Ptr) {
if (LocA.Size == LocB.Size) {
return MustAlias;
} else {
return PartialAlias;
}
}
if (isa<Constant>(LocA.Ptr) && isa<Constant>(LocB.Ptr)) {
return AAResultBase::alias(LocA, LocB);
}
AliasResult QueryResult = query(LocA, LocB);
if (QueryResult == MayAlias)
return AAResultBase::alias(LocA, LocB);
return QueryResult;
}
private:
struct FunctionHandle final : public CallbackVH {
FunctionHandle(Function *Fn, CFLAAResult *Result)
: CallbackVH(Fn), Result(Result) {
assert(Fn != nullptr);
assert(Result != nullptr);
}
void deleted() override { removeSelfFromCache(); }
void allUsesReplacedWith(Value *) override { removeSelfFromCache(); }
private:
CFLAAResult *Result;
void removeSelfFromCache() {
assert(Result != nullptr);
auto *Val = getValPtr();
Result->evict(cast<Function>(Val));
setValPtr(nullptr);
}
};
DenseMap<Function *, Optional<FunctionInfo>> Cache;
std::forward_list<FunctionHandle> Handles;
FunctionInfo buildSetsFrom(Function *F);
};
class CFLAA {
public:
typedef CFLAAResult Result;
static void *ID() { return (void *)&PassID; }
CFLAAResult run(Function &F, AnalysisManager<Function> *AM);
static StringRef name() { return "CFLAA"; }
private:
static char PassID;
};
class CFLAAWrapperPass : public ImmutablePass {
std::unique_ptr<CFLAAResult> Result;
public:
static char ID;
CFLAAWrapperPass();
CFLAAResult &getResult() { return *Result; }
const CFLAAResult &getResult() const { return *Result; }
bool doInitialization(Module &M) override;
bool doFinalization(Module &M) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
};
ImmutablePass *createCFLAAWrapperPass();
}
#endif