@@ -262,6 +262,115 @@ const char *Instruction::getOpcodeName(Opcode Opc) {
262
262
llvm_unreachable (" Unknown Opcode" );
263
263
}
264
264
265
+ llvm::Instruction *Instruction::getTopmostLLVMInstruction () const {
266
+ Instruction *Prev = getPrevNode ();
267
+ if (Prev == nullptr ) {
268
+ // If at top of the BB, return the first BB instruction.
269
+ return &*cast<llvm::BasicBlock>(getParent ()->Val )->begin ();
270
+ }
271
+ // Else get the Previous sandbox IR instruction's bottom IR instruction and
272
+ // return its successor.
273
+ llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val );
274
+ return PrevBotI->getNextNode ();
275
+ }
276
+
277
+ BBIterator Instruction::getIterator () const {
278
+ auto *I = cast<llvm::Instruction>(Val);
279
+ return BasicBlock::iterator (I->getParent (), I->getIterator (), &Ctx);
280
+ }
281
+
282
+ Instruction *Instruction::getNextNode () const {
283
+ assert (getParent () != nullptr && " Detached!" );
284
+ assert (getIterator () != getParent ()->end () && " Already at end!" );
285
+ auto *LLVMI = cast<llvm::Instruction>(Val);
286
+ assert (LLVMI->getParent () != nullptr && " LLVM IR instr is detached!" );
287
+ auto *NextLLVMI = LLVMI->getNextNode ();
288
+ auto *NextI = cast_or_null<Instruction>(Ctx.getValue (NextLLVMI));
289
+ if (NextI == nullptr )
290
+ return nullptr ;
291
+ return NextI;
292
+ }
293
+
294
+ Instruction *Instruction::getPrevNode () const {
295
+ assert (getParent () != nullptr && " Detached!" );
296
+ auto It = getIterator ();
297
+ if (It != getParent ()->begin ())
298
+ return std::prev (getIterator ()).get ();
299
+ return nullptr ;
300
+ }
301
+
302
+ void Instruction::removeFromParent () {
303
+ // Detach all the LLVM IR instructions from their parent BB.
304
+ for (llvm::Instruction *I : getLLVMInstrs ())
305
+ I->removeFromParent ();
306
+ }
307
+
308
+ void Instruction::eraseFromParent () {
309
+ assert (users ().empty () && " Still connected to users, can't erase!" );
310
+ // We don't have Tracking yet, so just erase the LLVM IR instructions.
311
+ // Erase in reverse to avoid erasing nstructions with attached uses.
312
+ for (llvm::Instruction *I : reverse (getLLVMInstrs ()))
313
+ I->eraseFromParent ();
314
+ }
315
+
316
+ void Instruction::moveBefore (BasicBlock &BB, const BBIterator &WhereIt) {
317
+ if (std::next (getIterator ()) == WhereIt)
318
+ // Destination is same as origin, nothing to do.
319
+ return ;
320
+ auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val );
321
+ llvm::BasicBlock::iterator It;
322
+ if (WhereIt == BB.end ()) {
323
+ It = LLVMBB->end ();
324
+ } else {
325
+ Instruction *WhereI = &*WhereIt;
326
+ It = WhereI->getTopmostLLVMInstruction ()->getIterator ();
327
+ }
328
+ // TODO: Move this to the verifier of sandboxir::Instruction.
329
+ assert (is_sorted (getLLVMInstrs (),
330
+ [](auto *I1, auto *I2) { return I1->comesBefore (I2); }) &&
331
+ " Expected program order!" );
332
+ // Do the actual move in LLVM IR.
333
+ for (auto *I : getLLVMInstrs ())
334
+ I->moveBefore (*LLVMBB, It);
335
+ }
336
+
337
+ void Instruction::insertBefore (Instruction *BeforeI) {
338
+ llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction ();
339
+ // TODO: Move this to the verifier of sandboxir::Instruction.
340
+ assert (is_sorted (getLLVMInstrs (),
341
+ [](auto *I1, auto *I2) { return I1->comesBefore (I2); }) &&
342
+ " Expected program order!" );
343
+ for (llvm::Instruction *I : getLLVMInstrs ())
344
+ I->insertBefore (BeforeTopI);
345
+ }
346
+
347
+ void Instruction::insertAfter (Instruction *AfterI) {
348
+ insertInto (AfterI->getParent (), std::next (AfterI->getIterator ()));
349
+ }
350
+
351
+ void Instruction::insertInto (BasicBlock *BB, const BBIterator &WhereIt) {
352
+ llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val );
353
+ llvm::Instruction *LLVMBeforeI;
354
+ llvm::BasicBlock::iterator LLVMBeforeIt;
355
+ if (WhereIt != BB->end ()) {
356
+ Instruction *BeforeI = &*WhereIt;
357
+ LLVMBeforeI = BeforeI->getTopmostLLVMInstruction ();
358
+ LLVMBeforeIt = LLVMBeforeI->getIterator ();
359
+ } else {
360
+ LLVMBeforeI = nullptr ;
361
+ LLVMBeforeIt = LLVMBB->end ();
362
+ }
363
+ for (llvm::Instruction *I : getLLVMInstrs ())
364
+ I->insertInto (LLVMBB, LLVMBeforeIt);
365
+ }
366
+
367
+ BasicBlock *Instruction::getParent () const {
368
+ auto *BB = cast<llvm::Instruction>(Val)->getParent ();
369
+ if (BB == nullptr )
370
+ return nullptr ;
371
+ return cast<BasicBlock>(Ctx.getValue (BB));
372
+ }
373
+
265
374
bool Instruction::classof (const sandboxir::Value *From) {
266
375
switch (From->getSubclassID ()) {
267
376
#define DEF_INSTR (ID, OPC, CLASS ) \
@@ -344,6 +453,24 @@ BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
344
453
return cast_or_null<Instruction>(Ctx->getValue (&*It));
345
454
}
346
455
456
+ std::unique_ptr<Value> Context::detachLLVMValue (llvm::Value *V) {
457
+ std::unique_ptr<Value> Erased;
458
+ auto It = LLVMValueToValueMap.find (V);
459
+ if (It != LLVMValueToValueMap.end ()) {
460
+ auto *Val = It->second .release ();
461
+ Erased = std::unique_ptr<Value>(Val);
462
+ LLVMValueToValueMap.erase (It);
463
+ }
464
+ return Erased;
465
+ }
466
+
467
+ std::unique_ptr<Value> Context::detach (Value *V) {
468
+ assert (V->getSubclassID () != Value::ClassID::Constant &&
469
+ " Can't detach a constant!" );
470
+ assert (V->getSubclassID () != Value::ClassID::User && " Can't detach a user!" );
471
+ return detachLLVMValue (V->Val );
472
+ }
473
+
347
474
Value *Context::registerValue (std::unique_ptr<Value> &&VPtr) {
348
475
assert (VPtr->getSubclassID () != Value::ClassID::User &&
349
476
" Can't register a user!" );
0 commit comments