@@ -28,6 +28,17 @@ using namespace llvm;
28
28
namespace {
29
29
struct OrderMap {
30
30
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
+ }
31
42
32
43
unsigned size () const { return IDs.size (); }
33
44
std::pair<unsigned , bool > &operator [](const Value *V) { return IDs[V]; }
@@ -44,7 +55,7 @@ static void orderValue(const Value *V, OrderMap &OM) {
44
55
if (const Constant *C = dyn_cast<Constant>(V))
45
56
if (C->getNumOperands () && !isa<GlobalValue>(C))
46
57
for (const Value *Op : C->operands ())
47
- if (!isa<BasicBlock>(Op))
58
+ if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op) )
48
59
orderValue (Op, OM);
49
60
50
61
// Note: we cannot cache this lookup above, since inserting into the map
@@ -57,12 +68,11 @@ static OrderMap orderModule(const Module *M) {
57
68
// and ValueEnumerator::incorporateFunction().
58
69
OrderMap OM;
59
70
60
- for (const GlobalVariable &G : M->globals ())
61
- orderValue (&G, OM);
62
- for (const Function &F : *M)
63
- orderValue (&F, OM);
64
- for (const GlobalAlias &A : M->aliases ())
65
- orderValue (&A, OM);
71
+ // In the reader, initializers of GlobalValues are set *after* all the
72
+ // globals have been read. Rather than awkwardly modeling this behaviour
73
+ // directly in predictValueUseListOrderImpl(), just assign IDs to
74
+ // initializers of GlobalValues before GlobalValues themselves to model this
75
+ // implicitly.
66
76
for (const GlobalVariable &G : M->globals ())
67
77
if (G.hasInitializer ())
68
78
orderValue (G.getInitializer (), OM);
@@ -71,6 +81,23 @@ static OrderMap orderModule(const Module *M) {
71
81
for (const Function &F : *M)
72
82
if (F.hasPrefixData ())
73
83
orderValue (F.getPrefixData (), OM);
84
+ OM.LastGlobalConstantID = OM.size ();
85
+
86
+ // Initializers of GlobalValues are processed in
87
+ // BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather
88
+ // than ValueEnumerator, and match the code in predictValueUseListOrderImpl()
89
+ // by giving IDs in reverse order.
90
+ //
91
+ // Since GlobalValues never reference each other directly (just through
92
+ // initializers), their relative IDs only matter for determining order of
93
+ // uses in their initializers.
94
+ for (const Function &F : *M)
95
+ orderValue (&F, OM);
96
+ for (const GlobalAlias &A : M->aliases ())
97
+ orderValue (&A, OM);
98
+ for (const GlobalVariable &G : M->globals ())
99
+ orderValue (&G, OM);
100
+ OM.LastGlobalValueID = OM.size ();
74
101
75
102
for (const Function &F : *M) {
76
103
if (F.isDeclaration ())
@@ -110,31 +137,45 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
110
137
// We may have lost some users.
111
138
return ;
112
139
113
- std::sort (List. begin (), List. end (),
114
- [&OM, ID ](const Entry &L, const Entry &R) {
140
+ bool IsGlobalValue = OM. isGlobalValue (ID);
141
+ std::sort (List. begin (), List. end (), [& ](const Entry &L, const Entry &R) {
115
142
const Use *LU = L.first ;
116
143
const Use *RU = R.first ;
117
144
if (LU == RU)
118
145
return false ;
119
146
120
147
auto LID = OM.lookup (LU->getUser ()).first ;
121
148
auto RID = OM.lookup (RU->getUser ()).first ;
149
+
150
+ // Global values are processed in reverse order.
151
+ //
152
+ // Moreover, initializers of GlobalValues are set *after* all the globals
153
+ // have been read (despite having earlier IDs). Rather than awkwardly
154
+ // modeling this behaviour here, orderModule() has assigned IDs to
155
+ // initializers of GlobalValues before GlobalValues themselves.
156
+ if (OM.isGlobalValue (LID) && OM.isGlobalValue (RID))
157
+ return LID < RID;
158
+
122
159
// If ID is 4, then expect: 7 6 5 1 2 3.
123
160
if (LID < RID) {
124
161
if (RID < ID)
125
- return true ;
162
+ if (!IsGlobalValue) // GlobalValue uses don't get reversed.
163
+ return true ;
126
164
return false ;
127
165
}
128
166
if (RID < LID) {
129
167
if (LID < ID)
130
- return false ;
168
+ if (!IsGlobalValue) // GlobalValue uses don't get reversed.
169
+ return false ;
131
170
return true ;
132
171
}
172
+
133
173
// LID and RID are equal, so we have different operands of the same user.
134
174
// Assume operands are added in order for all instructions.
135
- if (LU->getOperandNo () < RU->getOperandNo ())
136
- return LID < ID;
137
- return ID < LID;
175
+ if (LID < ID)
176
+ if (!IsGlobalValue) // GlobalValue uses don't get reversed.
177
+ return LU->getOperandNo () < RU->getOperandNo ();
178
+ return LU->getOperandNo () > RU->getOperandNo ();
138
179
});
139
180
140
181
if (std::is_sorted (
0 commit comments