Fix the conditions under which SCCP should examine insertvalue
[oota-llvm.git] / lib / AsmParser / llvmAsmParser.y
index 8f9c4529fe34048fae94680f9d05adae65a8b21f..ea3aef3a0bceb7c0ad132f1e505b65eed73d9ca8 100644 (file)
@@ -963,6 +963,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
   llvm::PATypeHolder                     *TypeVal;
   llvm::Value                            *ValueVal;
   std::vector<llvm::Value*>              *ValueList;
+  std::vector<unsigned>                  *ConstantList;
   llvm::ArgListType                      *ArgList;
   llvm::TypeWithAttrs                     TypeWithAttrs;
   llvm::TypeWithAttrsList                *TypeWithAttrsList;
@@ -1008,6 +1009,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
 %type <PHIList>       PHIList
 %type <ParamList>     ParamList      // For call param lists & GEP indices
 %type <ValueList>     IndexList         // For GEP indices
+%type <ConstantList>  ConstantIndexList // For insertvalue/extractvalue indices
 %type <TypeList>      TypeListI 
 %type <TypeWithAttrsList> ArgTypeList ArgTypeListI
 %type <TypeWithAttrs> ArgType
@@ -1974,46 +1976,20 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
     $$ = ConstantExpr::getShuffleVector($3, $5, $7);
     CHECK_FOR_ERROR
   }
-  | EXTRACTVALUE '(' ConstVal IndexList ')' {
+  | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' {
     if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
       GEN_ERROR("ExtractValue requires an aggregate operand");
 
-    const Type *IdxTy =
-      ExtractValueInst::getIndexedType($3->getType(), $4->begin(), $4->end());
-    if (!IdxTy)
-      GEN_ERROR("Index list invalid for constant extractvalue");
-
-    SmallVector<Constant*, 8> IdxVec;
-    for (unsigned i = 0, e = $4->size(); i != e; ++i)
-      if (Constant *C = dyn_cast<Constant>((*$4)[i]))
-        IdxVec.push_back(C);
-      else
-        GEN_ERROR("Indices to constant extractvalue must be constants");
-
+    $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size());
     delete $4;
-
-    $$ = ConstantExpr::getExtractValue($3, &IdxVec[0], IdxVec.size());
     CHECK_FOR_ERROR
   }
-  | INSERTVALUE '(' ConstVal ',' ConstVal IndexList ')' {
+  | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' {
     if (!isa<StructType>($3->getType()) && !isa<ArrayType>($3->getType()))
       GEN_ERROR("InsertValue requires an aggregate operand");
 
-    const Type *IdxTy =
-      ExtractValueInst::getIndexedType($3->getType(), $6->begin(), $6->end());
-    if (IdxTy != $5->getType())
-      GEN_ERROR("Index list invalid for constant insertvalue");
-
-    SmallVector<Constant*, 8> IdxVec;
-    for (unsigned i = 0, e = $6->size(); i != e; ++i)
-      if (Constant *C = dyn_cast<Constant>((*$6)[i]))
-        IdxVec.push_back(C);
-      else
-        GEN_ERROR("Indices to constant insertvalue must be constants");
-
+    $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size());
     delete $6;
-
-    $$ = ConstantExpr::getInsertValue($3, $5, &IdxVec[0], IdxVec.size());
     CHECK_FOR_ERROR
   };
 
@@ -2509,13 +2485,7 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
       GEN_ERROR("Invalid vector element type: " + ETy->getDescription());
     
     VectorType* pt = VectorType::get(ETy, NumElements);
-    PATypeHolder* PTy = new PATypeHolder(
-                                         HandleUpRefs(
-                                            VectorType::get(
-                                                ETy, 
-                                                NumElements)
-                                            )
-                                         );
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt));
     
     // Verify all elements are correct type!
     for (unsigned i = 0; i < $2->size(); i++) {
@@ -2529,6 +2499,80 @@ ConstValueRef : ESINT64VAL {    // A reference to a direct constant
     delete PTy; delete $2;
     CHECK_FOR_ERROR
   }
+  | '[' ConstVector ']' { // Nonempty unsized arr
+    const Type *ETy = (*$2)[0]->getType();
+    int NumElements = $2->size(); 
+
+    if (!ETy->isFirstClassType())
+      GEN_ERROR("Invalid array element type: " + ETy->getDescription());
+
+    ArrayType *ATy = ArrayType::get(ETy, NumElements);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy));
+
+    // Verify all elements are correct type!
+    for (unsigned i = 0; i < $2->size(); i++) {
+      if (ETy != (*$2)[i]->getType())
+        GEN_ERROR("Element #" + utostr(i) + " is not of type '" + 
+                       ETy->getDescription() +"' as required!\nIt is of type '"+
+                       (*$2)[i]->getType()->getDescription() + "'.");
+    }
+
+    $$ = ValID::create(ConstantArray::get(ATy, *$2));
+    delete PTy; delete $2;
+    CHECK_FOR_ERROR
+  }
+  | '[' ']' {
+    $$ = ValID::createUndef();
+    CHECK_FOR_ERROR
+  }
+  | 'c' STRINGCONSTANT {
+    int NumElements = $2->length();
+    const Type *ETy = Type::Int8Ty;
+
+    ArrayType *ATy = ArrayType::get(ETy, NumElements);
+
+    std::vector<Constant*> Vals;
+    for (unsigned i = 0; i < $2->length(); ++i)
+      Vals.push_back(ConstantInt::get(ETy, (*$2)[i]));
+    delete $2;
+    $$ = ValID::create(ConstantArray::get(ATy, Vals));
+    CHECK_FOR_ERROR
+  }
+  | '{' ConstVector '}' {
+    std::vector<const Type*> Elements($2->size());
+    for (unsigned i = 0, e = $2->size(); i != e; ++i)
+      Elements[i] = (*$2)[i]->getType();
+
+    const StructType *STy = StructType::get(Elements);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+    $$ = ValID::create(ConstantStruct::get(STy, *$2));
+    delete PTy; delete $2;
+    CHECK_FOR_ERROR
+  }
+  | '{' '}' {
+    const StructType *STy = StructType::get(std::vector<const Type*>());
+    $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+    CHECK_FOR_ERROR
+  }
+  | '<' '{' ConstVector '}' '>' {
+    std::vector<const Type*> Elements($3->size());
+    for (unsigned i = 0, e = $3->size(); i != e; ++i)
+      Elements[i] = (*$3)[i]->getType();
+
+    const StructType *STy = StructType::get(Elements, /*isPacked=*/true);
+    PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy));
+
+    $$ = ValID::create(ConstantStruct::get(STy, *$3));
+    delete PTy; delete $3;
+    CHECK_FOR_ERROR
+  }
+  | '<' '{' '}' '>' {
+    const StructType *STy = StructType::get(std::vector<const Type*>(),
+                                            /*isPacked=*/true);
+    $$ = ValID::create(ConstantStruct::get(STy, std::vector<Constant*>()));
+    CHECK_FOR_ERROR
+  }
   | ConstExpr {
     $$ = ValID::create($1);
     CHECK_FOR_ERROR
@@ -2885,6 +2929,22 @@ IndexList       // Used for gep instructions and constant expressions
   }
   ;
 
+ConstantIndexList       // Used for insertvalue and extractvalue instructions
+  : ',' EUINT64VAL {
+    $$ = new std::vector<unsigned>();
+    if ((unsigned)$2 != $2)
+      GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue.");
+    $$->push_back($2);
+  }
+  | ConstantIndexList ',' EUINT64VAL {
+    $$ = $1;
+    if ((unsigned)$3 != $3)
+      GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue.");
+    $$->push_back($3);
+    CHECK_FOR_ERROR
+  }
+  ;
+
 OptTailCall : TAIL CALL {
     $$ = true;
     CHECK_FOR_ERROR
@@ -3245,7 +3305,7 @@ MemoryInst : MALLOC Types OptCAlign {
     delete $2; 
     delete $4;
   }
-  | EXTRACTVALUE Types ValueRef IndexList {
+  | EXTRACTVALUE Types ValueRef ConstantIndexList {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
@@ -3260,7 +3320,7 @@ MemoryInst : MALLOC Types OptCAlign {
     delete $2; 
     delete $4;
   }
-  | INSERTVALUE Types ValueRef ',' Types ValueRef IndexList {
+  | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList {
     if (!UpRefs.empty())
       GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
     if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))