diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -501,9 +501,14 @@ std::vector> GlobalInits; std::vector> IndirectSymbolInits; - std::vector> FunctionPrefixes; - std::vector> FunctionPrologues; - std::vector> FunctionPersonalityFns; + + struct FunctionOperandInfo { + Function *F; + unsigned PersonalityFn; + unsigned Prefix; + unsigned Prologue; + }; + std::vector FunctionOperands; /// The set of attributes by index. Index zero in the file is for null, and /// is thus not represented here. As such all indices are off by one. @@ -2244,15 +2249,11 @@ std::vector> GlobalInitWorklist; std::vector> IndirectSymbolInitWorklist; - std::vector> FunctionPrefixWorklist; - std::vector> FunctionPrologueWorklist; - std::vector> FunctionPersonalityFnWorklist; + std::vector FunctionOperandWorklist; GlobalInitWorklist.swap(GlobalInits); IndirectSymbolInitWorklist.swap(IndirectSymbolInits); - FunctionPrefixWorklist.swap(FunctionPrefixes); - FunctionPrologueWorklist.swap(FunctionPrologues); - FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns); + FunctionOperandWorklist.swap(FunctionOperands); while (!GlobalInitWorklist.empty()) { unsigned ValID = GlobalInitWorklist.back().second; @@ -2284,43 +2285,41 @@ IndirectSymbolInitWorklist.pop_back(); } - while (!FunctionPrefixWorklist.empty()) { - unsigned ValID = FunctionPrefixWorklist.back().second; - if (ValID >= ValueList.size()) { - FunctionPrefixes.push_back(FunctionPrefixWorklist.back()); - } else { - if (Constant *C = dyn_cast_or_null(ValueList[ValID])) - FunctionPrefixWorklist.back().first->setPrefixData(C); - else - return error("Expected a constant"); + while (!FunctionOperandWorklist.empty()) { + FunctionOperandInfo &Info = FunctionOperandWorklist.back(); + if (Info.PersonalityFn) { + unsigned ValID = Info.PersonalityFn - 1; + if (ValID < ValueList.size()) { + if (Constant *C = dyn_cast_or_null(ValueList[ValID])) + Info.F->setPersonalityFn(C); + else + return error("Expected a constant"); + Info.PersonalityFn = 0; + } } - FunctionPrefixWorklist.pop_back(); - } - - while (!FunctionPrologueWorklist.empty()) { - unsigned ValID = FunctionPrologueWorklist.back().second; - if (ValID >= ValueList.size()) { - FunctionPrologues.push_back(FunctionPrologueWorklist.back()); - } else { - if (Constant *C = dyn_cast_or_null(ValueList[ValID])) - FunctionPrologueWorklist.back().first->setPrologueData(C); - else - return error("Expected a constant"); + if (Info.Prefix) { + unsigned ValID = Info.Prefix - 1; + if (ValID < ValueList.size()) { + if (Constant *C = dyn_cast_or_null(ValueList[ValID])) + Info.F->setPrefixData(C); + else + return error("Expected a constant"); + Info.Prefix = 0; + } } - FunctionPrologueWorklist.pop_back(); - } - - while (!FunctionPersonalityFnWorklist.empty()) { - unsigned ValID = FunctionPersonalityFnWorklist.back().second; - if (ValID >= ValueList.size()) { - FunctionPersonalityFns.push_back(FunctionPersonalityFnWorklist.back()); - } else { - if (Constant *C = dyn_cast_or_null(ValueList[ValID])) - FunctionPersonalityFnWorklist.back().first->setPersonalityFn(C); - else - return error("Expected a constant"); + if (Info.Prologue) { + unsigned ValID = Info.Prologue - 1; + if (ValID < ValueList.size()) { + if (Constant *C = dyn_cast_or_null(ValueList[ValID])) + Info.F->setPrologueData(C); + else + return error("Expected a constant"); + Info.Prologue = 0; + } } - FunctionPersonalityFnWorklist.pop_back(); + if (Info.PersonalityFn || Info.Prefix || Info.Prologue) + FunctionOperands.push_back(Info); + FunctionOperandWorklist.pop_back(); } return Error::success(); @@ -3385,8 +3384,10 @@ if (Record.size() > 9) UnnamedAddr = getDecodedUnnamedAddrType(Record[9]); Func->setUnnamedAddr(UnnamedAddr); - if (Record.size() > 10 && Record[10] != 0) - FunctionPrologues.push_back(std::make_pair(Func, Record[10] - 1)); + + FunctionOperandInfo OperandInfo = {Func, 0, 0, 0}; + if (Record.size() > 10) + OperandInfo.Prologue = Record[10]; if (Record.size() > 11) Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); @@ -3403,11 +3404,11 @@ Func->setComdat(reinterpret_cast(1)); } - if (Record.size() > 13 && Record[13] != 0) - FunctionPrefixes.push_back(std::make_pair(Func, Record[13] - 1)); + if (Record.size() > 13) + OperandInfo.Prefix = Record[13]; - if (Record.size() > 14 && Record[14] != 0) - FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1)); + if (Record.size() > 14) + OperandInfo.PersonalityFn = Record[14]; if (Record.size() > 15) { Func->setDSOLocal(getDecodedDSOLocal(Record[15])); @@ -3425,6 +3426,9 @@ ValueList.push_back(Func); + if (OperandInfo.PersonalityFn || OperandInfo.Prefix || OperandInfo.Prologue) + FunctionOperands.push_back(OperandInfo); + // If this is a function with a body, remember the prototype we are // creating now, so that we can match up the body with them later. if (!isProto) { diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -229,8 +229,11 @@ // have been read (despite having earlier IDs). Rather than awkwardly // modeling this behaviour here, orderModule() has assigned IDs to // initializers of GlobalValues before GlobalValues themselves. - if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID)) + if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID)) { + if (LID == RID) + return LU->getOperandNo() > RU->getOperandNo(); return LID < RID; + } // If ID is 4, then expect: 7 6 5 1 2 3. if (LID < RID) { diff --git a/llvm/test/Assembler/function-operand-uselistorder.ll b/llvm/test/Assembler/function-operand-uselistorder.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Assembler/function-operand-uselistorder.ll @@ -0,0 +1,11 @@ +; RUN: verify-uselistorder %s + +@g = global i8 0 + +define void @f1() prefix i8* @g prologue i8* @g personality i8* @g { + ret void +} + +define void @f2() prefix i8* @g prologue i8* @g personality i8* @g { + ret void +} diff --git a/llvm/tools/verify-uselistorder/verify-uselistorder.cpp b/llvm/tools/verify-uselistorder/verify-uselistorder.cpp --- a/llvm/tools/verify-uselistorder/verify-uselistorder.cpp +++ b/llvm/tools/verify-uselistorder/verify-uselistorder.cpp @@ -202,14 +202,9 @@ map(A.getAliasee()); for (const GlobalIFunc &IF : M.ifuncs()) map(IF.getResolver()); - for (const Function &F : M) { - if (F.hasPrefixData()) - map(F.getPrefixData()); - if (F.hasPrologueData()) - map(F.getPrologueData()); - if (F.hasPersonalityFn()) - map(F.getPersonalityFn()); - } + for (const Function &F : M) + for (Value *Op : F.operands()) + map(Op); // Function bodies. for (const Function &F : M) { @@ -484,14 +479,9 @@ changeValueUseList(A.getAliasee()); for (GlobalIFunc &IF : M.ifuncs()) changeValueUseList(IF.getResolver()); - for (Function &F : M) { - if (F.hasPrefixData()) - changeValueUseList(F.getPrefixData()); - if (F.hasPrologueData()) - changeValueUseList(F.getPrologueData()); - if (F.hasPersonalityFn()) - changeValueUseList(F.getPersonalityFn()); - } + for (Function &F : M) + for (Value *Op : F.operands()) + changeValueUseList(Op); // Function bodies. for (Function &F : M) {