14cc499d6e5ec602309501873449c938af61170b2Stephen Hines//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===//
24cc499d6e5ec602309501873449c938af61170b2Stephen Hines//
34cc499d6e5ec602309501873449c938af61170b2Stephen Hines//                     The LLVM Compiler Infrastructure
44cc499d6e5ec602309501873449c938af61170b2Stephen Hines//
54cc499d6e5ec602309501873449c938af61170b2Stephen Hines// This file is distributed under the University of Illinois Open Source
64cc499d6e5ec602309501873449c938af61170b2Stephen Hines// License. See LICENSE.TXT for details.
74cc499d6e5ec602309501873449c938af61170b2Stephen Hines//
84cc499d6e5ec602309501873449c938af61170b2Stephen Hines//===----------------------------------------------------------------------===//
94cc499d6e5ec602309501873449c938af61170b2Stephen Hines//
104cc499d6e5ec602309501873449c938af61170b2Stephen Hines// BitcodeWriterPass implementation.
114cc499d6e5ec602309501873449c938af61170b2Stephen Hines//
124cc499d6e5ec602309501873449c938af61170b2Stephen Hines//===----------------------------------------------------------------------===//
134cc499d6e5ec602309501873449c938af61170b2Stephen Hines
144cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include "ReaderWriter_2_9.h"
1523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Function.h"
1623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Instructions.h"
1723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines#include "llvm/IR/Module.h"
184cc499d6e5ec602309501873449c938af61170b2Stephen Hines#include "llvm/Pass.h"
194cc499d6e5ec602309501873449c938af61170b2Stephen Hinesusing namespace llvm;
204cc499d6e5ec602309501873449c938af61170b2Stephen Hines
214cc499d6e5ec602309501873449c938af61170b2Stephen Hinesnamespace {
224cc499d6e5ec602309501873449c938af61170b2Stephen Hines  class WriteBitcodePass : public ModulePass {
234cc499d6e5ec602309501873449c938af61170b2Stephen Hines    raw_ostream &OS; // raw_ostream to print on
24dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao
25dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao    bool expandCaseRange(Function &F);
264cc499d6e5ec602309501873449c938af61170b2Stephen Hines  public:
274cc499d6e5ec602309501873449c938af61170b2Stephen Hines    static char ID; // Pass identification, replacement for typeid
284cc499d6e5ec602309501873449c938af61170b2Stephen Hines    explicit WriteBitcodePass(raw_ostream &o)
294cc499d6e5ec602309501873449c938af61170b2Stephen Hines      : ModulePass(ID), OS(o) {}
304cc499d6e5ec602309501873449c938af61170b2Stephen Hines
314cc499d6e5ec602309501873449c938af61170b2Stephen Hines    const char *getPassName() const { return "Bitcode Writer"; }
324cc499d6e5ec602309501873449c938af61170b2Stephen Hines
334cc499d6e5ec602309501873449c938af61170b2Stephen 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
394cc499d6e5ec602309501873449c938af61170b2Stephen Hines      llvm_2_9::WriteBitcodeToFile(&M, OS);
40dbfe3fabb0b82d9c73e4a48a0bc3ebb6a9cda593Shih-wei Liao      return Changed;
414cc499d6e5ec602309501873449c938af61170b2Stephen Hines    }
424cc499d6e5ec602309501873449c938af61170b2Stephen Hines  };
434cc499d6e5ec602309501873449c938af61170b2Stephen Hines}
444cc499d6e5ec602309501873449c938af61170b2Stephen Hines
454cc499d6e5ec602309501873449c938af61170b2Stephen Hineschar WriteBitcodePass::ID = 0;
464cc499d6e5ec602309501873449c938af61170b2Stephen 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
964cc499d6e5ec602309501873449c938af61170b2Stephen Hines/// createBitcodeWriterPass - Create and return a pass that writes the module
974cc499d6e5ec602309501873449c938af61170b2Stephen Hines/// to the specified ostream.
984cc499d6e5ec602309501873449c938af61170b2Stephen Hinesllvm::ModulePass *llvm_2_9::createBitcodeWriterPass(llvm::raw_ostream &Str) {
994cc499d6e5ec602309501873449c938af61170b2Stephen Hines  return new WriteBitcodePass(Str);
1004cc499d6e5ec602309501873449c938af61170b2Stephen Hines}
101