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