forked from OSchip/llvm-project
70 lines
2.1 KiB
C++
70 lines
2.1 KiB
C++
//===--------- MarkModRef.cpp - Mark functions readnone/readonly ----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This pass marks functions readnone/readonly based on the results of alias
|
|
// analysis. This requires a sufficiently powerful alias analysis, such as
|
|
// GlobalsModRef (invoke as "opt ... -globalsmodref-aa -markmodref ...").
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "markmodref"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include "llvm/Transforms/Scalar.h"
|
|
#include "llvm/Function.h"
|
|
#include "llvm/Pass.h"
|
|
using namespace llvm;
|
|
|
|
STATISTIC(NumReadNone, "Number of functions marked readnone");
|
|
STATISTIC(NumReadOnly, "Number of functions marked readonly");
|
|
|
|
namespace {
|
|
struct VISIBILITY_HIDDEN MarkModRef : public FunctionPass {
|
|
static char ID; // Pass identification, replacement for typeid
|
|
MarkModRef() : FunctionPass(&ID) {}
|
|
|
|
bool runOnFunction(Function &F);
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesCFG();
|
|
AU.addRequired<AliasAnalysis>();
|
|
AU.addPreserved<AliasAnalysis>();
|
|
}
|
|
};
|
|
}
|
|
|
|
char MarkModRef::ID = 0;
|
|
static RegisterPass<MarkModRef>
|
|
X("markmodref", "Mark functions readnone/readonly");
|
|
|
|
bool MarkModRef::runOnFunction(Function &F) {
|
|
// FIXME: Wrong for functions with weak linkage.
|
|
if (F.doesNotAccessMemory())
|
|
// Cannot do better.
|
|
return false;
|
|
|
|
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
|
AliasAnalysis::ModRefBehavior ModRef = AA.getModRefBehavior(&F);
|
|
if (ModRef == AliasAnalysis::DoesNotAccessMemory) {
|
|
F.setDoesNotAccessMemory();
|
|
NumReadNone++;
|
|
return true;
|
|
} else if (ModRef == AliasAnalysis::OnlyReadsMemory && !F.onlyReadsMemory()) {
|
|
F.setOnlyReadsMemory();
|
|
NumReadOnly++;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
FunctionPass *llvm::createMarkModRefPass() {
|
|
return new MarkModRef();
|
|
}
|