@@ -262,6 +262,115 @@ 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+ // 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+
265374bool Instruction::classof (const sandboxir::Value *From) {
266375 switch (From->getSubclassID ()) {
267376#define DEF_INSTR (ID, OPC, CLASS ) \
@@ -344,6 +453,24 @@ BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
344453 return cast_or_null<Instruction>(Ctx->getValue (&*It));
345454}
346455
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+
347474Value *Context::registerValue (std::unique_ptr<Value> &&VPtr) {
348475 assert (VPtr->getSubclassID () != Value::ClassID::User &&
349476 " Can't register a user!" );
0 commit comments