Revert 107840 107839 107813 107804 107800 107797 107791.
[oota-llvm.git] / utils / TableGen / CodeGenTarget.cpp
index a0c2c21287179dedc74faf366fea348ccf2eb605..d8130fb36ddecd606df78002c6c2d4539271c2c0 100644 (file)
@@ -18,6 +18,7 @@
 #include "CodeGenIntrinsics.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include <algorithm>
 using namespace llvm;
@@ -79,6 +80,7 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
   case MVT::v1i64: return "MVT::v1i64";
   case MVT::v2i64: return "MVT::v2i64";
   case MVT::v4i64: return "MVT::v4i64";
+  case MVT::v8i64: return "MVT::v8i64";
   case MVT::v2f32: return "MVT::v2f32";
   case MVT::v4f32: return "MVT::v4f32";
   case MVT::v8f32: return "MVT::v8f32";
@@ -157,6 +159,7 @@ void CodeGenTarget::ReadRegisters() const {
   std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
   if (Regs.empty())
     throw std::string("No 'Register' subclasses defined!");
+  std::sort(Regs.begin(), Regs.end(), LessRecord());
 
   Registers.reserve(Regs.size());
   Registers.assign(Regs.begin(), Regs.end());
@@ -171,6 +174,11 @@ const std::string &CodeGenRegister::getName() const {
   return TheDef->getName();
 }
 
+void CodeGenTarget::ReadSubRegIndices() const {
+  SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex");
+  std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord());
+}
+
 void CodeGenTarget::ReadRegisterClasses() const {
   std::vector<Record*> RegClasses =
     Records.getAllDerivedDefinitions("RegisterClass");
@@ -194,6 +202,10 @@ getRegisterVTs(Record *R) const {
       }
     }
   }
+  
+  // Remove duplicates.
+  array_pod_sort(Result.begin(), Result.end());
+  Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
   return Result;
 }
 
@@ -223,17 +235,30 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
             "' does not derive from the Register class!";
     Elements.push_back(Reg);
   }
-  
-  std::vector<Record*> SubRegClassList = 
-                        R->getValueAsListOfDefs("SubRegClassList");
-  for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) {
-    Record *SubRegClass = SubRegClassList[i];
-    if (!SubRegClass->isSubClassOf("RegisterClass"))
-      throw "Register Class member '" + SubRegClass->getName() +
-            "' does not derive from the RegisterClass class!";
-    SubRegClasses.push_back(SubRegClass);
-  }  
-  
+
+  // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
+  ListInit *SRC = R->getValueAsListInit("SubRegClasses");
+  for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
+    DagInit *DAG = dynamic_cast<DagInit*>(*i);
+    if (!DAG) throw "SubRegClasses must contain DAGs";
+    DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
+    Record *RCRec;
+    if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
+      throw "Operator '" + DAG->getOperator()->getAsString() +
+        "' in SubRegClasses is not a RegisterClass";
+    // Iterate over args, all SubRegIndex instances.
+    for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
+         ai != ae; ++ai) {
+      DefInit *Idx = dynamic_cast<DefInit*>(*ai);
+      Record *IdxRec;
+      if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
+        throw "Argument '" + (*ai)->getAsString() +
+          "' in SubRegClasses is not a SubRegIndex";
+      if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
+        throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
+    }
+  }
+
   // Allow targets to override the size in bits of the RegisterClass.
   unsigned Size = R->getValueAsInt("Size");
 
@@ -304,58 +329,42 @@ struct SortInstByName {
 /// getInstructionsByEnumValue - Return all of the instructions defined by the
 /// target, ordered by their enum value.
 void CodeGenTarget::ComputeInstrsByEnum() const {
+  // The ordering here must match the ordering in TargetOpcodes.h.
+  const char *const FixedInstrs[] = {
+    "PHI",
+    "INLINEASM",
+    "DBG_LABEL",
+    "EH_LABEL",
+    "GC_LABEL",
+    "KILL",
+    "EXTRACT_SUBREG",
+    "INSERT_SUBREG",
+    "IMPLICIT_DEF",
+    "SUBREG_TO_REG",
+    "COPY_TO_REGCLASS",
+    "DBG_VALUE",
+    "REG_SEQUENCE",
+    "COPY",
+    0
+  };
   const DenseMap<const Record*, CodeGenInstruction*> &Insts = getInstructions();
-  const CodeGenInstruction *PHI = GetInstByName("PHI", Insts);
-  const CodeGenInstruction *INLINEASM = GetInstByName("INLINEASM", Insts);
-  const CodeGenInstruction *DBG_LABEL = GetInstByName("DBG_LABEL", Insts);
-  const CodeGenInstruction *EH_LABEL = GetInstByName("EH_LABEL", Insts);
-  const CodeGenInstruction *GC_LABEL = GetInstByName("GC_LABEL", Insts);
-  const CodeGenInstruction *KILL = GetInstByName("KILL", Insts);
-  const CodeGenInstruction *EXTRACT_SUBREG =
-    GetInstByName("EXTRACT_SUBREG", Insts);
-  const CodeGenInstruction *INSERT_SUBREG =
-    GetInstByName("INSERT_SUBREG", Insts);
-  const CodeGenInstruction *IMPLICIT_DEF = GetInstByName("IMPLICIT_DEF", Insts);
-  const CodeGenInstruction *SUBREG_TO_REG =
-    GetInstByName("SUBREG_TO_REG", Insts);
-  const CodeGenInstruction *COPY_TO_REGCLASS =
-    GetInstByName("COPY_TO_REGCLASS", Insts);
-  const CodeGenInstruction *DBG_VALUE = GetInstByName("DBG_VALUE", Insts);
-
-  // Print out the rest of the instructions now.
-  InstrsByEnum.push_back(PHI);
-  InstrsByEnum.push_back(INLINEASM);
-  InstrsByEnum.push_back(DBG_LABEL);
-  InstrsByEnum.push_back(EH_LABEL);
-  InstrsByEnum.push_back(GC_LABEL);
-  InstrsByEnum.push_back(KILL);
-  InstrsByEnum.push_back(EXTRACT_SUBREG);
-  InstrsByEnum.push_back(INSERT_SUBREG);
-  InstrsByEnum.push_back(IMPLICIT_DEF);
-  InstrsByEnum.push_back(SUBREG_TO_REG);
-  InstrsByEnum.push_back(COPY_TO_REGCLASS);
-  InstrsByEnum.push_back(DBG_VALUE);
-  
+  for (const char *const *p = FixedInstrs; *p; ++p) {
+    const CodeGenInstruction *Instr = GetInstByName(*p, Insts);
+    assert(Instr && "Missing target independent instruction");
+    assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
+    InstrsByEnum.push_back(Instr);
+  }
   unsigned EndOfPredefines = InstrsByEnum.size();
-  
+
   for (DenseMap<const Record*, CodeGenInstruction*>::const_iterator
        I = Insts.begin(), E = Insts.end(); I != E; ++I) {
     const CodeGenInstruction *CGI = I->second;
-    if (CGI != PHI &&
-        CGI != INLINEASM &&
-        CGI != DBG_LABEL &&
-        CGI != EH_LABEL &&
-        CGI != GC_LABEL &&
-        CGI != KILL &&
-        CGI != EXTRACT_SUBREG &&
-        CGI != INSERT_SUBREG &&
-        CGI != IMPLICIT_DEF &&
-        CGI != SUBREG_TO_REG &&
-        CGI != COPY_TO_REGCLASS &&
-        CGI != DBG_VALUE)
+    if (CGI->Namespace != "TargetOpcode")
       InstrsByEnum.push_back(CGI);
   }
-  
+
+  assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
+
   // All of the instructions are now in random order based on the map iteration.
   // Sort them by name.
   std::sort(InstrsByEnum.begin()+EndOfPredefines, InstrsByEnum.end(),
@@ -395,6 +404,8 @@ ComplexPattern::ComplexPattern(Record *R) {
       Properties |= 1 << SDNPSideEffect;
     } else if (PropList[i]->getName() == "SDNPMemOperand") {
       Properties |= 1 << SDNPMemOperand;
+    } else if (PropList[i]->getName() == "SDNPVariadic") {
+      Properties |= 1 << SDNPVariadic;
     } else {
       errs() << "Unsupported SD Node property '" << PropList[i]->getName()
              << "' on ComplexPattern '" << R->getName() << "'!\n";
@@ -486,15 +497,17 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
     }
     if (EVT(VT).isOverloaded()) {
       OverloadedVTs.push_back(VT);
-      isOverloaded |= true;
+      isOverloaded = true;
     }
+
+    // Reject invalid types.
+    if (VT == MVT::isVoid)
+      throw "Intrinsic '" + DefName + " has void in result type list!";
+    
     IS.RetVTs.push_back(VT);
     IS.RetTypeDefs.push_back(TyEl);
   }
-
-  if (IS.RetVTs.size() == 0)
-    throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";
-
+  
   // Parse the list of parameter types.
   TypeList = R->getValueAsListInit("ParamTypes");
   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
@@ -515,10 +528,16 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
              "Expected iAny or vAny type");
     } else
       VT = getValueType(TyEl->getValueAsDef("VT"));
+    
     if (EVT(VT).isOverloaded()) {
       OverloadedVTs.push_back(VT);
-      isOverloaded |= true;
+      isOverloaded = true;
     }
+    
+    // Reject invalid types.
+    if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
+      throw "Intrinsic '" + DefName + " has void in result type list!";
+    
     IS.ParamVTs.push_back(VT);
     IS.ParamTypeDefs.push_back(TyEl);
   }