summaryrefslogtreecommitdiff
path: root/lib/Bitcode/Writer
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/Writer
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/Writer')
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp87
1 files changed, 61 insertions, 26 deletions
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index b25d2e96d5..f8065e3b16 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -62,7 +62,10 @@ enum {
FUNCTION_INST_CAST_ABBREV,
FUNCTION_INST_RET_VOID_ABBREV,
FUNCTION_INST_RET_VAL_ABBREV,
- FUNCTION_INST_UNREACHABLE_ABBREV
+ FUNCTION_INST_UNREACHABLE_ABBREV,
+
+ // SwitchInst Magic
+ SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
};
static unsigned GetEncodedCastOpcode(unsigned Opcode) {
@@ -719,6 +722,42 @@ static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) {
Stream.ExitBlock();
}
+template <typename intty>
+static void EmitAPInt(SmallVectorImpl<intty> &Vals,
+ unsigned &Code, unsigned &AbbrevToUse, const APInt &Val,
+ bool EmitSizeForWideNumbers = false
+ ) {
+ if (Val.getBitWidth() <= 64) {
+ uint64_t V = Val.getSExtValue();
+ if ((int64_t)V >= 0)
+ Vals.push_back(V << 1);
+ else
+ Vals.push_back((-V << 1) | 1);
+ Code = bitc::CST_CODE_INTEGER;
+ AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
+ } else {
+ // Wide integers, > 64 bits in size.
+ // We have an arbitrary precision integer value to write whose
+ // bit width is > 64. However, in canonical unsigned integer
+ // format it is likely that the high bits are going to be zero.
+ // So, we only write the number of active words.
+ unsigned NWords = Val.getActiveWords();
+
+ if (EmitSizeForWideNumbers)
+ Vals.push_back(NWords);
+
+ const uint64_t *RawWords = Val.getRawData();
+ for (unsigned i = 0; i != NWords; ++i) {
+ int64_t V = RawWords[i];
+ if (V >= 0)
+ Vals.push_back(V << 1);
+ else
+ Vals.push_back((-V << 1) | 1);
+ }
+ Code = bitc::CST_CODE_WIDE_INTEGER;
+ }
+}
+
static void WriteConstants(unsigned FirstVal, unsigned LastVal,
const ValueEnumerator &VE,
BitstreamWriter &Stream, bool isGlobal) {
@@ -801,30 +840,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
} else if (isa<UndefValue>(C)) {
Code = bitc::CST_CODE_UNDEF;
} else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) {
- if (IV->getBitWidth() <= 64) {
- uint64_t V = IV->getSExtValue();
- if ((int64_t)V >= 0)
- Record.push_back(V << 1);
- else
- Record.push_back((-V << 1) | 1);
- Code = bitc::CST_CODE_INTEGER;
- AbbrevToUse = CONSTANTS_INTEGER_ABBREV;
- } else { // Wide integers, > 64 bits in size.
- // We have an arbitrary precision integer value to write whose
- // bit width is > 64. However, in canonical unsigned integer
- // format it is likely that the high bits are going to be zero.
- // So, we only write the number of active words.
- unsigned NWords = IV->getValue().getActiveWords();
- const uint64_t *RawWords = IV->getValue().getRawData();
- for (unsigned i = 0; i != NWords; ++i) {
- int64_t V = RawWords[i];
- if (V >= 0)
- Record.push_back(V << 1);
- else
- Record.push_back((-V << 1) | 1);
- }
- Code = bitc::CST_CODE_WIDE_INTEGER;
- }
+ EmitAPInt(Record, Code, AbbrevToUse, IV->getValue());
} else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
Code = bitc::CST_CODE_FLOAT;
Type *Ty = CFP->getType();
@@ -1139,12 +1155,31 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
{
Code = bitc::FUNC_CODE_INST_SWITCH;
SwitchInst &SI = cast<SwitchInst>(I);
+
+ uint32_t SwitchRecordHeader = SI.Hash() | (SWITCH_INST_MAGIC << 16);
+ Vals.push_back(SwitchRecordHeader);
+
Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
Vals.push_back(VE.getValueID(SI.getCondition()));
Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+ Vals.push_back(SI.getNumCases());
for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
- Vals.push_back(VE.getValueID(i.getCaseValue()));
+ ConstantRangesSet CRS = i.getCaseValueEx();
+ Vals.push_back(CRS.getNumItems());
+ for (unsigned ri = 0, rn = CRS.getNumItems(); ri != rn; ++ri) {
+ ConstantRangesSet::Range r = CRS.getItem(ri);
+
+ Vals.push_back(CRS.isSingleNumber(ri));
+
+ const APInt &Low = r.Low->getValue();
+ const APInt &High = r.High->getValue();
+ unsigned Code, Abbrev; // will unused.
+
+ EmitAPInt(Vals, Code, Abbrev, Low, true);
+ if (r.Low != r.High)
+ EmitAPInt(Vals, Code, Abbrev, High, true);
+ }
Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
}
}