std::pair<unsigned, bool> lookup(const Value *V) const {
return IDs.lookup(V);
}
+ void index(const Value *V) {
+ // Explicitly sequence get-size and insert-value operations to avoid UB.
+ unsigned ID = IDs.size() + 1;
+ IDs[V].first = ID;
+ }
};
}
orderValue(Op, OM);
// Note: we cannot cache this lookup above, since inserting into the map
- // changes the map's size, and thus affects the ID.
- OM[V].first = OM.size() + 1;
+ // changes the map's size, and thus affects the other IDs.
+ OM.index(V);
}
static OrderMap orderModule(const Module *M) {
// implicitly.
for (const GlobalVariable &G : M->globals())
if (G.hasInitializer())
- orderValue(G.getInitializer(), OM);
+ if (!isa<GlobalValue>(G.getInitializer()))
+ orderValue(G.getInitializer(), OM);
for (const GlobalAlias &A : M->aliases())
- orderValue(A.getAliasee(), OM);
+ if (!isa<GlobalValue>(A.getAliasee()))
+ orderValue(A.getAliasee(), OM);
for (const Function &F : *M)
if (F.hasPrefixData())
- orderValue(F.getPrefixData(), OM);
+ if (!isa<GlobalValue>(F.getPrefixData()))
+ orderValue(F.getPrefixData(), OM);
OM.LastGlobalConstantID = OM.size();
// Initializers of GlobalValues are processed in
// If ID is 4, then expect: 7 6 5 1 2 3.
if (LID < RID) {
- if (RID < ID)
+ if (RID <= ID)
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
return true;
return false;
}
if (RID < LID) {
- if (LID < ID)
+ if (LID <= ID)
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
return false;
return true;
// LID and RID are equal, so we have different operands of the same user.
// Assume operands are added in order for all instructions.
- if (LID < ID)
+ if (LID <= ID)
if (!IsGlobalValue) // GlobalValue uses don't get reversed.
return LU->getOperandNo() < RU->getOperandNo();
return LU->getOperandNo() > RU->getOperandNo();
// Recursive descent into constants.
if (const Constant *C = dyn_cast<Constant>(V))
- if (C->getNumOperands() && !isa<GlobalValue>(C))
+ if (C->getNumOperands()) // Visit GlobalValues.
for (const Value *Op : C->operands())
- if (isa<Constant>(Op) && !isa<GlobalValue>(Op))
+ if (isa<Constant>(Op)) // Visit GlobalValues.
predictValueUseListOrder(Op, F, OM, Stack);
}
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)
for (const Value *Op : I.operands())
- if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) ||
- isa<InlineAsm>(*Op))
+ if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues.
predictValueUseListOrder(Op, &F, OM, Stack);
for (const BasicBlock &BB : F)
for (const Instruction &I : BB)