@@ -262,6 +262,116 @@ 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
+ for (llvm::Instruction *I : getLLVMInstrs ())
312
+ I->eraseFromParent ();
313
+ // Detach from instruction-specific maps.
314
+ getContext ().detach (this );
315
+ }
316
+
317
+ void Instruction::moveBefore (BasicBlock &BB, const BBIterator &WhereIt) {
318
+ if (std::next (getIterator ()) == WhereIt)
319
+ // Destination is same as origin, nothing to do.
320
+ return ;
321
+ auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val );
322
+ llvm::BasicBlock::iterator It;
323
+ if (WhereIt == BB.end ()) {
324
+ It = LLVMBB->end ();
325
+ } else {
326
+ Instruction *WhereI = &*WhereIt;
327
+ It = WhereI->getTopmostLLVMInstruction ()->getIterator ();
328
+ }
329
+ // TODO: Move this to the verifier of sandboxir::Instruction.
330
+ assert (is_sorted (getLLVMInstrs (),
331
+ [](auto *I1, auto *I2) { return I1->comesBefore (I2); }) &&
332
+ " Expected program order!" );
333
+ // Do the actual move in LLVM IR.
334
+ for (auto *I : getLLVMInstrs ())
335
+ I->moveBefore (*LLVMBB, It);
336
+ }
337
+
338
+ void Instruction::insertBefore (Instruction *BeforeI) {
339
+ llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction ();
340
+ // TODO: Move this to the verifier of sandboxir::Instruction.
341
+ assert (is_sorted (getLLVMInstrs (),
342
+ [](auto *I1, auto *I2) { return I1->comesBefore (I2); }) &&
343
+ " Expected program order!" );
344
+ for (llvm::Instruction *I : getLLVMInstrs ())
345
+ I->insertBefore (BeforeTopI);
346
+ }
347
+
348
+ void Instruction::insertAfter (Instruction *AfterI) {
349
+ insertInto (AfterI->getParent (), std::next (AfterI->getIterator ()));
350
+ }
351
+
352
+ void Instruction::insertInto (BasicBlock *BB, const BBIterator &WhereIt) {
353
+ llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val );
354
+ llvm::Instruction *LLVMBeforeI;
355
+ llvm::BasicBlock::iterator LLVMBeforeIt;
356
+ if (WhereIt != BB->end ()) {
357
+ Instruction *BeforeI = &*WhereIt;
358
+ LLVMBeforeI = BeforeI->getTopmostLLVMInstruction ();
359
+ LLVMBeforeIt = LLVMBeforeI->getIterator ();
360
+ } else {
361
+ LLVMBeforeI = nullptr ;
362
+ LLVMBeforeIt = LLVMBB->end ();
363
+ }
364
+ for (llvm::Instruction *I : reverse (getLLVMInstrs ()))
365
+ I->insertInto (LLVMBB, LLVMBeforeIt);
366
+ }
367
+
368
+ BasicBlock *Instruction::getParent () const {
369
+ auto *BB = cast<llvm::Instruction>(Val)->getParent ();
370
+ if (BB == nullptr )
371
+ return nullptr ;
372
+ return cast<BasicBlock>(Ctx.getValue (BB));
373
+ }
374
+
265
375
bool Instruction::classof (const sandboxir::Value *From) {
266
376
switch (From->getSubclassID ()) {
267
377
#define DEF_INSTR (ID, OPC, CLASS ) \
@@ -344,6 +454,24 @@ BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
344
454
return cast_or_null<Instruction>(Ctx->getValue (&*It));
345
455
}
346
456
457
+ std::unique_ptr<Value> Context::detachLLVMValue (llvm::Value *V) {
458
+ std::unique_ptr<Value> Erased;
459
+ auto It = LLVMValueToValueMap.find (V);
460
+ if (It != LLVMValueToValueMap.end ()) {
461
+ auto *Val = It->second .release ();
462
+ Erased = std::unique_ptr<Value>(Val);
463
+ LLVMValueToValueMap.erase (It);
464
+ }
465
+ return Erased;
466
+ }
467
+
468
+ std::unique_ptr<Value> Context::detach (Value *V) {
469
+ assert (V->getSubclassID () != Value::ClassID::Constant &&
470
+ " Can't detach a constant!" );
471
+ assert (V->getSubclassID () != Value::ClassID::User && " Can't detach a user!" );
472
+ return detachLLVMValue (V->Val );
473
+ }
474
+
347
475
Value *Context::registerValue (std::unique_ptr<Value> &&VPtr) {
348
476
assert (VPtr->getSubclassID () != Value::ClassID::User &&
349
477
" Can't register a user!" );
0 commit comments