blob: 2a1eec263911d69038a376ef0d13aab70e933fb8 [file] [log] [blame]
Chris Lattner00950542001-06-06 20:29:01 +00001//===-- iSwitch.cpp - Implement the Switch instruction -----------*- C++ -*--=//
2//
3// This file implements the Switch instruction...
4//
5//===----------------------------------------------------------------------===//
6
7#include "llvm/iTerminators.h"
8#include "llvm/BasicBlock.h"
9#ifndef NDEBUG
10#include "llvm/Type.h"
11#endif
12
13SwitchInst::SwitchInst(Value *V, BasicBlock *DefV)
14 : TerminatorInst(Instruction::Switch),
15 DefaultDest(DefV, this), Val(V, this) {
16 assert(Val && DefV);
17}
18
19SwitchInst::SwitchInst(const SwitchInst &SI)
20 : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest),
21 Val(SI.Val) {
22
23 for (dest_const_iterator I = SI.Destinations.begin(),
24 end = SI.Destinations.end(); I != end; ++I)
25 Destinations.push_back(dest_value(ConstPoolUse(I->first, this),
26 BasicBlockUse(I->second, this)));
27}
28
29
30void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) {
31 Destinations.push_back(dest_value(ConstPoolUse(OnVal, this),
32 BasicBlockUse(Dest, this)));
33}
34
35void SwitchInst::dropAllReferences() {
36 Val = 0;
37 DefaultDest = 0;
38 Destinations.clear();
39}
40
41const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const {
42 if (idx == 0) return DefaultDest;
43 if (idx > Destinations.size()) return 0;
44 return Destinations[idx-1].second;
45}
46
47unsigned SwitchInst::getNumOperands() const {
48 return 2+Destinations.size();
49}
50
51const Value *SwitchInst::getOperand(unsigned i) const {
52 if (i == 0) return Val;
53 else if (i == 1) return DefaultDest;
54
55 unsigned slot = (i-2) >> 1;
56 if (slot >= Destinations.size()) return 0;
57
58 if (i & 1) return Destinations[slot].second;
59 return Destinations[slot].first;
60}
61
62bool SwitchInst::setOperand(unsigned i, Value *V) {
63 if (i == 0) { Val = V; return true; }
64 else if (i == 1) {
65 assert(V->getType() == Type::LabelTy);
66 DefaultDest = (BasicBlock*)V;
67 return true;
68 }
69
70 unsigned slot = (i-2) >> 1;
71 if (slot >= Destinations.size()) return 0;
72
73 if (i & 1) {
74 assert(V->getType() == Type::LabelTy);
75 Destinations[slot].second = (BasicBlock*)V;
76 } else {
77 // TODO: assert constant
78 Destinations[slot].first = (ConstPoolVal*)V;
79 }
80 return true;
81}