25#include <llvm/Config/llvm-config.h>
27#include "llvm/Analysis/ScalarEvolution.h"
28#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"
30#include "llvm/ADT/SmallVector.h"
32#include "llvm/IR/BasicBlock.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DebugInfoMetadata.h"
35#include "llvm/IR/Function.h"
36#include "llvm/IR/IRBuilder.h"
37#include "llvm/IR/InstrTypes.h"
38#include "llvm/IR/Instructions.h"
39#include "llvm/IR/MDBuilder.h"
40#include "llvm/IR/Metadata.h"
42#include "llvm/Support/Debug.h"
43#include "llvm/Transforms/Scalar.h"
45#include "llvm/Analysis/BasicAliasAnalysis.h"
46#include "llvm/Analysis/GlobalsModRef.h"
47#include "llvm/Analysis/ScalarEvolution.h"
49#include "llvm/Support/CommandLine.h"
50#include "llvm/Support/ErrorHandling.h"
52#include "ActivityAnalysis.h"
54#include "EnzymeLogic.h"
63#define DEBUG_TYPE "activity-analysis-results"
66static llvm::cl::opt<std::string>
68 cl::desc(
"Which function to analyze/print"));
70static llvm::cl::opt<bool>
71 InactiveArgs(
"activity-analysis-inactive-args", cl::init(
false), cl::Hidden,
72 cl::desc(
"Whether all args are inactive"));
74static llvm::cl::opt<bool>
76 cl::Hidden, cl::desc(
"Whether the return is duplicated"));
79bool printActivityAnalysis(llvm::Function &F, TargetLibraryInfo &TLI) {
84 for (
auto &a : type_args.Function->args()) {
86 if (a.getType()->isFPOrFPVectorTy()) {
88 }
else if (a.getType()->isPointerTy()) {
89#if LLVM_VERSION_MAJOR < 17
90 if (a.getContext().supportsTypedPointers()) {
91 auto et = a.getType()->getPointerElementType();
92 if (et->isFPOrFPVectorTy()) {
94 }
else if (et->isPointerTy()) {
99 }
else if (a.getType()->isIntOrIntVectorTy()) {
102 type_args.Arguments.
insert(
103 std::pair<Argument *, TypeTree>(&a, dt.
Only(-1,
nullptr)));
106 type_args.KnownValues.insert(
107 std::pair<Argument *, std::set<int64_t>>(&a, {}));
111 if (F.getReturnType()->isFPOrFPVectorTy()) {
113 }
else if (F.getReturnType()->isPointerTy()) {
114#if LLVM_VERSION_MAJOR < 17
115 if (F.getContext().supportsTypedPointers()) {
116 auto et = F.getReturnType()->getPointerElementType();
117 if (et->isFPOrFPVectorTy()) {
119 }
else if (et->isPointerTy()) {
124 }
else if (F.getReturnType()->isIntOrIntVectorTy()) {
127 type_args.Return = dt.
Only(-1,
nullptr);
133 llvm::SmallPtrSet<llvm::Value *, 4> ConstantValues;
134 llvm::SmallPtrSet<llvm::Value *, 4> ActiveValues;
135 for (
auto &a : type_args.Function->args()) {
137 ConstantValues.insert(&a);
138 }
else if (a.getType()->isIntOrIntVectorTy()) {
139 ConstantValues.insert(&a);
141 ActiveValues.insert(&a);
145 DIFFE_TYPE ActiveReturns = F.getReturnType()->isFPOrFPVectorTy()
152 notForAnalysis, TLI, ConstantValues, ActiveValues,
155 for (
auto &a : F.args()) {
156 ATA.isConstantValue(TR, &a);
157 llvm::errs().flush();
161 ATA.isConstantInstruction(TR, &I);
162 ATA.isConstantValue(TR, &I);
163 llvm::errs().flush();
167 for (
auto &a : F.args()) {
168 bool icv = ATA.isConstantValue(TR, &a);
169 llvm::errs().flush();
170 llvm::outs() << a <<
": icv:" << icv <<
"\n";
171 llvm::outs().flush();
174 llvm::outs() << BB.getName() <<
"\n";
176 bool ici = ATA.isConstantInstruction(TR, &I);
177 bool icv = ATA.isConstantValue(TR, &I);
178 llvm::errs().flush();
179 llvm::outs() << I <<
": icv:" << icv <<
" ici:" << ici <<
"\n";
180 llvm::outs().flush();
186class ActivityAnalysisPrinter final :
public ModulePass {
191 bool runOnModule(Module &M)
override {
195 "No function specified for -activity-analysis-func");
204 "' specified by -activity-analysis-func not found in module");
209 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(*TargetFunc);
210 return printActivityAnalysis(*TargetFunc, TLI);
213 void getAnalysisUsage(AnalysisUsage &AU)
const override {
214 AU.addRequired<TargetLibraryInfoWrapperPass>();
215 AU.setPreservesAll();
221char ActivityAnalysisPrinter::ID = 0;
223static RegisterPass<ActivityAnalysisPrinter>
224 X(
"print-activity-analysis",
"Print Activity Analysis Results");
228 llvm::ModuleAnalysisManager &MAM) {
232 "No function specified for -activity-analysis-func");
233 return PreservedAnalyses::all();
241 "' specified by -activity-analysis-func not found in module");
242 return PreservedAnalyses::all();
246 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
247 bool changed = printActivityAnalysis(
248 *TargetFunc, FAM.getResult<TargetLibraryAnalysis>(*TargetFunc));
249 return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
251llvm::AnalysisKey ActivityAnalysisPrinterNewPM::Key;
static llvm::cl::opt< bool > DuplicatedRet("activity-analysis-duplicated-ret", cl::init(false), cl::Hidden, cl::desc("Whether the return is duplicated"))
static RegisterPass< ActivityAnalysisPrinter > X("print-activity-analysis", "Print Activity Analysis Results")
static llvm::cl::opt< std::string > FunctionToAnalyze("activity-analysis-func", cl::init(""), cl::Hidden, cl::desc("Which function to analyze/print"))
Function TypeAnalysis will be starting its run from.
static llvm::cl::opt< bool > InactiveArgs("activity-analysis-inactive-args", cl::init(false), cl::Hidden, cl::desc("Whether all args are inactive"))
static llvm::SmallPtrSet< llvm::BasicBlock *, 4 > getGuaranteedUnreachable(llvm::Function *F)
DIFFE_TYPE
Potential differentiable argument classifications.
void EmitFailure(llvm::StringRef RemarkName, const llvm::DiagnosticLocation &Loc, const llvm::Instruction *CodeRegion, Args &...args)
llvm::PreservedAnalyses Result
Result run(llvm::Module &M, llvm::ModuleAnalysisManager &MAM)
Helper class to analyze the differential activity.
Concrete SubType of a given value.
Full interprocedural TypeAnalysis.
A holder class representing the results of running TypeAnalysis on a given function.
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.