LLVM 23.0.0git
Instruction.cpp
Go to the documentation of this file.
1//===- Instruction.cpp - The Instructions of Sandbox IR -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11
12namespace llvm::sandboxir {
13
15 Instruction *Prev = getPrevNode();
16 if (Prev == nullptr) {
17 // If at top of the BB, return the first BB instruction.
18 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
19 }
20 // Else get the Previous sandbox IR instruction's bottom IR instruction and
21 // return its successor.
23 return PrevBotI->getNextNode();
24}
25
26BBIterator Instruction::getIterator() const {
28 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
29}
30
32 assert(getParent() != nullptr && "Detached!");
33 assert(getIterator() != getParent()->end() && "Already at end!");
34 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
35 // and get the corresponding sandboxir Instruction that maps to it. This works
36 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
37 auto *LLVMI = cast<llvm::Instruction>(Val);
38 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
39 auto *NextLLVMI = LLVMI->getNextNode();
40 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
41 if (NextI == nullptr)
42 return nullptr;
43 return NextI;
44}
45
47 assert(getParent() != nullptr && "Detached!");
48 auto It = getIterator();
49 if (It != getParent()->begin())
50 return std::prev(getIterator()).get();
51 return nullptr;
52}
53
55 Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
56
57 // Detach all the LLVM IR instructions from their parent BB.
59 I->removeFromParent();
60}
61
63 assert(users().empty() && "Still connected to users, can't erase!");
64
65 Ctx.runEraseInstrCallbacks(this);
66 std::unique_ptr<Value> Detached = Ctx.detach(this);
67 auto LLVMInstrs = getLLVMInstrs();
68
69 auto &Tracker = Ctx.getTracker();
70 if (Tracker.isTracking()) {
71 Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
72 // We don't actually delete the IR instruction, because then it would be
73 // impossible to bring it back from the dead at the same memory location.
74 // Instead we remove it from its BB and track its current location.
75 for (llvm::Instruction *I : LLVMInstrs)
76 I->removeFromParent();
77 // TODO: Multi-instructions need special treatment because some of the
78 // references are internal to the instruction.
79 for (llvm::Instruction *I : LLVMInstrs)
80 I->dropAllReferences();
81 } else {
82 // Erase in reverse to avoid erasing nstructions with attached uses.
83 for (llvm::Instruction *I : reverse(LLVMInstrs))
84 I->eraseFromParent();
85 }
87
88void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
89 if (std::next(getIterator()) == WhereIt)
90 // Destination is same as origin, nothing to do.
91 return;
92
93 Ctx.runMoveInstrCallbacks(this, WhereIt);
94 Ctx.getTracker().emplaceIfTracking<MoveInstr>(this);
95
96 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
98 if (WhereIt == BB.end()) {
99 It = LLVMBB->end();
100 } else {
101 Instruction *WhereI = &*WhereIt;
102 It = WhereI->getTopmostLLVMInstruction()->getIterator();
103 }
104 // TODO: Move this to the verifier of sandboxir::Instruction.
106 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
107 "Expected program order!");
108 // Do the actual move in LLVM IR.
109 for (auto *I : getLLVMInstrs())
110 I->moveBefore(*LLVMBB, It);
111}
114 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
115
116 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
117
118 // Insert the LLVM IR Instructions in program order.
120 I->insertBefore(BeforeTopI->getIterator());
121}
122
124 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
125}
126
127void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
128 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
129 llvm::Instruction *LLVMBeforeI;
130 llvm::BasicBlock::iterator LLVMBeforeIt;
131 Instruction *BeforeI;
132 if (WhereIt != BB->end()) {
133 BeforeI = &*WhereIt;
134 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
135 LLVMBeforeIt = LLVMBeforeI->getIterator();
136 } else {
137 BeforeI = nullptr;
138 LLVMBeforeI = nullptr;
139 LLVMBeforeIt = LLVMBB->end();
140 }
142 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
143
144 // Insert the LLVM IR Instructions in program order.
146 I->insertInto(LLVMBB, LLVMBeforeIt);
147}
148
150 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
151 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
153 if (BB == nullptr)
154 return nullptr;
155 return cast<BasicBlock>(Ctx.getValue(BB));
156}
157
159 switch (From->getSubclassID()) {
160#define DEF_INSTR(ID, OPC, CLASS) \
161 case ClassID::ID: \
162 return true;
163#define DEF_DISABLE_AUTO_UNDEF // ValuesDefFilesList.def includes multiple .def
164#include "llvm/SandboxIR/ValuesDefFilesList.def"
165 default:
166 return false;
167 }
168}
169
171 Ctx.getTracker()
174 this);
175 cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
176}
177
179 Ctx.getTracker()
182 cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
183}
184
186 Ctx.getTracker()
187 .emplaceIfTracking<
189 cast<llvm::Instruction>(Val)->setFast(B);
190}
191
193 Ctx.getTracker()
194 .emplaceIfTracking<
195 GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this);
196 cast<llvm::Instruction>(Val)->setIsExact(B);
197}
198
200 Ctx.getTracker()
201 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc,
203 cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
205
207 Ctx.getTracker()
208 .emplaceIfTracking<
210 this);
211 cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
213
215 Ctx.getTracker()
216 .emplaceIfTracking<
218 this);
220}
221
223 Ctx.getTracker()
226 this);
227 cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
228}
229
231 Ctx.getTracker()
232 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReciprocal,
234 this);
235 cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
236}
237
239 Ctx.getTracker()
242 this);
243 cast<llvm::Instruction>(Val)->setHasAllowContract(B);
244}
245
247 Ctx.getTracker()
250 cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
251}
252
254 Ctx.getTracker()
257 cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
258}
259
263
265 Ctx.getTracker()
266 .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
268 cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
270
271#ifndef NDEBUG
273 OS << "Unimplemented! Please override dump().";
274}
275#endif // NDEBUG
276
278 Context &Ctx, const Twine &Name) {
279 auto &Builder = setInsertPos(Pos);
280 auto *LLVMI =
281 cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name));
282 return Ctx.createVAArgInst(LLVMI);
284
288
289FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx,
290 const Twine &Name) {
291 auto &Builder = setInsertPos(Pos);
292 auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name));
293 return Ctx.createFreezeInst(LLVMI);
294}
295
297 Context &Ctx, SyncScope::ID SSID) {
298 auto &Builder = Instruction::setInsertPos(Pos);
299 llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
300 return Ctx.createFenceInst(LLVMI);
301}
302
304 Ctx.getTracker()
305 .emplaceIfTracking<
307 this);
308 cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
309}
310
312 Ctx.getTracker()
313 .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
315 cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
316}
317
319 InsertPosition Pos, Context &Ctx, const Twine &Name) {
320 auto &Builder = Instruction::setInsertPos(Pos);
321 llvm::Value *NewV =
322 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
323 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
324 return Ctx.createSelectInst(NewSI);
325 assert(isa<llvm::Constant>(NewV) && "Expected constant");
326 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
327}
328
330 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
331 getOperandUse(2));
332 cast<llvm::SelectInst>(Val)->swapValues();
333}
334
335bool SelectInst::classof(const Value *From) {
336 return From->getSubclassID() == ClassID::Select;
337}
338
339BasicBlock *BrInstCommon::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
340 return cast<BasicBlock>(Ctx.getValue(BB));
342const BasicBlock *
343BrInstCommon::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
344 return cast<BasicBlock>(Ctx.getValue(BB));
345}
348 InsertPosition InsertBefore, Context &Ctx) {
349 auto &Builder = setInsertPos(InsertBefore);
351 Builder.CreateBr(cast<llvm::BasicBlock>(Target->Val));
352 return Ctx.createUncondBrInst(NewUBr);
353}
354
357 Ctx.getValue(cast<llvm::UncondBrInst>(Val)->getSuccessor()));
358}
359
361 Ctx.getTracker()
362 .emplaceIfTracking<GenericSetter<&UncondBrInst::getSuccessor,
364 cast<llvm::UncondBrInst>(Val)->setSuccessor(
365 0, cast<llvm::BasicBlock>(NewSucc->Val));
366}
367
368bool UncondBrInst::classof(const Value *From) {
369 return From->getSubclassID() == ClassID::UncondBr;
370}
371
373 BasicBlock *IfFalse, InsertPosition InsertBefore,
374 Context &Ctx) {
375 auto &Builder = setInsertPos(InsertBefore);
376 llvm::CondBrInst *NewCBr = Builder.CreateCondBr(
378 cast<llvm::BasicBlock>(IfFalse->Val));
379 return Ctx.createCondBrInst(NewCBr);
380}
381
384 "Cannot get condition of an uncond branch!");
385 return Ctx.getValue(cast<llvm::CondBrInst>(Val)->getCondition());
386}
388 Ctx.getTracker()
389 .emplaceIfTracking<
391 this);
392 llvm::Value *LLVMV = V->Val;
393 cast<llvm::CondBrInst>(Val)->setCondition(LLVMV);
394}
396BasicBlock *CondBrInst::getSuccessor(unsigned SuccIdx) const {
397 assert(SuccIdx < getNumSuccessors() &&
398 "Successor # out of range for Branch!");
400 Ctx.getValue(cast<llvm::CondBrInst>(Val)->getSuccessor(SuccIdx)));
401}
403void CondBrInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
404 assert(Idx < getNumSuccessors() && "Out of bounds!");
405 Ctx.getTracker()
408 Idx);
409 cast<llvm::CondBrInst>(Val)->setSuccessor(
410 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
411}
412
413bool CondBrInst::classof(const Value *From) {
414 return From->getSubclassID() == ClassID::CondBr;
415}
416
418 Ctx.getTracker()
419 .emplaceIfTracking<
420 GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this);
421 cast<llvm::LoadInst>(Val)->setVolatile(V);
422}
423
425 InsertPosition Pos, bool IsVolatile, Context &Ctx,
426 const Twine &Name) {
427 auto &Builder = setInsertPos(Pos);
428 auto *NewLI =
429 Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
430 auto *NewSBI = Ctx.createLoadInst(NewLI);
431 return NewSBI;
432}
434bool LoadInst::classof(const Value *From) {
435 return From->getSubclassID() == ClassID::Load;
436}
437
441
443 Ctx.getTracker()
444 .emplaceIfTracking<
445 GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(this);
446 cast<llvm::StoreInst>(Val)->setVolatile(V);
447}
448
450 InsertPosition Pos, bool IsVolatile,
451 Context &Ctx) {
452 auto &Builder = setInsertPos(Pos);
453 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
454 auto *NewSBI = Ctx.createStoreInst(NewSI);
455 return NewSBI;
456}
457
458bool StoreInst::classof(const Value *From) {
459 return From->getSubclassID() == ClassID::Store;
460}
461
465
469
470UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
471 auto &Builder = setInsertPos(Pos);
472 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
473 return Ctx.createUnreachableInst(NewUI);
474}
475
477 return From->getSubclassID() == ClassID::Unreachable;
478}
479
480ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
481 Context &Ctx) {
482 llvm::ReturnInst *NewRI;
483 if (RetVal != nullptr)
484 NewRI = Builder.CreateRet(RetVal->Val);
485 else
486 NewRI = Builder.CreateRetVoid();
487 return Ctx.createReturnInst(NewRI);
488}
489
490ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
491 Context &Ctx) {
492 auto &Builder = setInsertPos(Pos);
493 return createCommon(RetVal, Builder, Ctx);
494}
495
497 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
498 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
499}
500
502 return cast<FunctionType>(
503 Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
504}
505
507 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
509
511 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
512 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
513}
514
517 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
518}
520 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
521}
522
524 // F's function type is private, so we rely on `setCalledFunction()` to update
525 // it. But even though we are calling `setCalledFunction()` we also need to
526 // track this change at the SandboxIR level, which is why we call
527 // `setCalledOperand()` here.
528 // Note: This may break if `setCalledFunction()` early returns if `F`
529 // is already set, but we do have a unit test for it.
531 cast<llvm::CallBase>(Val)->setCalledFunction(
532 cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
533 cast<llvm::Function>(F->Val));
534}
535
536CallInst *CallInst::create(FunctionType *FTy, Value *Func,
538 Context &Ctx, const Twine &NameStr) {
539 auto &Builder = setInsertPos(Pos);
541 LLVMArgs.reserve(Args.size());
542 for (Value *Arg : Args)
543 LLVMArgs.push_back(Arg->Val);
544 llvm::CallInst *NewCI = Builder.CreateCall(
545 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
546 return Ctx.createCallInst(NewCI);
547}
548
549InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
550 BasicBlock *IfNormal, BasicBlock *IfException,
552 Context &Ctx, const Twine &NameStr) {
553 auto &Builder = setInsertPos(Pos);
555 LLVMArgs.reserve(Args.size());
556 for (Value *Arg : Args)
557 LLVMArgs.push_back(Arg->Val);
558 llvm::InvokeInst *Invoke = Builder.CreateInvoke(
559 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
560 cast<llvm::BasicBlock>(IfNormal->Val),
561 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
562 return Ctx.createInvokeInst(Invoke);
563}
564
566 return cast<BasicBlock>(
567 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
568}
570 return cast<BasicBlock>(
571 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
572}
574 setOperand(1, BB);
575 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
576}
578 setOperand(2, BB);
579 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
580}
583 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
584 ;
585}
586BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
587 return cast<BasicBlock>(
588 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
589}
590
591CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
592 BasicBlock *DefaultDest,
593 ArrayRef<BasicBlock *> IndirectDests,
595 Context &Ctx, const Twine &NameStr) {
596 auto &Builder = setInsertPos(Pos);
597 SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
598 LLVMIndirectDests.reserve(IndirectDests.size());
599 for (BasicBlock *IndDest : IndirectDests)
600 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
601
603 LLVMArgs.reserve(Args.size());
604 for (Value *Arg : Args)
605 LLVMArgs.push_back(Arg->Val);
606
607 llvm::CallBrInst *CallBr =
608 Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
609 cast<llvm::BasicBlock>(DefaultDest->Val),
610 LLVMIndirectDests, LLVMArgs, NameStr);
611 return Ctx.createCallBrInst(CallBr);
612}
613
615 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
616}
618 return Ctx.getValue(
619 cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
620}
623 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
624}
626 return cast<BasicBlock>(
627 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
628}
631 for (llvm::BasicBlock *LLVMBB :
632 cast<llvm::CallBrInst>(Val)->getIndirectDests())
633 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
634 return BBs;
635}
637 Ctx.getTracker()
638 .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
640 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
641}
643 Ctx.getTracker()
644 .emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest,
646 this, Idx);
647 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
648 cast<llvm::BasicBlock>(BB->Val));
649}
651 return cast<BasicBlock>(
652 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
653}
654
655LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
657 const Twine &Name) {
658 auto &Builder = setInsertPos(Pos);
659 llvm::LandingPadInst *LLVMI =
660 Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
661 return Ctx.createLandingPadInst(LLVMI);
663
665 Ctx.getTracker()
666 .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
668 cast<llvm::LandingPadInst>(Val)->setCleanup(V);
669}
670
673 Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
674}
675
677 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());
678}
679
681 Ctx.getTracker()
682 .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
684 cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
685}
686
688 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
689}
690
691void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
692 Ctx.getTracker()
693 .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
695 this, Idx);
696 cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
698
703
704CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
706 const Twine &Name) {
707 auto &Builder = setInsertPos(Pos);
709 LLVMArgs.reserve(Args.size());
710 for (auto *Arg : Args)
711 LLVMArgs.push_back(Arg->Val);
713 Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
714 return Ctx.createCatchPadInst(LLVMI);
715}
716
718 InsertPosition Pos, Context &Ctx,
719 const Twine &Name) {
720 auto &Builder = setInsertPos(Pos);
722 LLVMArgs.reserve(Args.size());
723 for (auto *Arg : Args)
724 LLVMArgs.push_back(Arg->Val);
725 llvm::CleanupPadInst *LLVMI =
726 Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
727 return Ctx.createCleanupPadInst(LLVMI);
728}
729
730CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
731 InsertPosition Pos, Context &Ctx) {
732 auto &Builder = setInsertPos(Pos);
733 llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
735 return Ctx.createCatchReturnInst(LLVMI);
736}
737
739 return cast<CatchPadInst>(
740 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
741}
742
744 Ctx.getTracker()
747 cast<llvm::CatchReturnInst>(Val)->setCatchPad(
748 cast<llvm::CatchPadInst>(CatchPad->Val));
749}
750
752 return cast<BasicBlock>(
753 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
754}
755
757 Ctx.getTracker()
760 cast<llvm::CatchReturnInst>(Val)->setSuccessor(
761 cast<llvm::BasicBlock>(NewSucc->Val));
762}
763
765 return Ctx.getValue(
766 cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
767}
768
769CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
770 BasicBlock *UnwindBB,
771 InsertPosition Pos, Context &Ctx) {
772 auto &Builder = setInsertPos(Pos);
773 auto *LLVMUnwindBB =
774 UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
775 llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
776 cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
777 return Ctx.createCleanupReturnInst(LLVMI);
778}
779
784
786 Ctx.getTracker()
789 this);
790 cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
791 cast<llvm::CleanupPadInst>(CleanupPad->Val));
792}
793
798
800 Ctx.getTracker()
803 this);
804 cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
805 cast<llvm::BasicBlock>(NewDest->Val));
806}
807
810 Context &Ctx, const Twine &NameStr) {
811 auto &Builder = setInsertPos(Pos);
812 SmallVector<llvm::Value *> LLVMIdxList;
813 LLVMIdxList.reserve(IdxList.size());
814 for (Value *Idx : IdxList)
815 LLVMIdxList.push_back(Idx->Val);
816 llvm::Value *NewV =
817 Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
818 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
819 return Ctx.createGetElementPtrInst(NewGEP);
820 assert(isa<llvm::Constant>(NewV) && "Expected constant");
821 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
822}
823
828
833
837
842
843BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
844 return cast<BasicBlock>(Ctx.getValue(LLVMBB));
845}
846
847PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
848 InsertPosition Pos, Context &Ctx, const Twine &Name) {
849 auto &Builder = setInsertPos(Pos);
850 llvm::PHINode *NewPHI =
851 Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
852 return Ctx.createPHINode(NewPHI);
853}
854
855bool PHINode::classof(const Value *From) {
856 return From->getSubclassID() == ClassID::PHI;
857}
858
859Value *PHINode::getIncomingValue(unsigned Idx) const {
860 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
861}
862void PHINode::setIncomingValue(unsigned Idx, Value *V) {
863 Ctx.getTracker()
866 Idx);
867 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
868}
870 return cast<BasicBlock>(
871 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
872}
874 llvm::Use *LLVMUse = U.LLVMUse;
875 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
876 return cast<BasicBlock>(Ctx.getValue(BB));
877}
878void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
879 // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
880 constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
882 Ctx.getTracker()
883 .emplaceIfTracking<
885 this, Idx);
886 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
887 cast<llvm::BasicBlock>(BB->Val));
888}
890 auto &Tracker = Ctx.getTracker();
892
893 cast<llvm::PHINode>(Val)->addIncoming(V->Val,
894 cast<llvm::BasicBlock>(BB->Val));
895}
897 auto &Tracker = Ctx.getTracker();
899 llvm::Value *LLVMV =
900 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
901 /*DeletePHIIfEmpty=*/false);
902 return Ctx.getValue(LLVMV);
903}
905 auto &Tracker = Ctx.getTracker();
907
908 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
909 llvm::Value *LLVMV =
910 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
911 /*DeletePHIIfEmpty=*/false);
912 return Ctx.getValue(LLVMV);
913}
915 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
916 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
917}
919 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
920 llvm::Value *LLVMV =
921 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
922 return Ctx.getValue(LLVMV);
923}
925 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
926 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
927}
929 assert(New && Old && "Sandbox IR PHI node got a null basic block!");
930 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
931 Idx != NumOps; ++Idx)
932 if (getIncomingBlock(Idx) == Old)
933 setIncomingBlock(Idx, New);
934}
935void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
936 // Avoid duplicate tracking by going through this->removeIncomingValue here at
937 // the expense of some performance. Copy PHI::removeIncomingValueIf more
938 // directly if performance becomes an issue.
939
940 // Removing the element at index X, moves the element previously at X + 1
941 // to X. Working from the end avoids complications from that.
942 unsigned Idx = getNumIncomingValues();
943 while (Idx > 0) {
944 if (Predicate(Idx - 1))
945 removeIncomingValue(Idx - 1);
946 --Idx;
947 }
948}
949
951 Context &Ctx, const Twine &Name) {
952 auto &Builder = setInsertPos(Pos);
953 auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
954 // It may have been folded into a constant.
955 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
956 return Ctx.getOrCreateConstant(LLVMC);
957 if (isa<llvm::ICmpInst>(LLVMV))
958 return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
959 return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
960}
961
963 const Instruction *F, InsertPosition Pos,
964 Context &Ctx, const Twine &Name) {
965 Value *V = create(P, S1, S2, Pos, Ctx, Name);
966 if (auto *C = dyn_cast<Constant>(V))
967 return C;
968 cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
969 return V;
970}
971
973 if (auto *VT = dyn_cast<VectorType>(OpndType)) {
974 // TODO: Cleanup when we have more complete support for
975 // sandboxir::VectorType
976 return OpndType->getContext().getType(llvm::VectorType::get(
978 cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
979 }
980 return Type::getInt1Ty(OpndType->getContext());
981}
982
984 Ctx.getTracker()
985 .emplaceIfTracking<
987 cast<llvm::CmpInst>(Val)->setPredicate(P);
989
991 if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
992 IC->swapOperands();
993 else
994 cast<FCmpInst>(this)->swapOperands();
995}
996
998 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
999 cast<llvm::ICmpInst>(Val)->swapOperands();
1000}
1001
1003 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
1004 cast<llvm::FCmpInst>(Val)->swapOperands();
1005}
1006
1007#ifndef NDEBUG
1009 dumpCommonPrefix(OS);
1010 dumpCommonSuffix(OS);
1011}
1012
1013void CmpInst::dump() const {
1014 dumpOS(dbgs());
1015 dbgs() << "\n";
1016}
1017#endif // NDEBUG
1018
1020 switch (Opc) {
1021 case Instruction::Opcode::ZExt:
1022 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1023 case Instruction::Opcode::SExt:
1024 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1025 case Instruction::Opcode::FPToUI:
1026 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1027 case Instruction::Opcode::FPToSI:
1028 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1029 case Instruction::Opcode::FPExt:
1030 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1031 case Instruction::Opcode::PtrToAddr:
1032 return static_cast<llvm::Instruction::CastOps>(
1033 llvm::Instruction::PtrToAddr);
1034 case Instruction::Opcode::PtrToInt:
1035 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1036 case Instruction::Opcode::IntToPtr:
1037 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1038 case Instruction::Opcode::SIToFP:
1039 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1040 case Instruction::Opcode::UIToFP:
1041 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1042 case Instruction::Opcode::Trunc:
1043 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1044 case Instruction::Opcode::FPTrunc:
1045 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1046 case Instruction::Opcode::BitCast:
1047 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1048 case Instruction::Opcode::AddrSpaceCast:
1049 return static_cast<llvm::Instruction::CastOps>(
1050 llvm::Instruction::AddrSpaceCast);
1051 default:
1052 llvm_unreachable("Opcode not suitable for CastInst!");
1053 }
1054}
1055
1056/// \Returns the LLVM opcode that corresponds to \p Opc.
1058 switch (Opc) {
1059 case Instruction::Opcode::FNeg:
1060 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1061 default:
1062 llvm_unreachable("Not a unary op!");
1063 }
1065
1066CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
1067 unsigned NumHandlers,
1069 const Twine &Name) {
1070 auto &Builder = setInsertPos(Pos);
1071 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1072 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1073 return Ctx.createCatchSwitchInst(LLVMCSI);
1074}
1075
1079
1081 Ctx.getTracker()
1082 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
1084 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1085}
1086
1089 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1090}
1091
1093 Ctx.getTracker()
1096 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1097 cast<llvm::BasicBlock>(UnwindDest->Val));
1098}
1099
1101 Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
1102 cast<llvm::CatchSwitchInst>(Val)->addHandler(
1103 cast<llvm::BasicBlock>(Dest->Val));
1105
1107 auto &Builder = setInsertPos(Pos);
1108 auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1109 return Ctx.createResumeInst(LLVMI);
1110}
1111
1113 return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1114}
1115
1116SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1118 const Twine &Name) {
1119 auto &Builder = setInsertPos(Pos);
1121 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1122 return Ctx.createSwitchInst(LLVMSwitch);
1123}
1124
1126 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1127}
1128
1130 Ctx.getTracker()
1131 .emplaceIfTracking<
1132 GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(
1133 this);
1134 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1135}
1136
1138 return cast<BasicBlock>(
1139 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1140}
1141
1143 Ctx.getTracker()
1144 .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
1146 cast<llvm::SwitchInst>(Val)->setDefaultDest(
1147 cast<llvm::BasicBlock>(DefaultCase->Val));
1148}
1149
1150template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1151ConstT *
1153 const auto &LLVMCaseHandle = *LLVMCaseIt;
1154 auto *LLVMC = Ctx.getValue(LLVMCaseHandle.getCaseValue());
1155 return cast<ConstT>(LLVMC);
1156}
1157
1158template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1159BlockT *
1161 const {
1162 const auto &LLVMCaseHandle = *LLVMCaseIt;
1163 auto *LLVMBB = LLVMCaseHandle.getCaseSuccessor();
1164 return cast<BlockT>(Ctx.getValue(LLVMBB));
1165}
1166
1168 ConstantInt>;
1170 ConstantInt>;
1172 const BasicBlock, const ConstantInt>;
1173template class SwitchInst::CaseItImpl<llvm::SwitchInst::ConstCaseIt,
1174 const BasicBlock, const ConstantInt>;
1175
1177 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1178 cast<llvm::BasicBlock>(BB->Val));
1179 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1180}
1181
1183 Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
1184 // TODO: Track this!
1186 cast<llvm::BasicBlock>(Dest->Val));
1187}
1188
1190 Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
1191
1193 unsigned CaseNum = It - case_begin();
1194 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1195 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1196 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1197 return CaseIt(this, Num);
1198}
1199
1201 return cast<BasicBlock>(
1202 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1203}
1204
1205void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1206 Ctx.getTracker()
1209 Idx);
1210 cast<llvm::SwitchInst>(Val)->setSuccessor(
1211 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1212}
1213
1215 InsertPosition Pos, Context &Ctx,
1216 const Twine &Name) {
1217 auto &Builder = setInsertPos(Pos);
1218 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1219 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1220 return Ctx.createUnaryOperator(NewUnOpV);
1221 }
1222 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1223 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1224}
1225
1227 Value *CopyFrom, InsertPosition Pos,
1228 Context &Ctx, const Twine &Name) {
1229 auto *NewV = create(Op, OpV, Pos, Ctx, Name);
1230 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1231 UnI->copyIRFlags(CopyFrom->Val);
1232 return NewV;
1233}
1234
1235/// \Returns the LLVM opcode that corresponds to \p Opc.
1237 switch (Opc) {
1238 case Instruction::Opcode::Add:
1239 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1240 case Instruction::Opcode::FAdd:
1241 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1242 case Instruction::Opcode::Sub:
1243 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1244 case Instruction::Opcode::FSub:
1245 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1246 case Instruction::Opcode::Mul:
1247 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1248 case Instruction::Opcode::FMul:
1249 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1250 case Instruction::Opcode::UDiv:
1251 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1252 case Instruction::Opcode::SDiv:
1253 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1254 case Instruction::Opcode::FDiv:
1255 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1256 case Instruction::Opcode::URem:
1257 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1258 case Instruction::Opcode::SRem:
1259 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1260 case Instruction::Opcode::FRem:
1261 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1262 case Instruction::Opcode::Shl:
1263 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1264 case Instruction::Opcode::LShr:
1265 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1266 case Instruction::Opcode::AShr:
1267 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1268 case Instruction::Opcode::And:
1269 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1270 case Instruction::Opcode::Or:
1271 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1272 case Instruction::Opcode::Xor:
1273 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1274 default:
1275 llvm_unreachable("Not a binary op!");
1276 }
1277}
1280 const Twine &Name) {
1281 auto &Builder = setInsertPos(Pos);
1282 llvm::Value *NewV =
1283 Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
1284 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1285 return Ctx.createBinaryOperator(NewBinOp);
1286 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1287 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1288}
1291 Value *RHS, Value *CopyFrom,
1293 const Twine &Name) {
1295 Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
1296 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1297 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1298 return NewV;
1299}
1300
1302 Ctx.getTracker()
1305 this);
1306 cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
1307}
1308
1310 Ctx.getTracker()
1311 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
1313 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1314}
1315
1317 Ctx.getTracker()
1318 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
1320 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1322
1324 Ctx.getTracker()
1325 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
1327 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1328}
1347 InsertPosition Pos, Context &Ctx,
1348 SyncScope::ID SSID, const Twine &Name) {
1349 auto &Builder = setInsertPos(Pos);
1350 auto *LLVMAtomicRMW =
1351 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1352 LLVMAtomicRMW->setName(Name);
1353 return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
1355
1357 Ctx.getTracker()
1360 this);
1373 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1374}
1375
1378 AtomicOrdering SuccessOrdering,
1379 AtomicOrdering FailureOrdering, InsertPosition Pos,
1380 Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
1381 auto &Builder = setInsertPos(Pos);
1382 auto *LLVMAtomicCmpXchg =
1383 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1384 SuccessOrdering, FailureOrdering, SSID);
1385 LLVMAtomicCmpXchg->setName(Name);
1386 return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1387}
1388
1390 Ctx.getTracker()
1391 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1393 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1394}
1395
1397 Ctx.getTracker()
1398 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1400 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1401}
1402
1404 Ctx.getTracker()
1405 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1407 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1408}
1409
1411 Ctx.getTracker()
1412 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1414 this);
1415 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1416}
1417
1419 Ctx.getTracker()
1422 this);
1423 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1424}
1425
1426AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
1427 Context &Ctx, Value *ArraySize,
1428 const Twine &Name) {
1429 auto &Builder = setInsertPos(Pos);
1430 auto *NewAlloca =
1431 Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
1432 return Ctx.createAllocaInst(NewAlloca);
1433}
1434
1438
1440 Ctx.getTracker()
1441 .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
1443 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
1445
1447 Ctx.getTracker()
1448 .emplaceIfTracking<
1450 this);
1451 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1452}
1453
1455 Ctx.getTracker()
1458 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1459}
1460
1466 return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
1467}
1468
1470 InsertPosition Pos, Context &Ctx, const Twine &Name) {
1471 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1472 auto &Builder = setInsertPos(Pos);
1473 auto *NewV =
1474 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
1475 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1476 return Ctx.createCastInst(NewCI);
1477 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1478 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1479}
1480
1481bool CastInst::classof(const Value *From) {
1482 return From->getSubclassID() == ClassID::Cast;
1483}
1484
1486 return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
1487}
1488
1490 return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
1491}
1492
1494 Ctx.getTracker()
1495 .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1498}
1499
1502 const Twine &Name) {
1503 auto &Builder = Instruction::setInsertPos(Pos);
1504 llvm::Value *NewV =
1505 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1506 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1507 return Ctx.createInsertElementInst(NewInsert);
1508 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1509 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1510}
1511
1513 Context &Ctx, const Twine &Name) {
1514 auto &Builder = setInsertPos(Pos);
1515 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1516 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1517 return Ctx.createExtractElementInst(NewExtract);
1518 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1519 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1520}
1521
1524 const Twine &Name) {
1525 auto &Builder = setInsertPos(Pos);
1526 llvm::Value *NewV =
1527 Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);
1528 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1529 return Ctx.createShuffleVectorInst(NewShuffle);
1530 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1531 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1532}
1533
1536 const Twine &Name) {
1537 auto &Builder = setInsertPos(Pos);
1538 llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
1539 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1540 return Ctx.createShuffleVectorInst(NewShuffle);
1541 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1542 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1543}
1544
1546 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1547 cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
1548}
1549
1551 return cast<VectorType>(
1552 Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
1553}
1554
1556 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1557 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
1558 getOperandUse(1));
1560}
1561
1566
1573
1577
1579 InsertPosition Pos, Context &Ctx,
1580 const Twine &Name) {
1581 auto &Builder = setInsertPos(Pos);
1582 llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
1583 if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
1584 return Ctx.createExtractValueInst(NewExtractValueInst);
1585 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1586 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1587}
1588
1590 auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
1591 return Agg->getContext().getType(LLVMTy);
1592}
1593
1595 InsertPosition Pos, Context &Ctx,
1596 const Twine &Name) {
1597 auto &Builder = setInsertPos(Pos);
1598 llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
1599 if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
1600 return Ctx.createInsertValueInst(NewInsertValueInst);
1601 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1602 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1603}
1604
1605ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
1606 auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
1607 return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
1608}
1609
1610} // namespace llvm::sandboxir
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static Value * getCondition(Instruction *I)
static constexpr Value * getValue(Ty &ValueOrUse)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
static Value * getParentPad(Value *EHPad)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
An instruction that atomically checks whether a specified value is in a memory location,...
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
void setFailureOrdering(AtomicOrdering Ordering)
Sets the failure ordering constraint of this cmpxchg instruction.
void setSuccessOrdering(AtomicOrdering Ordering)
Sets the success ordering constraint of this cmpxchg instruction.
void setVolatile(bool V)
Specify whether this is a volatile cmpxchg.
AtomicOrdering getSuccessOrdering() const
Returns the success ordering constraint of this cmpxchg instruction.
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this rmw instruction.
void setAlignment(Align Align)
AtomicOrdering getOrdering() const
Returns the ordering constraint of this rmw instruction.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:474
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
BasicBlock * getIndirectDest(unsigned i) const
void setDefaultDest(BasicBlock *B)
void setIndirectDest(unsigned i, BasicBlock *B)
BasicBlock * getDefaultDest() const
This class represents a function call, abstracting a target machine's calling convention.
Conditional Branch instruction.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantTokenNone * get(LLVMContext &Context)
Return the ConstantTokenNone.
static LLVM_ABI Type * getIndexedType(Type *Agg, ArrayRef< unsigned > Idxs)
Returns the type of the element that would be extracted with an extractvalue instruction with the spe...
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
An instruction for ordering other memory operations.
void setArgOperand(unsigned i, Value *v)
void setParentPad(Value *ParentPad)
Value * getParentPad() const
Convenience accessors.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th funcletpad argument.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2858
LLVM_ABI void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
LLVM_ABI bool hasAllowReciprocal() const LLVM_READONLY
Determine whether the allow-reciprocal flag is set.
LLVM_ABI void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
Instruction(const Instruction &)=delete
friend class Value
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
friend class BasicBlock
Various leaf nodes.
Invoke instruction.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
void setCleanup(bool V)
Indicate that this landingpad instruction is a cleanup.
Return a value (possibly void), from a function.
static LLVM_ABI Constant * convertShuffleMaskForBitcode(ArrayRef< int > Mask, Type *ResultTy)
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Multiway switch.
BasicBlock * getDefaultDest() const
CaseIteratorImpl< ConstCaseHandle > ConstCaseIt
CaseIteratorImpl< CaseHandle > CaseIt
void setDefaultDest(BasicBlock *DefaultCase)
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:310
Unconditional Branch instruction.
void setSuccessor(BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned i=0) const
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Use & Op()
Definition User.h:171
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition ilist_node.h:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
LLVM_ABI Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
LLVM_ABI void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
LLVM_ABI Value * getArraySize()
Get the number of elements allocated.
LLVM_ABI PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ABI void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
LLVM_ABI void setAlignment(Align Align)
static LLVM_ABI AllocaInst * create(Type *Ty, unsigned AddrSpace, InsertPosition Pos, Context &Ctx, Value *ArraySize=nullptr, const Twine &Name="")
LLVM_ABI void setSuccessOrdering(AtomicOrdering Ordering)
LLVM_ABI void setWeak(bool IsWeak)
LLVM_ABI void setVolatile(bool V)
Specify whether this is a volatile cmpxchg.
LLVM_ABI void setFailureOrdering(AtomicOrdering Ordering)
AtomicOrdering getFailureOrdering() const
LLVM_ABI void setAlignment(Align Align)
static LLVM_ABI AtomicCmpXchgInst * create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, InsertPosition Pos, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
LLVM_ABI void setSyncScopeID(SyncScope::ID SSID)
SyncScope::ID getSyncScopeID() const
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
static LLVM_ABI AtomicRMWInst * create(BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, InsertPosition Pos, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
LLVM_ABI void setSyncScopeID(SyncScope::ID SSID)
llvm::AtomicRMWInst::BinOp BinOp
LLVM_ABI void setOrdering(AtomicOrdering Ordering)
SyncScope::ID getSyncScopeID() const
LLVM_ABI void setVolatile(bool V)
LLVM_ABI Value * getPointerOperand()
LLVM_ABI void setAlignment(Align Align)
static LLVM_ABI Value * create(Instruction::Opcode Op, Value *LHS, Value *RHS, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI Function * getCalledFunction() const
LLVM_ABI Use getCalledOperandUse() const
LLVM_ABI FunctionType * getFunctionType() const
LLVM_ABI void setCalledFunction(Function *F)
LLVM_ABI Function * getCaller()
LLVM_ABI Value * getCalledOperand() const
void setCalledOperand(Value *V)
LLVM_ABI Value * getIndirectDestLabelUse(unsigned Idx) const
static LLVM_ABI CallBrInst * create(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest, ArrayRef< BasicBlock * > IndirectDests, ArrayRef< Value * > Args, InsertPosition Pos, Context &Ctx, const Twine &NameStr="")
LLVM_ABI Value * getIndirectDestLabel(unsigned Idx) const
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const
LLVM_ABI void setIndirectDest(unsigned Idx, BasicBlock *BB)
LLVM_ABI BasicBlock * getDefaultDest() const
LLVM_ABI BasicBlock * getIndirectDest(unsigned Idx) const
LLVM_ABI SmallVector< BasicBlock *, 16 > getIndirectDests() const
LLVM_ABI void setDefaultDest(BasicBlock *BB)
static LLVM_ABI CallInst * create(FunctionType *FTy, Value *Func, ArrayRef< Value * > Args, InsertPosition Pos, Context &Ctx, const Twine &NameStr="")
LLVM_ABI Type * getSrcTy() const
static LLVM_ABI Value * create(Type *DestTy, Opcode Op, Value *Operand, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI Type * getDestTy() const
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
static LLVM_ABI CatchPadInst * create(Value *ParentPad, ArrayRef< Value * > Args, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI CatchSwitchInst * getCatchSwitch() const
LLVM_ABI CatchPadInst * getCatchPad() const
LLVM_ABI BasicBlock * getSuccessor() const
LLVM_ABI void setSuccessor(BasicBlock *NewSucc)
LLVM_ABI void setCatchPad(CatchPadInst *CatchPad)
LLVM_ABI Value * getCatchSwitchParentPad() const
static LLVM_ABI CatchReturnInst * create(CatchPadInst *CatchPad, BasicBlock *BB, InsertPosition Pos, Context &Ctx)
LLVM_ABI void addHandler(BasicBlock *Dest)
LLVM_ABI void setParentPad(Value *ParentPad)
LLVM_ABI void setUnwindDest(BasicBlock *UnwindDest)
static LLVM_ABI CatchSwitchInst * create(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI BasicBlock * getUnwindDest() const
LLVM_ABI Value * getParentPad() const
static LLVM_ABI CleanupPadInst * create(Value *ParentPad, ArrayRef< Value * > Args, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI CleanupPadInst * getCleanupPad() const
LLVM_ABI void setUnwindDest(BasicBlock *NewDest)
static LLVM_ABI CleanupReturnInst * create(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, InsertPosition Pos, Context &Ctx)
LLVM_ABI BasicBlock * getUnwindDest() const
LLVM_ABI void setCleanupPad(CleanupPadInst *CleanupPad)
llvm::CmpInst::Predicate Predicate
void dumpOS(raw_ostream &OS) const override
LLVM_DUMP_METHOD void dump() const
static LLVM_ABI Value * createWithCopiedFlags(Predicate Pred, Value *S1, Value *S2, const Instruction *FlagsSource, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Type * makeCmpResultType(Type *OpndType)
Create a result type for fcmp/icmp.
static LLVM_ABI Value * create(Predicate Pred, Value *S1, Value *S2, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI void setPredicate(Predicate P)
LLVM_ABI void swapOperands()
static CondBrInst * create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore, Context &Ctx)
LLVM_ABI BasicBlock * getSuccessor(unsigned SuccIdx) const
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
unsigned getNumSuccessors() const
LLVM_ABI Value * getCondition() const
static LLVM_ABI ConstantTokenNone * get(Context &Ctx)
Return the ConstantTokenNone.
Type * getType(llvm::Type *LLVMTy)
Definition Context.h:264
LLVM_ABI Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition Context.cpp:451
LLVMContext & LLVMCtx
Definition Context.h:70
static LLVM_ABI Value * create(Value *Vec, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI VectorType * getVectorOperandType() const
static LLVM_ABI Value * create(Value *Agg, ArrayRef< unsigned > Idxs, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Type * getIndexedType(Type *Agg, ArrayRef< unsigned > Idxs)
Returns the type of the element that would be extracted with an extractvalue instruction with the spe...
static LLVM_ABI FenceInst * create(AtomicOrdering Ordering, InsertPosition Pos, Context &Ctx, SyncScope::ID SSID=SyncScope::System)
LLVM_ABI void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this fence instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this fence instruction.
LLVM_ABI void setSyncScopeID(SyncScope::ID SSID)
Sets the synchronization scope ID of this fence instruction.
static LLVM_ABI FreezeInst * create(Value *V, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI Value * getArgOperand(unsigned Idx) const
Return the Idx-th funcletpad argument.
LLVM_ABI Value * getParentPad() const
Return the outer EH-pad this funclet is nested within.
LLVM_ABI void setParentPad(Value *ParentPad)
LLVM_ABI void setArgOperand(unsigned Idx, Value *V)
Set the Idx-th funcletpad argument.
Similar to GenericSetter but the setters/getters have an index as their first argument.
Definition Tracker.h:305
This class can be used for tracking most instruction setters.
Definition Tracker.h:277
LLVM_ABI Type * getResultElementType() const
LLVM_ABI Type * getPointerOperandType() const
LLVM_ABI Type * getSourceElementType() const
LLVM_ABI Value * getPointerOperand() const
static LLVM_ABI Value * create(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, InsertPosition Pos, Context &Ctx, const Twine &NameStr="")
LLVM_ABI void swapOperands()
static LLVM_ABI Value * create(Value *Vec, Value *NewElt, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, InsertPosition Pos, Context &Ctx, const Twine &Name="")
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition Instruction.h:43
bool hasNoUnsignedWrap() const
Determine whether the no signed wrap flag is set.
static IRBuilder & setInsertPos(InsertPosition Pos)
Helper function for create().
LLVM_ABI void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
LLVM_ABI void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
LLVM_ABI void setHasNoSignedWrap(bool B=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
LLVM_ABI void insertAfter(Instruction *AfterI)
Insert this detached instruction after AfterI.
LLVM_ABI void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
bool hasAllowContract() const
Determine whether the allow-contract flag is set.
LLVM_ABI void setIsExact(bool B=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
bool hasApproxFunc() const
Determine whether the approximate-math-functions flag is set.
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
LLVM_ABI void setHasNoUnsignedWrap(bool B=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
void dumpOS(raw_ostream &OS) const override
LLVM_ABI BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
LLVM_ABI void setFast(bool B)
Set or clear all fast-math-flags on this instruction, which must be an operator which supports this f...
LLVM_ABI void setHasApproxFunc(bool B)
Set or clear the approximate-math-functions flag on this instruction, which must be an operator which...
LLVM_ABI void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
LLVM_ABI void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
LLVM_ABI llvm::Instruction * getTopmostLLVMInstruction() const
A SandboxIR Instruction may map to multiple LLVM IR Instruction.
LLVM_ABI void setHasAllowContract(bool B)
Set or clear the allow-contract flag on this instruction, which must be an operator which supports th...
virtual SmallVector< llvm::Instruction *, 1 > getLLVMInstrs() const =0
\Returns the LLVM IR Instructions that this SandboxIR maps to in program order.
LLVM_ABI Type * getAccessType() const
Instruction(ClassID ID, Opcode Opc, llvm::Instruction *I, sandboxir::Context &SBCtx)
Definition Instruction.h:57
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
LLVM_ABI Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
LLVM_ABI void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
LLVM_ABI Instruction * getPrevNode() const
\Returns the previous sandboxir::Instruction in the block, or nullptr if at the beginning of the bloc...
LLVM_ABI void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
LLVM_ABI void eraseFromParent()
Detach this Value from its parent and delete it.
LLVM_ABI void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
LLVM_ABI void setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
LLVM_ABI BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
static LLVM_ABI bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
LLVM_ABI BasicBlock * getUnwindDest() const
static LLVM_ABI InvokeInst * create(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, InsertPosition Pos, Context &Ctx, const Twine &NameStr="")
LLVM_ABI void setNormalDest(BasicBlock *BB)
LLVM_ABI void setUnwindDest(BasicBlock *BB)
LLVM_ABI BasicBlock * getSuccessor(unsigned SuccIdx) const
LLVM_ABI BasicBlock * getNormalDest() const
LLVM_ABI LandingPadInst * getLandingPadInst() const
bool isCleanup() const
Return 'true' if this landingpad instruction is a cleanup.
LLVM_ABI void setCleanup(bool V)
Indicate that this landingpad instruction is a cleanup.
LLVM_ABI Constant * getClause(unsigned Idx) const
Get the value of the clause at index Idx.
static LLVM_ABI LandingPadInst * create(Type *RetTy, unsigned NumReservedClauses, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx, const Twine &Name="")
LLVM_ABI void setVolatile(bool V)
Specify whether this is a volatile load or not.
LLVM_ABI Value * getPointerOperand() const
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
LLVM_ABI Value * hasConstantValue() const
LLVM_ABI int getBasicBlockIndex(const BasicBlock *BB) const
unsigned getNumIncomingValues() const
LLVM_ABI Value * getIncomingValue(unsigned Idx) const
LLVM_ABI void setIncomingBlock(unsigned Idx, BasicBlock *BB)
LLVM_ABI void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate)
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
static LLVM_ABI PHINode * create(Type *Ty, unsigned NumReservedValues, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI Value * removeIncomingValue(unsigned Idx)
LLVM_ABI void setIncomingValue(unsigned Idx, Value *V)
LLVM_ABI BasicBlock * getIncomingBlock(unsigned Idx) const
LLVM_ABI void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New)
LLVM_ABI Value * getIncomingValueForBlock(const BasicBlock *BB) const
LLVM_ABI void addIncoming(Value *V, BasicBlock *BB)
static LLVM_ABI ResumeInst * create(Value *Exn, InsertPosition Pos, Context &Ctx)
LLVM_ABI Value * getValue() const
static LLVM_ABI ReturnInst * create(Value *RetVal, InsertPosition Pos, Context &Ctx)
LLVM_ABI Value * getReturnValue() const
\Returns null if there is no return value.
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
static LLVM_ABI Value * create(Value *Cond, Value *True, Value *False, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI VectorType * getType() const
Overload to return most specific vector type.
LLVM_ABI Constant * getShuffleMaskForBitcode() const
Return the mask for this instruction, for use in bitcode.
LLVM_ABI void commute()
Swap the operands and adjust the mask to preserve the semantics of the instruction.
static LLVM_ABI Value * create(Value *V1, Value *V2, Value *Mask, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Constant * convertShuffleMaskForBitcode(ArrayRef< int > Mask, Type *ResultTy)
LLVM_ABI void setShuffleMask(ArrayRef< int > Mask)
LLVM_ABI void setVolatile(bool V)
Specify whether this is a volatile store or not.
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
static LLVM_ABI StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx)
LLVM_ABI Value * getPointerOperand() const
LLVM_ABI Value * getValueOperand() const
LLVM_ABI_FOR_TEST BlockT * getCaseSuccessor() const
LLVM_ABI_FOR_TEST ConstT * getCaseValue() const
static LLVM_ABI SwitchInst * create(Value *V, BasicBlock *Dest, unsigned NumCases, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI void addCase(ConstantInt *OnVal, BasicBlock *Dest)
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const
CaseIt case_begin()
Returns a read/write iterator that points to the first case in the SwitchInst.
LLVM_ABI void setDefaultDest(BasicBlock *DefaultCase)
LLVM_ABI BasicBlock * getDefaultDest() const
CaseItImpl< llvm::SwitchInst::CaseIt, BasicBlock, ConstantInt > CaseIt
LLVM_ABI Value * getCondition() const
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
LLVM_ABI void setCondition(Value *V)
LLVM_ABI ConstantInt * findCaseDest(BasicBlock *BB)
LLVM_ABI CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition Tracker.h:442
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition Tracker.h:504
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition Tracker.h:480
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition Tracker.h:497
Just like llvm::Type these are immutable, unique, never get freed and can only be created via static ...
Definition Type.h:48
llvm::Type * LLVMTy
Definition Type.h:50
static LLVM_ABI IntegerType * getInt1Ty(Context &Ctx)
Definition Type.cpp:30
Context & getContext() const
Definition Type.h:98
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Instruction::Opcode Op, Value *OpV, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static UncondBrInst * create(BasicBlock *Target, InsertPosition InsertBefore, Context &Ctx)
LLVM_ABI BasicBlock * getSuccessor() const
static LLVM_ABI bool classof(const Value *From)
For isa/dyn_cast.
LLVM_ABI void setSuccessor(BasicBlock *NewSucc)
static LLVM_ABI UnreachableInst * create(InsertPosition Pos, Context &Ctx)
static LLVM_ABI bool classof(const Value *From)
Tracks swapping a Use with another Use.
Definition Tracker.h:198
Represents a Def-use/Use-def edge in SandboxIR.
Definition Use.h:33
virtual void setOperand(unsigned OperandIdx, Value *Operand)
Definition User.cpp:92
virtual unsigned getNumOperands() const
Definition User.h:129
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
Definition User.h:126
LLVM_ABI Value * getPointerOperand()
static LLVM_ABI VAArgInst * create(Value *List, Type *Ty, InsertPosition Pos, Context &Ctx, const Twine &Name="")
A SandboxIR Value has users. This is the base class.
Definition Value.h:72
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
Definition Value.h:122
ClassID getSubclassID() const
Definition Value.h:213
void dumpCommonSuffix(raw_ostream &OS) const
Definition Value.cpp:107
Context & Ctx
All values point to the context.
Definition Value.h:201
iterator_range< user_iterator > users()
Definition Value.h:253
void dumpCommonPrefix(raw_ostream &OS) const
Definition Value.cpp:100
@ LLVMAtomicRMW
Definition Core.h:140
@ LLVMAtomicCmpXchg
Definition Core.h:139
@ LLVMSwitch
Definition Core.h:67
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
bool empty() const
Definition BasicBlock.h:101
LLVM_ABI_FOR_TEST void dumpOS(raw_ostream &OS) const final
static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc)
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
Definition BasicBlock.h:75
iterator end() const
Definition BasicBlock.h:89
static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
LLVM_ABI iterator begin() const
static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto cast_or_null(const Y &Val)
Definition Casting.h:714
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition STLExtras.h:1969
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
AtomicOrdering
Atomic ordering for LLVM's memory model.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106