Skip to content

Commit 99a43c2

Browse files
committed
IR: Add Value::reverseUseList()
I'm going to use this to improve `verify-uselistorder`. Part of PR5680. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214594 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent f425efd commit 99a43c2

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

include/llvm/IR/Value.h

+3
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ class Value {
462462
/// expected to compare two \a Use references.
463463
template <class Compare> void sortUseList(Compare Cmp);
464464

465+
/// \brief Reverse the use-list.
466+
void reverseUseList();
467+
465468
private:
466469
/// \brief Merge two lists together.
467470
///

lib/IR/Value.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,25 @@ Value *Value::DoPHITranslation(const BasicBlock *CurBB,
614614

615615
LLVMContext &Value::getContext() const { return VTy->getContext(); }
616616

617+
void Value::reverseUseList() {
618+
if (!UseList || !UseList->Next)
619+
// No need to reverse 0 or 1 uses.
620+
return;
621+
622+
Use *Head = UseList;
623+
Use *Current = UseList->Next;
624+
Head->Next = nullptr;
625+
while (Current) {
626+
Use *Next = Current->Next;
627+
Current->Next = Head;
628+
Head->setPrev(&Current->Next);
629+
Head = Current;
630+
Current = Next;
631+
}
632+
UseList = Head;
633+
Head->setPrev(&UseList);
634+
}
635+
617636
//===----------------------------------------------------------------------===//
618637
// ValueHandleBase Class
619638
//===----------------------------------------------------------------------===//

unittests/IR/UseTest.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,47 @@ TEST(UseTest, sort) {
6666
ASSERT_EQ(8u, I);
6767
}
6868

69+
TEST(UseTest, reverse) {
70+
LLVMContext C;
71+
72+
const char *ModuleString = "define void @f(i32 %x) {\n"
73+
"entry:\n"
74+
" %v0 = add i32 %x, 0\n"
75+
" %v2 = add i32 %x, 2\n"
76+
" %v5 = add i32 %x, 5\n"
77+
" %v1 = add i32 %x, 1\n"
78+
" %v3 = add i32 %x, 3\n"
79+
" %v7 = add i32 %x, 7\n"
80+
" %v6 = add i32 %x, 6\n"
81+
" %v4 = add i32 %x, 4\n"
82+
" ret void\n"
83+
"}\n";
84+
SMDiagnostic Err;
85+
char vnbuf[8];
86+
Module *M = ParseAssemblyString(ModuleString, nullptr, Err, C);
87+
Function *F = M->getFunction("f");
88+
ASSERT_TRUE(F);
89+
ASSERT_TRUE(F->arg_begin() != F->arg_end());
90+
Argument &X = *F->arg_begin();
91+
ASSERT_EQ("x", X.getName());
92+
93+
X.sortUseList([](const Use &L, const Use &R) {
94+
return L.getUser()->getName() < R.getUser()->getName();
95+
});
96+
unsigned I = 0;
97+
for (User *U : X.users()) {
98+
snprintf(vnbuf, sizeof(vnbuf), "v%u", I++);
99+
EXPECT_EQ(vnbuf, U->getName());
100+
}
101+
ASSERT_EQ(8u, I);
102+
103+
X.reverseUseList();
104+
I = 0;
105+
for (User *U : X.users()) {
106+
snprintf(vnbuf, sizeof(vnbuf), "v%u", (7 - I++));
107+
EXPECT_EQ(vnbuf, U->getName());
108+
}
109+
ASSERT_EQ(8u, I);
110+
}
111+
69112
} // end anonymous namespace

0 commit comments

Comments
 (0)