diff options
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 102 |
1 files changed, 53 insertions, 49 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 49ba562..543cb9a 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -501,9 +501,14 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer { std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInits; std::vector<std::pair<GlobalIndirectSymbol *, unsigned>> IndirectSymbolInits; - std::vector<std::pair<Function *, unsigned>> FunctionPrefixes; - std::vector<std::pair<Function *, unsigned>> FunctionPrologues; - std::vector<std::pair<Function *, unsigned>> FunctionPersonalityFns; + + struct FunctionOperandInfo { + Function *F; + unsigned PersonalityFn; + unsigned Prefix; + unsigned Prologue; + }; + std::vector<FunctionOperandInfo> 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 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInitWorklist; std::vector<std::pair<GlobalIndirectSymbol *, unsigned>> IndirectSymbolInitWorklist; - std::vector<std::pair<Function *, unsigned>> FunctionPrefixWorklist; - std::vector<std::pair<Function *, unsigned>> FunctionPrologueWorklist; - std::vector<std::pair<Function *, unsigned>> FunctionPersonalityFnWorklist; + std::vector<FunctionOperandInfo> 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 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() { 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<Constant>(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<Constant>(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<Constant>(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<Constant>(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<Constant>(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<Constant>(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 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { 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 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { Func->setComdat(reinterpret_cast<Comdat *>(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 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { 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) { |