Fix a regression in test/CodeGen/X86/2007-04-24-VectorCrash.ll introduced
[oota-llvm.git] / lib / VMCore / Function.cpp
index e47798e12cd277b0dcb264f046209896ff20babc..3582b321504f1e19ef94639817116d3195d6c5b7 100644 (file)
@@ -15,7 +15,9 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/ParameterAttributes.h"
 #include "llvm/IntrinsicInst.h"
+#include "llvm/CodeGen/ValueTypes.h"
 #include "llvm/Support/LeakDetector.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "SymbolTableListTraitsImpl.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace llvm;
@@ -89,49 +91,57 @@ std::string
 ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
   std::string Result;
   if (Attrs & ParamAttr::ZExt)
-    Result += "zext ";
+    Result += "zeroext ";
   if (Attrs & ParamAttr::SExt)
-    Result += "sext ";
+    Result += "signext ";
   if (Attrs & ParamAttr::NoReturn)
     Result += "noreturn ";
   if (Attrs & ParamAttr::NoUnwind)
     Result += "nounwind ";
   if (Attrs & ParamAttr::InReg)
     Result += "inreg ";
+  if (Attrs & ParamAttr::NoAlias)
+    Result += "noalias ";
   if (Attrs & ParamAttr::StructRet)
     Result += "sret ";  
+  if (Attrs & ParamAttr::ByVal)
+    Result += "byval ";
+  if (Attrs & ParamAttr::Nest)
+    Result += "nest ";
   return Result;
 }
 
-void
-ParamAttrsList::addAttributes(uint16_t Index, uint16_t Attrs) {
-  // First, try to replace an existing one
-  for (unsigned i = 0; i < attrs.size(); ++i)
-    if (attrs[i].index == Index) {
-      attrs[i].attrs |= Attrs;
-      return;
-    }
-
-  // If not found, add a new one
-  ParamAttrsWithIndex Val;
-  Val.attrs = Attrs;
-  Val.index = Index;
-  attrs.push_back(Val);
+void 
+ParamAttrsList::Profile(FoldingSetNodeID &ID) const {
+  for (unsigned i = 0; i < attrs.size(); ++i) {
+    unsigned val = attrs[i].attrs << 16 | attrs[i].index;
+    ID.AddInteger(val);
+  }
 }
 
-void
-ParamAttrsList::removeAttributes(uint16_t Index, uint16_t Attrs) {
-  // Find the index from which to remove the attributes
-  for (unsigned i = 0; i < attrs.size(); ++i)
-    if (attrs[i].index == Index) {
-      attrs[i].attrs &= ~Attrs;
-      if (attrs[i].attrs == ParamAttr::None)
-        attrs.erase(&attrs[i]);
-      return;
-    }
+static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
+
+ParamAttrsList *
+ParamAttrsList::get(const ParamAttrsVector &attrVec) {
+  assert(!attrVec.empty() && "Illegal to create empty ParamAttrsList");
+#ifndef NDEBUG
+  for (unsigned i = 1, e = attrVec.size(); i < e; ++i)
+    assert(attrVec[i-1].index < attrVec[i].index && "Misordered ParamAttrsList!");
+#endif
+  ParamAttrsList key(attrVec);
+  FoldingSetNodeID ID;
+  key.Profile(ID);
+  void *InsertPos;
+  ParamAttrsList* PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
+  if (!PAL) {
+    PAL = new ParamAttrsList(attrVec);
+    ParamAttrsLists->InsertNode(PAL, InsertPos);
+  }
+  return PAL;
+}
 
-  // The index wasn't found above
-  assert(0 && "Index not found for removeAttributes");
+ParamAttrsList::~ParamAttrsList() {
+  ParamAttrsLists->RemoveNode(this);
 }
 
 //===----------------------------------------------------------------------===//
@@ -142,19 +152,15 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
                    const std::string &name, Module *ParentModule)
   : GlobalValue(PointerType::get(Ty), Value::FunctionVal, 0, 0, Linkage, name) {
   ParamAttrs = 0;
-  CallingConvention = 0;
   SymTab = new ValueSymbolTable();
 
   assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy)
          && "LLVM functions cannot return aggregate values!");
 
-  // Create the arguments vector, all arguments start out unnamed.
-  for (unsigned i = 0, e = Ty->getNumParams(); i != e; ++i) {
-    assert(Ty->getParamType(i) != Type::VoidTy &&
-           "Cannot have void typed arguments!");
-    ArgumentList.push_back(new Argument(Ty->getParamType(i)));
-  }
-
+  // If the function has arguments, mark them as lazily built.
+  if (Ty->getNumParams())
+    SubclassData = 1;   // Set the "has lazy arguments" bit.
+  
   // Make sure that we get added to a function
   LeakDetector::addGarbageObject(this);
 
@@ -168,6 +174,30 @@ Function::~Function() {
   // Delete all of the method arguments and unlink from symbol table...
   ArgumentList.clear();
   delete SymTab;
+
+  // Drop our reference to the parameter attributes, if any.
+  if (ParamAttrs)
+    ParamAttrs->dropRef();
+}
+
+void Function::BuildLazyArguments() const {
+  // Create the arguments vector, all arguments start out unnamed.
+  const FunctionType *FT = getFunctionType();
+  for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+    assert(FT->getParamType(i) != Type::VoidTy &&
+           "Cannot have void typed arguments!");
+    ArgumentList.push_back(new Argument(FT->getParamType(i)));
+  }
+  
+  // Clear the lazy arguments bit.
+  const_cast<Function*>(this)->SubclassData &= ~1;
+}
+
+size_t Function::arg_size() const {
+  return getFunctionType()->getNumParams();
+}
+bool Function::arg_empty() const {
+  return getFunctionType()->getNumParams() == 0;
 }
 
 void Function::setParent(Module *parent) {
@@ -178,6 +208,16 @@ void Function::setParent(Module *parent) {
     LeakDetector::removeGarbageObject(this);
 }
 
+void Function::setParamAttrs(ParamAttrsList *attrs) { 
+  if (ParamAttrs)
+    ParamAttrs->dropRef();
+
+  if (attrs)
+    attrs->addRef();
+
+  ParamAttrs = attrs; 
+}
+
 const FunctionType *Function::getFunctionType() const {
   return cast<FunctionType>(getType()->getElementType());
 }
@@ -252,12 +292,12 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) {
   std::string Result(Table[id]);
   for (unsigned i = 0; i < numTys; ++i) 
     if (Tys[i])
-      Result += "." + Tys[i]->getDescription();
+      Result += "." + MVT::getValueTypeString(MVT::getValueType(Tys[i]));
   return Result;
 }
 
 const FunctionType *Intrinsic::getType(ID id, const Type **Tys, 
-                                       uint32_t numTys) {
+                                       unsigned numTys) {
   const Type *ResultTy = NULL;
   std::vector<const Type*> ArgTys;
   bool IsVarArg = false;
@@ -295,11 +335,8 @@ Value *IntrinsicInst::StripPointerCasts(Value *Ptr) {
     if (isa<PointerType>(CI->getOperand(0)->getType()))
       return StripPointerCasts(CI->getOperand(0));
   } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Ptr)) {
-    for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
-      if (!isa<Constant>(GEP->getOperand(i)) ||
-          !cast<Constant>(GEP->getOperand(i))->isNullValue())
-        return Ptr;
-    return StripPointerCasts(GEP->getOperand(0));
+    if (GEP->hasAllZeroIndices())
+      return StripPointerCasts(GEP->getOperand(0));
   }
   return Ptr;
 }