From 74ae9256197c794c58c3e659b1d690cf0b958aa4 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Thu, 1 Dec 2016 19:38:50 +0000 Subject: [PATCH] [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 --- test/TableGen/DuplicateFieldValues.td | 84 +++++++++++++++++++++++++++ utils/TableGen/CodeGenMapTable.cpp | 1 + 2 files changed, 85 insertions(+) create mode 100644 test/TableGen/DuplicateFieldValues.td diff --git a/test/TableGen/DuplicateFieldValues.td b/test/TableGen/DuplicateFieldValues.td new file mode 100644 index 000000000000..50c77fa88cce --- /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 527f530da479..8032d7b3ee95 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; } } }