LibCallAliasAnalysis.cpp [plain text]
#include "llvm/Analysis/LibCallAliasAnalysis.h"
#include "llvm/Analysis/LibCallSemantics.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
using namespace llvm;
char LibCallAliasAnalysis::ID = 0;
INITIALIZE_AG_PASS(LibCallAliasAnalysis, AliasAnalysis, "libcall-aa",
"LibCall Alias Analysis", false, true, false)
FunctionPass *llvm::createLibCallAliasAnalysisPass(LibCallInfo *LCI) {
return new LibCallAliasAnalysis(LCI);
}
LibCallAliasAnalysis::~LibCallAliasAnalysis() {
delete LCI;
}
void LibCallAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AliasAnalysis::getAnalysisUsage(AU);
AU.setPreservesAll(); }
bool LibCallAliasAnalysis::runOnFunction(Function &F) {
InitializeAliasAnalysis(this, &F.getParent()->getDataLayout());
return false;
}
AliasAnalysis::ModRefResult
LibCallAliasAnalysis::AnalyzeLibCallDetails(const LibCallFunctionInfo *FI,
ImmutableCallSite CS,
const Location &Loc) {
AliasAnalysis::ModRefResult MRInfo = FI->UniversalBehavior;
if (MRInfo == NoModRef) return MRInfo;
const LibCallFunctionInfo::LocationMRInfo *Details = FI->LocationDetails;
if (Details == nullptr)
return MRInfo;
if (FI->DetailsType == LibCallFunctionInfo::DoesNot) {
for (unsigned i = 0; Details[i].LocationID != ~0U; ++i) {
const LibCallLocationInfo &LocInfo =
LCI->getLocationInfo(Details[i].LocationID);
LibCallLocationInfo::LocResult Res = LocInfo.isLocation(CS, Loc);
if (Res != LibCallLocationInfo::Yes) continue;
return ModRefResult(MRInfo & ~Details[i].MRInfo);
}
return MRInfo;
}
assert(FI->DetailsType == LibCallFunctionInfo::DoesOnly);
bool NoneMatch = true;
for (unsigned i = 0; Details[i].LocationID != ~0U; ++i) {
const LibCallLocationInfo &LocInfo =
LCI->getLocationInfo(Details[i].LocationID);
LibCallLocationInfo::LocResult Res = LocInfo.isLocation(CS, Loc);
if (Res == LibCallLocationInfo::No) continue;
if (Res == LibCallLocationInfo::Unknown) {
NoneMatch = false;
continue;
}
return ModRefResult(MRInfo & Details[i].MRInfo);
}
if (NoneMatch)
return NoModRef;
return MRInfo;
}
AliasAnalysis::ModRefResult
LibCallAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
const Location &Loc) {
ModRefResult MRInfo = ModRef;
if (LCI) {
if (const Function *F = CS.getCalledFunction()) {
if (const LibCallFunctionInfo *FI = LCI->getFunctionInfo(F)) {
MRInfo = ModRefResult(MRInfo & AnalyzeLibCallDetails(FI, CS, Loc));
if (MRInfo == NoModRef) return NoModRef;
}
}
}
return (ModRefResult)(MRInfo | AliasAnalysis::getModRefInfo(CS, Loc));
}