1 //===- SandboxIR.cpp - A transactional overlay IR on top of LLVM IR -------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/SandboxIR/SandboxIR.h" 10 #include "llvm/ADT/SmallPtrSet.h" 11 #include "llvm/IR/Constants.h" 12 #include "llvm/Support/Debug.h" 13 #include <sstream> 14 15 using namespace llvm::sandboxir; 16 17 Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); } 18 19 void Use::set(Value *V) { LLVMUse->set(V->Val); } 20 21 unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); } 22 23 #ifndef NDEBUG 24 void Use::dump(raw_ostream &OS) const { 25 Value *Def = nullptr; 26 if (LLVMUse == nullptr) 27 OS << "<null> LLVM Use! "; 28 else 29 Def = Ctx->getValue(LLVMUse->get()); 30 OS << "Def: "; 31 if (Def == nullptr) 32 OS << "NULL"; 33 else 34 OS << *Def; 35 OS << "\n"; 36 37 OS << "User: "; 38 if (Usr == nullptr) 39 OS << "NULL"; 40 else 41 OS << *Usr; 42 OS << "\n"; 43 44 OS << "OperandNo: "; 45 if (Usr == nullptr) 46 OS << "N/A"; 47 else 48 OS << getOperandNo(); 49 OS << "\n"; 50 } 51 52 void Use::dump() const { dump(dbgs()); } 53 #endif // NDEBUG 54 55 Use OperandUseIterator::operator*() const { return Use; } 56 57 OperandUseIterator &OperandUseIterator::operator++() { 58 assert(Use.LLVMUse != nullptr && "Already at end!"); 59 User *User = Use.getUser(); 60 Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false); 61 return *this; 62 } 63 64 UserUseIterator &UserUseIterator::operator++() { 65 // Get the corresponding llvm::Use, get the next in the list, and update the 66 // sandboxir::Use. 67 llvm::Use *&LLVMUse = Use.LLVMUse; 68 assert(LLVMUse != nullptr && "Already at end!"); 69 LLVMUse = LLVMUse->getNext(); 70 if (LLVMUse == nullptr) { 71 Use.Usr = nullptr; 72 return *this; 73 } 74 auto *Ctx = Use.Ctx; 75 auto *LLVMUser = LLVMUse->getUser(); 76 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser)); 77 return *this; 78 } 79 80 Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx) 81 : SubclassID(SubclassID), Val(Val), Ctx(Ctx) { 82 #ifndef NDEBUG 83 UID = Ctx.getNumValues(); 84 #endif 85 } 86 87 Value::use_iterator Value::use_begin() { 88 llvm::Use *LLVMUse = nullptr; 89 if (Val->use_begin() != Val->use_end()) 90 LLVMUse = &*Val->use_begin(); 91 User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue( 92 Val->use_begin()->getUser())) 93 : nullptr; 94 return use_iterator(Use(LLVMUse, User, Ctx)); 95 } 96 97 Value::user_iterator Value::user_begin() { 98 auto UseBegin = Val->use_begin(); 99 auto UseEnd = Val->use_end(); 100 bool AtEnd = UseBegin == UseEnd; 101 llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin; 102 User *User = 103 AtEnd ? nullptr 104 : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser())); 105 return user_iterator(Use(LLVMUse, User, Ctx), UseToUser()); 106 } 107 108 unsigned Value::getNumUses() const { return range_size(Val->users()); } 109 110 void Value::replaceUsesWithIf( 111 Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) { 112 assert(getType() == OtherV->getType() && "Can't replace with different type"); 113 llvm::Value *OtherVal = OtherV->Val; 114 // We are delegating RUWIf to LLVM IR's RUWIf. 115 Val->replaceUsesWithIf( 116 OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool { 117 User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser())); 118 if (DstU == nullptr) 119 return false; 120 Use UseToReplace(&LLVMUse, DstU, Ctx); 121 if (!ShouldReplace(UseToReplace)) 122 return false; 123 auto &Tracker = Ctx.getTracker(); 124 if (Tracker.isTracking()) 125 Tracker.track(std::make_unique<UseSet>(UseToReplace, Tracker)); 126 return true; 127 }); 128 } 129 130 void Value::replaceAllUsesWith(Value *Other) { 131 assert(getType() == Other->getType() && 132 "Replacing with Value of different type!"); 133 auto &Tracker = Ctx.getTracker(); 134 if (Tracker.isTracking()) { 135 for (auto Use : uses()) 136 Tracker.track(std::make_unique<UseSet>(Use, Tracker)); 137 } 138 // We are delegating RAUW to LLVM IR's RAUW. 139 Val->replaceAllUsesWith(Other->Val); 140 } 141 142 #ifndef NDEBUG 143 std::string Value::getUid() const { 144 std::stringstream SS; 145 SS << "SB" << UID << "."; 146 return SS.str(); 147 } 148 149 void Value::dumpCommonHeader(raw_ostream &OS) const { 150 OS << getUid() << " " << getSubclassIDStr(SubclassID) << " "; 151 } 152 153 void Value::dumpCommonFooter(raw_ostream &OS) const { 154 OS.indent(2) << "Val: "; 155 if (Val) 156 OS << *Val; 157 else 158 OS << "NULL"; 159 OS << "\n"; 160 } 161 162 void Value::dumpCommonPrefix(raw_ostream &OS) const { 163 if (Val) 164 OS << *Val; 165 else 166 OS << "NULL "; 167 } 168 169 void Value::dumpCommonSuffix(raw_ostream &OS) const { 170 OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")"; 171 } 172 173 void Value::printAsOperandCommon(raw_ostream &OS) const { 174 if (Val) 175 Val->printAsOperand(OS); 176 else 177 OS << "NULL "; 178 } 179 180 void Argument::printAsOperand(raw_ostream &OS) const { 181 printAsOperandCommon(OS); 182 } 183 void Argument::dump(raw_ostream &OS) const { 184 dumpCommonPrefix(OS); 185 dumpCommonSuffix(OS); 186 } 187 void Argument::dump() const { 188 dump(dbgs()); 189 dbgs() << "\n"; 190 } 191 #endif // NDEBUG 192 193 Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const { 194 assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!"); 195 assert(isa<llvm::User>(Val) && "Non-users have no operands!"); 196 llvm::Use *LLVMUse; 197 if (OpIdx != getNumOperands()) 198 LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx); 199 else 200 LLVMUse = cast<llvm::User>(Val)->op_end(); 201 return Use(LLVMUse, const_cast<User *>(this), Ctx); 202 } 203 204 #ifndef NDEBUG 205 void User::verifyUserOfLLVMUse(const llvm::Use &Use) const { 206 assert(Ctx.getValue(Use.getUser()) == this && 207 "Use not found in this SBUser's operands!"); 208 } 209 #endif 210 211 bool User::classof(const Value *From) { 212 switch (From->getSubclassID()) { 213 #define DEF_VALUE(ID, CLASS) 214 #define DEF_USER(ID, CLASS) \ 215 case ClassID::ID: \ 216 return true; 217 #define DEF_INSTR(ID, OPC, CLASS) \ 218 case ClassID::ID: \ 219 return true; 220 #include "llvm/SandboxIR/SandboxIRValues.def" 221 default: 222 return false; 223 } 224 } 225 226 void User::setOperand(unsigned OperandIdx, Value *Operand) { 227 assert(isa<llvm::User>(Val) && "No operands!"); 228 auto &Tracker = Ctx.getTracker(); 229 if (Tracker.isTracking()) 230 Tracker.track(std::make_unique<UseSet>(getOperandUse(OperandIdx), Tracker)); 231 // We are delegating to llvm::User::setOperand(). 232 cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val); 233 } 234 235 bool User::replaceUsesOfWith(Value *FromV, Value *ToV) { 236 auto &Tracker = Ctx.getTracker(); 237 if (Tracker.isTracking()) { 238 for (auto OpIdx : seq<unsigned>(0, getNumOperands())) { 239 auto Use = getOperandUse(OpIdx); 240 if (Use.get() == FromV) 241 Tracker.track(std::make_unique<UseSet>(Use, Tracker)); 242 } 243 } 244 // We are delegating RUOW to LLVM IR's RUOW. 245 return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val); 246 } 247 248 #ifndef NDEBUG 249 void User::dumpCommonHeader(raw_ostream &OS) const { 250 Value::dumpCommonHeader(OS); 251 // TODO: This is incomplete 252 } 253 #endif // NDEBUG 254 255 BBIterator &BBIterator::operator++() { 256 auto ItE = BB->end(); 257 assert(It != ItE && "Already at end!"); 258 ++It; 259 if (It == ItE) 260 return *this; 261 Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It)); 262 unsigned Num = NextI.getNumOfIRInstrs(); 263 assert(Num > 0 && "Bad getNumOfIRInstrs()"); 264 It = std::next(It, Num - 1); 265 return *this; 266 } 267 268 BBIterator &BBIterator::operator--() { 269 assert(It != BB->begin() && "Already at begin!"); 270 if (It == BB->end()) { 271 --It; 272 return *this; 273 } 274 Instruction &CurrI = **this; 275 unsigned Num = CurrI.getNumOfIRInstrs(); 276 assert(Num > 0 && "Bad getNumOfIRInstrs()"); 277 assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!"); 278 It = std::prev(It, Num); 279 return *this; 280 } 281 282 const char *Instruction::getOpcodeName(Opcode Opc) { 283 switch (Opc) { 284 #define DEF_VALUE(ID, CLASS) 285 #define DEF_USER(ID, CLASS) 286 #define OP(OPC) \ 287 case Opcode::OPC: \ 288 return #OPC; 289 #define DEF_INSTR(ID, OPC, CLASS) OPC 290 #include "llvm/SandboxIR/SandboxIRValues.def" 291 } 292 llvm_unreachable("Unknown Opcode"); 293 } 294 295 llvm::Instruction *Instruction::getTopmostLLVMInstruction() const { 296 Instruction *Prev = getPrevNode(); 297 if (Prev == nullptr) { 298 // If at top of the BB, return the first BB instruction. 299 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin(); 300 } 301 // Else get the Previous sandbox IR instruction's bottom IR instruction and 302 // return its successor. 303 llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val); 304 return PrevBotI->getNextNode(); 305 } 306 307 BBIterator Instruction::getIterator() const { 308 auto *I = cast<llvm::Instruction>(Val); 309 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx); 310 } 311 312 Instruction *Instruction::getNextNode() const { 313 assert(getParent() != nullptr && "Detached!"); 314 assert(getIterator() != getParent()->end() && "Already at end!"); 315 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain, 316 // and get the corresponding sandboxir Instruction that maps to it. This works 317 // even for SandboxIR Instructions that map to more than one LLVM Instruction. 318 auto *LLVMI = cast<llvm::Instruction>(Val); 319 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!"); 320 auto *NextLLVMI = LLVMI->getNextNode(); 321 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI)); 322 if (NextI == nullptr) 323 return nullptr; 324 return NextI; 325 } 326 327 Instruction *Instruction::getPrevNode() const { 328 assert(getParent() != nullptr && "Detached!"); 329 auto It = getIterator(); 330 if (It != getParent()->begin()) 331 return std::prev(getIterator()).get(); 332 return nullptr; 333 } 334 335 void Instruction::removeFromParent() { 336 auto &Tracker = Ctx.getTracker(); 337 if (Tracker.isTracking()) 338 Tracker.track(std::make_unique<RemoveFromParent>(this, Tracker)); 339 340 // Detach all the LLVM IR instructions from their parent BB. 341 for (llvm::Instruction *I : getLLVMInstrs()) 342 I->removeFromParent(); 343 } 344 345 void Instruction::eraseFromParent() { 346 assert(users().empty() && "Still connected to users, can't erase!"); 347 std::unique_ptr<Value> Detached = Ctx.detach(this); 348 auto LLVMInstrs = getLLVMInstrs(); 349 350 auto &Tracker = Ctx.getTracker(); 351 if (Tracker.isTracking()) { 352 Tracker.track( 353 std::make_unique<EraseFromParent>(std::move(Detached), Tracker)); 354 // We don't actually delete the IR instruction, because then it would be 355 // impossible to bring it back from the dead at the same memory location. 356 // Instead we remove it from its BB and track its current location. 357 for (llvm::Instruction *I : LLVMInstrs) 358 I->removeFromParent(); 359 // TODO: Multi-instructions need special treatment because some of the 360 // references are internal to the instruction. 361 for (llvm::Instruction *I : LLVMInstrs) 362 I->dropAllReferences(); 363 } else { 364 // Erase in reverse to avoid erasing nstructions with attached uses. 365 for (llvm::Instruction *I : reverse(LLVMInstrs)) 366 I->eraseFromParent(); 367 } 368 } 369 370 void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) { 371 if (std::next(getIterator()) == WhereIt) 372 // Destination is same as origin, nothing to do. 373 return; 374 375 auto &Tracker = Ctx.getTracker(); 376 if (Tracker.isTracking()) 377 Tracker.track(std::make_unique<MoveInstr>(this, Tracker)); 378 379 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val); 380 llvm::BasicBlock::iterator It; 381 if (WhereIt == BB.end()) { 382 It = LLVMBB->end(); 383 } else { 384 Instruction *WhereI = &*WhereIt; 385 It = WhereI->getTopmostLLVMInstruction()->getIterator(); 386 } 387 // TODO: Move this to the verifier of sandboxir::Instruction. 388 assert(is_sorted(getLLVMInstrs(), 389 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) && 390 "Expected program order!"); 391 // Do the actual move in LLVM IR. 392 for (auto *I : getLLVMInstrs()) 393 I->moveBefore(*LLVMBB, It); 394 } 395 396 void Instruction::insertBefore(Instruction *BeforeI) { 397 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction(); 398 // TODO: Move this to the verifier of sandboxir::Instruction. 399 assert(is_sorted(getLLVMInstrs(), 400 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) && 401 "Expected program order!"); 402 // Insert the LLVM IR Instructions in program order. 403 for (llvm::Instruction *I : getLLVMInstrs()) 404 I->insertBefore(BeforeTopI); 405 } 406 407 void Instruction::insertAfter(Instruction *AfterI) { 408 insertInto(AfterI->getParent(), std::next(AfterI->getIterator())); 409 } 410 411 void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) { 412 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val); 413 llvm::Instruction *LLVMBeforeI; 414 llvm::BasicBlock::iterator LLVMBeforeIt; 415 if (WhereIt != BB->end()) { 416 Instruction *BeforeI = &*WhereIt; 417 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction(); 418 LLVMBeforeIt = LLVMBeforeI->getIterator(); 419 } else { 420 LLVMBeforeI = nullptr; 421 LLVMBeforeIt = LLVMBB->end(); 422 } 423 // Insert the LLVM IR Instructions in program order. 424 for (llvm::Instruction *I : getLLVMInstrs()) 425 I->insertInto(LLVMBB, LLVMBeforeIt); 426 } 427 428 BasicBlock *Instruction::getParent() const { 429 // Get the LLVM IR Instruction that this maps to, get its parent, and get the 430 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context. 431 auto *BB = cast<llvm::Instruction>(Val)->getParent(); 432 if (BB == nullptr) 433 return nullptr; 434 return cast<BasicBlock>(Ctx.getValue(BB)); 435 } 436 437 bool Instruction::classof(const sandboxir::Value *From) { 438 switch (From->getSubclassID()) { 439 #define DEF_INSTR(ID, OPC, CLASS) \ 440 case ClassID::ID: \ 441 return true; 442 #include "llvm/SandboxIR/SandboxIRValues.def" 443 default: 444 return false; 445 } 446 } 447 448 #ifndef NDEBUG 449 void Instruction::dump(raw_ostream &OS) const { 450 OS << "Unimplemented! Please override dump()."; 451 } 452 void Instruction::dump() const { 453 dump(dbgs()); 454 dbgs() << "\n"; 455 } 456 #endif // NDEBUG 457 458 Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False, 459 const Twine &Name, IRBuilder<> &Builder, 460 Context &Ctx) { 461 llvm::Value *NewV = 462 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name); 463 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV)) 464 return Ctx.createSelectInst(NewSI); 465 assert(isa<llvm::Constant>(NewV) && "Expected constant"); 466 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV)); 467 } 468 469 Value *SelectInst::create(Value *Cond, Value *True, Value *False, 470 Instruction *InsertBefore, Context &Ctx, 471 const Twine &Name) { 472 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction(); 473 auto &Builder = Ctx.getLLVMIRBuilder(); 474 Builder.SetInsertPoint(BeforeIR); 475 return createCommon(Cond, True, False, Name, Builder, Ctx); 476 } 477 478 Value *SelectInst::create(Value *Cond, Value *True, Value *False, 479 BasicBlock *InsertAtEnd, Context &Ctx, 480 const Twine &Name) { 481 auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->Val); 482 auto &Builder = Ctx.getLLVMIRBuilder(); 483 Builder.SetInsertPoint(IRInsertAtEnd); 484 return createCommon(Cond, True, False, Name, Builder, Ctx); 485 } 486 487 bool SelectInst::classof(const Value *From) { 488 return From->getSubclassID() == ClassID::Select; 489 } 490 491 #ifndef NDEBUG 492 void SelectInst::dump(raw_ostream &OS) const { 493 dumpCommonPrefix(OS); 494 dumpCommonSuffix(OS); 495 } 496 497 void SelectInst::dump() const { 498 dump(dbgs()); 499 dbgs() << "\n"; 500 } 501 #endif // NDEBUG 502 503 LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align, 504 Instruction *InsertBefore, Context &Ctx, 505 const Twine &Name) { 506 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction(); 507 auto &Builder = Ctx.getLLVMIRBuilder(); 508 Builder.SetInsertPoint(BeforeIR); 509 auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, 510 /*isVolatile=*/false, Name); 511 auto *NewSBI = Ctx.createLoadInst(NewLI); 512 return NewSBI; 513 } 514 515 LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align, 516 BasicBlock *InsertAtEnd, Context &Ctx, 517 const Twine &Name) { 518 auto &Builder = Ctx.getLLVMIRBuilder(); 519 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val)); 520 auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, 521 /*isVolatile=*/false, Name); 522 auto *NewSBI = Ctx.createLoadInst(NewLI); 523 return NewSBI; 524 } 525 526 bool LoadInst::classof(const Value *From) { 527 return From->getSubclassID() == ClassID::Load; 528 } 529 530 Value *LoadInst::getPointerOperand() const { 531 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand()); 532 } 533 534 #ifndef NDEBUG 535 void LoadInst::dump(raw_ostream &OS) const { 536 dumpCommonPrefix(OS); 537 dumpCommonSuffix(OS); 538 } 539 540 void LoadInst::dump() const { 541 dump(dbgs()); 542 dbgs() << "\n"; 543 } 544 #endif // NDEBUG 545 StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, 546 Instruction *InsertBefore, Context &Ctx) { 547 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction(); 548 auto &Builder = Ctx.getLLVMIRBuilder(); 549 Builder.SetInsertPoint(BeforeIR); 550 auto *NewSI = 551 Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false); 552 auto *NewSBI = Ctx.createStoreInst(NewSI); 553 return NewSBI; 554 } 555 StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align, 556 BasicBlock *InsertAtEnd, Context &Ctx) { 557 auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val); 558 auto &Builder = Ctx.getLLVMIRBuilder(); 559 Builder.SetInsertPoint(InsertAtEndIR); 560 auto *NewSI = 561 Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false); 562 auto *NewSBI = Ctx.createStoreInst(NewSI); 563 return NewSBI; 564 } 565 566 bool StoreInst::classof(const Value *From) { 567 return From->getSubclassID() == ClassID::Store; 568 } 569 570 Value *StoreInst::getValueOperand() const { 571 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand()); 572 } 573 574 Value *StoreInst::getPointerOperand() const { 575 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand()); 576 } 577 578 #ifndef NDEBUG 579 void StoreInst::dump(raw_ostream &OS) const { 580 dumpCommonPrefix(OS); 581 dumpCommonSuffix(OS); 582 } 583 584 void StoreInst::dump() const { 585 dump(dbgs()); 586 dbgs() << "\n"; 587 } 588 #endif // NDEBUG 589 590 ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder, 591 Context &Ctx) { 592 llvm::ReturnInst *NewRI; 593 if (RetVal != nullptr) 594 NewRI = Builder.CreateRet(RetVal->Val); 595 else 596 NewRI = Builder.CreateRetVoid(); 597 return Ctx.createReturnInst(NewRI); 598 } 599 600 ReturnInst *ReturnInst::create(Value *RetVal, Instruction *InsertBefore, 601 Context &Ctx) { 602 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction(); 603 auto &Builder = Ctx.getLLVMIRBuilder(); 604 Builder.SetInsertPoint(BeforeIR); 605 return createCommon(RetVal, Builder, Ctx); 606 } 607 608 ReturnInst *ReturnInst::create(Value *RetVal, BasicBlock *InsertAtEnd, 609 Context &Ctx) { 610 auto &Builder = Ctx.getLLVMIRBuilder(); 611 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val)); 612 return createCommon(RetVal, Builder, Ctx); 613 } 614 615 Value *ReturnInst::getReturnValue() const { 616 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue(); 617 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr; 618 } 619 620 #ifndef NDEBUG 621 void ReturnInst::dump(raw_ostream &OS) const { 622 dumpCommonPrefix(OS); 623 dumpCommonSuffix(OS); 624 } 625 626 void ReturnInst::dump() const { 627 dump(dbgs()); 628 dbgs() << "\n"; 629 } 630 631 void OpaqueInst::dump(raw_ostream &OS) const { 632 dumpCommonPrefix(OS); 633 dumpCommonSuffix(OS); 634 } 635 636 void OpaqueInst::dump() const { 637 dump(dbgs()); 638 dbgs() << "\n"; 639 } 640 #endif // NDEBUG 641 642 Constant *Constant::createInt(Type *Ty, uint64_t V, Context &Ctx, 643 bool IsSigned) { 644 llvm::Constant *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned); 645 return Ctx.getOrCreateConstant(LLVMC); 646 } 647 648 #ifndef NDEBUG 649 void Constant::dump(raw_ostream &OS) const { 650 dumpCommonPrefix(OS); 651 dumpCommonSuffix(OS); 652 } 653 654 void Constant::dump() const { 655 dump(dbgs()); 656 dbgs() << "\n"; 657 } 658 659 void Function::dumpNameAndArgs(raw_ostream &OS) const { 660 auto *F = cast<llvm::Function>(Val); 661 OS << *F->getReturnType() << " @" << F->getName() << "("; 662 interleave( 663 F->args(), 664 [this, &OS](const llvm::Argument &LLVMArg) { 665 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg)); 666 if (SBArg == nullptr) 667 OS << "NULL"; 668 else 669 SBArg->printAsOperand(OS); 670 }, 671 [&] { OS << ", "; }); 672 OS << ")"; 673 } 674 void Function::dump(raw_ostream &OS) const { 675 dumpNameAndArgs(OS); 676 OS << " {\n"; 677 auto *LLVMF = cast<llvm::Function>(Val); 678 interleave( 679 *LLVMF, 680 [this, &OS](const llvm::BasicBlock &LLVMBB) { 681 auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB)); 682 if (BB == nullptr) 683 OS << "NULL"; 684 else 685 OS << *BB; 686 }, 687 [&OS] { OS << "\n"; }); 688 OS << "}\n"; 689 } 690 void Function::dump() const { 691 dump(dbgs()); 692 dbgs() << "\n"; 693 } 694 #endif // NDEBUG 695 696 BasicBlock::iterator::pointer 697 BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const { 698 return cast_or_null<Instruction>(Ctx->getValue(&*It)); 699 } 700 701 std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) { 702 std::unique_ptr<Value> Erased; 703 auto It = LLVMValueToValueMap.find(V); 704 if (It != LLVMValueToValueMap.end()) { 705 auto *Val = It->second.release(); 706 Erased = std::unique_ptr<Value>(Val); 707 LLVMValueToValueMap.erase(It); 708 } 709 return Erased; 710 } 711 712 std::unique_ptr<Value> Context::detach(Value *V) { 713 assert(V->getSubclassID() != Value::ClassID::Constant && 714 "Can't detach a constant!"); 715 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!"); 716 return detachLLVMValue(V->Val); 717 } 718 719 Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) { 720 assert(VPtr->getSubclassID() != Value::ClassID::User && 721 "Can't register a user!"); 722 Value *V = VPtr.get(); 723 [[maybe_unused]] auto Pair = 724 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)}); 725 assert(Pair.second && "Already exists!"); 726 return V; 727 } 728 729 Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) { 730 auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr}); 731 auto It = Pair.first; 732 if (!Pair.second) 733 return It->second.get(); 734 735 if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) { 736 It->second = std::unique_ptr<Constant>(new Constant(C, *this)); 737 auto *NewC = It->second.get(); 738 for (llvm::Value *COp : C->operands()) 739 getOrCreateValueInternal(COp, C); 740 return NewC; 741 } 742 if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) { 743 It->second = std::unique_ptr<Argument>(new Argument(Arg, *this)); 744 return It->second.get(); 745 } 746 if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) { 747 assert(isa<BlockAddress>(U) && 748 "This won't create a SBBB, don't call this function directly!"); 749 if (auto *SBBB = getValue(BB)) 750 return SBBB; 751 return nullptr; 752 } 753 assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction"); 754 755 switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) { 756 case llvm::Instruction::Select: { 757 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV); 758 It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this)); 759 return It->second.get(); 760 } 761 case llvm::Instruction::Load: { 762 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV); 763 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this)); 764 return It->second.get(); 765 } 766 case llvm::Instruction::Store: { 767 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV); 768 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this)); 769 return It->second.get(); 770 } 771 case llvm::Instruction::Ret: { 772 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV); 773 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this)); 774 return It->second.get(); 775 } 776 default: 777 break; 778 } 779 780 It->second = std::unique_ptr<OpaqueInst>( 781 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this)); 782 return It->second.get(); 783 } 784 785 BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) { 786 assert(getValue(LLVMBB) == nullptr && "Already exists!"); 787 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this)); 788 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr))); 789 // Create SandboxIR for BB's body. 790 BB->buildBasicBlockFromLLVMIR(LLVMBB); 791 return BB; 792 } 793 794 SelectInst *Context::createSelectInst(llvm::SelectInst *SI) { 795 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this)); 796 return cast<SelectInst>(registerValue(std::move(NewPtr))); 797 } 798 799 LoadInst *Context::createLoadInst(llvm::LoadInst *LI) { 800 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this)); 801 return cast<LoadInst>(registerValue(std::move(NewPtr))); 802 } 803 804 StoreInst *Context::createStoreInst(llvm::StoreInst *SI) { 805 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this)); 806 return cast<StoreInst>(registerValue(std::move(NewPtr))); 807 } 808 809 ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) { 810 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this)); 811 return cast<ReturnInst>(registerValue(std::move(NewPtr))); 812 } 813 814 Value *Context::getValue(llvm::Value *V) const { 815 auto It = LLVMValueToValueMap.find(V); 816 if (It != LLVMValueToValueMap.end()) 817 return It->second.get(); 818 return nullptr; 819 } 820 821 Function *Context::createFunction(llvm::Function *F) { 822 assert(getValue(F) == nullptr && "Already exists!"); 823 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this)); 824 // Create arguments. 825 for (auto &Arg : F->args()) 826 getOrCreateArgument(&Arg); 827 // Create BBs. 828 for (auto &BB : *F) 829 createBasicBlock(&BB); 830 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr))); 831 return SBF; 832 } 833 834 Function *BasicBlock::getParent() const { 835 auto *BB = cast<llvm::BasicBlock>(Val); 836 auto *F = BB->getParent(); 837 if (F == nullptr) 838 // Detached 839 return nullptr; 840 return cast_or_null<Function>(Ctx.getValue(F)); 841 } 842 843 void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) { 844 for (llvm::Instruction &IRef : reverse(*LLVMBB)) { 845 llvm::Instruction *I = &IRef; 846 Ctx.getOrCreateValue(I); 847 for (auto [OpIdx, Op] : enumerate(I->operands())) { 848 // Skip instruction's label operands 849 if (isa<llvm::BasicBlock>(Op)) 850 continue; 851 // Skip metadata 852 if (isa<llvm::MetadataAsValue>(Op)) 853 continue; 854 // Skip asm 855 if (isa<llvm::InlineAsm>(Op)) 856 continue; 857 Ctx.getOrCreateValue(Op); 858 } 859 } 860 #if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS) 861 verify(); 862 #endif 863 } 864 865 BasicBlock::iterator BasicBlock::begin() const { 866 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val); 867 llvm::BasicBlock::iterator It = BB->begin(); 868 if (!BB->empty()) { 869 auto *V = Ctx.getValue(&*BB->begin()); 870 assert(V != nullptr && "No SandboxIR for BB->begin()!"); 871 auto *I = cast<Instruction>(V); 872 unsigned Num = I->getNumOfIRInstrs(); 873 assert(Num >= 1u && "Bad getNumOfIRInstrs()"); 874 It = std::next(It, Num - 1); 875 } 876 return iterator(BB, It, &Ctx); 877 } 878 879 Instruction *BasicBlock::getTerminator() const { 880 auto *TerminatorV = 881 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator()); 882 return cast_or_null<Instruction>(TerminatorV); 883 } 884 885 Instruction &BasicBlock::front() const { 886 auto *BB = cast<llvm::BasicBlock>(Val); 887 assert(!BB->empty() && "Empty block!"); 888 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin())); 889 assert(SBI != nullptr && "Expected Instr!"); 890 return *SBI; 891 } 892 893 Instruction &BasicBlock::back() const { 894 auto *BB = cast<llvm::BasicBlock>(Val); 895 assert(!BB->empty() && "Empty block!"); 896 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin())); 897 assert(SBI != nullptr && "Expected Instr!"); 898 return *SBI; 899 } 900 901 #ifndef NDEBUG 902 void BasicBlock::dump(raw_ostream &OS) const { 903 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val); 904 const auto &Name = BB->getName(); 905 OS << Name; 906 if (!Name.empty()) 907 OS << ":\n"; 908 // If there are Instructions in the BB that are not mapped to SandboxIR, then 909 // use a crash-proof dump. 910 if (any_of(*BB, [this](llvm::Instruction &I) { 911 return Ctx.getValue(&I) == nullptr; 912 })) { 913 OS << "<Crash-proof mode!>\n"; 914 DenseSet<Instruction *> Visited; 915 for (llvm::Instruction &IRef : *BB) { 916 Value *SBV = Ctx.getValue(&IRef); 917 if (SBV == nullptr) 918 OS << IRef << " *** No SandboxIR ***\n"; 919 else { 920 auto *SBI = dyn_cast<Instruction>(SBV); 921 if (SBI == nullptr) { 922 OS << IRef << " *** Not a SBInstruction!!! ***\n"; 923 } else { 924 if (Visited.insert(SBI).second) 925 OS << *SBI << "\n"; 926 } 927 } 928 } 929 } else { 930 for (auto &SBI : *this) { 931 SBI.dump(OS); 932 OS << "\n"; 933 } 934 } 935 } 936 void BasicBlock::dump() const { 937 dump(dbgs()); 938 dbgs() << "\n"; 939 } 940 #endif // NDEBUG 941