BitcodeWriterPass.cpp revision dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593
1//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// BitcodeWriterPass implementation.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ReaderWriter_2_9.h"
15#include "llvm/Function.h"
16#include "llvm/Instructions.h"
17#include "llvm/Module.h"
18#include "llvm/Pass.h"
19using namespace llvm;
20
21namespace {
22  class WriteBitcodePass : public ModulePass {
23    raw_ostream &OS; // raw_ostream to print on
24
25    bool expandCaseRange(Function &F);
26  public:
27    static char ID; // Pass identification, replacement for typeid
28    explicit WriteBitcodePass(raw_ostream &o)
29      : ModulePass(ID), OS(o) {}
30
31    const char *getPassName() const { return "Bitcode Writer"; }
32
33    bool runOnModule(Module &M) {
34      bool Changed = false;
35      for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
36        if (!F->isDeclaration())
37          Changed |= expandCaseRange(*F);
38
39      llvm_2_9::WriteBitcodeToFile(&M, OS);
40      return Changed;
41    }
42  };
43}
44
45char WriteBitcodePass::ID = 0;
46
47/// expandCaseRange - Expand case range into explicit case values within the
48/// range
49bool WriteBitcodePass::expandCaseRange(Function &F) {
50  bool Changed = false;
51
52  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
53    SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator());
54    if (SI == NULL) {
55      continue;
56    }
57
58    for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
59         i != e; ++i) {
60      IntegersSubset& CaseRanges = i.getCaseValueEx();
61
62      // All case ranges are already in single case values
63      if (CaseRanges.isSingleNumbersOnly()) {
64        continue;
65      }
66
67      // Create a new case
68      Type *IntTy = SI->getCondition()->getType();
69      IntegersSubsetToBB CaseBuilder;
70      Changed = true;
71
72      for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
73        IntegersSubset::Range r = CaseRanges.getItem(ri);
74        bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
75
76        if (IsSingleNumber) {
77          CaseBuilder.add(r);
78        } else {
79          const APInt &Low = r.getLow();
80          const APInt &High = r.getHigh();
81
82          for (APInt V = Low; V != High; V++) {
83            assert(r.isInRange(V) && "Unexpected out-of-range case value!");
84            CaseBuilder.add(IntItem::fromType(IntTy, V));
85          }
86        }
87
88        IntegersSubset Case = CaseBuilder.getCase();
89        i.setValueEx(Case);
90      }
91    }
92  }
93  return Changed;
94}
95
96/// createBitcodeWriterPass - Create and return a pass that writes the module
97/// to the specified ostream.
98llvm::ModulePass *llvm_2_9::createBitcodeWriterPass(llvm::raw_ostream &Str) {
99  return new WriteBitcodePass(Str);
100}
101