Pass a std::uinque_ptr to ParseAssembly to make the ownership explicit. NFC.
[oota-llvm.git] / lib / Bitcode / Writer / ValueEnumerator.cpp
index 09b6c470802b97a7197c537d9cd5e31714f6a894..4ed739ebe4abe72b5752ab929170ff60765f274f 100644 (file)
@@ -45,6 +45,11 @@ struct OrderMap {
   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;
+  }
 };
 }
 
@@ -59,8 +64,8 @@ static void orderValue(const Value *V, OrderMap &OM) {
           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) {
@@ -75,12 +80,15 @@ 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
@@ -158,13 +166,13 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
 
     // 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;
@@ -172,7 +180,7 @@ static void predictValueUseListOrderImpl(const Value *V, const Function *F,
 
     // 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();
@@ -206,9 +214,9 @@ static void predictValueUseListOrder(const Value *V, const Function *F,
 
   // 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);
 }
 
@@ -236,8 +244,7 @@ static UseListOrderStack predictUseListOrder(const Module *M) {
     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)