diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2021-12-30 13:42:11 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2021-12-30 13:54:37 +0300 |
commit | 62b1682570b1059e8c6542192159dcde32c13c30 (patch) | |
tree | bd44a364a7255071f0b4205f5b127a36dbc5f99a /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | a5337d6a1c6701eb98e085fb69a6e33c36f9533f (diff) | |
download | llvm-62b1682570b1059e8c6542192159dcde32c13c30.zip llvm-62b1682570b1059e8c6542192159dcde32c13c30.tar.gz llvm-62b1682570b1059e8c6542192159dcde32c13c30.tar.bz2 |
[Opaqueptrs][IR Serialization] Improve inlineasm [de]serialization
The bitcode reader expected that the pointers are typed,
so that it can extract the function type for the assembly
so `bitc::CST_CODE_INLINEASM` did not explicitly store said function type.
I'm not really sure how the upgrade path will look for existing bitcode,
but i think we can easily support opaque pointers going forward,
by simply storing the function type.
Reviewed By: #opaque-pointers, nikic
Differential Revision: https://reviews.llvm.org/D116341
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3360ad1..93b3dbf 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2824,6 +2824,7 @@ Error BitcodeReader::parseConstants() { for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); + // FIXME: support upgrading in opaque pointers mode. V = InlineAsm::get( cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack); @@ -2850,6 +2851,7 @@ Error BitcodeReader::parseConstants() { for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; UpgradeInlineAsmString(&AsmStr); + // FIXME: support upgrading in opaque pointers mode. V = InlineAsm::get( cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack, @@ -2857,7 +2859,7 @@ Error BitcodeReader::parseConstants() { break; } // This version adds support for the unwind keyword. - case bitc::CST_CODE_INLINEASM: { + case bitc::CST_CODE_INLINEASM_OLD3: { if (Record.size() < 2) return error("Invalid record"); unsigned OpNum = 0; @@ -2881,12 +2883,46 @@ Error BitcodeReader::parseConstants() { for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[OpNum + AsmStrSize + i]; UpgradeInlineAsmString(&AsmStr); + // FIXME: support upgrading in opaque pointers mode. V = InlineAsm::get( cast<FunctionType>(cast<PointerType>(CurTy)->getElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack, InlineAsm::AsmDialect(AsmDialect), CanThrow); break; } + // This version adds explicit function type. + case bitc::CST_CODE_INLINEASM: { + if (Record.size() < 3) + return error("Invalid record"); + unsigned OpNum = 0; + auto *FnTy = dyn_cast_or_null<FunctionType>(getTypeByID(Record[OpNum])); + ++OpNum; + if (!FnTy) + return error("Invalid record"); + std::string AsmStr, ConstrStr; + bool HasSideEffects = Record[OpNum] & 1; + bool IsAlignStack = (Record[OpNum] >> 1) & 1; + unsigned AsmDialect = (Record[OpNum] >> 2) & 1; + bool CanThrow = (Record[OpNum] >> 3) & 1; + ++OpNum; + unsigned AsmStrSize = Record[OpNum]; + ++OpNum; + if (OpNum + AsmStrSize >= Record.size()) + return error("Invalid record"); + unsigned ConstStrSize = Record[OpNum + AsmStrSize]; + if (OpNum + 1 + AsmStrSize + ConstStrSize > Record.size()) + return error("Invalid record"); + + for (unsigned i = 0; i != AsmStrSize; ++i) + AsmStr += (char)Record[OpNum + i]; + ++OpNum; + for (unsigned i = 0; i != ConstStrSize; ++i) + ConstrStr += (char)Record[OpNum + AsmStrSize + i]; + UpgradeInlineAsmString(&AsmStr); + V = InlineAsm::get(FnTy, AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect), CanThrow); + break; + } case bitc::CST_CODE_BLOCKADDRESS:{ if (Record.size() < 3) return error("Invalid record"); @@ -4783,7 +4819,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { cast<PointerType>(Callee->getType())->getElementType()); if (!FTy) return error("Callee is not of pointer to function type"); - } else if (cast<PointerType>(Callee->getType())->getElementType() != FTy) + } else if (!OpTy->isOpaqueOrPointeeTypeMatches(FTy)) return error("Explicit call type does not match pointee type of " "callee operand"); if (Record.size() < FTy->getNumParams() + OpNum) |