diff options
author | Stephen Hines <srhines@google.com> | 2013-12-16 17:45:42 -0800 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2013-12-16 17:45:42 -0800 |
commit | 99d429070eb7c4c39fb7d74555031d518a4e0a79 (patch) | |
tree | e8ffa0e46f883d46226746280654bfd6b7d5497c | |
parent | f6557f87687f9414656bc121b1b70df913edc186 (diff) | |
download | slang-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.cpp | 58 | ||||
-rw-r--r-- | BitWriter_3_2/BitcodeWriterPass.cpp | 61 | ||||
-rw-r--r-- | BitWriter_3_2/ValueEnumerator.cpp | 10 |
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; } } |