| //===-- iSwitch.cpp - Implement the Switch instruction -----------*- C++ -*--=// |
| // |
| // This file implements the Switch instruction... |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/iTerminators.h" |
| #include "llvm/BasicBlock.h" |
| #ifndef NDEBUG |
| #include "llvm/Type.h" |
| #endif |
| |
| SwitchInst::SwitchInst(Value *V, BasicBlock *DefV) |
| : TerminatorInst(Instruction::Switch), |
| DefaultDest(DefV, this), Val(V, this) { |
| assert(Val && DefV); |
| } |
| |
| SwitchInst::SwitchInst(const SwitchInst &SI) |
| : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest), |
| Val(SI.Val) { |
| |
| for (dest_const_iterator I = SI.Destinations.begin(), |
| end = SI.Destinations.end(); I != end; ++I) |
| Destinations.push_back(dest_value(ConstPoolUse(I->first, this), |
| BasicBlockUse(I->second, this))); |
| } |
| |
| |
| void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) { |
| Destinations.push_back(dest_value(ConstPoolUse(OnVal, this), |
| BasicBlockUse(Dest, this))); |
| } |
| |
| void SwitchInst::dropAllReferences() { |
| Val = 0; |
| DefaultDest = 0; |
| Destinations.clear(); |
| } |
| |
| const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const { |
| if (idx == 0) return DefaultDest; |
| if (idx > Destinations.size()) return 0; |
| return Destinations[idx-1].second; |
| } |
| |
| unsigned SwitchInst::getNumOperands() const { |
| return 2+Destinations.size(); |
| } |
| |
| const Value *SwitchInst::getOperand(unsigned i) const { |
| if (i == 0) return Val; |
| else if (i == 1) return DefaultDest; |
| |
| unsigned slot = (i-2) >> 1; |
| if (slot >= Destinations.size()) return 0; |
| |
| if (i & 1) return Destinations[slot].second; |
| return Destinations[slot].first; |
| } |
| |
| bool SwitchInst::setOperand(unsigned i, Value *V) { |
| if (i == 0) { Val = V; return true; } |
| else if (i == 1) { |
| assert(V->getType() == Type::LabelTy); |
| DefaultDest = (BasicBlock*)V; |
| return true; |
| } |
| |
| unsigned slot = (i-2) >> 1; |
| if (slot >= Destinations.size()) return 0; |
| |
| if (i & 1) { |
| assert(V->getType() == Type::LabelTy); |
| Destinations[slot].second = (BasicBlock*)V; |
| } else { |
| // TODO: assert constant |
| Destinations[slot].first = (ConstPoolVal*)V; |
| } |
| return true; |
| } |