Enzyme main
Loading...
Searching...
No Matches
JLInstSimplify.cpp
Go to the documentation of this file.
1//=- JLInstSimplify.h - Additional instsimplifyrules for julia programs =//
2//
3// Enzyme Project
4//
5// Part of the Enzyme Project, under the Apache License v2.0 with LLVM
6// Exceptions. See https://llvm.org/LICENSE.txt for license information.
7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8//
9// If using this code in an academic setting, please cite the following:
10// @incollection{enzymeNeurips,
11// title = {Instead of Rewriting Foreign Code for Machine Learning,
12// Automatically Synthesize Fast Gradients},
13// author = {Moses, William S. and Churavy, Valentin},
14// booktitle = {Advances in Neural Information Processing Systems 33},
15// year = {2020},
16// note = {To appear in},
17// }
18//
19//===----------------------------------------------------------------------===//
20//
21// This file contains a utility LLVM pass for printing derived Activity Analysis
22// results of a given function.
23//
24//===----------------------------------------------------------------------===//
25#include <cstdint>
26#include <llvm/Config/llvm-config.h>
27
28#include "llvm/ADT/SmallVector.h"
29
30#include "llvm/IR/BasicBlock.h"
31#include "llvm/IR/Constants.h"
32#include "llvm/IR/DebugInfoMetadata.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/IRBuilder.h"
35#include "llvm/IR/InstrTypes.h"
36#include "llvm/IR/Instructions.h"
37#include "llvm/IR/MDBuilder.h"
38#include "llvm/IR/Metadata.h"
39
40#include "llvm/IR/LegacyPassManager.h"
41
42#include "llvm/Support/Debug.h"
43
44#include "llvm/Analysis/TargetLibraryInfo.h"
45
46#include "llvm-c/Core.h"
47#include "llvm-c/DataTypes.h"
48
49#include "llvm-c/ExternC.h"
50#include "llvm-c/Types.h"
51
52#include "JLInstSimplify.h"
53#include "LibraryFuncs.h"
54#include "Utils.h"
55
56using namespace llvm;
57#ifdef DEBUG_TYPE
58#undef DEBUG_TYPE
59#endif
60#define DEBUG_TYPE "jl-inst-simplify"
61namespace {
62
63bool jlInstSimplify(llvm::Function &F, TargetLibraryInfo &TLI,
64 llvm::AAResults &AA, llvm::LoopInfo &LI,
65 DominatorTree &DT) {
66 bool changed = false;
67
68 for (auto &BB : F)
69 for (auto &I : BB) {
70 if (auto FI = dyn_cast<FreezeInst>(&I)) {
71 if (FI->hasOneUse()) {
72 bool allBranch = true;
73 for (auto user : FI->users()) {
74 if (!isAnyBranch(user)) {
75 allBranch = false;
76 break;
77 }
78 }
79 if (allBranch) {
80 FI->replaceAllUsesWith(FI->getOperand(0));
81 changed = true;
82 continue;
83 }
84 }
85 }
86 if (I.use_empty())
87 continue;
88
89 bool legal = false;
90 ICmpInst::Predicate pred;
91 if (auto cmp = dyn_cast<ICmpInst>(&I)) {
92 pred = cmp->getPredicate();
93 legal = true;
94 } else if (auto CI = dyn_cast<CallBase>(&I)) {
95 if (getFuncNameFromCall(CI) == "jl_mightalias") {
96#if LLVM_VERSION_MAJOR >= 14
97 size_t numargs = CI->arg_size();
98#else
99 size_t numargs = CI->getNumArgOperands();
100#endif
101 if (numargs == 2 && isa<PointerType>(I.getOperand(0)->getType()) &&
102 isa<PointerType>(I.getOperand(0)->getType())) {
103 legal = true;
104 pred = ICmpInst::Predicate::ICMP_EQ;
105 }
106 }
107 }
108
109 if (legal) {
110 if (auto alias = arePointersGuaranteedNoAlias(
111 TLI, AA, DT, LI, I.getOperand(0), I.getOperand(1), false)) {
112
113 bool val = *alias;
114 auto repval = ICmpInst::isTrueWhenEqual(pred)
115 ? ConstantInt::get(I.getType(), 1 - val)
116 : ConstantInt::get(I.getType(), val);
117 I.replaceAllUsesWith(repval);
118 changed = true;
119 continue;
120 }
121 }
122 }
123
124 return changed;
125}
126
127class JLInstSimplify final : public FunctionPass {
128public:
129 static char ID;
130 JLInstSimplify() : FunctionPass(ID) {}
131
132 void getAnalysisUsage(AnalysisUsage &AU) const override {
133 AU.addRequired<TargetLibraryInfoWrapperPass>();
134 AU.addRequired<AAResultsWrapperPass>();
135 AU.addRequired<LoopInfoWrapperPass>();
136 AU.addRequired<DominatorTreeWrapperPass>();
137 }
138
139 bool runOnFunction(Function &F) override {
140 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
141 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
142 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
143 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
144 return jlInstSimplify(F, TLI, AA, LI, DT);
145 }
146};
147
148} // namespace
149
150FunctionPass *createJLInstSimplifyPass() { return new JLInstSimplify(); }
151
152extern "C" void LLVMAddJLInstSimplifyPass(LLVMPassManagerRef PM) {
153 unwrap(PM)->add(createJLInstSimplifyPass());
154}
155
156char JLInstSimplify::ID = 0;
157
158static RegisterPass<JLInstSimplify> X("jl-inst-simplify",
159 "JL instruction simplification");
160
162JLInstSimplifyNewPM::run(llvm::Function &F,
163 llvm::FunctionAnalysisManager &FAM) {
164 bool changed = false;
165 changed = jlInstSimplify(
166 F, FAM.getResult<TargetLibraryAnalysis>(F), FAM.getResult<AAManager>(F),
167 FAM.getResult<LoopAnalysis>(F), FAM.getResult<DominatorTreeAnalysis>(F));
168 return changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
169}
170llvm::AnalysisKey JLInstSimplifyNewPM::Key;
FunctionPass * createJLInstSimplifyPass()
void LLVMAddJLInstSimplifyPass(LLVMPassManagerRef PM)
static RegisterPass< JLInstSimplify > X("jl-inst-simplify", "JL instruction simplification")
llvm::Optional< bool > arePointersGuaranteedNoAlias(TargetLibraryInfo &TLI, llvm::AAResults &AA, llvm::DominatorTree &DT, llvm::LoopInfo &LI, llvm::Value *op0, llvm::Value *op1, bool offsetAllowed)
Definition Utils.cpp:4968
static bool isAnyBranch(const llvm::Value *V)
Definition Utils.h:57
static llvm::StringRef getFuncNameFromCall(const llvm::CallBase *op)
Definition Utils.h:1470
Result run(llvm::Function &M, llvm::FunctionAnalysisManager &MAM)
llvm::PreservedAnalyses Result