//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
-//
+//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
//===----------------------------------------------------------------------===//
//
// This file defines pass wrappers around LLVM analyses that don't make sense to
//
//===----------------------------------------------------------------------===//
-#include "llvm/iPHINode.h"
-#include "llvm/Type.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/Analysis/InstForest.h"
-#include "llvm/Analysis/Expressions.h"
-#include "llvm/Analysis/InductionVariable.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Support/InstIterator.h"
-
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
- struct InstForestHelper : public FunctionPass {
- Function *F;
- virtual bool runOnFunction(Function &Func) { F = &Func; return false; }
-
- void print(std::ostream &OS) const {
- std::cout << InstForest<char>(F);
- }
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- }
- };
+ /// ExternalFunctionsPassedConstants - This pass prints out call sites to
+ /// external functions that are called with constant arguments. This can be
+ /// useful when looking for standard library functions we should constant fold
+ /// or handle in alias analyses.
+ struct ExternalFunctionsPassedConstants : public ModulePass {
+ static char ID; // Pass ID, replacement for typeid
+ ExternalFunctionsPassedConstants() : ModulePass(ID) {}
+ virtual bool runOnModule(Module &M) {
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+ if (!I->isDeclaration()) continue;
+
+ bool PrintedFn = false;
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI) {
+ Instruction *User = dyn_cast<Instruction>(*UI);
+ if (!User) continue;
+
+ CallSite CS(cast<Value>(User));
+ if (!CS) continue;
+
+ for (CallSite::arg_iterator AI = CS.arg_begin(),
+ E = CS.arg_end(); AI != E; ++AI) {
+ if (!isa<Constant>(*AI)) continue;
- RegisterAnalysis<InstForestHelper> P1("instforest", "InstForest Printer");
+ if (!PrintedFn) {
+ errs() << "Function '" << I->getName() << "':\n";
+ PrintedFn = true;
+ }
+ errs() << *User;
+ break;
+ }
+ }
+ }
- struct IndVars : public FunctionPass {
- Function *F;
- LoopInfo *LI;
- virtual bool runOnFunction(Function &Func) {
- F = &Func; LI = &getAnalysis<LoopInfo>();
return false;
}
- void print(std::ostream &OS) const {
- for (inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I)
- if (PHINode *PN = dyn_cast<PHINode>(*I)) {
- InductionVariable IV(PN, LI);
- if (IV.InductionType != InductionVariable::Unknown)
- IV.print(OS);
- }
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfo>();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
};
+}
- RegisterAnalysis<IndVars> P6("indvars", "Induction Variable Analysis");
-
+char ExternalFunctionsPassedConstants::ID = 0;
+static RegisterPass<ExternalFunctionsPassedConstants>
+ P1("print-externalfnconstants",
+ "Print external fn callsites passed constants");
- struct Exprs : public FunctionPass {
- Function *F;
- virtual bool runOnFunction(Function &Func) { F = &Func; return false; }
+namespace {
+ struct CallGraphPrinter : public ModulePass {
+ static char ID; // Pass ID, replacement for typeid
+ CallGraphPrinter() : ModulePass(ID) {}
- void print(std::ostream &OS) const {
- OS << "Classified expressions for: " << F->getName() << "\n";
- for (inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) {
- OS << *I;
-
- if ((*I)->getType() == Type::VoidTy) continue;
- ExprType R = ClassifyExpression(*I);
- if (R.Var == *I) continue; // Doesn't tell us anything
-
- OS << "\t\tExpr =";
- switch (R.ExprTy) {
- case ExprType::ScaledLinear:
- WriteAsOperand(OS << "(", (Value*)R.Scale) << " ) *";
- // fall through
- case ExprType::Linear:
- WriteAsOperand(OS << "(", R.Var) << " )";
- if (R.Offset == 0) break;
- else OS << " +";
- // fall through
- case ExprType::Constant:
- if (R.Offset) WriteAsOperand(OS, (Value*)R.Offset);
- else OS << " 0";
- break;
- }
- OS << "\n\n";
- }
- }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
+ AU.addRequiredTransitive<CallGraphWrapperPass>();
+ }
+ virtual bool runOnModule(Module &M) {
+ getAnalysis<CallGraphWrapperPass>().print(errs(), &M);
+ return false;
}
};
-
- RegisterAnalysis<Exprs> P7("exprs", "Expression Printer");
}
+
+char CallGraphPrinter::ID = 0;
+static RegisterPass<CallGraphPrinter>
+ P2("print-callgraph", "Print a call graph");