Clean up TargetOpcodes.h a bit, and limit the number of places where the full
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 2 Jul 2010 21:44:22 +0000 (21:44 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 2 Jul 2010 21:44:22 +0000 (21:44 +0000)
list of predefined instructions appear. Add some consistency checks.

Ideally, TargetOpcodes.h should be produced by TableGen from Target.td, but it
is hardly worth the effort.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107520 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
include/llvm/Target/TargetOpcodes.h
utils/TableGen/CodeEmitterGen.cpp
utils/TableGen/CodeGenTarget.cpp

index 1d1e1f86130c2340d4dccf70ee782374a41f9e50..51a501ed207a50bd9cf339ca3b23bd6296b78416 100644 (file)
@@ -396,24 +396,23 @@ class InstrInfo {
 }
 
 // Standard Pseudo Instructions.
-let isCodeGenOnly = 1 in {
+// This list must match TargetOpcodes.h and CodeGenTarget.cpp.
+// Only these instructions are allowed in the TargetOpcode namespace.
+let isCodeGenOnly = 1, Namespace = "TargetOpcode" in {
 def PHI : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins variable_ops);
   let AsmString = "PHINODE";
-  let Namespace = "TargetOpcode";
 }
 def INLINEASM : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins variable_ops);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
 }
 def DBG_LABEL : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins i32imm:$id);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let hasCtrlDep = 1;
   let isNotDuplicable = 1;
 }
@@ -421,7 +420,6 @@ def EH_LABEL : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins i32imm:$id);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let hasCtrlDep = 1;
   let isNotDuplicable = 1;
 }
@@ -429,7 +427,6 @@ def GC_LABEL : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins i32imm:$id);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let hasCtrlDep = 1;
   let isNotDuplicable = 1;
 }
@@ -437,21 +434,18 @@ def KILL : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins variable_ops);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
 }
 def EXTRACT_SUBREG : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins unknown:$supersrc, i32imm:$subidx);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
 }
 def INSERT_SUBREG : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins unknown:$supersrc, unknown:$subsrc, i32imm:$subidx);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
   let Constraints = "$supersrc = $dst";
 }
@@ -459,7 +453,6 @@ def IMPLICIT_DEF : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
   let isReMaterializable = 1;
   let isAsCheapAsAMove = 1;
@@ -468,14 +461,12 @@ def SUBREG_TO_REG : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins unknown:$implsrc, unknown:$subsrc, i32imm:$subidx);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
 }
 def COPY_TO_REGCLASS : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins unknown:$src, i32imm:$regclass);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
   let isAsCheapAsAMove = 1;
 }
@@ -483,7 +474,6 @@ def DBG_VALUE : Instruction {
   let OutOperandList = (outs);
   let InOperandList = (ins variable_ops);
   let AsmString = "DBG_VALUE";
-  let Namespace = "TargetOpcode";
   let isAsCheapAsAMove = 1;
 }
 
@@ -491,7 +481,6 @@ def REG_SEQUENCE : Instruction {
   let OutOperandList = (outs unknown:$dst);
   let InOperandList = (ins variable_ops);
   let AsmString = "";
-  let Namespace = "TargetOpcode";
   let neverHasSideEffects = 1;
   let isAsCheapAsAMove = 1;
 }
index 808645ef54d9f091699b873066871ed0fbc953b8..55e93eccc3cbc3018f9ff59ded3f314027eafe66 100644 (file)
 #define LLVM_TARGET_TARGETOPCODES_H
 
 namespace llvm {
-  
+
 /// Invariant opcodes: All instruction sets have these as their low opcodes.
+///
+/// Every instruction defined here must also appear in Target.td and the order
+/// must be the same as in CodeGenTarget.cpp.
+///
 namespace TargetOpcode {
-  enum { 
+  enum {
     PHI = 0,
     INLINEASM = 1,
     DBG_LABEL = 2,
     EH_LABEL = 3,
     GC_LABEL = 4,
-    
+
     /// KILL - This instruction is a noop that is used only to adjust the
     /// liveness of registers. This can be useful when dealing with
     /// sub-registers.
     KILL = 5,
-    
+
     /// EXTRACT_SUBREG - This instruction takes two operands: a register
     /// that has subregisters, and a subregister index. It returns the
     /// extracted subregister value. This is commonly used to implement
     /// truncation operations on target architectures which support it.
     EXTRACT_SUBREG = 6,
-    
+
     /// INSERT_SUBREG - This instruction takes three operands: a register that
     /// has subregisters, a register providing an insert value, and a
     /// subregister index. It returns the value of the first register with the
@@ -43,16 +47,16 @@ namespace TargetOpcode {
     /// defined by an IMPLICIT_DEF, because it is commonly used to implement
     /// anyext operations on target architectures which support it.
     INSERT_SUBREG = 7,
-    
+
     /// IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
     IMPLICIT_DEF = 8,
-    
+
     /// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that
     /// the first operand is an immediate integer constant. This constant is
     /// often zero, because it is commonly used to assert that the instruction
     /// defining the register implicitly clears the high bits.
     SUBREG_TO_REG = 9,
-    
+
     /// COPY_TO_REGCLASS - This instruction is a placeholder for a plain
     /// register-to-register copy into a specific register class. This is only
     /// used between instruction selection and MachineInstr creation, before
index 2a2a4ef63e16600c3818e2bc89e35470dab417d1..ec702c2a5d9cab0915744757ed7f0c112dd1c3fb 100644 (file)
@@ -24,19 +24,8 @@ void CodeEmitterGen::reverseBits(std::vector<Record*> &Insts) {
   for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
        I != E; ++I) {
     Record *R = *I;
-    if (R->getName() == "PHI" ||
-        R->getName() == "INLINEASM" ||
-        R->getName() == "DBG_LABEL" ||
-        R->getName() == "EH_LABEL" ||
-        R->getName() == "GC_LABEL" ||
-        R->getName() == "KILL" ||
-        R->getName() == "EXTRACT_SUBREG" ||
-        R->getName() == "INSERT_SUBREG" ||
-        R->getName() == "IMPLICIT_DEF" ||
-        R->getName() == "SUBREG_TO_REG" ||
-        R->getName() == "COPY_TO_REGCLASS" ||
-        R->getName() == "DBG_VALUE" ||
-        R->getName() == "REG_SEQUENCE") continue;
+    if (R->getValueAsString("Namespace") == "TargetOpcode")
+      continue;
 
     BitsInit *BI = R->getValueAsBitsInit("Inst");
 
@@ -103,19 +92,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
     const CodeGenInstruction *CGI = *IN;
     Record *R = CGI->TheDef;
     
-    if (R->getName() == "PHI" ||
-        R->getName() == "INLINEASM" ||
-        R->getName() == "DBG_LABEL" ||
-        R->getName() == "EH_LABEL" ||
-        R->getName() == "GC_LABEL" ||
-        R->getName() == "KILL" ||
-        R->getName() == "EXTRACT_SUBREG" ||
-        R->getName() == "INSERT_SUBREG" ||
-        R->getName() == "IMPLICIT_DEF" ||
-        R->getName() == "SUBREG_TO_REG" ||
-        R->getName() == "COPY_TO_REGCLASS" ||
-        R->getName() == "DBG_VALUE" ||
-        R->getName() == "REG_SEQUENCE") {
+    if (R->getValueAsString("Namespace") == "TargetOpcode") {
       o << "    0U,\n";
       continue;
     }
@@ -140,22 +117,10 @@ void CodeEmitterGen::run(raw_ostream &o) {
   for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
         IC != EC; ++IC) {
     Record *R = *IC;
+    if (R->getValueAsString("Namespace") == "TargetOpcode")
+      continue;
     const std::string &InstName = R->getName();
     std::string Case("");
-    
-    if (InstName == "PHI" ||
-        InstName == "INLINEASM" ||
-        InstName == "DBG_LABEL"||
-        InstName == "EH_LABEL"||
-        InstName == "GC_LABEL"||
-        InstName == "KILL"||
-        InstName == "EXTRACT_SUBREG" ||
-        InstName == "INSERT_SUBREG" ||
-        InstName == "IMPLICIT_DEF" ||
-        InstName == "SUBREG_TO_REG" ||
-        InstName == "COPY_TO_REGCLASS" ||
-        InstName == "DBG_VALUE" ||
-        InstName == "REG_SEQUENCE") continue;
 
     BitsInit *BI = R->getValueAsBitsInit("Inst");
     const std::vector<RecordVal> &Vals = R->getValues();
index 3797992d9d3f2ac73421bf013a1604eb07777d8b..72cea14ea6bf2cf238efa6864f2b04bd44767cb6 100644 (file)
@@ -329,61 +329,41 @@ 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",
+    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);
-  const CodeGenInstruction *REG_SEQUENCE = GetInstByName("REG_SEQUENCE", 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);
-  InstrsByEnum.push_back(REG_SEQUENCE);
-  
+  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 &&
-        CGI != REG_SEQUENCE)
+    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(),