Major repairs to the post-dominators implementation. Patch from Florian Brandner!
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index dfd3b830caaced46159274ce467e4d9764323d94..ad99c78c1ab97c904be5b65197af0a6466f43325 100644 (file)
@@ -17,7 +17,6 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
-#include "llvm/ParamAttrsList.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/MathExtras.h"
@@ -43,13 +42,13 @@ void CallSite::setCallingConv(unsigned CC) {
   else
     cast<InvokeInst>(I)->setCallingConv(CC);
 }
-const ParamAttrsList* CallSite::getParamAttrs() const {
+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 ParamAttrsList *PAL) {
+void CallSite::setParamAttrs(const PAListPtr &PAL) {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     CI->setParamAttrs(PAL);
   else
@@ -243,12 +242,9 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
 
 CallInst::~CallInst() {
   delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
 }
 
 void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
-  ParamAttrs = 0;
   NumOperands = NumParams+1;
   Use *OL = OperandList = new Use[NumParams+1];
   OL[0].init(Func, this);
@@ -269,7 +265,6 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
 }
 
 void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
-  ParamAttrs = 0;
   NumOperands = 3;
   Use *OL = OperandList = new Use[3];
   OL[0].init(Func, this);
@@ -292,7 +287,6 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) {
 }
 
 void CallInst::init(Value *Func, Value *Actual) {
-  ParamAttrs = 0;
   NumOperands = 2;
   Use *OL = OperandList = new Use[2];
   OL[0].init(Func, this);
@@ -311,7 +305,6 @@ void CallInst::init(Value *Func, Value *Actual) {
 }
 
 void CallInst::init(Value *Func) {
-  ParamAttrs = 0;
   NumOperands = 1;
   Use *OL = OperandList = new Use[1];
   OL[0].init(Func, this);
@@ -360,8 +353,7 @@ CallInst::CallInst(Value *Func, const std::string &Name,
 
 CallInst::CallInst(const CallInst &CI)
   : Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()],
-                CI.getNumOperands()),
-    ParamAttrs(0) {
+                CI.getNumOperands()) {
   setParamAttrs(CI.getParamAttrs());
   SubclassData = CI.SubclassData;
   Use *OL = OperandList;
@@ -370,78 +362,20 @@ CallInst::CallInst(const CallInst &CI)
     OL[i].init(InOL[i], this);
 }
 
-void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) {
-  if (ParamAttrs == newAttrs)
-    return;
-
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
-
-  if (newAttrs)
-    newAttrs->addRef();
-
-  ParamAttrs = newAttrs; 
-}
-
-bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool CallInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+  if (ParamAttrs.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-uint16_t CallInst::getParamAlignment(uint16_t i) const {
-  if (ParamAttrs && ParamAttrs->getParamAlignment(i))
-    return ParamAttrs->getParamAlignment(i);
-  if (const Function *F = getCalledFunction())
-    return F->getParamAlignment(i);
-  return 0;
-}
-
-/// @brief Determine if the call does not access memory.
-bool CallInst::doesNotAccessMemory() const {
-  return paramHasAttr(0, ParamAttr::ReadNone);
-}
-
-/// @brief Determine if the call does not access or only reads memory.
-bool CallInst::onlyReadsMemory() const {
-  return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
-}
-
-/// @brief Determine if the call cannot return.
-bool CallInst::doesNotReturn() const {
-  return paramHasAttr(0, ParamAttr::NoReturn);
-}
-
-/// @brief Determine if the call cannot unwind.
-bool CallInst::doesNotThrow() const {
-  return paramHasAttr(0, ParamAttr::NoUnwind);
-}
-
-/// @brief Determine if the call returns a structure.
-bool CallInst::isStructReturn() const {
-  // Be friendly and also check the callee.
-  return paramHasAttr(1, ParamAttr::StructRet);
-}
-
-/// @brief Determine if any call argument is an aggregate passed by value.
-bool CallInst::hasByValArgument() const {
-  if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal))
-    return true;
-  // Be consistent with other methods and check the callee too.
-  if (const Function *F = getCalledFunction())
-    if (const ParamAttrsList *PAL = F->getParamAttrs())
-      return PAL->hasAttrSomewhere(ParamAttr::ByVal);
-  return false;
-}
-
 void CallInst::setDoesNotThrow(bool doesNotThrow) {
-  const ParamAttrsList *PAL = getParamAttrs();
+  PAListPtr PAL = getParamAttrs();
   if (doesNotThrow)
-    PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
   else
-    PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
   setParamAttrs(PAL);
 }
 
@@ -452,13 +386,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) {
 
 InvokeInst::~InvokeInst() {
   delete [] OperandList;
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
 }
 
 void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
                       Value* const *Args, unsigned NumArgs) {
-  ParamAttrs = 0;
   NumOperands = 3+NumArgs;
   Use *OL = OperandList = new Use[3+NumArgs];
   OL[0].init(Fn, this);
@@ -483,8 +414,7 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
 
 InvokeInst::InvokeInst(const InvokeInst &II)
   : TerminatorInst(II.getType(), Instruction::Invoke,
-                   new Use[II.getNumOperands()], II.getNumOperands()),
-    ParamAttrs(0) {
+                   new Use[II.getNumOperands()], II.getNumOperands()) {
   setParamAttrs(II.getParamAttrs());
   SubclassData = II.SubclassData;
   Use *OL = OperandList, *InOL = II.OperandList;
@@ -502,70 +432,23 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   return setSuccessor(idx, B);
 }
 
-void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) {
-  if (ParamAttrs == newAttrs)
-    return;
-
-  if (ParamAttrs)
-    ParamAttrs->dropRef();
-
-  if (newAttrs)
-    newAttrs->addRef();
-
-  ParamAttrs = newAttrs; 
-}
-
-bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
-  if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr))
+bool InvokeInst::paramHasAttr(unsigned i, ParameterAttributes attr) const {
+  if (ParamAttrs.paramHasAttr(i, attr))
     return true;
   if (const Function *F = getCalledFunction())
     return F->paramHasAttr(i, attr);
   return false;
 }
 
-uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
-  if (ParamAttrs && ParamAttrs->getParamAlignment(i))
-    return ParamAttrs->getParamAlignment(i);
-  if (const Function *F = getCalledFunction())
-    return F->getParamAlignment(i);
-  return 0;
-}
-
-/// @brief Determine if the call does not access memory.
-bool InvokeInst::doesNotAccessMemory() const {
-  return paramHasAttr(0, ParamAttr::ReadNone);
-}
-
-/// @brief Determine if the call does not access or only reads memory.
-bool InvokeInst::onlyReadsMemory() const {
-  return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
-}
-
-/// @brief Determine if the call cannot return.
-bool InvokeInst::doesNotReturn() const {
-  return paramHasAttr(0, ParamAttr::NoReturn);
-}
-
-/// @brief Determine if the call cannot unwind.
-bool InvokeInst::doesNotThrow() const {
-  return paramHasAttr(0, ParamAttr::NoUnwind);
-}
-
 void InvokeInst::setDoesNotThrow(bool doesNotThrow) {
-  const ParamAttrsList *PAL = getParamAttrs();
+  PAListPtr PAL = getParamAttrs();
   if (doesNotThrow)
-    PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.addAttr(0, ParamAttr::NoUnwind);
   else
-    PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind);
+    PAL = PAL.removeAttr(0, ParamAttr::NoUnwind);
   setParamAttrs(PAL);
 }
 
-/// @brief Determine if the call returns a structure.
-bool InvokeInst::isStructReturn() const {
-  // Be friendly and also check the callee.
-  return paramHasAttr(1, ParamAttr::StructRet);
-}
-
 
 //===----------------------------------------------------------------------===//
 //                        ReturnInst Implementation
@@ -794,8 +677,8 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
                                unsigned Align, const std::string &Name,
                                Instruction *InsertBefore)
   : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertBefore), Alignment(Align) {
-  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+                     InsertBefore) {
+  setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
 }
@@ -804,8 +687,8 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
                                unsigned Align, const std::string &Name,
                                BasicBlock *InsertAtEnd)
   : UnaryInstruction(PointerType::getUnqual(Ty), iTy, getAISize(ArraySize),
-                     InsertAtEnd), Alignment(Align) {
-  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+                     InsertAtEnd) {
+  setAlignment(Align);
   assert(Ty != Type::VoidTy && "Cannot allocate void!");
   setName(Name);
 }
@@ -814,6 +697,12 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
 AllocationInst::~AllocationInst() {
 }
 
+void AllocationInst::setAlignment(unsigned Align) {
+  assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+  SubclassData = Log2_32(Align) + 1;
+  assert(getAlignment() == Align && "Alignment representation error!");
+}
+
 bool AllocationInst::isArrayAllocation() const {
   if (ConstantInt *CI = dyn_cast<ConstantInt>(getOperand(0)))
     return CI->getZExtValue() != 1;
@@ -2821,7 +2710,7 @@ bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
 // unit that uses these classes.
 
 GetElementPtrInst *GetElementPtrInst::clone() const {
-  return new GetElementPtrInst(*this);
+  return new(getNumOperands()) GetElementPtrInst(*this);
 }
 
 BinaryOperator *BinaryOperator::clone() const {
@@ -2852,24 +2741,24 @@ CastInst   *FPToSIInst::clone()   const { return new FPToSIInst(*this); }
 CastInst   *PtrToIntInst::clone() const { return new PtrToIntInst(*this); }
 CastInst   *IntToPtrInst::clone() const { return new IntToPtrInst(*this); }
 CastInst   *BitCastInst::clone()  const { return new BitCastInst(*this); }
-CallInst   *CallInst::clone()     const { return new CallInst(*this); }
-SelectInst *SelectInst::clone()   const { return new SelectInst(*this); }
+CallInst   *CallInst::clone()     const { return new(getNumOperands()) CallInst(*this); }
+SelectInst *SelectInst::clone()   const { return new(getNumOperands()) SelectInst(*this); }
 VAArgInst  *VAArgInst::clone()    const { return new VAArgInst(*this); }
 
 ExtractElementInst *ExtractElementInst::clone() const {
   return new ExtractElementInst(*this);
 }
 InsertElementInst *InsertElementInst::clone() const {
-  return new InsertElementInst(*this);
+  return InsertElementInst::Create(*this);
 }
 ShuffleVectorInst *ShuffleVectorInst::clone() const {
   return new ShuffleVectorInst(*this);
 }
 PHINode    *PHINode::clone()    const { return new PHINode(*this); }
-ReturnInst *ReturnInst::clone() const { return new ReturnInst(*this); }
-BranchInst *BranchInst::clone() const { return new BranchInst(*this); }
-SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
-InvokeInst *InvokeInst::clone() const { return new InvokeInst(*this); }
+ReturnInst *ReturnInst::clone() const { return new(getNumOperands()) ReturnInst(*this); }
+BranchInst *BranchInst::clone() const { return new(getNumOperands()) BranchInst(*this); }
+SwitchInst *SwitchInst::clone() const { return new(getNumOperands()) SwitchInst(*this); }
+InvokeInst *InvokeInst::clone() const { return new(getNumOperands()) InvokeInst(*this); }
 UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
 UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
 GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }