1132718Skan//===- AliasDebugger.cpp - Simple Alias Analysis Use Checker --------------===//
2169689Skan//
3132718Skan//                     The LLVM Compiler Infrastructure
4132718Skan//
5132718Skan// This file is distributed under the University of Illinois Open Source
6132718Skan// License. See LICENSE.TXT for details.
7132718Skan//
8132718Skan//===----------------------------------------------------------------------===//
9132718Skan//
10132718Skan// This simple pass checks alias analysis users to ensure that if they
11132718Skan// create a new value, they do not query AA without informing it of the value.
12132718Skan// It acts as a shim over any other AA pass you want.
13132718Skan//
14132718Skan// Yes keeping track of every value in the program is expensive, but this is
15132718Skan// a debugging pass.
16132718Skan//
17132718Skan//===----------------------------------------------------------------------===//
18169689Skan
19169689Skan#include "llvm/Analysis/Passes.h"
20132718Skan#include "llvm/Analysis/AliasAnalysis.h"
21132718Skan#include "llvm/IR/Constants.h"
22132718Skan#include "llvm/IR/DerivedTypes.h"
23132718Skan#include "llvm/IR/Instructions.h"
24132718Skan#include "llvm/IR/Module.h"
25132718Skan#include "llvm/Pass.h"
26132718Skan#include <set>
27132718Skanusing namespace llvm;
28132718Skan
29132718Skannamespace {
30132718Skan
31132718Skan  class AliasDebugger : public ModulePass, public AliasAnalysis {
32132718Skan
33132718Skan    //What we do is simple.  Keep track of every value the AA could
34132718Skan    //know about, and verify that queries are one of those.
35132718Skan    //A query to a value that didn't exist when the AA was created
36132718Skan    //means someone forgot to update the AA when creating new values
37132718Skan
38132718Skan    std::set<const Value*> Vals;
39132718Skan
40132718Skan  public:
41132718Skan    static char ID; // Class identification, replacement for typeinfo
42132718Skan    AliasDebugger() : ModulePass(ID) {
43132718Skan      initializeAliasDebuggerPass(*PassRegistry::getPassRegistry());
44132718Skan    }
45132718Skan
46132718Skan    bool runOnModule(Module &M) {
47132718Skan      InitializeAliasAnalysis(this);                 // set up super class
48132718Skan
49132718Skan      for(Module::global_iterator I = M.global_begin(),
50132718Skan            E = M.global_end(); I != E; ++I) {
51132718Skan        Vals.insert(&*I);
52132718Skan        for (User::const_op_iterator OI = I->op_begin(),
53132718Skan             OE = I->op_end(); OI != OE; ++OI)
54132718Skan          Vals.insert(*OI);
55132718Skan      }
56132718Skan
57132718Skan      for(Module::iterator I = M.begin(),
58132718Skan            E = M.end(); I != E; ++I){
59132718Skan        Vals.insert(&*I);
60132718Skan        if(!I->isDeclaration()) {
61132718Skan          for (Function::arg_iterator AI = I->arg_begin(), AE = I->arg_end();
62132718Skan               AI != AE; ++AI)
63132718Skan            Vals.insert(&*AI);
64169689Skan          for (Function::const_iterator FI = I->begin(), FE = I->end();
65169689Skan               FI != FE; ++FI)
66169689Skan            for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end();
67169689Skan                 BI != BE; ++BI) {
68169689Skan              Vals.insert(&*BI);
69132718Skan              for (User::const_op_iterator OI = BI->op_begin(),
70169689Skan                   OE = BI->op_end(); OI != OE; ++OI)
71132718Skan                Vals.insert(*OI);
72132718Skan            }
73132718Skan        }
74132718Skan
75132718Skan      }
76132718Skan      return false;
77132718Skan    }
78132718Skan
79132718Skan    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
80132718Skan      AliasAnalysis::getAnalysisUsage(AU);
81132718Skan      AU.setPreservesAll();                         // Does not transform code
82132718Skan    }
83132718Skan
84132718Skan    /// getAdjustedAnalysisPointer - This method is used when a pass implements
85132718Skan    /// an analysis interface through multiple inheritance.  If needed, it
86132718Skan    /// should override this to adjust the this pointer as needed for the
87132718Skan    /// specified pass info.
88169689Skan    virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
89169689Skan      if (PI == &AliasAnalysis::ID)
90132718Skan        return (AliasAnalysis*)this;
91169689Skan      return this;
92169689Skan    }
93132718Skan
94169689Skan    //------------------------------------------------
95132718Skan    // Implement the AliasAnalysis API
96132718Skan    //
97132718Skan    AliasResult alias(const Location &LocA, const Location &LocB) {
98261188Spfg      assert(Vals.find(LocA.Ptr) != Vals.end() &&
99261188Spfg             "Never seen value in AA before");
100261188Spfg      assert(Vals.find(LocB.Ptr) != Vals.end() &&
101261188Spfg             "Never seen value in AA before");
102261188Spfg      return AliasAnalysis::alias(LocA, LocB);
103261188Spfg    }
104261188Spfg
105261188Spfg    ModRefResult getModRefInfo(ImmutableCallSite CS,
106261188Spfg                               const Location &Loc) {
107261188Spfg      assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before");
108261188Spfg      return AliasAnalysis::getModRefInfo(CS, Loc);
109261188Spfg    }
110169689Skan
111169689Skan    ModRefResult getModRefInfo(ImmutableCallSite CS1,
112169689Skan                               ImmutableCallSite CS2) {
113169689Skan      return AliasAnalysis::getModRefInfo(CS1,CS2);
114169689Skan    }
115169689Skan
116169689Skan    bool pointsToConstantMemory(const Location &Loc, bool OrLocal) {
117169689Skan      assert(Vals.find(Loc.Ptr) != Vals.end() && "Never seen value in AA before");
118169689Skan      return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
119169689Skan    }
120169689Skan
121169689Skan    virtual void deleteValue(Value *V) {
122169689Skan      assert(Vals.find(V) != Vals.end() && "Never seen value in AA before");
123169689Skan      AliasAnalysis::deleteValue(V);
124169689Skan    }
125169689Skan    virtual void copyValue(Value *From, Value *To) {
126169689Skan      Vals.insert(To);
127169689Skan      AliasAnalysis::copyValue(From, To);
128169689Skan    }
129169689Skan
130169689Skan  };
131169689Skan}
132169689Skan
133169689Skanchar AliasDebugger::ID = 0;
134169689SkanINITIALIZE_AG_PASS(AliasDebugger, AliasAnalysis, "debug-aa",
135169689Skan                   "AA use debugger", false, true, false)
136132718Skan
137169689SkanPass *llvm::createAliasDebugger() { return new AliasDebugger(); }
138132718Skan
139132718Skan