25#include <llvm/Config/llvm-config.h>
27#if LLVM_VERSION_MAJOR >= 16
28#include "llvm/Analysis/ScalarEvolution.h"
29#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
31#include "SCEV/ScalarEvolution.h"
32#include "SCEV/ScalarEvolutionExpander.h"
35#include "llvm/ADT/SmallVector.h"
37#include "llvm/IR/BasicBlock.h"
38#include "llvm/IR/Constants.h"
39#include "llvm/IR/DebugInfoMetadata.h"
40#include "llvm/IR/Function.h"
41#include "llvm/IR/IRBuilder.h"
42#include "llvm/IR/InstrTypes.h"
43#include "llvm/IR/Instructions.h"
44#include "llvm/IR/MDBuilder.h"
45#include "llvm/IR/Metadata.h"
47#include "llvm/Support/Debug.h"
48#include "llvm/Transforms/Scalar.h"
50#include "llvm/Analysis/BasicAliasAnalysis.h"
51#include "llvm/Analysis/GlobalsModRef.h"
52#include "llvm/Analysis/ScalarEvolution.h"
54#include "llvm/Support/CommandLine.h"
55#include "llvm/Support/ErrorHandling.h"
57#include "../EnzymeLogic.h"
67#define DEBUG_TYPE "type-analysis-results"
71llvm::cl::opt<std::string>
73 cl::desc(
"Which function to analyze/print"));
77bool printTypeAnalyses(llvm::Function &F) {
83 for (
auto &a : type_args.Function->args()) {
85 if (a.getType()->isFPOrFPVectorTy()) {
87 }
else if (a.getType()->isPointerTy()) {
88#if LLVM_VERSION_MAJOR < 17
89#if LLVM_VERSION_MAJOR >= 15
90 if (F.getContext().supportsTypedPointers()) {
92 auto et = cast<PointerType>(a.getType())->getPointerElementType();
93 if (et->isFPOrFPVectorTy()) {
95 }
else if (et->isPointerTy()) {
98#if LLVM_VERSION_MAJOR >= 15
103 }
else if (a.getType()->isIntOrIntVectorTy()) {
106 type_args.Arguments.
insert(
107 std::pair<Argument *, TypeTree>(&a, dt.
Only(-1,
nullptr)));
110 type_args.KnownValues.insert(
111 std::pair<Argument *, std::set<int64_t>>(&a, {}));
115 if (F.getReturnType()->isFPOrFPVectorTy()) {
117 }
else if (F.getReturnType()->isPointerTy()) {
118#if LLVM_VERSION_MAJOR < 17
119#if LLVM_VERSION_MAJOR >= 15
120 if (F.getContext().supportsTypedPointers()) {
122 auto et = cast<PointerType>(F.getReturnType())->getPointerElementType();
123 if (et->isFPOrFPVectorTy()) {
125 }
else if (et->isPointerTy()) {
128#if LLVM_VERSION_MAJOR >= 15
133 }
else if (F.getReturnType()->isIntOrIntVectorTy()) {
136 type_args.Return = dt.
Only(-1,
nullptr);
139 TA.analyzeFunction(type_args);
140 for (Function &f : *F.getParent()) {
142 for (
auto &analysis : TA.analyzedFunctions) {
143 if (analysis.first.Function != &f)
145 auto &ta = *analysis.second;
146 llvm::outs() << f.getName() <<
" - " << analysis.first.Return.str()
149 for (
auto &a : f.args()) {
150 llvm::outs() << analysis.first.Arguments.find(&a)->second.str() <<
":"
151 <<
to_string(analysis.first.KnownValues.find(&a)->second)
154 llvm::outs() <<
"\n";
156 for (
auto &a : f.args()) {
157 llvm::outs() << a <<
": " << ta.getAnalysis(&a).str() <<
"\n";
160 llvm::outs() << BB.getName() <<
"\n";
162 llvm::outs() << I <<
": " << ta.getAnalysis(&I).str() <<
"\n";
170class TypeAnalysisPrinter final :
public ModulePass {
175 bool runOnModule(Module &M)
override {
179 "No function specified for -type-analysis-func");
188 "' specified by -type-analysis-func not found in module");
193 return printTypeAnalyses(*TargetFunc);
196 void getAnalysisUsage(AnalysisUsage &AU)
const override {
197 AU.setPreservesAll();
203char TypeAnalysisPrinter::ID = 0;
205static RegisterPass<TypeAnalysisPrinter>
X(
"print-type-analysis",
206 "Print Type Analysis Results");
210 llvm::ModuleAnalysisManager &MAM) {
214 "No function specified for -type-analysis-func");
215 return PreservedAnalyses::all();
223 "' specified by -type-analysis-func not found in module");
224 return PreservedAnalyses::all();
228 bool changed = printTypeAnalyses(*TargetFunc);
229 return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
231llvm::AnalysisKey TypeAnalysisPrinterNewPM::Key;
constexpr const char * to_string(ActivityAnalyzer::UseActivity UA)
llvm::cl::opt< std::string > EnzymeFunctionToAnalyze("type-analysis-func", cl::init(""), cl::Hidden, cl::desc("Which function to analyze/print"))
Function ActivityAnalysis will be starting its run from.
static RegisterPass< TypeAnalysisPrinter > X("print-type-analysis", "Print Type Analysis Results")
void EmitFailure(llvm::StringRef RemarkName, const llvm::DiagnosticLocation &Loc, const llvm::Instruction *CodeRegion, Args &...args)
Concrete SubType of a given value.
llvm::PreservedAnalyses Result
Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM)
Full interprocedural TypeAnalysis.
Class representing the underlying types of values as sequences of offsets to a ConcreteType.
TypeTree Only(int Off, llvm::Instruction *orig) const
Prepend an offset to all mappings.
bool insert(const std::vector< int > Seq, ConcreteType CT, bool PointerIntSame=false)
Return if changed.
Struct containing all contextual type information for a particular function call.