]> granicus.if.org Git - llvm/commitdiff
[tablegen] Delete duplicates from a vector without skipping elements
authorVedant Kumar <vsk@apple.com>
Thu, 1 Dec 2016 19:38:50 +0000 (19:38 +0000)
committerVedant Kumar <vsk@apple.com>
Thu, 1 Dec 2016 19:38:50 +0000 (19:38 +0000)
Tablegen's -gen-instr-info pass has a bug in its emitEnums() routine.
The function intends for values in a vector to be deduplicated, but it
accidentally skips over elements after performing a deletion.

I think there are smarter ways of doing this deduplication, but we can
do that in a follow-up commit if there's interest. See the thread:
[PATCH] TableGen InstrMapping Bug fix.

Patch by Tyler Kenney!

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

test/TableGen/DuplicateFieldValues.td [new file with mode: 0644]
utils/TableGen/CodeGenMapTable.cpp

diff --git a/test/TableGen/DuplicateFieldValues.td b/test/TableGen/DuplicateFieldValues.td
new file mode 100644 (file)
index 0000000..50c77fa
--- /dev/null
@@ -0,0 +1,84 @@
+// RUN: llvm-tblgen -gen-instr-info -I %p/../../include %s | FileCheck %s
+
+// CHECK: ABCForm_A
+// CHECK-NOT: ABCForm_A
+
+//
+// include Target.td for InstrMapping class and define minimally required objects
+//
+
+include "llvm/Target/Target.td"
+
+class DFVReg<string n> : Register<n> {
+  let Namespace = "DFV";
+}
+
+def R0 : DFVReg<"r0">;
+def DFVRegClass : RegisterClass<"DFV",[i32],0,(add R0)>;
+def DFVInstrInfo : InstrInfo;
+
+def DFVTest : Target {
+  let InstructionSet = DFVInstrInfo;
+}
+
+//
+// Define a number of a InstrMappings with repeated ValueCol fields
+//
+
+class ABCRel;
+
+def getAFormFromBForm : InstrMapping {
+  let FilterClass = "ABCRel";
+  let RowFields = ["BaseName"];
+  let ColFields = ["ABCForm"];
+  let KeyCol = ["B"];
+  let ValueCols = [["A"]];
+}
+
+def getAFormFromCForm : InstrMapping {
+  let FilterClass = "ABCRel";
+  let RowFields = ["BaseName"];
+  let ColFields = ["ABCForm"];
+  let KeyCol = ["C"];
+  let ValueCols = [["A"]];
+}
+
+def getAFormFromDForm : InstrMapping {
+  let FilterClass = "ABCRel";
+  let RowFields = ["BaseName"];
+  let ColFields = ["ABCForm"];
+  let KeyCol = ["D"];
+  let ValueCols = [["A"]];
+}
+
+def getAFormFromEForm : InstrMapping {
+  let FilterClass = "ABCRel";
+  let RowFields = ["BaseName"];
+  let ColFields = ["ABCForm"];
+  let KeyCol = ["E"];
+  let ValueCols = [["A"]];
+}
+
+class I : Instruction {
+  let Namespace = "DFV";
+  let OutOperandList = (outs);
+  let InOperandList = (ins);
+
+  string BaseName = "";
+  string ABCForm = "";
+}
+
+class isAForm { string ABCForm = "A"; }
+class isBForm { string ABCForm = "B"; }
+class isCForm { string ABCForm = "C"; }
+class isDForm { string ABCForm = "D"; }
+class isEForm { string ABCForm = "E"; }
+
+let BaseName = "0" in {
+  def A0 : I, ABCRel, isAForm;
+  def B0 : I, ABCRel, isBForm;
+  def C0 : I, ABCRel, isCForm;
+  def D0 : I, ABCRel, isDForm;
+  def E0 : I, ABCRel, isEForm;
+}
+
index 527f530da479a1881cffe12df733f1daf9ef3df1..8032d7b3ee95af897ceceb6ab9c2083915c26880 100644 (file)
@@ -542,6 +542,7 @@ static void emitEnums(raw_ostream &OS, RecordKeeper &Records) {
       for (unsigned j = i+1; j < FieldValues.size(); j++) {
         if (CurVal == FieldValues[j]) {
           FieldValues.erase(FieldValues.begin()+j);
+          --j;
         }
       }
     }