LLVM 24.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
12
13namespace llvm::sandboxir {
14
16 Instruction *Prev = getPrevNode();
17 if (Prev == nullptr) {
18 // If at top of the BB, return the first BB instruction.
19 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
20 }
21 // Else get the Previous sandbox IR instruction's bottom IR instruction and
22 // return its successor.
24 return PrevBotI->getNextNode();
25}
26
27BBIterator Instruction::getIterator() const {
29 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
30}
31
33 assert(getParent() != nullptr && "Detached!");
34 assert(getIterator() != getParent()->end() && "Already at end!");
35 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
36 // and get the corresponding sandboxir Instruction that maps to it. This works
37 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
39 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
40 auto *NextLLVMI = LLVMI->getNextNode();
41 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
42 if (NextI == nullptr)
43 return nullptr;
44 return NextI;
46
48 assert(getParent() != nullptr && "Detached!");
49 auto It = getIterator();
50 if (It != getParent()->begin())
51 return std::prev(getIterator()).get();
52 return nullptr;
53}
54
56 Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
57
58 // Detach all the LLVM IR instructions from their parent BB.
60 I->removeFromParent();
61}
62
64 assert(users().empty() && "Still connected to users, can't erase!");
65
66 Ctx.runEraseInstrCallbacks(this);
67 std::unique_ptr<Value> Detached = Ctx.detach(this);
68 auto LLVMInstrs = getLLVMInstrs();
69
70 auto &Tracker = Ctx.getTracker();
71 if (Tracker.isTracking()) {
72 Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
73 // We don't actually delete the IR instruction, because then it would be
74 // impossible to bring it back from the dead at the same memory location.
75 // Instead we remove it from its BB and track its current location.
76 for (llvm::Instruction *I : LLVMInstrs)
77 I->removeFromParent();
78 // TODO: Multi-instructions need special treatment because some of the
79 // references are internal to the instruction.
80 for (llvm::Instruction *I : LLVMInstrs)
81 I->dropAllReferences();
82 } else {
83 // Erase in reverse to avoid erasing nstructions with attached uses.
84 for (llvm::Instruction *I : reverse(LLVMInstrs))
85 I->eraseFromParent();
86 }
88
89void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
90 if (std::next(getIterator()) == WhereIt)
91 // Destination is same as origin, nothing to do.
92 return;
93
94 Ctx.runMoveInstrCallbacks(this, WhereIt);
95 Ctx.getTracker().emplaceIfTracking<MoveInstr>(this);
96
97 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
99 if (WhereIt == BB.end()) {
100 It = LLVMBB->end();
101 } else {
102 Instruction *WhereI = &*WhereIt;
103 It = WhereI->getTopmostLLVMInstruction()->getIterator();
104 }
105 // TODO: Move this to the verifier of sandboxir::Instruction.
107 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
108 "Expected program order!");
109 // Do the actual move in LLVM IR.
110 for (auto *I : getLLVMInstrs())
111 I->moveBefore(*LLVMBB, It);
112}
113
115 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
117 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
118
119 // Insert the LLVM IR Instructions in program order.
121 I->insertBefore(BeforeTopI->getIterator());
123
125 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
126}
127
128void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
129 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
130 llvm::Instruction *LLVMBeforeI;
131 llvm::BasicBlock::iterator LLVMBeforeIt;
132 Instruction *BeforeI;
133 if (WhereIt != BB->end()) {
134 BeforeI = &*WhereIt;
135 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
136 LLVMBeforeIt = LLVMBeforeI->getIterator();
137 } else {
138 BeforeI = nullptr;
139 LLVMBeforeI = nullptr;
140 LLVMBeforeIt = LLVMBB->end();
141 }
142
143 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
144
145 // Insert the LLVM IR Instructions in program order.
147 I->insertInto(LLVMBB, LLVMBeforeIt);
148}
149
151 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
152 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
154 if (BB == nullptr)
155 return nullptr;
156 return cast<BasicBlock>(Ctx.getValue(BB));
157}
158
160 auto *WhereBB = Pos.getBasicBlock();
161 auto WhereIt = Pos.getIterator();
162 auto &Builder = WhereBB->getParent()->getParent()->getLLVMIRBuilder();
163 if (WhereIt != WhereBB->end())
164 Builder.SetInsertPoint((*Pos).getTopmostLLVMInstruction());
165 else
166 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
167 return Builder;
168}
169
171 switch (From->getSubclassID()) {
172#define DEF_INSTR(ID, OPC, CLASS) \
173 case ClassID::ID: \
174 return true;
175#define DEF_DISABLE_AUTO_UNDEF // ValuesDefFilesList.def includes multiple .def
176#include "llvm/SandboxIR/ValuesDefFilesList.def"
177 default:
178 return false;
179 }
180}
183 Ctx.getTracker()
186 this);
187 cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
188}
191 Ctx.getTracker()
194 cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
195}
196
198 Ctx.getTracker()
199 .emplaceIfTracking<
200 GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this);
201 cast<llvm::Instruction>(Val)->setFast(B);
202}
203
205 Ctx.getTracker()
206 .emplaceIfTracking<
207 GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this);
208 cast<llvm::Instruction>(Val)->setIsExact(B);
209}
210
212 Ctx.getTracker()
213 .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc,
215 cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
217
219 Ctx.getTracker()
220 .emplaceIfTracking<
222 this);
223 cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
224}
225
227 Ctx.getTracker()
228 .emplaceIfTracking<
230 this);
231 cast<llvm::Instruction>(Val)->setHasNoInfs(B);
232}
233
235 Ctx.getTracker()
238 this);
239 cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
240}
241
243 Ctx.getTracker()
246 this);
247 cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
248}
249
251 Ctx.getTracker()
254 this);
255 cast<llvm::Instruction>(Val)->setHasAllowContract(B);
256}
257
259 Ctx.getTracker()
262 cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
263}
264
266 Ctx.getTracker()
269 cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
270}
271
275
277 Ctx.getTracker()
278 .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
280 cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
282
283#ifndef NDEBUG
285 OS << "Unimplemented! Please override dump().";
286}
287#endif // NDEBUG
288
290 Context &Ctx, const Twine &Name) {
291 auto &Builder = setInsertPos(Pos);
292 auto *LLVMI =
293 cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name));
294 return Ctx.createVAArgInst(LLVMI);
295}
296
300
301FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx,
302 const Twine &Name) {
303 auto &Builder = setInsertPos(Pos);
304 auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name));
305 return Ctx.createFreezeInst(LLVMI);
306}
307
309 Context &Ctx, SyncScope::ID SSID) {
310 auto &Builder = Instruction::setInsertPos(Pos);
311 llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
312 return Ctx.createFenceInst(LLVMI);
313}
314
316 Ctx.getTracker()
317 .emplaceIfTracking<
319 this);
320 cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
321}
322
324 Ctx.getTracker()
325 .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
327 cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
328}
329
331 InsertPosition Pos, Context &Ctx, const Twine &Name) {
332 auto &Builder = Instruction::setInsertPos(Pos);
333 llvm::Value *NewV =
334 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
335 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
336 return Ctx.createSelectInst(NewSI);
337 assert(isa<llvm::Constant>(NewV) && "Expected constant");
338 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
339}
340
342 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
343 getOperandUse(2));
344 cast<llvm::SelectInst>(Val)->swapValues();
346
347bool SelectInst::classof(const Value *From) {
348 return From->getSubclassID() == ClassID::Select;
349}
350
351BasicBlock *BrInstCommon::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
352 return cast<BasicBlock>(Ctx.getValue(BB));
353}
354const BasicBlock *
355BrInstCommon::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
356 return cast<BasicBlock>(Ctx.getValue(BB));
357}
358
360 InsertPosition InsertBefore, Context &Ctx) {
361 auto &Builder = setInsertPos(InsertBefore);
362 llvm::UncondBrInst *NewUBr =
363 Builder.CreateBr(cast<llvm::BasicBlock>(Target->Val));
364 return Ctx.createUncondBrInst(NewUBr);
365}
366
369 Ctx.getValue(cast<llvm::UncondBrInst>(Val)->getSuccessor()));
370}
371
373 Ctx.getTracker()
374 .emplaceIfTracking<GenericSetter<&UncondBrInst::getSuccessor,
376 cast<llvm::UncondBrInst>(Val)->setSuccessor(
377 0, cast<llvm::BasicBlock>(NewSucc->Val));
378}
379
380bool UncondBrInst::classof(const Value *From) {
381 return From->getSubclassID() == ClassID::UncondBr;
382}
383
385 BasicBlock *IfFalse, InsertPosition InsertBefore,
386 Context &Ctx) {
387 auto &Builder = setInsertPos(InsertBefore);
388 llvm::CondBrInst *NewCBr = Builder.CreateCondBr(
390 cast<llvm::BasicBlock>(IfFalse->Val));
391 return Ctx.createCondBrInst(NewCBr);
392}
393
396 "Cannot get condition of an uncond branch!");
397 return Ctx.getValue(cast<llvm::CondBrInst>(Val)->getCondition());
400 Ctx.getTracker()
401 .emplaceIfTracking<
403 this);
404 llvm::Value *LLVMV = V->Val;
405 cast<llvm::CondBrInst>(Val)->setCondition(LLVMV);
406}
407
408BasicBlock *CondBrInst::getSuccessor(unsigned SuccIdx) const {
409 assert(SuccIdx < getNumSuccessors() &&
410 "Successor # out of range for Branch!");
412 Ctx.getValue(cast<llvm::CondBrInst>(Val)->getSuccessor(SuccIdx)));
413}
414
415void CondBrInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
416 assert(Idx < getNumSuccessors() && "Out of bounds!");
417 Ctx.getTracker()
418 .emplaceIfTracking<GenericSetterWithIdx<&CondBrInst::getSuccessor,
420 Idx);
421 cast<llvm::CondBrInst>(Val)->setSuccessor(
422 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
424
425bool CondBrInst::classof(const Value *From) {
426 return From->getSubclassID() == ClassID::CondBr;
428
430 Ctx.getTracker()
431 .emplaceIfTracking<
433 cast<llvm::LoadInst>(Val)->setVolatile(V);
434}
435
437 InsertPosition Pos, bool IsVolatile, Context &Ctx,
438 const Twine &Name) {
439 auto &Builder = setInsertPos(Pos);
440 auto *NewLI =
441 Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
442 auto *NewSBI = Ctx.createLoadInst(NewLI);
443 return NewSBI;
444}
445
446bool LoadInst::classof(const Value *From) {
447 return From->getSubclassID() == ClassID::Load;
448}
449
453
455 Ctx.getTracker()
456 .emplaceIfTracking<
458 cast<llvm::StoreInst>(Val)->setVolatile(V);
459}
460
462 InsertPosition Pos, bool IsVolatile,
463 Context &Ctx) {
464 auto &Builder = setInsertPos(Pos);
465 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
466 auto *NewSBI = Ctx.createStoreInst(NewSI);
467 return NewSBI;
468}
469
470bool StoreInst::classof(const Value *From) {
471 return From->getSubclassID() == ClassID::Store;
472}
473
477
481
482UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
483 auto &Builder = setInsertPos(Pos);
484 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
485 return Ctx.createUnreachableInst(NewUI);
486}
487
489 return From->getSubclassID() == ClassID::Unreachable;
490}
491
492ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
493 Context &Ctx) {
494 llvm::ReturnInst *NewRI;
495 if (RetVal != nullptr)
496 NewRI = Builder.CreateRet(RetVal->Val);
497 else
498 NewRI = Builder.CreateRetVoid();
499 return Ctx.createReturnInst(NewRI);
500}
501
502ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
503 Context &Ctx) {
504 auto &Builder = setInsertPos(Pos);
505 return createCommon(RetVal, Builder, Ctx);
506}
507
509 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
510 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
511}
512
514 return cast<FunctionType>(
515 Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
516}
517
519 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
521
523 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
524 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
526
529 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
530}
532 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
533}
534
536 // F's function type is private, so we rely on `setCalledFunction()` to update
537 // it. But even though we are calling `setCalledFunction()` we also need to
538 // track this change at the SandboxIR level, which is why we call
539 // `setCalledOperand()` here.
540 // Note: This may break if `setCalledFunction()` early returns if `F`
541 // is already set, but we do have a unit test for it.
542 setCalledOperand(F);
543 cast<llvm::CallBase>(Val)->setCalledFunction(
544 cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
545 cast<llvm::Function>(F->Val));
546}
547
548CallInst *CallInst::create(FunctionType *FTy, Value *Func,
550 Context &Ctx, const Twine &NameStr) {
551 auto &Builder = setInsertPos(Pos);
553 LLVMArgs.reserve(Args.size());
554 for (Value *Arg : Args)
555 LLVMArgs.push_back(Arg->Val);
556 llvm::CallInst *NewCI = Builder.CreateCall(
557 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
558 return Ctx.createCallInst(NewCI);
559}
560
561InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
562 BasicBlock *IfNormal, BasicBlock *IfException,
564 Context &Ctx, const Twine &NameStr) {
565 auto &Builder = setInsertPos(Pos);
567 LLVMArgs.reserve(Args.size());
568 for (Value *Arg : Args)
569 LLVMArgs.push_back(Arg->Val);
570 llvm::InvokeInst *Invoke = Builder.CreateInvoke(
571 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
572 cast<llvm::BasicBlock>(IfNormal->Val),
573 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
574 return Ctx.createInvokeInst(Invoke);
576
578 return cast<BasicBlock>(
579 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
580}
582 return cast<BasicBlock>(
583 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
584}
586 setOperand(1, BB);
587 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
588}
590 setOperand(2, BB);
591 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
592}
595 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
596 ;
597}
598BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
599 return cast<BasicBlock>(
600 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
601}
602
603CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
604 BasicBlock *DefaultDest,
605 ArrayRef<BasicBlock *> IndirectDests,
607 Context &Ctx, const Twine &NameStr) {
608 auto &Builder = setInsertPos(Pos);
610 LLVMIndirectDests.reserve(IndirectDests.size());
611 for (BasicBlock *IndDest : IndirectDests)
612 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
615 LLVMArgs.reserve(Args.size());
616 for (Value *Arg : Args)
617 LLVMArgs.push_back(Arg->Val);
619 llvm::CallBrInst *CallBr =
620 Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
621 cast<llvm::BasicBlock>(DefaultDest->Val),
622 LLVMIndirectDests, LLVMArgs, NameStr);
623 return Ctx.createCallBrInst(CallBr);
624}
625
627 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
630 return Ctx.getValue(
632}
634 return cast<BasicBlock>(
635 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
636}
639 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
640}
643 for (llvm::BasicBlock *LLVMBB :
644 cast<llvm::CallBrInst>(Val)->getIndirectDests())
645 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
646 return BBs;
647}
649 Ctx.getTracker()
650 .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
652 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
655 Ctx.getTracker()
658 this, Idx);
659 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
660 cast<llvm::BasicBlock>(BB->Val));
661}
664 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
665}
666
667LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
668 InsertPosition Pos, Context &Ctx,
669 const Twine &Name) {
670 auto &Builder = setInsertPos(Pos);
671 llvm::LandingPadInst *LLVMI =
672 Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
673 return Ctx.createLandingPadInst(LLVMI);
674}
675
677 Ctx.getTracker()
678 .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
680 cast<llvm::LandingPadInst>(Val)->setCleanup(V);
681}
682
684 return cast<Constant>(
685 Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
686}
687
691
693 Ctx.getTracker()
694 .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
696 cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
697}
700 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
701}
702
703void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
704 Ctx.getTracker()
705 .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
707 this, Idx);
708 cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
709}
710
715
716CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
718 const Twine &Name) {
719 auto &Builder = setInsertPos(Pos);
721 LLVMArgs.reserve(Args.size());
722 for (auto *Arg : Args)
723 LLVMArgs.push_back(Arg->Val);
724 llvm::CatchPadInst *LLVMI =
725 Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
726 return Ctx.createCatchPadInst(LLVMI);
727}
728
729CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
731 const Twine &Name) {
732 auto &Builder = setInsertPos(Pos);
734 LLVMArgs.reserve(Args.size());
735 for (auto *Arg : Args)
736 LLVMArgs.push_back(Arg->Val);
737 llvm::CleanupPadInst *LLVMI =
738 Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
739 return Ctx.createCleanupPadInst(LLVMI);
740}
741
742CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
743 InsertPosition Pos, Context &Ctx) {
744 auto &Builder = setInsertPos(Pos);
745 llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
747 return Ctx.createCatchReturnInst(LLVMI);
748}
749
751 return cast<CatchPadInst>(
752 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
753}
754
756 Ctx.getTracker()
759 cast<llvm::CatchReturnInst>(Val)->setCatchPad(
760 cast<llvm::CatchPadInst>(CatchPad->Val));
761}
762
764 return cast<BasicBlock>(
765 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
766}
767
769 Ctx.getTracker()
770 .emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor,
772 cast<llvm::CatchReturnInst>(Val)->setSuccessor(
773 cast<llvm::BasicBlock>(NewSucc->Val));
774}
775
780
781CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
782 BasicBlock *UnwindBB,
783 InsertPosition Pos, Context &Ctx) {
784 auto &Builder = setInsertPos(Pos);
785 auto *LLVMUnwindBB =
786 UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
787 llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
788 cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
789 return Ctx.createCleanupReturnInst(LLVMI);
790}
791
796
798 Ctx.getTracker()
801 this);
802 cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
803 cast<llvm::CleanupPadInst>(CleanupPad->Val));
804}
805
810
812 Ctx.getTracker()
815 this);
816 cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
817 cast<llvm::BasicBlock>(NewDest->Val));
818}
819
822 Context &Ctx, const Twine &NameStr) {
823 auto &Builder = setInsertPos(Pos);
824 SmallVector<llvm::Value *> LLVMIdxList;
825 LLVMIdxList.reserve(IdxList.size());
826 for (Value *Idx : IdxList)
827 LLVMIdxList.push_back(Idx->Val);
828 llvm::Value *NewV =
829 Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
830 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
831 return Ctx.createGetElementPtrInst(NewGEP);
832 assert(isa<llvm::Constant>(NewV) && "Expected constant");
833 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
834}
835
840
845
849
854
855BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
856 return cast<BasicBlock>(Ctx.getValue(LLVMBB));
857}
858
859PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
860 InsertPosition Pos, Context &Ctx, const Twine &Name) {
861 auto &Builder = setInsertPos(Pos);
862 llvm::PHINode *NewPHI =
863 Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
864 return Ctx.createPHINode(NewPHI);
865}
866
867bool PHINode::classof(const Value *From) {
868 return From->getSubclassID() == ClassID::PHI;
869}
870
871Value *PHINode::getIncomingValue(unsigned Idx) const {
872 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
873}
874void PHINode::setIncomingValue(unsigned Idx, Value *V) {
875 Ctx.getTracker()
878 Idx);
879 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
880}
882 return cast<BasicBlock>(
883 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
884}
886 llvm::Use *LLVMUse = U.LLVMUse;
887 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
888 return cast<BasicBlock>(Ctx.getValue(BB));
889}
890void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
891 // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
892 constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
894 Ctx.getTracker()
895 .emplaceIfTracking<
897 this, Idx);
898 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
899 cast<llvm::BasicBlock>(BB->Val));
900}
902 auto &Tracker = Ctx.getTracker();
904
905 cast<llvm::PHINode>(Val)->addIncoming(V->Val,
906 cast<llvm::BasicBlock>(BB->Val));
907}
909 auto &Tracker = Ctx.getTracker();
911 llvm::Value *LLVMV =
912 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
913 /*DeletePHIIfEmpty=*/false);
914 return Ctx.getValue(LLVMV);
915}
917 auto &Tracker = Ctx.getTracker();
918 Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, getBasicBlockIndex(BB));
919
920 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
921 llvm::Value *LLVMV =
922 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
923 /*DeletePHIIfEmpty=*/false);
924 return Ctx.getValue(LLVMV);
925}
927 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
928 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
929}
931 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
932 llvm::Value *LLVMV =
933 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
934 return Ctx.getValue(LLVMV);
935}
937 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
938 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
939}
941 assert(New && Old && "Sandbox IR PHI node got a null basic block!");
942 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
943 Idx != NumOps; ++Idx)
944 if (getIncomingBlock(Idx) == Old)
945 setIncomingBlock(Idx, New);
946}
947void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
948 // Avoid duplicate tracking by going through this->removeIncomingValue here at
949 // the expense of some performance. Copy PHI::removeIncomingValueIf more
950 // directly if performance becomes an issue.
951
952 // Removing the element at index X, moves the element previously at X + 1
953 // to X. Working from the end avoids complications from that.
954 unsigned Idx = getNumIncomingValues();
955 while (Idx > 0) {
956 if (Predicate(Idx - 1))
957 removeIncomingValue(Idx - 1);
958 --Idx;
959 }
960}
961
963 Context &Ctx, const Twine &Name) {
964 auto &Builder = setInsertPos(Pos);
965 auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
966 // It may have been folded into a constant.
967 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
968 return Ctx.getOrCreateConstant(LLVMC);
969 if (isa<llvm::ICmpInst>(LLVMV))
970 return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
971 return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
972}
973
975 const Instruction *F, InsertPosition Pos,
976 Context &Ctx, const Twine &Name) {
977 Value *V = create(P, S1, S2, Pos, Ctx, Name);
978 if (auto *C = dyn_cast<Constant>(V))
979 return C;
980 cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
981 return V;
982}
983
985 if (auto *VT = dyn_cast<VectorType>(OpndType)) {
986 // TODO: Cleanup when we have more complete support for
987 // sandboxir::VectorType
988 return OpndType->getContext().getType(llvm::VectorType::get(
990 cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
991 }
992 return Type::getInt1Ty(OpndType->getContext());
993}
994
996 Ctx.getTracker()
997 .emplaceIfTracking<
999 cast<llvm::CmpInst>(Val)->setPredicate(P);
1000}
1001
1003 if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
1004 IC->swapOperands();
1005 else
1006 cast<FCmpInst>(this)->swapOperands();
1008
1010 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
1011 cast<llvm::ICmpInst>(Val)->swapOperands();
1013
1015 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
1016 cast<llvm::FCmpInst>(Val)->swapOperands();
1017}
1018
1019#ifndef NDEBUG
1021 dumpCommonPrefix(OS);
1022 dumpCommonSuffix(OS);
1023}
1024
1025void CmpInst::dump() const {
1026 dumpOS(dbgs());
1027 dbgs() << "\n";
1028}
1029#endif // NDEBUG
1030
1032 switch (Opc) {
1033 case Instruction::Opcode::ZExt:
1034 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1035 case Instruction::Opcode::SExt:
1036 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1037 case Instruction::Opcode::FPToUI:
1038 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1039 case Instruction::Opcode::FPToSI:
1040 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1041 case Instruction::Opcode::FPExt:
1042 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1043 case Instruction::Opcode::PtrToAddr:
1044 return static_cast<llvm::Instruction::CastOps>(
1045 llvm::Instruction::PtrToAddr);
1046 case Instruction::Opcode::PtrToInt:
1047 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1048 case Instruction::Opcode::IntToPtr:
1049 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1050 case Instruction::Opcode::SIToFP:
1051 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1052 case Instruction::Opcode::UIToFP:
1053 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1054 case Instruction::Opcode::Trunc:
1055 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1056 case Instruction::Opcode::FPTrunc:
1057 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1058 case Instruction::Opcode::BitCast:
1059 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1060 case Instruction::Opcode::AddrSpaceCast:
1061 return static_cast<llvm::Instruction::CastOps>(
1062 llvm::Instruction::AddrSpaceCast);
1063 default:
1064 llvm_unreachable("Opcode not suitable for CastInst!");
1065 }
1066}
1067
1068/// \Returns the LLVM opcode that corresponds to \p Opc.
1070 switch (Opc) {
1071 case Instruction::Opcode::FNeg:
1072 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1073 default:
1074 llvm_unreachable("Not a unary op!");
1075 }
1076}
1077
1078CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
1079 unsigned NumHandlers,
1081 const Twine &Name) {
1082 auto &Builder = setInsertPos(Pos);
1083 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1084 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1085 return Ctx.createCatchSwitchInst(LLVMCSI);
1086}
1087
1089 return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
1090}
1091
1093 Ctx.getTracker()
1094 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
1096 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1097}
1098
1101 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1102}
1103
1105 Ctx.getTracker()
1108 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1109 cast<llvm::BasicBlock>(UnwindDest->Val));
1110}
1111
1113 Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
1114 cast<llvm::CatchSwitchInst>(Val)->addHandler(
1115 cast<llvm::BasicBlock>(Dest->Val));
1116}
1117
1119 auto &Builder = setInsertPos(Pos);
1120 auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1121 return Ctx.createResumeInst(LLVMI);
1122}
1123
1125 return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1126}
1127
1128SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1130 const Twine &Name) {
1131 auto &Builder = setInsertPos(Pos);
1133 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1134 return Ctx.createSwitchInst(LLVMSwitch);
1135}
1136
1138 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1139}
1140
1142 Ctx.getTracker()
1143 .emplaceIfTracking<
1144 GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(
1145 this);
1146 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1147}
1148
1150 return cast<BasicBlock>(
1151 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1152}
1153
1155 Ctx.getTracker()
1156 .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
1158 cast<llvm::SwitchInst>(Val)->setDefaultDest(
1159 cast<llvm::BasicBlock>(DefaultCase->Val));
1160}
1162template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1163ConstT *
1165 const auto &LLVMCaseHandle = *LLVMCaseIt;
1166 auto *LLVMC = Ctx.getValue(LLVMCaseHandle.getCaseValue());
1167 return cast<ConstT>(LLVMC);
1168}
1169
1170template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1171BlockT *
1173 const {
1174 const auto &LLVMCaseHandle = *LLVMCaseIt;
1175 auto *LLVMBB = LLVMCaseHandle.getCaseSuccessor();
1176 return cast<BlockT>(Ctx.getValue(LLVMBB));
1177}
1178
1181template class SwitchInst::CaseItImpl<llvm::SwitchInst::CaseIt, BasicBlock,
1182 ConstantInt>;
1185template class SwitchInst::CaseItImpl<llvm::SwitchInst::ConstCaseIt,
1186 const BasicBlock, const ConstantInt>;
1187
1189 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1190 cast<llvm::BasicBlock>(BB->Val));
1191 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1192}
1193
1195 Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
1196 // TODO: Track this!
1198 cast<llvm::BasicBlock>(Dest->Val));
1199}
1200
1202 Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
1203
1205 unsigned CaseNum = It - case_begin();
1206 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1207 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1208 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1209 return CaseIt(this, Num);
1210}
1211
1213 return cast<BasicBlock>(
1214 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1215}
1216
1217void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1218 Ctx.getTracker()
1221 Idx);
1222 cast<llvm::SwitchInst>(Val)->setSuccessor(
1223 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1224}
1225
1227 InsertPosition Pos, Context &Ctx,
1228 const Twine &Name) {
1229 auto &Builder = setInsertPos(Pos);
1230 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1231 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1232 return Ctx.createUnaryOperator(NewUnOpV);
1233 }
1234 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1235 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1236}
1237
1239 Value *CopyFrom, InsertPosition Pos,
1240 Context &Ctx, const Twine &Name) {
1241 auto *NewV = create(Op, OpV, Pos, Ctx, Name);
1242 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1243 UnI->copyIRFlags(CopyFrom->Val);
1244 return NewV;
1245}
1246
1247/// \Returns the LLVM opcode that corresponds to \p Opc.
1249 switch (Opc) {
1250 case Instruction::Opcode::Add:
1251 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1252 case Instruction::Opcode::FAdd:
1253 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1254 case Instruction::Opcode::Sub:
1255 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1256 case Instruction::Opcode::FSub:
1257 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1258 case Instruction::Opcode::Mul:
1259 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1260 case Instruction::Opcode::FMul:
1261 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1262 case Instruction::Opcode::UDiv:
1263 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1264 case Instruction::Opcode::SDiv:
1265 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1266 case Instruction::Opcode::FDiv:
1267 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1268 case Instruction::Opcode::URem:
1269 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1270 case Instruction::Opcode::SRem:
1271 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1272 case Instruction::Opcode::FRem:
1273 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1274 case Instruction::Opcode::Shl:
1275 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1276 case Instruction::Opcode::LShr:
1277 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1278 case Instruction::Opcode::AShr:
1279 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1280 case Instruction::Opcode::And:
1281 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1282 case Instruction::Opcode::Or:
1283 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1284 case Instruction::Opcode::Xor:
1285 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1286 default:
1287 llvm_unreachable("Not a binary op!");
1288 }
1289}
1292 const Twine &Name) {
1293 auto &Builder = setInsertPos(Pos);
1294 llvm::Value *NewV =
1295 Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
1296 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1297 return Ctx.createBinaryOperator(NewBinOp);
1298 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1299 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1300}
1301
1303 Value *RHS, Value *CopyFrom,
1305 const Twine &Name) {
1306
1307 Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
1308 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1309 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1310 return NewV;
1311}
1312
1314 Ctx.getTracker()
1315 .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,
1317 this);
1318 cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
1319}
1320
1322 Ctx.getTracker()
1323 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
1325 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1326}
1327
1329 Ctx.getTracker()
1330 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
1332 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1333}
1334
1336 Ctx.getTracker()
1337 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
1339 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1340}
1341
1343 Ctx.getTracker()
1344 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,
1346 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1347}
1348
1352
1356
1360 SyncScope::ID SSID, const Twine &Name) {
1361 auto &Builder = setInsertPos(Pos);
1362 auto *LLVMAtomicRMW =
1363 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1364 LLVMAtomicRMW->setName(Name);
1365 return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
1366}
1369 Ctx.getTracker()
1390 AtomicOrdering SuccessOrdering,
1391 AtomicOrdering FailureOrdering, InsertPosition Pos,
1392 Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
1393 auto &Builder = setInsertPos(Pos);
1395 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1396 SuccessOrdering, FailureOrdering, SSID);
1397 LLVMAtomicCmpXchg->setName(Name);
1398 return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1399}
1400
1402 Ctx.getTracker()
1403 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1405 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1406}
1407
1409 Ctx.getTracker()
1410 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1412 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1413}
1414
1416 Ctx.getTracker()
1417 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1419 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1420}
1421
1423 Ctx.getTracker()
1424 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1426 this);
1427 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1428}
1429
1431 Ctx.getTracker()
1432 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
1434 this);
1435 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1436}
1437
1438AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
1439 Context &Ctx, Value *ArraySize,
1440 const Twine &Name) {
1441 auto &Builder = setInsertPos(Pos);
1442 auto *NewAlloca =
1443 Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
1444 return Ctx.createAllocaInst(NewAlloca);
1445}
1446
1450
1452 Ctx.getTracker()
1453 .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
1455 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
1456}
1457
1459 Ctx.getTracker()
1460 .emplaceIfTracking<
1462 this);
1463 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1464}
1465
1467 Ctx.getTracker()
1468 .emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca,
1470 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1471}
1472
1476
1478 return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
1480
1482 InsertPosition Pos, Context &Ctx, const Twine &Name) {
1483 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1484 auto &Builder = setInsertPos(Pos);
1485 auto *NewV =
1486 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
1487 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1488 return Ctx.createCastInst(NewCI);
1489 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1490 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1491}
1492
1493bool CastInst::classof(const Value *From) {
1494 return From->getSubclassID() == ClassID::Cast;
1495}
1496
1498 return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
1499}
1500
1502 return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
1503}
1504
1506 Ctx.getTracker()
1507 .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1510}
1511
1513 InsertPosition Pos, Context &Ctx,
1514 const Twine &Name) {
1515 auto &Builder = Instruction::setInsertPos(Pos);
1516 llvm::Value *NewV =
1517 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1518 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1519 return Ctx.createInsertElementInst(NewInsert);
1520 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1521 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1522}
1523
1525 Context &Ctx, const Twine &Name) {
1526 auto &Builder = setInsertPos(Pos);
1527 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1528 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1529 return Ctx.createExtractElementInst(NewExtract);
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 =
1539 Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);
1540 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1541 return Ctx.createShuffleVectorInst(NewShuffle);
1542 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1543 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1544}
1545
1548 const Twine &Name) {
1549 auto &Builder = setInsertPos(Pos);
1550 llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
1551 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1552 return Ctx.createShuffleVectorInst(NewShuffle);
1553 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1554 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1555}
1556
1558 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1559 cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
1560}
1561
1563 return cast<VectorType>(
1564 Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
1565}
1566
1568 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1569 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
1570 getOperandUse(1));
1572}
1573
1578
1585
1589
1591 InsertPosition Pos, Context &Ctx,
1592 const Twine &Name) {
1593 auto &Builder = setInsertPos(Pos);
1594 llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
1595 if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
1596 return Ctx.createExtractValueInst(NewExtractValueInst);
1597 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1598 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1599}
1600
1602 auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
1603 return Agg->getContext().getType(LLVMTy);
1604}
1605
1607 InsertPosition Pos, Context &Ctx,
1608 const Twine &Name) {
1609 auto &Builder = setInsertPos(Pos);
1610 llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
1611 if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
1612 return Ctx.createInsertValueInst(NewInsertValueInst);
1613 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1614 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1615}
1616
1617ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
1618 auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
1619 return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
1620}
1621
1622} // namespace llvm::sandboxir
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXPORT_TEMPLATE
Definition Compiler.h:217
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)
void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
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
void setWeak(bool IsWeak)
void setFailureOrdering(AtomicOrdering Ordering)
Sets the failure ordering constraint of this cmpxchg instruction.
AtomicOrdering getFailureOrdering() const
Returns the failure ordering constraint of this cmpxchg instruction.
void setSuccessOrdering(AtomicOrdering Ordering)
Sets the success ordering constraint of this cmpxchg instruction.
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
AtomicOrdering getSuccessOrdering() const
Returns the success ordering constraint of this cmpxchg instruction.
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this rmw instruction.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this rmw instruction.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:459
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 ...
This class represents a function call, abstracting a target machine's calling convention.
BasicBlock * getSuccessor() const
void setSuccessor(BasicBlock *NewSucc)
Conditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned i) const
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 setSyncScopeID(SyncScope::ID SSID)
Sets the synchronization scope ID of this fence instruction.
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:2918
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.
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
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...
bool isCleanup() const
Return 'true' if this landingpad instruction is a cleanup.
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.
A handle to a particular switch case.
Multiway switch.
CaseIteratorImpl< ConstCaseHandle > ConstCaseIt
CaseIteratorImpl< CaseHandle > CaseIt
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
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:296
Unconditional Branch instruction.
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
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)
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="")
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
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.
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
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 LLVM_ABI 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
LLVM_ABI void setCondition(Value *V)
static LLVM_ABI ConstantTokenNone * get(Context &Ctx)
Return the ConstantTokenNone.
Type * getType(llvm::Type *LLVMTy)
Definition Context.h:257
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:71
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:313
This class can be used for tracking most instruction setters.
Definition Tracker.h:285
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="")
static LLVM_ABI Value * create(Value *Vec, Value *NewElt, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
const BBIterator & getIterator() const
Definition Instruction.h:36
BasicBlock * getBasicBlock() const
Definition Instruction.h:38
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.
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...
static LLVM_ABI IRBuilder & setInsertPos(InsertPosition Pos)
Helper function for create().
bool hasAllowReciprocal() const
Determine whether the allow-reciprocal flag is set.
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
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
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:450
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition Tracker.h:512
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition Tracker.h:488
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition Tracker.h:505
Just like llvm::Type these are immutable, unique, never get freed and can only be created via static ...
Definition Type.h:49
llvm::Type * LLVMTy
Definition Type.h:51
static LLVM_ABI IntegerType * getInt1Ty(Context &Ctx)
Definition Type.cpp:30
Context & getContext() const
Definition Type.h:100
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 LLVM_ABI 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:206
Represents a Def-use/Use-def edge in SandboxIR.
Definition Use.h:43
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:143
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:136
@ LLVMAtomicRMW
Definition Core.h:144
@ LLVMAtomicCmpXchg
Definition Core.h:143
@ LLVMSwitch
Definition Core.h:69
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool empty() const
Definition BasicBlock.h:101
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 void dumpOS(raw_ostream &OS) const final
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:408
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:1986
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:111