Skip to content
Instructions.cpp 94.3 KiB
Newer Older
//===-- Instructions.cpp - Implement the LLVM instructions ----------------===//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and 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/BasicBlock.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
Reid Spencer's avatar
Reid Spencer committed
#include "llvm/ParameterAttributes.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ConstantRange.h"
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);
}


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

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

// 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,
                new Use[PN.getNumOperands()], PN.getNumOperands()),
    ReservedSpace(PN.getNumOperands()) {
  Use *OL = OperandList;
  for (unsigned i = 0, e = PN.getNumOperands(); i != e; i+=2) {
    OL[i].init(PN.getOperand(i), this);
    OL[i+1].init(PN.getOperand(i+1), this);
  }
}

PHINode::~PHINode() {
  delete [] 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) {
  if (NumOps == 0) {
    NumOps = (getNumOperands())*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 *NewOps = new Use[NumOps];
  Use *OldOps = OperandList;
  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
      NewOps[i].init(OldOps[i], this);
      OldOps[i].set(0);
  }
  delete [] OldOps;
  OperandList = NewOps;
}

/// hasConstantValue - If the specified PHI node always merges together the same
/// value, return the value, otherwise return null.
///
Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
  // If the PHI node only has one incoming value, eliminate the PHI node...
  if (getNumIncomingValues() == 1)
    if (getIncomingValue(0) != this)   // not  X = phi X
      return getIncomingValue(0);
    else
      return UndefValue::get(getType());  // Self cycle is dead.
      
  // Otherwise if all of the incoming values are the same for the PHI, replace
  // the PHI node with the incoming value.
  //
  Value *InVal = 0;
  for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
    if (isa<UndefValue>(getIncomingValue(i)))
      HasUndefInput = true;
    else if (getIncomingValue(i) != this)  // Not the PHI node itself...
      if (InVal && getIncomingValue(i) != InVal)
        return 0;  // Not the same, bail out.
      else
        InVal = getIncomingValue(i);
  
  // The only case that could cause InVal to be null is if we have a PHI node
  // that only has entries for itself.  In this case, there is no entry into the
  // loop, so kill the PHI.
  //
  if (InVal == 0) InVal = UndefValue::get(getType());
  
  // If we have a PHI node like phi(X, undef, X), where X is defined by some
  // instruction, we cannot always return X as the result of the PHI node.  Only
  // do this if X is not an instruction (thus it must dominate the PHI block),
  // or if the client is prepared to deal with this possibility.
  if (HasUndefInput && !AllowNonDominatingInstruction)
    if (Instruction *IV = dyn_cast<Instruction>(InVal))
      // If it's in the entry block, it dominates everything.
      if (IV->getParent() != &IV->getParent()->getParent()->getEntryBlock() ||
          isa<InvokeInst>(IV))
        return 0;   // Cannot guarantee that InVal dominates this PHINode.

  // All of the incoming values are the same, return the value now.
  return InVal;
}

//===----------------------------------------------------------------------===//
//                        CallInst Implementation
//===----------------------------------------------------------------------===//

CallInst::~CallInst() {
  delete [] OperandList;
Reid Spencer's avatar
Reid Spencer committed
  if (ParamAttrs)
    ParamAttrs->dropRef();
Chris Lattner's avatar
Chris Lattner committed
void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
Reid Spencer's avatar
Reid Spencer committed
  ParamAttrs = 0;
Chris Lattner's avatar
Chris Lattner committed
  NumOperands = NumParams+1;
  Use *OL = OperandList = new Use[NumParams+1];
  OL[0].init(Func, this);
  const FunctionType *FTy =
Loading
Loading full blame...