summaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorStepan Dyatkovskiy <stpworld@narod.ru>2012-05-08 06:36:08 +0000
committerStepan Dyatkovskiy <stpworld@narod.ru>2012-05-08 06:36:08 +0000
commit85a4406959fe7794062d62d2f17226235630eee1 (patch)
treebb1efcd88b32dec49569a1f11cca150671b4805a /lib/Bitcode/Reader/BitcodeReader.cpp
parentb78d83d837fc72a6565f186b0ad92d48cdfdb805 (diff)
downloadllvm-85a4406959fe7794062d62d2f17226235630eee1.tar.gz
llvm-85a4406959fe7794062d62d2f17226235630eee1.tar.bz2
llvm-85a4406959fe7794062d62d2f17226235630eee1.tar.xz
Ordinary patch for PR1255.
Added new case-ranges orientated methods for adding/removing cases in SwitchInst. After this patch cases will internally representated as ConstantArray-s instead of ConstantInt, externally cases wrapped within the ConstantRangesSet object. Old methods of SwitchInst are also works well, but marked as deprecated. So on this stage we have no side effects except that I added support for case ranges in BitcodeReader/Writer, of course test for Bitcode is also added. Old "switch" format is also supported. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156374 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp82
1 files changed, 75 insertions, 7 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index e3990403bd..a06a6f00f8 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -28,6 +28,10 @@
#include "llvm/OperandTraits.h"
using namespace llvm;
+enum {
+ SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
+};
+
void BitcodeReader::materializeForwardReferencedFunctions() {
while (!BlockAddrFwdRefs.empty()) {
Function *F = BlockAddrFwdRefs.begin()->first;
@@ -977,6 +981,17 @@ bool BitcodeReader::ResolveGlobalAndAliasInits() {
return false;
}
+template <typename intty>
+APInt ReadWideAPInt(const intty *Vals, unsigned ActiveWords,
+ unsigned TypeBits) {
+ SmallVector<uint64_t, 8> Words;
+ Words.resize(ActiveWords);
+ for (unsigned i = 0; i != ActiveWords; ++i)
+ Words[i] = DecodeSignRotatedValue(Vals[i]);
+
+ return APInt(TypeBits, Words);
+}
+
bool BitcodeReader::ParseConstants() {
if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
return Error("Malformed block record");
@@ -1033,13 +1048,11 @@ bool BitcodeReader::ParseConstants() {
return Error("Invalid WIDE_INTEGER record");
unsigned NumWords = Record.size();
- SmallVector<uint64_t, 8> Words;
- Words.resize(NumWords);
- for (unsigned i = 0; i != NumWords; ++i)
- Words[i] = DecodeSignRotatedValue(Record[i]);
- V = ConstantInt::get(Context,
- APInt(cast<IntegerType>(CurTy)->getBitWidth(),
- Words));
+
+ APInt VInt = ReadWideAPInt(&Record[0], NumWords,
+ cast<IntegerType>(CurTy)->getBitWidth());
+ V = ConstantInt::get(Context, VInt);
+
break;
}
case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval]
@@ -2271,6 +2284,61 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
break;
}
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
+ // Check magic
+ if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {
+ // New SwitchInst format with case ranges.
+
+ Type *OpTy = getTypeByID(Record[1]);
+ unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth();
+
+ Value *Cond = getFnValueByID(Record[2], OpTy);
+ BasicBlock *Default = getBasicBlock(Record[3]);
+ if (OpTy == 0 || Cond == 0 || Default == 0)
+ return Error("Invalid SWITCH record");
+
+ unsigned NumCases = Record[4];
+
+ SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases);
+
+ unsigned CurIdx = 5;
+ for (unsigned i = 0; i != NumCases; ++i) {
+ CRSBuilder CaseBuilder;
+ unsigned NumItems = Record[CurIdx++];
+ for (unsigned ci = 0; ci != NumItems; ++ci) {
+ bool isSingleNumber = Record[CurIdx++];
+
+ APInt Low;
+ unsigned ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ Low = ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
+ CurIdx += ActiveWords;
+
+ if (!isSingleNumber) {
+ ActiveWords = 1;
+ if (ValueBitWidth > 64)
+ ActiveWords = Record[CurIdx++];
+ APInt High =
+ ReadWideAPInt(&Record[CurIdx], ActiveWords, ValueBitWidth);
+ CaseBuilder.add(cast<ConstantInt>(ConstantInt::get(OpTy, Low)),
+ cast<ConstantInt>(ConstantInt::get(OpTy, High)));
+ CurIdx += ActiveWords;
+ } else
+ CaseBuilder.add(cast<ConstantInt>(ConstantInt::get(OpTy, Low)));
+ }
+ BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]);
+ ConstantRangesSet Case = CaseBuilder.getCase();
+ SI->addCase(Case, DestBB);
+ }
+ uint16_t Hash = SI->Hash();
+ if (Hash != (Record[0] & 0xFFFF))
+ return Error("Invalid SWITCH record");
+ I = SI;
+ break;
+ }
+
+ // Old SwitchInst format without case ranges.
+
if (Record.size() < 3 || (Record.size() & 1) == 0)
return Error("Invalid SWITCH record");
Type *OpTy = getTypeByID(Record[0]);