19b044ec938fd56355012851890c63974c8042c9fStephen Hines//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
29b044ec938fd56355012851890c63974c8042c9fStephen Hines//
39b044ec938fd56355012851890c63974c8042c9fStephen Hines//                     The LLVM Compiler Infrastructure
49b044ec938fd56355012851890c63974c8042c9fStephen Hines//
59b044ec938fd56355012851890c63974c8042c9fStephen Hines// This file is distributed under the University of Illinois Open Source
69b044ec938fd56355012851890c63974c8042c9fStephen Hines// License. See LICENSE.TXT for details.
79b044ec938fd56355012851890c63974c8042c9fStephen Hines//
89b044ec938fd56355012851890c63974c8042c9fStephen Hines//===----------------------------------------------------------------------===//
99b044ec938fd56355012851890c63974c8042c9fStephen Hines//
109b044ec938fd56355012851890c63974c8042c9fStephen Hines// BitcodeWriterPass implementation.
119b044ec938fd56355012851890c63974c8042c9fStephen Hines//
129b044ec938fd56355012851890c63974c8042c9fStephen Hines//===----------------------------------------------------------------------===//
139b044ec938fd56355012851890c63974c8042c9fStephen Hines
149b044ec938fd56355012851890c63974c8042c9fStephen Hines#include "ReaderWriter_2_9_func.h"
1523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Function.h"
1623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Instructions.h"
1723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Module.h"
189b044ec938fd56355012851890c63974c8042c9fStephen Hines#include "llvm/Pass.h"
199b044ec938fd56355012851890c63974c8042c9fStephen Hinesusing namespace llvm;
209b044ec938fd56355012851890c63974c8042c9fStephen Hines
219b044ec938fd56355012851890c63974c8042c9fStephen Hinesnamespace {
229b044ec938fd56355012851890c63974c8042c9fStephen Hines  class WriteBitcodePass : public ModulePass {
239b044ec938fd56355012851890c63974c8042c9fStephen Hines    raw_ostream &OS; // raw_ostream to print on
24dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
25dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    bool expandCaseRange(Function &F);
269b044ec938fd56355012851890c63974c8042c9fStephen Hines  public:
279b044ec938fd56355012851890c63974c8042c9fStephen Hines    static char ID; // Pass identification, replacement for typeid
289b044ec938fd56355012851890c63974c8042c9fStephen Hines    explicit WriteBitcodePass(raw_ostream &o)
299b044ec938fd56355012851890c63974c8042c9fStephen Hines      : ModulePass(ID), OS(o) {}
309b044ec938fd56355012851890c63974c8042c9fStephen Hines
319b044ec938fd56355012851890c63974c8042c9fStephen Hines    const char *getPassName() const { return "Bitcode Writer"; }
329b044ec938fd56355012851890c63974c8042c9fStephen Hines
339b044ec938fd56355012851890c63974c8042c9fStephen Hines    bool runOnModule(Module &M) {
34dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      bool Changed = false;
35dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
36dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        if (!F->isDeclaration())
37dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          Changed |= expandCaseRange(*F);
38dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
399b044ec938fd56355012851890c63974c8042c9fStephen Hines      llvm_2_9_func::WriteBitcodeToFile(&M, OS);
40dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      return Changed;
419b044ec938fd56355012851890c63974c8042c9fStephen Hines    }
429b044ec938fd56355012851890c63974c8042c9fStephen Hines  };
439b044ec938fd56355012851890c63974c8042c9fStephen Hines}
449b044ec938fd56355012851890c63974c8042c9fStephen Hines
459b044ec938fd56355012851890c63974c8042c9fStephen Hineschar WriteBitcodePass::ID = 0;
469b044ec938fd56355012851890c63974c8042c9fStephen Hines
47dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao/// expandCaseRange - Expand case range into explicit case values within the
48dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao/// range
49dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liaobool WriteBitcodePass::expandCaseRange(Function &F) {
50dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao  bool Changed = false;
51dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
52dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao  for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
53dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator());
54dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    if (SI == NULL) {
55dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      continue;
56dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    }
57dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
58dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
59dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao         i != e; ++i) {
60dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      IntegersSubset& CaseRanges = i.getCaseValueEx();
61dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
62dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      // All case ranges are already in single case values
63dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      if (CaseRanges.isSingleNumbersOnly()) {
64dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        continue;
65dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      }
66dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
67dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      // Create a new case
68dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      Type *IntTy = SI->getCondition()->getType();
69dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      IntegersSubsetToBB CaseBuilder;
70dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      Changed = true;
71dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
72dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
73dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        IntegersSubset::Range r = CaseRanges.getItem(ri);
74dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
75dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
76dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        if (IsSingleNumber) {
77dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          CaseBuilder.add(r);
78dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        } else {
79dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          const APInt &Low = r.getLow();
80dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          const APInt &High = r.getHigh();
81dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
82dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          for (APInt V = Low; V != High; V++) {
83dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao            assert(r.isInRange(V) && "Unexpected out-of-range case value!");
84dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao            CaseBuilder.add(IntItem::fromType(IntTy, V));
85dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao          }
86dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        }
87dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
88dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        IntegersSubset Case = CaseBuilder.getCase();
89dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao        i.setValueEx(Case);
90dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      }
91dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    }
92dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao  }
93dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao  return Changed;
94dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao}
95dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
969b044ec938fd56355012851890c63974c8042c9fStephen Hines/// createBitcodeWriterPass - Create and return a pass that writes the module
979b044ec938fd56355012851890c63974c8042c9fStephen Hines/// to the specified ostream.
989b044ec938fd56355012851890c63974c8042c9fStephen Hinesllvm::ModulePass *llvm_2_9_func::createBitcodeWriterPass(llvm::raw_ostream &Str) {
999b044ec938fd56355012851890c63974c8042c9fStephen Hines  return new WriteBitcodePass(Str);
1009b044ec938fd56355012851890c63974c8042c9fStephen Hines}
101