Skip to content
Instructions.cpp 108 KiB
Newer Older
//===-- Instructions.cpp - Implement the LLVM instructions ----------------===//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//
//
// This file implements all of the non-inline methods for the LLVM instruction
// classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
//===----------------------------------------------------------------------===//
//                            CallSite Class
//===----------------------------------------------------------------------===//

CallSite::CallSite(Instruction *C) {
  assert((isa<CallInst>(C) || isa<InvokeInst>(C)) && "Not a call!");
  I = C;
}
unsigned CallSite::getCallingConv() const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->getCallingConv();
  else
    return cast<InvokeInst>(I)->getCallingConv();
}
void CallSite::setCallingConv(unsigned CC) {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    CI->setCallingConv(CC);
  else
    cast<InvokeInst>(I)->setCallingConv(CC);
}
const PAListPtr &CallSite::getParamAttrs() const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->getParamAttrs();
  else
    return cast<InvokeInst>(I)->getParamAttrs();
}
void CallSite::setParamAttrs(const PAListPtr &PAL) {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    CI->setParamAttrs(PAL);
  else
    cast<InvokeInst>(I)->setParamAttrs(PAL);
}
bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->paramHasAttr(i, attr);
    return cast<InvokeInst>(I)->paramHasAttr(i, attr);
uint16_t CallSite::getParamAlignment(uint16_t i) const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->getParamAlignment(i);
  else
    return cast<InvokeInst>(I)->getParamAlignment(i);
}

bool CallSite::doesNotAccessMemory() const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->doesNotAccessMemory();
  else
    return cast<InvokeInst>(I)->doesNotAccessMemory();
}
bool CallSite::onlyReadsMemory() const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->onlyReadsMemory();
  else
    return cast<InvokeInst>(I)->onlyReadsMemory();
}
bool CallSite::doesNotThrow() const {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    return CI->doesNotThrow();
    return cast<InvokeInst>(I)->doesNotThrow();
void CallSite::setDoesNotThrow(bool doesNotThrow) {
  if (CallInst *CI = dyn_cast<CallInst>(I))
    CI->setDoesNotThrow(doesNotThrow);
  else
    cast<InvokeInst>(I)->setDoesNotThrow(doesNotThrow);
}
bool CallSite::hasArgument(const Value *Arg) const {
  for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E; ++AI)
    if (AI->get() == Arg)
      return true;
  return false;
}

//===----------------------------------------------------------------------===//
//                            TerminatorInst Class
//===----------------------------------------------------------------------===//

// Out of line virtual method, so the vtable, etc has a home.
TerminatorInst::~TerminatorInst() {
}

//===----------------------------------------------------------------------===//
//                           UnaryInstruction Class
//===----------------------------------------------------------------------===//

// Out of line virtual method, so the vtable, etc has a home.
UnaryInstruction::~UnaryInstruction() {
}

//===----------------------------------------------------------------------===//
//                               PHINode Class
//===----------------------------------------------------------------------===//

PHINode::PHINode(const PHINode &PN)
  : Instruction(PN.getType(), Instruction::PHI,
                allocHungoffUses(PN.getNumOperands()), PN.getNumOperands()),
    ReservedSpace(PN.getNumOperands()) {
  Use *OL = OperandList;
  for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
    OL[i] = PN.getOperand(i);
    OL[i+1] = PN.getOperand(i+1);
PHINode::~PHINode() {
Chris Lattner's avatar
Chris Lattner committed
  if (OperandList)
    dropHungoffUses(OperandList);
}

// removeIncomingValue - Remove an incoming value.  This is useful if a
// predecessor basic block is deleted.
Value *PHINode::removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty) {
  unsigned NumOps = getNumOperands();
  Use *OL = OperandList;
  assert(Idx*2 < NumOps && "BB not in PHI node!");
  Value *Removed = OL[Idx*2];

  // Move everything after this operand down.
  //
  // FIXME: we could just swap with the end of the list, then erase.  However,
  // client might not expect this to happen.  The code as it is thrashes the
  // use/def lists, which is kinda lame.
  for (unsigned i = (Idx+1)*2; i != NumOps; i += 2) {
    OL[i-2] = OL[i];
    OL[i-2+1] = OL[i+1];
  }

  // Nuke the last value.
  OL[NumOps-2].set(0);
  OL[NumOps-2+1].set(0);
  NumOperands = NumOps-2;

  // If the PHI node is dead, because it has zero entries, nuke it now.
  if (NumOps == 2 && DeletePHIIfEmpty) {
    // If anyone is using this PHI, make them use a dummy value instead...
    replaceAllUsesWith(UndefValue::get(getType()));
    eraseFromParent();
  }
  return Removed;
}

/// resizeOperands - resize operands - This adjusts the length of the operands
/// list according to the following behavior:
///   1. If NumOps == 0, grow the operand list in response to a push_back style
///      of operation.  This grows the number of ops by 1.5 times.
///   2. If NumOps > NumOperands, reserve space for NumOps operands.
///   3. If NumOps == NumOperands, trim the reserved space.
///
void PHINode::resizeOperands(unsigned NumOps) {
  unsigned e = getNumOperands();
  if (NumOps == 0) {
    NumOps = e*3/2;
    if (NumOps < 4) NumOps = 4;      // 4 op PHI nodes are VERY common.
  } else if (NumOps*2 > NumOperands) {
    // No resize needed.
    if (ReservedSpace >= NumOps) return;
  } else if (NumOps == NumOperands) {
    if (ReservedSpace == NumOps) return;
  } else {
    return;
  }

  ReservedSpace = NumOps;
  Use *OldOps = OperandList;
  Use *NewOps = allocHungoffUses(NumOps);
  for (unsigned i = 0; i != e; ++i) {
      NewOps[i] = OldOps[i];
  }
  OperandList = NewOps;
  if (OldOps) Use::zap(OldOps, OldOps + e, true);
/// hasConstantValue - If the specified PHI node always merges together the same
Loading
Loading full blame...