mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-01 04:29:57 +00:00
CallGraph. This makes the CallGraph a totally generic analysis object that is the container for the graph data structure and the primary interface for querying and manipulating it. The pass logic is separated into its own class. For compatibility reasons, the pass provides wrapper methods for most of the methods on CallGraph -- they all just forward. This will allow the new pass manager infrastructure to provide its own analysis pass that constructs the same CallGraph object and makes it available. The idea is that in the new pass manager, the analysis pass's 'run' method returns a concrete analysis 'result'. Here, that result is a 'CallGraph'. The 'run' method will typically do only minimal work, deferring much of the work into the implementation of the result object in order to be lazy about computing things, but when (like DomTree) there is *some* up-front computation, the analysis does it prior to handing the result back to the querying pass. I know some of this is fairly ugly. I'm happy to change it around if folks can suggest a cleaner interim state, but there is going to be some amount of unavoidable ugliness during the transition period. The good thing is that this is very limited and will naturally go away when the old pass infrastructure goes away. It won't hang around to bother us later. Next up is the initial new-PM-style call graph analysis. =] git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195722 91177308-0d34-0410-b5e6-96231b3b80d8
95 lines
3.2 KiB
C++
95 lines
3.2 KiB
C++
//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// 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
|
|
// be passes. It provides a nice standard pass interface to these classes so
|
|
// that they can be printed out by analyze.
|
|
//
|
|
// These classes are separated out of analyze.cpp so that it is more clear which
|
|
// code is the integral part of the analyze tool, and which part of the code is
|
|
// just making it so more passes are available.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#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 {
|
|
/// 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;
|
|
|
|
if (!PrintedFn) {
|
|
errs() << "Function '" << I->getName() << "':\n";
|
|
PrintedFn = true;
|
|
}
|
|
errs() << *User;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesAll();
|
|
}
|
|
};
|
|
}
|
|
|
|
char ExternalFunctionsPassedConstants::ID = 0;
|
|
static RegisterPass<ExternalFunctionsPassedConstants>
|
|
P1("print-externalfnconstants",
|
|
"Print external fn callsites passed constants");
|
|
|
|
namespace {
|
|
struct CallGraphPrinter : public ModulePass {
|
|
static char ID; // Pass ID, replacement for typeid
|
|
CallGraphPrinter() : ModulePass(ID) {}
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
|
AU.setPreservesAll();
|
|
AU.addRequiredTransitive<CallGraphWrapperPass>();
|
|
}
|
|
virtual bool runOnModule(Module &M) {
|
|
getAnalysis<CallGraphWrapperPass>().print(errs(), &M);
|
|
return false;
|
|
}
|
|
};
|
|
}
|
|
|
|
char CallGraphPrinter::ID = 0;
|
|
static RegisterPass<CallGraphPrinter>
|
|
P2("print-callgraph", "Print a call graph");
|