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 switch (Opc) {
16#define OP(OPC) \
17 case Opcode::OPC: \
18 return #OPC;
19#define OPCODES(...) __VA_ARGS__
20#define DEF_INSTR(ID, OPC, CLASS) OPC
21#include "llvm/SandboxIR/Values.def"
22 }
23 llvm_unreachable("Unknown Opcode");
24}
25
27 Instruction *Prev = getPrevNode();
28 if (Prev == nullptr) {
29 // If at top of the BB, return the first BB instruction.
30 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
31 }
32 // Else get the Previous sandbox IR instruction's bottom IR instruction and
33 // return its successor.
35 return PrevBotI->getNextNode();
36}
37
38BBIterator Instruction::getIterator() const {
40 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
41}
42
44 assert(getParent() != nullptr && "Detached!");
45 assert(getIterator() != getParent()->end() && "Already at end!");
46 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
47 // and get the corresponding sandboxir Instruction that maps to it. This works
48 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
49 auto *LLVMI = cast<llvm::Instruction>(Val);
50 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
51 auto *NextLLVMI = LLVMI->getNextNode();
52 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
53 if (NextI == nullptr)
54 return nullptr;
55 return NextI;
56}
57
59 assert(getParent() != nullptr && "Detached!");
60 auto It = getIterator();
61 if (It != getParent()->begin())
62 return std::prev(getIterator()).get();
63 return nullptr;
64}
65
67 Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
68
69 // Detach all the LLVM IR instructions from their parent BB.
71 I->removeFromParent();
72}
73
75 assert(users().empty() && "Still connected to users, can't erase!");
76
77 Ctx.runEraseInstrCallbacks(this);
78 std::unique_ptr<Value> Detached = Ctx.detach(this);
79 auto LLVMInstrs = getLLVMInstrs();
80
81 auto &Tracker = Ctx.getTracker();
82 if (Tracker.isTracking()) {
83 Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
84 // We don't actually delete the IR instruction, because then it would be
85 // impossible to bring it back from the dead at the same memory location.
86 // Instead we remove it from its BB and track its current location.
87 for (llvm::Instruction *I : LLVMInstrs)
88 I->removeFromParent();
89 // TODO: Multi-instructions need special treatment because some of the
90 // references are internal to the instruction.
91 for (llvm::Instruction *I : LLVMInstrs)
92 I->dropAllReferences();
93 } else {
94 // Erase in reverse to avoid erasing nstructions with attached uses.
95 for (llvm::Instruction *I : reverse(LLVMInstrs))
96 I->eraseFromParent();
97 }
98}
99
100void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
101 if (std::next(getIterator()) == WhereIt)
102 // Destination is same as origin, nothing to do.
103 return;
104
105 Ctx.runMoveInstrCallbacks(this, WhereIt);
106 Ctx.getTracker().emplaceIfTracking<MoveInstr>(this);
107
108 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
110 if (WhereIt == BB.end()) {
111 It = LLVMBB->end();
112 } else {
113 Instruction *WhereI = &*WhereIt;
114 It = WhereI->getTopmostLLVMInstruction()->getIterator();
115 }
116 // TODO: Move this to the verifier of sandboxir::Instruction.
118 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
119 "Expected program order!");
120 // Do the actual move in LLVM IR.
121 for (auto *I : getLLVMInstrs())
122 I->moveBefore(*LLVMBB, It);
123}
124
126 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
127
128 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
129
130 // Insert the LLVM IR Instructions in program order.
132 I->insertBefore(BeforeTopI->getIterator());
133}
134
136 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
138
139void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
140 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
141 llvm::Instruction *LLVMBeforeI;
142 llvm::BasicBlock::iterator LLVMBeforeIt;
143 Instruction *BeforeI;
144 if (WhereIt != BB->end()) {
145 BeforeI = &*WhereIt;
146 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
147 LLVMBeforeIt = LLVMBeforeI->getIterator();
148 } else {
149 BeforeI = nullptr;
150 LLVMBeforeI = nullptr;
151 LLVMBeforeIt = LLVMBB->end();
152 }
153
154 Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
155
156 // Insert the LLVM IR Instructions in program order.
158 I->insertInto(LLVMBB, LLVMBeforeIt);
159}
160
162 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
163 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
165 if (BB == nullptr)
166 return nullptr;
167 return cast<BasicBlock>(Ctx.getValue(BB));
168}
169
171 switch (From->getSubclassID()) {
172#define DEF_INSTR(ID, OPC, CLASS) \
173 case ClassID::ID: \
174 return true;
175#include "llvm/SandboxIR/Values.def"
176 default:
177 return false;
178 }
179}
180
182 Ctx.getTracker()
185 this);
186 cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
187}
190 Ctx.getTracker()
193 cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
194}
195
197 Ctx.getTracker()
198 .emplaceIfTracking<
199 GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this);
201}
202
204 Ctx.getTracker()
205 .emplaceIfTracking<
207 cast<llvm::Instruction>(Val)->setIsExact(B);
209
211 Ctx.getTracker()
214 cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
216
218 Ctx.getTracker()
219 .emplaceIfTracking<
221 this);
222 cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
224
226 Ctx.getTracker()
227 .emplaceIfTracking<
228 GenericSetter<&Instruction::hasNoInfs, &Instruction::setHasNoInfs>>(
229 this);
230 cast<llvm::Instruction>(Val)->setHasNoInfs(B);
231}
232
234 Ctx.getTracker()
237 this);
238 cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
239}
240
242 Ctx.getTracker()
245 this);
246 cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
247}
248
250 Ctx.getTracker()
253 this);
254 cast<llvm::Instruction>(Val)->setHasAllowContract(B);
255}
256
258 Ctx.getTracker()
261 cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
262}
263
265 Ctx.getTracker()
266 .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
268 cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
269}
270
274
276 Ctx.getTracker()
277 .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
279 cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
280}
281
282#ifndef NDEBUG
284 OS << "Unimplemented! Please override dump().";
285}
286#endif // NDEBUG
287
289 Context &Ctx, const Twine &Name) {
290 auto &Builder = setInsertPos(Pos);
291 auto *LLVMI =
292 cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name));
293 return Ctx.createVAArgInst(LLVMI);
295
299
300FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx,
301 const Twine &Name) {
302 auto &Builder = setInsertPos(Pos);
303 auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name));
304 return Ctx.createFreezeInst(LLVMI);
305}
306
308 Context &Ctx, SyncScope::ID SSID) {
309 auto &Builder = Instruction::setInsertPos(Pos);
310 llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
311 return Ctx.createFenceInst(LLVMI);
312}
313
315 Ctx.getTracker()
316 .emplaceIfTracking<
318 this);
319 cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
320}
321
323 Ctx.getTracker()
324 .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
326 cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
327}
328
330 InsertPosition Pos, Context &Ctx, const Twine &Name) {
331 auto &Builder = Instruction::setInsertPos(Pos);
332 llvm::Value *NewV =
333 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
334 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
335 return Ctx.createSelectInst(NewSI);
336 assert(isa<llvm::Constant>(NewV) && "Expected constant");
337 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
338}
339
341 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
343 cast<llvm::SelectInst>(Val)->swapValues();
344}
345
346bool SelectInst::classof(const Value *From) {
347 return From->getSubclassID() == ClassID::Select;
348}
349
350BasicBlock *BrInstCommon::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
351 return cast<BasicBlock>(Ctx.getValue(BB));
352}
353const BasicBlock *
354BrInstCommon::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
355 return cast<BasicBlock>(Ctx.getValue(BB));
357
359 InsertPosition InsertBefore, Context &Ctx) {
360 auto &Builder = setInsertPos(InsertBefore);
361 llvm::UncondBrInst *NewUBr =
362 Builder.CreateBr(cast<llvm::BasicBlock>(Target->Val));
363 return Ctx.createUncondBrInst(NewUBr);
364}
365
368 Ctx.getValue(cast<llvm::UncondBrInst>(Val)->getSuccessor()));
369}
370
372 Ctx.getTracker()
373 .emplaceIfTracking<GenericSetter<&UncondBrInst::getSuccessor,
375 cast<llvm::UncondBrInst>(Val)->setSuccessor(
376 0, cast<llvm::BasicBlock>(NewSucc->Val));
377}
378
379bool UncondBrInst::classof(const Value *From) {
380 return From->getSubclassID() == ClassID::UncondBr;
381}
382
384 BasicBlock *IfFalse, InsertPosition InsertBefore,
385 Context &Ctx) {
386 auto &Builder = setInsertPos(InsertBefore);
387 llvm::CondBrInst *NewCBr = Builder.CreateCondBr(
389 cast<llvm::BasicBlock>(IfFalse->Val));
390 return Ctx.createCondBrInst(NewCBr);
392
395 "Cannot get condition of an uncond branch!");
396 return Ctx.getValue(cast<llvm::CondBrInst>(Val)->getCondition());
397}
399 Ctx.getTracker()
400 .emplaceIfTracking<
402 this);
403 llvm::Value *LLVMV = V->Val;
404 cast<llvm::CondBrInst>(Val)->setCondition(LLVMV);
406
407BasicBlock *CondBrInst::getSuccessor(unsigned SuccIdx) const {
408 assert(SuccIdx < getNumSuccessors() &&
409 "Successor # out of range for Branch!");
411 Ctx.getValue(cast<llvm::CondBrInst>(Val)->getSuccessor(SuccIdx)));
412}
413
414void CondBrInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
415 assert(Idx < getNumSuccessors() && "Out of bounds!");
416 Ctx.getTracker()
417 .emplaceIfTracking<GenericSetterWithIdx<&CondBrInst::getSuccessor,
419 Idx);
420 cast<llvm::CondBrInst>(Val)->setSuccessor(
421 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
423
424bool CondBrInst::classof(const Value *From) {
425 return From->getSubclassID() == ClassID::CondBr;
426}
427
429 Ctx.getTracker()
430 .emplaceIfTracking<
431 GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this);
432 cast<llvm::LoadInst>(Val)->setVolatile(V);
433}
436 InsertPosition Pos, bool IsVolatile, Context &Ctx,
437 const Twine &Name) {
438 auto &Builder = setInsertPos(Pos);
439 auto *NewLI =
440 Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
441 auto *NewSBI = Ctx.createLoadInst(NewLI);
442 return NewSBI;
443}
444
445bool LoadInst::classof(const Value *From) {
446 return From->getSubclassID() == ClassID::Load;
447}
448
452
454 Ctx.getTracker()
455 .emplaceIfTracking<
457 cast<llvm::StoreInst>(Val)->setVolatile(V);
458}
459
461 InsertPosition Pos, bool IsVolatile,
462 Context &Ctx) {
463 auto &Builder = setInsertPos(Pos);
464 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
465 auto *NewSBI = Ctx.createStoreInst(NewSI);
466 return NewSBI;
467}
468
469bool StoreInst::classof(const Value *From) {
470 return From->getSubclassID() == ClassID::Store;
471}
472
476
480
481UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
482 auto &Builder = setInsertPos(Pos);
483 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
484 return Ctx.createUnreachableInst(NewUI);
485}
486
488 return From->getSubclassID() == ClassID::Unreachable;
489}
490
491ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
492 Context &Ctx) {
493 llvm::ReturnInst *NewRI;
494 if (RetVal != nullptr)
495 NewRI = Builder.CreateRet(RetVal->Val);
496 else
497 NewRI = Builder.CreateRetVoid();
498 return Ctx.createReturnInst(NewRI);
500
501ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
502 Context &Ctx) {
503 auto &Builder = setInsertPos(Pos);
504 return createCommon(RetVal, Builder, Ctx);
505}
506
508 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
509 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
510}
511
513 return cast<FunctionType>(
514 Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
515}
516
520
522 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
523 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
524}
525
528 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
529}
531 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
533
535 // F's function type is private, so we rely on `setCalledFunction()` to update
536 // it. But even though we are calling `setCalledFunction()` we also need to
537 // track this change at the SandboxIR level, which is why we call
538 // `setCalledOperand()` here.
539 // Note: This may break if `setCalledFunction()` early returns if `F`
540 // is already set, but we do have a unit test for it.
542 cast<llvm::CallBase>(Val)->setCalledFunction(
543 cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
544 cast<llvm::Function>(F->Val));
545}
546
547CallInst *CallInst::create(FunctionType *FTy, Value *Func,
549 Context &Ctx, const Twine &NameStr) {
550 auto &Builder = setInsertPos(Pos);
552 LLVMArgs.reserve(Args.size());
553 for (Value *Arg : Args)
554 LLVMArgs.push_back(Arg->Val);
555 llvm::CallInst *NewCI = Builder.CreateCall(
556 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
557 return Ctx.createCallInst(NewCI);
558}
559
560InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
561 BasicBlock *IfNormal, BasicBlock *IfException,
563 Context &Ctx, const Twine &NameStr) {
564 auto &Builder = setInsertPos(Pos);
566 LLVMArgs.reserve(Args.size());
567 for (Value *Arg : Args)
568 LLVMArgs.push_back(Arg->Val);
569 llvm::InvokeInst *Invoke = Builder.CreateInvoke(
570 cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
571 cast<llvm::BasicBlock>(IfNormal->Val),
572 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
573 return Ctx.createInvokeInst(Invoke);
574}
575
577 return cast<BasicBlock>(
578 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
579}
581 return cast<BasicBlock>(
582 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
583}
585 setOperand(1, BB);
586 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
587}
589 setOperand(2, BB);
590 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
591}
594 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
595 ;
596}
597BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
598 return cast<BasicBlock>(
599 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
600}
601
602CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
603 BasicBlock *DefaultDest,
606 Context &Ctx, const Twine &NameStr) {
607 auto &Builder = setInsertPos(Pos);
609 LLVMIndirectDests.reserve(IndirectDests.size());
610 for (BasicBlock *IndDest : IndirectDests)
611 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
612
614 LLVMArgs.reserve(Args.size());
615 for (Value *Arg : Args)
616 LLVMArgs.push_back(Arg->Val);
617
619 Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
620 cast<llvm::BasicBlock>(DefaultDest->Val),
621 LLVMIndirectDests, LLVMArgs, NameStr);
622 return Ctx.createCallBrInst(CallBr);
624
626 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
627}
629 return Ctx.getValue(
631}
634 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
635}
637 return cast<BasicBlock>(
638 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
639}
642 for (llvm::BasicBlock *LLVMBB :
643 cast<llvm::CallBrInst>(Val)->getIndirectDests())
644 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
645 return BBs;
646}
648 Ctx.getTracker()
649 .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
651 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
652}
654 Ctx.getTracker()
655 .emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest,
657 this, Idx);
658 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
659 cast<llvm::BasicBlock>(BB->Val));
660}
662 return cast<BasicBlock>(
663 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
664}
665
666LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
668 const Twine &Name) {
669 auto &Builder = setInsertPos(Pos);
670 llvm::LandingPadInst *LLVMI =
671 Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
672 return Ctx.createLandingPadInst(LLVMI);
674
676 Ctx.getTracker()
677 .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
679 cast<llvm::LandingPadInst>(Val)->setCleanup(V);
680}
681
684 Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
685}
686
688 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());
689}
690
692 Ctx.getTracker()
693 .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
695 cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
696}
697
699 return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
700}
701
702void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
703 Ctx.getTracker()
704 .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
706 this, Idx);
707 cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
708}
709
712 Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch()));
713}
714
715CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
717 const Twine &Name) {
718 auto &Builder = setInsertPos(Pos);
720 LLVMArgs.reserve(Args.size());
721 for (auto *Arg : Args)
722 LLVMArgs.push_back(Arg->Val);
723 llvm::CatchPadInst *LLVMI =
724 Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
725 return Ctx.createCatchPadInst(LLVMI);
726}
727
728CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
730 const Twine &Name) {
731 auto &Builder = setInsertPos(Pos);
733 LLVMArgs.reserve(Args.size());
734 for (auto *Arg : Args)
735 LLVMArgs.push_back(Arg->Val);
736 llvm::CleanupPadInst *LLVMI =
737 Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
738 return Ctx.createCleanupPadInst(LLVMI);
739}
740
741CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
742 InsertPosition Pos, Context &Ctx) {
743 auto &Builder = setInsertPos(Pos);
744 llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
746 return Ctx.createCatchReturnInst(LLVMI);
747}
748
750 return cast<CatchPadInst>(
751 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
752}
753
755 Ctx.getTracker()
758 cast<llvm::CatchReturnInst>(Val)->setCatchPad(
759 cast<llvm::CatchPadInst>(CatchPad->Val));
760}
761
763 return cast<BasicBlock>(
764 Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
765}
766
768 Ctx.getTracker()
771 cast<llvm::CatchReturnInst>(Val)->setSuccessor(
772 cast<llvm::BasicBlock>(NewSucc->Val));
773}
774
779
780CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
781 BasicBlock *UnwindBB,
782 InsertPosition Pos, Context &Ctx) {
783 auto &Builder = setInsertPos(Pos);
784 auto *LLVMUnwindBB =
785 UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
786 llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
787 cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
788 return Ctx.createCleanupReturnInst(LLVMI);
789}
790
795
797 Ctx.getTracker()
798 .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
800 this);
801 cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
802 cast<llvm::CleanupPadInst>(CleanupPad->Val));
803}
804
809
811 Ctx.getTracker()
814 this);
815 cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
816 cast<llvm::BasicBlock>(NewDest->Val));
817}
818
821 Context &Ctx, const Twine &NameStr) {
822 auto &Builder = setInsertPos(Pos);
823 SmallVector<llvm::Value *> LLVMIdxList;
824 LLVMIdxList.reserve(IdxList.size());
825 for (Value *Idx : IdxList)
826 LLVMIdxList.push_back(Idx->Val);
827 llvm::Value *NewV =
828 Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
829 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
830 return Ctx.createGetElementPtrInst(NewGEP);
831 assert(isa<llvm::Constant>(NewV) && "Expected constant");
832 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
833}
834
839
844
848
853
854BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
855 return cast<BasicBlock>(Ctx.getValue(LLVMBB));
856}
857
858PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
859 InsertPosition Pos, Context &Ctx, const Twine &Name) {
860 auto &Builder = setInsertPos(Pos);
861 llvm::PHINode *NewPHI =
862 Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
863 return Ctx.createPHINode(NewPHI);
864}
865
866bool PHINode::classof(const Value *From) {
867 return From->getSubclassID() == ClassID::PHI;
868}
869
870Value *PHINode::getIncomingValue(unsigned Idx) const {
871 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
872}
873void PHINode::setIncomingValue(unsigned Idx, Value *V) {
874 Ctx.getTracker()
877 Idx);
878 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
879}
881 return cast<BasicBlock>(
882 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
883}
885 llvm::Use *LLVMUse = U.LLVMUse;
886 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
887 return cast<BasicBlock>(Ctx.getValue(BB));
888}
889void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
890 // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
891 constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
893 Ctx.getTracker()
894 .emplaceIfTracking<
896 this, Idx);
897 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
898 cast<llvm::BasicBlock>(BB->Val));
899}
901 auto &Tracker = Ctx.getTracker();
903
904 cast<llvm::PHINode>(Val)->addIncoming(V->Val,
905 cast<llvm::BasicBlock>(BB->Val));
906}
908 auto &Tracker = Ctx.getTracker();
910 llvm::Value *LLVMV =
911 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
912 /*DeletePHIIfEmpty=*/false);
913 return Ctx.getValue(LLVMV);
914}
916 auto &Tracker = Ctx.getTracker();
918
919 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
920 llvm::Value *LLVMV =
921 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
922 /*DeletePHIIfEmpty=*/false);
923 return Ctx.getValue(LLVMV);
924}
926 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
927 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
928}
930 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
931 llvm::Value *LLVMV =
932 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
933 return Ctx.getValue(LLVMV);
934}
936 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
937 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
938}
940 assert(New && Old && "Sandbox IR PHI node got a null basic block!");
941 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
942 Idx != NumOps; ++Idx)
943 if (getIncomingBlock(Idx) == Old)
944 setIncomingBlock(Idx, New);
945}
946void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
947 // Avoid duplicate tracking by going through this->removeIncomingValue here at
948 // the expense of some performance. Copy PHI::removeIncomingValueIf more
949 // directly if performance becomes an issue.
950
951 // Removing the element at index X, moves the element previously at X + 1
952 // to X. Working from the end avoids complications from that.
953 unsigned Idx = getNumIncomingValues();
954 while (Idx > 0) {
955 if (Predicate(Idx - 1))
956 removeIncomingValue(Idx - 1);
957 --Idx;
958 }
959}
960
962 Context &Ctx, const Twine &Name) {
963 auto &Builder = setInsertPos(Pos);
964 auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
965 // It may have been folded into a constant.
966 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
967 return Ctx.getOrCreateConstant(LLVMC);
968 if (isa<llvm::ICmpInst>(LLVMV))
969 return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
970 return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
971}
972
974 const Instruction *F, InsertPosition Pos,
975 Context &Ctx, const Twine &Name) {
976 Value *V = create(P, S1, S2, Pos, Ctx, Name);
977 if (auto *C = dyn_cast<Constant>(V))
978 return C;
979 cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
980 return V;
981}
982
984 if (auto *VT = dyn_cast<VectorType>(OpndType)) {
985 // TODO: Cleanup when we have more complete support for
986 // sandboxir::VectorType
987 return OpndType->getContext().getType(llvm::VectorType::get(
989 cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
990 }
991 return Type::getInt1Ty(OpndType->getContext());
992}
993
995 Ctx.getTracker()
996 .emplaceIfTracking<
998 cast<llvm::CmpInst>(Val)->setPredicate(P);
999}
1000
1002 if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
1003 IC->swapOperands();
1004 else
1005 cast<FCmpInst>(this)->swapOperands();
1007
1009 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
1010 cast<llvm::ICmpInst>(Val)->swapOperands();
1011}
1012
1014 Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
1015 cast<llvm::FCmpInst>(Val)->swapOperands();
1016}
1017
1018#ifndef NDEBUG
1020 dumpCommonPrefix(OS);
1021 dumpCommonSuffix(OS);
1022}
1023
1024void CmpInst::dump() const {
1025 dumpOS(dbgs());
1026 dbgs() << "\n";
1027}
1028#endif // NDEBUG
1029
1031 switch (Opc) {
1032 case Instruction::Opcode::ZExt:
1033 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1034 case Instruction::Opcode::SExt:
1035 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1036 case Instruction::Opcode::FPToUI:
1037 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1038 case Instruction::Opcode::FPToSI:
1039 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1040 case Instruction::Opcode::FPExt:
1041 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1042 case Instruction::Opcode::PtrToAddr:
1043 return static_cast<llvm::Instruction::CastOps>(
1044 llvm::Instruction::PtrToAddr);
1045 case Instruction::Opcode::PtrToInt:
1046 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1047 case Instruction::Opcode::IntToPtr:
1048 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1049 case Instruction::Opcode::SIToFP:
1050 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1051 case Instruction::Opcode::UIToFP:
1052 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1053 case Instruction::Opcode::Trunc:
1054 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1055 case Instruction::Opcode::FPTrunc:
1056 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1057 case Instruction::Opcode::BitCast:
1058 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1059 case Instruction::Opcode::AddrSpaceCast:
1060 return static_cast<llvm::Instruction::CastOps>(
1061 llvm::Instruction::AddrSpaceCast);
1062 default:
1063 llvm_unreachable("Opcode not suitable for CastInst!");
1064 }
1065}
1066
1067/// \Returns the LLVM opcode that corresponds to \p Opc.
1069 switch (Opc) {
1070 case Instruction::Opcode::FNeg:
1071 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1072 default:
1073 llvm_unreachable("Not a unary op!");
1074 }
1075}
1076
1077CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
1078 unsigned NumHandlers,
1080 const Twine &Name) {
1081 auto &Builder = setInsertPos(Pos);
1082 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1083 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1084 return Ctx.createCatchSwitchInst(LLVMCSI);
1085}
1086
1088 return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
1090
1092 Ctx.getTracker()
1093 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
1095 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1096}
1097
1100 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1101}
1102
1104 Ctx.getTracker()
1105 .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest,
1107 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1108 cast<llvm::BasicBlock>(UnwindDest->Val));
1109}
1110
1112 Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
1113 cast<llvm::CatchSwitchInst>(Val)->addHandler(
1114 cast<llvm::BasicBlock>(Dest->Val));
1115}
1118 auto &Builder = setInsertPos(Pos);
1119 auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1120 return Ctx.createResumeInst(LLVMI);
1121}
1122
1124 return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1125}
1126
1127SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1128 InsertPosition Pos, Context &Ctx,
1129 const Twine &Name) {
1130 auto &Builder = setInsertPos(Pos);
1132 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1133 return Ctx.createSwitchInst(LLVMSwitch);
1134}
1135
1137 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1138}
1139
1141 Ctx.getTracker()
1142 .emplaceIfTracking<
1144 this);
1145 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1146}
1147
1149 return cast<BasicBlock>(
1150 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1151}
1152
1154 Ctx.getTracker()
1155 .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
1157 cast<llvm::SwitchInst>(Val)->setDefaultDest(
1158 cast<llvm::BasicBlock>(DefaultCase->Val));
1159}
1160
1161template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1162ConstT *
1164 const auto &LLVMCaseHandle = *LLVMCaseIt;
1165 auto *LLVMC = Ctx.getValue(LLVMCaseHandle.getCaseValue());
1166 return cast<ConstT>(LLVMC);
1167}
1168
1169template <typename LLVMCaseItT, typename BlockT, typename ConstT>
1170BlockT *
1172 const {
1173 const auto &LLVMCaseHandle = *LLVMCaseIt;
1174 auto *LLVMBB = LLVMCaseHandle.getCaseSuccessor();
1175 return cast<BlockT>(Ctx.getValue(LLVMBB));
1176}
1177
1179 ConstantInt>;
1181 ConstantInt>;
1183 const BasicBlock, const ConstantInt>;
1185 const BasicBlock, const ConstantInt>;
1186
1188 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1189 cast<llvm::BasicBlock>(BB->Val));
1190 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1191}
1192
1194 Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
1195 // TODO: Track this!
1197 cast<llvm::BasicBlock>(Dest->Val));
1198}
1199
1201 Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
1202
1204 unsigned CaseNum = It - case_begin();
1205 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1206 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1207 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1208 return CaseIt(this, Num);
1209}
1210
1212 return cast<BasicBlock>(
1213 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1214}
1215
1216void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1217 Ctx.getTracker()
1218 .emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor,
1220 Idx);
1221 cast<llvm::SwitchInst>(Val)->setSuccessor(
1222 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1223}
1224
1226 InsertPosition Pos, Context &Ctx,
1227 const Twine &Name) {
1228 auto &Builder = setInsertPos(Pos);
1229 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1230 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1231 return Ctx.createUnaryOperator(NewUnOpV);
1232 }
1233 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1234 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1235}
1236
1238 Value *CopyFrom, InsertPosition Pos,
1239 Context &Ctx, const Twine &Name) {
1240 auto *NewV = create(Op, OpV, Pos, Ctx, Name);
1241 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1242 UnI->copyIRFlags(CopyFrom->Val);
1243 return NewV;
1244}
1245
1246/// \Returns the LLVM opcode that corresponds to \p Opc.
1248 switch (Opc) {
1249 case Instruction::Opcode::Add:
1250 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1251 case Instruction::Opcode::FAdd:
1252 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1253 case Instruction::Opcode::Sub:
1254 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1255 case Instruction::Opcode::FSub:
1256 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1257 case Instruction::Opcode::Mul:
1258 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1259 case Instruction::Opcode::FMul:
1260 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1261 case Instruction::Opcode::UDiv:
1262 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1263 case Instruction::Opcode::SDiv:
1264 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1265 case Instruction::Opcode::FDiv:
1266 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1267 case Instruction::Opcode::URem:
1268 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1269 case Instruction::Opcode::SRem:
1270 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1271 case Instruction::Opcode::FRem:
1272 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1273 case Instruction::Opcode::Shl:
1274 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1275 case Instruction::Opcode::LShr:
1276 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1277 case Instruction::Opcode::AShr:
1278 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1279 case Instruction::Opcode::And:
1280 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1281 case Instruction::Opcode::Or:
1282 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1283 case Instruction::Opcode::Xor:
1284 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1285 default:
1286 llvm_unreachable("Not a binary op!");
1288}
1291 const Twine &Name) {
1292 auto &Builder = setInsertPos(Pos);
1293 llvm::Value *NewV =
1294 Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
1295 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1296 return Ctx.createBinaryOperator(NewBinOp);
1297 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1298 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1299}
1300
1302 Value *RHS, Value *CopyFrom,
1304 const Twine &Name) {
1306 Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
1307 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1308 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1309 return NewV;
1310}
1311
1313 Ctx.getTracker()
1314 .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,
1316 this);
1317 cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
1318}
1321 Ctx.getTracker()
1322 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
1324 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1325}
1326
1328 Ctx.getTracker()
1329 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
1331 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1332}
1333
1335 Ctx.getTracker()
1336 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
1338 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1339}
1340
1342 Ctx.getTracker()
1343 .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,
1345 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1346}
1347
1351
1355
1359 SyncScope::ID SSID, const Twine &Name) {
1360 auto &Builder = setInsertPos(Pos);
1361 auto *LLVMAtomicRMW =
1362 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1363 LLVMAtomicRMW->setName(Name);
1364 return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
1365}
1366
1368 Ctx.getTracker()
1369 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
1371 this);
1372 cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1373}
1374
1378
1382
1386
1389 AtomicOrdering SuccessOrdering,
1390 AtomicOrdering FailureOrdering, InsertPosition Pos,
1391 Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
1392 auto &Builder = setInsertPos(Pos);
1393 auto *LLVMAtomicCmpXchg =
1394 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1395 SuccessOrdering, FailureOrdering, SSID);
1396 LLVMAtomicCmpXchg->setName(Name);
1397 return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1398}
1399
1401 Ctx.getTracker()
1402 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1404 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1405}
1406
1408 Ctx.getTracker()
1409 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1411 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1412}
1413
1415 Ctx.getTracker()
1416 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1418 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1419}
1420
1422 Ctx.getTracker()
1423 .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1425 this);
1426 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1427}
1428
1430 Ctx.getTracker()
1433 this);
1434 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1435}
1436
1437AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
1438 Context &Ctx, Value *ArraySize,
1439 const Twine &Name) {
1440 auto &Builder = setInsertPos(Pos);
1441 auto *NewAlloca =
1442 Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
1443 return Ctx.createAllocaInst(NewAlloca);
1444}
1445
1449
1451 Ctx.getTracker()
1452 .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
1454 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
1455}
1456
1458 Ctx.getTracker()
1459 .emplaceIfTracking<
1461 this);
1462 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1463}
1464
1466 Ctx.getTracker()
1469 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1470}
1471
1475
1477 return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
1478}
1479
1481 InsertPosition Pos, Context &Ctx, const Twine &Name) {
1482 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1483 auto &Builder = setInsertPos(Pos);
1484 auto *NewV =
1485 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
1486 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1487 return Ctx.createCastInst(NewCI);
1488 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1489 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1490}
1491
1492bool CastInst::classof(const Value *From) {
1493 return From->getSubclassID() == ClassID::Cast;
1494}
1495
1497 return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
1498}
1499
1501 return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
1502}
1503
1505 Ctx.getTracker()
1506 .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1509}
1510
1513 const Twine &Name) {
1514 auto &Builder = Instruction::setInsertPos(Pos);
1515 llvm::Value *NewV =
1516 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1517 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1518 return Ctx.createInsertElementInst(NewInsert);
1519 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1520 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1521}
1522
1524 Context &Ctx, const Twine &Name) {
1525 auto &Builder = setInsertPos(Pos);
1526 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1527 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1528 return Ctx.createExtractElementInst(NewExtract);
1529 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1530 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1531}
1532
1535 const Twine &Name) {
1536 auto &Builder = setInsertPos(Pos);
1537 llvm::Value *NewV =
1538 Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, 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
1547 const Twine &Name) {
1548 auto &Builder = setInsertPos(Pos);
1549 llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
1550 if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1551 return Ctx.createShuffleVectorInst(NewShuffle);
1552 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1553 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1554}
1555
1557 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1558 cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
1559}
1560
1562 return cast<VectorType>(
1563 Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
1564}
1565
1567 Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1568 Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
1569 getOperandUse(1));
1571}
1572
1577
1584
1588
1590 InsertPosition Pos, Context &Ctx,
1591 const Twine &Name) {
1592 auto &Builder = setInsertPos(Pos);
1593 llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
1594 if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
1595 return Ctx.createExtractValueInst(NewExtractValueInst);
1596 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1597 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1598}
1599
1601 auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
1602 return Agg->getContext().getType(LLVMTy);
1603}
1604
1606 InsertPosition Pos, Context &Ctx,
1607 const Twine &Name) {
1608 auto &Builder = setInsertPos(Pos);
1609 llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
1610 if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
1611 return Ctx.createInsertValueInst(NewInsertValueInst);
1612 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1613 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1614}
1615
1616ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
1617 auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
1618 return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
1619}
1620
1621} // 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)
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)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
void setSyncScopeID(SyncScope::ID SSID)
Sets the synchronization scope ID of this cmpxchg instruction.
void setSuccessOrdering(AtomicOrdering Ordering)
Sets the success ordering constraint of this cmpxchg instruction.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
void setAlignment(Align Align)
AtomicOrdering getSuccessOrdering() const
Returns the success ordering constraint of this cmpxchg instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this cmpxchg instruction.
void setSyncScopeID(SyncScope::ID SSID)
Sets the synchronization scope ID of this rmw instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this rmw instruction.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:462
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.
void setUnwindDest(BasicBlock *UnwindDest)
BasicBlock * getUnwindDest() const
CleanupPadInst * getCleanupPad() const
Convenience accessor.
void setCleanupPad(CleanupPadInst *CleanupPad)
Conditional Branch instruction.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
BasicBlock * getSuccessor(unsigned i) const
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:2811
LLVM_ABI void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
Instruction(const Instruction &)=delete
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.
CaseIteratorImpl< ConstCaseHandle > ConstCaseIt
BasicBlock * getSuccessor(unsigned idx) const
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:310
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
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="")
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
LLVM_ABI void setSyncScopeID(SyncScope::ID SSID)
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)
LLVM_ABI void setVolatile(bool V)
AtomicOrdering getOrdering() const
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="")
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...
bool hasAllowReassoc() const
Determine whether the allow-reassociation flag is set.
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.
const char * getOpcodeName() const
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:53
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...
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
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 emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition Tracker.h:500
Just like llvm::Type these are immutable, unique, never get freed and can only be created via static ...
Definition Type.h:47
llvm::Type * LLVMTy
Definition Type.h:49
static LLVM_ABI IntegerType * getInt1Ty(Context &Ctx)
Definition Type.cpp:30
Context & getContext() const
Definition Type.h:94
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:91
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:68
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
Definition Value.h:108
ClassID getSubclassID() const
Definition Value.h:194
void dumpCommonSuffix(raw_ostream &OS) const
Definition Value.cpp:107
Context & Ctx
All values point to the context.
Definition Value.h:182
iterator_range< user_iterator > users()
Definition Value.h:234
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:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
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:1970
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