From: Vedant Kumar Date: Thu, 1 Dec 2016 19:38:50 +0000 (+0000) Subject: [tablegen] Delete duplicates from a vector without skipping elements X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=74ae9256197c794c58c3e659b1d690cf0b958aa4;p=llvm [tablegen] Delete duplicates from a vector without skipping elements 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 --- diff --git a/test/TableGen/DuplicateFieldValues.td b/test/TableGen/DuplicateFieldValues.td new file mode 100644 index 00000000000..50c77fa88cc --- /dev/null +++ b/test/TableGen/DuplicateFieldValues.td @@ -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 : Register { + 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; +} + diff --git a/utils/TableGen/CodeGenMapTable.cpp b/utils/TableGen/CodeGenMapTable.cpp index 527f530da47..8032d7b3ee9 100644 --- a/utils/TableGen/CodeGenMapTable.cpp +++ b/utils/TableGen/CodeGenMapTable.cpp @@ -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; } } }