[SandboxIR][NFC] Add some comments (#99359)
This commit is contained in:
parent
321a0c0042
commit
ddbf5ea6d4
@ -76,7 +76,8 @@ class Instruction;
|
|||||||
class User;
|
class User;
|
||||||
class Value;
|
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 {
|
class OperandUseIterator {
|
||||||
sandboxir::Use Use;
|
sandboxir::Use Use;
|
||||||
/// Don't let the user create a non-empty OperandUseIterator.
|
/// Don't let the user create a non-empty OperandUseIterator.
|
||||||
@ -103,7 +104,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Returns user edge when dereferenced.
|
/// Iterator for the `Use` edges of a Value's users.
|
||||||
|
/// \Returns a `Use` when dereferenced.
|
||||||
class UserUseIterator {
|
class UserUseIterator {
|
||||||
sandboxir::Use Use;
|
sandboxir::Use Use;
|
||||||
/// Don't let the user create a non-empty UserUseIterator.
|
/// Don't let the user create a non-empty UserUseIterator.
|
||||||
@ -162,7 +164,9 @@ protected:
|
|||||||
unsigned UID;
|
unsigned UID;
|
||||||
#endif
|
#endif
|
||||||
/// The LLVM Value that corresponds to this SandboxIR Value.
|
/// 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;
|
llvm::Value *Val = nullptr;
|
||||||
|
|
||||||
friend class Context; // For getting `Val`.
|
friend class Context; // For getting `Val`.
|
||||||
@ -300,6 +304,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A sandboxir::User has operands.
|
||||||
class User : public Value {
|
class User : public Value {
|
||||||
protected:
|
protected:
|
||||||
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
|
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
|
||||||
@ -309,6 +314,9 @@ protected:
|
|||||||
/// match the underlying LLVM instruction. All others should use a different
|
/// match the underlying LLVM instruction. All others should use a different
|
||||||
/// implementation.
|
/// implementation.
|
||||||
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
|
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;
|
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
|
||||||
friend class OperandUseIterator; // for getOperandUseInternal()
|
friend class OperandUseIterator; // for getOperandUseInternal()
|
||||||
|
|
||||||
@ -414,7 +422,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The BasicBlock::iterator.
|
/// Iterator for `Instruction`s in a `BasicBlock.
|
||||||
|
/// \Returns an sandboxir::Instruction & when derereferenced.
|
||||||
class BBIterator {
|
class BBIterator {
|
||||||
public:
|
public:
|
||||||
using difference_type = std::ptrdiff_t;
|
using difference_type = std::ptrdiff_t;
|
||||||
@ -456,7 +465,8 @@ public:
|
|||||||
pointer get() const { return getInstr(It); }
|
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 {
|
class Instruction : public sandboxir::User {
|
||||||
public:
|
public:
|
||||||
enum class Opcode {
|
enum class Opcode {
|
||||||
@ -577,6 +587,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Contains a list of sandboxir::Instruction's.
|
||||||
class BasicBlock : public Value {
|
class BasicBlock : public Value {
|
||||||
/// Builds a graph that contains all values in \p BB in their original form
|
/// Builds a graph that contains all values in \p BB in their original form
|
||||||
/// i.e., no vectorization is taking place here.
|
/// i.e., no vectorization is taking place here.
|
||||||
@ -643,9 +654,10 @@ protected:
|
|||||||
friend void Instruction::eraseFromParent(); // For detach().
|
friend void Instruction::eraseFromParent(); // For detach().
|
||||||
/// Take ownership of VPtr and store it in `LLVMValueToValueMap`.
|
/// Take ownership of VPtr and store it in `LLVMValueToValueMap`.
|
||||||
Value *registerValue(std::unique_ptr<Value> &&VPtr);
|
Value *registerValue(std::unique_ptr<Value> &&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);
|
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) {
|
Argument *getOrCreateArgument(llvm::Argument *LLVMArg) {
|
||||||
auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr});
|
auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr});
|
||||||
auto It = Pair.first;
|
auto It = Pair.first;
|
||||||
@ -655,11 +667,12 @@ protected:
|
|||||||
}
|
}
|
||||||
return cast<Argument>(It->second.get());
|
return cast<Argument>(It->second.get());
|
||||||
}
|
}
|
||||||
|
/// Get or create a sandboxir::Value for an existing LLVM IR \p LLVMV.
|
||||||
Value *getOrCreateValue(llvm::Value *LLVMV) {
|
Value *getOrCreateValue(llvm::Value *LLVMV) {
|
||||||
return getOrCreateValueInternal(LLVMV, 0);
|
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);
|
BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
|
||||||
|
|
||||||
friend class BasicBlock; // For getOrCreateValue().
|
friend class BasicBlock; // For getOrCreateValue().
|
||||||
@ -671,7 +684,9 @@ public:
|
|||||||
const sandboxir::Value *getValue(const llvm::Value *V) const {
|
const sandboxir::Value *getValue(const llvm::Value *V) const {
|
||||||
return getValue(const_cast<llvm::Value *>(V));
|
return getValue(const_cast<llvm::Value *>(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);
|
Function *createFunction(llvm::Function *F);
|
||||||
|
|
||||||
/// \Returns the number of values registered with Context.
|
/// \Returns the number of values registered with Context.
|
||||||
|
@ -60,6 +60,8 @@ OperandUseIterator &OperandUseIterator::operator++() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UserUseIterator &UserUseIterator::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;
|
llvm::Use *&LLVMUse = Use.LLVMUse;
|
||||||
assert(LLVMUse != nullptr && "Already at end!");
|
assert(LLVMUse != nullptr && "Already at end!");
|
||||||
LLVMUse = LLVMUse->getNext();
|
LLVMUse = LLVMUse->getNext();
|
||||||
@ -107,6 +109,7 @@ void Value::replaceUsesWithIf(
|
|||||||
Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
|
Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
|
||||||
assert(getType() == OtherV->getType() && "Can't replace with different type");
|
assert(getType() == OtherV->getType() && "Can't replace with different type");
|
||||||
llvm::Value *OtherVal = OtherV->Val;
|
llvm::Value *OtherVal = OtherV->Val;
|
||||||
|
// We are delegating RUWIf to LLVM IR's RUWIf.
|
||||||
Val->replaceUsesWithIf(
|
Val->replaceUsesWithIf(
|
||||||
OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool {
|
OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool {
|
||||||
User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
|
User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
|
||||||
@ -119,6 +122,7 @@ void Value::replaceUsesWithIf(
|
|||||||
void Value::replaceAllUsesWith(Value *Other) {
|
void Value::replaceAllUsesWith(Value *Other) {
|
||||||
assert(getType() == Other->getType() &&
|
assert(getType() == Other->getType() &&
|
||||||
"Replacing with Value of different type!");
|
"Replacing with Value of different type!");
|
||||||
|
// We are delegating RAUW to LLVM IR's RAUW.
|
||||||
Val->replaceAllUsesWith(Other->Val);
|
Val->replaceAllUsesWith(Other->Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,10 +212,12 @@ bool User::classof(const Value *From) {
|
|||||||
|
|
||||||
void User::setOperand(unsigned OperandIdx, Value *Operand) {
|
void User::setOperand(unsigned OperandIdx, Value *Operand) {
|
||||||
assert(isa<llvm::User>(Val) && "No operands!");
|
assert(isa<llvm::User>(Val) && "No operands!");
|
||||||
|
// We are delegating to llvm::User::setOperand().
|
||||||
cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
|
cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool User::replaceUsesOfWith(Value *FromV, Value *ToV) {
|
bool User::replaceUsesOfWith(Value *FromV, Value *ToV) {
|
||||||
|
// We are delegating RUOW to LLVM IR's RUOW.
|
||||||
return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
|
return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +288,9 @@ BBIterator Instruction::getIterator() const {
|
|||||||
Instruction *Instruction::getNextNode() const {
|
Instruction *Instruction::getNextNode() const {
|
||||||
assert(getParent() != nullptr && "Detached!");
|
assert(getParent() != nullptr && "Detached!");
|
||||||
assert(getIterator() != getParent()->end() && "Already at end!");
|
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<llvm::Instruction>(Val);
|
auto *LLVMI = cast<llvm::Instruction>(Val);
|
||||||
assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
|
assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
|
||||||
auto *NextLLVMI = LLVMI->getNextNode();
|
auto *NextLLVMI = LLVMI->getNextNode();
|
||||||
@ -342,6 +351,7 @@ void Instruction::insertBefore(Instruction *BeforeI) {
|
|||||||
assert(is_sorted(getLLVMInstrs(),
|
assert(is_sorted(getLLVMInstrs(),
|
||||||
[](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
|
[](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
|
||||||
"Expected program order!");
|
"Expected program order!");
|
||||||
|
// Insert the LLVM IR Instructions in program order.
|
||||||
for (llvm::Instruction *I : getLLVMInstrs())
|
for (llvm::Instruction *I : getLLVMInstrs())
|
||||||
I->insertBefore(BeforeTopI);
|
I->insertBefore(BeforeTopI);
|
||||||
}
|
}
|
||||||
@ -362,11 +372,14 @@ void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
|
|||||||
LLVMBeforeI = nullptr;
|
LLVMBeforeI = nullptr;
|
||||||
LLVMBeforeIt = LLVMBB->end();
|
LLVMBeforeIt = LLVMBB->end();
|
||||||
}
|
}
|
||||||
|
// Insert the LLVM IR Instructions in program order.
|
||||||
for (llvm::Instruction *I : getLLVMInstrs())
|
for (llvm::Instruction *I : getLLVMInstrs())
|
||||||
I->insertInto(LLVMBB, LLVMBeforeIt);
|
I->insertInto(LLVMBB, LLVMBeforeIt);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock *Instruction::getParent() const {
|
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<llvm::Instruction>(Val)->getParent();
|
auto *BB = cast<llvm::Instruction>(Val)->getParent();
|
||||||
if (BB == nullptr)
|
if (BB == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user