//
//===----------------------------------------------------------------------===//
-#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/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include <iostream>
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();
- }
- };
-
- RegisterAnalysis<InstForestHelper> P1("instforest", "InstForest Printer");
+ /// 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 {
+ virtual bool runOnModule(Module &M) {
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (I->isExternal()) {
+ bool PrintedFn = false;
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI)
+ if (Instruction *User = dyn_cast<Instruction>(*UI)) {
+ CallSite CS = CallSite::get(User);
+ if (CS.getInstruction()) {
+ for (CallSite::arg_iterator AI = CS.arg_begin(),
+ E = CS.arg_end(); AI != E; ++AI)
+ if (isa<Constant>(*AI)) {
+ if (!PrintedFn) {
+ std::cerr << "Function '" << I->getName() << "':\n";
+ PrintedFn = true;
+ }
+ std::cerr << *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 print(std::ostream &OS) const {}
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<LoopInfo>();
- AU.setPreservesAll();
- }
- };
-
- RegisterAnalysis<IndVars> P6("indvars", "Induction Variable Analysis");
-
-
- struct Exprs : public FunctionPass {
- Function *F;
- virtual bool runOnFunction(Function &Func) { F = &Func; return false; }
-
- 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();
}
};
- RegisterAnalysis<Exprs> P7("exprs", "Expression Printer");
+ RegisterAnalysis<ExternalFunctionsPassedConstants>
+ P2("externalfnconstants", "Print external fn callsites passed constants");
}