[llvm-commits] [llvm] r119129 - in /llvm/trunk/utils/TableGen: CodeEmitterGen.cpp CodeEmitterGen.h

Chris Lattner sabre at nondot.org
Sun Nov 14 22:59:17 PST 2010


Author: lattner
Date: Mon Nov 15 00:59:17 2010
New Revision: 119129

URL: http://llvm.org/viewvc/llvm-project?rev=119129&view=rev
Log:
split the giant encoder loop into two new helper functions.

Modified:
    llvm/trunk/utils/TableGen/CodeEmitterGen.cpp
    llvm/trunk/utils/TableGen/CodeEmitterGen.h

Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.cpp?rev=119129&r1=119128&r2=119129&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeEmitterGen.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeEmitterGen.cpp Mon Nov 15 00:59:17 2010
@@ -61,7 +61,7 @@
 // If the VarBitInit at position 'bit' matches the specified variable then
 // return the variable bit position.  Otherwise return -1.
 int CodeEmitterGen::getVariableBit(const std::string &VarName,
-            BitsInit *BI, int bit) {
+                                   BitsInit *BI, int bit) {
   if (VarBitInit *VBI = dynamic_cast<VarBitInit*>(BI->getBit(bit)))
     if (VarInit *VI = dynamic_cast<VarInit*>(VBI->getVariable()))
       if (VI->getName() == VarName)
@@ -70,6 +70,123 @@
   return -1;
 }
 
+void CodeEmitterGen::
+AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
+                        unsigned &NumberedOp,
+                        std::string &Case, CodeGenTarget &Target) {
+  bool gotOp = false;
+  CodeGenInstruction &CGI = Target.getInstruction(R);
+
+  for (int bit = BI->getNumBits()-1; bit >= 0; ) {
+    int varBit = getVariableBit(VarName, BI, bit);
+    
+    // If this bit isn't from a variable, skip it.
+    if (varBit == -1) {
+      --bit;
+      continue;
+    }
+    
+    // Figure out the consequtive range of bits covered by this operand, in
+    // order to generate better encoding code.
+    int beginInstBit = bit;
+    int beginVarBit = varBit;
+    int N = 1;
+    for (--bit; bit >= 0;) {
+      varBit = getVariableBit(VarName, BI, bit);
+      if (varBit == -1 || varBit != (beginVarBit - N)) break;
+      ++N;
+      --bit;
+    }
+    
+    if (!gotOp) {
+      // If the operand matches by name, reference according to that
+      // operand number. Non-matching operands are assumed to be in
+      // order.
+      unsigned OpIdx;
+      if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
+        // Get the machine operand number for the indicated operand.
+        OpIdx = CGI.Operands[OpIdx].MIOperandNo;
+        assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
+               "Explicitly used operand also marked as not emitted!");
+      } else {
+        /// If this operand is not supposed to be emitted by the
+        /// generated emitter, skip it.
+        while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
+          ++NumberedOp;
+        OpIdx = NumberedOp++;
+      }
+      std::pair<unsigned, unsigned> SO =CGI.Operands.getSubOperandNumber(OpIdx);
+      std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
+      
+      // If the source operand has a custom encoder, use it. This will
+      // get the encoding for all of the suboperands.
+      if (!EncoderMethodName.empty()) {
+        // A custom encoder has all of the information for the
+        // sub-operands, if there are more than one, so only
+        // query the encoder once per source operand.
+        if (SO.second == 0) {
+          Case += "      // op: " + VarName + "\n"
+          + "      op = " + EncoderMethodName + "(MI, "
+          + utostr(OpIdx);
+          if (MCEmitter)
+            Case += ", Fixups";
+          Case += ");\n";
+        }
+      } else {
+        Case += "      // op: " + VarName + "\n" +
+                "      op = getMachineOpValue(MI, MI.getOperand(" +
+                utostr(OpIdx) + ")";
+        if (MCEmitter)
+          Case += ", Fixups";
+        Case += ");\n";
+      }
+      gotOp = true;
+    }
+    
+    unsigned opMask = ~0U >> (32-N);
+    int opShift = beginVarBit - N + 1;
+    opMask <<= opShift;
+    opShift = beginInstBit - beginVarBit;
+    
+    if (opShift > 0) {
+      Case += "      Value |= (op & " + utostr(opMask) + "U) << " +
+              itostr(opShift) + ";\n";
+    } else if (opShift < 0) {
+      Case += "      Value |= (op & " + utostr(opMask) + "U) >> " + 
+              itostr(-opShift) + ";\n";
+    } else {
+      Case += "      Value |= op & " + utostr(opMask) + "U;\n";
+    }
+  }
+}
+
+
+std::string CodeEmitterGen::getInstructionCase(Record *R,
+                                               CodeGenTarget &Target) {
+  std::string Case;
+  
+  BitsInit *BI = R->getValueAsBitsInit("Inst");
+  const std::vector<RecordVal> &Vals = R->getValues();
+  unsigned NumberedOp = 0;
+
+  // Loop over all of the fields in the instruction, determining which are the
+  // operands to the instruction.
+  for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+    // Ignore fixed fields in the record, we're looking for values like:
+    //    bits<5> RST = { ?, ?, ?, ?, ? };
+    if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
+      continue;
+    
+    AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp, Case, Target);
+  }
+  
+  std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
+  if (!PostEmitter.empty())
+    Case += "      Value = " + PostEmitter + "(MI, Value);\n";
+  
+  return Case;
+}
+
 void CodeEmitterGen::run(raw_ostream &o) {
   CodeGenTarget Target;
   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
@@ -107,12 +224,11 @@
 
     BitsInit *BI = R->getValueAsBitsInit("Inst");
 
-    // Start by filling in fixed values...
+    // Start by filling in fixed values.
     unsigned Value = 0;
     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
-      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
+      if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1)))
         Value |= B->getValue() << (e-i-1);
-      }
     }
     o << "    " << Value << "U," << '\t' << "// " << R->getName() << "\n";
   }
@@ -128,115 +244,9 @@
     if (R->getValueAsString("Namespace") == "TargetOpcode")
       continue;
     const std::string &InstName = R->getName();
-    std::string Case("");
-
-    BitsInit *BI = R->getValueAsBitsInit("Inst");
-    const std::vector<RecordVal> &Vals = R->getValues();
-    CodeGenInstruction &CGI = Target.getInstruction(R);
-
-    // Loop over all of the fields in the instruction, determining which are the
-    // operands to the instruction.
-    unsigned NumberedOp = 0;
-    for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
-      // Ignore fixed fields.
-      if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
-        continue;
-      
-      // Is the operand continuous? If so, we can just mask and OR it in
-      // instead of doing it bit-by-bit, saving a lot in runtime cost.
-      const std::string &VarName = Vals[i].getName();
-      bool gotOp = false;
-
-      for (int bit = BI->getNumBits()-1; bit >= 0; ) {
-        int varBit = getVariableBit(VarName, BI, bit);
-
-        // If this bit isn't from a variable, skip it.
-        if (varBit == -1) {
-          --bit;
-          continue;
-        }
-
-        int beginInstBit = bit;
-        int beginVarBit = varBit;
-        int N = 1;
-
-        for (--bit; bit >= 0;) {
-          varBit = getVariableBit(VarName, BI, bit);
-          if (varBit == -1 || varBit != (beginVarBit - N)) break;
-          ++N;
-          --bit;
-        }
-
-        if (!gotOp) {
-          // If the operand matches by name, reference according to that
-          // operand number. Non-matching operands are assumed to be in
-          // order.
-          unsigned OpIdx;
-          if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
-            // Get the machine operand number for the indicated operand.
-            OpIdx = CGI.Operands[OpIdx].MIOperandNo;
-            assert (!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
-                    "Explicitly used operand also marked as not emitted!");
-          } else {
-            /// If this operand is not supposed to be emitted by the
-            /// generated emitter, skip it.
-            while (CGI.Operands.isFlatOperandNotEmitted(NumberedOp))
-              ++NumberedOp;
-            OpIdx = NumberedOp++;
-          }
-          std::pair<unsigned, unsigned> SO =
-            CGI.Operands.getSubOperandNumber(OpIdx);
-          std::string &EncoderMethodName =
-            CGI.Operands[SO.first].EncoderMethodName;
-
-          // If the source operand has a custom encoder, use it. This will
-          // get the encoding for all of the suboperands.
-          if (!EncoderMethodName.empty()) {
-            // A custom encoder has all of the information for the
-            // sub-operands, if there are more than one, so only
-            // query the encoder once per source operand.
-            if (SO.second == 0) {
-              Case += "      // op: " + VarName + "\n"
-                   + "      op = " + EncoderMethodName + "(MI, "
-                   + utostr(OpIdx);
-              if (MCEmitter)
-                Case += ", Fixups";
-              Case += ");\n";
-            }
-          } else {
-            Case += "      // op: " + VarName + "\n"
-                 +  "      op = getMachineOpValue(MI, MI.getOperand("
-                 +  utostr(OpIdx) + ")";
-            if (MCEmitter)
-              Case += ", Fixups";
-            Case += ");\n";
-          }
-          gotOp = true;
-        }
-
-        unsigned opMask = ~0U >> (32-N);
-        int opShift = beginVarBit - N + 1;
-        opMask <<= opShift;
-        opShift = beginInstBit - beginVarBit;
-
-        if (opShift > 0) {
-          Case += "      Value |= (op & " + utostr(opMask) + "U) << "
-               +  itostr(opShift) + ";\n";
-        } else if (opShift < 0) {
-          Case += "      Value |= (op & " + utostr(opMask) + "U) >> "
-               +  itostr(-opShift) + ";\n";
-        } else {
-          Case += "      Value |= op & " + utostr(opMask) + "U;\n";
-        }
-      }
-    }
-
-    std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
-    if (!PostEmitter.empty())
-      Case += "      Value = " + PostEmitter + "(MI, Value);\n";
+    std::string Case = getInstructionCase(R, Target);
 
-    std::vector<std::string> &InstList = CaseMap[Case];
-    InstList.push_back(InstName);
+    CaseMap[Case].push_back(InstName);
   }
 
   // Emit initial function code

Modified: llvm/trunk/utils/TableGen/CodeEmitterGen.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeEmitterGen.h?rev=119129&r1=119128&r2=119129&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeEmitterGen.h (original)
+++ llvm/trunk/utils/TableGen/CodeEmitterGen.h Mon Nov 15 00:59:17 2010
@@ -23,6 +23,7 @@
 
 class RecordVal;
 class BitsInit;
+class CodeGenTarget;
 
 class CodeEmitterGen : public TableGenBackend {
   RecordKeeper &Records;
@@ -36,6 +37,12 @@
   void emitGetValueBit(raw_ostream &o, const std::string &Namespace);
   void reverseBits(std::vector<Record*> &Insts);
   int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
+  std::string getInstructionCase(Record *R, CodeGenTarget &Target);
+  void
+  AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
+                          unsigned &NumberedOp,
+                          std::string &Case, CodeGenTarget &Target);
+    
 };
 
 } // End llvm namespace





More information about the llvm-commits mailing list