Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/SandboxIR/Instruction.cpp
213766 views
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
9
#include "llvm/SandboxIR/Instruction.h"
10
#include "llvm/SandboxIR/Function.h"
11
12
namespace llvm::sandboxir {
13
14
const char *Instruction::getOpcodeName(Opcode Opc) {
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
26
llvm::Instruction *Instruction::getTopmostLLVMInstruction() const {
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.
34
llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
35
return PrevBotI->getNextNode();
36
}
37
38
BBIterator Instruction::getIterator() const {
39
auto *I = cast<llvm::Instruction>(Val);
40
return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
41
}
42
43
Instruction *Instruction::getNextNode() const {
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
58
Instruction *Instruction::getPrevNode() const {
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
66
void Instruction::removeFromParent() {
67
Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
68
69
// Detach all the LLVM IR instructions from their parent BB.
70
for (llvm::Instruction *I : getLLVMInstrs())
71
I->removeFromParent();
72
}
73
74
void Instruction::eraseFromParent() {
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
100
void 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);
109
llvm::BasicBlock::iterator It;
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.
117
assert(is_sorted(getLLVMInstrs(),
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
125
void Instruction::insertBefore(Instruction *BeforeI) {
126
llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
127
128
Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
129
130
// Insert the LLVM IR Instructions in program order.
131
for (llvm::Instruction *I : getLLVMInstrs())
132
I->insertBefore(BeforeTopI->getIterator());
133
}
134
135
void Instruction::insertAfter(Instruction *AfterI) {
136
insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
137
}
138
139
void 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.
157
for (llvm::Instruction *I : getLLVMInstrs())
158
I->insertInto(LLVMBB, LLVMBeforeIt);
159
}
160
161
BasicBlock *Instruction::getParent() const {
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.
164
auto *BB = cast<llvm::Instruction>(Val)->getParent();
165
if (BB == nullptr)
166
return nullptr;
167
return cast<BasicBlock>(Ctx.getValue(BB));
168
}
169
170
bool Instruction::classof(const sandboxir::Value *From) {
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
181
void Instruction::setHasNoUnsignedWrap(bool B) {
182
Ctx.getTracker()
183
.emplaceIfTracking<GenericSetter<&Instruction::hasNoUnsignedWrap,
184
&Instruction::setHasNoUnsignedWrap>>(
185
this);
186
cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
187
}
188
189
void Instruction::setHasNoSignedWrap(bool B) {
190
Ctx.getTracker()
191
.emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedWrap,
192
&Instruction::setHasNoSignedWrap>>(this);
193
cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
194
}
195
196
void Instruction::setFast(bool B) {
197
Ctx.getTracker()
198
.emplaceIfTracking<
199
GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this);
200
cast<llvm::Instruction>(Val)->setFast(B);
201
}
202
203
void Instruction::setIsExact(bool B) {
204
Ctx.getTracker()
205
.emplaceIfTracking<
206
GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this);
207
cast<llvm::Instruction>(Val)->setIsExact(B);
208
}
209
210
void Instruction::setHasAllowReassoc(bool B) {
211
Ctx.getTracker()
212
.emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc,
213
&Instruction::setHasAllowReassoc>>(this);
214
cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
215
}
216
217
void Instruction::setHasNoNaNs(bool B) {
218
Ctx.getTracker()
219
.emplaceIfTracking<
220
GenericSetter<&Instruction::hasNoNaNs, &Instruction::setHasNoNaNs>>(
221
this);
222
cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
223
}
224
225
void Instruction::setHasNoInfs(bool B) {
226
Ctx.getTracker()
227
.emplaceIfTracking<
228
GenericSetter<&Instruction::hasNoInfs, &Instruction::setHasNoInfs>>(
229
this);
230
cast<llvm::Instruction>(Val)->setHasNoInfs(B);
231
}
232
233
void Instruction::setHasNoSignedZeros(bool B) {
234
Ctx.getTracker()
235
.emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedZeros,
236
&Instruction::setHasNoSignedZeros>>(
237
this);
238
cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
239
}
240
241
void Instruction::setHasAllowReciprocal(bool B) {
242
Ctx.getTracker()
243
.emplaceIfTracking<GenericSetter<&Instruction::hasAllowReciprocal,
244
&Instruction::setHasAllowReciprocal>>(
245
this);
246
cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
247
}
248
249
void Instruction::setHasAllowContract(bool B) {
250
Ctx.getTracker()
251
.emplaceIfTracking<GenericSetter<&Instruction::hasAllowContract,
252
&Instruction::setHasAllowContract>>(
253
this);
254
cast<llvm::Instruction>(Val)->setHasAllowContract(B);
255
}
256
257
void Instruction::setFastMathFlags(FastMathFlags FMF) {
258
Ctx.getTracker()
259
.emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
260
&Instruction::copyFastMathFlags>>(this);
261
cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
262
}
263
264
void Instruction::copyFastMathFlags(FastMathFlags FMF) {
265
Ctx.getTracker()
266
.emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
267
&Instruction::copyFastMathFlags>>(this);
268
cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
269
}
270
271
Type *Instruction::getAccessType() const {
272
return Ctx.getType(cast<llvm::Instruction>(Val)->getAccessType());
273
}
274
275
void Instruction::setHasApproxFunc(bool B) {
276
Ctx.getTracker()
277
.emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
278
&Instruction::setHasApproxFunc>>(this);
279
cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
280
}
281
282
#ifndef NDEBUG
283
void Instruction::dumpOS(raw_ostream &OS) const {
284
OS << "Unimplemented! Please override dump().";
285
}
286
#endif // NDEBUG
287
288
VAArgInst *VAArgInst::create(Value *List, Type *Ty, InsertPosition Pos,
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);
294
}
295
296
Value *VAArgInst::getPointerOperand() {
297
return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());
298
}
299
300
FreezeInst *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
307
FenceInst *FenceInst::create(AtomicOrdering Ordering, InsertPosition Pos,
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
314
void FenceInst::setOrdering(AtomicOrdering Ordering) {
315
Ctx.getTracker()
316
.emplaceIfTracking<
317
GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>(
318
this);
319
cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
320
}
321
322
void FenceInst::setSyncScopeID(SyncScope::ID SSID) {
323
Ctx.getTracker()
324
.emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
325
&FenceInst::setSyncScopeID>>(this);
326
cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
327
}
328
329
Value *SelectInst::create(Value *Cond, Value *True, Value *False,
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
340
void SelectInst::swapValues() {
341
Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
342
getOperandUse(2));
343
cast<llvm::SelectInst>(Val)->swapValues();
344
}
345
346
bool SelectInst::classof(const Value *From) {
347
return From->getSubclassID() == ClassID::Select;
348
}
349
350
BranchInst *BranchInst::create(BasicBlock *IfTrue, InsertPosition Pos,
351
Context &Ctx) {
352
auto &Builder = setInsertPos(Pos);
353
llvm::BranchInst *NewBr =
354
Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
355
return Ctx.createBranchInst(NewBr);
356
}
357
358
BranchInst *BranchInst::create(BasicBlock *IfTrue, BasicBlock *IfFalse,
359
Value *Cond, InsertPosition Pos, Context &Ctx) {
360
auto &Builder = setInsertPos(Pos);
361
llvm::BranchInst *NewBr =
362
Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
363
cast<llvm::BasicBlock>(IfFalse->Val));
364
return Ctx.createBranchInst(NewBr);
365
}
366
367
bool BranchInst::classof(const Value *From) {
368
return From->getSubclassID() == ClassID::Br;
369
}
370
371
Value *BranchInst::getCondition() const {
372
assert(isConditional() && "Cannot get condition of an uncond branch!");
373
return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
374
}
375
376
BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
377
assert(SuccIdx < getNumSuccessors() &&
378
"Successor # out of range for Branch!");
379
return cast_or_null<BasicBlock>(
380
Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
381
}
382
383
void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
384
assert((Idx == 0 || Idx == 1) && "Out of bounds!");
385
setOperand(2u - Idx, NewSucc);
386
}
387
388
BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
389
return cast<BasicBlock>(Ctx.getValue(BB));
390
}
391
const BasicBlock *
392
BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
393
return cast<BasicBlock>(Ctx.getValue(BB));
394
}
395
396
void LoadInst::setVolatile(bool V) {
397
Ctx.getTracker()
398
.emplaceIfTracking<
399
GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this);
400
cast<llvm::LoadInst>(Val)->setVolatile(V);
401
}
402
403
LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
404
InsertPosition Pos, bool IsVolatile, Context &Ctx,
405
const Twine &Name) {
406
auto &Builder = setInsertPos(Pos);
407
auto *NewLI =
408
Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
409
auto *NewSBI = Ctx.createLoadInst(NewLI);
410
return NewSBI;
411
}
412
413
bool LoadInst::classof(const Value *From) {
414
return From->getSubclassID() == ClassID::Load;
415
}
416
417
Value *LoadInst::getPointerOperand() const {
418
return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
419
}
420
421
void StoreInst::setVolatile(bool V) {
422
Ctx.getTracker()
423
.emplaceIfTracking<
424
GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(this);
425
cast<llvm::StoreInst>(Val)->setVolatile(V);
426
}
427
428
StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
429
InsertPosition Pos, bool IsVolatile,
430
Context &Ctx) {
431
auto &Builder = setInsertPos(Pos);
432
auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
433
auto *NewSBI = Ctx.createStoreInst(NewSI);
434
return NewSBI;
435
}
436
437
bool StoreInst::classof(const Value *From) {
438
return From->getSubclassID() == ClassID::Store;
439
}
440
441
Value *StoreInst::getValueOperand() const {
442
return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
443
}
444
445
Value *StoreInst::getPointerOperand() const {
446
return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
447
}
448
449
UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
450
auto &Builder = setInsertPos(Pos);
451
llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
452
return Ctx.createUnreachableInst(NewUI);
453
}
454
455
bool UnreachableInst::classof(const Value *From) {
456
return From->getSubclassID() == ClassID::Unreachable;
457
}
458
459
ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
460
Context &Ctx) {
461
llvm::ReturnInst *NewRI;
462
if (RetVal != nullptr)
463
NewRI = Builder.CreateRet(RetVal->Val);
464
else
465
NewRI = Builder.CreateRetVoid();
466
return Ctx.createReturnInst(NewRI);
467
}
468
469
ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
470
Context &Ctx) {
471
auto &Builder = setInsertPos(Pos);
472
return createCommon(RetVal, Builder, Ctx);
473
}
474
475
Value *ReturnInst::getReturnValue() const {
476
auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
477
return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
478
}
479
480
FunctionType *CallBase::getFunctionType() const {
481
return cast<FunctionType>(
482
Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
483
}
484
485
Value *CallBase::getCalledOperand() const {
486
return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
487
}
488
489
Use CallBase::getCalledOperandUse() const {
490
llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
491
return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
492
}
493
494
Function *CallBase::getCalledFunction() const {
495
return cast_or_null<Function>(
496
Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
497
}
498
Function *CallBase::getCaller() {
499
return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
500
}
501
502
void CallBase::setCalledFunction(Function *F) {
503
// F's function type is private, so we rely on `setCalledFunction()` to update
504
// it. But even though we are calling `setCalledFunction()` we also need to
505
// track this change at the SandboxIR level, which is why we call
506
// `setCalledOperand()` here.
507
// Note: This may break if `setCalledFunction()` early returns if `F`
508
// is already set, but we do have a unit test for it.
509
setCalledOperand(F);
510
cast<llvm::CallBase>(Val)->setCalledFunction(
511
cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
512
cast<llvm::Function>(F->Val));
513
}
514
515
CallInst *CallInst::create(FunctionType *FTy, Value *Func,
516
ArrayRef<Value *> Args, InsertPosition Pos,
517
Context &Ctx, const Twine &NameStr) {
518
auto &Builder = setInsertPos(Pos);
519
SmallVector<llvm::Value *> LLVMArgs;
520
LLVMArgs.reserve(Args.size());
521
for (Value *Arg : Args)
522
LLVMArgs.push_back(Arg->Val);
523
llvm::CallInst *NewCI = Builder.CreateCall(
524
cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
525
return Ctx.createCallInst(NewCI);
526
}
527
528
InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
529
BasicBlock *IfNormal, BasicBlock *IfException,
530
ArrayRef<Value *> Args, InsertPosition Pos,
531
Context &Ctx, const Twine &NameStr) {
532
auto &Builder = setInsertPos(Pos);
533
SmallVector<llvm::Value *> LLVMArgs;
534
LLVMArgs.reserve(Args.size());
535
for (Value *Arg : Args)
536
LLVMArgs.push_back(Arg->Val);
537
llvm::InvokeInst *Invoke = Builder.CreateInvoke(
538
cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
539
cast<llvm::BasicBlock>(IfNormal->Val),
540
cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
541
return Ctx.createInvokeInst(Invoke);
542
}
543
544
BasicBlock *InvokeInst::getNormalDest() const {
545
return cast<BasicBlock>(
546
Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
547
}
548
BasicBlock *InvokeInst::getUnwindDest() const {
549
return cast<BasicBlock>(
550
Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
551
}
552
void InvokeInst::setNormalDest(BasicBlock *BB) {
553
setOperand(1, BB);
554
assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
555
}
556
void InvokeInst::setUnwindDest(BasicBlock *BB) {
557
setOperand(2, BB);
558
assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
559
}
560
LandingPadInst *InvokeInst::getLandingPadInst() const {
561
return cast<LandingPadInst>(
562
Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
563
;
564
}
565
BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
566
return cast<BasicBlock>(
567
Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
568
}
569
570
CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
571
BasicBlock *DefaultDest,
572
ArrayRef<BasicBlock *> IndirectDests,
573
ArrayRef<Value *> Args, InsertPosition Pos,
574
Context &Ctx, const Twine &NameStr) {
575
auto &Builder = setInsertPos(Pos);
576
SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
577
LLVMIndirectDests.reserve(IndirectDests.size());
578
for (BasicBlock *IndDest : IndirectDests)
579
LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
580
581
SmallVector<llvm::Value *> LLVMArgs;
582
LLVMArgs.reserve(Args.size());
583
for (Value *Arg : Args)
584
LLVMArgs.push_back(Arg->Val);
585
586
llvm::CallBrInst *CallBr =
587
Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
588
cast<llvm::BasicBlock>(DefaultDest->Val),
589
LLVMIndirectDests, LLVMArgs, NameStr);
590
return Ctx.createCallBrInst(CallBr);
591
}
592
593
Value *CallBrInst::getIndirectDestLabel(unsigned Idx) const {
594
return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
595
}
596
Value *CallBrInst::getIndirectDestLabelUse(unsigned Idx) const {
597
return Ctx.getValue(
598
cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
599
}
600
BasicBlock *CallBrInst::getDefaultDest() const {
601
return cast<BasicBlock>(
602
Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
603
}
604
BasicBlock *CallBrInst::getIndirectDest(unsigned Idx) const {
605
return cast<BasicBlock>(
606
Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
607
}
608
llvm::SmallVector<BasicBlock *, 16> CallBrInst::getIndirectDests() const {
609
SmallVector<BasicBlock *, 16> BBs;
610
for (llvm::BasicBlock *LLVMBB :
611
cast<llvm::CallBrInst>(Val)->getIndirectDests())
612
BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
613
return BBs;
614
}
615
void CallBrInst::setDefaultDest(BasicBlock *BB) {
616
Ctx.getTracker()
617
.emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
618
&CallBrInst::setDefaultDest>>(this);
619
cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
620
}
621
void CallBrInst::setIndirectDest(unsigned Idx, BasicBlock *BB) {
622
Ctx.getTracker()
623
.emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest,
624
&CallBrInst::setIndirectDest>>(
625
this, Idx);
626
cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
627
cast<llvm::BasicBlock>(BB->Val));
628
}
629
BasicBlock *CallBrInst::getSuccessor(unsigned Idx) const {
630
return cast<BasicBlock>(
631
Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
632
}
633
634
LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
635
InsertPosition Pos, Context &Ctx,
636
const Twine &Name) {
637
auto &Builder = setInsertPos(Pos);
638
llvm::LandingPadInst *LLVMI =
639
Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
640
return Ctx.createLandingPadInst(LLVMI);
641
}
642
643
void LandingPadInst::setCleanup(bool V) {
644
Ctx.getTracker()
645
.emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
646
&LandingPadInst::setCleanup>>(this);
647
cast<llvm::LandingPadInst>(Val)->setCleanup(V);
648
}
649
650
Constant *LandingPadInst::getClause(unsigned Idx) const {
651
return cast<Constant>(
652
Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
653
}
654
655
Value *FuncletPadInst::getParentPad() const {
656
return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());
657
}
658
659
void FuncletPadInst::setParentPad(Value *ParentPad) {
660
Ctx.getTracker()
661
.emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
662
&FuncletPadInst::setParentPad>>(this);
663
cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
664
}
665
666
Value *FuncletPadInst::getArgOperand(unsigned Idx) const {
667
return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
668
}
669
670
void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
671
Ctx.getTracker()
672
.emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
673
&FuncletPadInst::setArgOperand>>(
674
this, Idx);
675
cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
676
}
677
678
CatchSwitchInst *CatchPadInst::getCatchSwitch() const {
679
return cast<CatchSwitchInst>(
680
Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch()));
681
}
682
683
CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
684
InsertPosition Pos, Context &Ctx,
685
const Twine &Name) {
686
auto &Builder = setInsertPos(Pos);
687
SmallVector<llvm::Value *> LLVMArgs;
688
LLVMArgs.reserve(Args.size());
689
for (auto *Arg : Args)
690
LLVMArgs.push_back(Arg->Val);
691
llvm::CatchPadInst *LLVMI =
692
Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
693
return Ctx.createCatchPadInst(LLVMI);
694
}
695
696
CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
697
InsertPosition Pos, Context &Ctx,
698
const Twine &Name) {
699
auto &Builder = setInsertPos(Pos);
700
SmallVector<llvm::Value *> LLVMArgs;
701
LLVMArgs.reserve(Args.size());
702
for (auto *Arg : Args)
703
LLVMArgs.push_back(Arg->Val);
704
llvm::CleanupPadInst *LLVMI =
705
Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
706
return Ctx.createCleanupPadInst(LLVMI);
707
}
708
709
CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
710
InsertPosition Pos, Context &Ctx) {
711
auto &Builder = setInsertPos(Pos);
712
llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
713
cast<llvm::CatchPadInst>(CatchPad->Val), cast<llvm::BasicBlock>(BB->Val));
714
return Ctx.createCatchReturnInst(LLVMI);
715
}
716
717
CatchPadInst *CatchReturnInst::getCatchPad() const {
718
return cast<CatchPadInst>(
719
Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
720
}
721
722
void CatchReturnInst::setCatchPad(CatchPadInst *CatchPad) {
723
Ctx.getTracker()
724
.emplaceIfTracking<GenericSetter<&CatchReturnInst::getCatchPad,
725
&CatchReturnInst::setCatchPad>>(this);
726
cast<llvm::CatchReturnInst>(Val)->setCatchPad(
727
cast<llvm::CatchPadInst>(CatchPad->Val));
728
}
729
730
BasicBlock *CatchReturnInst::getSuccessor() const {
731
return cast<BasicBlock>(
732
Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
733
}
734
735
void CatchReturnInst::setSuccessor(BasicBlock *NewSucc) {
736
Ctx.getTracker()
737
.emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor,
738
&CatchReturnInst::setSuccessor>>(this);
739
cast<llvm::CatchReturnInst>(Val)->setSuccessor(
740
cast<llvm::BasicBlock>(NewSucc->Val));
741
}
742
743
Value *CatchReturnInst::getCatchSwitchParentPad() const {
744
return Ctx.getValue(
745
cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
746
}
747
748
CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
749
BasicBlock *UnwindBB,
750
InsertPosition Pos, Context &Ctx) {
751
auto &Builder = setInsertPos(Pos);
752
auto *LLVMUnwindBB =
753
UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
754
llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
755
cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
756
return Ctx.createCleanupReturnInst(LLVMI);
757
}
758
759
CleanupPadInst *CleanupReturnInst::getCleanupPad() const {
760
return cast<CleanupPadInst>(
761
Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));
762
}
763
764
void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) {
765
Ctx.getTracker()
766
.emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
767
&CleanupReturnInst::setCleanupPad>>(
768
this);
769
cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
770
cast<llvm::CleanupPadInst>(CleanupPad->Val));
771
}
772
773
BasicBlock *CleanupReturnInst::getUnwindDest() const {
774
return cast_or_null<BasicBlock>(
775
Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));
776
}
777
778
void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
779
Ctx.getTracker()
780
.emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest,
781
&CleanupReturnInst::setUnwindDest>>(
782
this);
783
cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
784
cast<llvm::BasicBlock>(NewDest->Val));
785
}
786
787
Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
788
ArrayRef<Value *> IdxList, InsertPosition Pos,
789
Context &Ctx, const Twine &NameStr) {
790
auto &Builder = setInsertPos(Pos);
791
SmallVector<llvm::Value *> LLVMIdxList;
792
LLVMIdxList.reserve(IdxList.size());
793
for (Value *Idx : IdxList)
794
LLVMIdxList.push_back(Idx->Val);
795
llvm::Value *NewV =
796
Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
797
if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
798
return Ctx.createGetElementPtrInst(NewGEP);
799
assert(isa<llvm::Constant>(NewV) && "Expected constant");
800
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
801
}
802
803
Type *GetElementPtrInst::getSourceElementType() const {
804
return Ctx.getType(
805
cast<llvm::GetElementPtrInst>(Val)->getSourceElementType());
806
}
807
808
Type *GetElementPtrInst::getResultElementType() const {
809
return Ctx.getType(
810
cast<llvm::GetElementPtrInst>(Val)->getResultElementType());
811
}
812
813
Value *GetElementPtrInst::getPointerOperand() const {
814
return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
815
}
816
817
Type *GetElementPtrInst::getPointerOperandType() const {
818
return Ctx.getType(
819
cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType());
820
}
821
822
BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
823
return cast<BasicBlock>(Ctx.getValue(LLVMBB));
824
}
825
826
PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
827
InsertPosition Pos, Context &Ctx, const Twine &Name) {
828
auto &Builder = setInsertPos(Pos);
829
llvm::PHINode *NewPHI =
830
Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
831
return Ctx.createPHINode(NewPHI);
832
}
833
834
bool PHINode::classof(const Value *From) {
835
return From->getSubclassID() == ClassID::PHI;
836
}
837
838
Value *PHINode::getIncomingValue(unsigned Idx) const {
839
return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
840
}
841
void PHINode::setIncomingValue(unsigned Idx, Value *V) {
842
Ctx.getTracker()
843
.emplaceIfTracking<GenericSetterWithIdx<&PHINode::getIncomingValue,
844
&PHINode::setIncomingValue>>(this,
845
Idx);
846
cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
847
}
848
BasicBlock *PHINode::getIncomingBlock(unsigned Idx) const {
849
return cast<BasicBlock>(
850
Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
851
}
852
BasicBlock *PHINode::getIncomingBlock(const Use &U) const {
853
llvm::Use *LLVMUse = U.LLVMUse;
854
llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
855
return cast<BasicBlock>(Ctx.getValue(BB));
856
}
857
void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
858
// Helper to disambiguate PHINode::getIncomingBlock(unsigned).
859
constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
860
&PHINode::getIncomingBlock;
861
Ctx.getTracker()
862
.emplaceIfTracking<
863
GenericSetterWithIdx<GetIncomingBlockFn, &PHINode::setIncomingBlock>>(
864
this, Idx);
865
cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
866
cast<llvm::BasicBlock>(BB->Val));
867
}
868
void PHINode::addIncoming(Value *V, BasicBlock *BB) {
869
auto &Tracker = Ctx.getTracker();
870
Tracker.emplaceIfTracking<PHIAddIncoming>(this);
871
872
cast<llvm::PHINode>(Val)->addIncoming(V->Val,
873
cast<llvm::BasicBlock>(BB->Val));
874
}
875
Value *PHINode::removeIncomingValue(unsigned Idx) {
876
auto &Tracker = Ctx.getTracker();
877
Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, Idx);
878
llvm::Value *LLVMV =
879
cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
880
/*DeletePHIIfEmpty=*/false);
881
return Ctx.getValue(LLVMV);
882
}
883
Value *PHINode::removeIncomingValue(BasicBlock *BB) {
884
auto &Tracker = Ctx.getTracker();
885
Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, getBasicBlockIndex(BB));
886
887
auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
888
llvm::Value *LLVMV =
889
cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
890
/*DeletePHIIfEmpty=*/false);
891
return Ctx.getValue(LLVMV);
892
}
893
int PHINode::getBasicBlockIndex(const BasicBlock *BB) const {
894
auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
895
return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
896
}
897
Value *PHINode::getIncomingValueForBlock(const BasicBlock *BB) const {
898
auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
899
llvm::Value *LLVMV =
900
cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
901
return Ctx.getValue(LLVMV);
902
}
903
Value *PHINode::hasConstantValue() const {
904
llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
905
return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
906
}
907
void PHINode::replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) {
908
assert(New && Old && "Sandbox IR PHI node got a null basic block!");
909
for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
910
Idx != NumOps; ++Idx)
911
if (getIncomingBlock(Idx) == Old)
912
setIncomingBlock(Idx, New);
913
}
914
void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
915
// Avoid duplicate tracking by going through this->removeIncomingValue here at
916
// the expense of some performance. Copy PHI::removeIncomingValueIf more
917
// directly if performance becomes an issue.
918
919
// Removing the element at index X, moves the element previously at X + 1
920
// to X. Working from the end avoids complications from that.
921
unsigned Idx = getNumIncomingValues();
922
while (Idx > 0) {
923
if (Predicate(Idx - 1))
924
removeIncomingValue(Idx - 1);
925
--Idx;
926
}
927
}
928
929
Value *CmpInst::create(Predicate P, Value *S1, Value *S2, InsertPosition Pos,
930
Context &Ctx, const Twine &Name) {
931
auto &Builder = setInsertPos(Pos);
932
auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
933
// It may have been folded into a constant.
934
if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
935
return Ctx.getOrCreateConstant(LLVMC);
936
if (isa<llvm::ICmpInst>(LLVMV))
937
return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
938
return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
939
}
940
941
Value *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2,
942
const Instruction *F, InsertPosition Pos,
943
Context &Ctx, const Twine &Name) {
944
Value *V = create(P, S1, S2, Pos, Ctx, Name);
945
if (auto *C = dyn_cast<Constant>(V))
946
return C;
947
cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
948
return V;
949
}
950
951
Type *CmpInst::makeCmpResultType(Type *OpndType) {
952
if (auto *VT = dyn_cast<VectorType>(OpndType)) {
953
// TODO: Cleanup when we have more complete support for
954
// sandboxir::VectorType
955
return OpndType->getContext().getType(llvm::VectorType::get(
956
llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx),
957
cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
958
}
959
return Type::getInt1Ty(OpndType->getContext());
960
}
961
962
void CmpInst::setPredicate(Predicate P) {
963
Ctx.getTracker()
964
.emplaceIfTracking<
965
GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this);
966
cast<llvm::CmpInst>(Val)->setPredicate(P);
967
}
968
969
void CmpInst::swapOperands() {
970
if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
971
IC->swapOperands();
972
else
973
cast<FCmpInst>(this)->swapOperands();
974
}
975
976
void ICmpInst::swapOperands() {
977
Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
978
cast<llvm::ICmpInst>(Val)->swapOperands();
979
}
980
981
void FCmpInst::swapOperands() {
982
Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
983
cast<llvm::FCmpInst>(Val)->swapOperands();
984
}
985
986
#ifndef NDEBUG
987
void CmpInst::dumpOS(raw_ostream &OS) const {
988
dumpCommonPrefix(OS);
989
dumpCommonSuffix(OS);
990
}
991
992
void CmpInst::dump() const {
993
dumpOS(dbgs());
994
dbgs() << "\n";
995
}
996
#endif // NDEBUG
997
998
static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
999
switch (Opc) {
1000
case Instruction::Opcode::ZExt:
1001
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1002
case Instruction::Opcode::SExt:
1003
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1004
case Instruction::Opcode::FPToUI:
1005
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1006
case Instruction::Opcode::FPToSI:
1007
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1008
case Instruction::Opcode::FPExt:
1009
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1010
case Instruction::Opcode::PtrToInt:
1011
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1012
case Instruction::Opcode::IntToPtr:
1013
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1014
case Instruction::Opcode::SIToFP:
1015
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1016
case Instruction::Opcode::UIToFP:
1017
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1018
case Instruction::Opcode::Trunc:
1019
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1020
case Instruction::Opcode::FPTrunc:
1021
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1022
case Instruction::Opcode::BitCast:
1023
return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1024
case Instruction::Opcode::AddrSpaceCast:
1025
return static_cast<llvm::Instruction::CastOps>(
1026
llvm::Instruction::AddrSpaceCast);
1027
default:
1028
llvm_unreachable("Opcode not suitable for CastInst!");
1029
}
1030
}
1031
1032
/// \Returns the LLVM opcode that corresponds to \p Opc.
1033
static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc) {
1034
switch (Opc) {
1035
case Instruction::Opcode::FNeg:
1036
return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1037
default:
1038
llvm_unreachable("Not a unary op!");
1039
}
1040
}
1041
1042
CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
1043
unsigned NumHandlers,
1044
InsertPosition Pos, Context &Ctx,
1045
const Twine &Name) {
1046
auto &Builder = setInsertPos(Pos);
1047
llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1048
ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1049
return Ctx.createCatchSwitchInst(LLVMCSI);
1050
}
1051
1052
Value *CatchSwitchInst::getParentPad() const {
1053
return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
1054
}
1055
1056
void CatchSwitchInst::setParentPad(Value *ParentPad) {
1057
Ctx.getTracker()
1058
.emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
1059
&CatchSwitchInst::setParentPad>>(this);
1060
cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1061
}
1062
1063
BasicBlock *CatchSwitchInst::getUnwindDest() const {
1064
return cast_or_null<BasicBlock>(
1065
Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1066
}
1067
1068
void CatchSwitchInst::setUnwindDest(BasicBlock *UnwindDest) {
1069
Ctx.getTracker()
1070
.emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest,
1071
&CatchSwitchInst::setUnwindDest>>(this);
1072
cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1073
cast<llvm::BasicBlock>(UnwindDest->Val));
1074
}
1075
1076
void CatchSwitchInst::addHandler(BasicBlock *Dest) {
1077
Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
1078
cast<llvm::CatchSwitchInst>(Val)->addHandler(
1079
cast<llvm::BasicBlock>(Dest->Val));
1080
}
1081
1082
ResumeInst *ResumeInst::create(Value *Exn, InsertPosition Pos, Context &Ctx) {
1083
auto &Builder = setInsertPos(Pos);
1084
auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1085
return Ctx.createResumeInst(LLVMI);
1086
}
1087
1088
Value *ResumeInst::getValue() const {
1089
return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1090
}
1091
1092
SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1093
InsertPosition Pos, Context &Ctx,
1094
const Twine &Name) {
1095
auto &Builder = setInsertPos(Pos);
1096
llvm::SwitchInst *LLVMSwitch =
1097
Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1098
return Ctx.createSwitchInst(LLVMSwitch);
1099
}
1100
1101
Value *SwitchInst::getCondition() const {
1102
return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1103
}
1104
1105
void SwitchInst::setCondition(Value *V) {
1106
Ctx.getTracker()
1107
.emplaceIfTracking<
1108
GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(
1109
this);
1110
cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1111
}
1112
1113
BasicBlock *SwitchInst::getDefaultDest() const {
1114
return cast<BasicBlock>(
1115
Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1116
}
1117
1118
void SwitchInst::setDefaultDest(BasicBlock *DefaultCase) {
1119
Ctx.getTracker()
1120
.emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
1121
&SwitchInst::setDefaultDest>>(this);
1122
cast<llvm::SwitchInst>(Val)->setDefaultDest(
1123
cast<llvm::BasicBlock>(DefaultCase->Val));
1124
}
1125
ConstantInt *SwitchInst::findCaseDest(BasicBlock *BB) {
1126
auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1127
cast<llvm::BasicBlock>(BB->Val));
1128
return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1129
}
1130
1131
void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
1132
Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
1133
// TODO: Track this!
1134
cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),
1135
cast<llvm::BasicBlock>(Dest->Val));
1136
}
1137
1138
SwitchInst::CaseIt SwitchInst::removeCase(CaseIt It) {
1139
Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
1140
1141
auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);
1142
unsigned CaseNum = It - case_begin();
1143
llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1144
auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1145
unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1146
return CaseIt(this, Num);
1147
}
1148
1149
BasicBlock *SwitchInst::getSuccessor(unsigned Idx) const {
1150
return cast<BasicBlock>(
1151
Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1152
}
1153
1154
void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1155
Ctx.getTracker()
1156
.emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor,
1157
&SwitchInst::setSuccessor>>(this,
1158
Idx);
1159
cast<llvm::SwitchInst>(Val)->setSuccessor(
1160
Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1161
}
1162
1163
Value *UnaryOperator::create(Instruction::Opcode Op, Value *OpV,
1164
InsertPosition Pos, Context &Ctx,
1165
const Twine &Name) {
1166
auto &Builder = setInsertPos(Pos);
1167
auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1168
if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1169
return Ctx.createUnaryOperator(NewUnOpV);
1170
}
1171
assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1172
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1173
}
1174
1175
Value *UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *OpV,
1176
Value *CopyFrom, InsertPosition Pos,
1177
Context &Ctx, const Twine &Name) {
1178
auto *NewV = create(Op, OpV, Pos, Ctx, Name);
1179
if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1180
UnI->copyIRFlags(CopyFrom->Val);
1181
return NewV;
1182
}
1183
1184
/// \Returns the LLVM opcode that corresponds to \p Opc.
1185
static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc) {
1186
switch (Opc) {
1187
case Instruction::Opcode::Add:
1188
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1189
case Instruction::Opcode::FAdd:
1190
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1191
case Instruction::Opcode::Sub:
1192
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1193
case Instruction::Opcode::FSub:
1194
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1195
case Instruction::Opcode::Mul:
1196
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1197
case Instruction::Opcode::FMul:
1198
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1199
case Instruction::Opcode::UDiv:
1200
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1201
case Instruction::Opcode::SDiv:
1202
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1203
case Instruction::Opcode::FDiv:
1204
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1205
case Instruction::Opcode::URem:
1206
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1207
case Instruction::Opcode::SRem:
1208
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1209
case Instruction::Opcode::FRem:
1210
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1211
case Instruction::Opcode::Shl:
1212
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1213
case Instruction::Opcode::LShr:
1214
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1215
case Instruction::Opcode::AShr:
1216
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1217
case Instruction::Opcode::And:
1218
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1219
case Instruction::Opcode::Or:
1220
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1221
case Instruction::Opcode::Xor:
1222
return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1223
default:
1224
llvm_unreachable("Not a binary op!");
1225
}
1226
}
1227
Value *BinaryOperator::create(Instruction::Opcode Op, Value *LHS, Value *RHS,
1228
InsertPosition Pos, Context &Ctx,
1229
const Twine &Name) {
1230
auto &Builder = setInsertPos(Pos);
1231
llvm::Value *NewV =
1232
Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
1233
if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1234
return Ctx.createBinaryOperator(NewBinOp);
1235
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1236
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1237
}
1238
1239
Value *BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *LHS,
1240
Value *RHS, Value *CopyFrom,
1241
InsertPosition Pos, Context &Ctx,
1242
const Twine &Name) {
1243
1244
Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
1245
if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1246
cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1247
return NewV;
1248
}
1249
1250
void PossiblyDisjointInst::setIsDisjoint(bool B) {
1251
Ctx.getTracker()
1252
.emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,
1253
&PossiblyDisjointInst::setIsDisjoint>>(
1254
this);
1255
cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
1256
}
1257
1258
void AtomicRMWInst::setAlignment(Align Align) {
1259
Ctx.getTracker()
1260
.emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
1261
&AtomicRMWInst::setAlignment>>(this);
1262
cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1263
}
1264
1265
void AtomicRMWInst::setVolatile(bool V) {
1266
Ctx.getTracker()
1267
.emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
1268
&AtomicRMWInst::setVolatile>>(this);
1269
cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1270
}
1271
1272
void AtomicRMWInst::setOrdering(AtomicOrdering Ordering) {
1273
Ctx.getTracker()
1274
.emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
1275
&AtomicRMWInst::setOrdering>>(this);
1276
cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1277
}
1278
1279
void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID) {
1280
Ctx.getTracker()
1281
.emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,
1282
&AtomicRMWInst::setSyncScopeID>>(this);
1283
cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1284
}
1285
1286
Value *AtomicRMWInst::getPointerOperand() {
1287
return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());
1288
}
1289
1290
Value *AtomicRMWInst::getValOperand() {
1291
return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());
1292
}
1293
1294
AtomicRMWInst *AtomicRMWInst::create(BinOp Op, Value *Ptr, Value *Val,
1295
MaybeAlign Align, AtomicOrdering Ordering,
1296
InsertPosition Pos, Context &Ctx,
1297
SyncScope::ID SSID, const Twine &Name) {
1298
auto &Builder = setInsertPos(Pos);
1299
auto *LLVMAtomicRMW =
1300
Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1301
LLVMAtomicRMW->setName(Name);
1302
return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
1303
}
1304
1305
void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {
1306
Ctx.getTracker()
1307
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
1308
&AtomicCmpXchgInst::setSyncScopeID>>(
1309
this);
1310
cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1311
}
1312
1313
Value *AtomicCmpXchgInst::getPointerOperand() {
1314
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
1315
}
1316
1317
Value *AtomicCmpXchgInst::getCompareOperand() {
1318
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
1319
}
1320
1321
Value *AtomicCmpXchgInst::getNewValOperand() {
1322
return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1323
}
1324
1325
AtomicCmpXchgInst *
1326
AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1327
AtomicOrdering SuccessOrdering,
1328
AtomicOrdering FailureOrdering, InsertPosition Pos,
1329
Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
1330
auto &Builder = setInsertPos(Pos);
1331
auto *LLVMAtomicCmpXchg =
1332
Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1333
SuccessOrdering, FailureOrdering, SSID);
1334
LLVMAtomicCmpXchg->setName(Name);
1335
return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1336
}
1337
1338
void AtomicCmpXchgInst::setAlignment(Align Align) {
1339
Ctx.getTracker()
1340
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1341
&AtomicCmpXchgInst::setAlignment>>(this);
1342
cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1343
}
1344
1345
void AtomicCmpXchgInst::setVolatile(bool V) {
1346
Ctx.getTracker()
1347
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1348
&AtomicCmpXchgInst::setVolatile>>(this);
1349
cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1350
}
1351
1352
void AtomicCmpXchgInst::setWeak(bool IsWeak) {
1353
Ctx.getTracker()
1354
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1355
&AtomicCmpXchgInst::setWeak>>(this);
1356
cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1357
}
1358
1359
void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {
1360
Ctx.getTracker()
1361
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1362
&AtomicCmpXchgInst::setSuccessOrdering>>(
1363
this);
1364
cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1365
}
1366
1367
void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {
1368
Ctx.getTracker()
1369
.emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
1370
&AtomicCmpXchgInst::setFailureOrdering>>(
1371
this);
1372
cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1373
}
1374
1375
AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
1376
Context &Ctx, Value *ArraySize,
1377
const Twine &Name) {
1378
auto &Builder = setInsertPos(Pos);
1379
auto *NewAlloca =
1380
Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
1381
return Ctx.createAllocaInst(NewAlloca);
1382
}
1383
1384
Type *AllocaInst::getAllocatedType() const {
1385
return Ctx.getType(cast<llvm::AllocaInst>(Val)->getAllocatedType());
1386
}
1387
1388
void AllocaInst::setAllocatedType(Type *Ty) {
1389
Ctx.getTracker()
1390
.emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
1391
&AllocaInst::setAllocatedType>>(this);
1392
cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
1393
}
1394
1395
void AllocaInst::setAlignment(Align Align) {
1396
Ctx.getTracker()
1397
.emplaceIfTracking<
1398
GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>(
1399
this);
1400
cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1401
}
1402
1403
void AllocaInst::setUsedWithInAlloca(bool V) {
1404
Ctx.getTracker()
1405
.emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca,
1406
&AllocaInst::setUsedWithInAlloca>>(this);
1407
cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1408
}
1409
1410
Value *AllocaInst::getArraySize() {
1411
return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
1412
}
1413
1414
PointerType *AllocaInst::getType() const {
1415
return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
1416
}
1417
1418
Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand,
1419
InsertPosition Pos, Context &Ctx, const Twine &Name) {
1420
assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1421
auto &Builder = setInsertPos(Pos);
1422
auto *NewV =
1423
Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
1424
if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1425
return Ctx.createCastInst(NewCI);
1426
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1427
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1428
}
1429
1430
bool CastInst::classof(const Value *From) {
1431
return From->getSubclassID() == ClassID::Cast;
1432
}
1433
1434
Type *CastInst::getSrcTy() const {
1435
return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
1436
}
1437
1438
Type *CastInst::getDestTy() const {
1439
return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
1440
}
1441
1442
void PossiblyNonNegInst::setNonNeg(bool B) {
1443
Ctx.getTracker()
1444
.emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1445
&PossiblyNonNegInst::setNonNeg>>(this);
1446
cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B);
1447
}
1448
1449
Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx,
1450
InsertPosition Pos, Context &Ctx,
1451
const Twine &Name) {
1452
auto &Builder = Instruction::setInsertPos(Pos);
1453
llvm::Value *NewV =
1454
Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1455
if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1456
return Ctx.createInsertElementInst(NewInsert);
1457
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1458
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1459
}
1460
1461
Value *ExtractElementInst::create(Value *Vec, Value *Idx, InsertPosition Pos,
1462
Context &Ctx, const Twine &Name) {
1463
auto &Builder = setInsertPos(Pos);
1464
llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1465
if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1466
return Ctx.createExtractElementInst(NewExtract);
1467
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1468
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1469
}
1470
1471
Value *ShuffleVectorInst::create(Value *V1, Value *V2, Value *Mask,
1472
InsertPosition Pos, Context &Ctx,
1473
const Twine &Name) {
1474
auto &Builder = setInsertPos(Pos);
1475
llvm::Value *NewV =
1476
Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);
1477
if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1478
return Ctx.createShuffleVectorInst(NewShuffle);
1479
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1480
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1481
}
1482
1483
Value *ShuffleVectorInst::create(Value *V1, Value *V2, ArrayRef<int> Mask,
1484
InsertPosition Pos, Context &Ctx,
1485
const Twine &Name) {
1486
auto &Builder = setInsertPos(Pos);
1487
llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
1488
if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1489
return Ctx.createShuffleVectorInst(NewShuffle);
1490
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1491
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1492
}
1493
1494
void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
1495
Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1496
cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
1497
}
1498
1499
VectorType *ShuffleVectorInst::getType() const {
1500
return cast<VectorType>(
1501
Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
1502
}
1503
1504
void ShuffleVectorInst::commute() {
1505
Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1506
Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
1507
getOperandUse(1));
1508
cast<llvm::ShuffleVectorInst>(Val)->commute();
1509
}
1510
1511
Constant *ShuffleVectorInst::getShuffleMaskForBitcode() const {
1512
return Ctx.getOrCreateConstant(
1513
cast<llvm::ShuffleVectorInst>(Val)->getShuffleMaskForBitcode());
1514
}
1515
1516
Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,
1517
Type *ResultTy) {
1518
return ResultTy->getContext().getOrCreateConstant(
1519
llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask,
1520
ResultTy->LLVMTy));
1521
}
1522
1523
VectorType *ExtractElementInst::getVectorOperandType() const {
1524
return cast<VectorType>(Ctx.getType(getVectorOperand()->getType()->LLVMTy));
1525
}
1526
1527
Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs,
1528
InsertPosition Pos, Context &Ctx,
1529
const Twine &Name) {
1530
auto &Builder = setInsertPos(Pos);
1531
llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
1532
if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
1533
return Ctx.createExtractValueInst(NewExtractValueInst);
1534
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1535
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1536
}
1537
1538
Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {
1539
auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
1540
return Agg->getContext().getType(LLVMTy);
1541
}
1542
1543
Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
1544
InsertPosition Pos, Context &Ctx,
1545
const Twine &Name) {
1546
auto &Builder = setInsertPos(Pos);
1547
llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
1548
if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
1549
return Ctx.createInsertValueInst(NewInsertValueInst);
1550
assert(isa<llvm::Constant>(NewV) && "Expected constant");
1551
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1552
}
1553
1554
ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
1555
auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
1556
return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
1557
}
1558
1559
} // namespace llvm::sandboxir
1560
1561