From a443e5b1f1013612950fc3c9ebfafca60a1c20df Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Fri, 23 Mar 2012 05:50:46 +0000 Subject: Remove the C backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153307 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/GenLibDeps.pl | 2 -- utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp | 2 +- utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'utils') diff --git a/utils/GenLibDeps.pl b/utils/GenLibDeps.pl index 0cd9e6a..656250c 100755 --- a/utils/GenLibDeps.pl +++ b/utils/GenLibDeps.pl @@ -96,7 +96,6 @@ if ($PEROBJ) { $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/; $libpath =~ s/^BitReader/Bitcode\/Reader/; $libpath =~ s/^BitWriter/Bitcode\/Writer/; - $libpath =~ s/^CBackend/Target\/CBackend/; $libpath =~ s/^CppBackend/Target\/CppBackend/; $libpath =~ s/^MSIL/Target\/MSIL/; $libpath =~ s/^Core/VMCore/; @@ -138,7 +137,6 @@ if ($PEROBJ) { $libpath =~ s/^AsmPrinter/CodeGen\/AsmPrinter/; $libpath =~ s/^BitReader/Bitcode\/Reader/; $libpath =~ s/^BitWriter/Bitcode\/Writer/; - $libpath =~ s/^CBackend/Target\/CBackend/; $libpath =~ s/^CppBackend/Target\/CppBackend/; $libpath =~ s/^MSIL/Target\/MSIL/; $libpath =~ s/^Core/VMCore/; diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp index 0cbfc4b..4bc58d7 100644 --- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp +++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp @@ -2,7 +2,7 @@ # Do not edit here. If you wish to override these values # edit the last section set target_triplet "x86_64-apple-darwin10" -set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend" +set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin MSIL CppBackend" set srcroot "/Volumes/Data/ddunbar/llvm" set objroot "/Volumes/Data/ddunbar/llvm.obj.64" set srcdir "/Volumes/Data/ddunbar/llvm/test" diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp index 0cbfc4b..4bc58d7 100644 --- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp +++ b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp @@ -2,7 +2,7 @@ # Do not edit here. If you wish to override these values # edit the last section set target_triplet "x86_64-apple-darwin10" -set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin CBackend MSIL CppBackend" +set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips CellSPU PIC16 XCore MSP430 Blackfin MSIL CppBackend" set srcroot "/Volumes/Data/ddunbar/llvm" set objroot "/Volumes/Data/ddunbar/llvm.obj.64" set srcdir "/Volumes/Data/ddunbar/llvm/test" -- cgit v1.1 From 901b85888c2de6bf982c47ab69b7e83908b6a216 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 23 Mar 2012 11:35:30 +0000 Subject: Include cstdio in a few place that depended on getting it transitively through StringExtras.h git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153328 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 3 ++- utils/TableGen/InstrInfoEmitter.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 3280e09..d2ddf23 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -19,8 +19,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include #include +#include +#include using namespace llvm; //===----------------------------------------------------------------------===// diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 0d27828..9a07970 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -18,6 +18,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include +#include using namespace llvm; static void PrintDefList(const std::vector &Uses, -- cgit v1.1 From cc85160672e3b2d5ec363cc4e151e5b944a60454 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sun, 25 Mar 2012 09:02:19 +0000 Subject: Continue cleanup of LIT, getting rid of the remaining artifacts from dejagnu * Removed test/lib/llvm.exp - it is no longer needed * Deleted the dg.exp reading code from test/lit.cfg. There are no dg.exp files left in the test suite so this code is no longer required. test/lit.cfg is now much shorter and clearer * Removed a lot of duplicate code in lit.local.cfg files that need access to the root configuration, by adding a "root" attribute to the TestingConfig object. This attribute is dynamically computed to provide the same information as was previously provided by the custom getRoot functions. * Documented the config.root attribute in docs/CommandGuide/lit.pod git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153408 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lit/lit/TestingConfig.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'utils') diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py index 78bf268..e4980b3 100644 --- a/utils/lit/lit/TestingConfig.py +++ b/utils/lit/lit/TestingConfig.py @@ -114,3 +114,9 @@ class TestingConfig: # files. Should we distinguish them? self.test_source_root = str(self.test_source_root) self.excludes = set(self.excludes) + + @property + def root(self): + """root attribute - The root configuration for the test suite.""" + return self if self.parent is None else self.parent.root + -- cgit v1.1 From 0417d7dca09b0beb7f27045b0ab9e93096905c74 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sun, 25 Mar 2012 09:42:28 +0000 Subject: Fix lit failure on cmake-clang-x64_64-linux bot, apparently due to its having a very (*very*) old version of Python (2.4?) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153409 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/lit/lit/TestingConfig.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py index e4980b3..223120c 100644 --- a/utils/lit/lit/TestingConfig.py +++ b/utils/lit/lit/TestingConfig.py @@ -118,5 +118,8 @@ class TestingConfig: @property def root(self): """root attribute - The root configuration for the test suite.""" - return self if self.parent is None else self.parent.root + if self.parent is None: + return self + else: + return self.parent.root -- cgit v1.1 From 72e84f51a68fac35074133b4dcc4b152d77f2636 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Mon, 26 Mar 2012 11:08:03 +0000 Subject: TableGen: Don't emit the llvm intrinsic -> gcc builtin table, its only user was the c backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153432 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/IntrinsicEmitter.cpp | 19 ------------------- utils/TableGen/IntrinsicEmitter.h | 2 -- 2 files changed, 21 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 578b3aa..39ece32 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -57,9 +57,6 @@ void IntrinsicEmitter::run(raw_ostream &OS) { // Emit intrinsic alias analysis mod/ref behavior. EmitModRefBehavior(Ints, OS); - // Emit a list of intrinsics with corresponding GCC builtins. - EmitGCCBuiltinList(Ints, OS); - // Emit code to translate GCC builtins into LLVM intrinsics. EmitIntrinsicToGCCBuiltinMap(Ints, OS); @@ -653,22 +650,6 @@ EmitModRefBehavior(const std::vector &Ints, raw_ostream &OS){ << "#endif // GET_INTRINSIC_MODREF_BEHAVIOR\n\n"; } -void IntrinsicEmitter:: -EmitGCCBuiltinList(const std::vector &Ints, raw_ostream &OS){ - OS << "// Get the GCC builtin that corresponds to an LLVM intrinsic.\n"; - OS << "#ifdef GET_GCC_BUILTIN_NAME\n"; - OS << " switch (F->getIntrinsicID()) {\n"; - OS << " default: BuiltinName = \"\"; break;\n"; - for (unsigned i = 0, e = Ints.size(); i != e; ++i) { - if (!Ints[i].GCCBuiltinName.empty()) { - OS << " case Intrinsic::" << Ints[i].EnumName << ": BuiltinName = \"" - << Ints[i].GCCBuiltinName << "\"; break;\n"; - } - } - OS << " }\n"; - OS << "#endif\n\n"; -} - /// EmitTargetBuiltins - All of the builtins in the specified map are for the /// same target, and we already checked it. static void EmitTargetBuiltins(const std::map &BIM, diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h index eb6379c..f9bcd59 100644 --- a/utils/TableGen/IntrinsicEmitter.h +++ b/utils/TableGen/IntrinsicEmitter.h @@ -48,8 +48,6 @@ namespace llvm { raw_ostream &OS); void EmitModRefBehavior(const std::vector &Ints, raw_ostream &OS); - void EmitGCCBuiltinList(const std::vector &Ints, - raw_ostream &OS); void EmitIntrinsicToGCCBuiltinMap(const std::vector &Ints, raw_ostream &OS); void EmitSuffix(raw_ostream &OS); -- cgit v1.1 From ef18cd381cb8513a53baba2b0062159323b13056 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Mar 2012 19:11:51 +0000 Subject: fix a failure path to print the right thing, part of PR12357 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153457 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/DAGISelMatcherGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index 49ad956..2ac7b87 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -217,7 +217,7 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode *N) { DefInit *DI = dynamic_cast(N->getLeafValue()); if (DI == 0) { - errs() << "Unknown leaf kind: " << *DI << "\n"; + errs() << "Unknown leaf kind: " << *N << "\n"; abort(); } -- cgit v1.1 From 5b2f9136644c58ae32e00d8317540692a697d1c9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 28 Mar 2012 21:20:32 +0000 Subject: Spill DPair registers, not just QPR. The arm_neon intrinsics can create virtual registers from the DPair register class which allows both even-odd and odd-even D-register pairs. This fixes PR12389. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153603 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/EDEmitter.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'utils') diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 1b473d3..3eed07c 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -569,6 +569,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, REG("DPR"); REG("DPR_VFP2"); REG("DPR_8"); + REG("DPair"); REG("SPR"); REG("QPR"); REG("QQPR"); -- cgit v1.1 From c6a96ff6aeeb77e1007364e5603b72f3ab4cc7bd Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 29 Mar 2012 18:03:59 +0000 Subject: Add more constness to CodeGenRegisters. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153667 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 6 +++--- utils/TableGen/CodeGenRegisters.h | 4 ++-- utils/TableGen/RegisterInfoEmitter.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 9c61f3f..d86ca7a 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -231,7 +231,7 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { } void -CodeGenRegister::addSubRegsPreOrder(SetVector &OSet, +CodeGenRegister::addSubRegsPreOrder(SetVector &OSet, CodeGenRegBank &RegBank) const { assert(SubRegsComplete && "Must precompute sub-registers"); std::vector Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); @@ -1095,7 +1095,7 @@ CodeGenRegBank::getRegClassForRegister(Record *R) { } BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef Regs) { - SetVector Set; + SetVector Set; // First add Regs with all sub-registers. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { @@ -1110,7 +1110,7 @@ BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef Regs) { for (unsigned i = 0; i != Set.size(); ++i) { const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs(); for (unsigned j = 0, e = SR.size(); j != e; ++j) { - CodeGenRegister *Super = SR[j]; + const CodeGenRegister *Super = SR[j]; if (!Super->CoveredBySubRegs || Set.count(Super)) continue; // This new super-register is covered by its sub-registers. diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index beaa678..f5372c0 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -110,11 +110,11 @@ namespace llvm { } // Add sub-registers to OSet following a pre-order defined by the .td file. - void addSubRegsPreOrder(SetVector &OSet, + void addSubRegsPreOrder(SetVector &OSet, CodeGenRegBank&) const; // List of super-registers in topological order, small to large. - typedef std::vector SuperRegList; + typedef std::vector SuperRegList; // Get the list of super-registers. // This is only valid after computeDerivedInfo has visited all registers. diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 2380e23..f082cfa 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -306,7 +306,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, if (Reg.getSubRegs().empty()) continue; // getSubRegs() orders by SubRegIndex. We want a topological order. - SetVector SR; + SetVector SR; Reg.addSubRegsPreOrder(SR, RegBank); OS << " /* " << Reg.getName() << "_SubRegsSet */ "; for (unsigned j = 0, je = SR.size(); j != je; ++j) @@ -351,7 +351,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "/* " << Reg->getName() << "_SubRegsSet */ " << SubRegIndex << ", "; // FIXME not very nice to recalculate this - SetVector SR; + SetVector SR; Reg->addSubRegsPreOrder(SR, RegBank); SubRegIndex += SR.size() + 1; } else -- cgit v1.1 From 184440e8085379f8c3749f04dcffee8d9f16f435 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Mar 2012 17:25:40 +0000 Subject: Add a SequenceToOffsetTable to TableGen. This is similar to the StringToOffsetTable we use to produce string tables, but it can be used for other sequences than strings, and it eliminates entries for suffixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153760 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/SequenceToOffsetTable.h | 123 +++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 utils/TableGen/SequenceToOffsetTable.h (limited to 'utils') diff --git a/utils/TableGen/SequenceToOffsetTable.h b/utils/TableGen/SequenceToOffsetTable.h new file mode 100644 index 0000000..26e7058 --- /dev/null +++ b/utils/TableGen/SequenceToOffsetTable.h @@ -0,0 +1,123 @@ +//===-- SequenceToOffsetTable.h - Compress similar sequences ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// SequenceToOffsetTable can be used to emit a number of null-terminated +// sequences as one big array. Use the same memory when a sequence is a suffix +// of another. +// +//===----------------------------------------------------------------------===// + +#ifndef TBLGEN_SEQUENCE_TO_OFFSET_TABLE_H +#define TBLGEN_SEQUENCE_TO_OFFSET_TABLE_H + +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include + +namespace llvm { + +/// SequenceToOffsetTable - Collect a number of terminated sequences of T. +/// Compute the layout of a table that contains all the sequences, possibly by +/// reusing entries. +/// +/// @param SeqT The sequence container. (vector or string). +/// @param Less A stable comparator for SeqT elements. +template > +class SequenceToOffsetTable { + typedef typename SeqT::value_type ElemT; + + // Define a comparator for SeqT that sorts a suffix immediately before a + // sequence with that suffix. + struct SeqLess : public std::binary_function { + Less L; + bool operator()(const SeqT &A, const SeqT &B) const { + return std::lexicographical_compare(A.rbegin(), A.rend(), + B.rbegin(), B.rend(), L); + } + }; + + // Keep sequences ordered according to SeqLess so suffixes are easy to find. + // Map each sequence to its offset in the table. + typedef std::map SeqMap; + + // Sequences added so far, with suffixes removed. + SeqMap Seqs; + + // Entries in the final table, or 0 before layout was called. + unsigned Entries; + + // isSuffix - Returns true if A is a suffix of B. + static bool isSuffix(const SeqT &A, const SeqT &B) { + return A.size() <= B.size() && std::equal(A.rbegin(), A.rend(), B.rbegin()); + } + +public: + SequenceToOffsetTable() : Entries(0) {} + + /// add - Add a sequence to the table. + /// This must be called before layout(). + void add(const SeqT &Seq) { + assert(Entries == 0 && "Cannot call add() after layout()"); + typename SeqMap::iterator I = Seqs.lower_bound(Seq); + + // If SeqMap contains a sequence that has Seq as a suffix, I will be + // pointing to it. + if (I != Seqs.end() && isSuffix(Seq, I->first)) + return; + + I = Seqs.insert(I, std::make_pair(Seq, 0u)); + + // The entry before I may be a suffix of Seq that can now be erased. + if (I != Seqs.begin() && isSuffix((--I)->first, Seq)) + Seqs.erase(I); + } + + /// layout - Computes the final table layout. + void layout() { + assert(Entries == 0 && "Can only call layout() once"); + // Lay out the table in Seqs iteration order. + for (typename SeqMap::iterator I = Seqs.begin(), E = Seqs.end(); I != E; + ++I) { + I->second = Entries; + // Include space for a terminator. + Entries += I->first.size() + 1; + } + } + + /// get - Returns the offset of Seq in the final table. + unsigned get(const SeqT &Seq) const { + assert(Entries && "Call layout() before get()"); + typename SeqMap::const_iterator I = Seqs.lower_bound(Seq); + assert(I != Seqs.end() && isSuffix(Seq, I->first) && + "get() called with sequence that wasn't added first"); + return I->second + (I->first.size() - Seq.size()); + } + + /// emit - Print out the table as the body of an array initializer. + /// Use the Print function to print elements. + void emit(raw_ostream &OS, void (*Print)(raw_ostream&, ElemT)) const { + assert(Entries && "Call layout() before emit()"); + for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); + I != E; ++I) { + OS << " /* " << I->second << " */ "; + for (typename SeqT::const_iterator SI = I->first.begin(), + SE = I->first.end(); SI != SE; ++SI) { + Print(OS, *SI); + OS << ", "; + } + OS << "0,\n"; + } + } +}; + +} // end namespace llvm + +#endif -- cgit v1.1 From 8f36b0b139b5ba683eedf022f1b0c1279b680cf7 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Mar 2012 17:25:43 +0000 Subject: Compress register lists by sharing suffixes. TableGen emits lists of sub-registers, super-registers, and overlaps. Put them all in a single table and use a SequenceToOffsetTable to share suffixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153761 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 143 ++++++++++++++------------------- 1 file changed, 62 insertions(+), 81 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index f082cfa..f1719b8 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -16,6 +16,7 @@ #include "RegisterInfoEmitter.h" #include "CodeGenTarget.h" #include "CodeGenRegisters.h" +#include "SequenceToOffsetTable.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" @@ -259,6 +260,10 @@ public: } }; +static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) { + OS << getQualifiedName(Reg->TheDef); +} + // // runMCDesc - Print out MC register descriptions. // @@ -270,98 +275,78 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; OS << "#undef GET_REGINFO_MC_DESC\n"; + const std::vector &Regs = RegBank.getRegisters(); std::map Overlaps; RegBank.computeOverlaps(Overlaps); - OS << "namespace llvm {\n\n"; - - const std::string &TargetName = Target.getName(); - - const std::vector &Regs = RegBank.getRegisters(); - - OS << "extern const uint16_t " << TargetName << "RegOverlaps[] = {\n"; + // The lists of sub-registers, super-registers, and overlaps all go in the + // same array. That allows us to share suffixes. + typedef std::vector RegVec; + SmallVector SubRegLists(Regs.size()); + SmallVector OverlapLists(Regs.size()); + SequenceToOffsetTable RegSeqs; - // Emit an overlap list for all registers. + // Precompute register lists for the SequenceToOffsetTable. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; - const CodeGenRegister::Set &O = Overlaps[Reg]; - // Move Reg to the front so TRI::getAliasSet can share the list. - OS << " /* " << Reg->getName() << "_Overlaps */ " - << getQualifiedName(Reg->TheDef) << ", "; - for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end(); - I != E; ++I) - if (*I != Reg) - OS << getQualifiedName((*I)->TheDef) << ", "; - OS << "0,\n"; - } - OS << "};\n\n"; - OS << "extern const uint16_t " << TargetName << "SubRegsSet[] = {\n"; - // Emit the empty sub-registers list - OS << " /* Empty_SubRegsSet */ 0,\n"; - // Loop over all of the registers which have sub-registers, emitting the - // sub-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - if (Reg.getSubRegs().empty()) - continue; - // getSubRegs() orders by SubRegIndex. We want a topological order. + // Compute the ordered sub-register list. SetVector SR; - Reg.addSubRegsPreOrder(SR, RegBank); - OS << " /* " << Reg.getName() << "_SubRegsSet */ "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0,\n"; + Reg->addSubRegsPreOrder(SR, RegBank); + RegVec &SubRegList = SubRegLists[i]; + SubRegList.assign(SR.begin(), SR.end()); + RegSeqs.add(SubRegList); + + // Super-registers are already computed. + const RegVec &SuperRegList = Reg->getSuperRegs(); + RegSeqs.add(SuperRegList); + + // The list of overlaps doesn't need to have any particular order, except + // Reg itself must be the first element. Pick an ordering that has one of + // the other lists as a suffix. + RegVec &OverlapList = OverlapLists[i]; + const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ? + SubRegList : SuperRegList; + CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end()); + + // First element is Reg itself. + OverlapList.push_back(Reg); + Omit.insert(Reg); + + // Any elements not in Suffix. + const CodeGenRegister::Set &OSet = Overlaps[Reg]; + std::set_difference(OSet.begin(), OSet.end(), + Omit.begin(), Omit.end(), + std::back_inserter(OverlapList)); + + // Finally, Suffix itself. + OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end()); + RegSeqs.add(OverlapList); } - OS << "};\n\n"; - OS << "extern const uint16_t " << TargetName << "SuperRegsSet[] = {\n"; - // Emit the empty super-registers list - OS << " /* Empty_SuperRegsSet */ 0,\n"; - // Loop over all of the registers which have super-registers, emitting the - // super-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs(); - if (SR.empty()) - continue; - OS << " /* " << Reg.getName() << "_SuperRegsSet */ "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0,\n"; - } + // Compute the final layout of the sequence table. + RegSeqs.layout(); + + OS << "namespace llvm {\n\n"; + + const std::string &TargetName = Target.getName(); + + // Emit the shared table of register lists. + OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n"; + RegSeqs.emit(OS, printRegister); OS << "};\n\n"; OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; OS << " { \"NOREG\", 0, 0, 0 },\n"; - // Now that register alias and sub-registers sets have been emitted, emit the - // register descriptors now. - unsigned OverlapsIndex = 0; - unsigned SubRegIndex = 1; // skip 1 for empty set - unsigned SuperRegIndex = 1; // skip 1 for empty set + // Emit the register descriptors now. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; - OS << " { \""; - OS << Reg->getName() << "\", /* " << Reg->getName() << "_Overlaps */ " - << OverlapsIndex << ", "; - OverlapsIndex += Overlaps[Reg].size() + 1; - if (!Reg->getSubRegs().empty()) { - OS << "/* " << Reg->getName() << "_SubRegsSet */ " << SubRegIndex - << ", "; - // FIXME not very nice to recalculate this - SetVector SR; - Reg->addSubRegsPreOrder(SR, RegBank); - SubRegIndex += SR.size() + 1; - } else - OS << "/* Empty_SubRegsSet */ 0, "; - if (!Reg->getSuperRegs().empty()) { - OS << "/* " << Reg->getName() << "_SuperRegsSet */ " << SuperRegIndex; - SuperRegIndex += Reg->getSuperRegs().size() + 1; - } else - OS << "/* Empty_SuperRegsSet */ 0"; - OS << " },\n"; + OS << " { \"" << Reg->getName() << "\", " + << RegSeqs.get(OverlapLists[i]) << ", " + << RegSeqs.get(SubRegLists[i]) << ", " + << RegSeqs.get(Reg->getSuperRegs()) << " },\n"; } OS << "};\n\n"; // End of register descriptors... @@ -464,8 +449,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " - << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet, "; + << RegisterClasses.size() << ", " << TargetName << "RegLists, "; if (SubRegIndices.size() != 0) OS << "(uint16_t*)" << TargetName << "SubRegTable, " << SubRegIndices.size() << ");\n\n"; @@ -889,9 +873,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; - OS << "extern const uint16_t " << TargetName << "RegOverlaps[];\n"; - OS << "extern const uint16_t " << TargetName << "SubRegsSet[];\n"; - OS << "extern const uint16_t " << TargetName << "SuperRegsSet[];\n"; + OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; if (SubRegIndices.size() != 0) OS << "extern const uint16_t *get" << TargetName << "SubRegTable();\n"; @@ -904,8 +886,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" - << " " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet,\n" + << " " << TargetName << "RegLists,\n" << " "; if (SubRegIndices.size() != 0) OS << "get" << TargetName << "SubRegTable(), " -- cgit v1.1 From ecf2d9fc0d5ea162571b0e229f47b22e84c93eaa Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Mar 2012 17:42:04 +0000 Subject: Compress SimpleValueType lists by sharing. Many register classes have the same value types. Share the table space. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153764 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 33 +++++++++++++-------------------- utils/TableGen/SequenceToOffsetTable.h | 6 ++++-- 2 files changed, 17 insertions(+), 22 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index f1719b8..b43203d 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -264,6 +264,10 @@ static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) { OS << getQualifiedName(Reg->TheDef); } +static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { + OS << getEnumName(VT); +} + // // runMCDesc - Print out MC register descriptions. // @@ -547,25 +551,14 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, AllocatableRegs.insert(Order.begin(), Order.end()); } - OS << "namespace { // Register classes...\n"; - - // Emit the ValueType arrays for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = *RegisterClasses[rc]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.getName() + "VTs"; - - // Emit the register list now. - OS << " // " << Name - << " Register Class Value Types...\n" - << " const MVT::SimpleValueType " << Name - << "[] = {\n "; - for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i) - OS << getEnumName(RC.VTs[i]) << ", "; - OS << "MVT::Other\n };\n\n"; - } - OS << "} // end anonymous namespace\n\n"; + // Build a shared array of value types. + SequenceToOffsetTable > VTSeqs; + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) + VTSeqs.add(RegisterClasses[rc]->VTs); + VTSeqs.layout(); + OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n"; + VTSeqs.emit(OS, printSimpleValueType, "MVT::Other"); + OS << "};\n"; // Now that all of the structs have been emitted, emit the instances. if (!RegisterClasses.empty()) { @@ -692,7 +685,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << RegisterClasses[i]->getName() << "RegClass = {\n " << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n " - << RC.getName() << "VTs,\n " + << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName() << "SubclassMask,\n "; if (RC.getSuperClasses().empty()) OS << "NullRegClasses,\n "; diff --git a/utils/TableGen/SequenceToOffsetTable.h b/utils/TableGen/SequenceToOffsetTable.h index 26e7058..09dccbb 100644 --- a/utils/TableGen/SequenceToOffsetTable.h +++ b/utils/TableGen/SequenceToOffsetTable.h @@ -103,7 +103,9 @@ public: /// emit - Print out the table as the body of an array initializer. /// Use the Print function to print elements. - void emit(raw_ostream &OS, void (*Print)(raw_ostream&, ElemT)) const { + void emit(raw_ostream &OS, + void (*Print)(raw_ostream&, ElemT), + const char *Term = "0") const { assert(Entries && "Call layout() before emit()"); for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); I != E; ++I) { @@ -113,7 +115,7 @@ public: Print(OS, *SI); OS << ", "; } - OS << "0,\n"; + OS << Term << ",\n"; } } }; -- cgit v1.1 From 77ff8bbc2abf13b269bf1e66526e813955b078a7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 30 Mar 2012 20:09:06 +0000 Subject: Revert 153764 and 153761. They broke a --enable-optimized --enable-assertions --enable-expensive-checks build. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153771 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 176 +++++++++++++++++++-------------- utils/TableGen/SequenceToOffsetTable.h | 6 +- 2 files changed, 103 insertions(+), 79 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index b43203d..f082cfa 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -16,7 +16,6 @@ #include "RegisterInfoEmitter.h" #include "CodeGenTarget.h" #include "CodeGenRegisters.h" -#include "SequenceToOffsetTable.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" @@ -260,14 +259,6 @@ public: } }; -static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) { - OS << getQualifiedName(Reg->TheDef); -} - -static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { - OS << getEnumName(VT); -} - // // runMCDesc - Print out MC register descriptions. // @@ -279,78 +270,98 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; OS << "#undef GET_REGINFO_MC_DESC\n"; - const std::vector &Regs = RegBank.getRegisters(); std::map Overlaps; RegBank.computeOverlaps(Overlaps); - // The lists of sub-registers, super-registers, and overlaps all go in the - // same array. That allows us to share suffixes. - typedef std::vector RegVec; - SmallVector SubRegLists(Regs.size()); - SmallVector OverlapLists(Regs.size()); - SequenceToOffsetTable RegSeqs; + OS << "namespace llvm {\n\n"; + + const std::string &TargetName = Target.getName(); + + const std::vector &Regs = RegBank.getRegisters(); + + OS << "extern const uint16_t " << TargetName << "RegOverlaps[] = {\n"; - // Precompute register lists for the SequenceToOffsetTable. + // Emit an overlap list for all registers. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; + const CodeGenRegister::Set &O = Overlaps[Reg]; + // Move Reg to the front so TRI::getAliasSet can share the list. + OS << " /* " << Reg->getName() << "_Overlaps */ " + << getQualifiedName(Reg->TheDef) << ", "; + for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end(); + I != E; ++I) + if (*I != Reg) + OS << getQualifiedName((*I)->TheDef) << ", "; + OS << "0,\n"; + } + OS << "};\n\n"; - // Compute the ordered sub-register list. + OS << "extern const uint16_t " << TargetName << "SubRegsSet[] = {\n"; + // Emit the empty sub-registers list + OS << " /* Empty_SubRegsSet */ 0,\n"; + // Loop over all of the registers which have sub-registers, emitting the + // sub-registers list to memory. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Regs[i]; + if (Reg.getSubRegs().empty()) + continue; + // getSubRegs() orders by SubRegIndex. We want a topological order. SetVector SR; - Reg->addSubRegsPreOrder(SR, RegBank); - RegVec &SubRegList = SubRegLists[i]; - SubRegList.assign(SR.begin(), SR.end()); - RegSeqs.add(SubRegList); - - // Super-registers are already computed. - const RegVec &SuperRegList = Reg->getSuperRegs(); - RegSeqs.add(SuperRegList); - - // The list of overlaps doesn't need to have any particular order, except - // Reg itself must be the first element. Pick an ordering that has one of - // the other lists as a suffix. - RegVec &OverlapList = OverlapLists[i]; - const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ? - SubRegList : SuperRegList; - CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end()); - - // First element is Reg itself. - OverlapList.push_back(Reg); - Omit.insert(Reg); - - // Any elements not in Suffix. - const CodeGenRegister::Set &OSet = Overlaps[Reg]; - std::set_difference(OSet.begin(), OSet.end(), - Omit.begin(), Omit.end(), - std::back_inserter(OverlapList)); - - // Finally, Suffix itself. - OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end()); - RegSeqs.add(OverlapList); + Reg.addSubRegsPreOrder(SR, RegBank); + OS << " /* " << Reg.getName() << "_SubRegsSet */ "; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + OS << getQualifiedName(SR[j]->TheDef) << ", "; + OS << "0,\n"; } + OS << "};\n\n"; - // Compute the final layout of the sequence table. - RegSeqs.layout(); - - OS << "namespace llvm {\n\n"; - - const std::string &TargetName = Target.getName(); - - // Emit the shared table of register lists. - OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n"; - RegSeqs.emit(OS, printRegister); + OS << "extern const uint16_t " << TargetName << "SuperRegsSet[] = {\n"; + // Emit the empty super-registers list + OS << " /* Empty_SuperRegsSet */ 0,\n"; + // Loop over all of the registers which have super-registers, emitting the + // super-registers list to memory. + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister &Reg = *Regs[i]; + const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs(); + if (SR.empty()) + continue; + OS << " /* " << Reg.getName() << "_SuperRegsSet */ "; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + OS << getQualifiedName(SR[j]->TheDef) << ", "; + OS << "0,\n"; + } OS << "};\n\n"; OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; OS << " { \"NOREG\", 0, 0, 0 },\n"; - // Emit the register descriptors now. + // Now that register alias and sub-registers sets have been emitted, emit the + // register descriptors now. + unsigned OverlapsIndex = 0; + unsigned SubRegIndex = 1; // skip 1 for empty set + unsigned SuperRegIndex = 1; // skip 1 for empty set for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; - OS << " { \"" << Reg->getName() << "\", " - << RegSeqs.get(OverlapLists[i]) << ", " - << RegSeqs.get(SubRegLists[i]) << ", " - << RegSeqs.get(Reg->getSuperRegs()) << " },\n"; + OS << " { \""; + OS << Reg->getName() << "\", /* " << Reg->getName() << "_Overlaps */ " + << OverlapsIndex << ", "; + OverlapsIndex += Overlaps[Reg].size() + 1; + if (!Reg->getSubRegs().empty()) { + OS << "/* " << Reg->getName() << "_SubRegsSet */ " << SubRegIndex + << ", "; + // FIXME not very nice to recalculate this + SetVector SR; + Reg->addSubRegsPreOrder(SR, RegBank); + SubRegIndex += SR.size() + 1; + } else + OS << "/* Empty_SubRegsSet */ 0, "; + if (!Reg->getSuperRegs().empty()) { + OS << "/* " << Reg->getName() << "_SuperRegsSet */ " << SuperRegIndex; + SuperRegIndex += Reg->getSuperRegs().size() + 1; + } else + OS << "/* Empty_SuperRegsSet */ 0"; + OS << " },\n"; } OS << "};\n\n"; // End of register descriptors... @@ -453,7 +464,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " - << RegisterClasses.size() << ", " << TargetName << "RegLists, "; + << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, " + << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet, "; if (SubRegIndices.size() != 0) OS << "(uint16_t*)" << TargetName << "SubRegTable, " << SubRegIndices.size() << ");\n\n"; @@ -551,14 +563,25 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, AllocatableRegs.insert(Order.begin(), Order.end()); } - // Build a shared array of value types. - SequenceToOffsetTable > VTSeqs; - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) - VTSeqs.add(RegisterClasses[rc]->VTs); - VTSeqs.layout(); - OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n"; - VTSeqs.emit(OS, printSimpleValueType, "MVT::Other"); - OS << "};\n"; + OS << "namespace { // Register classes...\n"; + + // Emit the ValueType arrays for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.getName() + "VTs"; + + // Emit the register list now. + OS << " // " << Name + << " Register Class Value Types...\n" + << " const MVT::SimpleValueType " << Name + << "[] = {\n "; + for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i) + OS << getEnumName(RC.VTs[i]) << ", "; + OS << "MVT::Other\n };\n\n"; + } + OS << "} // end anonymous namespace\n\n"; // Now that all of the structs have been emitted, emit the instances. if (!RegisterClasses.empty()) { @@ -685,7 +708,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << RegisterClasses[i]->getName() << "RegClass = {\n " << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n " - << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " + << RC.getName() << "VTs,\n " << RC.getName() << "SubclassMask,\n "; if (RC.getSuperClasses().empty()) OS << "NullRegClasses,\n "; @@ -866,7 +889,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; - OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; + OS << "extern const uint16_t " << TargetName << "RegOverlaps[];\n"; + OS << "extern const uint16_t " << TargetName << "SubRegsSet[];\n"; + OS << "extern const uint16_t " << TargetName << "SuperRegsSet[];\n"; if (SubRegIndices.size() != 0) OS << "extern const uint16_t *get" << TargetName << "SubRegTable();\n"; @@ -879,7 +904,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" - << " " << TargetName << "RegLists,\n" + << " " << TargetName << "RegOverlaps, " + << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet,\n" << " "; if (SubRegIndices.size() != 0) OS << "get" << TargetName << "SubRegTable(), " diff --git a/utils/TableGen/SequenceToOffsetTable.h b/utils/TableGen/SequenceToOffsetTable.h index 09dccbb..26e7058 100644 --- a/utils/TableGen/SequenceToOffsetTable.h +++ b/utils/TableGen/SequenceToOffsetTable.h @@ -103,9 +103,7 @@ public: /// emit - Print out the table as the body of an array initializer. /// Use the Print function to print elements. - void emit(raw_ostream &OS, - void (*Print)(raw_ostream&, ElemT), - const char *Term = "0") const { + void emit(raw_ostream &OS, void (*Print)(raw_ostream&, ElemT)) const { assert(Entries && "Call layout() before emit()"); for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); I != E; ++I) { @@ -115,7 +113,7 @@ public: Print(OS, *SI); OS << ", "; } - OS << Term << ",\n"; + OS << "0,\n"; } } }; -- cgit v1.1 From 0d4e2ea00eac5d51a74a54dd504a8f34580041d7 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Mar 2012 20:24:14 +0000 Subject: Reapply 153764 and 153761 with a fix. Use an explicit comparator instead of the default. The sets are sorted, but not using the default comparator. Hopefully, this will unbreak the Linux builders. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153772 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 177 ++++++++++++++------------------- utils/TableGen/SequenceToOffsetTable.h | 6 +- 2 files changed, 80 insertions(+), 103 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index f082cfa..338e6ae 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -16,6 +16,7 @@ #include "RegisterInfoEmitter.h" #include "CodeGenTarget.h" #include "CodeGenRegisters.h" +#include "SequenceToOffsetTable.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" @@ -259,6 +260,14 @@ public: } }; +static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) { + OS << getQualifiedName(Reg->TheDef); +} + +static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { + OS << getEnumName(VT); +} + // // runMCDesc - Print out MC register descriptions. // @@ -270,98 +279,79 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; OS << "#undef GET_REGINFO_MC_DESC\n"; + const std::vector &Regs = RegBank.getRegisters(); std::map Overlaps; RegBank.computeOverlaps(Overlaps); - OS << "namespace llvm {\n\n"; - - const std::string &TargetName = Target.getName(); - - const std::vector &Regs = RegBank.getRegisters(); - - OS << "extern const uint16_t " << TargetName << "RegOverlaps[] = {\n"; + // The lists of sub-registers, super-registers, and overlaps all go in the + // same array. That allows us to share suffixes. + typedef std::vector RegVec; + SmallVector SubRegLists(Regs.size()); + SmallVector OverlapLists(Regs.size()); + SequenceToOffsetTable RegSeqs; - // Emit an overlap list for all registers. + // Precompute register lists for the SequenceToOffsetTable. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; - const CodeGenRegister::Set &O = Overlaps[Reg]; - // Move Reg to the front so TRI::getAliasSet can share the list. - OS << " /* " << Reg->getName() << "_Overlaps */ " - << getQualifiedName(Reg->TheDef) << ", "; - for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end(); - I != E; ++I) - if (*I != Reg) - OS << getQualifiedName((*I)->TheDef) << ", "; - OS << "0,\n"; - } - OS << "};\n\n"; - OS << "extern const uint16_t " << TargetName << "SubRegsSet[] = {\n"; - // Emit the empty sub-registers list - OS << " /* Empty_SubRegsSet */ 0,\n"; - // Loop over all of the registers which have sub-registers, emitting the - // sub-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - if (Reg.getSubRegs().empty()) - continue; - // getSubRegs() orders by SubRegIndex. We want a topological order. + // Compute the ordered sub-register list. SetVector SR; - Reg.addSubRegsPreOrder(SR, RegBank); - OS << " /* " << Reg.getName() << "_SubRegsSet */ "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0,\n"; + Reg->addSubRegsPreOrder(SR, RegBank); + RegVec &SubRegList = SubRegLists[i]; + SubRegList.assign(SR.begin(), SR.end()); + RegSeqs.add(SubRegList); + + // Super-registers are already computed. + const RegVec &SuperRegList = Reg->getSuperRegs(); + RegSeqs.add(SuperRegList); + + // The list of overlaps doesn't need to have any particular order, except + // Reg itself must be the first element. Pick an ordering that has one of + // the other lists as a suffix. + RegVec &OverlapList = OverlapLists[i]; + const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ? + SubRegList : SuperRegList; + CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end()); + + // First element is Reg itself. + OverlapList.push_back(Reg); + Omit.insert(Reg); + + // Any elements not in Suffix. + const CodeGenRegister::Set &OSet = Overlaps[Reg]; + std::set_difference(OSet.begin(), OSet.end(), + Omit.begin(), Omit.end(), + std::back_inserter(OverlapList), + CodeGenRegister::Less()); + + // Finally, Suffix itself. + OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end()); + RegSeqs.add(OverlapList); } - OS << "};\n\n"; - OS << "extern const uint16_t " << TargetName << "SuperRegsSet[] = {\n"; - // Emit the empty super-registers list - OS << " /* Empty_SuperRegsSet */ 0,\n"; - // Loop over all of the registers which have super-registers, emitting the - // super-registers list to memory. - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister &Reg = *Regs[i]; - const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs(); - if (SR.empty()) - continue; - OS << " /* " << Reg.getName() << "_SuperRegsSet */ "; - for (unsigned j = 0, je = SR.size(); j != je; ++j) - OS << getQualifiedName(SR[j]->TheDef) << ", "; - OS << "0,\n"; - } + // Compute the final layout of the sequence table. + RegSeqs.layout(); + + OS << "namespace llvm {\n\n"; + + const std::string &TargetName = Target.getName(); + + // Emit the shared table of register lists. + OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n"; + RegSeqs.emit(OS, printRegister); OS << "};\n\n"; OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; OS << " { \"NOREG\", 0, 0, 0 },\n"; - // Now that register alias and sub-registers sets have been emitted, emit the - // register descriptors now. - unsigned OverlapsIndex = 0; - unsigned SubRegIndex = 1; // skip 1 for empty set - unsigned SuperRegIndex = 1; // skip 1 for empty set + // Emit the register descriptors now. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; - OS << " { \""; - OS << Reg->getName() << "\", /* " << Reg->getName() << "_Overlaps */ " - << OverlapsIndex << ", "; - OverlapsIndex += Overlaps[Reg].size() + 1; - if (!Reg->getSubRegs().empty()) { - OS << "/* " << Reg->getName() << "_SubRegsSet */ " << SubRegIndex - << ", "; - // FIXME not very nice to recalculate this - SetVector SR; - Reg->addSubRegsPreOrder(SR, RegBank); - SubRegIndex += SR.size() + 1; - } else - OS << "/* Empty_SubRegsSet */ 0, "; - if (!Reg->getSuperRegs().empty()) { - OS << "/* " << Reg->getName() << "_SuperRegsSet */ " << SuperRegIndex; - SuperRegIndex += Reg->getSuperRegs().size() + 1; - } else - OS << "/* Empty_SuperRegsSet */ 0"; - OS << " },\n"; + OS << " { \"" << Reg->getName() << "\", " + << RegSeqs.get(OverlapLists[i]) << ", " + << RegSeqs.get(SubRegLists[i]) << ", " + << RegSeqs.get(Reg->getSuperRegs()) << " },\n"; } OS << "};\n\n"; // End of register descriptors... @@ -464,8 +454,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " - << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet, "; + << RegisterClasses.size() << ", " << TargetName << "RegLists, "; if (SubRegIndices.size() != 0) OS << "(uint16_t*)" << TargetName << "SubRegTable, " << SubRegIndices.size() << ");\n\n"; @@ -563,25 +552,14 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, AllocatableRegs.insert(Order.begin(), Order.end()); } - OS << "namespace { // Register classes...\n"; - - // Emit the ValueType arrays for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = *RegisterClasses[rc]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.getName() + "VTs"; - - // Emit the register list now. - OS << " // " << Name - << " Register Class Value Types...\n" - << " const MVT::SimpleValueType " << Name - << "[] = {\n "; - for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i) - OS << getEnumName(RC.VTs[i]) << ", "; - OS << "MVT::Other\n };\n\n"; - } - OS << "} // end anonymous namespace\n\n"; + // Build a shared array of value types. + SequenceToOffsetTable > VTSeqs; + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) + VTSeqs.add(RegisterClasses[rc]->VTs); + VTSeqs.layout(); + OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n"; + VTSeqs.emit(OS, printSimpleValueType, "MVT::Other"); + OS << "};\n"; // Now that all of the structs have been emitted, emit the instances. if (!RegisterClasses.empty()) { @@ -708,7 +686,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << RegisterClasses[i]->getName() << "RegClass = {\n " << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n " - << RC.getName() << "VTs,\n " + << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName() << "SubclassMask,\n "; if (RC.getSuperClasses().empty()) OS << "NullRegClasses,\n "; @@ -889,9 +867,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; - OS << "extern const uint16_t " << TargetName << "RegOverlaps[];\n"; - OS << "extern const uint16_t " << TargetName << "SubRegsSet[];\n"; - OS << "extern const uint16_t " << TargetName << "SuperRegsSet[];\n"; + OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; if (SubRegIndices.size() != 0) OS << "extern const uint16_t *get" << TargetName << "SubRegTable();\n"; @@ -904,8 +880,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" - << " " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet,\n" + << " " << TargetName << "RegLists,\n" << " "; if (SubRegIndices.size() != 0) OS << "get" << TargetName << "SubRegTable(), " diff --git a/utils/TableGen/SequenceToOffsetTable.h b/utils/TableGen/SequenceToOffsetTable.h index 26e7058..09dccbb 100644 --- a/utils/TableGen/SequenceToOffsetTable.h +++ b/utils/TableGen/SequenceToOffsetTable.h @@ -103,7 +103,9 @@ public: /// emit - Print out the table as the body of an array initializer. /// Use the Print function to print elements. - void emit(raw_ostream &OS, void (*Print)(raw_ostream&, ElemT)) const { + void emit(raw_ostream &OS, + void (*Print)(raw_ostream&, ElemT), + const char *Term = "0") const { assert(Entries && "Call layout() before emit()"); for (typename SeqMap::const_iterator I = Seqs.begin(), E = Seqs.end(); I != E; ++I) { @@ -113,7 +115,7 @@ public: Print(OS, *SI); OS << ", "; } - OS << "0,\n"; + OS << Term << ",\n"; } } }; -- cgit v1.1 From c19f72bd83e8cb2cc31257008ee9d7797dbf3dbb Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Mar 2012 21:12:52 +0000 Subject: Use SequenceToOffsetTable in emitRegisterNameString. This allows suffix sharing in register names. (AX is a suffix of EAX). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153777 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 22 ++++++++++++++-------- utils/TableGen/SequenceToOffsetTable.h | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index c4812dc..f840709 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -16,6 +16,7 @@ #include "AsmWriterInst.h" #include "CodeGenTarget.h" #include "StringToOffsetTable.h" +#include "SequenceToOffsetTable.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" @@ -462,12 +463,12 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { static void emitRegisterNameString(raw_ostream &O, StringRef AltName, const std::vector &Registers) { - StringToOffsetTable StringTable; - O << " static const unsigned RegAsmOffset" << AltName << "[] = {\n "; + SequenceToOffsetTable StringTable; + SmallVector AsmNames(Registers.size()); for (unsigned i = 0, e = Registers.size(); i != e; ++i) { const CodeGenRegister &Reg = *Registers[i]; + std::string &AsmName = AsmNames[i]; - std::string AsmName; // "NoRegAltName" is special. We don't need to do a lookup for that, // as it's just a reference to the default register name. if (AltName == "" || AltName == "NoRegAltName") { @@ -495,8 +496,17 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, AsmName = AltNames[Idx]; } } + StringTable.add(AsmName); + } + + StringTable.layout(); + O << " static const char AsmStrs" << AltName << "[] = {\n"; + StringTable.emit(O, printChar); + O << " };\n\n"; - O << StringTable.GetOrAddStringOffset(AsmName); + O << " static const unsigned RegAsmOffset" << AltName << "[] = {\n "; + for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + O << StringTable.get(AsmNames[i]); if (((i + 1) % 14) == 0) O << ",\n "; else @@ -506,10 +516,6 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, O << "0\n" << " };\n" << "\n"; - - O << " const char *AsmStrs" << AltName << " =\n"; - StringTable.EmitString(O); - O << ";\n"; } void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { diff --git a/utils/TableGen/SequenceToOffsetTable.h b/utils/TableGen/SequenceToOffsetTable.h index 09dccbb..97c764e 100644 --- a/utils/TableGen/SequenceToOffsetTable.h +++ b/utils/TableGen/SequenceToOffsetTable.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace llvm { @@ -120,6 +121,19 @@ public: } }; +// Helper function for SequenceToOffsetTable. +static inline void printChar(raw_ostream &OS, char C) { + unsigned char UC(C); + if (isalnum(UC) || ispunct(UC)) { + OS << '\''; + if (C == '\\' || C == '\'') + OS << '\\'; + OS << C << '\''; + } else { + OS << unsigned(UC); + } +} + } // end namespace llvm #endif -- cgit v1.1 From cef670a3a3fd448edfb38d8b513f5aa775257352 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 30 Mar 2012 23:13:40 +0000 Subject: Rip out emission of the regIsInRegClass function for the asm printer. It's slow, bloated and completely redundant with MCRegisterClass::contains. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153782 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 70 ++----------------------------------- utils/TableGen/AsmWriterEmitter.h | 1 - 2 files changed, 3 insertions(+), 68 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index f840709..0844fc7 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -705,68 +705,6 @@ static void EmitGetMapOperandNumber(raw_ostream &O) { O << "}\n\n"; } -void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { - CodeGenTarget Target(Records); - - // Enumerate the register classes. - ArrayRef RegisterClasses = - Target.getRegBank().getRegClasses(); - - O << "namespace { // Register classes\n"; - O << " enum RegClass {\n"; - - // Emit the register enum value for each RegisterClass. - for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { - if (I != 0) O << ",\n"; - O << " RC_" << RegisterClasses[I]->getName(); - } - - O << "\n };\n"; - O << "} // end anonymous namespace\n\n"; - - // Emit a function that returns 'true' if a regsiter is part of a particular - // register class. I.e., RAX is part of GR64 on X86. - O << "static bool regIsInRegisterClass" - << "(unsigned RegClass, unsigned Reg) {\n"; - - // Emit the switch that checks if a register belongs to a particular register - // class. - O << " switch (RegClass) {\n"; - O << " default: break;\n"; - - for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { - const CodeGenRegisterClass &RC = *RegisterClasses[I]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.getName(); - O << " case RC_" << Name << ":\n"; - - // Emit the register list now. - unsigned IE = RC.getOrder().size(); - if (IE == 1) { - O << " if (Reg == " << getQualifiedName(RC.getOrder()[0]) << ")\n"; - O << " return true;\n"; - } else { - O << " switch (Reg) {\n"; - O << " default: break;\n"; - - for (unsigned II = 0; II != IE; ++II) { - Record *Reg = RC.getOrder()[II]; - O << " case " << getQualifiedName(Reg) << ":\n"; - } - - O << " return true;\n"; - O << " }\n"; - } - - O << " break;\n"; - } - - O << " }\n\n"; - O << " return false;\n"; - O << "}\n\n"; -} - static unsigned CountNumOperands(StringRef AsmString) { unsigned NumOps = 0; std::pair ASM = AsmString.split(' '); @@ -810,8 +748,6 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { O << "\n#ifdef PRINT_ALIAS_INSTR\n"; O << "#undef PRINT_ALIAS_INSTR\n\n"; - EmitRegIsInRegClass(O); - // Emit the method that prints the alias instruction. std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); @@ -877,9 +813,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (!IAP->isOpMapped(ROName)) { IAP->addOperand(ROName, i); - Cond = std::string("regIsInRegisterClass(RC_") + - CGA->ResultOperands[i].getRecord()->getName() + - ", MI->getOperand(" + llvm::utostr(i) + ").getReg())"; + Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" + + CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)" + ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())"; IAP->addCond(Cond); } else { Cond = std::string("MI->getOperand(") + diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h index 731e31c..08f7ae3 100644 --- a/utils/TableGen/AsmWriterEmitter.h +++ b/utils/TableGen/AsmWriterEmitter.h @@ -38,7 +38,6 @@ private: void EmitPrintInstruction(raw_ostream &o); void EmitGetRegisterName(raw_ostream &o); void EmitGetInstructionName(raw_ostream &o); - void EmitRegIsInRegClass(raw_ostream &O); void EmitPrintAliasInstruction(raw_ostream &O); AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { -- cgit v1.1 From dd9a50196cd75dbcb2bd604754cd62f8c1f30357 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Sat, 31 Mar 2012 01:35:59 +0000 Subject: Introduce Register Units: Give each leaf register a number. First small step toward modeling multi-register multi-pressure. In the future, register units can also be used to model liveness and aliasing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153794 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 49 +++++++++++++++++++++++++++++++++++++ utils/TableGen/CodeGenRegisters.h | 11 +++++++++ 2 files changed, 60 insertions(+) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index d86ca7a..73f0356 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -88,6 +88,26 @@ const std::string &CodeGenRegister::getName() const { return TheDef->getName(); } +// Merge two RegUnitLists maintining the order and removing duplicates. +// Overwrites MergedRU in the process. +static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, + const CodeGenRegister::RegUnitList &RRU) +{ + CodeGenRegister::RegUnitList LRU = MergedRU; + MergedRU.clear(); + for (CodeGenRegister::RegUnitList::const_iterator + RI = RRU.begin(), RE = RRU.end(), LI = LRU.begin(), LE = LRU.end(); + RI != RE || LI != LE;) { + + CodeGenRegister::RegUnitList::const_iterator &NextI = + (RI != RE && (LI == LE || *RI < *LI)) ? RI : LI; + + if (MergedRU.empty() || *NextI != MergedRU.back()) + MergedRU.push_back(*NextI); + ++NextI; + } +} + const CodeGenRegister::SubRegMap & CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { // Only compute this map once. @@ -227,6 +247,34 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { if (Orphans.erase(SI->second)) SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second; } + + // Initialize RegUnitList. A register with no subregisters creates its own + // unit. Otherwise, it inherits all its subregister's units. Because + // getSubRegs is called recursively, this processes the register hierarchy in + // postorder. + // + // TODO: We currently assume all register units correspond to a named "leaf" + // register. We should also unify register units for ad-hoc register + // aliases. This can be done by iteratively merging units for aliasing + // registers using a worklist. + assert(RegUnits.empty() && "Should only initialize RegUnits once"); + if (SubRegs.empty()) { + RegUnits.push_back(RegBank.newRegUnit()); + } + else { + for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end(); + I != E; ++I) { + // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM. + CodeGenRegister *SR = I->second; + if (SR == this) { + if (RegUnits.empty()) + RegUnits.push_back(RegBank.newRegUnit()); + continue; + } + // Merge the subregister's units into this register's RegUnits. + mergeRegUnits(RegUnits, SR->RegUnits); + } + } return SubRegs; } @@ -659,6 +707,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { // Precompute all sub-register maps now all the registers are known. // This will create Composite entries for all inferred sub-register indices. + NumRegUnits = 0; for (unsigned i = 0, e = Registers.size(); i != e; ++i) Registers[i]->getSubRegs(*this); diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index f5372c0..f73519e 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -123,6 +123,13 @@ namespace llvm { return SuperRegs; } + // List of register units in ascending order. + typedef SmallVector RegUnitList; + + // Get the list of register units. + // This is only valid after getSubRegs() completes. + const RegUnitList &getRegUnits() const { return RegUnits; } + // Order CodeGenRegister pointers by EnumValue. struct Less { bool operator()(const CodeGenRegister *A, @@ -139,6 +146,7 @@ namespace llvm { bool SubRegsComplete; SubRegMap SubRegs; SuperRegList SuperRegs; + RegUnitList RegUnits; }; @@ -307,6 +315,7 @@ namespace llvm { // Registers. std::vector Registers; DenseMap Def2Reg; + unsigned NumRegUnits; // Register classes. std::vector RegClasses; @@ -355,6 +364,8 @@ namespace llvm { // Find a register from its Record def. CodeGenRegister *getReg(Record*); + unsigned newRegUnit() { return NumRegUnits++; } + ArrayRef getRegClasses() const { return RegClasses; } -- cgit v1.1 From 9f2a9d741f58f0a2a591ec16e5e038c905142dbc Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Sat, 31 Mar 2012 02:39:17 +0000 Subject: comment typo git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153796 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 73f0356..cdf20ff 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -88,7 +88,7 @@ const std::string &CodeGenRegister::getName() const { return TheDef->getName(); } -// Merge two RegUnitLists maintining the order and removing duplicates. +// Merge two RegUnitLists maintaining the order and removing duplicates. // Overwrites MergedRU in the process. static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, const CodeGenRegister::RegUnitList &RRU) -- cgit v1.1 From 243018ffcf764e4dde2968f909f4a2e578aafe86 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 1 Apr 2012 14:23:58 +0000 Subject: Emit the LLVM<->DWARF register mapping as a sorted table and use binary search to do the lookup. This also avoids emitting the information twice, which led to code bloat. On i386-linux-Release+Asserts with all targets built this change shaves a whopping 1.3 MB off clang. The number is probably exaggerated by recent inliner changes but the methods were already enormous with the old inline cost computation. The DWARF reg -> LLVM reg mapping doesn't seem to have holes in it, so it could be a simple lookup table. I didn't implement that optimization yet to avoid potentially changing functionality. There is still some duplication both in tablegen and the generated code that should be cleaned up eventually. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153837 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 186 +++++++++++++++++++++++++-------- utils/TableGen/RegisterInfoEmitter.h | 3 + 2 files changed, 146 insertions(+), 43 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 338e6ae..a5fe756 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -118,11 +118,11 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, OS << "#endif // GET_REGINFO_ENUM\n\n"; } -void -RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, - const std::vector &Regs, - bool isCtor) { +void +RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, + const std::vector &Regs, + bool isCtor) { // Collect all information about dwarf register numbers typedef std::map, LessRecord> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; @@ -148,6 +148,121 @@ RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, for (unsigned i = I->second.size(), e = maxLength; i != e; ++i) I->second.push_back(-1); + std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace"); + + OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n"; + + // Emit reverse information about the dwarf register numbers. + for (unsigned j = 0; j < 2; ++j) { + for (unsigned i = 0, e = maxLength; i != e; ++i) { + OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace; + OS << (j == 0 ? "DwarfFlavour" : "EHFlavour"); + OS << i << "Dwarf2L[]"; + + if (!isCtor) { + OS << " = {\n"; + + // Store the mapping sorted by the LLVM reg num so lookup can be done + // with a binary search. + std::map Dwarf2LMap; + for (DwarfRegNumsMapTy::iterator + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { + int DwarfRegNo = I->second[i]; + if (DwarfRegNo < 0) + continue; + Dwarf2LMap[DwarfRegNo] = I->first; + } + + for (std::map::iterator + I = Dwarf2LMap.begin(), E = Dwarf2LMap.end(); I != E; ++I) + OS << " { " << I->first << "U, " << getQualifiedName(I->second) + << " },\n"; + + OS << "};\n"; + } else { + OS << ";\n"; + } + + // We have to store the size in a const global, it's used in multiple + // places. + OS << "extern const unsigned " << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "Dwarf2LSize"; + if (!isCtor) + OS << " = sizeof(" << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i + << "Dwarf2L)/sizeof(MCRegisterInfo::DwarfLLVMRegPair);\n\n"; + else + OS << ";\n\n"; + } + } + + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + Record *Reg = Regs[i]->TheDef; + const RecordVal *V = Reg->getValue("DwarfAlias"); + if (!V || !V->getValue()) + continue; + + DefInit *DI = dynamic_cast(V->getValue()); + Record *Alias = DI->getDef(); + DwarfRegNums[Reg] = DwarfRegNums[Alias]; + } + + // Emit information about the dwarf register numbers. + for (unsigned j = 0; j < 2; ++j) { + for (unsigned i = 0, e = maxLength; i != e; ++i) { + OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace; + OS << (j == 0 ? "DwarfFlavour" : "EHFlavour"); + OS << i << "L2Dwarf[]"; + if (!isCtor) { + OS << " = {\n"; + // Store the mapping sorted by the Dwarf reg num so lookup can be done + // with a binary search. + for (DwarfRegNumsMapTy::iterator + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { + int RegNo = I->second[i]; + if (RegNo == -1) // -1 is the default value, don't emit a mapping. + continue; + + OS << " { " << getQualifiedName(I->first) << ", " << RegNo + << "U },\n"; + } + OS << "};\n"; + } else { + OS << ";\n"; + } + + // We have to store the size in a const global, it's used in multiple + // places. + OS << "extern const unsigned " << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "L2DwarfSize"; + if (!isCtor) + OS << " = sizeof(" << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i + << "L2Dwarf)/sizeof(MCRegisterInfo::DwarfLLVMRegPair);\n\n"; + else + OS << ";\n\n"; + } + } +} + +void +RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, + const std::vector &Regs, + bool isCtor) { + // Emit the initializer so the tables from EmitRegMappingTables get wired up + // to the MCRegisterInfo object. + unsigned maxLength = 0; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + Record *Reg = Regs[i]->TheDef; + maxLength = std::max((size_t)maxLength, + Reg->getValueAsListOfInts("DwarfNumbers").size()); + } + + if (!maxLength) + return; + + std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace"); + // Emit reverse information about the dwarf register numbers. for (unsigned j = 0; j < 2; ++j) { OS << " switch ("; @@ -161,38 +276,24 @@ RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, for (unsigned i = 0, e = maxLength; i != e; ++i) { OS << " case " << i << ":\n"; - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { - int DwarfRegNo = I->second[i]; - if (DwarfRegNo < 0) - continue; - OS << " "; - if (!isCtor) - OS << "RI->"; - OS << "mapDwarfRegToLLVMReg(" << DwarfRegNo << ", " - << getQualifiedName(I->first) << ", "; - if (j == 0) + OS << " "; + if (!isCtor) + OS << "RI->"; + std::string Tmp; + raw_string_ostream(Tmp) << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i + << "Dwarf2L"; + OS << "mapDwarfRegsToLLVMRegs(" << Tmp << ", " << Tmp << "Size, "; + if (j == 0) OS << "false"; else OS << "true"; - OS << " );\n"; - } + OS << ");\n"; OS << " break;\n"; } OS << " }\n"; } - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - Record *Reg = Regs[i]->TheDef; - const RecordVal *V = Reg->getValue("DwarfAlias"); - if (!V || !V->getValue()) - continue; - - DefInit *DI = dynamic_cast(V->getValue()); - Record *Alias = DI->getDef(); - DwarfRegNums[Reg] = DwarfRegNums[Alias]; - } - // Emit information about the dwarf register numbers. for (unsigned j = 0; j < 2; ++j) { OS << " switch ("; @@ -206,24 +307,19 @@ RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, for (unsigned i = 0, e = maxLength; i != e; ++i) { OS << " case " << i << ":\n"; - // Sort by name to get a stable order. - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { - int RegNo = I->second[i]; - if (RegNo == -1) // -1 is the default value, don't emit a mapping. - continue; - - OS << " "; - if (!isCtor) - OS << "RI->"; - OS << "mapLLVMRegToDwarfReg(" << getQualifiedName(I->first) << ", " - << RegNo << ", "; - if (j == 0) + OS << " "; + if (!isCtor) + OS << "RI->"; + std::string Tmp; + raw_string_ostream(Tmp) << Namespace + << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i + << "L2Dwarf"; + OS << "mapLLVMRegsToDwarfRegs(" << Tmp << ", " << Tmp << "Size, "; + if (j == 0) OS << "false"; else OS << "true"; - OS << " );\n"; - } + OS << ");\n"; OS << " break;\n"; } OS << " }\n"; @@ -448,6 +544,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << "SubRegTable;\n}\n\n"; } + EmitRegMappingTables(OS, Regs, false); + // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " @@ -872,6 +970,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const uint16_t *get" << TargetName << "SubRegTable();\n"; + EmitRegMappingTables(OS, Regs, true); + OS << ClassName << "::\n" << ClassName << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h index 0fd4d07..2e6b64a 100644 --- a/utils/TableGen/RegisterInfoEmitter.h +++ b/utils/TableGen/RegisterInfoEmitter.h @@ -50,6 +50,9 @@ public: private: void EmitRegMapping(raw_ostream &o, const std::vector &Regs, bool isCtor); + void EmitRegMappingTables(raw_ostream &o, + const std::vector &Regs, + bool isCtor); void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); }; -- cgit v1.1 From 413b2e7539a1e41f8694abb809678ae48d1e6125 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 1 Apr 2012 18:14:14 +0000 Subject: Use SequenceToOffsetTable to create instruction name table. Saves space particularly on X86 where AVX instructions just add a 'v' to the front of other instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153841 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/InstrInfoEmitter.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 9a07970..0941d2e 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -14,7 +14,7 @@ #include "InstrInfoEmitter.h" #include "CodeGenTarget.h" -#include "StringToOffsetTable.h" +#include "SequenceToOffsetTable.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include @@ -214,21 +214,28 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OperandInfoIDs, OS); OS << "};\n\n"; - OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {\n "; - StringToOffsetTable StringTable; + // Build an array of instruction names + SequenceToOffsetTable InstrNames; for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { const CodeGenInstruction *Instr = NumberedInstructions[i]; - OS << StringTable.GetOrAddStringOffset(Instr->TheDef->getName()) << "U, "; + InstrNames.add(Instr->TheDef->getName()); + } + + InstrNames.layout(); + OS << "extern const char " << TargetName << "InstrNameData[] = {\n"; + InstrNames.emit(OS, printChar); + OS << "};\n\n"; + + OS << "extern const unsigned " << TargetName <<"InstrNameIndices[] = {"; + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { if (i % 8 == 0) OS << "\n "; + const CodeGenInstruction *Instr = NumberedInstructions[i]; + OS << InstrNames.get(Instr->TheDef->getName()) << "U, "; } OS << "\n};\n\n"; - OS << "const char *" << TargetName << "InstrNameData =\n"; - StringTable.EmitString(OS); - OS << ";\n\n"; - // MCInstrInfo initialization routine. OS << "static inline void Init" << TargetName << "MCInstrInfo(MCInstrInfo *II) {\n"; @@ -259,7 +266,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) { OS << "namespace llvm {\n"; OS << "extern const MCInstrDesc " << TargetName << "Insts[];\n"; OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n"; - OS << "extern const char *" << TargetName << "InstrNameData;\n"; + OS << "extern const char " << TargetName << "InstrNameData[];\n"; OS << ClassName << "::" << ClassName << "(int SO, int DO)\n" << " : TargetInstrInfoImpl(SO, DO) {\n" << " InitMCInstrInfo(" << TargetName << "Insts, " -- cgit v1.1 From a4bd58b0f0d6ca33ff230aff450c9f2b94934bff Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 2 Apr 2012 00:47:39 +0000 Subject: Use SequenceToOffsetTable to generate instruction name table for AsmWriter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153857 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 52 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 0844fc7..de2dc51 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -374,7 +374,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { O << " };\n\n"; // Emit the string itself. - O << " const char *AsmStrs = \n"; + O << " const char *const AsmStrs = \n"; StringTable.EmitString(O); O << ";\n\n"; @@ -504,17 +504,13 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, StringTable.emit(O, printChar); O << " };\n\n"; - O << " static const unsigned RegAsmOffset" << AltName << "[] = {\n "; + O << " static const unsigned RegAsmOffset" << AltName << "[] = {"; for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - O << StringTable.get(AsmNames[i]); - if (((i + 1) % 14) == 0) - O << ",\n "; - else - O << ", "; - + if ((i % 14) == 0) + O << "\n "; + O << StringTable.get(AsmNames[i]) << ", "; } - O << "0\n" - << " };\n" + O << " };\n" << "\n"; } @@ -577,19 +573,30 @@ void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { const std::vector &NumberedInstructions = Target.getInstructionsByEnumValue(); - StringToOffsetTable StringTable; O << "\n\n#ifdef GET_INSTRUCTION_NAME\n" "#undef GET_INSTRUCTION_NAME\n\n" "/// getInstructionName: This method is automatically generated by tblgen\n" "/// from the instruction set description. This returns the enum name of the\n" "/// specified instruction.\n" - "const char *" << Target.getName() << ClassName - << "::getInstructionName(unsigned Opcode) {\n" - << " assert(Opcode < " << NumberedInstructions.size() - << " && \"Invalid instruction number!\");\n" - << "\n" - << " static const unsigned InstAsmOffset[] = {"; + << "const char *" << Target.getName() << ClassName + << "::getInstructionName(unsigned Opcode) {\n" + << " assert(Opcode < " << NumberedInstructions.size() + << " && \"Invalid instruction number!\");\n" + << "\n"; + + SequenceToOffsetTable StringTable; + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { + const CodeGenInstruction &Inst = *NumberedInstructions[i]; + StringTable.add(Inst.TheDef->getName()); + } + + StringTable.layout(); + O << " static const char Strs[] = {\n"; + StringTable.emit(O, printChar); + O << " };\n\n"; + + O << " static const unsigned InstAsmOffset[] = {"; for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { const CodeGenInstruction &Inst = *NumberedInstructions[i]; @@ -597,15 +604,10 @@ void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { if ((i % 14) == 0) O << "\n "; - O << StringTable.GetOrAddStringOffset(AsmName) << ", "; + O << StringTable.get(AsmName) << ", "; } - O << "0\n" - << " };\n" - << "\n"; - - O << " const char *Strs =\n"; - StringTable.EmitString(O); - O << ";\n"; + O << " };\n" + << "\n"; O << " return Strs+InstAsmOffset[Opcode];\n" << "}\n\n#endif\n"; -- cgit v1.1 From 7c0b3c1fb6395475e262d66ee403645f0c67dee2 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 2 Apr 2012 07:01:04 +0000 Subject: Remove getInstructionName from MCInstPrinter implementations in favor of using the instruction name table from MCInstrInfo. Reduces static data in the InstPrinter implementations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153863 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 49 ------------------------------------- utils/TableGen/AsmWriterEmitter.h | 1 - 2 files changed, 50 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index de2dc51..bc63454 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -565,54 +565,6 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { << "}\n"; } -void AsmWriterEmitter::EmitGetInstructionName(raw_ostream &O) { - CodeGenTarget Target(Records); - Record *AsmWriter = Target.getAsmWriter(); - std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); - - const std::vector &NumberedInstructions = - Target.getInstructionsByEnumValue(); - - O << -"\n\n#ifdef GET_INSTRUCTION_NAME\n" -"#undef GET_INSTRUCTION_NAME\n\n" -"/// getInstructionName: This method is automatically generated by tblgen\n" -"/// from the instruction set description. This returns the enum name of the\n" -"/// specified instruction.\n" - << "const char *" << Target.getName() << ClassName - << "::getInstructionName(unsigned Opcode) {\n" - << " assert(Opcode < " << NumberedInstructions.size() - << " && \"Invalid instruction number!\");\n" - << "\n"; - - SequenceToOffsetTable StringTable; - for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { - const CodeGenInstruction &Inst = *NumberedInstructions[i]; - StringTable.add(Inst.TheDef->getName()); - } - - StringTable.layout(); - O << " static const char Strs[] = {\n"; - StringTable.emit(O, printChar); - O << " };\n\n"; - - O << " static const unsigned InstAsmOffset[] = {"; - for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { - const CodeGenInstruction &Inst = *NumberedInstructions[i]; - - std::string AsmName = Inst.TheDef->getName(); - if ((i % 14) == 0) - O << "\n "; - - O << StringTable.get(AsmName) << ", "; - } - O << " };\n" - << "\n"; - - O << " return Strs+InstAsmOffset[Opcode];\n" - << "}\n\n#endif\n"; -} - namespace { // IAPrinter - Holds information about an InstAlias. Two InstAliases match if // they both have the same conditionals. In which case, we cannot print out the @@ -965,7 +917,6 @@ void AsmWriterEmitter::run(raw_ostream &O) { EmitPrintInstruction(O); EmitGetRegisterName(O); - EmitGetInstructionName(O); EmitPrintAliasInstruction(O); } diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h index 08f7ae3..9719b20 100644 --- a/utils/TableGen/AsmWriterEmitter.h +++ b/utils/TableGen/AsmWriterEmitter.h @@ -37,7 +37,6 @@ namespace llvm { private: void EmitPrintInstruction(raw_ostream &o); void EmitGetRegisterName(raw_ostream &o); - void EmitGetInstructionName(raw_ostream &o); void EmitPrintAliasInstruction(raw_ostream &O); AsmWriterInst *getAsmWriterInstByID(unsigned ID) const { -- cgit v1.1 From fab3f7ee6f2adca5037f597ce4f28c5acdcbd852 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 2 Apr 2012 07:48:39 +0000 Subject: Reorder fields in MatchEntry and OperandMatchEntry to reduce padding. A bit tricky due to the target specific sizes for some of the fields so the ordering is only optimal for the targets in the tree. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153865 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 49 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index c8d90aa..96edaa1 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2024,12 +2024,12 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, OS << "namespace {\n"; OS << " struct OperandMatchEntry {\n"; OS << " static const char *const MnemonicTable;\n"; - OS << " unsigned OperandMask;\n"; - OS << " unsigned Mnemonic;\n"; - OS << " " << getMinimalTypeForRange(Info.Classes.size()) - << " Class;\n"; + OS << " uint32_t OperandMask;\n"; + OS << " uint32_t Mnemonic;\n"; OS << " " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size()) - << " RequiredFeatures;\n\n"; + << " RequiredFeatures;\n"; + OS << " " << getMinimalTypeForRange(Info.Classes.size()) + << " Class;\n\n"; OS << " StringRef getMnemonic() const {\n"; OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; OS << " MnemonicTable[Mnemonic]);\n"; @@ -2080,10 +2080,7 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, // Store a pascal-style length byte in the mnemonic. std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); OS << ", " << StringTable.GetOrAddStringOffset(LenMnemonic, false) - << " /* " << II.Mnemonic << " */"; - - OS << ", " << OMI.CI->Name - << ", "; + << " /* " << II.Mnemonic << " */, "; // Write the required features mask. if (!II.RequiredFeatures.empty()) { @@ -2093,6 +2090,9 @@ static void EmitCustomOperandParsing(raw_ostream &OS, CodeGenTarget &Target, } } else OS << "0"; + + OS << ", " << OMI.CI->Name; + OS << " },\n"; } OS << "};\n\n"; @@ -2321,14 +2321,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "namespace {\n"; OS << " struct MatchEntry {\n"; OS << " static const char *const MnemonicTable;\n"; + OS << " uint32_t Mnemonic;\n"; OS << " uint16_t Opcode;\n"; - OS << " unsigned Mnemonic;\n"; OS << " " << getMinimalTypeForRange(Info.Matchables.size()) << " ConvertFn;\n"; - OS << " " << getMinimalTypeForRange(Info.Classes.size()) - << " Classes[" << MaxNumOperands << "];\n"; OS << " " << getMinimalTypeForRange(1ULL << Info.SubtargetFeatures.size()) << " RequiredFeatures;\n"; + OS << " " << getMinimalTypeForRange(Info.Classes.size()) + << " Classes[" << MaxNumOperands << "];\n"; OS << " uint8_t AsmVariantID;\n\n"; OS << " StringRef getMnemonic() const {\n"; OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n"; @@ -2363,18 +2363,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Store a pascal-style length byte in the mnemonic. std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str(); - OS << " { " << Target.getName() << "::" + OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false) + << " /* " << II.Mnemonic << " */, " + << Target.getName() << "::" << II.getResultInst()->TheDef->getName() << ", " - << StringTable.GetOrAddStringOffset(LenMnemonic, false) - << " /* " << II.Mnemonic << " */" - << ", " << II.ConversionFnKind << ", { "; - for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { - MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; - - if (i) OS << ", "; - OS << Op.Class->Name; - } - OS << " }, "; + << II.ConversionFnKind << ", "; // Write the required features mask. if (!II.RequiredFeatures.empty()) { @@ -2384,7 +2377,15 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { } } else OS << "0"; - OS << ", " << II.AsmVariantID; + + OS << ", { "; + for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) { + MatchableInfo::AsmOperand &Op = II.AsmOperands[i]; + + if (i) OS << ", "; + OS << Op.Class->Name; + } + OS << " }, " << II.AsmVariantID; OS << "},\n"; } -- cgit v1.1 From 94338594efed5575ab83b7d8d4bacb0dbf1778a3 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Mon, 2 Apr 2012 09:13:46 +0000 Subject: Emit the asm writer's mnemonic table with SequenceToOffsetTable. This way we can get AVX v-prefixed instructions tail merged with the normal insns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153869 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index bc63454..d3f7f0e 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -278,12 +278,27 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); // Build an aggregate string, and build a table of offsets into it. - StringToOffsetTable StringTable; + SequenceToOffsetTable StringTable; /// OpcodeInfo - This encodes the index of the string to use for the first /// chunk of the output as well as indices used for operand printing. std::vector OpcodeInfo; + // Add all strings to the string table upfront so it can generate an optimized + // representation. + for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { + AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; + if (AWI != 0 && + AWI->Operands[0].OperandType == AsmWriterOperand::isLiteralTextOperand && + !AWI->Operands[0].Str.empty()) { + std::string Str = AWI->Operands[0].Str; + UnescapeString(Str); + StringTable.add(Str); + } + } + + StringTable.layout(); + unsigned MaxStringIdx = 0; for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; @@ -295,11 +310,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { AsmWriterOperand::isLiteralTextOperand || AWI->Operands[0].Str.empty()) { // Something handled by the asmwriter printer, but with no leading string. - Idx = StringTable.GetOrAddStringOffset(""); + Idx = StringTable.get(""); } else { std::string Str = AWI->Operands[0].Str; UnescapeString(Str); - Idx = StringTable.GetOrAddStringOffset(Str); + Idx = StringTable.get(Str); MaxStringIdx = std::max(MaxStringIdx, Idx); // Nuke the string from the operand list. It is now handled! @@ -374,9 +389,9 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { O << " };\n\n"; // Emit the string itself. - O << " const char *const AsmStrs = \n"; - StringTable.EmitString(O); - O << ";\n\n"; + O << " const char AsmStrs[] = {\n"; + StringTable.emit(O, printChar); + O << " };\n\n"; O << " O << \"\\t\";\n\n"; -- cgit v1.1 From 545b962f1565eaf9ba0f7dfa1b0a74c43359022d Mon Sep 17 00:00:00 2001 From: Silviu Baranga Date: Mon, 2 Apr 2012 15:46:46 +0000 Subject: Second part for the 153874 one git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153875 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/FixedLenDecoderEmitter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index 10e04a6..9b676f2 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -552,12 +552,12 @@ void Filter::emit(raw_ostream &o, unsigned &Indentation) const { // encoding bits do not match exactly. if (!DefaultCase) { ++Indentation; ++Indentation; } - bool finished = filterIterator->second->emit(o, Indentation); + filterIterator->second->emit(o, Indentation); // For top level default case, there's no need for a break statement. if (Owner->isTopLevel() && DefaultCase) break; - if (!finished) - o.indent(Indentation) << "break;\n"; + + o.indent(Indentation) << "break;\n"; if (!DefaultCase) { --Indentation; --Indentation; } } -- cgit v1.1 From 1adc215ddcadcfaaa07a8e93f48a8f62c4561afe Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 2 Apr 2012 23:27:43 +0000 Subject: Compare the .o files only for release builds. Add an option to bypass the comparison altogether. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153909 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/release/test-release.sh | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'utils') diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh index 6ec2861..7aafc6d 100755 --- a/utils/release/test-release.sh +++ b/utils/release/test-release.sh @@ -35,6 +35,7 @@ do_objc="yes" do_64bit="yes" do_debug="no" do_asserts="no" +do_compare="yes" BuildDir="`pwd`" function usage() { @@ -54,6 +55,7 @@ function usage() { echo " -disable-objc Disable ObjC build. [default: enable]" echo " -test-debug Test the debug build. [default: no]" echo " -test-asserts Test with asserts on. [default: no]" + echo " -no-compare-files Don't test that phase 2 and 3 files are identical." } while [ $# -gt 0 ]; do @@ -108,6 +110,9 @@ while [ $# -gt 0 ]; do -test-asserts | --test-asserts ) do_asserts="yes" ;; + -no-compare-files | --no-compare-files ) + do_compare="no" + ;; -help | --help | -h | --h | -\? ) usage exit 0 @@ -403,7 +408,7 @@ for Flavor in $Flavors ; do # Test clang if [ "$do_clang" = "yes" ]; then - ############################################################################ + ######################################################################## # Phase 2: Build llvmCore with newly built clang from phase 1. c_compiler=$llvmCore_phase1_installdir/bin/clang cxx_compiler=$llvmCore_phase1_installdir/bin/clang++ @@ -413,7 +418,7 @@ for Flavor in $Flavors ; do build_llvmCore 2 $Flavor \ $llvmCore_phase2_objdir - ############################################################################ + ######################################################################## # Phase 3: Build llvmCore with newly built clang from phase 2. c_compiler=$llvmCore_phase2_installdir/bin/clang cxx_compiler=$llvmCore_phase2_installdir/bin/clang++ @@ -423,21 +428,26 @@ for Flavor in $Flavors ; do build_llvmCore 3 $Flavor \ $llvmCore_phase3_objdir - ############################################################################ + ######################################################################## # Testing: Test phase 3 echo "# Testing - built with clang" test_llvmCore 3 $Flavor $llvmCore_phase3_objdir - ############################################################################ - # Compare .o files between Phase2 and Phase3 and report which ones differ. - echo - echo "# Comparing Phase 2 and Phase 3 files" - for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do - p3=`echo $o | sed -e 's,Phase2,Phase3,'` - if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then - echo "file `basename $o` differs between phase 2 and phase 3" + ######################################################################## + # Compare .o files between Phase2 and Phase3 and report which ones + # differ. + if [ "$do_compare" = "yes" ]; then + if [ "$Flavor" = "Release" -o "$Flavor" = "Release-64" ]; then + echo + echo "# Comparing Phase 2 and Phase 3 files" + for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do + p3=`echo $o | sed -e 's,Phase2,Phase3,'` + if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then + echo "file `basename $o` differs between phase 2 and phase 3" + fi + done fi - done + fi fi # Test dragonegg @@ -450,7 +460,7 @@ for Flavor in $Flavors ; do cxx_compiler="$gxx_compiler" build_dragonegg 1 $Flavor $llvmCore_phase1_installdir $dragonegg_phase1_objdir - ############################################################################ + ######################################################################## # Phase 2: Build llvmCore with newly built dragonegg from phase 1. c_compiler="$gcc_compiler -fplugin=$dragonegg_phase1_objdir/dragonegg.so" cxx_compiler="$gxx_compiler -fplugin=$dragonegg_phase1_objdir/dragonegg.so" @@ -461,7 +471,7 @@ for Flavor in $Flavors ; do $llvmCore_de_phase2_objdir build_dragonegg 2 $Flavor $llvmCore_de_phase2_installdir $dragonegg_phase2_objdir - ############################################################################ + ######################################################################## # Phase 3: Build llvmCore with newly built clang from phase 2. c_compiler="$gcc_compiler -fplugin=$dragonegg_phase2_objdir/dragonegg.so" cxx_compiler="$gxx_compiler -fplugin=$dragonegg_phase2_objdir/dragonegg.so" @@ -472,14 +482,14 @@ for Flavor in $Flavors ; do $llvmCore_de_phase3_objdir build_dragonegg 3 $Flavor $llvmCore_de_phase3_installdir $dragonegg_phase3_objdir - ############################################################################ + ######################################################################## # Testing: Test phase 3 c_compiler="$gcc_compiler -fplugin=$dragonegg_phase3_objdir/dragonegg.so" cxx_compiler="$gxx_compiler -fplugin=$dragonegg_phase3_objdir/dragonegg.so" echo "# Testing - built with dragonegg" test_llvmCore 3 $Flavor $llvmCore_de_phase3_objdir - ############################################################################ + ######################################################################## # Compare .o files between Phase2 and Phase3 and report which ones differ. echo echo "# Comparing Phase 2 and Phase 3 files" -- cgit v1.1 From f1275959b2b6ac5212e8b5547251b0303168b0b1 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 3 Apr 2012 00:47:23 +0000 Subject: Use std::set_union instead of nasty custom code. I just noticed Jakob's examples of the proper application of std::set... routines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153918 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index cdf20ff..609bf54 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -91,21 +91,11 @@ const std::string &CodeGenRegister::getName() const { // Merge two RegUnitLists maintaining the order and removing duplicates. // Overwrites MergedRU in the process. static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, - const CodeGenRegister::RegUnitList &RRU) -{ + const CodeGenRegister::RegUnitList &RRU) { CodeGenRegister::RegUnitList LRU = MergedRU; MergedRU.clear(); - for (CodeGenRegister::RegUnitList::const_iterator - RI = RRU.begin(), RE = RRU.end(), LI = LRU.begin(), LE = LRU.end(); - RI != RE || LI != LE;) { - - CodeGenRegister::RegUnitList::const_iterator &NextI = - (RI != RE && (LI == LE || *RI < *LI)) ? RI : LI; - - if (MergedRU.empty() || *NextI != MergedRU.back()) - MergedRU.push_back(*NextI); - ++NextI; - } + std::set_union(LRU.begin(), LRU.end(), RRU.begin(), RRU.end(), + std::inserter(MergedRU, MergedRU.begin())); } const CodeGenRegister::SubRegMap & -- cgit v1.1 From 5aeda3f07684e555f19813e41b7fc101434cfe64 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 3 Apr 2012 01:35:52 +0000 Subject: Cleanup set_union usage. The same thing but a bit cleaner now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153922 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 609bf54..6784d53 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -95,7 +95,7 @@ static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, CodeGenRegister::RegUnitList LRU = MergedRU; MergedRU.clear(); std::set_union(LRU.begin(), LRU.end(), RRU.begin(), RRU.end(), - std::inserter(MergedRU, MergedRU.begin())); + std::back_inserter(MergedRU)); } const CodeGenRegister::SubRegMap & -- cgit v1.1 From cbece8c2a6c06b3c14e35228b326e629f936c458 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Apr 2012 03:27:43 +0000 Subject: As Eric pointed out, even a Debug build should be equal. Leave the flag that can turn off comparisons though. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153927 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/release/test-release.sh | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'utils') diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh index 7aafc6d..ad1af5f 100755 --- a/utils/release/test-release.sh +++ b/utils/release/test-release.sh @@ -437,16 +437,14 @@ for Flavor in $Flavors ; do # Compare .o files between Phase2 and Phase3 and report which ones # differ. if [ "$do_compare" = "yes" ]; then - if [ "$Flavor" = "Release" -o "$Flavor" = "Release-64" ]; then - echo - echo "# Comparing Phase 2 and Phase 3 files" - for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do - p3=`echo $o | sed -e 's,Phase2,Phase3,'` - if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then - echo "file `basename $o` differs between phase 2 and phase 3" - fi - done - fi + echo + echo "# Comparing Phase 2 and Phase 3 files" + for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do + p3=`echo $o | sed -e 's,Phase2,Phase3,'` + if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then + echo "file `basename $o` differs between phase 2 and phase 3" + fi + done fi fi -- cgit v1.1 From 769bbfd951018f9b36f3d2f0d70a23d81f2d3287 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 3 Apr 2012 05:20:24 +0000 Subject: Add support for AVX enhanced comparison predicates. Patch from Kay Tiong Khoo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153935 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/EDEmitter.cpp | 1 + utils/TableGen/X86RecognizableInstr.cpp | 2 ++ 2 files changed, 3 insertions(+) (limited to 'utils') diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 3eed07c..3809a45 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -287,6 +287,7 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type, IMM("i64i8imm"); IMM("i64i32imm"); IMM("SSECC"); + IMM("AVXCC"); // all R, I, R, I, R MEM("i8mem"); diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 6bbc929..6a01cce 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -1115,6 +1115,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("i16imm_pcrel", TYPE_REL16) TYPE("i32imm_pcrel", TYPE_REL32) TYPE("SSECC", TYPE_IMM3) + TYPE("AVXCC", TYPE_IMM5) TYPE("brtarget", TYPE_RELv) TYPE("uncondbrtarget", TYPE_RELv) TYPE("brtarget8", TYPE_REL8) @@ -1156,6 +1157,7 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString ENCODING("i32i8imm", ENCODING_IB) ENCODING("u32u8imm", ENCODING_IB) ENCODING("SSECC", ENCODING_IB) + ENCODING("AVXCC", ENCODING_IB) ENCODING("i16imm", ENCODING_Iv) ENCODING("i16i8imm", ENCODING_IB) ENCODING("i32imm", ENCODING_Iv) -- cgit v1.1 From 9b1b25f0631b22cd09c2fa7383ce28721fa3e212 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Tue, 3 Apr 2012 06:52:47 +0000 Subject: Tidy up spacing in some tablegen outputs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153937 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 4 ++-- utils/TableGen/RegisterInfoEmitter.cpp | 16 +++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index d3f7f0e..8fdbe89 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -477,7 +477,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { static void emitRegisterNameString(raw_ostream &O, StringRef AltName, - const std::vector &Registers) { + const std::vector &Registers) { SequenceToOffsetTable StringTable; SmallVector AsmNames(Registers.size()); for (unsigned i = 0, e = Registers.size(); i != e; ++i) { @@ -525,7 +525,7 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, O << "\n "; O << StringTable.get(AsmNames[i]) << ", "; } - O << " };\n" + O << "\n };\n" << "\n"; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index a5fe756..0e273bc 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -578,8 +578,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, const std::string &TargetName = Target.getName(); std::string ClassName = TargetName + "GenRegisterInfo"; - OS << "#include \"llvm/Target/TargetRegisterInfo.h\"\n"; - OS << "#include \n\n"; + OS << "#include \"llvm/Target/TargetRegisterInfo.h\"\n\n"; OS << "namespace llvm {\n\n"; @@ -812,19 +811,18 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit extra information about registers. const std::string &TargetName = Target.getName(); - OS << "\n static const TargetRegisterInfoDesc " - << TargetName << "RegInfoDesc[] = " - << "{ // Extra Descriptors\n"; - OS << " { 0, 0 },\n"; + OS << "\nstatic const TargetRegisterInfoDesc " + << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n"; + OS << " { 0, 0 },\n"; const std::vector &Regs = RegBank.getRegisters(); for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister &Reg = *Regs[i]; - OS << " { "; + OS << " { "; OS << Reg.CostPerUse << ", " << int(AllocatableRegs.count(Reg.TheDef)) << " },\n"; } - OS << " };\n"; // End of register descriptors... + OS << "};\n"; // End of register descriptors... // Calculate the mapping of subregister+index pairs to physical registers. @@ -833,7 +831,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit SubRegIndex names, skipping 0 ArrayRef SubRegIndices = RegBank.getSubRegIndices(); - OS << "\n static const char *const " << TargetName + OS << "\nstatic const char *const " << TargetName << "SubRegIndexTable[] = { \""; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { OS << SubRegIndices[i]->getName(); -- cgit v1.1 From ac07407acb53f3c9462141928ab18ec07dab43be Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 3 Apr 2012 21:50:24 +0000 Subject: Remove a reference to the C backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153971 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/build_llvm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 4cf6578..5c4909c 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -117,7 +117,7 @@ elif [ "$IOS_SIM_BUILD" = yes ]; then configure_opts="--enable-targets=x86 --host=i686-apple-darwin_sim \ --build=i686-apple-darwin10" else - configure_opts="--enable-targets=arm,x86,cbe" + configure_opts="--enable-targets=arm,x86" fi if [ \! -f Makefile.config ]; then -- cgit v1.1 From 585d580acb252c048692d9a6a3b705d65bf7e5e2 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 3 Apr 2012 21:50:26 +0000 Subject: When building llvmCore, pass the SDKROOT and -arch setting to configure. So far all of configure tests have been run against the default SDK and architecture, regardless of what is actually being built. We've gotten lucky until now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153972 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/build_llvm | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'utils') diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 5c4909c..41ac667 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -120,11 +120,21 @@ else configure_opts="--enable-targets=arm,x86" fi +if [ "$ARM_HOSTED_BUILD" != yes ]; then + if [ $SDKROOT ]; then + CPPFLAGS="$CPPFLAGS -isysroot $SDKROOT" + fi + for host in $HOSTS; do + CPPFLAGS="$CPPFLAGS -arch $host" + done +fi + if [ \! -f Makefile.config ]; then $SRC_DIR/configure --prefix=$DEST_DIR$DEST_ROOT $configure_opts \ --enable-assertions=$LLVM_ASSERTIONS \ --enable-optimized=$LLVM_OPTIMIZED \ --disable-bindings \ + CPPFLAGS="$CPPFLAGS" \ || exit 1 fi -- cgit v1.1 From 93210e847a1496b24cef881723e57c489082dcfe Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Tue, 3 Apr 2012 23:09:22 +0000 Subject: Add YAML parser to Support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153977 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/yaml-bench/CMakeLists.txt | 5 + utils/yaml-bench/Makefile | 20 ++++ utils/yaml-bench/YAMLBench.cpp | 203 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 utils/yaml-bench/CMakeLists.txt create mode 100644 utils/yaml-bench/Makefile create mode 100644 utils/yaml-bench/YAMLBench.cpp (limited to 'utils') diff --git a/utils/yaml-bench/CMakeLists.txt b/utils/yaml-bench/CMakeLists.txt new file mode 100644 index 0000000..403182c --- /dev/null +++ b/utils/yaml-bench/CMakeLists.txt @@ -0,0 +1,5 @@ +add_llvm_utility(yaml-bench + YAMLBench.cpp + ) + +target_link_libraries(yaml-bench LLVMSupport) diff --git a/utils/yaml-bench/Makefile b/utils/yaml-bench/Makefile new file mode 100644 index 0000000..07e9122 --- /dev/null +++ b/utils/yaml-bench/Makefile @@ -0,0 +1,20 @@ +##===- utils/yaml-bench/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +TOOLNAME = yaml-bench +USEDLIBS = LLVMSupport.a + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +# Don't install this utility +NO_INSTALL = 1 + +include $(LEVEL)/Makefile.common diff --git a/utils/yaml-bench/YAMLBench.cpp b/utils/yaml-bench/YAMLBench.cpp new file mode 100644 index 0000000..e5ee52a --- /dev/null +++ b/utils/yaml-bench/YAMLBench.cpp @@ -0,0 +1,203 @@ +//===- YAMLBench - Benchmark the YAMLParser implementation ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program executes the YAMLParser on differntly sized YAML texts and +// outputs the run time. +// +//===----------------------------------------------------------------------===// + + +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/system_error.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/YAMLParser.h" + +using namespace llvm; + +static cl::opt + DumpTokens( "tokens" + , cl::desc("Print the tokenization of the file.") + , cl::init(false) + ); + +static cl::opt + DumpCanonical( "canonical" + , cl::desc("Print the canonical YAML for this file.") + , cl::init(false) + ); + +static cl::opt + Input(cl::Positional, cl::desc("")); + +static cl::opt + Verify( "verify" + , cl::desc( + "Run a quick verification useful for regression testing") + , cl::init(false) + ); + +static cl::opt + MemoryLimitMB("memory-limit", cl::desc( + "Do not use more megabytes of memory"), + cl::init(1000)); + +struct indent { + unsigned distance; + indent(unsigned d) : distance(d) {} +}; + +static raw_ostream &operator <<(raw_ostream &os, const indent &in) { + for (unsigned i = 0; i < in.distance; ++i) + os << " "; + return os; +} + +static void dumpNode( yaml::Node *n + , unsigned Indent = 0 + , bool SuppressFirstIndent = false) { + if (!n) + return; + if (!SuppressFirstIndent) + outs() << indent(Indent); + StringRef Anchor = n->getAnchor(); + if (!Anchor.empty()) + outs() << "&" << Anchor << " "; + if (yaml::ScalarNode *sn = dyn_cast(n)) { + SmallString<32> Storage; + StringRef Val = sn->getValue(Storage); + outs() << "!!str \"" << yaml::escape(Val) << "\""; + } else if (yaml::SequenceNode *sn = dyn_cast(n)) { + outs() << "!!seq [\n"; + ++Indent; + for (yaml::SequenceNode::iterator i = sn->begin(), e = sn->end(); + i != e; ++i) { + dumpNode(i, Indent); + outs() << ",\n"; + } + --Indent; + outs() << indent(Indent) << "]"; + } else if (yaml::MappingNode *mn = dyn_cast(n)) { + outs() << "!!map {\n"; + ++Indent; + for (yaml::MappingNode::iterator i = mn->begin(), e = mn->end(); + i != e; ++i) { + outs() << indent(Indent) << "? "; + dumpNode(i->getKey(), Indent, true); + outs() << "\n"; + outs() << indent(Indent) << ": "; + dumpNode(i->getValue(), Indent, true); + outs() << ",\n"; + } + --Indent; + outs() << indent(Indent) << "}"; + } else if (yaml::AliasNode *an = dyn_cast(n)){ + outs() << "*" << an->getName(); + } else if (dyn_cast(n)) { + outs() << "!!null null"; + } +} + +static void dumpStream(yaml::Stream &stream) { + for (yaml::document_iterator di = stream.begin(), de = stream.end(); di != de; + ++di) { + outs() << "%YAML 1.2\n" + << "---\n"; + yaml::Node *n = di->getRoot(); + if (n) + dumpNode(n); + else + break; + outs() << "\n...\n"; + } +} + +static void benchmark( llvm::TimerGroup &Group + , llvm::StringRef Name + , llvm::StringRef JSONText) { + llvm::Timer BaseLine((Name + ": Loop").str(), Group); + BaseLine.startTimer(); + char C = 0; + for (llvm::StringRef::iterator I = JSONText.begin(), + E = JSONText.end(); + I != E; ++I) { C += *I; } + BaseLine.stopTimer(); + volatile char DontOptimizeOut = C; (void)DontOptimizeOut; + + llvm::Timer Tokenizing((Name + ": Tokenizing").str(), Group); + Tokenizing.startTimer(); + { + yaml::scanTokens(JSONText); + } + Tokenizing.stopTimer(); + + llvm::Timer Parsing((Name + ": Parsing").str(), Group); + Parsing.startTimer(); + { + llvm::SourceMgr SM; + llvm::yaml::Stream stream(JSONText, SM); + stream.skip(); + } + Parsing.stopTimer(); +} + +static std::string createJSONText(size_t MemoryMB, unsigned ValueSize) { + std::string JSONText; + llvm::raw_string_ostream Stream(JSONText); + Stream << "[\n"; + size_t MemoryBytes = MemoryMB * 1024 * 1024; + while (JSONText.size() < MemoryBytes) { + Stream << " {\n" + << " \"key1\": \"" << std::string(ValueSize, '*') << "\",\n" + << " \"key2\": \"" << std::string(ValueSize, '*') << "\",\n" + << " \"key3\": \"" << std::string(ValueSize, '*') << "\"\n" + << " }"; + Stream.flush(); + if (JSONText.size() < MemoryBytes) Stream << ","; + Stream << "\n"; + } + Stream << "]\n"; + Stream.flush(); + return JSONText; +} + +int main(int argc, char **argv) { + llvm::cl::ParseCommandLineOptions(argc, argv); + if (Input.getNumOccurrences()) { + OwningPtr Buf; + if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) + return 1; + + llvm::SourceMgr sm; + if (DumpTokens) { + yaml::dumpTokens(Buf->getBuffer(), outs()); + } + + if (DumpCanonical) { + yaml::Stream stream(Buf->getBuffer(), sm); + dumpStream(stream); + } + } + + if (Verify) { + llvm::TimerGroup Group("YAML parser benchmark"); + benchmark(Group, "Fast", createJSONText(10, 500)); + } else if (!DumpCanonical && !DumpTokens) { + llvm::TimerGroup Group("YAML parser benchmark"); + benchmark(Group, "Small Values", createJSONText(MemoryLimitMB, 5)); + benchmark(Group, "Medium Values", createJSONText(MemoryLimitMB, 500)); + benchmark(Group, "Large Values", createJSONText(MemoryLimitMB, 50000)); + } + + return 0; +} -- cgit v1.1 From d13af63df7ce87440547e9149fe55337c700328e Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 3 Apr 2012 23:13:26 +0000 Subject: Remove dead code for installing libLTO when building llvmCore. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153978 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/GNUmakefile | 5 +---- utils/buildit/build_llvm | 39 ++++++--------------------------------- 2 files changed, 7 insertions(+), 37 deletions(-) (limited to 'utils') diff --git a/utils/buildit/GNUmakefile b/utils/buildit/GNUmakefile index a362fa6..bdf87d5 100644 --- a/utils/buildit/GNUmakefile +++ b/utils/buildit/GNUmakefile @@ -46,9 +46,6 @@ else LLVM_OPTIMIZED := yes endif -# Default to not install libLTO.dylib. -INSTALL_LIBLTO := no - # Default to do a native build, not a cross-build for an ARM host or simulator. ARM_HOSTED_BUILD := no IOS_SIM_BUILD := no @@ -66,7 +63,7 @@ install: $(OBJROOT) $(SYMROOT) $(DSTROOT) cd $(OBJROOT) && \ $(SRC)/utils/buildit/build_llvm "$(RC_ARCHS)" "$(TARGETS)" \ $(SRC) $(PREFIX) $(DSTROOT) $(SYMROOT) \ - $(ENABLE_ASSERTIONS) $(LLVM_OPTIMIZED) $(INSTALL_LIBLTO) \ + $(ENABLE_ASSERTIONS) $(LLVM_OPTIMIZED) \ $(ARM_HOSTED_BUILD) $(IOS_SIM_BUILD) \ $(RC_ProjectSourceVersion) $(RC_ProjectSourceSubversion) diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 41ac667..d6086c1 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -42,21 +42,17 @@ LLVM_ASSERTIONS="$7" # build. LLVM_OPTIMIZED="$8" -# The ninth parameter is a yes/no that indicates whether libLTO.dylib -# should be installed. -INSTALL_LIBLTO="$9" - # A yes/no parameter that controls whether to cross-build for an ARM host. -ARM_HOSTED_BUILD="${10}" +ARM_HOSTED_BUILD="$9" # A yes/no parameter that controls whether to cross-build for the iOS simulator -IOS_SIM_BUILD="${11}" +IOS_SIM_BUILD="${10}" # The version number of the submission, e.g. 1007. -LLVM_SUBMIT_VERSION="${12}" +LLVM_SUBMIT_VERSION="${11}" # The subversion number of the submission, e.g. 03. -LLVM_SUBMIT_SUBVERSION="${13}" +LLVM_SUBMIT_SUBVERSION="${12}" # The current working directory is where the build will happen. It may already # contain a partial result of an interrupted build, in which case this script @@ -297,34 +293,11 @@ find obj-* -name \*.\[chy\] -o -name \*.cpp -print \ | cpio -pdml $SYM_DIR/src || exit 1 ################################################################################ -# Install and strip libLTO.dylib +# Remove libLTO.dylib and lto.h. Those are installed by clang. cd $DEST_DIR$DEST_ROOT -if [ "$INSTALL_LIBLTO" = "yes" ]; then - DT_HOME="$DEST_DIR/Developer/usr" - mkdir -p $DT_HOME/lib - mv lib/libLTO.dylib $DT_HOME/lib/libLTO.dylib - - # Save a copy of the unstripped dylib - mkdir -p $SYM_DIR/Developer/usr/lib - cp $DT_HOME/lib/libLTO.dylib $SYM_DIR/Developer/usr/lib/libLTO.dylib - - # Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or - # PPC objects! - $STRIP -arch all -Sl $DT_HOME/lib/libLTO.dylib - - if [ "x$DISABLE_USR_LINKS" == "x" ]; then - # Add a symlink in /usr/lib for B&I. - mkdir -p $DEST_DIR/usr/lib/ - (cd $DEST_DIR/usr/lib && \ - ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib) - fi -else - rm -f lib/libLTO.dylib -fi +rm -f lib/libLTO.dylib rm -f lib/libLTO.a lib/libLTO.la - -# Omit lto.h from the result. Clang will supply. find $DEST_DIR$DEST_ROOT -name lto.h -delete ################################################################################ -- cgit v1.1 From a348fecf2fab7bf075b1dfcd02dfa36d16df7659 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 3 Apr 2012 23:44:39 +0000 Subject: Fix the install location for the Embedded makefile target. svn r145378 inadvertently changed the destination for the Embedded target in the makefile. Add a "/Developer" suffix to DSTROOT to compensate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153980 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/buildit/GNUmakefile b/utils/buildit/GNUmakefile index bdf87d5..fc5578a 100644 --- a/utils/buildit/GNUmakefile +++ b/utils/buildit/GNUmakefile @@ -79,7 +79,7 @@ EmbeddedSim: Embedded: ARM_PLATFORM=`xcodebuild -version -sdk iphoneos PlatformPath` && \ - $(MAKE) DSTROOT=$(DSTROOT)$$ARM_PLATFORM install + $(MAKE) DSTROOT=$(DSTROOT)$$ARM_PLATFORM/Developer install # installhdrs does nothing, because the headers aren't useful until # the compiler is installed. -- cgit v1.1 From 58609b741301976a2ea3923f4c6494ba1c7e5439 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 4 Apr 2012 04:55:46 +0000 Subject: Convert assert(false) followed by a return to llvm_unreachable git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153997 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 8fdbe89..e0b0aac 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -669,8 +669,7 @@ static void EmitGetMapOperandNumber(raw_ostream &O) { O << " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n"; O << " if (I->first == Name)\n"; O << " return I->second;\n"; - O << " assert(false && \"Operand not in map!\");\n"; - O << " return 0;\n"; + O << " llvm_unreachable(\"Operand not in map!\");\n"; O << "}\n\n"; } -- cgit v1.1 From 63246de68653ce330c55453cf9a18a306a4d2319 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Thu, 5 Apr 2012 00:35:55 +0000 Subject: Do not include multiple -arch options in CPPFLAGS. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154070 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/build_llvm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'utils') diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index d6086c1..88a26d3 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -120,9 +120,8 @@ if [ "$ARM_HOSTED_BUILD" != yes ]; then if [ $SDKROOT ]; then CPPFLAGS="$CPPFLAGS -isysroot $SDKROOT" fi - for host in $HOSTS; do - CPPFLAGS="$CPPFLAGS -arch $host" - done + for host in $HOSTS; do :; done + CPPFLAGS="$CPPFLAGS -arch $host" fi if [ \! -f Makefile.config ]; then -- cgit v1.1 From aec111a06b595742683b529a7f4391becd7e24ec Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 02:25:18 +0000 Subject: Fix header comment git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154372 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index f73519e..0d26bc4 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -116,8 +116,8 @@ namespace llvm { // List of super-registers in topological order, small to large. typedef std::vector SuperRegList; - // Get the list of super-registers. - // This is only valid after computeDerivedInfo has visited all registers. + // Get the list of super-registers. This is valid after getSubReg + // visits all registers during RegBank construction. const SuperRegList &getSuperRegs() const { assert(SubRegsComplete && "Must precompute sub-registers"); return SuperRegs; -- cgit v1.1 From d35ac3c8bc37ab383b10a04b9c8b1087d6b2bc45 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 02:25:21 +0000 Subject: Added register unit weights to the target description. This is a new algorithm that associates registers with weighted register units to accuretely model their effect on register pressure. This handles registers with multiple overlapping subregisters. It is possible, but almost inconceivable that the algorithm fails to find an exact solution for a target description. If an exact solution cannot be found, an inexact, but reasonable solution will be chosen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154373 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 323 ++++++++++++++++++++++++++++++++++-- utils/TableGen/CodeGenRegisters.h | 48 +++++- 2 files changed, 352 insertions(+), 19 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 6784d53..5939804 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -15,6 +15,7 @@ #include "CodeGenRegisters.h" #include "CodeGenTarget.h" #include "llvm/TableGen/Error.h" +#include "llvm/ADT/IntEqClasses.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -88,6 +89,48 @@ const std::string &CodeGenRegister::getName() const { return TheDef->getName(); } +namespace { +// Iterate over all register units in a set of registers. +class RegUnitIterator { + CodeGenRegister::Set::const_iterator RegI, RegE; + CodeGenRegister::RegUnitList::const_iterator UnitI, UnitE; + +public: + RegUnitIterator(const CodeGenRegister::Set &Regs): + RegI(Regs.begin()), RegE(Regs.end()), UnitI(), UnitE() { + + if (RegI != RegE) { + UnitI = (*RegI)->getRegUnits().begin(); + UnitE = (*RegI)->getRegUnits().end(); + advance(); + } + } + + bool isValid() const { return UnitI != UnitE; } + + unsigned operator* () const { assert(isValid()); return *UnitI; }; + + const CodeGenRegister *getReg() const { assert(isValid()); return *RegI; } + + /// Preincrement. Move to the next unit. + void operator++() { + assert(isValid() && "Cannot advance beyond the last operand"); + ++UnitI; + advance(); + } + +protected: + void advance() { + while (UnitI == UnitE) { + if (++RegI == RegE) + break; + UnitI = (*RegI)->getRegUnits().begin(); + UnitE = (*RegI)->getRegUnits().end(); + } + } +}; +} // namespace + // Merge two RegUnitLists maintaining the order and removing duplicates. // Overwrites MergedRU in the process. static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, @@ -98,6 +141,32 @@ static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU, std::back_inserter(MergedRU)); } +// Return true of this unit appears in RegUnits. +static bool hasRegUnit(CodeGenRegister::RegUnitList &RegUnits, unsigned Unit) { + return std::count(RegUnits.begin(), RegUnits.end(), Unit); +} + +// Inherit register units from subregisters. +// Return true if the RegUnits changed. +bool CodeGenRegister::inheritRegUnits(CodeGenRegBank &RegBank) { + unsigned OldNumUnits = RegUnits.size(); + for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end(); + I != E; ++I) { + // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM. + // Only create a unit if no other subregs have units. + CodeGenRegister *SR = I->second; + if (SR == this) { + // RegUnits are only empty during getSubRegs, prior to computing weight. + if (RegUnits.empty()) + RegUnits.push_back(RegBank.newRegUnit(0)); + continue; + } + // Merge the subregister's units into this register's RegUnits. + mergeRegUnits(RegUnits, SR->RegUnits); + } + return OldNumUnits != RegUnits.size(); +} + const CodeGenRegister::SubRegMap & CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { // Only compute this map once. @@ -248,23 +317,10 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { // aliases. This can be done by iteratively merging units for aliasing // registers using a worklist. assert(RegUnits.empty() && "Should only initialize RegUnits once"); - if (SubRegs.empty()) { - RegUnits.push_back(RegBank.newRegUnit()); - } - else { - for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end(); - I != E; ++I) { - // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM. - CodeGenRegister *SR = I->second; - if (SR == this) { - if (RegUnits.empty()) - RegUnits.push_back(RegBank.newRegUnit()); - continue; - } - // Merge the subregister's units into this register's RegUnits. - mergeRegUnits(RegUnits, SR->RegUnits); - } - } + if (SubRegs.empty()) + RegUnits.push_back(RegBank.newRegUnit(0)); + else + inheritRegUnits(RegBank); return SubRegs; } @@ -281,6 +337,16 @@ CodeGenRegister::addSubRegsPreOrder(SetVector &OSet, } } +// Get the sum of this register's unit weights. +unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const { + unsigned Weight = 0; + for (RegUnitList::const_iterator I = RegUnits.begin(), E = RegUnits.end(); + I != E; ++I) { + Weight += RegBank.getRegUnitWeight(*I); + } + return Weight; +} + //===----------------------------------------------------------------------===// // RegisterTuples //===----------------------------------------------------------------------===// @@ -701,6 +767,10 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { for (unsigned i = 0, e = Registers.size(); i != e; ++i) Registers[i]->getSubRegs(*this); + // Native register units are associated with a leaf register. They've all been + // discovered now. + NumNativeRegUnits = NumRegUnits; + // Read in register class definitions. std::vector RCs = Records.getAllDerivedDefinitions("RegisterClass"); if (RCs.empty()) @@ -833,6 +903,221 @@ void CodeGenRegBank::computeComposites() { SubRegIndices[i]->cleanComposites(); } +namespace { +// UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is +// the transitive closure of the union of overlapping register +// classes. Together, the UberRegSets form a partition of the registers. If we +// consider overlapping register classes to be connected, then each UberRegSet +// is a set of connected components. +// +// An UberRegSet will likely be a horizontal slice of register names of +// the same width. Nontrivial subregisters should then be in a separate +// UberRegSet. But this property isn't required for valid computation of +// register unit weights. +// +// A Weight field caches the max per-register unit weight in each UberRegSet. +// +// A set of SingularDeterminants flags single units of some register in this set +// for which the unit weight equals the set weight. These units should not have +// their weight increased. +struct UberRegSet { + CodeGenRegister::Set Regs; + unsigned Weight; + CodeGenRegister::RegUnitList SingularDeterminants; + + UberRegSet(): Weight(0) {} +}; +} // namespace + +// Partition registers into UberRegSets, where each set is the transitive +// closure of the union of overlapping register classes. +// +// UberRegSets[0] is a special non-allocatable set. +static void computeUberSets(std::vector &UberSets, + std::vector &RegSets, + CodeGenRegBank &RegBank) { + + const std::vector &Registers = RegBank.getRegisters(); + + // The Register EnumValue is one greater than its index into Registers. + assert(Registers.size() == Registers[Registers.size()-1]->EnumValue && + "register enum value mismatch"); + + // For simplicitly make the SetID the same as EnumValue. + IntEqClasses UberSetIDs(Registers.size()+1); + for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) { + CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i]; + const CodeGenRegister::Set &Regs = RegClass->getMembers(); + if (Regs.empty()) continue; + + unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue); + assert(USetID && "register number 0 is invalid"); + + // combine non-allocatable classes + if (!RegClass->Allocatable) { + UberSetIDs.join(0, USetID); + USetID = 0; + } + for (CodeGenRegister::Set::const_iterator I = llvm::next(Regs.begin()), + E = Regs.end(); I != E; ++I) + UberSetIDs.join(USetID, (*I)->EnumValue); + } + UberSetIDs.compress(); + + // Make the first UberSet a special unallocatable set. + unsigned ZeroID = UberSetIDs[0]; + + // Insert Registers into the UberSets formed by union-find. + // Do not resize after this. + UberSets.resize(UberSetIDs.getNumClasses()); + for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + const CodeGenRegister *Reg = Registers[i]; + unsigned USetID = UberSetIDs[Reg->EnumValue]; + if (!USetID) + USetID = ZeroID; + else if (USetID == ZeroID) + USetID = 0; + + UberRegSet *USet = &UberSets[USetID]; + USet->Regs.insert(Reg); + RegSets[i] = USet; + } +} + +// Recompute each UberSet weight after changing unit weights. +static void computeUberWeights(std::vector &UberSets, + CodeGenRegBank &RegBank) { + // Skip the first unallocatable set. + for (std::vector::iterator I = llvm::next(UberSets.begin()), + E = UberSets.end(); I != E; ++I) { + + // Initialize all unit weights in this set, and remember the max units/reg. + const CodeGenRegister *Reg = 0; + unsigned MaxWeight = 0, Weight = 0; + for (RegUnitIterator UnitI(I->Regs); UnitI.isValid(); ++UnitI) { + if (Reg != UnitI.getReg()) { + if (Weight > MaxWeight) + MaxWeight = Weight; + Reg = UnitI.getReg(); + Weight = 0; + } + unsigned UWeight = RegBank.getRegUnitWeight(*UnitI); + if (!UWeight) { + UWeight = 1; + RegBank.increaseRegUnitWeight(*UnitI, UWeight); + } + Weight += UWeight; + } + if (Weight > MaxWeight) + MaxWeight = Weight; + + // Update the set weight. + I->Weight = MaxWeight; + + // Find singular determinants. + for (CodeGenRegister::Set::iterator RegI = I->Regs.begin(), + RegE = I->Regs.end(); RegI != RegE; ++RegI) { + if ((*RegI)->getRegUnits().size() == 1 + && (*RegI)->getWeight(RegBank) == I->Weight) + mergeRegUnits(I->SingularDeterminants, (*RegI)->getRegUnits()); + } + } +} + +// normalizeWeight is a computeRegUnitWeights helper that adjusts the weight of +// a register and its subregisters so that they have the same weight as their +// UberSet. Self-recursion processes the subregister tree in postorder so +// subregisters are normalized first. +// +// Side effects: +// - creates new adopted register units +// - causes superregisters to inherit adopted units +// - increases the weight of "singular" units +// - induces recomputation of UberWeights. +static bool normalizeWeight(CodeGenRegister *Reg, + std::vector &UberSets, + std::vector &RegSets, + CodeGenRegister::RegUnitList &NormalUnits, + CodeGenRegBank &RegBank) { + bool Changed = false; + const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs(); + for (CodeGenRegister::SubRegMap::const_iterator SRI = SRM.begin(), + SRE = SRM.end(); SRI != SRE; ++SRI) { + if (SRI->second == Reg) + continue; // self-cycles happen + + Changed |= + normalizeWeight(SRI->second, UberSets, RegSets, NormalUnits, RegBank); + } + // Postorder register normalization. + + // Inherit register units newly adopted by subregisters. + if (Reg->inheritRegUnits(RegBank)) + computeUberWeights(UberSets, RegBank); + + // Check if this register is too skinny for its UberRegSet. + UberRegSet *UberSet = RegSets[RegBank.getRegIndex(Reg)]; + + unsigned RegWeight = Reg->getWeight(RegBank); + if (UberSet->Weight > RegWeight) { + // A register unit's weight can be adjusted only if it is the singular unit + // for this register, has not been used to normalize a subregister's set, + // and has not already been used to singularly determine this UberRegSet. + unsigned AdjustUnit = Reg->getRegUnits().front(); + if (Reg->getRegUnits().size() != 1 + || hasRegUnit(NormalUnits, AdjustUnit) + || hasRegUnit(UberSet->SingularDeterminants, AdjustUnit)) { + // We don't have an adjustable unit, so adopt a new one. + AdjustUnit = RegBank.newRegUnit(UberSet->Weight - RegWeight); + Reg->adoptRegUnit(AdjustUnit); + // Adopting a unit does not immediately require recomputing set weights. + } + else { + // Adjust the existing single unit. + RegBank.increaseRegUnitWeight(AdjustUnit, UberSet->Weight - RegWeight); + // The unit may be shared among sets and registers within this set. + computeUberWeights(UberSets, RegBank); + } + Changed = true; + } + + // Mark these units normalized so superregisters can't change their weights. + mergeRegUnits(NormalUnits, Reg->getRegUnits()); + + return Changed; +} + +// Compute a weight for each register unit created during getSubRegs. +// +// The goal is that two registers in the same class will have the same weight, +// where each register's weight is defined as sum of its units' weights. +void CodeGenRegBank::computeRegUnitWeights() { + assert(RegUnitWeights.empty() && "Only initialize RegUnitWeights once"); + + // Only allocatable units will be initialized to nonzero weight. + RegUnitWeights.resize(NumRegUnits); + + std::vector UberSets; + std::vector RegSets(Registers.size()); + computeUberSets(UberSets, RegSets, *this); + // UberSets and RegSets are now immutable. + + computeUberWeights(UberSets, *this); + + // Iterate over each Register, normalizing the unit weights until reaching + // a fix point. + unsigned NumIters = 0; + for (bool Changed = true; Changed; ++NumIters) { + assert(NumIters <= NumNativeRegUnits && "Runaway register unit weights"); + Changed = false; + for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + CodeGenRegister::RegUnitList NormalUnits; + Changed |= + normalizeWeight(Registers[i], UberSets, RegSets, NormalUnits, *this); + } + } +} + // Compute sets of overlapping registers. // // The standard set is all super-registers and all sub-registers, but the @@ -909,6 +1194,10 @@ computeOverlaps(std::map &Map) { void CodeGenRegBank::computeDerivedInfo() { computeComposites(); + + // Compute a weight for each register unit created during getSubRegs. + // This may create adopted register units (with unit # >= NumNativeRegUnits). + computeRegUnitWeights(); } // diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 0d26bc4..d22dced 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -130,6 +130,17 @@ namespace llvm { // This is only valid after getSubRegs() completes. const RegUnitList &getRegUnits() const { return RegUnits; } + // Inherit register units from subregisters. + // Return true if the RegUnits changed. + bool inheritRegUnits(CodeGenRegBank &RegBank); + + // Adopt a register unit for pressure tracking. + // A unit is adopted iff its unit number is >= NumNativeRegUnits. + void adoptRegUnit(unsigned RUID) { RegUnits.push_back(RUID); } + + // Get the sum of this register's register unit weights. + unsigned getWeight(const CodeGenRegBank &RegBank) const; + // Order CodeGenRegister pointers by EnumValue. struct Less { bool operator()(const CodeGenRegister *A, @@ -315,7 +326,12 @@ namespace llvm { // Registers. std::vector Registers; DenseMap Def2Reg; - unsigned NumRegUnits; + unsigned NumNativeRegUnits; + unsigned NumRegUnits; // # native + adopted register units. + + // Map each register unit to a weight (for register pressure). + // Includes native and adopted register units. + std::vector RegUnitWeights; // Register classes. std::vector RegClasses; @@ -338,6 +354,9 @@ namespace llvm { void inferMatchingSuperRegClass(CodeGenRegisterClass *RC, unsigned FirstSubRegRC = 0); + // Compute a weight for each register unit created during getSubRegs. + void computeRegUnitWeights(); + // Populate the Composite map from sub-register relationships. void computeComposites(); @@ -364,7 +383,24 @@ namespace llvm { // Find a register from its Record def. CodeGenRegister *getReg(Record*); - unsigned newRegUnit() { return NumRegUnits++; } + // Get a Register's index into the Registers array. + unsigned getRegIndex(const CodeGenRegister *Reg) const { + return Reg->EnumValue - 1; + } + + // Create a new non-native register unit that can be adopted by a register + // to increase its pressure. Note that NumNativeRegUnits is not increased. + unsigned newRegUnit(unsigned Weight) { + if (!RegUnitWeights.empty()) { + RegUnitWeights.resize(NumRegUnits+1); + RegUnitWeights[NumRegUnits] = Weight; + } + return NumRegUnits++; + } + + bool isNativeUnit(unsigned RUID) { + return RUID < NumNativeRegUnits; + } ArrayRef getRegClasses() const { return RegClasses; @@ -380,6 +416,14 @@ namespace llvm { /// return the superclass. Otherwise return null. const CodeGenRegisterClass* getRegClassForRegister(Record *R); + unsigned getRegUnitWeight(unsigned RUID) const { + return RegUnitWeights[RUID]; + } + + void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { + RegUnitWeights[RUID] += Inc; + } + // Computed derived records such as missing sub-register indices. void computeDerivedInfo(); -- cgit v1.1 From 176194d4ee2774bc135ababc5bd6c6c9f606b2a5 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 02:25:24 +0000 Subject: Added register unit sets to the target description. This is a new algorithm that finds sets of register units that can be used to model registers pressure. This handles arbitrary, overlapping register classes. Each register class is associated with a (small) list of pressure sets. These are the dimensions of pressure affected by the register class's liveness. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154374 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 167 +++++++++++++++++++++++++++++++++ utils/TableGen/CodeGenRegisters.h | 46 +++++++++ utils/TableGen/RegisterInfoEmitter.cpp | 76 +++++++++++++++ utils/TableGen/RegisterInfoEmitter.h | 3 + 4 files changed, 292 insertions(+) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 5939804..fc5c780 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1118,6 +1118,169 @@ void CodeGenRegBank::computeRegUnitWeights() { } } +// Find a set in UniqueSets with the same elements as Set. +// Return an iterator into UniqueSets. +static std::vector::const_iterator +findRegUnitSet(const std::vector &UniqueSets, + const RegUnitSet &Set) { + std::vector::const_iterator + I = UniqueSets.begin(), E = UniqueSets.end(); + for(;I != E; ++I) { + if (I->Units == Set.Units) + break; + } + return I; +} + +// Return true if the RUSubSet is a subset of RUSuperSet. +static bool isRegUnitSubSet(const std::vector &RUSubSet, + const std::vector &RUSuperSet) { + for (RegUnitSet::iterator SubIdx = RUSubSet.begin(), EndIdx = RUSubSet.end(), + SearchIdx = RUSuperSet.begin(), SearchEnd = RUSuperSet.end(); + SubIdx != EndIdx; ++SubIdx) { + SearchIdx = find(SearchIdx, SearchEnd, *SubIdx); + if (SearchIdx == SearchEnd) + return false; + ++SearchIdx; + } + return true; +} + +// Iteratively prune unit sets. +void CodeGenRegBank::pruneUnitSets() { + assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets"); + + // Form an equivalence class of UnitSets with no significant difference. + IntEqClasses RepUnitSetIDs(RegUnitSets.size()); + for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size(); + SubIdx != EndIdx; ++SubIdx) { + const RegUnitSet &SubSet = RegUnitSets[SubIdx]; + for (unsigned SuperIdx = 0; SuperIdx != EndIdx; ++SuperIdx) { + if (SuperIdx == SubIdx) + continue; + + const RegUnitSet &SuperSet = RegUnitSets[SuperIdx]; + if (isRegUnitSubSet(SubSet.Units, SuperSet.Units) + && (SubSet.Units.size() + 3 > SuperSet.Units.size())) { + RepUnitSetIDs.join(SubIdx, SuperIdx); + } + } + } + RepUnitSetIDs.compress(); + + // Populate PrunedUnitSets with each equivalence class's superset. + std::vector PrunedUnitSets(RepUnitSetIDs.getNumClasses()); + for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) { + RegUnitSet &SuperSet = PrunedUnitSets[RepUnitSetIDs[i]]; + if (SuperSet.Units.size() < RegUnitSets[i].Units.size()) + SuperSet = RegUnitSets[i]; + } + RegUnitSets.swap(PrunedUnitSets); +} + +// Create a RegUnitSet for each RegClass that contains all units in the class +// including adopted units that are necessary to model register pressure. Then +// iteratively compute RegUnitSets such that the union of any two overlapping +// RegUnitSets is repreresented. +// +// RegisterInfoEmitter will map each RegClass to its RegUnitClass and any +// RegUnitSet that is a superset of that RegUnitClass. +void CodeGenRegBank::computeRegUnitSets() { + + // Compute a unique RegUnitSet for each RegClass. + const ArrayRef &RegClasses = getRegClasses(); + unsigned NumRegClasses = RegClasses.size(); + for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { + + // Compute a sorted list of units in this class. + std::vector RegUnits; + const CodeGenRegister::Set &Regs = RegClasses[RCIdx]->getMembers(); + for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) + RegUnits.push_back(*UnitI); + std::sort(RegUnits.begin(), RegUnits.end()); + + // Speculatively grow the RegUnitSets to hold the new set. + RegUnitSets.resize(RegUnitSets.size() + 1); + RegUnitSets.back().Name = RegClasses[RCIdx]->getName(); + std::unique_copy(RegUnits.begin(), RegUnits.end(), + std::back_inserter(RegUnitSets.back().Units)); + + // Find an existing RegUnitSet. + std::vector::const_iterator SetI = + findRegUnitSet(RegUnitSets, RegUnitSets.back()); + if (SetI != llvm::prior(RegUnitSets.end())) + RegUnitSets.pop_back(); + } + + // Iteratively prune unit sets. + pruneUnitSets(); + + // Iterate over all unit sets, including new ones added by this loop. + unsigned NumRegUnitSubSets = RegUnitSets.size(); + for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) { + // In theory, this is combinatorial. In practice, it needs to be bounded + // by a small number of sets for regpressure to be efficient. + // If the assert is hit, we need to implement pruning. + assert(Idx < (2*NumRegUnitSubSets) && "runaway unit set inference"); + + // Compare new sets with all original classes. + for (unsigned SearchIdx = (SearchIdx >= NumRegUnitSubSets) ? 0 : Idx+1; + SearchIdx != EndIdx; ++SearchIdx) { + std::set Intersection; + std::set_intersection(RegUnitSets[Idx].Units.begin(), + RegUnitSets[Idx].Units.end(), + RegUnitSets[SearchIdx].Units.begin(), + RegUnitSets[SearchIdx].Units.end(), + std::inserter(Intersection, Intersection.begin())); + if (Intersection.empty()) + continue; + + // Speculatively grow the RegUnitSets to hold the new set. + RegUnitSets.resize(RegUnitSets.size() + 1); + RegUnitSets.back().Name = + RegUnitSets[Idx].Name + "+" + RegUnitSets[SearchIdx].Name; + + std::set_union(RegUnitSets[Idx].Units.begin(), + RegUnitSets[Idx].Units.end(), + RegUnitSets[SearchIdx].Units.begin(), + RegUnitSets[SearchIdx].Units.end(), + std::inserter(RegUnitSets.back().Units, + RegUnitSets.back().Units.begin())); + + // Find an existing RegUnitSet, or add the union to the unique sets. + std::vector::const_iterator SetI = + findRegUnitSet(RegUnitSets, RegUnitSets.back()); + if (SetI != llvm::prior(RegUnitSets.end())) + RegUnitSets.pop_back(); + } + } + + // Iteratively prune unit sets again after inferring supersets. + pruneUnitSets(); + + // For each register class, list the UnitSets that are supersets. + RegClassUnitSets.resize(NumRegClasses); + for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { + // Recompute the sorted list of units in this class. + std::vector RegUnits; + const CodeGenRegister::Set &Regs = RegClasses[RCIdx]->getMembers(); + for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) + RegUnits.push_back(*UnitI); + std::sort(RegUnits.begin(), RegUnits.end()); + + // Don't increase pressure for unallocatable regclasses. + if (RegUnits.empty()) + continue; + + // Find all supersets. + for (unsigned USIdx = 0, USEnd = RegUnitSets.size(); + USIdx != USEnd; ++USIdx) { + if (isRegUnitSubSet(RegUnits, RegUnitSets[USIdx].Units)) + RegClassUnitSets[RCIdx].push_back(USIdx); + } + } +} + // Compute sets of overlapping registers. // // The standard set is all super-registers and all sub-registers, but the @@ -1198,6 +1361,10 @@ void CodeGenRegBank::computeDerivedInfo() { // Compute a weight for each register unit created during getSubRegs. // This may create adopted register units (with unit # >= NumNativeRegUnits). computeRegUnitWeights(); + + // Compute a unique set of RegUnitSets. One for each RegClass and inferred + // supersets for the union of overlapping sets. + computeRegUnitSets(); } // diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index d22dced..4b45467 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -188,6 +188,7 @@ namespace llvm { // DenseMap > SuperRegClasses; + public: unsigned EnumValue; std::string Namespace; @@ -312,6 +313,14 @@ namespace llvm { static void computeSubClasses(CodeGenRegBank&); }; + // Each RegUnitSet is a sorted vector with a name. + struct RegUnitSet { + typedef std::vector::const_iterator iterator; + + std::string Name; + std::vector Units; + }; + // CodeGenRegBank - Represent a target's registers and the relations between // them. class CodeGenRegBank { @@ -339,6 +348,15 @@ namespace llvm { typedef std::map RCKeyMap; RCKeyMap Key2RC; + // Remember each unique set of register units. Initially, this contains a + // unique set for each register class. Simliar sets are coalesced with + // pruneUnitSets and new supersets are inferred during computeRegUnitSets. + std::vector RegUnitSets; + + // Map RegisterClass index to the index of the RegUnitSet that contains the + // class's units and any inferred RegUnit supersets. + std::vector > RegClassUnitSets; + // Add RC to *2RC maps. void addToMaps(CodeGenRegisterClass*); @@ -354,9 +372,15 @@ namespace llvm { void inferMatchingSuperRegClass(CodeGenRegisterClass *RC, unsigned FirstSubRegRC = 0); + // Iteratively prune unit sets. + void pruneUnitSets(); + // Compute a weight for each register unit created during getSubRegs. void computeRegUnitWeights(); + // Create a RegUnitSet for each RegClass and infer superclasses. + void computeRegUnitSets(); + // Populate the Composite map from sub-register relationships. void computeComposites(); @@ -392,12 +416,16 @@ namespace llvm { // to increase its pressure. Note that NumNativeRegUnits is not increased. unsigned newRegUnit(unsigned Weight) { if (!RegUnitWeights.empty()) { + assert(Weight && "should only add allocatable units"); RegUnitWeights.resize(NumRegUnits+1); RegUnitWeights[NumRegUnits] = Weight; } return NumRegUnits++; } + // Native units are the singular unit of a leaf register. Register aliasing + // is completely characterized by native units. Adopted units exist to give + // register additional weight but don't affect aliasing. bool isNativeUnit(unsigned RUID) { return RUID < NumNativeRegUnits; } @@ -416,14 +444,32 @@ namespace llvm { /// return the superclass. Otherwise return null. const CodeGenRegisterClass* getRegClassForRegister(Record *R); + // Get a register unit's weight. Zero for unallocatable registers. unsigned getRegUnitWeight(unsigned RUID) const { return RegUnitWeights[RUID]; } + // Increase a RegUnitWeight. void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { RegUnitWeights[RUID] += Inc; } + // Get the number of register pressure dimensions. + unsigned getNumRegPressureSets() const { return RegUnitSets.size(); } + + // Get a set of register unit IDs for a given dimension of pressure. + RegUnitSet getRegPressureSet(unsigned Idx) const { + return RegUnitSets[Idx]; + } + + // Get a list of pressure set IDs for a register class. Liveness of a + // register in this class impacts each pressure set in this list by the + // weight of the register. An exact solution requires all registers in a + // class to have the same class, but it is not strictly guaranteed. + ArrayRef getRCPressureSetIDs(unsigned RCIdx) const { + return RegClassUnitSets[RCIdx]; + } + // Computed derived records such as missing sub-register indices. void computeDerivedInfo(); diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 0e273bc..ac89e25 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -118,6 +118,75 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, OS << "#endif // GET_REGINFO_ENUM\n\n"; } +void RegisterInfoEmitter:: +EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, + const std::string &ClassName) { + unsigned NumRCs = RegBank.getRegClasses().size(); + unsigned NumSets = RegBank.getNumRegPressureSets(); + + OS << "/// Get the weight in units of pressure for this register class.\n" + << "unsigned " << ClassName << "::\n" + << "getRegClassWeight(const TargetRegisterClass *RC) const {\n" + << " static const unsigned RCWeightTable[] = {\n"; + for (unsigned i = 0, e = NumRCs; i != e; ++i) { + const CodeGenRegisterClass &RC = *RegBank.getRegClasses()[i]; + const CodeGenRegister::Set &Regs = RC.getMembers(); + if (Regs.empty()) + OS << " 0"; + else + OS << " " << (*Regs.begin())->getWeight(RegBank); + OS << ", \t// " << RC.getName() << "\n"; + } + OS << " 0 };\n" + << " return RCWeightTable[RC->getID()];\n" + << "}\n\n"; + + OS << "\n" + << "// Get the number of dimensions of register pressure.\n" + << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n" + << " return " << NumSets << ";\n}\n\n"; + + OS << "// Get the register unit pressure limit for this dimension.\n" + << "// This limit must be adjusted dynamically for reserved registers.\n" + << "unsigned " << ClassName << "::\n" + << "getRegPressureSetLimit(unsigned Idx) const {\n" + << " static const unsigned PressureLimitTable[] = {\n"; + for (unsigned i = 0; i < NumSets; ++i ) { + OS << " " << RegBank.getRegPressureSet(i).Units.size() + << ", \t// " << i << ": " << RegBank.getRegPressureSet(i).Name << "\n"; + } + OS << " 0 };\n" + << " return PressureLimitTable[Idx];\n" + << "}\n\n"; + + OS << "/// Get the dimensions of register pressure " + << "impacted by this register class.\n" + << "/// Returns a -1 terminated array of pressure set IDs\n" + << "const int* " << ClassName << "::\n" + << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n" + << " static const int RCSetsTable[] = {\n "; + std::vector RCSetStarts(NumRCs); + for (unsigned i = 0, StartIdx = 0, e = NumRCs; i != e; ++i) { + RCSetStarts[i] = StartIdx; + ArrayRef PSetIDs = RegBank.getRCPressureSetIDs(i); + for (ArrayRef::iterator PSetI = PSetIDs.begin(), + PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) { + OS << *PSetI << ", "; + ++StartIdx; + } + OS << "-1, \t// " << RegBank.getRegClasses()[i]->getName() << "\n "; + ++StartIdx; + } + OS << "-1 };\n"; + OS << " static const unsigned RCSetStartTable[] = {\n "; + for (unsigned i = 0, e = NumRCs; i != e; ++i) { + OS << RCSetStarts[i] << ","; + } + OS << "0 };\n" + << " unsigned SetListStart = RCSetStartTable[RC->getID()];\n" + << " return &RCSetsTable[SetListStart];\n" + << "}\n\n"; +} void RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, @@ -593,6 +662,11 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, << " const TargetRegisterClass *getMatchingSuperRegClass(" "const TargetRegisterClass*, const TargetRegisterClass*, " "unsigned) const;\n" + << " unsigned getRegClassWeight(const TargetRegisterClass *RC) const;\n" + << " unsigned getNumRegPressureSets() const;\n" + << " unsigned getRegPressureSetLimit(unsigned Idx) const;\n" + << " const int *getRegClassPressureSets(" + << "const TargetRegisterClass *RC) const;\n" << "};\n\n"; ArrayRef RegisterClasses = RegBank.getRegClasses(); @@ -961,6 +1035,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << "}\n\n"; + EmitRegUnitPressure(OS, RegBank, ClassName); + // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h index 2e6b64a..ee9903c 100644 --- a/utils/TableGen/RegisterInfoEmitter.h +++ b/utils/TableGen/RegisterInfoEmitter.h @@ -54,6 +54,9 @@ private: const std::vector &Regs, bool isCtor); void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); + + void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, + const std::string &ClassName); }; } // End llvm namespace -- cgit v1.1 From c72e08b4a95e494d3bfdf1262ea8b28f614ac40e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 03:12:29 +0000 Subject: Use std::includes instead of my own implementation. Jakob's review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154377 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index fc5c780..bd1eefe 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1135,15 +1135,8 @@ findRegUnitSet(const std::vector &UniqueSets, // Return true if the RUSubSet is a subset of RUSuperSet. static bool isRegUnitSubSet(const std::vector &RUSubSet, const std::vector &RUSuperSet) { - for (RegUnitSet::iterator SubIdx = RUSubSet.begin(), EndIdx = RUSubSet.end(), - SearchIdx = RUSuperSet.begin(), SearchEnd = RUSuperSet.end(); - SubIdx != EndIdx; ++SubIdx) { - SearchIdx = find(SearchIdx, SearchEnd, *SubIdx); - if (SearchIdx == SearchEnd) - return false; - ++SearchIdx; - } - return true; + return std::includes(RUSuperSet.begin(), RUSuperSet.end(), + RUSubSet.begin(), RUSubSet.end()); } // Iteratively prune unit sets. -- cgit v1.1 From 0fb0678106c490b38343487ab121461f635875a0 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 03:36:49 +0000 Subject: Fix for register pressure tables. Recent refactoring introduced a bug. Fix: added buildRegUnitSets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154382 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index bd1eefe..f071749 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1118,6 +1118,17 @@ void CodeGenRegBank::computeRegUnitWeights() { } } +// Populate a unique sorted list of units from a register set. +static void buildRegUnitSet(const CodeGenRegister::Set &Regs, + std::vector &RegUnits) { + std::vector TmpUnits; + for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) + TmpUnits.push_back(*UnitI); + std::sort(TmpUnits.begin(), TmpUnits.end()); + std::unique_copy(TmpUnits.begin(), TmpUnits.end(), + std::back_inserter(RegUnits)); +} + // Find a set in UniqueSets with the same elements as Set. // Return an iterator into UniqueSets. static std::vector::const_iterator @@ -1185,18 +1196,12 @@ void CodeGenRegBank::computeRegUnitSets() { unsigned NumRegClasses = RegClasses.size(); for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { - // Compute a sorted list of units in this class. - std::vector RegUnits; - const CodeGenRegister::Set &Regs = RegClasses[RCIdx]->getMembers(); - for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) - RegUnits.push_back(*UnitI); - std::sort(RegUnits.begin(), RegUnits.end()); - // Speculatively grow the RegUnitSets to hold the new set. RegUnitSets.resize(RegUnitSets.size() + 1); RegUnitSets.back().Name = RegClasses[RCIdx]->getName(); - std::unique_copy(RegUnits.begin(), RegUnits.end(), - std::back_inserter(RegUnitSets.back().Units)); + + // Compute a sorted list of units in this class. + buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnitSets.back().Units); // Find an existing RegUnitSet. std::vector::const_iterator SetI = @@ -1256,10 +1261,7 @@ void CodeGenRegBank::computeRegUnitSets() { for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { // Recompute the sorted list of units in this class. std::vector RegUnits; - const CodeGenRegister::Set &Regs = RegClasses[RCIdx]->getMembers(); - for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) - RegUnits.push_back(*UnitI); - std::sort(RegUnits.begin(), RegUnits.end()); + buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnits); // Don't increase pressure for unallocatable regclasses. if (RegUnits.empty()) -- cgit v1.1 From 4b745588c935a99cd3fcc574bc6e4934c2e85397 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Tue, 10 Apr 2012 23:53:32 +0000 Subject: TableGen/reginfo potential bug: typo from previous checkin. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154452 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index f071749..920d56f 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1222,7 +1222,7 @@ void CodeGenRegBank::computeRegUnitSets() { assert(Idx < (2*NumRegUnitSubSets) && "runaway unit set inference"); // Compare new sets with all original classes. - for (unsigned SearchIdx = (SearchIdx >= NumRegUnitSubSets) ? 0 : Idx+1; + for (unsigned SearchIdx = (Idx >= NumRegUnitSubSets) ? 0 : Idx+1; SearchIdx != EndIdx; ++SearchIdx) { std::set Intersection; std::set_intersection(RegUnitSets[Idx].Units.begin(), -- cgit v1.1 From aa744e2c44b530fc2f7b266fb61f22976cb4ea0f Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 11 Apr 2012 03:19:15 +0000 Subject: Table-generated register pressure fixes. Handle mixing allocatable and unallocatable register gracefully. Simplify the pruning of register unit sets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154474 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 71 ++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 24 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 920d56f..b59a45e 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -945,22 +945,34 @@ static void computeUberSets(std::vector &UberSets, // For simplicitly make the SetID the same as EnumValue. IntEqClasses UberSetIDs(Registers.size()+1); + std::set AllocatableRegs; for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) { + CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i]; + if (!RegClass->Allocatable) + continue; + const CodeGenRegister::Set &Regs = RegClass->getMembers(); - if (Regs.empty()) continue; + if (Regs.empty()) + continue; unsigned USetID = UberSetIDs.findLeader((*Regs.begin())->EnumValue); assert(USetID && "register number 0 is invalid"); - // combine non-allocatable classes - if (!RegClass->Allocatable) { - UberSetIDs.join(0, USetID); - USetID = 0; - } + AllocatableRegs.insert((*Regs.begin())->EnumValue); for (CodeGenRegister::Set::const_iterator I = llvm::next(Regs.begin()), - E = Regs.end(); I != E; ++I) + E = Regs.end(); I != E; ++I) { + AllocatableRegs.insert((*I)->EnumValue); UberSetIDs.join(USetID, (*I)->EnumValue); + } + } + // Combine non-allocatable regs. + for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + unsigned RegNum = Registers[i]->EnumValue; + if (AllocatableRegs.count(RegNum)) + continue; + + UberSetIDs.join(0, RegNum); } UberSetIDs.compress(); @@ -1155,29 +1167,34 @@ void CodeGenRegBank::pruneUnitSets() { assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets"); // Form an equivalence class of UnitSets with no significant difference. - IntEqClasses RepUnitSetIDs(RegUnitSets.size()); + // Populate PrunedUnitSets with each equivalence class's superset. + std::vector PrunedUnitSets; for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size(); SubIdx != EndIdx; ++SubIdx) { const RegUnitSet &SubSet = RegUnitSets[SubIdx]; - for (unsigned SuperIdx = 0; SuperIdx != EndIdx; ++SuperIdx) { + unsigned SuperIdx = 0; + for (; SuperIdx != EndIdx; ++SuperIdx) { if (SuperIdx == SubIdx) continue; - - const RegUnitSet &SuperSet = RegUnitSets[SuperIdx]; - if (isRegUnitSubSet(SubSet.Units, SuperSet.Units) - && (SubSet.Units.size() + 3 > SuperSet.Units.size())) { - RepUnitSetIDs.join(SubIdx, SuperIdx); + const RegUnitSet *SuperSet = 0; + if (SuperIdx > SubIdx) + SuperSet = &RegUnitSets[SuperIdx]; + else { + // Compare with already-pruned sets. + if (SuperIdx >= PrunedUnitSets.size()) + continue; + SuperSet = &PrunedUnitSets[SuperIdx]; + } + if (isRegUnitSubSet(SubSet.Units, SuperSet->Units) + && (SubSet.Units.size() + 3 > SuperSet->Units.size())) { + break; } } - } - RepUnitSetIDs.compress(); - - // Populate PrunedUnitSets with each equivalence class's superset. - std::vector PrunedUnitSets(RepUnitSetIDs.getNumClasses()); - for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) { - RegUnitSet &SuperSet = PrunedUnitSets[RepUnitSetIDs[i]]; - if (SuperSet.Units.size() < RegUnitSets[i].Units.size()) - SuperSet = RegUnitSets[i]; + if (SuperIdx != EndIdx) + continue; + PrunedUnitSets.resize(PrunedUnitSets.size()+1); + PrunedUnitSets.back().Name = RegUnitSets[SubIdx].Name; + PrunedUnitSets.back().Units.swap(RegUnitSets[SubIdx].Units); } RegUnitSets.swap(PrunedUnitSets); } @@ -1195,6 +1212,8 @@ void CodeGenRegBank::computeRegUnitSets() { const ArrayRef &RegClasses = getRegClasses(); unsigned NumRegClasses = RegClasses.size(); for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { + if (!RegClasses[RCIdx]->Allocatable) + continue; // Speculatively grow the RegUnitSets to hold the new set. RegUnitSets.resize(RegUnitSets.size() + 1); @@ -1253,12 +1272,15 @@ void CodeGenRegBank::computeRegUnitSets() { } } - // Iteratively prune unit sets again after inferring supersets. + // Iteratively prune unit sets after inferring supersets. pruneUnitSets(); // For each register class, list the UnitSets that are supersets. RegClassUnitSets.resize(NumRegClasses); for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { + if (!RegClasses[RCIdx]->Allocatable) + continue; + // Recompute the sorted list of units in this class. std::vector RegUnits; buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnits); @@ -1273,6 +1295,7 @@ void CodeGenRegBank::computeRegUnitSets() { if (isRegUnitSubSet(RegUnits, RegUnitSets[USIdx].Units)) RegClassUnitSets[RCIdx].push_back(USIdx); } + assert(!RegClassUnitSets[RCIdx].empty() && "missing unit set for regclass"); } } -- cgit v1.1 From 680363b5fdf7ce6e188d4c8c7508fc819061ba6d Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 11 Apr 2012 04:31:33 +0000 Subject: Tablegen'd regpressure: emit the weighted pressure limit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154477 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index ac89e25..8085955 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -152,7 +152,13 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << "getRegPressureSetLimit(unsigned Idx) const {\n" << " static const unsigned PressureLimitTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { - OS << " " << RegBank.getRegPressureSet(i).Units.size() + const RegUnitSet &RegUnits = RegBank.getRegPressureSet(i); + unsigned Weight = 0; + for (RegUnitSet::iterator + I = RegUnits.Units.begin(), E = RegUnits.Units.end(); I != E; ++I) { + Weight += RegBank.getRegUnitWeight(*I); + } + OS << " " << Weight << ", \t// " << i << ": " << RegBank.getRegPressureSet(i).Name << "\n"; } OS << " 0 };\n" -- cgit v1.1 From 5c1761d486deb47648fa1b854692f4b64a35f0e2 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 11 Apr 2012 17:35:26 +0000 Subject: TableGen'd regpressure: register unit set pruning. The pruning is more complete if it is not done incrementally. The code is also a tad less convluted. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154510 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index b59a45e..33d0f80 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1167,8 +1167,7 @@ void CodeGenRegBank::pruneUnitSets() { assert(RegClassUnitSets.empty() && "this invalidates RegClassUnitSets"); // Form an equivalence class of UnitSets with no significant difference. - // Populate PrunedUnitSets with each equivalence class's superset. - std::vector PrunedUnitSets; + std::vector SuperSetIDs; for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size(); SubIdx != EndIdx; ++SubIdx) { const RegUnitSet &SubSet = RegUnitSets[SubIdx]; @@ -1176,25 +1175,22 @@ void CodeGenRegBank::pruneUnitSets() { for (; SuperIdx != EndIdx; ++SuperIdx) { if (SuperIdx == SubIdx) continue; - const RegUnitSet *SuperSet = 0; - if (SuperIdx > SubIdx) - SuperSet = &RegUnitSets[SuperIdx]; - else { - // Compare with already-pruned sets. - if (SuperIdx >= PrunedUnitSets.size()) - continue; - SuperSet = &PrunedUnitSets[SuperIdx]; - } - if (isRegUnitSubSet(SubSet.Units, SuperSet->Units) - && (SubSet.Units.size() + 3 > SuperSet->Units.size())) { + + const RegUnitSet &SuperSet = RegUnitSets[SuperIdx]; + if (isRegUnitSubSet(SubSet.Units, SuperSet.Units) + && (SubSet.Units.size() + 3 > SuperSet.Units.size())) { break; } } - if (SuperIdx != EndIdx) - continue; - PrunedUnitSets.resize(PrunedUnitSets.size()+1); - PrunedUnitSets.back().Name = RegUnitSets[SubIdx].Name; - PrunedUnitSets.back().Units.swap(RegUnitSets[SubIdx].Units); + if (SuperIdx == EndIdx) + SuperSetIDs.push_back(SubIdx); + } + // Populate PrunedUnitSets with each equivalence class's superset. + std::vector PrunedUnitSets(SuperSetIDs.size()); + for (unsigned i = 0, e = SuperSetIDs.size(); i != e; ++i) { + unsigned SuperIdx = SuperSetIDs[i]; + PrunedUnitSets[i].Name = RegUnitSets[SuperIdx].Name; + PrunedUnitSets[i].Units.swap(RegUnitSets[SuperIdx].Units); } RegUnitSets.swap(PrunedUnitSets); } -- cgit v1.1 From ec14cd7ddc66d47cd7927f18d8c11844c400367e Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 11 Apr 2012 18:16:28 +0000 Subject: TableGen's regpressure: emit per-registerclass weight limits. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154518 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 25 ++++++++++++------------- utils/TableGen/CodeGenRegisters.h | 12 ++++++++++++ utils/TableGen/RegisterInfoEmitter.cpp | 28 ++++++++++++++-------------- 3 files changed, 38 insertions(+), 27 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 33d0f80..7ce4f87 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -722,6 +722,16 @@ CodeGenRegisterClass::getSuperRegClasses(CodeGenSubRegIndex *SubIdx, Out.set((*I)->EnumValue); } +// Populate a unique sorted list of units from a register set. +void CodeGenRegisterClass::buildRegUnitSet( + std::vector &RegUnits) const { + std::vector TmpUnits; + for (RegUnitIterator UnitI(Members); UnitI.isValid(); ++UnitI) + TmpUnits.push_back(*UnitI); + std::sort(TmpUnits.begin(), TmpUnits.end()); + std::unique_copy(TmpUnits.begin(), TmpUnits.end(), + std::back_inserter(RegUnits)); +} //===----------------------------------------------------------------------===// // CodeGenRegBank @@ -1130,17 +1140,6 @@ void CodeGenRegBank::computeRegUnitWeights() { } } -// Populate a unique sorted list of units from a register set. -static void buildRegUnitSet(const CodeGenRegister::Set &Regs, - std::vector &RegUnits) { - std::vector TmpUnits; - for (RegUnitIterator UnitI(Regs); UnitI.isValid(); ++UnitI) - TmpUnits.push_back(*UnitI); - std::sort(TmpUnits.begin(), TmpUnits.end()); - std::unique_copy(TmpUnits.begin(), TmpUnits.end(), - std::back_inserter(RegUnits)); -} - // Find a set in UniqueSets with the same elements as Set. // Return an iterator into UniqueSets. static std::vector::const_iterator @@ -1216,7 +1215,7 @@ void CodeGenRegBank::computeRegUnitSets() { RegUnitSets.back().Name = RegClasses[RCIdx]->getName(); // Compute a sorted list of units in this class. - buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnitSets.back().Units); + RegClasses[RCIdx]->buildRegUnitSet(RegUnitSets.back().Units); // Find an existing RegUnitSet. std::vector::const_iterator SetI = @@ -1279,7 +1278,7 @@ void CodeGenRegBank::computeRegUnitSets() { // Recompute the sorted list of units in this class. std::vector RegUnits; - buildRegUnitSet(RegClasses[RCIdx]->getMembers(), RegUnits); + RegClasses[RCIdx]->buildRegUnitSet(RegUnits); // Don't increase pressure for unallocatable regclasses. if (RegUnits.empty()) diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 4b45467..232a6e7 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -279,6 +279,9 @@ namespace llvm { // getOrder(0). const CodeGenRegister::Set &getMembers() const { return Members; } + // Populate a unique sorted list of units from a register set. + void buildRegUnitSet(std::vector &RegUnits) const; + CodeGenRegisterClass(CodeGenRegBank&, Record *R); // A key representing the parts of a register class used for forming @@ -449,6 +452,15 @@ namespace llvm { return RegUnitWeights[RUID]; } + // Get the sum of unit weights. + unsigned getRegUnitSetWeight(const std::vector &Units) const { + unsigned Weight = 0; + for (std::vector::const_iterator + I = Units.begin(), E = Units.end(); I != E; ++I) + Weight += getRegUnitWeight(*I); + return Weight; + } + // Increase a RegUnitWeight. void increaseRegUnitWeight(unsigned RUID, unsigned Inc) { RegUnitWeights[RUID] += Inc; diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 8085955..a2478a7 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -125,19 +125,23 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, unsigned NumSets = RegBank.getNumRegPressureSets(); OS << "/// Get the weight in units of pressure for this register class.\n" - << "unsigned " << ClassName << "::\n" + << "const RegClassWeight &" << ClassName << "::\n" << "getRegClassWeight(const TargetRegisterClass *RC) const {\n" - << " static const unsigned RCWeightTable[] = {\n"; + << " static const RegClassWeight RCWeightTable[] = {\n"; for (unsigned i = 0, e = NumRCs; i != e; ++i) { const CodeGenRegisterClass &RC = *RegBank.getRegClasses()[i]; const CodeGenRegister::Set &Regs = RC.getMembers(); if (Regs.empty()) - OS << " 0"; - else - OS << " " << (*Regs.begin())->getWeight(RegBank); - OS << ", \t// " << RC.getName() << "\n"; + OS << " {0, 0"; + else { + std::vector RegUnits; + RC.buildRegUnitSet(RegUnits); + OS << " {" << (*Regs.begin())->getWeight(RegBank) + << ", " << RegBank.getRegUnitSetWeight(RegUnits); + } + OS << "}, \t// " << RC.getName() << "\n"; } - OS << " 0 };\n" + OS << " {0, 0} };\n" << " return RCWeightTable[RC->getID()];\n" << "}\n\n"; @@ -153,12 +157,7 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << " static const unsigned PressureLimitTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { const RegUnitSet &RegUnits = RegBank.getRegPressureSet(i); - unsigned Weight = 0; - for (RegUnitSet::iterator - I = RegUnits.Units.begin(), E = RegUnits.Units.end(); I != E; ++I) { - Weight += RegBank.getRegUnitWeight(*I); - } - OS << " " << Weight + OS << " " << RegBank.getRegUnitSetWeight(RegUnits.Units) << ", \t// " << i << ": " << RegBank.getRegPressureSet(i).Name << "\n"; } OS << " 0 };\n" @@ -668,7 +667,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, << " const TargetRegisterClass *getMatchingSuperRegClass(" "const TargetRegisterClass*, const TargetRegisterClass*, " "unsigned) const;\n" - << " unsigned getRegClassWeight(const TargetRegisterClass *RC) const;\n" + << " const RegClassWeight &getRegClassWeight(" + << "const TargetRegisterClass *RC) const;\n" << " unsigned getNumRegPressureSets() const;\n" << " unsigned getRegPressureSetLimit(unsigned Idx) const;\n" << " const int *getRegClassPressureSets(" -- cgit v1.1 From bf1aab15075884933e94a3aa950d88a7f16b5989 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 11 Apr 2012 21:02:30 +0000 Subject: Tidy up. Whitespace. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154531 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/InstrInfoEmitter.cpp | 2 +- utils/TableGen/InstrInfoEmitter.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 0941d2e..8b3efd3 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -373,7 +373,7 @@ void InstrInfoEmitter::emitEnums(raw_ostream &OS) { // We must emit the PHI opcode first... std::string Namespace = Target.getInstNamespace(); - + if (Namespace.empty()) { fprintf(stderr, "No instructions defined!\n"); exit(1); diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h index 1461e2c..ba4048e 100644 --- a/utils/TableGen/InstrInfoEmitter.h +++ b/utils/TableGen/InstrInfoEmitter.h @@ -31,7 +31,7 @@ class InstrInfoEmitter : public TableGenBackend { RecordKeeper &Records; CodeGenDAGPatterns CDP; std::map ItinClassMap; - + public: InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { } @@ -41,9 +41,9 @@ public: private: void emitEnums(raw_ostream &OS); - typedef std::map, unsigned> OperandInfoMapTy; + typedef std::map, unsigned> OperandInfoMapTy; void emitRecord(const CodeGenInstruction &Inst, unsigned Num, - Record *InstrInfo, + Record *InstrInfo, std::map, unsigned> &EL, const OperandInfoMapTy &OpInfo, raw_ostream &OS); @@ -51,7 +51,7 @@ private: // Itinerary information. void GatherItinClasses(); unsigned getItinClassNumber(const Record *InstRec); - + // Operand information. void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs); std::vector GetOperandInfo(const CodeGenInstruction &Inst); -- cgit v1.1 From 11fc6467e6a7bbd39037ec488d1138c5518fd17e Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 11 Apr 2012 21:02:33 +0000 Subject: Tidy up. Remove hard tab characters. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154532 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 96edaa1..39a3c25 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -288,7 +288,7 @@ struct MatchableInfo { Record *SingletonReg; explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1), - SingletonReg(0) {} + SingletonReg(0) {} }; /// ResOperand - This represents a single operand in the result instruction @@ -421,7 +421,7 @@ struct MatchableInfo { void Initialize(const AsmMatcherInfo &Info, SmallPtrSet &SingletonRegisters, - int AsmVariantNo, std::string &RegisterPrefix); + int AsmVariantNo, std::string &RegisterPrefix); /// Validate - Return true if this matchable is a valid thing to match against /// and perform a bunch of validity checking. @@ -818,7 +818,7 @@ bool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const { void MatchableInfo:: extractSingletonRegisterForAsmOperand(unsigned OperandNo, const AsmMatcherInfo &Info, - std::string &RegisterPrefix) { + std::string &RegisterPrefix) { StringRef Tok = AsmOperands[OperandNo].Token; if (RegisterPrefix.empty()) { std::string LoweredTok = Tok.lower(); @@ -1186,37 +1186,37 @@ void AsmMatcherInfo::BuildInfo() { int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) { + E = Target.inst_end(); I != E; ++I) { const CodeGenInstruction &CGI = **I; // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instructions we consider. if (!StringRef(CGI.TheDef->getName()).startswith(MatchPrefix)) - continue; + continue; // Ignore "codegen only" instructions. if (CGI.TheDef->getValueAsBit("isCodeGenOnly")) - continue; + continue; // Validate the operand list to ensure we can handle this instruction. for (unsigned i = 0, e = CGI.Operands.size(); i != e; ++i) { - const CGIOperandList::OperandInfo &OI = CGI.Operands[i]; - - // Validate tied operands. - if (OI.getTiedRegister() != -1) { - // If we have a tied operand that consists of multiple MCOperands, - // reject it. We reject aliases and ignore instructions for now. - if (OI.MINumOperands != 1) { - // FIXME: Should reject these. The ARM backend hits this with $lane - // in a bunch of instructions. It is unclear what the right answer is. - DEBUG({ - errs() << "warning: '" << CGI.TheDef->getName() << "': " - << "ignoring instruction with multi-operand tied operand '" - << OI.Name << "'\n"; - }); - continue; - } - } + const CGIOperandList::OperandInfo &OI = CGI.Operands[i]; + + // Validate tied operands. + if (OI.getTiedRegister() != -1) { + // If we have a tied operand that consists of multiple MCOperands, + // reject it. We reject aliases and ignore instructions for now. + if (OI.MINumOperands != 1) { + // FIXME: Should reject these. The ARM backend hits this with $lane + // in a bunch of instructions. It is unclear what the right answer is. + DEBUG({ + errs() << "warning: '" << CGI.TheDef->getName() << "': " + << "ignoring instruction with multi-operand tied operand '" + << OI.Name << "'\n"; + }); + continue; + } + } } OwningPtr II(new MatchableInfo(CGI)); @@ -1226,14 +1226,14 @@ void AsmMatcherInfo::BuildInfo() { // Ignore instructions which shouldn't be matched and diagnose invalid // instruction definitions with an error. if (!II->Validate(CommentDelimiter, true)) - continue; + continue; // Ignore "Int_*" and "*_Int" instructions, which are internal aliases. // // FIXME: This is a total hack. if (StringRef(II->TheDef->getName()).startswith("Int_") || - StringRef(II->TheDef->getName()).endswith("_Int")) - continue; + StringRef(II->TheDef->getName()).endswith("_Int")) + continue; Matchables.push_back(II.take()); } @@ -1249,8 +1249,8 @@ void AsmMatcherInfo::BuildInfo() { // filter the set of instruction aliases we consider, based on the target // instruction. if (!StringRef(Alias->ResultInst->TheDef->getName()).startswith( - MatchPrefix)) - continue; + MatchPrefix)) + continue; OwningPtr II(new MatchableInfo(Alias)); -- cgit v1.1 From 2ce182c90cd8738bf76e5cdaa21eb6627c6e6aec Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 11 Apr 2012 21:09:54 +0000 Subject: Remove incorrect comment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154533 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/InstrInfoEmitter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/InstrInfoEmitter.h b/utils/TableGen/InstrInfoEmitter.h index ba4048e..f8d3ea5 100644 --- a/utils/TableGen/InstrInfoEmitter.h +++ b/utils/TableGen/InstrInfoEmitter.h @@ -35,7 +35,7 @@ class InstrInfoEmitter : public TableGenBackend { public: InstrInfoEmitter(RecordKeeper &R) : Records(R), CDP(R) { } - // run - Output the instruction set description, returning true on failure. + // run - Output the instruction set description. void run(raw_ostream &OS); private: -- cgit v1.1 From b57b170317f12370183111fc458de3352c5f71dc Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 13 Apr 2012 06:14:57 +0000 Subject: Fix target specific intrinsic handling to adjust intrinsic number before doing attribute table lookup. Also fix attribute table lookup to handle 'invalid' intrinsic correctly. Fixes PR12542 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154658 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/IntrinsicEmitter.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 39ece32..8e1bae8 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -537,7 +537,6 @@ EmitAttributes(const std::vector &Ints, raw_ostream &OS) { // at least one entry, for the function itself (index ~1), which is // usually nounwind. OS << " static const uint8_t IntrinsicsToAttributesMap[] = {\n"; - OS << " 255, // Invalid intrinsic\n"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { const CodeGenIntrinsic &intrinsic = Ints[i]; @@ -549,11 +548,17 @@ EmitAttributes(const std::vector &Ints, raw_ostream &OS) { OS << " AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n"; OS << " unsigned NumAttrs = 0;\n"; - OS << " switch(IntrinsicsToAttributesMap[id]) {\n"; - OS << " default: llvm_unreachable(\"Invalid attribute number\");\n"; + OS << " if (id != 0) {\n"; + OS << " switch(IntrinsicsToAttributesMap[id - "; + if (TargetOnly) + OS << "Intrinsic::num_intrinsics"; + else + OS << "1"; + OS << "]) {\n"; + OS << " default: llvm_unreachable(\"Invalid attribute number\");\n"; for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(), E = UniqAttributes.end(); I != E; ++I) { - OS << " case " << I->second << ":\n"; + OS << " case " << I->second << ":\n"; const CodeGenIntrinsic &intrinsic = *(I->first); @@ -564,7 +569,7 @@ EmitAttributes(const std::vector &Ints, raw_ostream &OS) { for (unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size(); ai != ae;) { unsigned argNo = intrinsic.ArgumentAttributes[ai].first; - OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(" + OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(" << argNo+1 << ", "; bool moreThanOne = false; @@ -588,7 +593,7 @@ EmitAttributes(const std::vector &Ints, raw_ostream &OS) { ModRefKind modRef = getModRefKind(intrinsic); if (!intrinsic.canThrow || modRef) { - OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, "; + OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, "; if (!intrinsic.canThrow) { OS << "Attribute::NoUnwind"; if (modRef) OS << '|'; @@ -602,13 +607,14 @@ EmitAttributes(const std::vector &Ints, raw_ostream &OS) { } if (numAttrs) { - OS << " NumAttrs = " << numAttrs << ";\n"; - OS << " break;\n"; + OS << " NumAttrs = " << numAttrs << ";\n"; + OS << " break;\n"; } else { - OS << " return AttrListPtr();\n"; + OS << " return AttrListPtr();\n"; } } + OS << " }\n"; OS << " }\n"; OS << " return AttrListPtr::get(AWI, NumAttrs);\n"; OS << "}\n"; -- cgit v1.1 From 6335e41d38ff85c263451c5cd71b2588c5cc74cc Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 13 Apr 2012 22:58:53 +0000 Subject: Remove old code to strip out unwanted PPC slices for Apple llvmCore. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154706 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/buildit/build_llvm | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'utils') diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 88a26d3..994fb06 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -228,19 +228,6 @@ fi cd $DEST_DIR$DEST_ROOT rm -f bin/.dir etc/llvm/.dir lib/.dir -# Remove PPC64 fat slices. -cd $DEST_DIR$DEST_ROOT/bin -if [ $MACOSX_DEPLOYMENT_TARGET = "10.4" ]; then - find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \ - -exec lipo -extract ppc -extract i386 {} -output {} \; -elif [ $MACOSX_DEPLOYMENT_TARGET = "10.5" ]; then - find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \ - -exec lipo -extract ppc7400 -extract i386 {} -output {} \; -else - find . -perm 755 -type f \! \( -name '*gccas' -o -name '*gccld' -o -name llvm-config \) \ - -exec lipo -extract i386 -extract x86_64 {} -output {} \; -fi - # The Hello dylib is an example of how to build a pass. # The BugpointPasses module is only used to test bugpoint. # These unversioned dylibs cause verification failures, so do not install them. -- cgit v1.1 From 65da6fc8af561e77620bd86b83be8ca50acfdd30 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 17 Apr 2012 00:01:04 +0000 Subject: Tidy up. 80 columns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154881 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 39a3c25..503d073 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1181,7 +1181,8 @@ void AsmMatcherInfo::BuildInfo() { unsigned VariantCount = Target.getAsmParserVariantCount(); for (unsigned VC = 0; VC != VariantCount; ++VC) { Record *AsmVariant = Target.getAsmParserVariant(VC); - std::string CommentDelimiter = AsmVariant->getValueAsString("CommentDelimiter"); + std::string CommentDelimiter = + AsmVariant->getValueAsString("CommentDelimiter"); std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix"); int AsmVariantNo = AsmVariant->getValueAsInt("Variant"); @@ -1208,11 +1209,11 @@ void AsmMatcherInfo::BuildInfo() { // reject it. We reject aliases and ignore instructions for now. if (OI.MINumOperands != 1) { // FIXME: Should reject these. The ARM backend hits this with $lane - // in a bunch of instructions. It is unclear what the right answer is. + // in a bunch of instructions. The right answer is unclear. DEBUG({ errs() << "warning: '" << CGI.TheDef->getName() << "': " - << "ignoring instruction with multi-operand tied operand '" - << OI.Name << "'\n"; + << "ignoring instruction with multi-operand tied operand '" + << OI.Name << "'\n"; }); continue; } @@ -1248,8 +1249,8 @@ void AsmMatcherInfo::BuildInfo() { // If the tblgen -match-prefix option is specified (for tblgen hackers), // filter the set of instruction aliases we consider, based on the target // instruction. - if (!StringRef(Alias->ResultInst->TheDef->getName()).startswith( - MatchPrefix)) + if (!StringRef(Alias->ResultInst->TheDef->getName()) + .startswith( MatchPrefix)) continue; OwningPtr II(new MatchableInfo(Alias)); @@ -1868,7 +1869,8 @@ static void EmitComputeAvailableFeatures(AsmMatcherInfo &Info, SubtargetFeatureInfo &SFI = *it->second; OS << " if ("; - std::string CondStorage = SFI.TheDef->getValueAsString("AssemblerCondString"); + std::string CondStorage = + SFI.TheDef->getValueAsString("AssemblerCondString"); StringRef Conds = CondStorage; std::pair Comma = Conds.split(','); bool First = true; -- cgit v1.1 From 6d9cf6cf9adb1de4e3c68b5e04b9d6060c077085 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 17 Apr 2012 01:01:55 +0000 Subject: Don't tag libcxx and libcxxabi since we don't release them just yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154889 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/release/tag.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'utils') diff --git a/utils/release/tag.sh b/utils/release/tag.sh index 80da47a..551fe91 100755 --- a/utils/release/tag.sh +++ b/utils/release/tag.sh @@ -30,7 +30,7 @@ function usage() { function tag_version() { set -x - for proj in llvm cfe dragonegg test-suite compiler-rt libcxx libcxxabi ; do + for proj in llvm cfe dragonegg test-suite compiler-rt ; do if ! svn ls $base_url/$proj/branches/release_$release > /dev/null 2>&1 ; then svn copy -m "Creating release_$release branch" \ $base_url/$proj/trunk \ @@ -42,7 +42,7 @@ function tag_version() { function tag_release_candidate() { set -x - for proj in llvm cfe dragonegg test-suite compiler-rt libcxx libcxxabi ; do + for proj in llvm cfe dragonegg test-suite compiler-rt ; do if ! svn ls $base_url/$proj/tags/RELEASE_$release > /dev/null 2>&1 ; then svn mkdir -m "Creating release directory for release_$release." $base_url/$proj/tags/RELEASE_$release fi -- cgit v1.1 From e4576266f49169ad0ae112d9cb565e7d7c4bf24e Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 17 Apr 2012 05:11:51 +0000 Subject: Download and build the compiler-rt project. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154905 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/release/test-release.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh index ad1af5f..d2946d8 100755 --- a/utils/release/test-release.sh +++ b/utils/release/test-release.sh @@ -18,7 +18,7 @@ else MAKE=make fi -projects="llvm cfe dragonegg test-suite" +projects="llvm cfe dragonegg compiler-rt test-suite" # Base SVN URL for the sources. Base_url="http://llvm.org/svn/llvm-project" @@ -214,6 +214,9 @@ function export_sources() { if [ ! -h llvm-test ]; then ln -s ../../test-suite.src llvm-test fi + if [ ! -h compiler-rt ]; then + ln -s ../../compiler-rt.src compiler-rt + fi cd $BuildDir } -- cgit v1.1 From 61c3d3001515619ce112ae6e26b7d127a4db1b1c Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 17 Apr 2012 17:21:17 +0000 Subject: Goodbye, JSONParser... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154930 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/Makefile | 2 +- utils/json-bench/CMakeLists.txt | 5 --- utils/json-bench/JSONBench.cpp | 85 ----------------------------------------- utils/json-bench/Makefile | 21 ---------- 4 files changed, 1 insertion(+), 112 deletions(-) delete mode 100644 utils/json-bench/CMakeLists.txt delete mode 100644 utils/json-bench/JSONBench.cpp delete mode 100644 utils/json-bench/Makefile (limited to 'utils') diff --git a/utils/Makefile b/utils/Makefile index b983760..ecb30be 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -9,7 +9,7 @@ LEVEL = .. PARALLEL_DIRS := FileCheck FileUpdate TableGen PerfectShuffle \ - count fpcmp llvm-lit not unittest json-bench + count fpcmp llvm-lit not unittest EXTRA_DIST := check-each-file codegen-diff countloc.sh \ DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \ diff --git a/utils/json-bench/CMakeLists.txt b/utils/json-bench/CMakeLists.txt deleted file mode 100644 index 03ac51c..0000000 --- a/utils/json-bench/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_llvm_utility(json-bench - JSONBench.cpp - ) - -target_link_libraries(json-bench LLVMSupport) diff --git a/utils/json-bench/JSONBench.cpp b/utils/json-bench/JSONBench.cpp deleted file mode 100644 index ca8a36a..0000000 --- a/utils/json-bench/JSONBench.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===- JSONBench - Benchmark the JSONParser implementation ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This program executes the JSONParser on differntly sized JSON texts and -// outputs the run time. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Twine.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/JSONParser.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" - -static llvm::cl::opt -Verify("verify", llvm::cl::desc( - "Run a quick verification useful for regression testing"), - llvm::cl::init(false)); - -static llvm::cl::opt -MemoryLimitMB("memory-limit", llvm::cl::desc( - "Do not use more megabytes of memory"), - llvm::cl::init(1000)); - -void benchmark(llvm::TimerGroup &Group, llvm::StringRef Name, - llvm::StringRef JSONText) { - llvm::Timer BaseLine((Name + ": Loop").str(), Group); - BaseLine.startTimer(); - char C = 0; - for (llvm::StringRef::iterator I = JSONText.begin(), - E = JSONText.end(); - I != E; ++I) { C += *I; } - BaseLine.stopTimer(); - volatile char DontOptimizeOut = C; (void)DontOptimizeOut; - - llvm::Timer Parsing((Name + ": Parsing").str(), Group); - Parsing.startTimer(); - llvm::SourceMgr SM; - llvm::JSONParser Parser(JSONText, &SM); - if (!Parser.validate()) { - llvm::errs() << "Parsing error in JSON parser benchmark.\n"; - exit(1); - } - Parsing.stopTimer(); -} - -std::string createJSONText(size_t MemoryMB, unsigned ValueSize) { - std::string JSONText; - llvm::raw_string_ostream Stream(JSONText); - Stream << "[\n"; - size_t MemoryBytes = MemoryMB * 1024 * 1024; - while (JSONText.size() < MemoryBytes) { - Stream << " {\n" - << " \"key1\": \"" << std::string(ValueSize, '*') << "\",\n" - << " \"key2\": \"" << std::string(ValueSize, '*') << "\",\n" - << " \"key3\": \"" << std::string(ValueSize, '*') << "\"\n" - << " }"; - Stream.flush(); - if (JSONText.size() < MemoryBytes) Stream << ","; - Stream << "\n"; - } - Stream << "]\n"; - Stream.flush(); - return JSONText; -} - -int main(int argc, char **argv) { - llvm::cl::ParseCommandLineOptions(argc, argv); - llvm::TimerGroup Group("JSON parser benchmark"); - if (Verify) { - benchmark(Group, "Fast", createJSONText(10, 500)); - } else { - benchmark(Group, "Small Values", createJSONText(MemoryLimitMB, 5)); - benchmark(Group, "Medium Values", createJSONText(MemoryLimitMB, 500)); - benchmark(Group, "Large Values", createJSONText(MemoryLimitMB, 50000)); - } - return 0; -} - diff --git a/utils/json-bench/Makefile b/utils/json-bench/Makefile deleted file mode 100644 index 6651626..0000000 --- a/utils/json-bench/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -##===- utils/FileCheck/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -TOOLNAME = json-bench -USEDLIBS = LLVMSupport.a - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -# Don't install this utility -NO_INSTALL = 1 - -include $(LEVEL)/Makefile.common - -- cgit v1.1 From 67cd20d0396a68e61858736b7943dd352f1b0d0b Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 17 Apr 2012 21:23:52 +0000 Subject: Sanity check error handling for TokenAlias. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154951 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 503d073..dc92a6c 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1329,6 +1329,9 @@ void AsmMatcherInfo::BuildInfo() { Record *Rec = AllTokenAliases[i]; ClassInfo *FromClass = getTokenClass(Rec->getValueAsString("FromToken")); ClassInfo *ToClass = getTokenClass(Rec->getValueAsString("ToToken")); + if (FromClass == ToClass) + throw TGError(Rec->getLoc(), + "error: Destination value identical to source value."); FromClass->SuperClasses.push_back(ToClass); } -- cgit v1.1 From e546c4c9c3004274c8e275e8303ca078b794bf28 Mon Sep 17 00:00:00 2001 From: Silviu Baranga Date: Wed, 18 Apr 2012 13:02:55 +0000 Subject: Fixed decoding for the ARM cdp2 instruction. The restriction on the coprocessor number was removed for this instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155000 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/EDEmitter.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'utils') diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 3809a45..fe484ca 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -594,6 +594,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("jtblock_operand"); IMM("nohash_imm"); IMM("p_imm"); + IMM("pf_imm"); IMM("c_imm"); IMM("coproc_option_imm"); IMM("imod_op"); -- cgit v1.1 From 9b29ea4eb39b5f03ef2405c6355a9c627771c5dd Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 17:46:41 +0000 Subject: TableGen use PrintWarning rather than fprintf(stderr,...) for warnings. That way we get source line number information from the diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155014 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index d2ddf23..665a5f1 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -17,6 +17,7 @@ #include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include @@ -2483,10 +2484,9 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // If we decided that this is a store from the pattern, then the .td file // entry is redundant. if (MayStore) - fprintf(stderr, - "Warning: mayStore flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + Twine("Warning: mayStore flag explicitly set on ") + + "instruction, but flag already inferred from pattern.\n"); MayStore = true; } @@ -2494,24 +2494,25 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // If we decided that this is a load from the pattern, then the .td file // entry is redundant. if (MayLoad) - fprintf(stderr, - "Warning: mayLoad flag explicitly set on instruction '%s'" - " but flag already inferred from pattern.\n", - Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + Twine("Warning: mayLoad flag explicitly set on ") + + "instruction, but flag already inferred from pattern.\n"); MayLoad = true; } if (Inst.neverHasSideEffects) { if (HadPattern) - fprintf(stderr, "Warning: neverHasSideEffects set on instruction '%s' " - "which already has a pattern\n", Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + Twine("Warning: neverHasSideEffects flag explicitly set on ") + + "instruction, but flag already inferred from pattern.\n"); HasSideEffects = false; } if (Inst.hasSideEffects) { if (HasSideEffects) - fprintf(stderr, "Warning: hasSideEffects set on instruction '%s' " - "which already inferred this.\n", Inst.TheDef->getName().c_str()); + PrintWarning(Inst.TheDef->getLoc(), + Twine("Warning: hasSideEffects flag explicitly set on ") + + "instruction, but flag already inferred from pattern.\n"); HasSideEffects = true; } -- cgit v1.1 From 7be43977b4a12b2e2361a3d0cf087e637394896b Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:09:50 +0000 Subject: Clean up warning text. Remove extraneous prefix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155015 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 665a5f1..5e6f6b6 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2485,7 +2485,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // entry is redundant. if (MayStore) PrintWarning(Inst.TheDef->getLoc(), - Twine("Warning: mayStore flag explicitly set on ") + + Twine("mayStore flag explicitly set on ") + "instruction, but flag already inferred from pattern.\n"); MayStore = true; } @@ -2495,7 +2495,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // entry is redundant. if (MayLoad) PrintWarning(Inst.TheDef->getLoc(), - Twine("Warning: mayLoad flag explicitly set on ") + + Twine("mayLoad flag explicitly set on ") + "instruction, but flag already inferred from pattern.\n"); MayLoad = true; } @@ -2503,7 +2503,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (Inst.neverHasSideEffects) { if (HadPattern) PrintWarning(Inst.TheDef->getLoc(), - Twine("Warning: neverHasSideEffects flag explicitly set on ") + + Twine("neverHasSideEffects flag explicitly set on ") + "instruction, but flag already inferred from pattern.\n"); HasSideEffects = false; } @@ -2511,7 +2511,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (Inst.hasSideEffects) { if (HasSideEffects) PrintWarning(Inst.TheDef->getLoc(), - Twine("Warning: hasSideEffects flag explicitly set on ") + + Twine("hasSideEffects flag explicitly set on ") + "instruction, but flag already inferred from pattern.\n"); HasSideEffects = true; } -- cgit v1.1 From 5bd9e0dd028202f94391a394a12a6b8c69ee52e3 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:39:19 +0000 Subject: Tidy up. Add a '.' at the end of the sentence. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155024 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index a2478a7..0216c36 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -32,7 +32,7 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &Bank) { const std::vector &Registers = Bank.getRegisters(); - // Register enums are stored as uint16_t in the tables. Make sure we'll fit + // Register enums are stored as uint16_t in the tables. Make sure we'll fit. assert(Registers.size() <= 0xffff && "Too many regs to fit in tables"); std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace"); -- cgit v1.1 From 723fc11f91240e267dd748b467b43b6c00498e4b Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:39:23 +0000 Subject: Formatting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155025 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/RegisterInfoEmitter.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 0216c36..21e9e99 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -27,9 +27,8 @@ using namespace llvm; // runEnums - Print out enum values for all of the registers. -void -RegisterInfoEmitter::runEnums(raw_ostream &OS, - CodeGenTarget &Target, CodeGenRegBank &Bank) { +void RegisterInfoEmitter::runEnums(raw_ostream &OS, + CodeGenTarget &Target, CodeGenRegBank &Bank) { const std::vector &Registers = Bank.getRegisters(); // Register enums are stored as uint16_t in the tables. Make sure we'll fit. -- cgit v1.1 From 37c53ff6a715b2f9efcfa5253b2774b31301b6f8 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:39:27 +0000 Subject: Tidy up. No need for a Twine here, as it's just constants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155026 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 5e6f6b6..4f5d58c 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2485,7 +2485,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // entry is redundant. if (MayStore) PrintWarning(Inst.TheDef->getLoc(), - Twine("mayStore flag explicitly set on ") + + "mayStore flag explicitly set on " "instruction, but flag already inferred from pattern.\n"); MayStore = true; } @@ -2495,7 +2495,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, // entry is redundant. if (MayLoad) PrintWarning(Inst.TheDef->getLoc(), - Twine("mayLoad flag explicitly set on ") + + "mayLoad flag explicitly set on " "instruction, but flag already inferred from pattern.\n"); MayLoad = true; } @@ -2503,7 +2503,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (Inst.neverHasSideEffects) { if (HadPattern) PrintWarning(Inst.TheDef->getLoc(), - Twine("neverHasSideEffects flag explicitly set on ") + + "neverHasSideEffects flag explicitly set on " "instruction, but flag already inferred from pattern.\n"); HasSideEffects = false; } @@ -2511,7 +2511,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (Inst.hasSideEffects) { if (HasSideEffects) PrintWarning(Inst.TheDef->getLoc(), - Twine("hasSideEffects flag explicitly set on ") + + "hasSideEffects flag explicitly set on " "instruction, but flag already inferred from pattern.\n"); HasSideEffects = true; } -- cgit v1.1 From bfb4327baa5bbab78f0da4c8c069482878660a04 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:39:31 +0000 Subject: Move a few more warnings to use PrintWarning(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155027 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 10 +++++----- utils/TableGen/RegisterInfoEmitter.cpp | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 7ce4f87..85e33b1 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" using namespace llvm; @@ -896,11 +897,10 @@ void CodeGenRegBank::computeComposites() { if (i1d->second == Reg3) { // Conflicting composition? Emit a warning but allow it. if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, i1d->first)) - errs() << "Warning: SubRegIndex " << Idx1->getQualifiedName() - << " and " << Idx2->getQualifiedName() - << " compose ambiguously as " - << Prev->getQualifiedName() << " or " - << i1d->first->getQualifiedName() << "\n"; + PrintWarning(Twine("SubRegIndex") + Idx1->getQualifiedName() + + " and " + Idx2->getQualifiedName() + + " compose ambiguously as " + Prev->getQualifiedName() + + " or " + i1d->first->getQualifiedName() +"\n"); } } } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 21e9e99..748ffc5 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -17,10 +17,12 @@ #include "CodeGenTarget.h" #include "CodeGenRegisters.h" #include "SequenceToOffsetTable.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/Twine.h" #include "llvm/Support/Format.h" #include #include @@ -207,8 +209,8 @@ RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, std::vector RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); maxLength = std::max((size_t)maxLength, RegNums.size()); if (DwarfRegNums.count(Reg)) - errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg) - << "specified multiple times\n"; + PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + + getQualifiedName(Reg) + "specified multiple times\n"); DwarfRegNums[Reg] = RegNums; } -- cgit v1.1 From 016c679c50e13532a30d80b59232e4b82ab807bf Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 18:56:33 +0000 Subject: Tidy up. Formatting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155032 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index e0b0aac..0d6d0c8 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -289,7 +289,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) { AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]]; if (AWI != 0 && - AWI->Operands[0].OperandType == AsmWriterOperand::isLiteralTextOperand && + AWI->Operands[0].OperandType == + AsmWriterOperand::isLiteralTextOperand && !AWI->Operands[0].Str.empty()) { std::string Str = AWI->Operands[0].Str; UnescapeString(Str); @@ -919,7 +920,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { O << " }\n"; O << " }\n"; O << " }\n\n"; - + O << " return true;\n"; O << "}\n\n"; -- cgit v1.1 From a5b0685142e8d3f5d9b6cf5aee270ebbd796c1ba Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 19:02:43 +0000 Subject: Use SmallVector for the requirements on an InstAlias. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155034 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 0d6d0c8..d079b45 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -590,7 +590,7 @@ class IAPrinter { std::map OpMap; std::string Result; std::string AsmString; - std::vector ReqFeatures; + SmallVector ReqFeatures; public: IAPrinter(std::string R, std::string AS) : Result(R), AsmString(AS) {} -- cgit v1.1 From 325478d78dcf8a113c0bda932f76222b6299fa43 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 19:13:59 +0000 Subject: Replace some uses of std:map with StringMap. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155037 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index d079b45..b803283 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -724,7 +724,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { Records.getAllDerivedDefinitions("InstAlias"); // Create a map from the qualified name to a list of potential matches. - std::map > AliasMap; + StringMap > AliasMap; for (std::vector::iterator I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); @@ -738,9 +738,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // A map of which conditions need to be met for each instruction operand // before it can be matched to the mnemonic. - std::map > IAPrinterMap; + StringMap > IAPrinterMap; - for (std::map >::iterator + for (StringMap >::iterator I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { std::vector &Aliases = I->second; @@ -828,7 +828,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } if (CantHandle) continue; - IAPrinterMap[I->first].push_back(IAP); + IAPrinterMap[I->first()].push_back(IAP); } } @@ -842,7 +842,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { std::string Cases; raw_string_ostream CasesO(Cases); - for (std::map >::iterator + for (StringMap >::iterator I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) { std::vector &IAPs = I->second; std::vector UniqueIAPs; @@ -865,7 +865,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (UniqueIAPs.empty()) continue; - CasesO.indent(2) << "case " << I->first << ":\n"; + CasesO.indent(2) << "case " << I->first() << ":\n"; for (std::vector::iterator II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) { -- cgit v1.1 From 3cbcffc4e5990209ce80a54e615f55245fe3b824 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 18 Apr 2012 19:22:47 +0000 Subject: tblgen: remove duplicated newlines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155038 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenDAGPatterns.cpp | 8 ++++---- utils/TableGen/CodeGenRegisters.cpp | 2 +- utils/TableGen/RegisterInfoEmitter.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 4f5d58c..d4b02fb 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -2486,7 +2486,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (MayStore) PrintWarning(Inst.TheDef->getLoc(), "mayStore flag explicitly set on " - "instruction, but flag already inferred from pattern.\n"); + "instruction, but flag already inferred from pattern."); MayStore = true; } @@ -2496,7 +2496,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (MayLoad) PrintWarning(Inst.TheDef->getLoc(), "mayLoad flag explicitly set on " - "instruction, but flag already inferred from pattern.\n"); + "instruction, but flag already inferred from pattern."); MayLoad = true; } @@ -2504,7 +2504,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (HadPattern) PrintWarning(Inst.TheDef->getLoc(), "neverHasSideEffects flag explicitly set on " - "instruction, but flag already inferred from pattern.\n"); + "instruction, but flag already inferred from pattern."); HasSideEffects = false; } @@ -2512,7 +2512,7 @@ static void InferFromPattern(const CodeGenInstruction &Inst, if (HasSideEffects) PrintWarning(Inst.TheDef->getLoc(), "hasSideEffects flag explicitly set on " - "instruction, but flag already inferred from pattern.\n"); + "instruction, but flag already inferred from pattern."); HasSideEffects = true; } diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 85e33b1..45c5bb8 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -900,7 +900,7 @@ void CodeGenRegBank::computeComposites() { PrintWarning(Twine("SubRegIndex") + Idx1->getQualifiedName() + " and " + Idx2->getQualifiedName() + " compose ambiguously as " + Prev->getQualifiedName() + - " or " + i1d->first->getQualifiedName() +"\n"); + " or " + i1d->first->getQualifiedName()); } } } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 748ffc5..97fcca3 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -210,7 +210,7 @@ RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, maxLength = std::max((size_t)maxLength, RegNums.size()); if (DwarfRegNums.count(Reg)) PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + - getQualifiedName(Reg) + "specified multiple times\n"); + getQualifiedName(Reg) + "specified multiple times"); DwarfRegNums[Reg] = RegNums; } -- cgit v1.1 From b4b26f87fe2309abaa6fceaa71a9d6e812654c9f Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 20:24:49 +0000 Subject: Revert "Replace some uses of std:map with StringMap." StringMap iterators are not deterministic, and that's more important here than speed or memory. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155039 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index b803283..d079b45 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -724,7 +724,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { Records.getAllDerivedDefinitions("InstAlias"); // Create a map from the qualified name to a list of potential matches. - StringMap > AliasMap; + std::map > AliasMap; for (std::vector::iterator I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) { CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target); @@ -738,9 +738,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // A map of which conditions need to be met for each instruction operand // before it can be matched to the mnemonic. - StringMap > IAPrinterMap; + std::map > IAPrinterMap; - for (StringMap >::iterator + for (std::map >::iterator I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) { std::vector &Aliases = I->second; @@ -828,7 +828,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { } if (CantHandle) continue; - IAPrinterMap[I->first()].push_back(IAP); + IAPrinterMap[I->first].push_back(IAP); } } @@ -842,7 +842,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { std::string Cases; raw_string_ostream CasesO(Cases); - for (StringMap >::iterator + for (std::map >::iterator I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) { std::vector &IAPs = I->second; std::vector UniqueIAPs; @@ -865,7 +865,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (UniqueIAPs.empty()) continue; - CasesO.indent(2) << "case " << I->first() << ":\n"; + CasesO.indent(2) << "case " << I->first << ":\n"; for (std::vector::iterator II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) { -- cgit v1.1 From bdcfb7663a2a62fd52a14dbeaa076423c719ec2d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 18 Apr 2012 21:38:12 +0000 Subject: Add a flag to rebranch if we need to. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155049 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/release/tag.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'utils') diff --git a/utils/release/tag.sh b/utils/release/tag.sh index 551fe91..399d5c5 100755 --- a/utils/release/tag.sh +++ b/utils/release/tag.sh @@ -16,26 +16,33 @@ set -e release="" rc="" +rebranch="no" base_url="https://llvm.org/svn/llvm-project" function usage() { - echo "usage: `basename $0` -release " + echo "usage: `basename $0` -release [-rebranch]" echo "usage: `basename $0` -release -rc " echo " " echo " -release The version number of the release" echo " -rc The release candidate number" + echo " -rebranch Remove existing branch, if present, before branching" echo " -final Tag final release candidate" } function tag_version() { set -x for proj in llvm cfe dragonegg test-suite compiler-rt ; do - if ! svn ls $base_url/$proj/branches/release_$release > /dev/null 2>&1 ; then - svn copy -m "Creating release_$release branch" \ - $base_url/$proj/trunk \ + if svn ls $base_url/$proj/branches/release_$release > /dev/null 2>&1 ; then + if [ $rebranch = "no" ]; then + continue + fi + svn remove -m "Removing old release_$release branch for rebranching." \ $base_url/$proj/branches/release_$release fi + svn copy -m "Creating release_$release branch" \ + $base_url/$proj/trunk \ + $base_url/$proj/branches/release_$release done set +x } @@ -65,6 +72,9 @@ while [ $# -gt 0 ]; do shift rc="rc$1" ;; + -rebranch | --rebranch ) + rebranch="yes" + ;; -final | --final ) rc="final" ;; -- cgit v1.1 From d4824fc8aa1df5501600dd2a73c6da823f3b02db Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 18 Apr 2012 23:46:25 +0000 Subject: Fix typo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155075 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index dc92a6c..812d81c 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -1127,7 +1127,7 @@ AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, /// defined operand parsing methods. void AsmMatcherInfo::BuildOperandMatchInfo() { - /// Map containing a mask with all operands indicies that can be found for + /// Map containing a mask with all operands indices that can be found for /// that class inside a instruction. std::map OpClassMask; -- cgit v1.1