blob: 1ae455608daba9829fe4ab1ab54db55620c852a2 [file] [log] [blame]
Stephen Hines4cc499d2011-08-24 19:06:17 -07001//===--- 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"
Shih-wei Liaodbfe3fa2012-08-05 23:47:54 -070015#include "llvm/Function.h"
16#include "llvm/Instructions.h"
17#include "llvm/Module.h"
Stephen Hines4cc499d2011-08-24 19:06:17 -070018#include "llvm/Pass.h"
19using namespace llvm;
20
21namespace {
22 class WriteBitcodePass : public ModulePass {
23 raw_ostream &OS; // raw_ostream to print on
Shih-wei Liaodbfe3fa2012-08-05 23:47:54 -070024
25 bool expandCaseRange(Function &F);
Stephen Hines4cc499d2011-08-24 19:06:17 -070026 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) {
Shih-wei Liaodbfe3fa2012-08-05 23:47:54 -070034 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
Stephen Hines4cc499d2011-08-24 19:06:17 -070039 llvm_2_9::WriteBitcodeToFile(&M, OS);
Shih-wei Liaodbfe3fa2012-08-05 23:47:54 -070040 return Changed;
Stephen Hines4cc499d2011-08-24 19:06:17 -070041 }
42 };
43}
44
45char WriteBitcodePass::ID = 0;
46
Shih-wei Liaodbfe3fa2012-08-05 23:47:54 -070047/// 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
Stephen Hines4cc499d2011-08-24 19:06:17 -070096/// 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}