aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-12-16 17:45:42 -0800
committerStephen Hines <srhines@google.com>2013-12-16 17:45:42 -0800
commit99d429070eb7c4c39fb7d74555031d518a4e0a79 (patch)
treee8ffa0e46f883d46226746280654bfd6b7d5497c
parentf6557f87687f9414656bc121b1b70df913edc186 (diff)
downloadslang-99d429070eb7c4c39fb7d74555031d518a4e0a79.tar.gz
Split up case-range in BitWriter_3_2 as well.
Bug: 12135682 This is a temporary WAR, as LLVM 3.4 removes support for case-range statements completely. That is a much larger patch to external/llvm, and requires more thorough testing. Change-Id: Ief8ec4796a8cce13ffc8cb4f2b961eecdc7ca264
-rw-r--r--BitWriter_3_2/BitcodeWriter.cpp58
-rw-r--r--BitWriter_3_2/BitcodeWriterPass.cpp61
-rw-r--r--BitWriter_3_2/ValueEnumerator.cpp10
3 files changed, 82 insertions, 47 deletions
diff --git a/BitWriter_3_2/BitcodeWriter.cpp b/BitWriter_3_2/BitcodeWriter.cpp
index 11f224a..b6ac056 100644
--- a/BitWriter_3_2/BitcodeWriter.cpp
+++ b/BitWriter_3_2/BitcodeWriter.cpp
@@ -1165,63 +1165,29 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::Switch:
{
- // Redefine Vals, since here we need to use 64 bit values
- // explicitly to store large APInt numbers.
- SmallVector<uint64_t, 128> Vals64;
-
Code = bitc::FUNC_CODE_INST_SWITCH;
const SwitchInst &SI = cast<SwitchInst>(I);
- uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16);
- Vals64.push_back(SwitchRecordHeader);
-
- Vals64.push_back(VE.getTypeID(SI.getCondition()->getType()));
- Vals64.push_back(VE.getValueID(SI.getCondition()));
- Vals64.push_back(VE.getValueID(SI.getDefaultDest()));
- Vals64.push_back(SI.getNumCases());
+ Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+ Vals.push_back(VE.getValueID(SI.getCondition()));
+ Vals.push_back(VE.getValueID(SI.getDefaultDest()));
for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end();
i != e; ++i) {
const IntegersSubset& CaseRanges = i.getCaseValueEx();
- unsigned Code, Abbrev; // will unused.
if (CaseRanges.isSingleNumber()) {
- Vals64.push_back(1/*NumItems = 1*/);
- Vals64.push_back(true/*IsSingleNumber = true*/);
- EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
+ Vals.push_back(VE.getValueID(CaseRanges.getSingleNumber(0).toConstantInt()));
+ Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+ } else if (CaseRanges.isSingleNumbersOnly()) {
+ for (unsigned ri = 0, rn = CaseRanges.getNumItems();
+ ri != rn; ++ri) {
+ Vals.push_back(VE.getValueID(CaseRanges.getSingleNumber(ri).toConstantInt()));
+ Vals.push_back(VE.getValueID(i.getCaseSuccessor()));
+ }
} else {
-
- Vals64.push_back(CaseRanges.getNumItems());
-
- if (CaseRanges.isSingleNumbersOnly()) {
- for (unsigned ri = 0, rn = CaseRanges.getNumItems();
- ri != rn; ++ri) {
-
- Vals64.push_back(true/*IsSingleNumber = true*/);
-
- EmitAPInt(Vals64, Code, Abbrev,
- CaseRanges.getSingleNumber(ri), true);
- }
- } else
- for (unsigned ri = 0, rn = CaseRanges.getNumItems();
- ri != rn; ++ri) {
- IntegersSubset::Range r = CaseRanges.getItem(ri);
- bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
-
- Vals64.push_back(IsSingleNumber);
-
- EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
- if (!IsSingleNumber)
- EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
- }
+ llvm_unreachable("Not single number?");
}
- Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
}
-
- Stream.EmitRecord(Code, Vals64, AbbrevToUse);
-
- // Also do expected action - clear external Vals collection:
- Vals.clear();
- return;
}
break;
case Instruction::IndirectBr:
diff --git a/BitWriter_3_2/BitcodeWriterPass.cpp b/BitWriter_3_2/BitcodeWriterPass.cpp
index 23ee35a..a1e6e7e 100644
--- a/BitWriter_3_2/BitcodeWriterPass.cpp
+++ b/BitWriter_3_2/BitcodeWriterPass.cpp
@@ -12,12 +12,17 @@
//===----------------------------------------------------------------------===//
#include "ReaderWriter_3_2.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
using namespace llvm;
namespace {
class WriteBitcodePass : public ModulePass {
raw_ostream &OS; // raw_ostream to print on
+
+ bool expandCaseRange(Function &F);
public:
static char ID; // Pass identification, replacement for typeid
explicit WriteBitcodePass(raw_ostream &o)
@@ -26,14 +31,68 @@ namespace {
const char *getPassName() const { return "Bitcode Writer"; }
bool runOnModule(Module &M) {
+ bool Changed = false;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ if (!F->isDeclaration())
+ Changed |= expandCaseRange(*F);
+
llvm_3_2::WriteBitcodeToFile(&M, OS);
- return false;
+ return Changed;
}
};
}
char WriteBitcodePass::ID = 0;
+/// expandCaseRange - Expand case range into explicit case values within the
+/// range
+bool WriteBitcodePass::expandCaseRange(Function &F) {
+ bool Changed = false;
+
+ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
+ SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator());
+ if (SI == NULL) {
+ continue;
+ }
+
+ for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
+ i != e; ++i) {
+ IntegersSubset& CaseRanges = i.getCaseValueEx();
+
+ // All case ranges are already in single case values
+ if (CaseRanges.isSingleNumbersOnly()) {
+ continue;
+ }
+
+ // Create a new case
+ Type *IntTy = SI->getCondition()->getType();
+ IntegersSubsetToBB CaseBuilder;
+ Changed = true;
+
+ for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
+ IntegersSubset::Range r = CaseRanges.getItem(ri);
+ bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
+
+ if (IsSingleNumber) {
+ CaseBuilder.add(r);
+ } else {
+ const APInt &Low = r.getLow();
+ const APInt &High = r.getHigh();
+
+ for (APInt V = Low; V != High; V++) {
+ assert(r.isInRange(V) && "Unexpected out-of-range case value!");
+ CaseBuilder.add(IntItem::fromType(IntTy, V));
+ }
+ }
+
+ IntegersSubset Case = CaseBuilder.getCase();
+ i.setValueEx(Case);
+ }
+ }
+ }
+ return Changed;
+}
+
/// createBitcodeWriterPass - Create and return a pass that writes the module
/// to the specified ostream.
ModulePass *llvm_3_2::createBitcodeWriterPass(raw_ostream &Str) {
diff --git a/BitWriter_3_2/ValueEnumerator.cpp b/BitWriter_3_2/ValueEnumerator.cpp
index 85fee79..47dd2d0 100644
--- a/BitWriter_3_2/ValueEnumerator.cpp
+++ b/BitWriter_3_2/ValueEnumerator.cpp
@@ -343,6 +343,16 @@ void ValueEnumerator::EnumerateValue(const Value *V) {
Values.push_back(std::make_pair(V, 1U));
ValueMap[V] = Values.size();
return;
+ } else if (const ConstantDataSequential *CDS =
+ dyn_cast<ConstantDataSequential>(C)) {
+ // For our legacy handling of the new ConstantDataSequential type, we
+ // need to enumerate the individual elements, as well as mark the
+ // outer constant as used.
+ for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
+ EnumerateValue(CDS->getElementAsConstant(i));
+ Values.push_back(std::make_pair(V, 1U));
+ ValueMap[V] = Values.size();
+ return;
}
}