Skip to content

Commit cd29d80

Browse files
committed
Reapply "UseListOrder: Order GlobalValue uses after initializers"
This reverts commit r214249, reapplying r214242 and r214243, now that r214270 has fixed the UB. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214271 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c128f3b commit cd29d80

File tree

4 files changed

+71
-14
lines changed

4 files changed

+71
-14
lines changed

lib/Bitcode/Writer/ValueEnumerator.cpp

+55-14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ using namespace llvm;
2828
namespace {
2929
struct OrderMap {
3030
DenseMap<const Value *, std::pair<unsigned, bool>> IDs;
31+
unsigned LastGlobalConstantID;
32+
unsigned LastGlobalValueID;
33+
34+
OrderMap() : LastGlobalConstantID(0), LastGlobalValueID(0) {}
35+
36+
bool isGlobalConstant(unsigned ID) const {
37+
return ID <= LastGlobalConstantID;
38+
}
39+
bool isGlobalValue(unsigned ID) const {
40+
return ID <= LastGlobalValueID && !isGlobalConstant(ID);
41+
}
3142

3243
unsigned size() const { return IDs.size(); }
3344
std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; }
@@ -49,7 +60,7 @@ static void orderValue(const Value *V, OrderMap &OM) {
4960
if (const Constant *C = dyn_cast<Constant>(V))
5061
if (C->getNumOperands() && !isa<GlobalValue>(C))
5162
for (const Value *Op : C->operands())
52-
if (!isa<BasicBlock>(Op))
63+
if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op))
5364
orderValue(Op, OM);
5465

5566
// Note: we cannot cache this lookup above, since inserting into the map
@@ -62,12 +73,11 @@ static OrderMap orderModule(const Module *M) {
6273
// and ValueEnumerator::incorporateFunction().
6374
OrderMap OM;
6475

65-
for (const GlobalVariable &G : M->globals())
66-
orderValue(&G, OM);
67-
for (const Function &F : *M)
68-
orderValue(&F, OM);
69-
for (const GlobalAlias &A : M->aliases())
70-
orderValue(&A, OM);
76+
// In the reader, initializers of GlobalValues are set *after* all the
77+
// globals have been read. Rather than awkwardly modeling this behaviour
78+
// directly in predictValueUseListOrderImpl(), just assign IDs to
79+
// initializers of GlobalValues before GlobalValues themselves to model this
80+
// implicitly.
7181
for (const GlobalVariable &G : M->globals())
7282
if (G.hasInitializer())
7383
orderValue(G.getInitializer(), OM);
@@ -76,6 +86,23 @@ static OrderMap orderModule(const Module *M) {
7686
for (const Function &F : *M)
7787
if (F.hasPrefixData())
7888
orderValue(F.getPrefixData(), OM);
89+
OM.LastGlobalConstantID = OM.size();
90+
91+
// Initializers of GlobalValues are processed in
92+
// BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather
93+
// than ValueEnumerator, and match the code in predictValueUseListOrderImpl()
94+
// by giving IDs in reverse order.
95+
//
96+
// Since GlobalValues never reference each other directly (just through
97+
// initializers), their relative IDs only matter for determining order of
98+
// uses in their initializers.
99+
for (const Function &F : *M)
100+
orderValue(&F, OM);
101+
for (const GlobalAlias &A : M->aliases())
102+
orderValue(&A, OM);
103+
for (const GlobalVariable &G : M->globals())
104+
orderValue(&G, OM);
105+
OM.LastGlobalValueID = OM.size();
79106

80107
for (const Function &F : *M) {
81108
if (F.isDeclaration())
@@ -115,31 +142,45 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
115142
// We may have lost some users.
116143
return;
117144

118-
std::sort(List.begin(), List.end(),
119-
[&OM, ID](const Entry &L, const Entry &R) {
145+
bool IsGlobalValue = OM.isGlobalValue(ID);
146+
std::sort(List.begin(), List.end(), [&](const Entry &L, const Entry &R) {
120147
const Use *LU = L.first;
121148
const Use *RU = R.first;
122149
if (LU == RU)
123150
return false;
124151

125152
auto LID = OM.lookup(LU->getUser()).first;
126153
auto RID = OM.lookup(RU->getUser()).first;
154+
155+
// Global values are processed in reverse order.
156+
//
157+
// Moreover, initializers of GlobalValues are set *after* all the globals
158+
// have been read (despite having earlier IDs). Rather than awkwardly
159+
// modeling this behaviour here, orderModule() has assigned IDs to
160+
// initializers of GlobalValues before GlobalValues themselves.
161+
if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID))
162+
return LID < RID;
163+
127164
// If ID is 4, then expect: 7 6 5 1 2 3.
128165
if (LID < RID) {
129166
if (RID < ID)
130-
return true;
167+
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
168+
return true;
131169
return false;
132170
}
133171
if (RID < LID) {
134172
if (LID < ID)
135-
return false;
173+
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
174+
return false;
136175
return true;
137176
}
177+
138178
// LID and RID are equal, so we have different operands of the same user.
139179
// Assume operands are added in order for all instructions.
140-
if (LU->getOperandNo() < RU->getOperandNo())
141-
return LID < ID;
142-
return ID < LID;
180+
if (LID < ID)
181+
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
182+
return LU->getOperandNo() < RU->getOperandNo();
183+
return LU->getOperandNo() > RU->getOperandNo();
143184
});
144185

145186
if (std::is_sorted(

test/Bitcode/local-linkage-default-visibility.3.4.ll

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llvm-dis < %s.bc | FileCheck %s
2+
; RUN: llvm-uselistorder < %s.bc -preserve-bc-use-list-order -num-shuffles=5
23

34
; local-linkage-default-visibility.3.4.ll.bc was generated by passing this file
45
; to llvm-as-3.4. The test checks that LLVM upgrades visibility of symbols

test/Bitcode/old-aliases.ll

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llvm-dis < %s.bc | FileCheck %s
2+
; RUN: llvm-uselistorder < %s.bc -preserve-bc-use-list-order -num-shuffles=5
23

34
; old-aliases.bc consist of this file assembled with an old llvm-as (3.5 trunk)
45
; from when aliases contained a ConstantExpr.

test/Bitcode/use-list-order.ll

+14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@
33
@a = global [4 x i1] [i1 0, i1 1, i1 0, i1 1]
44
@b = alias i1* getelementptr ([4 x i1]* @a, i64 0, i64 2)
55

6+
; Check use-list order of constants used by globals.
7+
@glob1 = global i5 7
8+
@glob2 = global i5 7
9+
@glob3 = global i5 7
10+
11+
; Check use-list order between variables and aliases.
12+
@target = global i3 zeroinitializer
13+
@alias1 = alias i3* @target
14+
@alias2 = alias i3* @target
15+
@alias3 = alias i3* @target
16+
@var1 = global i3* @target
17+
@var2 = global i3* @target
18+
@var3 = global i3* @target
19+
620
define i64 @f(i64 %f) {
721
entry:
822
%sum = add i64 %f, 0

0 commit comments

Comments
 (0)