@@ -262,6 +262,117 @@ const char *Instruction::getOpcodeName(Opcode Opc) {
262262 llvm_unreachable (" Unknown Opcode" );
263263}
264264
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+
265376bool Instruction::classof (const sandboxir::Value *From) {
266377 switch (From->getSubclassID ()) {
267378#define DEF_INSTR (ID, OPC, CLASS ) \
@@ -344,6 +455,24 @@ BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
344455 return cast_or_null<Instruction>(Ctx->getValue (&*It));
345456}
346457
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+
347476Value *Context::registerValue (std::unique_ptr<Value> &&VPtr) {
348477 assert (VPtr->getSubclassID () != Value::ClassID::User &&
349478 " Can't register a user!" );
0 commit comments