• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_func.h"
15 #include "llvm/IR/Function.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Pass.h"
19 using namespace llvm;
20 
21 namespace {
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
WriteBitcodePass(raw_ostream & o)28     explicit WriteBitcodePass(raw_ostream &o)
29       : ModulePass(ID), OS(o) {}
30 
getPassName() const31     const char *getPassName() const { return "Bitcode Writer"; }
32 
runOnModule(Module & M)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_func::WriteBitcodeToFile(&M, OS);
40       return Changed;
41     }
42   };
43 }
44 
45 char WriteBitcodePass::ID = 0;
46 
47 /// expandCaseRange - Expand case range into explicit case values within the
48 /// range
expandCaseRange(Function & F)49 bool 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.
createBitcodeWriterPass(llvm::raw_ostream & Str)98 llvm::ModulePass *llvm_2_9_func::createBitcodeWriterPass(llvm::raw_ostream &Str) {
99   return new WriteBitcodePass(Str);
100 }
101