Improve instcombine's handling of integer min and max in two ways:
[oota-llvm.git] / lib / Transforms / Scalar / MarkModRef.cpp
1 //===--------- MarkModRef.cpp - Mark functions readnone/readonly ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass marks functions readnone/readonly based on the results of alias
11 // analysis.  This requires a sufficiently powerful alias analysis, such as
12 // GlobalsModRef (invoke as "opt ... -globalsmodref-aa -markmodref ...").
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define DEBUG_TYPE "markmodref"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/Analysis/AliasAnalysis.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Transforms/Scalar.h"
21 #include "llvm/Function.h"
22 #include "llvm/Pass.h"
23 using namespace llvm;
24
25 STATISTIC(NumReadNone, "Number of functions marked readnone");
26 STATISTIC(NumReadOnly, "Number of functions marked readonly");
27
28 namespace {
29   struct VISIBILITY_HIDDEN MarkModRef : public FunctionPass {
30     static char ID; // Pass identification, replacement for typeid
31     MarkModRef() : FunctionPass(&ID) {}
32
33     bool runOnFunction(Function &F);
34
35     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
36       AU.setPreservesCFG();
37       AU.addRequired<AliasAnalysis>();
38       AU.addPreserved<AliasAnalysis>();
39     }
40   };
41 }
42
43 char MarkModRef::ID = 0;
44 static RegisterPass<MarkModRef>
45 X("markmodref", "Mark functions readnone/readonly");
46
47 bool MarkModRef::runOnFunction(Function &F) {
48   // FIXME: Wrong for functions with weak linkage.
49   if (F.doesNotAccessMemory())
50     // Cannot do better.
51     return false;
52
53   AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
54   AliasAnalysis::ModRefBehavior ModRef = AA.getModRefBehavior(&F);
55   if (ModRef == AliasAnalysis::DoesNotAccessMemory) {
56     F.setDoesNotAccessMemory();
57     NumReadNone++;
58     return true;
59   } else if (ModRef == AliasAnalysis::OnlyReadsMemory && !F.onlyReadsMemory()) {
60     F.setOnlyReadsMemory();
61     NumReadOnly++;
62     return true;
63   }
64   return false;
65 }
66
67 FunctionPass *llvm::createMarkModRefPass() {
68   return new MarkModRef();
69 }