Home | History | Annotate | Download | only in BitWriter_2_9_func
      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
     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_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
     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.
     98 llvm::ModulePass *llvm_2_9_func::createBitcodeWriterPass(llvm::raw_ostream &Str) {
     99   return new WriteBitcodePass(Str);
    100 }
    101