Enzyme main
Loading...
Searching...
No Matches
TraceUtils.cpp
Go to the documentation of this file.
1//===- TraceUtils.cpp - Utilites for interacting with traces ------------===//
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 utilities for interacting with probabilistic programming
22// traces using the probabilistic programming
23// trace interface
24//
25//===----------------------------------------------------------------------===//
26
27#include "TraceUtils.h"
28
29#include "llvm/ADT/SmallPtrSet.h"
30#include "llvm/ADT/SmallVector.h"
31
32#include "llvm/IR/BasicBlock.h"
33#include "llvm/IR/IRBuilder.h"
34#include "llvm/IR/Instructions.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/User.h"
37#include "llvm/IR/Value.h"
38#include "llvm/IR/ValueMap.h"
39
40#include "llvm/Transforms/Utils/BasicBlockUtils.h"
41#include "llvm/Transforms/Utils/Cloning.h"
42
43#include "TraceInterface.h"
44
45using namespace llvm;
46
48 const SmallPtrSetImpl<Function *> &sampleFunctions,
49 const SmallPtrSetImpl<Function *> &observeFunctions,
50 Function *newFunc, Argument *trace,
51 Argument *observations, Argument *likelihood,
52 TraceInterface *interface)
53 : trace(trace), observations(observations), likelihood(likelihood),
54 interface(interface), mode(mode), newFunc(newFunc),
55 sampleFunctions(sampleFunctions.begin(), sampleFunctions.end()),
56 observeFunctions(observeFunctions.begin(), observeFunctions.end()){};
57
60 const SmallPtrSetImpl<Function *> &sampleFunctions,
61 const SmallPtrSetImpl<Function *> &observeFunctions,
62 TraceInterface *interface, Function *oldFunc,
63 ValueToValueMapTy &originalToNewFn) {
64 auto &Context = oldFunc->getContext();
65 FunctionType *orig_FTy = oldFunc->getFunctionType();
66 SmallVector<Type *, 4> params;
67
68 for (unsigned i = 0; i < orig_FTy->getNumParams(); ++i) {
69 params.push_back(orig_FTy->getParamType(i));
70 }
71
72 Type *likelihood_acc_type = getUnqual(Type::getDoubleTy(Context));
73 params.push_back(likelihood_acc_type);
74
76 Type *traceType = interface->getTraceTy()->getReturnType();
77
79 params.push_back(traceType);
80
81 params.push_back(traceType);
82 }
83
84 Type *RetTy = oldFunc->getReturnType();
85 FunctionType *FTy = FunctionType::get(RetTy, params, oldFunc->isVarArg());
86
87 const char *mode_str;
88 switch (mode) {
90 mode_str = "likelihood";
91 break;
93 mode_str = "trace";
94 break;
96 mode_str = "condition";
97 break;
98 }
99
100 Function *newFunc = Function::Create(
101 FTy, Function::LinkageTypes::InternalLinkage,
102 Twine(mode_str) + "_" + oldFunc->getName(), oldFunc->getParent());
103
104 auto DestArg = newFunc->arg_begin();
105 auto SrcArg = oldFunc->arg_begin();
106
107 for (unsigned i = 0; i < orig_FTy->getNumParams(); ++i) {
108 Argument *arg = SrcArg;
109 originalToNewFn[arg] = DestArg;
110 DestArg->setName(arg->getName());
111 DestArg++;
112 SrcArg++;
113 }
114
115 SmallVector<ReturnInst *, 4> Returns;
116 if (!oldFunc->empty()) {
117#if LLVM_VERSION_MAJOR >= 13
118 CloneFunctionInto(newFunc, oldFunc, originalToNewFn,
119 CloneFunctionChangeType::LocalChangesOnly, Returns, "",
120 nullptr);
122#else
123 CloneFunctionInto(newFunc, oldFunc, originalToNewFn, true, Returns, "",
124 nullptr);
126#endif
127 }
128 if (newFunc->empty()) {
129 auto entry = BasicBlock::Create(newFunc->getContext(), "entry", newFunc);
130 IRBuilder<> B(entry);
131 B.CreateUnreachable();
132 }
133
134 newFunc->setLinkage(Function::LinkageTypes::InternalLinkage);
135
136 Argument *trace = nullptr;
137 Argument *observations = nullptr;
138 Argument *likelihood = nullptr;
139
140 auto arg = newFunc->arg_end();
141
143 arg -= 1;
144 trace = arg;
145 arg->setName("trace");
146 arg->addAttr(Attribute::get(Context, TraceParameterAttribute));
147 }
148
150 arg -= 1;
151 observations = arg;
152 arg->setName("observations");
153 arg->addAttr(Attribute::get(Context, ObservationsParameterAttribute));
154 }
155
156 arg -= 1;
157 likelihood = arg;
158 arg->setName("likelihood");
159 arg->addAttr(Attribute::get(Context, LikelihoodParameterAttribute));
160
162 observations, likelihood, interface);
163};
164
165TraceUtils::~TraceUtils() = default;
166
168
169Value *TraceUtils::getTrace() { return trace; }
170
171Value *TraceUtils::getObservations() { return observations; }
172
173Value *TraceUtils::getLikelihood() { return likelihood; }
174
175std::pair<Value *, Constant *>
176TraceUtils::ValueToVoidPtrAndSize(IRBuilder<> &Builder, Value *val,
177 Type *size_type) {
178 auto valsize = val->getType()->getPrimitiveSizeInBits();
179
180 if (val->getType()->isPointerTy()) {
181 Value *retval =
182 Builder.CreatePointerCast(val, getInt8PtrTy(val->getContext()));
183 return {retval, ConstantInt::get(size_type, valsize / 8)};
184 }
185
186 auto M = Builder.GetInsertBlock()->getModule();
187 auto &DL = M->getDataLayout();
188 auto pointersize = DL.getPointerSizeInBits();
189
190 if (valsize <= pointersize) {
191 auto cast =
192 Builder.CreateBitCast(val, IntegerType::get(M->getContext(), valsize));
193 if (valsize != pointersize)
194 cast = Builder.CreateZExt(cast, Builder.getIntPtrTy(DL));
195
196 Value *retval =
197 Builder.CreateIntToPtr(cast, getInt8PtrTy(cast->getContext()));
198 return {retval, ConstantInt::get(size_type, valsize / 8)};
199 } else {
200 IRBuilder<> AllocaBuilder(getFirstNonPHIOrDbgOrLifetime(
201 &Builder.GetInsertBlock()->getParent()->getEntryBlock()));
202 auto alloca = AllocaBuilder.CreateAlloca(val->getType(), nullptr,
203 val->getName() + ".ptr");
204 Builder.CreateStore(val, alloca);
205 return {alloca, ConstantInt::get(size_type, valsize / 8)};
206 }
207}
208
209CallInst *TraceUtils::CreateTrace(IRBuilder<> &Builder, const Twine &Name) {
210 auto call = Builder.CreateCall(interface->newTraceTy(),
211 interface->newTrace(Builder), {}, Name);
212#if LLVM_VERSION_MAJOR >= 14
213 call->addAttributeAtIndex(
214 AttributeList::FunctionIndex,
215 Attribute::get(call->getContext(), "enzyme_newtrace"));
216#else
217 call->addAttribute(AttributeList::FunctionIndex,
218 Attribute::get(call->getContext(), "enzyme_newtrace"));
219
220#endif
221 return call;
222}
223
224CallInst *TraceUtils::FreeTrace(IRBuilder<> &Builder) {
225 auto call = Builder.CreateCall(interface->freeTraceTy(),
226 interface->freeTrace(Builder), {trace});
227#if LLVM_VERSION_MAJOR >= 14
228 call->addAttributeAtIndex(
229 AttributeList::FunctionIndex,
230 Attribute::get(call->getContext(), "enzyme_freetrace"));
231#else
232 call->addAttribute(AttributeList::FunctionIndex,
233 Attribute::get(call->getContext(), "enzyme_freetrace"));
234
235#endif
236 return call;
237}
238
239CallInst *TraceUtils::InsertChoice(IRBuilder<> &Builder, Value *address,
240 Value *score, Value *choice) {
241 Type *size_type = interface->insertChoiceTy()->getParamType(4);
242 auto &&[retval, sizeval] = ValueToVoidPtrAndSize(Builder, choice, size_type);
243
244 Value *args[] = {trace, address, score, retval, sizeval};
245
246 auto call = Builder.CreateCall(interface->insertChoiceTy(),
247 interface->insertChoice(Builder), args);
248 call->addParamAttr(1, Attribute::ReadOnly);
249
250 addCallSiteNoCapture(call, 1);
251 return call;
252}
253
254CallInst *TraceUtils::InsertCall(IRBuilder<> &Builder, Value *address,
255 Value *subtrace) {
256 Value *args[] = {trace, address, subtrace};
257
258 auto call = Builder.CreateCall(interface->insertCallTy(),
259 interface->insertCall(Builder), args);
260 call->addParamAttr(1, Attribute::ReadOnly);
261 addCallSiteNoCapture(call, 1);
262#if LLVM_VERSION_MAJOR >= 14
263 call->addAttributeAtIndex(
264 AttributeList::FunctionIndex,
265 Attribute::get(call->getContext(), "enzyme_insert_call"));
266#else
267 call->addAttribute(AttributeList::FunctionIndex,
268 Attribute::get(call->getContext(), "enzyme_insert_call"));
269
270#endif
271 return call;
272}
273
274CallInst *TraceUtils::InsertArgument(IRBuilder<> &Builder, Value *name,
275 Value *argument) {
276 Type *size_type = interface->insertArgumentTy()->getParamType(3);
277 auto &&[retval, sizeval] =
278 ValueToVoidPtrAndSize(Builder, argument, size_type);
279
280 Value *args[] = {trace, name, retval, sizeval};
281
282 auto call = Builder.CreateCall(interface->insertArgumentTy(),
283 interface->insertArgument(Builder), args);
284 call->addParamAttr(1, Attribute::ReadOnly);
285 addCallSiteNoCapture(call, 1);
286 return call;
287}
288
289CallInst *TraceUtils::InsertReturn(IRBuilder<> &Builder, Value *val) {
290 Type *size_type = interface->insertReturnTy()->getParamType(2);
291 auto &&[retval, sizeval] = ValueToVoidPtrAndSize(Builder, val, size_type);
292
293 Value *args[] = {trace, retval, sizeval};
294
295 auto call = Builder.CreateCall(interface->insertReturnTy(),
296 interface->insertReturn(Builder), args);
297 return call;
298}
299
300CallInst *TraceUtils::InsertFunction(IRBuilder<> &Builder, Function *function) {
301 assert(!function->isIntrinsic());
302 auto FunctionPtr =
303 Builder.CreateBitCast(function, getInt8PtrTy(function->getContext()));
304
305 Value *args[] = {trace, FunctionPtr};
306
307 auto call = Builder.CreateCall(interface->insertFunctionTy(),
308 interface->insertFunction(Builder), args);
309 return call;
310}
311
312CallInst *TraceUtils::InsertChoiceGradient(IRBuilder<> &Builder,
313 FunctionType *interface_type,
314 Value *interface_function,
315 Value *address, Value *choice,
316 Value *trace) {
317 Type *size_type = interface_type->getParamType(3);
318 auto &&[retval, sizeval] = ValueToVoidPtrAndSize(Builder, choice, size_type);
319
320 Value *args[] = {trace, address, retval, sizeval};
321
322 auto call = Builder.CreateCall(interface_type, interface_function, args);
323 call->addParamAttr(1, Attribute::ReadOnly);
324 addCallSiteNoCapture(call, 1);
325 return call;
326}
327
328CallInst *TraceUtils::InsertArgumentGradient(IRBuilder<> &Builder,
329 FunctionType *interface_type,
330 Value *interface_function,
331 Value *name, Value *argument,
332 Value *trace) {
333 Type *size_type = interface_type->getParamType(3);
334 auto &&[retval, sizeval] =
335 ValueToVoidPtrAndSize(Builder, argument, size_type);
336
337 Value *args[] = {trace, name, retval, sizeval};
338
339 auto call = Builder.CreateCall(interface_type, interface_function, args);
340 call->addParamAttr(1, Attribute::ReadOnly);
341 addCallSiteNoCapture(call, 1);
342 return call;
343}
344
345CallInst *TraceUtils::GetTrace(IRBuilder<> &Builder, Value *address,
346 const Twine &Name) {
347 assert(address->getType()->isPointerTy());
348
349 Value *args[] = {observations, address};
350
351 auto call = Builder.CreateCall(interface->getTraceTy(),
352 interface->getTrace(Builder), args, Name);
353 call->addParamAttr(1, Attribute::ReadOnly);
354 addCallSiteNoCapture(call, 1);
355 return call;
356}
357
358Instruction *TraceUtils::GetChoice(IRBuilder<> &Builder, Value *address,
359 Type *choiceType, const Twine &Name) {
360 IRBuilder<> AllocaBuilder(getFirstNonPHIOrDbgOrLifetime(
361 &Builder.GetInsertBlock()->getParent()->getEntryBlock()));
362 AllocaInst *store_dest =
363 AllocaBuilder.CreateAlloca(choiceType, nullptr, Name + ".ptr");
364 auto preallocated_size = choiceType->getPrimitiveSizeInBits() / 8;
365 Type *size_type = interface->getChoiceTy()->getParamType(3);
366
367 Value *args[] = {observations, address,
368 Builder.CreatePointerCast(
369 store_dest, getInt8PtrTy(store_dest->getContext())),
370 ConstantInt::get(size_type, preallocated_size)};
371
372 auto call =
373 Builder.CreateCall(interface->getChoiceTy(),
374 interface->getChoice(Builder), args, Name + ".size");
375
376#if LLVM_VERSION_MAJOR >= 14
377 call->addAttributeAtIndex(
378 AttributeList::FunctionIndex,
379 Attribute::get(call->getContext(), "enzyme_inactive"));
380#else
381 call->addAttribute(AttributeList::FunctionIndex,
382 Attribute::get(call->getContext(), "enzyme_inactive"));
383#endif
384 call->addParamAttr(1, Attribute::ReadOnly);
385 addCallSiteNoCapture(call, 1);
386 return Builder.CreateLoad(choiceType, store_dest, "from.trace." + Name);
387}
388
389Instruction *TraceUtils::HasChoice(IRBuilder<> &Builder, Value *address,
390 const Twine &Name) {
391 Value *args[]{observations, address};
392
393 auto call = Builder.CreateCall(interface->hasChoiceTy(),
394 interface->hasChoice(Builder), args, Name);
395 call->addParamAttr(1, Attribute::ReadOnly);
396 addCallSiteNoCapture(call, 1);
397 return call;
398}
399
400Instruction *TraceUtils::HasCall(IRBuilder<> &Builder, Value *address,
401 const Twine &Name) {
402 Value *args[]{observations, address};
403
404 auto call = Builder.CreateCall(interface->hasCallTy(),
405 interface->hasCall(Builder), args, Name);
406 call->addParamAttr(1, Attribute::ReadOnly);
407 addCallSiteNoCapture(call, 1);
408 return call;
409}
410
411Instruction *TraceUtils::SampleOrCondition(IRBuilder<> &Builder,
412 Function *sample_fn,
413 ArrayRef<Value *> sample_args,
414 Value *address, const Twine &Name) {
415 auto &Context = Builder.getContext();
416 auto parent_fn = Builder.GetInsertBlock()->getParent();
417
418 switch (mode) {
420 case ProbProgMode::Trace: {
421 auto sample_call = Builder.CreateCall(sample_fn->getFunctionType(),
422 sample_fn, sample_args);
423 return sample_call;
424 }
426 Instruction *hasChoice = HasChoice(Builder, address, "has.choice." + Name);
427
428 Value *ThenChoice, *ElseChoice;
429 BasicBlock *ThenBlock = BasicBlock::Create(
430 Context, "condition." + Name + ".with.trace", parent_fn);
431 BasicBlock *ElseBlock = BasicBlock::Create(
432 Context, "condition." + Name + ".without.trace", parent_fn);
433 BasicBlock *EndBlock = BasicBlock::Create(Context, "end", parent_fn);
434
435 Builder.CreateCondBr(hasChoice, ThenBlock, ElseBlock);
436 Builder.SetInsertPoint(ThenBlock);
437 ThenChoice = GetChoice(Builder, address, sample_fn->getReturnType(), Name);
438 Builder.CreateBr(EndBlock);
439
440 Builder.SetInsertPoint(ElseBlock);
441 ElseChoice = Builder.CreateCall(sample_fn->getFunctionType(), sample_fn,
442 sample_args, "sample." + Name);
443 Builder.CreateBr(EndBlock);
444
445 Builder.SetInsertPoint(EndBlock);
446 auto phi = Builder.CreatePHI(sample_fn->getReturnType(), 2);
447 phi->addIncoming(ThenChoice, ThenBlock);
448 phi->addIncoming(ElseChoice, ElseBlock);
449
450 return phi;
451 }
452 }
453 llvm_unreachable("Invalid sample_or_condition");
454}
455
457 IRBuilder<> &Builder,
458 function_ref<void(IRBuilder<> &, TraceUtils *, ArrayRef<Value *>)> Outlined,
459 Type *RetTy, ArrayRef<Value *> Arguments, bool needsLikelihood,
460 const Twine &Name) {
461 SmallVector<Type *, 4> Tys;
462 SmallVector<Value *, 4> Vals;
463 Module *M = Builder.GetInsertBlock()->getModule();
464
465 for (auto Arg : Arguments) {
466 Vals.push_back(Arg);
467 Tys.push_back(Arg->getType());
468 }
469
470 if (needsLikelihood) {
471 Vals.push_back(likelihood);
472 Tys.push_back(likelihood->getType());
473 }
474
476 Vals.push_back(observations);
477 Tys.push_back(observations->getType());
478 }
479
481 Vals.push_back(trace);
482 Tys.push_back(trace->getType());
483 }
484
485 FunctionType *FTy = FunctionType::get(RetTy, Tys, false);
486 Function *F =
487 Function::Create(FTy, Function::LinkageTypes::InternalLinkage, Name, M);
488 F->addFnAttr(Attribute::AlwaysInline);
489
490 auto Entry = BasicBlock::Create(M->getContext(), "entry", F);
491
492 auto ArgRange = make_pointer_range(
493 make_range(F->arg_begin(), F->arg_begin() + Arguments.size()));
494 SmallVector<Value *, 4> Rets(ArgRange);
495
496 auto idx = F->arg_begin() + Arguments.size();
497
498 Argument *likelihood_arg = nullptr;
499 if (needsLikelihood)
500 likelihood_arg = idx++;
501
502 Argument *observations_arg = nullptr;
504 observations_arg = idx++;
505
506 Argument *trace_arg = nullptr;
508 trace_arg = idx++;
509
510 TraceUtils OutlineTutils =
512 observations_arg, likelihood_arg, interface);
513 IRBuilder<> OutlineBuilder(Entry);
514 Outlined(OutlineBuilder, &OutlineTutils, Rets);
515
516 return Builder.CreateCall(FTy, F, Vals);
517}
518
519bool TraceUtils::isSampleCall(CallInst *call) {
520 auto F = getFunctionFromCall(call);
521 return sampleFunctions.count(F);
522}
523
524bool TraceUtils::isObserveCall(CallInst *call) {
525 auto F = getFunctionFromCall(call);
526 return observeFunctions.count(F);
527}
static Operation * getFunctionFromCall(CallOpInterface iface)
PointerType * traceType(LLVMContext &C)
static llvm::PointerType * getUnqual(llvm::Type *T)
Definition Utils.h:1329
static llvm::PointerType * getInt8PtrTy(llvm::LLVMContext &Context, unsigned AddressSpace=0)
Definition Utils.h:1324
ProbProgMode
Definition Utils.h:533
static void addCallSiteNoCapture(llvm::CallBase *call, size_t idx)
Definition Utils.h:2599
static void resetClonedGUID(llvm::Function *F)
Definition Utils.h:91
static llvm::Instruction * getFirstNonPHIOrDbgOrLifetime(llvm::BasicBlock *B)
Definition Utils.h:2591
virtual llvm::Value * insertFunction(llvm::IRBuilder<> &Builder)=0
virtual llvm::Value * insertChoice(llvm::IRBuilder<> &Builder)=0
virtual llvm::Value * newTrace(llvm::IRBuilder<> &Builder)=0
virtual llvm::Value * freeTrace(llvm::IRBuilder<> &Builder)=0
llvm::FunctionType * hasCallTy()
llvm::FunctionType * insertFunctionTy()
llvm::FunctionType * hasChoiceTy()
llvm::FunctionType * insertChoiceTy()
virtual llvm::Value * insertArgument(llvm::IRBuilder<> &Builder)=0
llvm::FunctionType * insertArgumentTy()
llvm::FunctionType * insertCallTy()
virtual llvm::Value * hasCall(llvm::IRBuilder<> &Builder)=0
virtual llvm::Value * insertReturn(llvm::IRBuilder<> &Builder)=0
llvm::FunctionType * freeTraceTy()
virtual llvm::Value * getChoice(llvm::IRBuilder<> &Builder)=0
virtual llvm::Value * hasChoice(llvm::IRBuilder<> &Builder)=0
llvm::FunctionType * insertReturnTy()
virtual llvm::Value * insertCall(llvm::IRBuilder<> &Builder)=0
llvm::FunctionType * getChoiceTy()
llvm::FunctionType * newTraceTy()
llvm::FunctionType * getTraceTy()
virtual llvm::Value * getTrace(llvm::IRBuilder<> &Builder)=0
llvm::CallInst * InsertFunction(llvm::IRBuilder<> &Builder, llvm::Function *function)
static TraceUtils * FromClone(ProbProgMode mode, const llvm::SmallPtrSetImpl< llvm::Function * > &sampleFunctions, const llvm::SmallPtrSetImpl< llvm::Function * > &observeFunctions, TraceInterface *interface, llvm::Function *oldFunc, llvm::ValueMap< const llvm::Value *, llvm::WeakTrackingVH > &originalToNewFn)
static constexpr const char TraceParameterAttribute[]
Definition TraceUtils.h:57
llvm::CallInst * CreateTrace(llvm::IRBuilder<> &Builder, const llvm::Twine &Name="trace")
llvm::Instruction * SampleOrCondition(llvm::IRBuilder<> &Builder, llvm::Function *sample_fn, llvm::ArrayRef< llvm::Value * > sample_args, llvm::Value *address, const llvm::Twine &Name="")
TraceUtils(ProbProgMode mode, const llvm::SmallPtrSetImpl< llvm::Function * > &sampleFunctions, const llvm::SmallPtrSetImpl< llvm::Function * > &observeFunctions, llvm::Function *newFunc, llvm::Argument *trace, llvm::Argument *observations, llvm::Argument *likelihood, TraceInterface *interface)
llvm::CallInst * InsertChoice(llvm::IRBuilder<> &Builder, llvm::Value *address, llvm::Value *score, llvm::Value *choice)
llvm::Instruction * GetChoice(llvm::IRBuilder<> &Builder, llvm::Value *address, llvm::Type *choiceType, const llvm::Twine &Name="")
llvm::CallInst * InsertReturn(llvm::IRBuilder<> &Builder, llvm::Value *ret)
TraceInterface * getTraceInterface()
static llvm::CallInst * InsertChoiceGradient(llvm::IRBuilder<> &Builder, llvm::FunctionType *interface_type, llvm::Value *interface_function, llvm::Value *address, llvm::Value *choice, llvm::Value *trace)
TraceInterface * interface
Definition TraceUtils.h:51
llvm::CallInst * FreeTrace(llvm::IRBuilder<> &Builder)
llvm::Instruction * HasCall(llvm::IRBuilder<> &Builder, llvm::Value *address, const llvm::Twine &Name="")
static constexpr const char ObservationsParameterAttribute[]
Definition TraceUtils.h:58
llvm::Instruction * HasChoice(llvm::IRBuilder<> &Builder, llvm::Value *address, const llvm::Twine &Name="")
llvm::SmallPtrSet< llvm::Function *, 4 > observeFunctions
Definition TraceUtils.h:55
llvm::CallInst * CreateOutlinedFunction(llvm::IRBuilder<> &Builder, llvm::function_ref< void(llvm::IRBuilder<> &, TraceUtils *, llvm::ArrayRef< llvm::Value * >)> Outlined, llvm::Type *RetTy, llvm::ArrayRef< llvm::Value * > Arguments, bool needsLikelihood=true, const llvm::Twine &Name="")
static constexpr const char LikelihoodParameterAttribute[]
Definition TraceUtils.h:60
static llvm::CallInst * InsertArgumentGradient(llvm::IRBuilder<> &Builder, llvm::FunctionType *interface_type, llvm::Value *interface_function, llvm::Value *name, llvm::Value *argument, llvm::Value *trace)
llvm::Function * newFunc
Definition TraceUtils.h:53
llvm::SmallPtrSet< llvm::Function *, 4 > sampleFunctions
Definition TraceUtils.h:54
llvm::Value * getLikelihood()
bool isObserveCall(llvm::CallInst *call)
ProbProgMode mode
Definition TraceUtils.h:52
llvm::CallInst * InsertArgument(llvm::IRBuilder<> &Builder, llvm::Value *name, llvm::Value *argument)
llvm::CallInst * GetTrace(llvm::IRBuilder<> &Builder, llvm::Value *address, const llvm::Twine &Name="")
bool isSampleCall(llvm::CallInst *call)
llvm::Value * getObservations()
llvm::CallInst * InsertCall(llvm::IRBuilder<> &Builder, llvm::Value *address, llvm::Value *subtrace)
llvm::Value * getTrace()