[llvm] 9392b45 - Revert "[SandboxIR] sandboxir::Use operands (part 1) and uses (part 2) (#98251)"
Vasileios Porpodas via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 15:15:27 PDT 2024
Author: Vasileios Porpodas
Date: 2024-07-10T15:14:56-07:00
New Revision: 9392b45ef4720f470ffc11fb052f397c92758a16
URL: https://github.com/llvm/llvm-project/commit/9392b45ef4720f470ffc11fb052f397c92758a16
DIFF: https://github.com/llvm/llvm-project/commit/9392b45ef4720f470ffc11fb052f397c92758a16.diff
LOG: Revert "[SandboxIR] sandboxir::Use operands (part 1) and uses (part 2) (#98251)"
This reverts commit eb97761b4db4877e8c2507054d94a35154e2ba54.
Added:
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 039c7ed078d7b..c84f25f6f5754 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -71,96 +71,6 @@ namespace sandboxir {
class Function;
class Context;
class Instruction;
-class User;
-class Value;
-
-/// Represents a Def-use/Use-def edge in SandboxIR.
-/// NOTE: Unlike llvm::Use, this is not an integral part of the use-def chains.
-/// It is also not uniqued and is currently passed by value, so you can have
-/// more than one sandboxir::Use objects for the same use-def edge.
-class Use {
- llvm::Use *LLVMUse;
- User *Usr;
- Context *Ctx;
-
- /// Don't allow the user to create a sandboxir::Use directly.
- Use(llvm::Use *LLVMUse, User *Usr, Context &Ctx)
- : LLVMUse(LLVMUse), Usr(Usr), Ctx(&Ctx) {}
- Use() : LLVMUse(nullptr), Ctx(nullptr) {}
-
- friend class Value; // For constructor
- friend class User; // For constructor
- friend class OperandUseIterator; // For constructor
- friend class UserUseIterator; // For accessing members
-
-public:
- operator Value *() const { return get(); }
- Value *get() const;
- class User *getUser() const { return Usr; }
- unsigned getOperandNo() const;
- Context *getContext() const { return Ctx; }
- bool operator==(const Use &Other) const {
- assert(Ctx == Other.Ctx && "Contexts
diff er!");
- return LLVMUse == Other.LLVMUse && Usr == Other.Usr;
- }
- bool operator!=(const Use &Other) const { return !(*this == Other); }
-#ifndef NDEBUG
- void dump(raw_ostream &OS) const;
- void dump() const;
-#endif // NDEBUG
-};
-
-/// Returns the operand edge when dereferenced.
-class OperandUseIterator {
- Use Use;
- /// Don't let the user create a non-empty OperandUseIterator.
- OperandUseIterator(const class Use &Use) : Use(Use) {}
- friend class User; // For constructor
-#define DEF_INSTR(ID, OPC, CLASS) friend class CLASS; // For constructor
-#include "llvm/SandboxIR/SandboxIRValues.def"
-
-public:
- using
diff erence_type = std::ptr
diff _t;
- using value_type = sandboxir::Use;
- using pointer = value_type *;
- using reference = value_type &;
- using iterator_category = std::input_iterator_tag;
-
- OperandUseIterator() = default;
- value_type operator*() const;
- OperandUseIterator &operator++();
- bool operator==(const OperandUseIterator &Other) const {
- return Use == Other.Use;
- }
- bool operator!=(const OperandUseIterator &Other) const {
- return !(*this == Other);
- }
-};
-
-/// Returns user edge when dereferenced.
-class UserUseIterator {
- Use Use;
- /// Don't let the user create a non-empty UserUseIterator.
- UserUseIterator(const class Use &Use) : Use(Use) {}
- friend class Value; // For constructor
-
-public:
- using
diff erence_type = std::ptr
diff _t;
- using value_type = sandboxir::Use;
- using pointer = value_type *;
- using reference = value_type &;
- using iterator_category = std::input_iterator_tag;
-
- UserUseIterator() = default;
- value_type operator*() const { return Use; }
- UserUseIterator &operator++();
- bool operator==(const UserUseIterator &Other) const {
- return Use == Other.Use;
- }
- bool operator!=(const UserUseIterator &Other) const {
- return !(*this == Other);
- }
-};
/// A SandboxIR Value has users. This is the base class.
class Value {
@@ -213,77 +123,9 @@ class Value {
virtual ~Value() = default;
ClassID getSubclassID() const { return SubclassID; }
- using use_iterator = UserUseIterator;
- using const_use_iterator = UserUseIterator;
-
- use_iterator use_begin();
- const_use_iterator use_begin() const {
- return const_cast<Value *>(this)->use_begin();
- }
- use_iterator use_end() { return use_iterator(Use(nullptr, nullptr, Ctx)); }
- const_use_iterator use_end() const {
- return const_cast<Value *>(this)->use_end();
- }
-
- iterator_range<use_iterator> uses() {
- return make_range<use_iterator>(use_begin(), use_end());
- }
- iterator_range<const_use_iterator> uses() const {
- return make_range<const_use_iterator>(use_begin(), use_end());
- }
-
- /// Helper for mapped_iterator.
- struct UseToUser {
- User *operator()(const Use &Use) const { return &*Use.getUser(); }
- };
-
- using user_iterator = mapped_iterator<sandboxir::UserUseIterator, UseToUser>;
- using const_user_iterator = user_iterator;
-
- user_iterator user_begin();
- user_iterator user_end() {
- return user_iterator(Use(nullptr, nullptr, Ctx), UseToUser());
- }
- const_user_iterator user_begin() const {
- return const_cast<Value *>(this)->user_begin();
- }
- const_user_iterator user_end() const {
- return const_cast<Value *>(this)->user_end();
- }
-
- iterator_range<user_iterator> users() {
- return make_range<user_iterator>(user_begin(), user_end());
- }
- iterator_range<const_user_iterator> users() const {
- return make_range<const_user_iterator>(user_begin(), user_end());
- }
- /// \Returns the number of user edges (not necessarily to unique users).
- /// WARNING: This is a linear-time operation.
- unsigned getNumUses() const;
- /// Return true if this value has N uses or more.
- /// This is logically equivalent to getNumUses() >= N.
- /// WARNING: This can be expensive, as it is linear to the number of users.
- bool hasNUsesOrMore(unsigned Num) const {
- unsigned Cnt = 0;
- for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
- if (++Cnt >= Num)
- return true;
- }
- return false;
- }
- /// Return true if this Value has exactly N uses.
- bool hasNUses(unsigned Num) const {
- unsigned Cnt = 0;
- for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
- if (++Cnt > Num)
- return false;
- }
- return Cnt == Num;
- }
-
Type *getType() const { return Val->getType(); }
- Context &getContext() const { return Ctx; }
+ Context &getContext() const;
#ifndef NDEBUG
/// Should crash if there is something wrong with the instruction.
virtual void verify() const = 0;
@@ -332,61 +174,9 @@ class User : public Value {
protected:
User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
- /// \Returns the Use edge that corresponds to \p OpIdx.
- /// Note: This is the default implementation that works for instructions that
- /// match the underlying LLVM instruction. All others should use a
diff erent
- /// implementation.
- Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
- virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
- friend class OperandUseIterator; // for getOperandUseInternal()
-
- /// The default implementation works only for single-LLVMIR-instruction
- /// Users and only if they match exactly the LLVM instruction.
- unsigned getUseOperandNoDefault(const Use &Use) const {
- return Use.LLVMUse->getOperandNo();
- }
- /// \Returns the operand index of \p Use.
- virtual unsigned getUseOperandNo(const Use &Use) const = 0;
- friend unsigned Use::getOperandNo() const; // For getUseOperandNo()
-
public:
/// For isa/dyn_cast.
static bool classof(const Value *From);
- using op_iterator = OperandUseIterator;
- using const_op_iterator = OperandUseIterator;
- using op_range = iterator_range<op_iterator>;
- using const_op_range = iterator_range<const_op_iterator>;
-
- virtual op_iterator op_begin() {
- assert(isa<llvm::User>(Val) && "Expect User value!");
- return op_iterator(getOperandUseInternal(0, /*Verify=*/false));
- }
- virtual op_iterator op_end() {
- assert(isa<llvm::User>(Val) && "Expect User value!");
- return op_iterator(
- getOperandUseInternal(getNumOperands(), /*Verify=*/false));
- }
- virtual const_op_iterator op_begin() const {
- return const_cast<User *>(this)->op_begin();
- }
- virtual const_op_iterator op_end() const {
- return const_cast<User *>(this)->op_end();
- }
-
- op_range operands() { return make_range<op_iterator>(op_begin(), op_end()); }
- const_op_range operands() const {
- return make_range<const_op_iterator>(op_begin(), op_end());
- }
- Value *getOperand(unsigned OpIdx) const { return getOperandUse(OpIdx).get(); }
- /// \Returns the operand edge for \p OpIdx. NOTE: This should also work for
- /// OpIdx == getNumOperands(), which is used for op_end().
- Use getOperandUse(unsigned OpIdx) const {
- return getOperandUseInternal(OpIdx, /*Verify=*/true);
- }
- virtual unsigned getNumOperands() const {
- return isa<llvm::User>(Val) ? cast<llvm::User>(Val)->getNumOperands() : 0;
- }
-
#ifndef NDEBUG
void verify() const override {
assert(isa<llvm::User>(Val) && "Expected User!");
@@ -405,9 +195,6 @@ class Constant : public sandboxir::User {
Constant(llvm::Constant *C, sandboxir::Context &SBCtx)
: sandboxir::User(ClassID::Constant, C, SBCtx) {}
friend class Context; // For constructor.
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
- return getOperandUseDefault(OpIdx, Verify);
- }
public:
/// For isa/dyn_cast.
@@ -416,9 +203,6 @@ class Constant : public sandboxir::User {
From->getSubclassID() == ClassID::Function;
}
sandboxir::Context &getParent() const { return getContext(); }
- unsigned getUseOperandNo(const Use &Use) const final {
- return getUseOperandNoDefault(Use);
- }
#ifndef NDEBUG
void verify() const final {
assert(isa<llvm::Constant>(Val) && "Expected Constant!");
@@ -525,17 +309,11 @@ class OpaqueInst : public sandboxir::Instruction {
OpaqueInst(ClassID SubclassID, llvm::Instruction *I, sandboxir::Context &Ctx)
: sandboxir::Instruction(SubclassID, Opcode::Opaque, I, Ctx) {}
friend class Context; // For constructor.
- Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
- return getOperandUseDefault(OpIdx, Verify);
- }
public:
static bool classof(const sandboxir::Value *From) {
return From->getSubclassID() == ClassID::Opaque;
}
- unsigned getUseOperandNo(const Use &Use) const final {
- return getUseOperandNoDefault(Use);
- }
unsigned getNumOfIRInstrs() const final { return 1u; }
#ifndef NDEBUG
void verify() const final {
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 160d807738a3c..f64b1145ebf43 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -7,72 +7,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/SandboxIR/SandboxIR.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Constants.h"
#include "llvm/Support/Debug.h"
#include <sstream>
using namespace llvm::sandboxir;
-Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); }
-
-unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); }
-
-#ifndef NDEBUG
-void Use::dump(raw_ostream &OS) const {
- Value *Def = nullptr;
- if (LLVMUse == nullptr)
- OS << "<null> LLVM Use! ";
- else
- Def = Ctx->getValue(LLVMUse->get());
- OS << "Def: ";
- if (Def == nullptr)
- OS << "NULL";
- else
- OS << *Def;
- OS << "\n";
-
- OS << "User: ";
- if (Usr == nullptr)
- OS << "NULL";
- else
- OS << *Usr;
- OS << "\n";
-
- OS << "OperandNo: ";
- if (Usr == nullptr)
- OS << "N/A";
- else
- OS << getOperandNo();
- OS << "\n";
-}
-
-void Use::dump() const { dump(dbgs()); }
-#endif // NDEBUG
-
-Use OperandUseIterator::operator*() const { return Use; }
-
-OperandUseIterator &OperandUseIterator::operator++() {
- assert(Use.LLVMUse != nullptr && "Already at end!");
- User *User = Use.getUser();
- Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false);
- return *this;
-}
-
-UserUseIterator &UserUseIterator::operator++() {
- llvm::Use *&LLVMUse = Use.LLVMUse;
- assert(LLVMUse != nullptr && "Already at end!");
- LLVMUse = LLVMUse->getNext();
- if (LLVMUse == nullptr) {
- Use.Usr = nullptr;
- return *this;
- }
- auto *Ctx = Use.Ctx;
- auto *LLVMUser = LLVMUse->getUser();
- Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
- return *this;
-}
-
Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
: SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
#ifndef NDEBUG
@@ -80,29 +20,6 @@ Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
#endif
}
-Value::use_iterator Value::use_begin() {
- llvm::Use *LLVMUse = nullptr;
- if (Val->use_begin() != Val->use_end())
- LLVMUse = &*Val->use_begin();
- User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
- Val->use_begin()->getUser()))
- : nullptr;
- return use_iterator(Use(LLVMUse, User, Ctx));
-}
-
-Value::user_iterator Value::user_begin() {
- auto UseBegin = Val->use_begin();
- auto UseEnd = Val->use_end();
- bool AtEnd = UseBegin == UseEnd;
- llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
- User *User =
- AtEnd ? nullptr
- : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
- return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
-}
-
-unsigned Value::getNumUses() const { return range_size(Val->users()); }
-
#ifndef NDEBUG
std::string Value::getName() const {
std::stringstream SS;
@@ -154,17 +71,6 @@ void Argument::dump() const {
}
#endif // NDEBUG
-Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const {
- assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!");
- assert(isa<llvm::User>(Val) && "Non-users have no operands!");
- llvm::Use *LLVMUse;
- if (OpIdx != getNumOperands())
- LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx);
- else
- LLVMUse = cast<llvm::User>(Val)->op_end();
- return Use(LLVMUse, const_cast<User *>(this), Ctx);
-}
-
bool User::classof(const Value *From) {
switch (From->getSubclassID()) {
#define DEF_VALUE(ID, CLASS)
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 72e81bf640350..161ee51432cd3 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -109,126 +109,6 @@ define void @foo(i32 %v1) {
#endif
}
-TEST_F(SandboxIRTest, Use) {
- parseIR(C, R"IR(
-define i32 @foo(i32 %v0, i32 %v1) {
- %add0 = add i32 %v0, %v1
- ret i32 %add0
-}
-)IR");
- Function &LLVMF = *M->getFunction("foo");
- sandboxir::Context Ctx(C);
-
- BasicBlock *LLVMBB = &*LLVMF.begin();
- auto LLVMBBIt = LLVMBB->begin();
- Instruction *LLVMI0 = &*LLVMBBIt++;
-
- auto &F = *Ctx.createFunction(&LLVMF);
- auto &BB = *F.begin();
- auto *Arg0 = F.getArg(0);
- auto *Arg1 = F.getArg(1);
- auto It = BB.begin();
- auto *I0 = &*It++;
- auto *Ret = &*It++;
-
- SmallVector<sandboxir::Argument *> Args{Arg0, Arg1};
- unsigned OpIdx = 0;
- for (sandboxir::Use Use : I0->operands()) {
- // Check Use.getOperandNo().
- EXPECT_EQ(Use.getOperandNo(), OpIdx);
- // Check Use.getUser().
- EXPECT_EQ(Use.getUser(), I0);
- // Check Use.getContext().
- EXPECT_EQ(Use.getContext(), &Ctx);
- // Check Use.get().
- sandboxir::Value *Op = Use.get();
- EXPECT_EQ(Op, Ctx.getValue(LLVMI0->getOperand(OpIdx)));
- // Check Use.getUser().
- EXPECT_EQ(Use.getUser(), I0);
- // Check implicit cast to Value.
- sandboxir::Value *Cast = Use;
- EXPECT_EQ(Cast, Op);
- // Check that Use points to the correct operand.
- EXPECT_EQ(Op, Args[OpIdx]);
- // Check getOperand().
- EXPECT_EQ(Op, I0->getOperand(OpIdx));
- // Check getOperandUse().
- EXPECT_EQ(Use, I0->getOperandUse(OpIdx));
- ++OpIdx;
- }
- EXPECT_EQ(OpIdx, 2u);
-
- // Check Use.operator==() and Use.operator!=().
- sandboxir::Use UseA = I0->getOperandUse(0);
- sandboxir::Use UseB = I0->getOperandUse(0);
- EXPECT_TRUE(UseA == UseB);
- EXPECT_FALSE(UseA != UseB);
-
- // Check getNumOperands().
- EXPECT_EQ(I0->getNumOperands(), 2u);
- EXPECT_EQ(Ret->getNumOperands(), 1u);
-
- EXPECT_EQ(Ret->getOperand(0), I0);
-
-#ifndef NDEBUG
- // Check Use.dump()
- std::string Buff;
- raw_string_ostream BS(Buff);
- BS << "\n";
- I0->getOperandUse(0).dump(BS);
- EXPECT_EQ(Buff, R"IR(
-Def: i32 %v0 ; SB1. (Argument)
-User: %add0 = add i32 %v0, %v1 ; SB4. (Opaque)
-OperandNo: 0
-)IR");
-#endif // NDEBUG
-
- // Check Value.user_begin().
- sandboxir::Value::user_iterator UIt = I0->user_begin();
- sandboxir::User *U = *UIt;
- EXPECT_EQ(U, Ret);
- // Check Value.uses().
- EXPECT_EQ(range_size(I0->uses()), 1u);
- EXPECT_EQ((*I0->uses().begin()).getUser(), Ret);
- // Check Value.users().
- EXPECT_EQ(range_size(I0->users()), 1u);
- EXPECT_EQ(*I0->users().begin(), Ret);
- // Check Value.getNumUses().
- EXPECT_EQ(I0->getNumUses(), 1u);
- // Check Value.hasNUsesOrMore().
- EXPECT_TRUE(I0->hasNUsesOrMore(0u));
- EXPECT_TRUE(I0->hasNUsesOrMore(1u));
- EXPECT_FALSE(I0->hasNUsesOrMore(2u));
- // Check Value.hasNUses().
- EXPECT_FALSE(I0->hasNUses(0u));
- EXPECT_TRUE(I0->hasNUses(1u));
- EXPECT_FALSE(I0->hasNUses(2u));
-}
-
-// Check that the operands/users are counted correctly.
-// I1
-// / \
-// \ /
-// I2
-TEST_F(SandboxIRTest, DuplicateUses) {
- parseIR(C, R"IR(
-define void @foo(i8 %v) {
- %I1 = add i8 %v, %v
- %I2 = add i8 %I1, %I1
- ret void
-}
-)IR");
- Function &LLVMF = *M->getFunction("foo");
- sandboxir::Context Ctx(C);
- auto *F = Ctx.createFunction(&LLVMF);
- auto *BB = &*F->begin();
- auto It = BB->begin();
- auto *I1 = &*It++;
- auto *I2 = &*It++;
- EXPECT_EQ(range_size(I1->users()), 2u);
- EXPECT_EQ(range_size(I2->operands()), 2u);
-}
-
TEST_F(SandboxIRTest, Function) {
parseIR(C, R"IR(
define void @foo(i32 %arg0, i32 %arg1) {
More information about the llvm-commits
mailing list