diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h index fcb581211736ee..473bd93aea7c10 100644 --- a/llvm/include/llvm/SandboxIR/SandboxIR.h +++ b/llvm/include/llvm/SandboxIR/SandboxIR.h @@ -76,7 +76,8 @@ class Instruction; class User; class Value; -/// Returns the operand edge when dereferenced. +/// Iterator for the `Use` edges of a User's operands. +/// \Returns the operand `Use` when dereferenced. class OperandUseIterator { sandboxir::Use Use; /// Don't let the user create a non-empty OperandUseIterator. @@ -103,7 +104,8 @@ class OperandUseIterator { } }; -/// Returns user edge when dereferenced. +/// Iterator for the `Use` edges of a Value's users. +/// \Returns a `Use` when dereferenced. class UserUseIterator { sandboxir::Use Use; /// Don't let the user create a non-empty UserUseIterator. @@ -162,7 +164,9 @@ class Value { unsigned UID; #endif /// The LLVM Value that corresponds to this SandboxIR Value. - /// NOTE: Some SBInstructions, like Packs, may include more than one value. + /// NOTE: Some sandboxir Instructions, like Packs, may include more than one + /// value and in these cases `Val` points to the last instruction in program + /// order. llvm::Value *Val = nullptr; friend class Context; // For getting `Val`. @@ -300,6 +304,7 @@ class Argument : public sandboxir::Value { #endif }; +/// A sandboxir::User has operands. class User : public Value { protected: User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {} @@ -309,6 +314,9 @@ class User : public Value { /// match the underlying LLVM instruction. All others should use a different /// implementation. Use getOperandUseDefault(unsigned OpIdx, bool Verify) const; + /// \Returns the Use for the \p OpIdx'th operand. This is virtual to allow + /// instructions to deviate from the LLVM IR operands, which is a requirement + /// for sandboxir Instructions that consist of more than one LLVM Instruction. virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0; friend class OperandUseIterator; // for getOperandUseInternal() @@ -414,7 +422,8 @@ class Constant : public sandboxir::User { #endif }; -/// The BasicBlock::iterator. +/// Iterator for `Instruction`s in a `BasicBlock. +/// \Returns an sandboxir::Instruction & when derereferenced. class BBIterator { public: using difference_type = std::ptrdiff_t; @@ -456,7 +465,8 @@ class BBIterator { pointer get() const { return getInstr(It); } }; -/// A sandboxir::User with operands and opcode. +/// A sandboxir::User with operands, opcode and linked with previous/next +/// instructions in an instruction list. class Instruction : public sandboxir::User { public: enum class Opcode { @@ -577,6 +587,7 @@ class OpaqueInst : public sandboxir::Instruction { #endif }; +/// Contains a list of sandboxir::Instruction's. class BasicBlock : public Value { /// Builds a graph that contains all values in \p BB in their original form /// i.e., no vectorization is taking place here. @@ -643,9 +654,10 @@ class Context { friend void Instruction::eraseFromParent(); // For detach(). /// Take ownership of VPtr and store it in `LLVMValueToValueMap`. Value *registerValue(std::unique_ptr &&VPtr); - + /// This is the actual function that creates sandboxir values for \p V, + /// and among others handles all instruction types. Value *getOrCreateValueInternal(llvm::Value *V, llvm::User *U = nullptr); - + /// Get or create a sandboxir::Argument for an existing LLVM IR \p LLVMArg. Argument *getOrCreateArgument(llvm::Argument *LLVMArg) { auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr}); auto It = Pair.first; @@ -655,11 +667,12 @@ class Context { } return cast(It->second.get()); } - + /// Get or create a sandboxir::Value for an existing LLVM IR \p LLVMV. Value *getOrCreateValue(llvm::Value *LLVMV) { return getOrCreateValueInternal(LLVMV, 0); } - + /// Create a sandboxir::BasicBlock for an existing LLVM IR \p BB. This will + /// also create all contents of the block. BasicBlock *createBasicBlock(llvm::BasicBlock *BB); friend class BasicBlock; // For getOrCreateValue(). @@ -671,7 +684,9 @@ class Context { const sandboxir::Value *getValue(const llvm::Value *V) const { return getValue(const_cast(V)); } - + /// Create a sandboxir::Function for an existing LLVM IR \p F, including all + /// blocks and instructions. + /// This is the main API function for creating Sandbox IR. Function *createFunction(llvm::Function *F); /// \Returns the number of values registered with Context. diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp index a3f350e9ca8b03..2984c6eaccd640 100644 --- a/llvm/lib/SandboxIR/SandboxIR.cpp +++ b/llvm/lib/SandboxIR/SandboxIR.cpp @@ -60,6 +60,8 @@ OperandUseIterator &OperandUseIterator::operator++() { } UserUseIterator &UserUseIterator::operator++() { + // Get the corresponding llvm::Use, get the next in the list, and update the + // sandboxir::Use. llvm::Use *&LLVMUse = Use.LLVMUse; assert(LLVMUse != nullptr && "Already at end!"); LLVMUse = LLVMUse->getNext(); @@ -107,6 +109,7 @@ void Value::replaceUsesWithIf( Value *OtherV, llvm::function_ref ShouldReplace) { assert(getType() == OtherV->getType() && "Can't replace with different type"); llvm::Value *OtherVal = OtherV->Val; + // We are delegating RUWIf to LLVM IR's RUWIf. Val->replaceUsesWithIf( OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool { User *DstU = cast_or_null(Ctx.getValue(LLVMUse.getUser())); @@ -119,6 +122,7 @@ void Value::replaceUsesWithIf( void Value::replaceAllUsesWith(Value *Other) { assert(getType() == Other->getType() && "Replacing with Value of different type!"); + // We are delegating RAUW to LLVM IR's RAUW. Val->replaceAllUsesWith(Other->Val); } @@ -208,10 +212,12 @@ bool User::classof(const Value *From) { void User::setOperand(unsigned OperandIdx, Value *Operand) { assert(isa(Val) && "No operands!"); + // We are delegating to llvm::User::setOperand(). cast(Val)->setOperand(OperandIdx, Operand->Val); } bool User::replaceUsesOfWith(Value *FromV, Value *ToV) { + // We are delegating RUOW to LLVM IR's RUOW. return cast(Val)->replaceUsesOfWith(FromV->Val, ToV->Val); } @@ -282,6 +288,9 @@ BBIterator Instruction::getIterator() const { Instruction *Instruction::getNextNode() const { assert(getParent() != nullptr && "Detached!"); assert(getIterator() != getParent()->end() && "Already at end!"); + // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain, + // and get the corresponding sandboxir Instruction that maps to it. This works + // even for SandboxIR Instructions that map to more than one LLVM Instruction. auto *LLVMI = cast(Val); assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!"); auto *NextLLVMI = LLVMI->getNextNode(); @@ -342,6 +351,7 @@ void Instruction::insertBefore(Instruction *BeforeI) { assert(is_sorted(getLLVMInstrs(), [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) && "Expected program order!"); + // Insert the LLVM IR Instructions in program order. for (llvm::Instruction *I : getLLVMInstrs()) I->insertBefore(BeforeTopI); } @@ -362,11 +372,14 @@ void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) { LLVMBeforeI = nullptr; LLVMBeforeIt = LLVMBB->end(); } + // Insert the LLVM IR Instructions in program order. for (llvm::Instruction *I : getLLVMInstrs()) I->insertInto(LLVMBB, LLVMBeforeIt); } BasicBlock *Instruction::getParent() const { + // Get the LLVM IR Instruction that this maps to, get its parent, and get the + // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context. auto *BB = cast(Val)->getParent(); if (BB == nullptr) return nullptr;