summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-10-05 19:32:12 +0000
committerChris Lattner <sabre@nondot.org>2003-10-05 19:32:12 +0000
commit5516347535ddf0c27cd207135ebf9ce975f30673 (patch)
tree4b89b4e60378e5864eaa0c27c1febe8246ee2805
parent091bbbada30ef4c17e5f66b740adda0acf7cc31a (diff)
downloadllvm-5516347535ddf0c27cd207135ebf9ce975f30673.tar.gz
llvm-5516347535ddf0c27cd207135ebf9ce975f30673.tar.bz2
llvm-5516347535ddf0c27cd207135ebf9ce975f30673.tar.xz
Move support/lib into lib/Support
Move support/tools into utils git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8878 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--support/Makefile6
-rw-r--r--support/lib/Makefile6
-rw-r--r--support/lib/Support/Annotation.cpp89
-rw-r--r--support/lib/Support/CommandLine.cpp877
-rw-r--r--support/lib/Support/ConstantRange.cpp243
-rw-r--r--support/lib/Support/Debug.cpp57
-rw-r--r--support/lib/Support/FileUtilities.cpp203
-rw-r--r--support/lib/Support/LeakDetector.cpp82
-rw-r--r--support/lib/Support/Makefile5
-rw-r--r--support/lib/Support/Mangler.cpp94
-rw-r--r--support/lib/Support/PluginLoader.cpp31
-rw-r--r--support/lib/Support/Signals.cpp57
-rw-r--r--support/lib/Support/Statistic.cpp99
-rw-r--r--support/lib/Support/SystemUtils.cpp266
-rw-r--r--support/lib/Support/Timer.cpp328
-rw-r--r--support/lib/Support/ToolRunner.cpp374
-rw-r--r--support/lib/Support/ValueHolder.cpp16
-rw-r--r--support/tools/Burg/COPYRIGHT13
-rw-r--r--support/tools/Burg/Doc/Makefile84
-rw-r--r--support/tools/Burg/Doc/doc.aux50
-rw-r--r--support/tools/Burg/Doc/doc.dvibin29856 -> 0 bytes
-rw-r--r--support/tools/Burg/Doc/doc.log157
-rw-r--r--support/tools/Burg/Doc/doc.tex596
-rw-r--r--support/tools/Burg/LOG_CHANGES10
-rw-r--r--support/tools/Burg/Makefile28
-rw-r--r--support/tools/Burg/README14
-rw-r--r--support/tools/Burg/b.h311
-rw-r--r--support/tools/Burg/be.c1052
-rw-r--r--support/tools/Burg/burg.shar.gzbin38843 -> 0 bytes
-rw-r--r--support/tools/Burg/burs.c71
-rw-r--r--support/tools/Burg/closure.c95
-rw-r--r--support/tools/Burg/delta.c143
-rw-r--r--support/tools/Burg/fe.c403
-rw-r--r--support/tools/Burg/fe.h132
-rw-r--r--support/tools/Burg/gram.yc91
-rw-r--r--support/tools/Burg/item.c133
-rw-r--r--support/tools/Burg/lex.c259
-rw-r--r--support/tools/Burg/list.c75
-rw-r--r--support/tools/Burg/main.c182
-rw-r--r--support/tools/Burg/map.c135
-rw-r--r--support/tools/Burg/nonterminal.c49
-rw-r--r--support/tools/Burg/operator.c48
-rw-r--r--support/tools/Burg/pattern.c38
-rw-r--r--support/tools/Burg/plank.c921
-rw-r--r--support/tools/Burg/queue.c64
-rw-r--r--support/tools/Burg/rule.c49
-rw-r--r--support/tools/Burg/sample.gr150
-rw-r--r--support/tools/Burg/string.c65
-rw-r--r--support/tools/Burg/symtab.c38
-rw-r--r--support/tools/Burg/table.c552
-rw-r--r--support/tools/Burg/trim.c412
-rw-r--r--support/tools/Burg/zalloc.c35
-rw-r--r--support/tools/Makefile6
-rw-r--r--support/tools/TableGen/CodeEmitterGen.cpp217
-rw-r--r--support/tools/TableGen/CodeEmitterGen.h24
-rw-r--r--support/tools/TableGen/CodeGenWrappers.cpp89
-rw-r--r--support/tools/TableGen/CodeGenWrappers.h56
-rw-r--r--support/tools/TableGen/FileLexer.l222
-rw-r--r--support/tools/TableGen/FileParser.y510
-rw-r--r--support/tools/TableGen/InstrInfoEmitter.cpp160
-rw-r--r--support/tools/TableGen/InstrInfoEmitter.h34
-rw-r--r--support/tools/TableGen/InstrSelectorEmitter.cpp1287
-rw-r--r--support/tools/TableGen/InstrSelectorEmitter.h387
-rw-r--r--support/tools/TableGen/Makefile18
-rw-r--r--support/tools/TableGen/Record.cpp676
-rw-r--r--support/tools/TableGen/Record.h849
-rw-r--r--support/tools/TableGen/RegisterInfoEmitter.cpp234
-rw-r--r--support/tools/TableGen/RegisterInfoEmitter.h29
-rw-r--r--support/tools/TableGen/TableGen.cpp482
-rw-r--r--support/tools/TableGen/TableGenBackend.cpp27
-rw-r--r--support/tools/TableGen/TableGenBackend.h34
71 files changed, 0 insertions, 14629 deletions
diff --git a/support/Makefile b/support/Makefile
deleted file mode 100644
index ba074f506c..0000000000
--- a/support/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-LEVEL = ..
-
-DIRS = lib tools
-
-include $(LEVEL)/Makefile.common
-
diff --git a/support/lib/Makefile b/support/lib/Makefile
deleted file mode 100644
index f5446d31f6..0000000000
--- a/support/lib/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-LEVEL = ../..
-
-DIRS = Support
-
-include $(LEVEL)/Makefile.common
-
diff --git a/support/lib/Support/Annotation.cpp b/support/lib/Support/Annotation.cpp
deleted file mode 100644
index 9166240b82..0000000000
--- a/support/lib/Support/Annotation.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- Annotation.cpp - Implement the Annotation Classes --------*- C++ -*--=//
-//
-// This file implements the AnnotationManager class.
-//
-//===----------------------------------------------------------------------===//
-
-#include <map>
-#include "Support/Annotation.h"
-
-typedef std::map<const std::string, unsigned> IDMapType;
-static unsigned IDCounter = 0; // Unique ID counter
-
-// Static member to ensure initialiation on demand.
-static IDMapType &getIDMap() { static IDMapType TheMap; return TheMap; }
-
-// On demand annotation creation support...
-typedef Annotation *(*AnnFactory)(AnnotationID, const Annotable *, void *);
-typedef std::map<unsigned, std::pair<AnnFactory,void*> > FactMapType;
-
-static FactMapType *TheFactMap = 0;
-static FactMapType &getFactMap() {
- if (TheFactMap == 0)
- TheFactMap = new FactMapType();
- return *TheFactMap;
-}
-
-static void eraseFromFactMap(unsigned ID) {
- assert(TheFactMap && "No entries found!");
- TheFactMap->erase(ID);
- if (TheFactMap->empty()) { // Delete when empty
- delete TheFactMap;
- TheFactMap = 0;
- }
-}
-
-
-AnnotationID AnnotationManager::getID(const std::string &Name) { // Name -> ID
- IDMapType::iterator I = getIDMap().find(Name);
- if (I == getIDMap().end()) {
- getIDMap()[Name] = IDCounter++; // Add a new element
- return IDCounter-1;
- }
- return I->second;
-}
-
-// getID - Name -> ID + registration of a factory function for demand driven
-// annotation support.
-AnnotationID AnnotationManager::getID(const std::string &Name, Factory Fact,
- void *Data) {
- AnnotationID Result(getID(Name));
- registerAnnotationFactory(Result, Fact, Data);
- return Result;
-}
-
-
-// getName - This function is especially slow, but that's okay because it should
-// only be used for debugging.
-//
-const std::string &AnnotationManager::getName(AnnotationID ID) { // ID -> Name
- IDMapType &TheMap = getIDMap();
- for (IDMapType::iterator I = TheMap.begin(); ; ++I) {
- assert(I != TheMap.end() && "Annotation ID is unknown!");
- if (I->second == ID.ID) return I->first;
- }
-}
-
-
-// registerAnnotationFactory - This method is used to register a callback
-// function used to create an annotation on demand if it is needed by the
-// Annotable::findOrCreateAnnotation method.
-//
-void AnnotationManager::registerAnnotationFactory(AnnotationID ID,
- AnnFactory F,
- void *ExtraData) {
- if (F)
- getFactMap()[ID.ID] = std::make_pair(F, ExtraData);
- else
- eraseFromFactMap(ID.ID);
-}
-
-// createAnnotation - Create an annotation of the specified ID for the
-// specified object, using a register annotation creation function.
-//
-Annotation *AnnotationManager::createAnnotation(AnnotationID ID,
- const Annotable *Obj) {
- FactMapType::iterator I = getFactMap().find(ID.ID);
- if (I == getFactMap().end()) return 0;
- return I->second.first(ID, Obj, I->second.second);
-}
diff --git a/support/lib/Support/CommandLine.cpp b/support/lib/Support/CommandLine.cpp
deleted file mode 100644
index c0be0ecb34..0000000000
--- a/support/lib/Support/CommandLine.cpp
+++ /dev/null
@@ -1,877 +0,0 @@
-//===-- CommandLine.cpp - Command line parser implementation --------------===//
-//
-// This class implements a command line argument processor that is useful when
-// creating a tool. It provides a simple, minimalistic interface that is easily
-// extensible and supports nonlocal (library) command line options.
-//
-// Note that rather than trying to figure out what this code does, you could try
-// reading the library documentation located in docs/CommandLine.html
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/CommandLine.h"
-#include <algorithm>
-#include <map>
-#include <set>
-#include <iostream>
-
-using namespace cl;
-
-//===----------------------------------------------------------------------===//
-// Basic, shared command line option processing machinery...
-//
-
-// Return the global command line option vector. Making it a function scoped
-// static ensures that it will be initialized correctly before its first use.
-//
-static std::map<std::string, Option*> *CommandLineOptions = 0;
-static std::map<std::string, Option*> &getOpts() {
- if (CommandLineOptions == 0)
- CommandLineOptions = new std::map<std::string,Option*>();
- return *CommandLineOptions;
-}
-
-static Option *getOption(const std::string &Str) {
- if (CommandLineOptions == 0) return 0;
- std::map<std::string,Option*>::iterator I = CommandLineOptions->find(Str);
- return I != CommandLineOptions->end() ? I->second : 0;
-}
-
-static std::vector<Option*> &getPositionalOpts() {
- static std::vector<Option*> Positional;
- return Positional;
-}
-
-static void AddArgument(const char *ArgName, Option *Opt) {
- if (getOption(ArgName)) {
- std::cerr << "CommandLine Error: Argument '" << ArgName
- << "' defined more than once!\n";
- } else {
- // Add argument to the argument map!
- getOpts()[ArgName] = Opt;
- }
-}
-
-// RemoveArgument - It's possible that the argument is no longer in the map if
-// options have already been processed and the map has been deleted!
-//
-static void RemoveArgument(const char *ArgName, Option *Opt) {
- if (CommandLineOptions == 0) return;
- assert(getOption(ArgName) == Opt && "Arg not in map!");
- CommandLineOptions->erase(ArgName);
- if (CommandLineOptions->empty()) {
- delete CommandLineOptions;
- CommandLineOptions = 0;
- }
-}
-
-static const char *ProgramName = 0;
-static const char *ProgramOverview = 0;
-
-static inline bool ProvideOption(Option *Handler, const char *ArgName,
- const char *Value, int argc, char **argv,
- int &i) {
- // Enforce value requirements
- switch (Handler->getValueExpectedFlag()) {
- case ValueRequired:
- if (Value == 0 || *Value == 0) { // No value specified?
- if (i+1 < argc) { // Steal the next argument, like for '-o filename'
- Value = argv[++i];
- } else {
- return Handler->error(" requires a value!");
- }
- }
- break;
- case ValueDisallowed:
- if (*Value != 0)
- return Handler->error(" does not allow a value! '" +
- std::string(Value) + "' specified.");
- break;
- case ValueOptional: break;
- default: std::cerr << "Bad ValueMask flag! CommandLine usage error:"
- << Handler->getValueExpectedFlag() << "\n"; abort();
- }
-
- // Run the handler now!
- return Handler->addOccurrence(ArgName, Value);
-}
-
-static bool ProvidePositionalOption(Option *Handler, const std::string &Arg) {
- int Dummy;
- return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy);
-}
-
-
-// Option predicates...
-static inline bool isGrouping(const Option *O) {
- return O->getFormattingFlag() == cl::Grouping;
-}
-static inline bool isPrefixedOrGrouping(const Option *O) {
- return isGrouping(O) || O->getFormattingFlag() == cl::Prefix;
-}
-
-// getOptionPred - Check to see if there are any options that satisfy the
-// specified predicate with names that are the prefixes in Name. This is
-// checked by progressively stripping characters off of the name, checking to
-// see if there options that satisfy the predicate. If we find one, return it,
-// otherwise return null.
-//
-static Option *getOptionPred(std::string Name, unsigned &Length,
- bool (*Pred)(const Option*)) {
-
- Option *Op = getOption(Name);
- if (Op && Pred(Op)) {
- Length = Name.length();
- return Op;
- }
-
- if (Name.size() == 1) return 0;
- do {
- Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
- Op = getOption(Name);
-
- // Loop while we haven't found an option and Name still has at least two
- // characters in it (so that the next iteration will not be the empty
- // string...
- } while ((Op == 0 || !Pred(Op)) && Name.size() > 1);
-
- if (Op && Pred(Op)) {
- Length = Name.length();
- return Op; // Found one!
- }
- return 0; // No option found!
-}
-
-static bool RequiresValue(const Option *O) {
- return O->getNumOccurrencesFlag() == cl::Required ||
- O->getNumOccurrencesFlag() == cl::OneOrMore;
-}
-
-static bool EatsUnboundedNumberOfValues(const Option *O) {
- return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
- O->getNumOccurrencesFlag() == cl::OneOrMore;
-}
-
-/// ParseCStringVector - Break INPUT up wherever one or more
-/// whitespace characters are found, and store the resulting tokens in
-/// OUTPUT. The tokens stored in OUTPUT are dynamically allocated
-/// using strdup (), so it is the caller's responsibility to free ()
-/// them later.
-///
-static void ParseCStringVector (std::vector<char *> &output,
- const char *input) {
- // Characters which will be treated as token separators:
- static const char *delims = " \v\f\t\r\n";
-
- std::string work (input);
- // Skip past any delims at head of input string.
- size_t pos = work.find_first_not_of (delims);
- // If the string consists entirely of delims, then exit early.
- if (pos == std::string::npos) return;
- // Otherwise, jump forward to beginning of first word.
- work = work.substr (pos);
- // Find position of first delimiter.
- pos = work.find_first_of (delims);
-
- while (!work.empty() && pos != std::string::npos) {
- // Everything from 0 to POS is the next word to copy.
- output.push_back (strdup (work.substr (0,pos).c_str ()));
- // Is there another word in the string?
- size_t nextpos = work.find_first_not_of (delims, pos + 1);
- if (nextpos != std::string::npos) {
- // Yes? Then remove delims from beginning ...
- work = work.substr (work.find_first_not_of (delims, pos + 1));
- // and find the end of the word.
- pos = work.find_first_of (delims);
- } else {
- // No? (Remainder of string is delims.) End the loop.
- work = "";
- pos = std::string::npos;
- }
- }
-
- // If `input' ended with non-delim char, then we'll get here with
- // the last word of `input' in `work'; copy it now.
- if (!work.empty ()) {
- output.push_back (strdup (work.c_str ()));
- }
-}
-
-/// ParseEnvironmentOptions - An alternative entry point to the
-/// CommandLine library, which allows you to read the program's name
-/// from the caller (as PROGNAME) and its command-line arguments from
-/// an environment variable (whose name is given in ENVVAR).
-///
-void cl::ParseEnvironmentOptions (const char *progName, const char *envVar,
- const char *Overview) {
- // Check args.
- assert (progName && "Program name not specified");
- assert (envVar && "Environment variable name missing");
-
- // Get the environment variable they want us to parse options out of.
- const char *envValue = getenv (envVar);
- if (!envValue)
- return;
-
- // Get program's "name", which we wouldn't know without the caller
- // telling us.
- std::vector<char *> newArgv;
- newArgv.push_back (strdup (progName));
-
- // Parse the value of the environment variable into a "command line"
- // and hand it off to ParseCommandLineOptions().
- ParseCStringVector (newArgv, envValue);
- int newArgc = newArgv.size ();
- ParseCommandLineOptions (newArgc, &newArgv[0], Overview);
-
- // Free all the strdup()ed strings.
- for (std::vector<char *>::iterator i = newArgv.begin (), e = newArgv.end ();
- i != e; ++i) {
- free (*i);
- }
-}
-
-void cl::ParseCommandLineOptions(int &argc, char **argv,
- const char *Overview) {
- assert((!getOpts().empty() || !getPositionalOpts().empty()) &&
- "No options specified, or ParseCommandLineOptions called more"
- " than once!");
- ProgramName = argv[0]; // Save this away safe and snug
- ProgramOverview = Overview;
- bool ErrorParsing = false;
-
- std::map<std::string, Option*> &Opts = getOpts();
- std::vector<Option*> &PositionalOpts = getPositionalOpts();
-
- // Check out the positional arguments to collect information about them.
- unsigned NumPositionalRequired = 0;
- Option *ConsumeAfterOpt = 0;
- if (!PositionalOpts.empty()) {
- if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
- assert(PositionalOpts.size() > 1 &&
- "Cannot specify cl::ConsumeAfter without a positional argument!");
- ConsumeAfterOpt = PositionalOpts[0];
- }
-
- // Calculate how many positional values are _required_.
- bool UnboundedFound = false;
- for (unsigned i = ConsumeAfterOpt != 0, e = PositionalOpts.size();
- i != e; ++i) {
- Option *Opt = PositionalOpts[i];
- if (RequiresValue(Opt))
- ++NumPositionalRequired;
- else if (ConsumeAfterOpt) {
- // ConsumeAfter cannot be combined with "optional" positional options
- // unless there is only one positional argument...
- if (PositionalOpts.size() > 2)
- ErrorParsing |=
- Opt->error(" error - this positional option will never be matched, "
- "because it does not Require a value, and a "
- "cl::ConsumeAfter option is active!");
- } else if (UnboundedFound && !Opt->ArgStr[0]) {
- // This option does not "require" a value... Make sure this option is
- // not specified after an option that eats all extra arguments, or this
- // one will never get any!
- //
- ErrorParsing |= Opt->error(" error - option can never match, because "
- "another positional argument will match an "
- "unbounded number of values, and this option"
- " does not require a value!");
- }
- UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
- }
- }
-
- // PositionalVals - A vector of "positional" arguments we accumulate into to
- // processes at the end...
- //
- std::vector<std::string> PositionalVals;
-
- // If the program has named positional arguments, and the name has been run
- // across, keep track of which positional argument was named. Otherwise put
- // the positional args into the PositionalVals list...
- Option *ActivePositionalArg = 0;
-
- // Loop over all of the arguments... processing them.
- bool DashDashFound = false; // Have we read '--'?
- for (int i = 1; i < argc; ++i) {
- Option *Handler = 0;
- const char *Value = "";
- const char *ArgName = "";
-
- // Check to see if this is a positional argument. This argument is
- // considered to be positional if it doesn't start with '-', if it is "-"
- // itself, or if we have seen "--" already.
- //
- if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
- // Positional argument!
- if (ActivePositionalArg) {
- ProvidePositionalOption(ActivePositionalArg, argv[i]);
- continue; // We are done!
- } else if (!PositionalOpts.empty()) {
- PositionalVals.push_back(argv[i]);
-
- // All of the positional arguments have been fulfulled, give the rest to
- // the consume after option... if it's specified...
- //
- if (PositionalVals.size() >= NumPositionalRequired &&
- ConsumeAfterOpt != 0) {
- for (++i; i < argc; ++i)
- PositionalVals.push_back(argv[i]);
- break; // Handle outside of the argument processing loop...
- }
-
- // Delay processing positional arguments until the end...
- continue;
- }
- } else { // We start with a '-', must be an argument...
- ArgName = argv[i]+1;
- while (*ArgName == '-') ++ArgName; // Eat leading dashes
-
- if (*ArgName == 0 && !DashDashFound) { // Is this the mythical "--"?
- DashDashFound = true; // Yup, take note of that fact...
- continue; // Don't try to process it as an argument itself.
- }
-
- const char *ArgNameEnd = ArgName;
- while (*ArgNameEnd && *ArgNameEnd != '=')
- ++ArgNameEnd; // Scan till end of argument name...
-
- Value = ArgNameEnd;
- if (*Value) // If we have an equals sign...
- ++Value; // Advance to value...
-
- if (*ArgName != 0) {
- std::string RealName(ArgName, ArgNameEnd);
- // Extract arg name part
- std::map<std::string, Option*>::iterator I = Opts.find(RealName);
-
- if (I == Opts.end() && !*Value && RealName.size() > 1) {
- // Check to see if this "option" is really a prefixed or grouped
- // argument...
- //
- unsigned Length = 0;
- Option *PGOpt = getOptionPred(RealName, Length, isPrefixedOrGrouping);
-
- // If the option is a prefixed option, then the value is simply the
- // rest of the name... so fall through to later processing, by
- // setting up the argument name flags and value fields.
- //
- if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) {
- ArgNameEnd = ArgName+Length;
- Value = ArgNameEnd;
- I = Opts.find(std::string(ArgName, ArgNameEnd));
- assert(I->second == PGOpt);
- } else if (PGOpt) {
- // This must be a grouped option... handle all of them now...
- assert(isGrouping(PGOpt) && "Broken getOptionPred!");
-
- do {
- // Move current arg name out of RealName into RealArgName...
- std::string RealArgName(RealName.begin(),RealName.begin()+Length);
- RealName.erase(RealName.begin(), RealName.begin()+Length);
-
- // Because ValueRequired is an invalid flag for grouped arguments,
- // we don't need to pass argc/argv in...
- //
- assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
- "Option can not be cl::Grouping AND cl::ValueRequired!");
- int Dummy;
- ErrorParsing |= ProvideOption(PGOpt, RealArgName.c_str(), "",
- 0, 0, Dummy);
-
- // Get the next grouping option...
- if (!RealName.empty())
- PGOpt = getOptionPred(RealName, Length, isGrouping);
- } while (!RealName.empty() && PGOpt);
-
- if (RealName.empty()) // Processed all of the options, move on
- continue; // to the next argv[] value...
-
- // If RealName is not empty, that means we did not match one of the
- // options! This is an error.
- //
- I = Opts.end();
- }
- }
-
- Handler = I != Opts.end() ? I->second : 0;
- }
- }
-
- if (Handler == 0) {
- std::cerr << "Unknown command line argument '" << argv[i] << "'. Try: '"
- << argv[0] << " --help'\n";
- ErrorParsing = true;
- continue;
- }
-
- // Check to see if this option accepts a comma separated list of values. If
- // it does, we have to split up the value into multiple values...
- if (Handler->getMiscFlags() & CommaSeparated) {
- std::string Val(Value);
- std::string::size_type Pos = Val.find(',');
-
- while (Pos != std::string::npos) {
- // Process the portion before the comma...
- ErrorParsing |= ProvideOption(Handler, ArgName,
- std::string(Val.begin(),
- Val.begin()+Pos).c_str(),
- argc, argv, i);
- // Erase the portion before the comma, AND the comma...
- Val.erase(Val.begin(), Val.begin()+Pos+1);
- Value += Pos+1; // Increment the original value pointer as well...
-
- // Check for another comma...
- Pos = Val.find(',');
- }
- }
-
- // If this is a named positional argument, just remember that it is the
- // active one...
- if (Handler->getFormattingFlag() == cl::Positional)
- ActivePositionalArg = Handler;
- else
- ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);
- }
-
- // Check and handle positional arguments now...
- if (NumPositionalRequired > PositionalVals.size()) {
- std::cerr << "Not enough positional command line arguments specified!\n"
- << "Must specify at least " << NumPositionalRequired
- << " positional arguments: See: " << argv[0] << " --help\n";
- ErrorParsing = true;
-
-
- } else if (ConsumeAfterOpt == 0) {
- // Positional args have already been handled if ConsumeAfter is specified...
- unsigned ValNo = 0, NumVals = PositionalVals.size();
- for (unsigned i = 0, e = PositionalOpts.size(); i != e; ++i) {
- if (RequiresValue(PositionalOpts[i])) {
- ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]);
- --NumPositionalRequired; // We fulfilled our duty...
- }
-
- // If we _can_ give this option more arguments, do so now, as long as we
- // do not give it values that others need. 'Done' controls whether the
- // option even _WANTS_ any more.
- //
- bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required;
- while (NumVals-ValNo > NumPositionalRequired && !Done) {
- switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
- case cl::Optional:
- Done = true; // Optional arguments want _at most_ one value
- // FALL THROUGH
- case cl::ZeroOrMore: // Zero or more will take all they can get...
- case cl::OneOrMore: // One or more will take all they can get...
- ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo++]);
- break;
- default:
- assert(0 && "Internal error, unexpected NumOccurrences flag in "
- "positional argument processing!");
- }
- }
- }
- } else {
- assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
- unsigned ValNo = 0;
- for (unsigned j = 1, e = PositionalOpts.size(); j != e; ++j)
- if (RequiresValue(PositionalOpts[j]))
- ErrorParsing |= ProvidePositionalOption(PositionalOpts[j],
- PositionalVals[ValNo++]);
-
- // Handle the case where there is just one positional option, and it's
- // optional. In this case, we want to give JUST THE FIRST option to the
- // positional option and keep the rest for the consume after. The above
- // loop would have assigned no values to positional options in this case.
- //
- if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty())
- ErrorParsing |= ProvidePositionalOption(PositionalOpts[1],
- PositionalVals[ValNo++]);
-
- // Handle over all of the rest of the arguments to the
- // cl::ConsumeAfter command line option...
- for (; ValNo != PositionalVals.size(); ++ValNo)
- ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt,
- PositionalVals[ValNo]);
- }
-
- // Loop over args and make sure all required args are specified!
- for (std::map<std::string, Option*>::iterator I = Opts.begin(),
- E = Opts.end(); I != E; ++I) {
- switch (I->second->getNumOccurrencesFlag()) {
- case Required:
- case OneOrMore:
- if (I->second->getNumOccurrences() == 0) {
- I->second->error(" must be specified at least once!");
- ErrorParsing = true;
- }
- // Fall through
- default:
- break;
- }
- }
-
- // Free all of the memory allocated to the map. Command line options may only
- // be processed once!
- delete CommandLineOptions;
- CommandLineOptions = 0;
- PositionalOpts.clear();
-
- // If we had an error processing our arguments, don't let the program execute
- if (ErrorParsing) exit(1);
-}
-
-//===----------------------------------------------------------------------===//
-// Option Base class implementation
-//
-
-bool Option::error(std::string Message, const char *ArgName) {
- if (ArgName == 0) ArgName = ArgStr;
- if (ArgName[0] == 0)
- std::cerr << HelpStr; // Be nice for positional arguments
- else
- std::cerr << "-" << ArgName;
- std::cerr << " option" << Message << "\n";
- return true;
-}
-
-bool Option::addOccurrence(const char *ArgName, const std::string &Value) {
- NumOccurrences++; // Increment the number of times we have been seen
-
- switch (getNumOccurrencesFlag()) {
- case Optional:
- if (NumOccurrences > 1)
- return error(": may only occur zero or one times!", ArgName);
- break;
- case Required:
- if (NumOccurrences > 1)
- return error(": must occur exactly one time!", ArgName);
- // Fall through
- case OneOrMore:
- case ZeroOrMore:
- case ConsumeAfter: break;
- default: return error(": bad num occurrences flag value!");
- }
-
- return handleOccurrence(ArgName, Value);
-}
-
-// addArgument - Tell the system that this Option subclass will handle all
-// occurrences of -ArgStr on the command line.
-//
-void Option::addArgument(const char *ArgStr) {
- if (ArgStr[0])
- AddArgument(ArgStr, this);
-
- if (getFormattingFlag() == Positional)
- getPositionalOpts().push_back(this);
- else if (getNumOccurrencesFlag() == ConsumeAfter) {
- if (!getPositionalOpts().empty() &&
- getPositionalOpts().front()->getNumOccurrencesFlag() == ConsumeAfter)
- error("Cannot specify more than one option with cl::ConsumeAfter!");
- getPositionalOpts().insert(getPositionalOpts().begin(), this);
- }
-}
-
-void Option::removeArgument(const char *ArgStr) {
- if (ArgStr[0])
- RemoveArgument(ArgStr, this);
-
- if (getFormattingFlag() == Positional) {
- std::vector<Option*>::iterator I =
- std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
- assert(I != getPositionalOpts().end() && "Arg not registered!");
- getPositionalOpts().erase(I);
- } else if (getNumOccurrencesFlag() == ConsumeAfter) {
- assert(!getPositionalOpts().empty() && getPositionalOpts()[0] == this &&
- "Arg not registered correctly!");
- getPositionalOpts().erase(getPositionalOpts().begin());
- }
-}
-
-
-// getValueStr - Get the value description string, using "DefaultMsg" if nothing
-// has been specified yet.
-//
-static const char *getValueStr(const Option &O, const char *DefaultMsg) {
- if (O.ValueStr[0] == 0) return DefaultMsg;
- return O.ValueStr;
-}
-
-//===----------------------------------------------------------------------===//
-// cl::alias class implementation
-//
-
-// Return the width of the option tag for printing...
-unsigned alias::getOptionWidth() const {
- return std::strlen(ArgStr)+6;
-}
-
-// Print out the option for the alias...
-void alias::printOptionInfo(unsigned GlobalWidth) const {
- unsigned L = std::strlen(ArgStr);
- std::cerr << " -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
- << HelpStr << "\n";
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// Parser Implementation code...
-//
-
-// basic_parser implementation
-//
-
-// Return the width of the option tag for printing...
-unsigned basic_parser_impl::getOptionWidth(const Option &O) const {
- unsigned Len = std::strlen(O.ArgStr);
- if (const char *ValName = getValueName())
- Len += std::strlen(getValueStr(O, ValName))+3;
-
- return Len + 6;
-}
-
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
-//
-void basic_parser_impl::printOptionInfo(const Option &O,
- unsigned GlobalWidth) const {
- std::cerr << " -" << O.ArgStr;
-
- if (const char *ValName = getValueName())
- std::cerr << "=<" << getValueStr(O, ValName) << ">";
-
- std::cerr << std::string(GlobalWidth-getOptionWidth(O), ' ') << " - "
- << O.HelpStr << "\n";
-}
-
-
-
-
-// parser<bool> implementation
-//
-bool parser<bool>::parse(Option &O, const char *ArgName,
- const std::string &Arg, bool &Value) {
- if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
- Arg == "1") {
- Value = true;
- } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
- Value = false;
- } else {
- return O.error(": '" + Arg +
- "' is invalid value for boolean argument! Try 0 or 1");
- }
- return false;
-}
-
-// parser<int> implementation
-//
-bool parser<int>::parse(Option &O, const char *ArgName,
- const std::string &Arg, int &Value) {
- char *End;
- Value = (int)strtol(Arg.c_str(), &End, 0);
- if (*End != 0)
- return O.error(": '" + Arg + "' value invalid for integer argument!");
- return false;
-}
-
-// parser<unsigned> implementation
-//
-bool parser<unsigned>::parse(Option &O, const char *ArgName,
- const std::string &Arg, unsigned &Value) {
- char *End;
- long long int V = strtoll(Arg.c_str(), &End, 0);
- Value = (unsigned)V;
- if (*End != 0 || V < 0 || Value != V)
- return O.error(": '" + Arg + "' value invalid for uint argument!");
- return false;
-}
-
-// parser<double>/parser<float> implementation
-//
-static bool parseDouble(Option &O, const std::string &Arg, double &Value) {
- const char *ArgStart = Arg.c_str();
- char *End;
- Value = strtod(ArgStart, &End);
- if (*End != 0)
- return O.error(": '" +Arg+ "' value invalid for floating point argument!");
- return false;
-}
-
-bool parser<double>::parse(Option &O, const char *AN,
- const std::string &Arg, double &Val) {
- return parseDouble(O, Arg, Val);
-}
-
-bool parser<float>::parse(Option &O, const char *AN,
- const std::string &Arg, float &Val) {
- double dVal;
- if (parseDouble(O, Arg, dVal))
- return true;
- Val = (float)dVal;
- return false;
-}
-
-
-
-// generic_parser_base implementation
-//
-
-// findOption - Return the option number corresponding to the specified
-// argument string. If the option is not found, getNumOptions() is returned.
-//
-unsigned generic_parser_base::findOption(const char *Name) {
- unsigned i = 0, e = getNumOptions();
- std::string N(Name);
-
- while (i != e)
- if (getOption(i) == N)
- return i;
- else
- ++i;
- return e;
-}
-
-
-// Return the width of the option tag for printing...
-unsigned generic_parser_base::getOptionWidth(const Option &O) const {
- if (O.hasArgStr()) {
- unsigned Size = std::strlen(O.ArgStr)+6;
- for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- Size = std::max(Size, (unsigned)std::strlen(getOption(i))+8);
- return Size;
- } else {
- unsigned BaseSize = 0;
- for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- BaseSize = std::max(BaseSize, (unsigned)std::strlen(getOption(i))+8);
- return BaseSize;
- }
-}
-
-// printOptionInfo - Print out information about this option. The
-// to-be-maintained width is specified.
-//
-void generic_parser_base::printOptionInfo(const Option &O,
- unsigned GlobalWidth) const {
- if (O.hasArgStr()) {
- unsigned L = std::strlen(O.ArgStr);
- std::cerr << " -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ')
- << " - " << O.HelpStr << "\n";
-
- for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
- unsigned NumSpaces = GlobalWidth-strlen(getOption(i))-8;
- std::cerr << " =" << getOption(i) << std::string(NumSpaces, ' ')
- << " - " << getDescription(i) << "\n";
- }
- } else {
- if (O.HelpStr[0])
- std::cerr << " " << O.HelpStr << "\n";
- for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
- unsigned L = std::strlen(getOption(i));
- std::cerr << " -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
- << " - " << getDescription(i) << "\n";
- }
- }
-}
-
-
-//===----------------------------------------------------------------------===//
-// --help and --help-hidden option implementation
-//
-namespace {
-
-class HelpPrinter {
- unsigned MaxArgLen;
- const Option *EmptyArg;
- const bool ShowHidden;
-
- // isHidden/isReallyHidden - Predicates to be used to filter down arg lists.
- inline static bool isHidden(std::pair<std::string, Option *> &OptPair) {
- return OptPair.second->getOptionHiddenFlag() >= Hidden;
- }
- inline static bool isReallyHidden(std::pair<std::string, Option *> &OptPair) {
- return OptPair.second->getOptionHiddenFlag() == ReallyHidden;
- }
-
-public:
- HelpPrinter(bool showHidden) : ShowHidden(showHidden) {
- EmptyArg = 0;
- }
-
- void operator=(bool Value) {
- if (Value == false) return;
-
- // Copy Options into a vector so we can sort them as we like...
- std::vector<std::pair<std::string, Option*> > Options;
- copy(getOpts().begin(), getOpts().end(), std::back_inserter(Options));
-
- // Eliminate Hidden or ReallyHidden arguments, depending on ShowHidden
- Options.erase(std::remove_if(Options.begin(), Options.end(),
- std::ptr_fun(ShowHidden ? isReallyHidden : isHidden)),
- Options.end());
-
- // Eliminate duplicate entries in table (from enum flags options, f.e.)
- { // Give OptionSet a scope
- std::set<Option*> OptionSet;
- for (unsigned i = 0; i != Options.size(); ++i)
- if (OptionSet.count(Options[i].second) == 0)
- OptionSet.insert(Options[i].second); // Add new entry to set
- else
- Options.erase(Options.begin()+i--); // Erase duplicate
- }
-
- if (ProgramOverview)
- std::cerr << "OVERVIEW:" << ProgramOverview << "\n";
-
- std::cerr << "USAGE: " << ProgramName << " [options]";
-
- // Print out the positional options...
- std::vector<Option*> &PosOpts = getPositionalOpts();
- Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists...
- if (!PosOpts.empty() && PosOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
- CAOpt = PosOpts[0];
-
- for (unsigned i = CAOpt != 0, e = PosOpts.size(); i != e; ++i) {
- if (PosOpts[i]->ArgStr[0])
- std::cerr << " --" << PosOpts[i]->ArgStr;
- std::cerr << " " << PosOpts[i]->HelpStr;
- }
-
- // Print the consume after option info if it exists...
- if (CAOpt) std::cerr << " " << CAOpt->HelpStr;
-
- std::cerr << "\n\n";
-
- // Compute the maximum argument length...
- MaxArgLen = 0;
- for (unsigned i = 0, e = Options.size(); i != e; ++i)
- MaxArgLen = std::max(MaxArgLen, Options[i].second->getOptionWidth());
-
- std::cerr << "OPTIONS:\n";
- for (unsigned i = 0, e = Options.size(); i != e; ++i)
- Options[i].second->printOptionInfo(MaxArgLen);
-
- // Halt the program if help information is printed
- exit(1);
- }
-};
-
-
-
-// Define the two HelpPrinter instances that are used to print out help, or
-// help-hidden...
-//
-HelpPrinter NormalPrinter(false);
-HelpPrinter HiddenPrinter(true);
-
-cl::opt<HelpPrinter, true, parser<bool> >
-HOp("help", cl::desc("display available options (--help-hidden for more)"),
- cl::location(NormalPrinter), cl::ValueDisallowed);
-
-cl::opt<HelpPrinter, true, parser<bool> >
-HHOp("help-hidden", cl::desc("display all available options"),
- cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
-
-} // End anonymous namespace
diff --git a/support/lib/Support/ConstantRange.cpp b/support/lib/Support/ConstantRange.cpp
deleted file mode 100644
index c9d8ae6fbb..0000000000
--- a/support/lib/Support/ConstantRange.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-//===-- ConstantRange.cpp - ConstantRange implementation ------------------===//
-//
-// Represent a range of possible values that may occur when the program is run
-// for an integral value. This keeps track of a lower and upper bound for the
-// constant, which MAY wrap around the end of the numeric range. To do this, it
-// keeps track of a [lower, upper) bound, which specifies an interval just like
-// STL iterators. When used with boolean values, the following are important
-// ranges (other integral ranges use min/max values for special range values):
-//
-// [F, F) = {} = Empty set
-// [T, F) = {T}
-// [F, T) = {F}
-// [T, T) = {F, T} = Full set
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/ConstantRange.h"
-#include "llvm/Type.h"
-#include "llvm/Instruction.h"
-#include "llvm/ConstantHandling.h"
-
-/// Initialize a full (the default) or empty set for the specified type.
-///
-ConstantRange::ConstantRange(const Type *Ty, bool Full) {
- assert(Ty->isIntegral() &&
- "Cannot make constant range of non-integral type!");
- if (Full)
- Lower = Upper = ConstantIntegral::getMaxValue(Ty);
- else
- Lower = Upper = ConstantIntegral::getMinValue(Ty);
-}
-
-/// Initialize a range of values explicitly... this will assert out if
-/// Lower==Upper and Lower != Min or Max for its type (or if the two constants
-/// have different types)
-///
-ConstantRange::ConstantRange(ConstantIntegral *L,
- ConstantIntegral *U) : Lower(L), Upper(U) {
- assert(Lower->getType() == Upper->getType() &&
- "Incompatible types for ConstantRange!");
-
- // Make sure that if L & U are equal that they are either Min or Max...
- assert((L != U || (L == ConstantIntegral::getMaxValue(L->getType()) ||
- L == ConstantIntegral::getMinValue(L->getType()))) &&
- "Lower == Upper, but they aren't min or max for type!");
-}
-
-static ConstantIntegral *Next(ConstantIntegral *CI) {
- if (CI->getType() == Type::BoolTy)
- return CI == ConstantBool::True ? ConstantBool::False : ConstantBool::True;
-
- // Otherwise use operator+ in the ConstantHandling Library.
- Constant *Result = *ConstantInt::get(CI->getType(), 1) + *CI;
- assert(Result && "ConstantHandling not implemented for integral plus!?");
- return cast<ConstantIntegral>(Result);
-}
-
-/// Initialize a set of values that all satisfy the condition with C.
-///
-ConstantRange::ConstantRange(unsigned SetCCOpcode, ConstantIntegral *C) {
- switch (SetCCOpcode) {
- default: assert(0 && "Invalid SetCC opcode to ConstantRange ctor!");
- case Instruction::SetEQ: Lower = C; Upper = Next(C); return;
- case Instruction::SetNE: Upper = C; Lower = Next(C); return;
- case Instruction::SetLT:
- Lower = ConstantIntegral::getMinValue(C->getType());
- Upper = C;
- return;
- case Instruction::SetGT:
- Lower = Next(C);
- Upper = ConstantIntegral::getMinValue(C->getType()); // Min = Next(Max)
- return;
- case Instruction::SetLE:
- Lower = ConstantIntegral::getMinValue(C->getType());
- Upper = Next(C);
- return;
- case Instruction::SetGE:
- Lower = C;
- Upper = ConstantIntegral::getMinValue(C->getType()); // Min = Next(Max)
- return;
- }
-}
-
-/// getType - Return the LLVM data type of this range.
-///
-const Type *ConstantRange::getType() const { return Lower->getType(); }
-
-/// isFullSet - Return true if this set contains all of the elements possible
-/// for this data-type
-bool ConstantRange::isFullSet() const {
- return Lower == Upper && Lower == ConstantIntegral::getMaxValue(getType());
-}
-
-/// isEmptySet - Return true if this set contains no members.
-///
-bool ConstantRange::isEmptySet() const {
- return Lower == Upper && Lower == ConstantIntegral::getMinValue(getType());
-}
-
-/// isWrappedSet - Return true if this set wraps around the top of the range,
-/// for example: [100, 8)
-///
-bool ConstantRange::isWrappedSet() const {
- return (*(Constant*)Lower > *(Constant*)Upper)->getValue();
-}
-
-
-/// getSingleElement - If this set contains a single element, return it,
-/// otherwise return null.
-ConstantIntegral *ConstantRange::getSingleElement() const {
- if (Upper == Next(Lower)) // Is it a single element range?
- return Lower;
- return 0;
-}
-
-/// getSetSize - Return the number of elements in this set.
-///
-uint64_t ConstantRange::getSetSize() const {
- if (isEmptySet()) return 0;
- if (getType() == Type::BoolTy) {
- if (Lower != Upper) // One of T or F in the set...
- return 1;
- return 2; // Must be full set...
- }
-
- // Simply subtract the bounds...
- Constant *Result = *(Constant*)Upper - *(Constant*)Lower;
- assert(Result && "Subtraction of constant integers not implemented?");
- return cast<ConstantInt>(Result)->getRawValue();
-}
-
-
-
-
-// intersect1Wrapped - This helper function is used to intersect two ranges when
-// it is known that LHS is wrapped and RHS isn't.
-//
-static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
- const ConstantRange &RHS) {
- assert(LHS.isWrappedSet() && !RHS.isWrappedSet());
-
- // Check to see if we overlap on the Left side of RHS...
- //
- if ((*(Constant*)RHS.getLower() < *(Constant*)LHS.getUpper())->getValue()) {
- // We do overlap on the left side of RHS, see if we overlap on the right of
- // RHS...
- if ((*(Constant*)RHS.getUpper() > *(Constant*)LHS.getLower())->getValue()) {
- // Ok, the result overlaps on both the left and right sides. See if the
- // resultant interval will be smaller if we wrap or not...
- //
- if (LHS.getSetSize() < RHS.getSetSize())
- return LHS;
- else
- return RHS;
-
- } else {
- // No overlap on the right, just on the left.
- return ConstantRange(RHS.getLower(), LHS.getUpper());
- }
-
- } else {
- // We don't overlap on the left side of RHS, see if we overlap on the right
- // of RHS...
- if ((*(Constant*)RHS.getUpper() > *(Constant*)LHS.getLower())->getValue()) {
- // Simple overlap...
- return ConstantRange(LHS.getLower(), RHS.getUpper());
- } else {
- // No overlap...
- return ConstantRange(LHS.getType(), false);
- }
- }
-}
-
-static ConstantIntegral *Min(ConstantIntegral *A, ConstantIntegral *B) {
- if ((*(Constant*)A < *(Constant*)B)->getValue())
- return A;
- return B;
-}
-static ConstantIntegral *Max(ConstantIntegral *A, ConstantIntegral *B) {
- if ((*(Constant*)A > *(Constant*)B)->getValue())
- return A;
- return B;
-}
-
-
-/// intersect - Return the range that results from the intersection of this
-/// range with another range.
-///
-ConstantRange ConstantRange::intersectWith(const ConstantRange &CR) const {
- assert(getType() == CR.getType() && "ConstantRange types don't agree!");
- // Handle common special cases
- if (isEmptySet() || CR.isFullSet()) return *this;
- if (isFullSet() || CR.isEmptySet()) return CR;
-
- if (!isWrappedSet()) {
- if (!CR.isWrappedSet()) {
- ConstantIntegral *L = Max(Lower, CR.Lower);
- ConstantIntegral *U = Min(Upper, CR.Upper);
-
- if ((*L < *U)->getValue()) // If range isn't empty...
- return ConstantRange(L, U);
- else
- return ConstantRange(getType(), false); // Otherwise, return empty set
- } else
- return intersect1Wrapped(CR, *this);
- } else { // We know "this" is wrapped...
- if (!CR.isWrappedSet())
- return intersect1Wrapped(*this, CR);
- else {
- // Both ranges are wrapped...
- ConstantIntegral *L = Max(Lower, CR.Lower);
- ConstantIntegral *U = Min(Upper, CR.Upper);
- return ConstantRange(L, U);
- }
- }
- return *this;
-}
-
-/// union - Return the range that results from the union of this range with
-/// another range. The resultant range is guaranteed to include the elements of
-/// both sets, but may contain more. For example, [3, 9) union [12,15) is [3,
-/// 15), which includes 9, 10, and 11, which were not included in either set
-/// before.
-///
-ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const {
- assert(getType() == CR.getType() && "ConstantRange types don't agree!");
-
- assert(0 && "Range union not implemented yet!");
-
- return *this;
-}
-
-/// print - Print out the bounds to a stream...
-///
-void ConstantRange::print(std::ostream &OS) const {
- OS << "[" << Lower << "," << Upper << " )";
-}
-
-/// dump - Allow printing from a debugger easily...
-///
-void ConstantRange::dump() const {
- print(std::cerr);
-}
diff --git a/support/lib/Support/Debug.cpp b/support/lib/Support/Debug.cpp
deleted file mode 100644
index f87cddfe4e..0000000000
--- a/support/lib/Support/Debug.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===-- Debug.cpp - An easy way to add debug output to your code ----------===//
-//
-// This file implements a handle way of adding debugging information to your
-// code, without it being enabled all of the time, and without having to add
-// command line options to enable it.
-//
-// In particular, just wrap your code with the DEBUG() macro, and it will be
-// enabled automatically if you specify '-debug' on the command-line.
-// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
-// that your debug code belongs to class "foo". Then, on the command line, you
-// can specify '-debug-only=foo' to enable JUST the debug information for the
-// foo class.
-//
-// When compiling in release mode, the -debug-* options and all code in DEBUG()
-// statements disappears, so it does not effect the runtime of the code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/Statistic.h"
-#include "Support/CommandLine.h"
-
-bool DebugFlag; // DebugFlag - Exported boolean set by the -debug option
-
-namespace {
-#ifndef NDEBUG
- // -debug - Command line option to enable the DEBUG statements in the passes.
- // This flag may only be enabled in debug builds.
- cl::opt<bool, true>
- Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
- cl::location(DebugFlag));
-
- std::string CurrentDebugType;
- struct DebugOnlyOpt {
- void operator=(const std::string &Val) const {
- DebugFlag |= !Val.empty();
- CurrentDebugType = Val;
- }
- } DebugOnlyOptLoc;
-
- cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
- DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"),
- cl::Hidden, cl::value_desc("debug string"),
- cl::location(DebugOnlyOptLoc), cl::ValueRequired);
-#endif
-}
-
-// isCurrentDebugType - Return true if the specified string is the debug type
-// specified on the command line, or if none was specified on the command line
-// with the -debug-only=X option.
-//
-bool isCurrentDebugType(const char *DebugType) {
-#ifndef NDEBUG
- return CurrentDebugType.empty() || DebugType == CurrentDebugType;
-#else
- return false;
-#endif
-}
diff --git a/support/lib/Support/FileUtilities.cpp b/support/lib/Support/FileUtilities.cpp
deleted file mode 100644
index ca4603628c..0000000000
--- a/support/lib/Support/FileUtilities.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//===- Support/FileUtilities.cpp - File System Utilities ------------------===//
-//
-// This file implements a family of utility functions which are useful for doing
-// various things with files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/FileUtilities.h"
-#include "Config/unistd.h"
-#include "Config/sys/stat.h"
-#include "Config/sys/types.h"
-#include <fstream>
-#include <iostream>
-#include <cstdio>
-
-/// DiffFiles - Compare the two files specified, returning true if they are
-/// different or if there is a file error. If you specify a string to fill in
-/// for the error option, it will set the string to an error message if an error
-/// occurs, allowing the caller to distinguish between a failed diff and a file
-/// system error.
-///
-bool DiffFiles(const std::string &FileA, const std::string &FileB,
- std::string *Error) {
- std::ifstream FileAStream(FileA.c_str());
- if (!FileAStream) {
- if (Error) *Error = "Couldn't open file '" + FileA + "'";
- return true;
- }
-
- std::ifstream FileBStream(FileB.c_str());
- if (!FileBStream) {
- if (Error) *Error = "Couldn't open file '" + FileB + "'";
- return true;
- }
-
- // Compare the two files...
- int C1, C2;
- do {
- C1 = FileAStream.get();
- C2 = FileBStream.get();
- if (C1 != C2) return true;
- } while (C1 != EOF);
-
- return false;
-}
-
-
-/// MoveFileOverIfUpdated - If the file specified by New is different than Old,
-/// or if Old does not exist, move the New file over the Old file. Otherwise,
-/// remove the New file.
-///
-void MoveFileOverIfUpdated(const std::string &New, const std::string &Old) {
- if (DiffFiles(New, Old)) {
- if (std::rename(New.c_str(), Old.c_str()))
- std::cerr << "Error renaming '" << New << "' to '" << Old << "'!\n";
- } else {
- std::remove(New.c_str());
- }
-}
-
-/// removeFile - Delete the specified file
-///
-void removeFile(const std::string &Filename) {
- std::remove(Filename.c_str());
-}
-
-/// getUniqueFilename - Return a filename with the specified prefix. If the
-/// file does not exist yet, return it, otherwise add a suffix to make it
-/// unique.
-///
-std::string getUniqueFilename(const std::string &FilenameBase) {
- if (!std::ifstream(FilenameBase.c_str()))
- return FilenameBase; // Couldn't open the file? Use it!
-
- // Create a pattern for mkstemp...
- char *FNBuffer = new char[FilenameBase.size()+8];
- strcpy(FNBuffer, FilenameBase.c_str());
- strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX");
-
- // Agree on a temporary file name to use....
- int TempFD;
- if ((TempFD = mkstemp(FNBuffer)) == -1) {
- std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current "
- << " directory!\n";
- exit(1);
- }
-
- // We don't need to hold the temp file descriptor... we will trust that no one
- // will overwrite/delete the file while we are working on it...
- close(TempFD);
- std::string Result(FNBuffer);
- delete[] FNBuffer;
- return Result;
-}
-
-///
-/// Method: MakeFileExecutable ()
-///
-/// Description:
-/// This method makes the specified filename executable by giving it
-/// execute permission. It respects the umask value of the process, and it
-/// does not enable any unnecessary access bits.
-///
-/// Algorithm:
-/// o Get file's current permissions.
-/// o Get the process's current umask.
-/// o Take the set of all execute bits and disable those found in the umask.
-/// o Add the remaining permissions to the file's permissions.
-///
-bool
-MakeFileExecutable (const std::string & Filename)
-{
- // Permissions masking value of the user
- mode_t mask;
-
- // Permissions currently enabled on the file
- struct stat fstat;
-
- //
- // Grab the umask value from the operating system. We want to use it when
- // changing the file's permissions.
- //
- // Note:
- // Umask() is one of those annoying system calls. You have to call it
- // to get the current value and then set it back.
- //
- mask = umask (0x777);
- umask (mask);
-
- //
- // Go fetch the file's current permission bits. We want to *add* execute
- // access to the file.
- //
- if ((stat (Filename.c_str(), &fstat)) == -1)
- {
- return false;
- }
-
- //
- // Make the file executable...
- //
- if ((chmod(Filename.c_str(), (fstat.st_mode | (0111 & ~mask)))) == -1)
- {
- return false;
- }
-
- return true;
-}
-
-///
-/// Method: MakeFileReadable ()
-///
-/// Description:
-/// This method makes the specified filename readable by giving it
-/// read permission. It respects the umask value of the process, and it
-/// does not enable any unnecessary access bits.
-///
-/// Algorithm:
-/// o Get file's current permissions.
-/// o Get the process's current umask.
-/// o Take the set of all read bits and disable those found in the umask.
-/// o Add the remaining permissions to the file's permissions.
-///
-bool
-MakeFileReadable (const std::string & Filename)
-{
- // Permissions masking value of the user
- mode_t mask;
-
- // Permissions currently enabled on the file
- struct stat fstat;
-
- //
- // Grab the umask value from the operating system. We want to use it when
- // changing the file's permissions.
- //
- // Note:
- // Umask() is one of those annoying system calls. You have to call it
- // to get the current value and then set it back.
- //
- mask = umask (0x777);
- umask (mask);
-
- //
- // Go fetch the file's current permission bits. We want to *add* execute
- // access to the file.
- //
- if ((stat (Filename.c_str(), &fstat)) == -1)
- {
- return false;
- }
-
- //
- // Make the file executable...
- //
- if ((chmod(Filename.c_str(), (fstat.st_mode | (0444 & ~mask)))) == -1)
- {
- return false;
- }
-
- return true;
-}
-
diff --git a/support/lib/Support/LeakDetector.cpp b/support/lib/Support/LeakDetector.cpp
deleted file mode 100644
index ecc4868d2e..0000000000
--- a/support/lib/Support/LeakDetector.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
-//
-// This file implements the LeakDetector class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/LeakDetector.h"
-#include "llvm/Value.h"
-#include <set>
-
-// Lazily allocate set so that release build doesn't have to do anything.
-static std::set<const void*> *Objects = 0;
-static std::set<const Value*> *LLVMObjects = 0;
-
-// Because the most common usage pattern, by far, is to add a garbage object,
-// then remove it immediately, we optimize this case. When an object is added,
-// it is not added to the set immediately, it is added to the CachedValue Value.
-// If it is immediately removed, no set search need be performed.
-//
-static const Value *CachedValue;
-
-void LeakDetector::addGarbageObjectImpl(void *Object) {
- if (Objects == 0)
- Objects = new std::set<const void*>();
- assert(Objects->count(Object) == 0 && "Object already in set!");
- Objects->insert(Object);
-}
-
-void LeakDetector::removeGarbageObjectImpl(void *Object) {
- if (Objects)
- Objects->erase(Object);
-}
-
-void LeakDetector::addGarbageObjectImpl(const Value *Object) {
- if (CachedValue) {
- if (LLVMObjects == 0)
- LLVMObjects = new std::set<const Value*>();
- assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!");
- LLVMObjects->insert(CachedValue);
- }
- CachedValue = Object;
-}
-
-void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
- if (Object == CachedValue)
- CachedValue = 0; // Cache hit!
- else if (LLVMObjects)
- LLVMObjects->erase(Object);
-}
-
-void LeakDetector::checkForGarbageImpl(const std::string &Message) {
- if (CachedValue) // Flush the cache to the set...
- addGarbageObjectImpl((Value*)0);
-
- assert(CachedValue == 0 && "No value should be cached anymore!");
-
- if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){
- std::cerr << "Leaked objects found: " << Message << "\n";
-
- if (Objects && !Objects->empty()) {
- std::cerr << " Non-Value objects leaked:";
- for (std::set<const void*>::iterator I = Objects->begin(),
- E = Objects->end(); I != E; ++I)
- std::cerr << " " << *I;
- }
-
- if (LLVMObjects && !LLVMObjects->empty()) {
- std::cerr << " LLVM Value subclasses leaked:";
- for (std::set<const Value*>::iterator I = LLVMObjects->begin(),
- E = LLVMObjects->end(); I != E; ++I)
- std::cerr << **I << "\n";
- }
-
- std::cerr << "This is probably because you removed an LLVM value "
- << "(Instruction, BasicBlock, \netc), but didn't delete it. "
- << "Please check your code for memory leaks.\n";
-
- // Clear out results so we don't get duplicate warnings on next call...
- delete Objects; delete LLVMObjects;
- Objects = 0; LLVMObjects = 0;
- }
-}
diff --git a/support/lib/Support/Makefile b/support/lib/Support/Makefile
deleted file mode 100644
index d52d7315bf..0000000000
--- a/support/lib/Support/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-LEVEL = ../../..
-LIBRARYNAME = support
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
diff --git a/support/lib/Support/Mangler.cpp b/support/lib/Support/Mangler.cpp
deleted file mode 100644
index d9186a9c93..0000000000
--- a/support/lib/Support/Mangler.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
-//
-// Unified name mangler for CWriter and assembly backends.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Mangler.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
-#include "Support/StringExtras.h"
-
-static char HexDigit(int V) {
- return V < 10 ? V+'0' : V+'A'-10;
-}
-
-static std::string MangleLetter(unsigned char C) {
- return std::string("_")+HexDigit(C >> 4) + HexDigit(C & 15) + "_";
-}
-
-/// makeNameProper - We don't want identifier names non-C-identifier characters
-/// in them, so mangle them as appropriate.
-///
-std::string Mangler::makeNameProper(const std::string &X) {
- std::string Result;
-
- // Mangle the first letter specially, don't allow numbers...
- if ((X[0] < 'a' || X[0] > 'z') && (X[0] < 'A' || X[0] > 'Z') && X[0] != '_')
- Result += MangleLetter(X[0]);
- else
- Result += X[0];
-
- for (std::string::const_iterator I = X.begin()+1, E = X.end(); I != E; ++I)
- if ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') &&
- (*I < '0' || *I > '9') && *I != '_')
- Result += MangleLetter(*I);
- else
- Result += *I;
- return Result;
-}
-
-std::string Mangler::getValueName(const Value *V) {
- // Check to see whether we've already named V.
- ValueMap::iterator VI = Memo.find(V);
- if (VI != Memo.end()) {
- return VI->second; // Return the old name for V.
- }
-
- std::string name;
- if (V->hasName()) { // Print out the label if it exists...
- // Name mangling occurs as follows:
- // - If V is not a global, mangling always occurs.
- // - Otherwise, mangling occurs when any of the following are true:
- // 1) V has internal linkage
- // 2) V's name would collide if it is not mangled.
- //
- const GlobalValue* gv = dyn_cast<GlobalValue>(V);
- if (gv && !gv->hasInternalLinkage() && !MangledGlobals.count(gv)) {
- name = makeNameProper(gv->getName());
- if (AddUnderscorePrefix) name = "_" + name;
- } else {
- // Non-global, or global with internal linkage / colliding name
- // -> mangle.
- name = "l" + utostr(V->getType()->getUniqueID()) + "_" +
- makeNameProper(V->getName());
- }
- } else {
- name = "ltmp_" + utostr(Count++) + "_"
- + utostr(V->getType()->getUniqueID());
- }
-
- Memo[V] = name;
- return name;
-}
-
-Mangler::Mangler(Module &m, bool addUnderscorePrefix)
- : M(m), AddUnderscorePrefix(addUnderscorePrefix) {
- // Calculate which global values have names that will collide when we throw
- // away type information.
- std::set<std::string> FoundNames;
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
-
- for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
- if (I->hasName()) // If the global has a name...
- if (FoundNames.count(I->getName())) // And the name is already used
- MangledGlobals.insert(I); // Mangle the name
- else
- FoundNames.insert(I->getName()); // Otherwise, keep track of name
-}
-
diff --git a/support/lib/Support/PluginLoader.cpp b/support/lib/Support/PluginLoader.cpp
deleted file mode 100644
index 76c5e8197d..0000000000
--- a/support/lib/Support/PluginLoader.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- PluginLoader.cpp - Implement -load command line option ------------===//
-//
-// This file implements the -load <plugin> command line option processor. When
-// linked into a program, this new command line option is available that allows
-// users to load shared objects into the running program.
-//
-// Note that there are no symbols exported by the .o file generated for this
-// .cpp file. Because of this, a program must link against support.o instead of
-// support.a: otherwise this translation unit will not be included.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/CommandLine.h"
-#include "Config/dlfcn.h"
-#include "Config/link.h"
-#include <iostream>
-
-namespace {
- struct PluginLoader {
- void operator=(const std::string &Filename) {
- if (dlopen(Filename.c_str(), RTLD_NOW|RTLD_GLOBAL) == 0)
- std::cerr << "Error opening '" << Filename << "': " << dlerror()
- << "\n -load request ignored.\n";
- }
- };
-}
-
-// This causes operator= above to be invoked for every -load option.
-static cl::opt<PluginLoader, false, cl::parser<std::string> >
-LoadOpt("load", cl::ZeroOrMore, cl::value_desc("plugin.so"),
- cl::desc("Load the specified plugin"));
diff --git a/support/lib/Support/Signals.cpp b/support/lib/Support/Signals.cpp
deleted file mode 100644
index 563147eabf..0000000000
--- a/support/lib/Support/Signals.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===- Signals.cpp - Signal Handling support ------------------------------===//
-//
-// This file defines some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/Signals.h"
-#include <vector>
-#include <algorithm>
-#include <cstdlib>
-#include <cstdio>
-#include <signal.h>
-#include "Config/config.h" // Get the signal handler return type
-
-static std::vector<std::string> FilesToRemove;
-
-// IntSigs - Signals that may interrupt the program at any time.
-static const int IntSigs[] = {
- SIGHUP, SIGINT, SIGQUIT, SIGKILL, SIGPIPE, SIGTERM, SIGUSR1, SIGUSR2
-};
-static const int *IntSigsEnd = IntSigs + sizeof(IntSigs)/sizeof(IntSigs[0]);
-
-// KillSigs - Signals that are synchronous with the program that will cause it
-// to die.
-static const int KillSigs[] = {
- SIGILL, SIGTRAP, SIGABRT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGXCPU, SIGXFSZ
-#ifdef SIGEMT
- , SIGEMT
-#endif
-};
-static const int *KillSigsEnd = KillSigs + sizeof(KillSigs)/sizeof(KillSigs[0]);
-
-
-// SignalHandler - The signal handler that runs...
-static RETSIGTYPE SignalHandler(int Sig) {
- while (!FilesToRemove.empty()) {
- std::remove(FilesToRemove.back().c_str());
- FilesToRemove.pop_back();
- }
-
- if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd)
- exit(1); // If this is an interrupt signal, exit the program
-
- // Otherwise if it is a fault (like SEGV) reissue the signal to die...
- signal(Sig, SIG_DFL);
-}
-
-static void RegisterHandler(int Signal) { signal(Signal, SignalHandler); }
-
-// RemoveFileOnSignal - The public API
-void RemoveFileOnSignal(const std::string &Filename) {
- FilesToRemove.push_back(Filename);
-
- std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
- std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
-}
diff --git a/support/lib/Support/Statistic.cpp b/support/lib/Support/Statistic.cpp
deleted file mode 100644
index ae9f57f80e..0000000000
--- a/support/lib/Support/Statistic.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- Statistic.cpp - Easy way to expose stats information --------------===//
-//
-// This file implements the 'Statistic' class, which is designed to be an easy
-// way to expose various success metrics from passes. These statistics are
-// printed at the end of a run, when the -stats command line option is enabled
-// on the command line.
-//
-// This is useful for reporting information like the number of instructions
-// simplified, optimized or removed by various transformations, like this:
-//
-// static Statistic<> NumInstEliminated("GCSE - Number of instructions killed");
-//
-// Later, in the code: ++NumInstEliminated;
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/Statistic.h"
-#include "Support/CommandLine.h"
-#include <sstream>
-#include <iostream>
-#include <algorithm>
-
-// GetLibSupportInfoOutputFile - Return a file stream to print our output on...
-std::ostream *GetLibSupportInfoOutputFile();
-
-unsigned StatisticBase::NumStats = 0;
-
-// -stats - Command line option to cause transformations to emit stats about
-// what they did.
-//
-static cl::opt<bool>
-Enabled("stats", cl::desc("Enable statistics output from program"));
-
-struct StatRecord {
- std::string Value;
- const char *Name, *Desc;
-
- StatRecord(const std::string V, const char *N, const char *D)
- : Value(V), Name(N), Desc(D) {}
-
- bool operator<(const StatRecord &SR) const {
- return std::strcmp(Name, SR.Name) < 0;
- }
-
- void print(unsigned ValFieldSize, unsigned NameFieldSize,
- std::ostream &OS) {
- OS << std::string(ValFieldSize-Value.length(), ' ')
- << Value << " " << Name
- << std::string(NameFieldSize-std::strlen(Name), ' ')
- << " - " << Desc << "\n";
- }
-};
-
-static std::vector<StatRecord> *AccumStats = 0;
-
-// Print information when destroyed, iff command line option is specified
-void StatisticBase::destroy() const {
- if (Enabled && hasSomeData()) {
- if (AccumStats == 0)
- AccumStats = new std::vector<StatRecord>();
-
- std::ostringstream Out;
- printValue(Out);
- AccumStats->push_back(StatRecord(Out.str(), Name, Desc));
- }
-
- if (--NumStats == 0 && AccumStats) {
- std::ostream *OutStream = GetLibSupportInfoOutputFile();
-
- // Figure out how long the biggest Value and Name fields are...
- unsigned MaxNameLen = 0, MaxValLen = 0;
- for (unsigned i = 0, e = AccumStats->size(); i != e; ++i) {
- MaxValLen = std::max(MaxValLen,
- (unsigned)(*AccumStats)[i].Value.length());
- MaxNameLen = std::max(MaxNameLen,
- (unsigned)std::strlen((*AccumStats)[i].Name));
- }
-
- // Sort the fields...
- std::stable_sort(AccumStats->begin(), AccumStats->end());
-
- // Print out the statistics header...
- *OutStream << "===" << std::string(73, '-') << "===\n"
- << " ... Statistics Collected ...\n"
- << "===" << std::string(73, '-') << "===\n\n";
-
- // Print all of the statistics accumulated...
- for (unsigned i = 0, e = AccumStats->size(); i != e; ++i)
- (*AccumStats)[i].print(MaxValLen, MaxNameLen, *OutStream);
-
- *OutStream << std::endl; // Flush the output stream...
-
- // Free all accumulated statistics...
- delete AccumStats;
- AccumStats = 0;
- if (OutStream != &std::cerr && OutStream != &std::cout)
- delete OutStream; // Close the file...
- }
-}
diff --git a/support/lib/Support/SystemUtils.cpp b/support/lib/Support/SystemUtils.cpp
deleted file mode 100644
index e198c7ec06..0000000000
--- a/support/lib/Support/SystemUtils.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-//===- SystemUtils.h - Utilities to do low-level system stuff --*- C++ -*--===//
-//
-// This file contains functions used to do a variety of low-level, often
-// system-specific, tasks.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/SystemUtils.h"
-#include <algorithm>
-#include <fstream>
-#include <iostream>
-#include <cstdlib>
-#include "Config/sys/types.h"
-#include "Config/sys/stat.h"
-#include "Config/fcntl.h"
-#include "Config/sys/wait.h"
-#include "Config/unistd.h"
-#include "Config/errno.h"
-
-/// isExecutableFile - This function returns true if the filename specified
-/// exists and is executable.
-///
-bool isExecutableFile(const std::string &ExeFileName) {
- struct stat Buf;
- if (stat(ExeFileName.c_str(), &Buf))
- return false; // Must not be executable!
-
- if (!(Buf.st_mode & S_IFREG))
- return false; // Not a regular file?
-
- if (Buf.st_uid == getuid()) // Owner of file?
- return Buf.st_mode & S_IXUSR;
- else if (Buf.st_gid == getgid()) // In group of file?
- return Buf.st_mode & S_IXGRP;
- else // Unrelated to file?
- return Buf.st_mode & S_IXOTH;
-}
-
-/// FindExecutable - Find a named executable, giving the argv[0] of program
-/// being executed. This allows us to find another LLVM tool if it is built
-/// into the same directory, but that directory is neither the current
-/// directory, nor in the PATH. If the executable cannot be found, return an
-/// empty string.
-///
-std::string FindExecutable(const std::string &ExeName,
- const std::string &ProgramPath) {
- // First check the directory that bugpoint is in. We can do this if
- // BugPointPath contains at least one / character, indicating that it is a
- // relative path to bugpoint itself.
- //
- std::string Result = ProgramPath;
- while (!Result.empty() && Result[Result.size()-1] != '/')
- Result.erase(Result.size()-1, 1);
-
- if (!Result.empty()) {
- Result += ExeName;
- if (isExecutableFile(Result)) return Result; // Found it?
- }
-
- // Okay, if the path to the program didn't tell us anything, try using the
- // PATH environment variable.
- const char *PathStr = getenv("PATH");
- if (PathStr == 0) return "";
-
- // Now we have a colon separated list of directories to search... try them...
- unsigned PathLen = strlen(PathStr);
- while (PathLen) {
- // Find the first colon...
- const char *Colon = std::find(PathStr, PathStr+PathLen, ':');
-
- // Check to see if this first directory contains the executable...
- std::string FilePath = std::string(PathStr, Colon) + '/' + ExeName;
- if (isExecutableFile(FilePath))
- return FilePath; // Found the executable!
-
- // Nope it wasn't in this directory, check the next range!
- PathLen -= Colon-PathStr;
- PathStr = Colon;
- while (*PathStr == ':') { // Advance past colons
- PathStr++;
- PathLen--;
- }
- }
-
- // If we fell out, we ran out of directories in PATH to search, return failure
- return "";
-}
-
-static void RedirectFD(const std::string &File, int FD) {
- if (File.empty()) return; // Noop
-
- // Open the file
- int InFD = open(File.c_str(), FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666);
- if (InFD == -1) {
- std::cerr << "Error opening file '" << File << "' for "
- << (FD == 0 ? "input" : "output") << "!\n";
- exit(1);
- }
-
- dup2(InFD, FD); // Install it as the requested FD
- close(InFD); // Close the original FD
-}
-
-/// RunProgramWithTimeout - This function executes the specified program, with
-/// the specified null-terminated argument array, with the stdin/out/err fd's
-/// redirected, with a timeout specified on the command line. This terminates
-/// the calling program if there is an error executing the specified program.
-/// It returns the return value of the program, or -1 if a timeout is detected.
-///
-int RunProgramWithTimeout(const std::string &ProgramPath, const char **Args,
- const std::string &StdInFile,
- const std::string &StdOutFile,
- const std::string &StdErrFile) {
-
- // FIXME: install sigalarm handler here for timeout...
-
- int Child = fork();
- switch (Child) {
- case -1:
- std::cerr << "ERROR forking!\n";
- exit(1);
- case 0: // Child
- RedirectFD(StdInFile, 0); // Redirect file descriptors...
- RedirectFD(StdOutFile, 1);
- RedirectFD(StdErrFile, 2);
-
- execv(ProgramPath.c_str(), (char *const *)Args);
- std::cerr << "Error executing program '" << ProgramPath;
- for (; *Args; ++Args)
- std::cerr << " " << *Args;
- exit(1);
-
- default: break;
- }
-
- // Make sure all output has been written while waiting
- std::cout << std::flush;
-
- int Status;
- if (wait(&Status) != Child) {
- if (errno == EINTR) {
- static bool FirstTimeout = true;
- if (FirstTimeout) {
- std::cout <<
- "*** Program execution timed out! This mechanism is designed to handle\n"
- " programs stuck in infinite loops gracefully. The -timeout option\n"
- " can be used to change the timeout threshold or disable it completely\n"
- " (with -timeout=0). This message is only displayed once.\n";
- FirstTimeout = false;
- }
- return -1; // Timeout detected
- }
-
- std::cerr << "Error waiting for child process!\n";
- exit(1);
- }
- return Status;
-}
-
-
-//
-// Function: ExecWait ()
-//
-// Description:
-// This function executes a program with the specified arguments and
-// environment. It then waits for the progarm to termiante and then returns
-// to the caller.
-//
-// Inputs:
-// argv - The arguments to the program as an array of C strings. The first
-// argument should be the name of the program to execute, and the
-// last argument should be a pointer to NULL.
-//
-// envp - The environment passes to the program as an array of C strings in
-// the form of "name=value" pairs. The last element should be a
-// pointer to NULL.
-//
-// Outputs:
-// None.
-//
-// Return value:
-// 0 - No errors.
-// 1 - The program could not be executed.
-// 1 - The program returned a non-zero exit status.
-// 1 - The program terminated abnormally.
-//
-// Notes:
-// The program will inherit the stdin, stdout, and stderr file descriptors
-// as well as other various configuration settings (umask).
-//
-// This function should not print anything to stdout/stderr on its own. It is
-// a generic library function. The caller or executed program should report
-// errors in the way it sees fit.
-//
-// This function does not use $PATH to find programs.
-//
-int
-ExecWait (const char * const old_argv[], const char * const old_envp[])
-{
- // Child process ID
- register int child;
-
- // Status from child process when it exits
- int status;
-
- //
- // Create local versions of the parameters that can be passed into execve()
- // without creating const problems.
- //
- char ** const argv = (char ** const) old_argv;
- char ** const envp = (char ** const) old_envp;
-
- //
- // Create a child process.
- //
- switch (child=fork())
- {
- //
- // An error occured: Return to the caller.
- //
- case -1:
- return 1;
- break;
-
- //
- // Child process: Execute the program.
- //
- case 0:
- execve (argv[0], argv, envp);
-
- //
- // If the execve() failed, we should exit and let the parent pick up
- // our non-zero exit status.
- //
- exit (1);
- break;
-
- //
- // Parent process: Break out of the switch to do our processing.
- //
- default:
- break;
- }
-
- //
- // Parent process: Wait for the child process to termiante.
- //
- if ((wait (&status)) == -1)
- {
- return 1;
- }
-
- //
- // If the program exited normally with a zero exit status, return success!
- //
- if (WIFEXITED (status) && (WEXITSTATUS(status) == 0))
- {
- return 0;
- }
-
- //
- // Otherwise, return failure.
- //
- return 1;
-}
-
diff --git a/support/lib/Support/Timer.cpp b/support/lib/Support/Timer.cpp
deleted file mode 100644
index 98001287d9..0000000000
--- a/support/lib/Support/Timer.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-//===-- Timer.cpp - Interval Timing Support -------------------------------===//
-//
-// Interval Timing implementation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Support/Timer.h"
-#include "Support/CommandLine.h"
-
-#include "Config/sys/resource.h"
-#include "Config/sys/time.h"
-#include "Config/unistd.h"
-#include "Config/malloc.h"
-#include "Config/stdio.h"
-#include <iostream>
-#include <algorithm>
-#include <functional>
-#include <fstream>
-
-// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
-// of constructor/destructor ordering being unspecified by C++. Basically the
-// problem is that a Statistic<> object gets destroyed, which ends up calling
-// 'GetLibSupportInfoOutputFile()' (below), which calls this function.
-// LibSupportInfoOutputFilename used to be a global variable, but sometimes it
-// would get destroyed before the Statistic, causing havoc to ensue. We "fix"
-// this by creating the string the first time it is needed and never destroying
-// it.
-static std::string &getLibSupportInfoOutputFilename() {
- static std::string *LibSupportInfoOutputFilename = new std::string();
- return *LibSupportInfoOutputFilename;
-}
-
-namespace {
-#ifdef HAVE_MALLINFO
- cl::opt<bool>
- TrackSpace("track-memory", cl::desc("Enable -time-passes memory "
- "tracking (this may be slow)"),
- cl::Hidden);
-#endif
-
- cl::opt<std::string, true>
- InfoOutputFilename("info-output-file", cl::value_desc("filename"),
- cl::desc("File to append -stats and -timer output to"),
- cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
-}
-
-static TimerGroup *DefaultTimerGroup = 0;
-static TimerGroup *getDefaultTimerGroup() {
- if (DefaultTimerGroup) return DefaultTimerGroup;
- return DefaultTimerGroup = new TimerGroup("Miscellaneous Ungrouped Timers");
-}
-
-Timer::Timer(const std::string &N)
- : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N),
- Started(false), TG(getDefaultTimerGroup()) {
- TG->addTimer();
-}
-
-Timer::Timer(const std::string &N, TimerGroup &tg)
- : Elapsed(0), UserTime(0), SystemTime(0), MemUsed(0), PeakMem(0), Name(N),
- Started(false), TG(&tg) {
- TG->addTimer();
-}
-
-Timer::Timer(const Timer &T) {
- TG = T.TG;
- if (TG) TG->addTimer();
- operator=(T);
-}
-
-
-// Copy ctor, initialize with no TG member.
-Timer::Timer(bool, const Timer &T) {
- TG = T.TG; // Avoid assertion in operator=
- operator=(T); // Copy contents
- TG = 0;
-}
-
-
-Timer::~Timer() {
- if (TG) {
- if (Started) {
- Started = false;
- TG->addTimerToPrint(*this);
- }
- TG->removeTimer();
- }
-}
-
-static long getMemUsage() {
-#ifdef HAVE_MALLINFO
- if (TrackSpace) {
- struct mallinfo MI = mallinfo();
- return MI.uordblks/*+MI.hblkhd*/;
- }
-#endif
- return 0;
-}
-
-struct TimeRecord {
- double Elapsed, UserTime, SystemTime;
- long MemUsed;
-};
-
-static TimeRecord getTimeRecord(bool Start) {
- struct rusage RU;
- struct timeval T;
- long MemUsed = 0;
- if (Start) {
- MemUsed = getMemUsage();
- if (getrusage(RUSAGE_SELF, &RU))
- perror("getrusage call failed: -time-passes info incorrect!");
- }
- gettimeofday(&T, 0);
-
- if (!Start) {
- MemUsed = getMemUsage();
- if (getrusage(RUSAGE_SELF, &RU))
- perror("getrusage call failed: -time-passes info incorrect!");
- }
-
- TimeRecord Result;
- Result.Elapsed = T.tv_sec + T.tv_usec/1000000.0;
- Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0;
- Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0;
- Result.MemUsed = MemUsed;
-
- return Result;
-}
-
-static std::vector<Timer*> ActiveTimers;
-
-void Timer::startTimer() {
- Started = true;
- TimeRecord TR = getTimeRecord(true);
- Elapsed -= TR.Elapsed;
- UserTime -= TR.UserTime;
- SystemTime -= TR.SystemTime;
- MemUsed -= TR.MemUsed;
- PeakMemBase = TR.MemUsed;
- ActiveTimers.push_back(this);
-}
-
-void Timer::stopTimer() {
- TimeRecord TR = getTimeRecord(false);
- Elapsed += TR.Elapsed;
- UserTime += TR.UserTime;
- SystemTime += TR.SystemTime;
- MemUsed += TR.MemUsed;
-
- if (ActiveTimers.back() == this) {
- ActiveTimers.pop_back();
- } else {
- std::vector<Timer*>::iterator I =
- std::find(ActiveTimers.begin(), ActiveTimers.end(), this);
- assert(I != ActiveTimers.end() && "stop but no startTimer?");
- ActiveTimers.erase(I);
- }
-}
-
-void Timer::sum(const Timer &T) {
- Elapsed += T.Elapsed;
- UserTime += T.UserTime;
- SystemTime += T.SystemTime;
- MemUsed += T.MemUsed;
- PeakMem += T.PeakMem;
-}
-
-/// addPeakMemoryMeasurement - This method should be called whenever memory
-/// usage needs to be checked. It adds a peak memory measurement to the
-/// currently active timers, which will be printed when the timer group prints
-///
-void Timer::addPeakMemoryMeasurement() {
- long MemUsed = getMemUsage();
-
- for (std::vector<Timer*>::iterator I = ActiveTimers.begin(),
- E = ActiveTimers.end(); I != E; ++I)
- (*I)->PeakMem = std::max((*I)->PeakMem, MemUsed-(*I)->PeakMemBase);
-}
-
-
-//===----------------------------------------------------------------------===//
-// TimerGroup Implementation
-//===----------------------------------------------------------------------===//
-
-// printAlignedFP - Simulate the printf "%A.Bf" format, where A is the
-// TotalWidth size, and B is the AfterDec size.
-//
-static void printAlignedFP(double Val, unsigned AfterDec, unsigned TotalWidth,
- std::ostream &OS) {
- assert(TotalWidth >= AfterDec+1 && "Bad FP Format!");
- OS.width(TotalWidth-AfterDec-1);
- char OldFill = OS.fill();
- OS.fill(' ');
- OS << (int)Val; // Integer part;
- OS << ".";
- OS.width(AfterDec);
- OS.fill('0');
- unsigned ResultFieldSize = 1;
- while (AfterDec--) ResultFieldSize *= 10;
- OS << (int)(Val*ResultFieldSize) % ResultFieldSize;
- OS.fill(OldFill);
-}
-
-static void printVal(double Val, double Total, std::ostream &OS) {
- if (Total < 1e-7) // Avoid dividing by zero...
- OS << " ----- ";
- else {
- OS << " ";
- printAlignedFP(Val, 4, 7, OS);
- OS << " (";
- printAlignedFP(Val*100/Total, 1, 5, OS);
- OS << "%)";
- }
-}
-
-void Timer::print(const Timer &Total, std::ostream &OS) {
- if (Total.UserTime)
- printVal(UserTime, Total.UserTime, OS);
- if (Total.SystemTime)
- printVal(SystemTime, Total.SystemTime, OS);
- if (Total.getProcessTime())
- printVal(getProcessTime(), Total.getProcessTime(), OS);
- printVal(Elapsed, Total.Elapsed, OS);
-
- OS << " ";
-
- if (Total.MemUsed) {
- OS.width(9);
- OS << MemUsed << " ";
- }
- if (Total.PeakMem) {
- if (PeakMem) {
- OS.width(9);
- OS << PeakMem << " ";
- } else
- OS << " ";
- }
- OS << Name << "\n";
-
- Started = false; // Once printed, don't print again
-}
-
-// GetLibSupportInfoOutputFile - Return a file stream to print our output on...
-std::ostream *GetLibSupportInfoOutputFile() {
- std::string &LibSupportInfoOutputFilename = getLibSupportInfoOutputFilename();
- if (LibSupportInfoOutputFilename.empty())
- return &std::cerr;
- if (LibSupportInfoOutputFilename == "-")
- return &std::cout;
-
- std::ostream *Result = new std::ofstream(LibSupportInfoOutputFilename.c_str(),
- std::ios::app);
- if (!Result->good()) {
- std::cerr << "Error opening info-output-file '"
- << LibSupportInfoOutputFilename << " for appending!\n";
- delete Result;
- return &std::cerr;
- }
- return Result;
-}
-
-
-void TimerGroup::removeTimer() {
- if (--NumTimers == 0 && !TimersToPrint.empty()) { // Print timing report...
- // Sort the timers in descending order by amount of time taken...
- std::sort(TimersToPrint.begin(), TimersToPrint.end(),
- std::greater<Timer>());
-
- // Figure out how many spaces to indent TimerGroup name...
- unsigned Padding = (80-Name.length())/2;
- if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
-
- std::ostream *OutStream = GetLibSupportInfoOutputFile();
-
- ++NumTimers;
- { // Scope to contain Total timer... don't allow total timer to drop us to
- // zero timers...
- Timer Total("TOTAL");
-
- for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
- Total.sum(TimersToPrint[i]);
-
- // Print out timing header...
- *OutStream << "===" << std::string(73, '-') << "===\n"
- << std::string(Padding, ' ') << Name << "\n"
- << "===" << std::string(73, '-')
- << "===\n Total Execution Time: ";
-
- printAlignedFP(Total.getProcessTime(), 4, 5, *OutStream);
- *OutStream << " seconds (";
- printAlignedFP(Total.getWallTime(), 4, 5, *OutStream);
- *OutStream << " wall clock)\n\n";
-
- if (Total.UserTime)
- *OutStream << " ---User Time---";
- if (Total.SystemTime)
- *OutStream << " --System Time--";
- if (Total.getProcessTime())
- *OutStream << " --User+System--";
- *OutStream << " ---Wall Time---";
- if (Total.getMemUsed())
- *OutStream << " ---Mem---";
- if (Total.getPeakMem())
- *OutStream << " -PeakMem-";
- *OutStream << " --- Name ---\n";
-
- // Loop through all of the timing data, printing it out...
- for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i)
- TimersToPrint[i].print(Total, *OutStream);
-
- Total.print(Total, *OutStream);
- *OutStream << std::endl; // Flush output
- }
- --NumTimers;
-
- TimersToPrint.clear();
-
- if (OutStream != &std::cerr && OutStream != &std::cout)
- delete OutStream; // Close the file...
- }
-
- // Delete default timer group!
- if (NumTimers == 0 && this == DefaultTimerGroup) {
- delete DefaultTimerGroup;
- DefaultTimerGroup = 0;
- }
-}
diff --git a/support/lib/Support/ToolRunner.cpp b/support/lib/Support/ToolRunner.cpp
deleted file mode 100644
index 1ae5260bef..0000000000
--- a/support/lib/Support/ToolRunner.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-#include "Support/Debug.h"
-#include "Support/FileUtilities.h"
-#include "Support/ToolRunner.h"
-
-//===---------------------------------------------------------------------===//
-// LLI Implementation of AbstractIntepreter interface
-//
-class LLI : public AbstractInterpreter {
- std::string LLIPath; // The path to the LLI executable
-public:
- LLI(const std::string &Path) : LLIPath(Path) { }
-
-
- virtual int ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib = "");
-};
-
-int LLI::ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib) {
- if (!SharedLib.empty()) {
- std::cerr << "LLI currently does not support loading shared libraries.\n"
- << "Exiting.\n";
- exit(1);
- }
-
- std::vector<const char*> LLIArgs;
- LLIArgs.push_back(LLIPath.c_str());
- LLIArgs.push_back("-abort-on-exception");
- LLIArgs.push_back("-quiet");
- LLIArgs.push_back("-force-interpreter=true");
- LLIArgs.push_back(Bytecode.c_str());
- // Add optional parameters to the running program from Argv
- for (unsigned i=0, e = Args.size(); i != e; ++i)
- LLIArgs.push_back(Args[i].c_str());
- LLIArgs.push_back(0);
-
- std::cout << "<lli>" << std::flush;
- DEBUG(std::cerr << "\nAbout to run:\n\t";
- for (unsigned i=0, e = LLIArgs.size(); i != e; ++i)
- std::cerr << " " << LLIArgs[i];
- std::cerr << "\n";
- );
- return RunProgramWithTimeout(LLIPath, &LLIArgs[0],
- InputFile, OutputFile, OutputFile);
-}
-
-// LLI create method - Try to find the LLI executable
-AbstractInterpreter *createLLItool(const std::string &ProgramPath,
- std::string &Message) {
- std::string LLIPath = FindExecutable("lli", ProgramPath);
- if (!LLIPath.empty()) {
- Message = "Found lli: " + LLIPath + "\n";
- return new LLI(LLIPath);
- }
-
- Message = "Cannot find `lli' in executable directory or PATH!\n";
- return 0;
-}
-
-//===----------------------------------------------------------------------===//
-// LLC Implementation of AbstractIntepreter interface
-//
-int LLC::OutputAsm(const std::string &Bytecode,
- std::string &OutputAsmFile) {
- OutputAsmFile = getUniqueFilename(Bytecode+".llc.s");
- const char *LLCArgs[] = {
- LLCPath.c_str(),
- "-o", OutputAsmFile.c_str(), // Output to the Asm file
- "-f", // Overwrite as necessary...
- Bytecode.c_str(), // This is the input bytecode
- 0
- };
-
- std::cout << "<llc>" << std::flush;
- if (RunProgramWithTimeout(LLCPath, LLCArgs, "/dev/null", "/dev/null",
- "/dev/null")) {
- // If LLC failed on the bytecode, print error...
- std::cerr << "Error: `llc' failed!\n";
- removeFile(OutputAsmFile);
- return 1;
- }
-
- return 0;
-}
-
-int LLC::ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib) {
-
- std::string OutputAsmFile;
- if (OutputAsm(Bytecode, OutputAsmFile)) {
- std::cerr << "Could not generate asm code with `llc', exiting.\n";
- exit(1);
- }
-
- // Assuming LLC worked, compile the result with GCC and run it.
- int Result = gcc->ExecuteProgram(OutputAsmFile, Args, AsmFile,
- InputFile, OutputFile, SharedLib);
- removeFile(OutputAsmFile);
- return Result;
-}
-
-/// createLLCtool - Try to find the LLC executable
-///
-LLC *createLLCtool(const std::string &ProgramPath, std::string &Message)
-{
- std::string LLCPath = FindExecutable("llc", ProgramPath);
- if (LLCPath.empty()) {
- Message = "Cannot find `llc' in executable directory or PATH!\n";
- return 0;
- }
-
- Message = "Found llc: " + LLCPath + "\n";
- GCC *gcc = createGCCtool(ProgramPath, Message);
- if (!gcc) {
- std::cerr << Message << "\n";
- exit(1);
- }
- return new LLC(LLCPath, gcc);
-}
-
-//===---------------------------------------------------------------------===//
-// JIT Implementation of AbstractIntepreter interface
-//
-class JIT : public AbstractInterpreter {
- std::string LLIPath; // The path to the LLI executable
-public:
- JIT(const std::string &Path) : LLIPath(Path) { }
-
-
- virtual int ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib = "");
-};
-
-int JIT::ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib) {
- // Construct a vector of parameters, incorporating those from the command-line
- std::vector<const char*> JITArgs;
- JITArgs.push_back(LLIPath.c_str());
- JITArgs.push_back("-quiet");
- JITArgs.push_back("-force-interpreter=false");
- if (!SharedLib.empty()) {
- JITArgs.push_back("-load");
- JITArgs.push_back(SharedLib.c_str());
- }
- JITArgs.push_back(Bytecode.c_str());
- // Add optional parameters to the running program from Argv
- for (unsigned i=0, e = Args.size(); i != e; ++i)
- JITArgs.push_back(Args[i].c_str());
- JITArgs.push_back(0);
-
- std::cout << "<jit>" << std::flush;
- DEBUG(std::cerr << "\nAbout to run:\n\t";
- for (unsigned i=0, e = JITArgs.size(); i != e; ++i)
- std::cerr << " " << JITArgs[i];
- std::cerr << "\n";
- );
- DEBUG(std::cerr << "\nSending output to " << OutputFile << "\n");
- return RunProgramWithTimeout(LLIPath, &JITArgs[0],
- InputFile, OutputFile, OutputFile);
-}
-
-/// createJITtool - Try to find the LLI executable
-///
-AbstractInterpreter *createJITtool(const std::string &ProgramPath,
- std::string &Message) {
- std::string LLIPath = FindExecutable("lli", ProgramPath);
- if (!LLIPath.empty()) {
- Message = "Found lli: " + LLIPath + "\n";
- return new JIT(LLIPath);
- }
-
- Message = "Cannot find `lli' in executable directory or PATH!\n";
- return 0;
-}
-
-int CBE::OutputC(const std::string &Bytecode,
- std::string &OutputCFile) {
- OutputCFile = getUniqueFilename(Bytecode+".cbe.c");
- const char *DisArgs[] = {
- DISPath.c_str(),
- "-o", OutputCFile.c_str(), // Output to the C file
- "-c", // Output to C
- "-f", // Overwrite as necessary...
- Bytecode.c_str(), // This is the input bytecode
- 0
- };
-
- std::cout << "<cbe>" << std::flush;
- if (RunProgramWithTimeout(DISPath, DisArgs, "/dev/null", "/dev/null",
- "/dev/null")) {
- // If dis failed on the bytecode, print error...
- std::cerr << "Error: `llvm-dis -c' failed!\n";
- return 1;
- }
-
- return 0;
-}
-
-int CBE::ExecuteProgram(const std::string &Bytecode,
- const cl::list<std::string> &Args,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib) {
- std::string OutputCFile;
- if (OutputC(Bytecode, OutputCFile)) {
- std::cerr << "Could not generate C code with `llvm-dis', exiting.\n";
- exit(1);
- }
-
- int Result = gcc->ExecuteProgram(OutputCFile, Args, CFile,
- InputFile, OutputFile, SharedLib);
- removeFile(OutputCFile);
-
- return Result;
-}
-
-/// createCBEtool - Try to find the 'dis' executable
-///
-CBE *createCBEtool(const std::string &ProgramPath, std::string &Message) {
- std::string DISPath = FindExecutable("llvm-dis", ProgramPath);
- if (DISPath.empty()) {
- Message =
- "Cannot find `llvm-dis' in executable directory or PATH!\n";
- return 0;
- }
-
- Message = "Found llvm-dis: " + DISPath + "\n";
- GCC *gcc = createGCCtool(ProgramPath, Message);
- if (!gcc) {
- std::cerr << Message << "\n";
- exit(1);
- }
- return new CBE(DISPath, gcc);
-}
-
-//===---------------------------------------------------------------------===//
-// GCC abstraction
-//
-// This is not a *real* AbstractInterpreter as it does not accept bytecode
-// files, but only input acceptable to GCC, i.e. C, C++, and assembly files
-//
-int GCC::ExecuteProgram(const std::string &ProgramFile,
- const cl::list<std::string> &Args,
- FileType fileType,
- const std::string &InputFile,
- const std::string &OutputFile,
- const std::string &SharedLib) {
- std::string OutputBinary = getUniqueFilename(ProgramFile+".gcc.exe");
- std::vector<const char*> GCCArgs;
-
- GCCArgs.push_back(GCCPath.c_str());
- if (!SharedLib.empty()) // Specify the shared library to link in...
- GCCArgs.push_back(SharedLib.c_str());
- GCCArgs.push_back("-x");
- if (fileType == CFile) {
- GCCArgs.push_back("c");
- GCCArgs.push_back("-fno-strict-aliasing");
- } else {
- GCCArgs.push_back("assembler");
- }
- GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename...
- GCCArgs.push_back("-o");
- GCCArgs.push_back(OutputBinary.c_str()); // Output to the right file...
- GCCArgs.push_back("-lm"); // Hard-code the math library...
- GCCArgs.push_back("-O2"); // Optimize the program a bit...
- GCCArgs.push_back(0); // NULL terminator
-
- std::cout << "<gcc>" << std::flush;
- if (RunProgramWithTimeout(GCCPath, &GCCArgs[0], "/dev/null", "/dev/null",
- "/dev/null")) {
- ProcessFailure(&GCCArgs[0]);
- exit(1);
- }
-
- std::vector<const char*> ProgramArgs;
- ProgramArgs.push_back(OutputBinary.c_str());
- // Add optional parameters to the running program from Argv
- for (unsigned i=0, e = Args.size(); i != e; ++i)
- ProgramArgs.push_back(Args[i].c_str());
- ProgramArgs.push_back(0); // NULL terminator
-
- // Now that we have a binary, run it!
- std::cout << "<program>" << std::flush;
- DEBUG(std::cerr << "\nAbout to run:\n\t";
- for (unsigned i=0, e = ProgramArgs.size(); i != e; ++i)
- std::cerr << " " << ProgramArgs[i];
- std::cerr << "\n";
- );
- int ProgramResult = RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
- InputFile, OutputFile, OutputFile);
- removeFile(OutputBinary);
- return ProgramResult;
-}
-
-int GCC::MakeSharedObject(const std::string &InputFile,
- FileType fileType,
- std::string &OutputFile) {
- OutputFile = getUniqueFilename(InputFile+".so");
- // Compile the C/asm file into a shared object
- const char* GCCArgs[] = {
- GCCPath.c_str(),
- "-x", (fileType == AsmFile) ? "assembler" : "c",
- "-fno-strict-aliasing",
- InputFile.c_str(), // Specify the input filename...
-#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
- "-G", // Compile a shared library, `-G' for Sparc
-#else
- "-shared", // `-shared' for Linux/X86, maybe others
-#endif
- "-o", OutputFile.c_str(), // Output to the right filename...
- "-O2", // Optimize the program a bit...
- 0
- };
-
- std::cout << "<gcc>" << std::flush;
- if(RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", "/dev/null",
- "/dev/null")) {
- ProcessFailure(GCCArgs);
- exit(1);
- }
- return 0;
-}
-
-void GCC::ProcessFailure(const char** GCCArgs) {
- std::cerr << "\n*** Error: invocation of the C compiler failed!\n";
- for (const char **Arg = GCCArgs; *Arg; ++Arg)
- std::cerr << " " << *Arg;
- std::cerr << "\n";
-
- // Rerun the compiler, capturing any error messages to print them.
- std::string ErrorFilename = getUniqueFilename("gcc.errors");
- RunProgramWithTimeout(GCCPath, GCCArgs, "/dev/null", ErrorFilename.c_str(),
- ErrorFilename.c_str());
-
- // Print out the error messages generated by GCC if possible...
- std::ifstream ErrorFile(ErrorFilename.c_str());
- if (ErrorFile) {
- std::copy(std::istreambuf_iterator<char>(ErrorFile),
- std::istreambuf_iterator<char>(),
- std::ostreambuf_iterator<char>(std::cerr));
- ErrorFile.close();
- std::cerr << "\n";
- }
-
- removeFile(ErrorFilename);
-}
-
-/// createGCCtool - Try to find the `gcc' executable
-///
-GCC *createGCCtool(const std::string &ProgramPath, std::string &Message) {
- std::string GCCPath = FindExecutable("gcc", ProgramPath);
- if (GCCPath.empty()) {
- Message = "Cannot find `gcc' in executable directory or PATH!\n";
- return 0;
- }
-
- Message = "Found gcc: " + GCCPath + "\n";
- return new GCC(GCCPath);
-}
diff --git a/support/lib/Support/ValueHolder.cpp b/support/lib/Support/ValueHolder.cpp
deleted file mode 100644
index e0806b538a..0000000000
--- a/support/lib/Support/ValueHolder.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===-- ValueHolder.cpp - Wrapper for Value implementation ----------------===//
-//
-// This class defines a simple subclass of User, which keeps a pointer to a
-// Value, which automatically updates when Value::replaceAllUsesWith is called.
-// This is useful when you have pointers to Value's in your pass, but the
-// pointers get invalidated when some other portion of the algorithm is
-// replacing Values with other Values.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/ValueHolder.h"
-#include "llvm/Type.h"
-
-ValueHolder::ValueHolder(Value *V) : User(Type::TypeTy, Value::TypeVal) {
- Operands.push_back(Use(V, this));
-}
diff --git a/support/tools/Burg/COPYRIGHT b/support/tools/Burg/COPYRIGHT
deleted file mode 100644
index 1de0aad6f2..0000000000
--- a/support/tools/Burg/COPYRIGHT
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright (C) 1991 Todd A. Proebsting
-All Rights Reserved.
-
-This software is in the public domain. You may use and copy this material
-freely. This privilege extends to modifications, although any modified
-version of this system given to a third party should clearly identify your
-modifications as well as the original source.
-
-The responsibility for the use of this material resides entirely with you.
-We make no warranty of any kind concerning this material, nor do we make
-any claim as to the suitability of BURG for any application. This software
-is experimental in nature and there is no written or implied warranty. Use
-it at your own risk.
diff --git a/support/tools/Burg/Doc/Makefile b/support/tools/Burg/Doc/Makefile
deleted file mode 100644
index 226210d6ca..0000000000
--- a/support/tools/Burg/Doc/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-# $Id$
-
-#CFLAGS =
-#CFLAGS = -O
-#CFLAGS = -O -DNOLEX
-CFLAGS = -g -DDEBUG
-#CFLAGS = -g -DNOLEX -DDEBUG
-
-SRCS = \
- be.c \
- burs.c \
- closure.c \
- delta.c \
- fe.c \
- item.c \
- lex.c \
- list.c \
- main.c \
- map.c \
- nonterminal.c \
- operator.c \
- pattern.c \
- plank.c \
- queue.c \
- rule.c \
- string.c \
- symtab.c \
- table.c \
- trim.c \
- zalloc.c
-
-BU_OBJS = \
- burs.o \
- closure.o \
- delta.o \
- item.o \
- list.o \
- map.o \
- nonterminal.o \
- operator.o \
- pattern.o \
- queue.o \
- rule.o \
- table.o \
- trim.o \
- zalloc.o
-
-FE_OBJS = \
- be.o \
- fe.o \
- lex.o \
- main.o \
- plank.o \
- string.o \
- symtab.o \
- y.tab.o
-
-all: test
-
-burg: $(BU_OBJS) $(FE_OBJS)
- $(CC) -o burg $(CFLAGS) $(BU_OBJS) $(FE_OBJS)
-
-y.tab.c y.tab.h: gram.y
- yacc -d gram.y
-
-clean:
- rm -f *.o y.tab.h y.tab.c core burg *.aux *.log *.dvi sample sample.c tmp
-
-$(FE_OBJS): b.h
-$(BU_OBJS): b.h
-$(FE_OBJS): fe.h
-
-lex.o: y.tab.h
-
-doc.dvi: doc.tex
- latex doc; latex doc
-
-test: burg sample.gr
- ./burg -I <sample.gr >sample.c && cc $(CFLAGS) -o sample sample.c && ./sample
- ./burg -I sample.gr >tmp && cmp tmp sample.c
- ./burg -I <sample.gr -o tmp && cmp tmp sample.c
- ./burg -I sample.gr -o tmp && cmp tmp sample.c
- ./burg -I -O0 <sample.gr >tmp && cmp tmp sample.c
- ./burg -I -= <sample.gr >tmp && cmp tmp sample.c
diff --git a/support/tools/Burg/Doc/doc.aux b/support/tools/Burg/Doc/doc.aux
deleted file mode 100644
index 0f7c13f020..0000000000
--- a/support/tools/Burg/Doc/doc.aux
+++ /dev/null
@@ -1,50 +0,0 @@
-\relax
-\bibstyle{alpha}
-\citation{aho-twig-toplas}
-\citation{appel-87}
-\citation{balachandran-complang}
-\citation{kron-phd}
-\citation{hoffmann-jacm}
-\citation{hatcher-popl}
-\citation{chase-popl}
-\citation{pelegri-popl}
-\citation{pelegri-phd}
-\citation{wilhelm-tr}
-\citation{henry-budp}
-\citation{fraser-henry-spe-91}
-\citation{proebsting-91}
-\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}}
-\@writefile{toc}{\contentsline {section}{\numberline {2}Input}{1}}
-\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces A Sample Tree Grammar}}{2}}
-\newlabel{fig-tree-grammar}{{1}{2}}
-\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces EBNF Grammar for Tree Grammars for {\sc Burg}\ }}{3}}
-\newlabel{fig-grammar-grammar}{{2}{3}}
-\@writefile{toc}{\contentsline {section}{\numberline {3}Output}{3}}
-\citation{aho-johnson-dp-classic}
-\citation{fraser-henry-spe-91}
-\citation{henry-budp}
-\citation{pelegri-phd}
-\@writefile{toc}{\contentsline {section}{\numberline {4}Debugging}{6}}
-\@writefile{toc}{\contentsline {section}{\numberline {5}Running {\sc Burg}\ }{6}}
-\newlabel{sec-man-page}{{5}{6}}
-\citation{pelegri-popl}
-\citation{henry-budp}
-\citation{balachandran-complang}
-\citation{proebsting-91}
-\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces A Diverging Tree Grammar}}{7}}
-\newlabel{fig-diverge-grammar}{{3}{7}}
-\@writefile{toc}{\contentsline {section}{\numberline {6}Acknowledgements}{7}}
-\bibcite{aho-twig-toplas}{AGT89}
-\bibcite{aho-johnson-dp-classic}{AJ76}
-\bibcite{appel-87}{App87}
-\bibcite{balachandran-complang}{BDB90}
-\bibcite{wilhelm-tr}{BMW87}
-\bibcite{chase-popl}{Cha87}
-\bibcite{fraser-henry-spe-91}{FH91}
-\bibcite{hatcher-popl}{HC86}
-\bibcite{henry-budp}{Hen89}
-\bibcite{hoffmann-jacm}{HO82}
-\bibcite{kron-phd}{Kro75}
-\bibcite{pelegri-phd}{PL87}
-\bibcite{pelegri-popl}{PLG88}
-\bibcite{proebsting-91}{Pro91}
diff --git a/support/tools/Burg/Doc/doc.dvi b/support/tools/Burg/Doc/doc.dvi
deleted file mode 100644
index 3211f32c96..0000000000
--- a/support/tools/Burg/Doc/doc.dvi
+++ /dev/null
Binary files differ
diff --git a/support/tools/Burg/Doc/doc.log b/support/tools/Burg/Doc/doc.log
deleted file mode 100644
index a224a4edf7..0000000000
--- a/support/tools/Burg/Doc/doc.log
+++ /dev/null
@@ -1,157 +0,0 @@
-This is TeX, Version 3.14159 (Web2C 7.3.2) (format=latex 2000.8.30) 4 JUN 2001 13:20
-**doc
-(doc.tex
-LaTeX2e <2000/06/01>
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/latex209.def
-File: latex209.def 1998/05/13 v0.52 Standard LaTeX file
-
-
- Entering LaTeX 2.09 COMPATIBILITY MODE
- *************************************************************
- !!WARNING!! !!WARNING!! !!WARNING!! !!WARNING!!
-
- This mode attempts to provide an emulation of the LaTeX 2.09
- author environment so that OLD documents can be successfully
- processed. It should NOT be used for NEW documents!
-
- New documents should use Standard LaTeX conventions and start
- with the \documentclass command.
-
- Compatibility mode is UNLIKELY TO WORK with LaTeX 2.09 style
- files that change any internal macros, especially not with
- those that change the FONT SELECTION or OUTPUT ROUTINES.
-
- Therefore such style files MUST BE UPDATED to use
- Current Standard LaTeX: LaTeX2e.
- If you suspect that you may be using such a style file, which
- is probably very, very old by now, then you should attempt to
- get it updated by sending a copy of this error message to the
- author of that file.
- *************************************************************
-
-\footheight=\dimen102
-\@maxsep=\dimen103
-\@dblmaxsep=\dimen104
-\@cla=\count79
-\@clb=\count80
-\mscount=\count81
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/tracefnt.sty
-Package: tracefnt 1997/05/29 v3.0j Standard LaTeX package (font tracing)
-\tracingfonts=\count82
-LaTeX Info: Redefining \selectfont on input line 96.
-)
-\symbold=\mathgroup4
-\symsans=\mathgroup5
-\symtypewriter=\mathgroup6
-\symitalic=\mathgroup7
-\symsmallcaps=\mathgroup8
-\symslanted=\mathgroup9
-LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 288.
-LaTeX Font Info: Redeclaring math alphabet \mathsf on input line 289.
-LaTeX Font Info: Redeclaring math alphabet \mathtt on input line 290.
-LaTeX Font Info: Redeclaring math alphabet \mathit on input line 296.
-LaTeX Info: Redefining \em on input line 306.
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/latexsym.sty
-Package: latexsym 1998/08/17 v2.2e Standard LaTeX package (lasy symbols)
-\symlasy=\mathgroup10
-LaTeX Font Info: Overwriting symbol font `lasy' in version `bold'
-(Font) U/lasy/m/n --> U/lasy/b/n on input line 42.
-)
-LaTeX Font Info: Redeclaring math delimiter \lgroup on input line 370.
-LaTeX Font Info: Redeclaring math delimiter \rgroup on input line 372.
-LaTeX Font Info: Redeclaring math delimiter \bracevert on input line 374.
-
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/config/latex209.cf
-g
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/tools/rawfonts.sty
-Compatibility mode: package `' requested, but `rawfonts' provided.
-Package: rawfonts 1994/05/08 Low-level LaTeX 2.09 font compatibility
-
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/tools/somedefs.sty
-Package: somedefs 1994/06/01 Toolkit for optional definitions
-)
-LaTeX Font Info: Try loading font information for U+lasy on input line 44.
- (/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/ulasy.fd
-File: ulasy.fd 1998/08/17 v2.2eLaTeX symbol font definitions
-)))) (/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/article.
-cls
-Document Class: article 2000/05/19 v1.4b Standard LaTeX document class
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/size11.clo
-File: size11.clo 2000/05/19 v1.4b Standard LaTeX file (size option)
-)
-\c@part=\count83
-\c@section=\count84
-\c@subsection=\count85
-\c@subsubsection=\count86
-\c@paragraph=\count87
-\c@subparagraph=\count88
-\c@figure=\count89
-\c@table=\count90
-\abovecaptionskip=\skip41
-\belowcaptionskip=\skip42
-Compatibility mode: definition of \rm ignored.
-Compatibility mode: definition of \sf ignored.
-Compatibility mode: definition of \tt ignored.
-Compatibility mode: definition of \bf ignored.
-Compatibility mode: definition of \it ignored.
-Compatibility mode: definition of \sl ignored.
-Compatibility mode: definition of \sc ignored.
-LaTeX Info: Redefining \cal on input line 501.
-LaTeX Info: Redefining \mit on input line 502.
-\bibindent=\dimen105
-)
-(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/pstex/fullpage.sty
-) (doc.aux)
-\openout1 = `doc.aux'.
-
-LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 2.
-LaTeX Font Info: ... okay on input line 2.
-LaTeX Font Info: External font `cmex10' loaded for size
-(Font) <12> on input line 33.
-LaTeX Font Info: External font `cmex10' loaded for size
-(Font) <8> on input line 33.
-LaTeX Font Info: External font `cmex10' loaded for size
-(Font) <6> on input line 33.
-LaTeX Font Info: Try loading font information for OMS+cmtt on input line 100
-.
-LaTeX Font Info: No file OMScmtt.fd. on input line 100.
-LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
-(Font) using `OMS/cmsy/m/n' instead
-(Font) for symbol `textbraceleft' on input line 100.
- [1
-
-]
-LaTeX Font Info: External font `cmex10' loaded for size
-(Font) <10.95> on input line 150.
- [2] [3] [4] [5] [6]
-Overfull \hbox (1.38191pt too wide) in paragraph at lines 480--484
-[]\OT1/cmr/m/n/10.95 Emit code for \OT1/cmtt/m/n/10.95 burm[]arity\OT1/cmr/m/n/
-10.95 , \OT1/cmtt/m/n/10.95 burm[]child\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.95
- burm[]cost\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.95 burm[]ntname\OT1/cmr/m/n/10
-.95 , \OT1/cmtt/m/n/10.95 burm[]op[]label\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.
-95 burm[]opname\OT1/cmr/m/n/10.95 ,
- []
-
-[7] [8] [9] (doc.aux)
-LaTeX Font Warning: Some font shapes were not available, defaults substituted.
- )
-Here is how much of TeX's memory you used:
- 543 strings out of 12968
- 6147 string characters out of 289029
- 446019 words of memory out of 1453895
- 3433 multiletter control sequences out of 10000+10000
- 23403 words of font info for 87 fonts, out of 400000 for 2000
- 14 hyphenation exceptions out of 1000
- 21i,6n,20p,308b,283s stack positions out of 300i,100n,500p,50000b,4000s
-
-Output written on doc.dvi (9 pages, 29856 bytes).
diff --git a/support/tools/Burg/Doc/doc.tex b/support/tools/Burg/Doc/doc.tex
deleted file mode 100644
index 3dc67be317..0000000000
--- a/support/tools/Burg/Doc/doc.tex
+++ /dev/null
@@ -1,596 +0,0 @@
-\documentstyle[11pt,fullpage]{article}
-\begin{document}
-
-\def\AddSpace#1{\ifcat#1a\ \fi#1} % if next is a letter, add a space
-\def\YACC#1{{\sc Yacc}\AddSpace#1}
-\def\TWIG#1{{\sc Twig}\AddSpace#1}
-\def\PROG#1{{\sc Burg}\AddSpace#1}
-\def\PARSER#1{{\sc Burm}\AddSpace#1}
-\def\CODEGEN#1{{\sc Codegen}\AddSpace#1}
-
-\title{{\sc Burg} --- Fast Optimal Instruction Selection and Tree Parsing}
-\author{
-Christopher W. Fraser \\
-AT\&T Bell Laboratories \\
-600 Mountain Avenue 2C-464 \\
-Murray Hill, NJ 07974-0636 \\
-{\tt cwf@research.att.com}
-\and
-Robert R. Henry \\
-Tera Computer Company \\
-400 N. 34th St., Suite 300 \\
-Seattle, WA 98103-8600 \\
-{\tt rrh@tera.com}
-\and
-Todd A. Proebsting \\
-Dept. of Computer Sciences \\
-University of Wisconsin \\
-Madison, WI 53706 \\
-{\tt todd@cs.wisc.edu}
-}
-\date{December 1991}
-
-\maketitle
-\bibliographystyle{alpha}
-\newcommand\term[1]{{\it #1}}
-\newcommand\secref[1]{\S\ref{#1}}
-\newcommand\figref[1]{Figure~\ref{#1}}
-%
-% rationale table making
-%
-{\catcode`\^^M=13 \gdef\Obeycr{\catcode`\^^M=13 \def^^M{\\}}%
-\gdef\Restorecr{\catcode`\^^M=5 }} %
-
-%
-% for printing out options
-%
-\newcommand\option[1]{% #1=option character
-{\tt -#1}%
-}
-\newcommand\var[1]{%
-{\tt #1}%
-}
-\section{Overview}
-
-\PROG is a program that generates a fast tree parser using BURS
-(Bottom-Up Rewrite System) technology. It accepts a cost-augmented
-tree grammar and emits a C program that discovers in linear time an
-optimal parse of trees in the language described by the grammar. \PROG
-has been used to construct fast optimal instruction selectors for use
-in code generation. \PROG addresses many of the problems addressed by
-{\sc Twig}~\cite{aho-twig-toplas,appel-87}, but it is somewhat less flexible and
-much faster. \PROG is available via anonymous \var{ftp} from
-\var{kaese.cs.wisc.edu}. The compressed \var{shar} file
-\var{pub/burg.shar.Z} holds the complete distribution.
-
-This document describes only that fraction of the BURS model that is
-required to use \PROG. Readers interested in more detail might start
-with Reference~\cite{balachandran-complang}. Other relevant documents
-include References~\cite{kron-phd,hoffmann-jacm,hatcher-popl,chase-popl,pelegri-popl,pelegri-phd,wilhelm-tr,henry-budp,fraser-henry-spe-91,proebsting-91}.
-
-\section{Input}
-
-\PROG accepts a tree grammar and emits a BURS tree parser.
-\figref{fig-tree-grammar} shows a sample grammar that implements a very
-simple instruction selector.
-\begin{figure}
-\begin{verbatim}
-%{
-#define NODEPTR_TYPE treepointer
-#define OP_LABEL(p) ((p)->op)
-#define LEFT_CHILD(p) ((p)->left)
-#define RIGHT_CHILD(p) ((p)->right)
-#define STATE_LABEL(p) ((p)->state_label)
-#define PANIC printf
-%}
-%start reg
-%term Assign=1 Constant=2 Fetch=3 Four=4 Mul=5 Plus=6
-%%
-con: Constant = 1 (0);
-con: Four = 2 (0);
-addr: con = 3 (0);
-addr: Plus(con,reg) = 4 (0);
-addr: Plus(con,Mul(Four,reg)) = 5 (0);
-reg: Fetch(addr) = 6 (1);
-reg: Assign(addr,reg) = 7 (1);
-\end{verbatim}
-\caption{A Sample Tree Grammar\label{fig-tree-grammar}}
-\end{figure}
-\PROG grammars are structurally similar to \YACC's. Comments follow C
-conventions. Text between ``\var{\%\{}'' and ``\var{\%\}}'' is called
-the \term{configuration section}; there may be several such segments.
-All are concatenated and copied verbatim into the head of the generated
-parser, which is called \PARSER. Text after the second ``\var{\%\%}'',
-if any, is also copied verbatim into \PARSER, at the end.
-
-The configuration section configures \PARSER for the trees being parsed
-and the client's environment. This section must define
-\var{NODEPTR\_TYPE} to be a visible typedef symbol for a pointer to a
-node in the subject tree. \PARSER invokes \var{OP\_LABEL(p)},
-\var{LEFT\_CHILD(p)}, and \var{RIGHT\_CHILD(p)} to read the operator
-and children from the node pointed to by \var{p}. It invokes
-\var{PANIC} when it detects an error. If the configuration section
-defines these operations as macros, they are implemented in-line;
-otherwise, they must be implemented as functions. The section on
-diagnostics elaborates on \var{PANIC}.
-
-\PARSER computes and stores a single integral \term{state} in each node
-of the subject tree. The configuration section must define a macro
-\var{STATE\_LABEL(p)} to access the state field of the node pointed to
-by \var{p}. A macro is required because \PROG uses it as an lvalue. A
-C \var{short} is usually the right choice; typical code generation
-grammars require 100--1000 distinct state labels.
-
-The tree grammar follows the configuration section.
-\figref{fig-grammar-grammar} gives an EBNF grammar for \PROG tree
-grammars.
-\begin{figure}
-\begin{verbatim}
-grammar: {dcl} '%%' {rule}
-
-dcl: '%start' Nonterminal
-dcl: '%term' { Identifier '=' Integer }
-
-rule: Nonterminal ':' tree '=' Integer cost ';'
-cost: /* empty */
-cost: '(' Integer { ',' Integer } ')'
-
-tree: Term '(' tree ',' tree ')'
-tree: Term '(' tree ')'
-tree: Term
-tree: Nonterminal
-\end{verbatim}
-\caption{EBNF Grammar for Tree Grammars for \PROG\ \label{fig-grammar-grammar}}
-\end{figure}
-Comments, the text between ``\var{\%\{}'' and ``\var{\%\}}'', and the
-text after the optional second ``\var{\%\%}'' are treated lexically, so
-the figure omits them. In the EBNF grammar, quoted text must appear
-literally, \var{Nonterminal} and \var{Integer} are self-explanatory,
-and \var{Term} denotes an identifier previously declared as a
-terminal. {\tt\{$X$\}} denotes zero or more instances of $X$.
-
-Text before the first ``\var{\%\%}'' declares the start symbol and the
-terminals or operators in subject trees. All terminals must be
-declared; each line of such declarations begins with \var{\%term}.
-Each terminal has fixed arity, which \PROG infers from the rules using that terminal.
-\PROG restricts terminals to have at most two children. Each terminal
-is declared with a positive, unique, integral \term{external symbol
-number} after a ``\var{=}''. \var{OP\_LABEL(p)} must return the valid
-external symbol number for \var{p}. Ideally, external symbol numbers
-form a dense enumeration. Non-terminals are not declared, but the
-start symbol may be declared with a line that begins with
-\var{\%start}.
-
-Text after the first ``\var{\%\%}'' declares the rules. A tree grammar
-is like a context-free grammar: it has rules, non-terminals,
-terminals, and a special start non-terminal. The right-hand side of a
-rule, called the \term{pattern}, is a tree. Tree patterns appear in
-prefix parenthesized form. Every non-terminal denotes a tree. A chain
-rule is a rule whose pattern is another non-terminal. If no start
-symbol is declared, \PROG uses the non-terminal defined by the first
-rule. \PROG needs a single start symbol; grammars for which it is
-natural to use multiple start symbols must be augmented with an
-artificial start symbol that derives, with zero cost, the grammar's
-natural start symbols. \PARSER will automatically select one
-that costs least for any given tree.
-
-\PROG accepts no embedded semantic actions like \YACC's, because no one
-format suited all intended applications. Instead, each rule has a
-positive, unique, integral \term{external rule number}, after the
-pattern and preceded by a ``\var{=}''. Ideally, external rule numbers
-form a dense enumeration. \PARSER uses these numbers to report the
-matching rule to a user-supplied routine, which must implement any
-desired semantic action; see below. Humans may select these integers
-by hand, but \PROG is intended as a \term{server} for building BURS
-tree parsers. Thus some \PROG clients will consume a richer
-description and translate it into \PROG's simpler input.
-
-Rules end with a vector of non-negative, integer costs, in parentheses
-and separated by commas. If the cost vector is omitted, then all
-elements are assumed to be zero. \PROG retains only the first four
-elements of the list. The cost of a derivation is the sum of the costs
-for all rules applied in the derivation. Arithmetic on cost vectors
-treats each member of the vector independently. The tree parser finds
-the cheapest parse of the subject tree. It breaks ties arbitrarily.
-By default, \PROG uses only the \term{principal cost} of each cost
-vector, which defaults to the first element, but options described
-below provide alternatives.
-
-\section{Output}
-
-\PARSER traverses the subject tree twice. The first pass or
-\term{labeller} runs bottom-up and left-to-right, visiting each node
-exactly once. Each node is labeled with a state, a single number that
-encodes all full and partial optimal pattern matches viable at that
-node. The second pass or \term{reducer} traverses the subject tree
-top-down. The reducer accepts a tree node's state label and a
-\term{goal} non-terminal --- initially the root's state label and the
-start symbol --- which combine to determine the rule to be applied at
-that node. By construction, the rule has the given goal non-terminal
-as its left-hand side. The rule's pattern identifies the subject
-subtrees and goal non-terminals for all recursive visits. Here, a
-``subtree'' is not necessarily an immediate child of the current node.
-Patterns with interior operators cause the reducer to skip the
-corresponding subject nodes, so the reducer may proceed directly to
-grandchildren, great-grandchildren, and so on. On the other hand,
-chain rules cause the reducer to revisit the current subject node, with
-a new goal
-non-terminal, so \term{x} is also regarded as a subtree of \term{x}.
-
-As the reducer visits (and possibly revisits) each node, user-supplied
-code implements semantic action side effects and controls the order in
-which subtrees are visited. The labeller is self-contained, but the
-reducer combines code from \PROG with code from the user, so \PARSER
-does not stand alone.
-
-The \PARSER that is generated by \PROG provides primitives for
-labelling and reducing trees. These mechanisms are a compromise
-between expressibility, abstraction, simplicity, flexibility and
-efficiency. Clients may combine primitives into labellers and reducers
-that can traverse trees in arbitrary ways, and they may call semantic
-routines when and how they wish during traversal. Also, \PROG
-generates a few higher level routines that implement common
-combinations of primitives, and it generates mechanisms that help debug
-the tree parse.
-
-\PROG generates the labeller as a function named \var{burm\_label} with
-the signature
-\begin{verbatim}
-extern int burm_label(NODEPTR_TYPE p);
-\end{verbatim}
-It labels the entire subject tree pointed to by \var{p} and returns the
-root's state label. State zero labels unmatched trees. The trees may
-be corrupt or merely inconsistent with the grammar.
-
-The simpler \var{burm\_state} is \var{burm\_label} without the
-code to traverse the tree and to read and write its fields. It may be
-used to integrate labelling into user-supplied traversal code. A
-typical signature is
-\begin{verbatim}
-extern int burm_state(int op, int leftstate, int rightstate);
-\end{verbatim}
-It accepts an external symbol number for a node and the labels for the
-node's left and right children. It returns the state label to assign
-to that node. For unary operators, the last argument is ignored; for
-leaves, the last two arguments are ignored. In general, \PROG
-generates a \var{burm\_state} that accepts the maximum number of child
-states required by the input grammar. For example, if the grammar
-includes no binary operators, then \var{burm\_state} will have the
-signature
-\begin{verbatim}
-extern int burm_state(int op, int leftstate);
-\end{verbatim}
-This feature is included to permit future expansion to operators with
-more than two children.
-
-The user must write the reducer, but \PARSER writes code and data that
-help. Primary is
-\begin{verbatim}
-extern int burm_rule(int state, int goalnt);
-\end{verbatim}
-which accepts a tree's state label and a goal non-terminal and returns the
-external rule number of a rule. The rule will have matched the tree
-and have the goal non-terminal on the left-hand side; \var{burm\_rule}
-returns zero when the tree labelled with the given state did not match
-the goal non-terminal. For the initial, root-level call, \var{goalnt}
-must be one, and \PARSER exports an array that identifies the values
-for nested calls:
-\begin{verbatim}
-extern short *burm_nts[] = { ... };
-\end{verbatim}
-is an array indexed by external rule numbers. Each element points to a
-zero-terminated vector of short integers, which encode the goal
-non-terminals for that rule's pattern, left-to-right. The user needs
-only these two externals to write a complete reducer, but a third
-external simplifies some applications:
-\begin{verbatim}
-extern NODEPTR_TYPE *burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
-\end{verbatim}
-accepts the address of a tree \var{p}, an external rule number, and an
-empty vector of pointers to trees. The procedure assumes that \var{p}
-matched the given rule, and it fills in the vector with the subtrees (in
-the sense described above) of \var{p} that must be reduced recursively.
-\var{kids} is returned. It is not zero-terminated.
-
-The simple user code below labels and then fully reduces a subject tree;
-the reducer prints the tree cover. \var{burm\_string} is defined below.
-\begin{verbatim}
-parse(NODEPTR_TYPE p) {
- burm_label(p); /* label the tree */
- reduce(p, 1, 0); /* and reduce it */
-}
-
-reduce(NODEPTR_TYPE p, int goalnt, int indent) {
- int eruleno = burm_rule(STATE_LABEL(p), goalnt); /* matching rule number */
- short *nts = burm_nts[eruleno]; /* subtree goal non-terminals */
- NODEPTR_TYPE kids[10]; /* subtree pointers */
- int i;
-
- for (i = 0; i < indent; i++)
- printf("."); /* print indented ... */
- printf("%s\n", burm_string[eruleno]); /* ... text of rule */
- burm_kids(p, eruleno, kids); /* initialize subtree pointers */
- for (i = 0; nts[i]; i++) /* traverse subtrees left-to-right */
- reduce(kids[i], nts[i], indent+1); /* and print them recursively */
-}
-\end{verbatim}
-The reducer may recursively traverse subtrees in any order, and it may
-interleave arbitrary semantic actions with recursive traversals.
-Multiple reducers may be written, to implement multi-pass algorithms
-or independent single-pass algorithms.
-
-For each non-terminal $x$, \PROG emits a preprocessor directive to
-equate \var{burm\_}$x$\var{\_NT} with $x$'s integral encoding. It also
-defines a macro \var{burm\_}$x$\var{\_rule(a)} that is equivalent to
-\var{burm\_rule(a,}$x$\var{)}. For the grammar in
-\figref{fig-tree-grammar}, \PROG emits
-\begin{verbatim}
-#define burm_reg_NT 1
-#define burm_con_NT 2
-#define burm_addr_NT 3
-#define burm_reg_rule(a) ...
-#define burm_con_rule(a) ...
-#define burm_addr_rule(a) ...
-\end{verbatim}
-Such symbols are visible only to the code after the second
-``\var{\%\%}''. If the symbols \var{burm\_}$x$\var{\_NT} are needed
-elsewhere, extract them from the \PARSER source.
-
-The \option{I} option directs \PROG to emit an encoding of the input
-that may help the user produce diagnostics. The vectors
-\begin{verbatim}
-extern char *burm_opname[];
-extern char burm_arity[];
-\end{verbatim}
-hold the name and number of children, respectively, for each terminal.
-They are indexed by the terminal's external symbol number. The vectors
-\begin{verbatim}
-extern char *burm_string[];
-extern short burm_cost[][4];
-\end{verbatim}
-hold the text and cost vector for each rule. They are indexed by the
-external rule number. The zero-terminated vector
-\begin{verbatim}
-extern char *burm_ntname[];
-\end{verbatim}
-is indexed by \var{burm\_}$x$\var{\_NT} and holds the name of
-non-terminal $x$. Finally, the procedures
-\begin{verbatim}
-extern int burm_op_label(NODEPTR_TYPE p);
-extern int burm_state_label(NODEPTR_TYPE p);
-extern NODEPTR_TYPE burm_child(NODEPTR_TYPE p, int index);
-\end{verbatim}
-are callable versions of the configuration macros.
-\var{burm\_child(p,0)} implements \var{LEFT\_CHILD(p)}, and
-\var{burm\_child(p,1)} implements \var{RIGHT\_CHILD(p)}. A sample use
-is the grammar-independent expression
-\var{burm\_opname[burm\_op\_label(p)]}, which yields the textual name
-for the operator in the tree node pointed to by \var{p}.
-
-A complete tree parser can be assembled from just \var{burm\_state},
-\var{burm\_rule}, and \var{burm\_nts}, which use none of the
-configuration section except \var{PANIC}. The generated routines that
-use the rest of the configuration section are compiled only if the
-configuration section defines \var{STATE\_LABEL}, so they can be
-omitted if the user prefers to hide the tree structure from \PARSER.
-This course may be wise if, say, the tree structure is defined in a
-large header file with symbols that might collide with \PARSER's.
-
-\PARSER selects an optimal parse without dynamic programming at compile
-time~\cite{aho-johnson-dp-classic}. Instead, \PROG does the dynamic
-programming at compile-compile time, as it builds \PARSER.
-Consequently, \PARSER parses quickly. Similar labellers have taken as
-few as 15 instructions per node, and reducers as few as 35 per node
-visited~\cite{fraser-henry-spe-91}.
-
-\section{Debugging}
-
-\PARSER invokes \var{PANIC} when an error prevents it from proceeding.
-\var{PANIC} has the same signature as \var{printf}. It should pass its
-arguments to \var{printf} if diagnostics are desired and then either
-abort (say via \var{exit}) or recover (say via \var{longjmp}). If it
-returns, \PARSER aborts. Some errors are not caught.
-
-\PROG assumes a robust preprocessor, so it omits full consistency
-checking and error recovery. \PROG constructs a set of states using a
-closure algorithm like that used in LR table construction. \PROG
-considers all possible trees generated by the tree grammar and
-summarizes infinite sets of trees with finite sets. The summary
-records the cost of those trees but actually manipulates the
-differences in costs between viable alternatives using a dynamic
-programming algorithm. Reference~\cite{henry-budp} elaborates.
-
-Some grammars derive trees whose optimal parses depend on arbitrarily
-distant data. When this happens, \PROG and the tree grammar
-\term{cost diverge}, and \PROG attempts to build an infinite
-set of states; it first thrashes and ultimately exhausts
-memory and exits. For example, the tree grammar in
-\figref{fig-diverge-grammar}
-\begin{figure}
-\begin{verbatim}
-%term Const=17 RedFetch=20 GreenFetch=21 Plus=22
-%%
-reg: GreenFetch(green_reg) = 10 (0);
-reg: RedFetch(red_reg) = 11 (0);
-
-green_reg: Const = 20 (0);
-green_reg: Plus(green_reg,green_reg) = 21 (1);
-
-red_reg: Const = 30 (0);
-red_reg: Plus(red_reg,red_reg) = 31 (2);
-\end{verbatim}
-\caption{A Diverging Tree Grammar\label{fig-diverge-grammar}}
-\end{figure}
-diverges, since non-terminals \var{green\_reg} and \var{red\_reg}
-derive identical infinite trees with different costs. If the cost of
-rule 31 is changed to 1, then the grammar does not diverge.
-
-Practical tree grammars describing instruction selection do not
-cost-diverge because infinite trees are derived from non-terminals
-that model temporary registers. Machines can move data between
-different types of registers for a small bounded cost, and the rules
-for these instructions prevent divergence. For example, if
-\figref{fig-diverge-grammar} included rules to move data between red
-and green registers, the grammar would not diverge. If a bonafide
-machine grammar appears to make \PROG loop, try a host with more
-memory. To apply \PROG to problems other than instruction selection,
-be prepared to consult the literature on
-cost-divergence~\cite{pelegri-phd}.
-
-\section{Running \PROG\ }\label{sec-man-page}
-
-\PROG reads a tree grammar and writes a \PARSER in C. \PARSER can be
-compiled by itself or included in another file. When suitably named
-with the \option{p} option, disjoint instances of \PARSER should link
-together without name conflicts. The command:
-\begin{flushleft}
-\var{burg} [ {\it arguments} ] [ {\it file} ]
-\end{flushleft}
-invokes \PROG. If a {\it file} is named, \PROG expects its grammar
-there; otherwise it reads the standard input. The options include:
-\def\Empty{}
-%
-\newcommand\odescr[2]{% #1=option character, #2=optional argument
-\gdef\Arg2{#2}%
-\item[\option{#1}\ifx\Arg2\Empty\else{{\it #2}}\fi]
-}
-\begin{description}
-%
-\odescr{c}{} $N$
-Abort if any relative cost exceeds $N$, which keeps \PROG from looping on
-diverging grammars. Several
-references~\cite{pelegri-popl,henry-budp,balachandran-complang,proebsting-91}
-explain relative costs.
-%
-\odescr{d}{}
-Report a few statistics and flag unused rules and terminals.
-%
-\odescr{o}{} {\it file}
-Write parser into {\it file}. Otherwise it writes to the standard output.
-%
-\odescr{p}{} {\it prefix}
-Start exported names with {\it prefix}. The default is \var{burm}.
-%
-\odescr{t}{}
-Generates smaller tables faster, but all goal non-terminals passed to
-\var{burm\_rule} must come from an appropriate \var{burm\_nts}. Using
-\var{burm\_}$x$\var{\_NT} instead may give unpredictable results.
-%
-\odescr{I}{}
-Emit code for \var{burm\_arity}, \var{burm\_child}, \var{burm\_cost},
-\var{burm\_ntname}, \var{burm\_op\_label}, \var{burm\_opname},
-\var{burm\_state\_label}, and \var{burm\_string}.
-%
-\odescr{O}{} $N$
-Change the principal cost to $N$. Elements of each cost vector are
-numbered from zero.
-%
-\odescr{=}{}
-Compare costs lexicographically, using all costs in the given order.
-This option slows \PROG and may produce a larger parser. Increases
-range from small to astronomical.
-\end{description}
-
-\section{Acknowledgements}
-
-The first \PROG was adapted by the second author from his \CODEGEN
-package, which was developed at the University of Washington with
-partial support from NSF Grant CCR-88-01806. It was unbundled from
-\CODEGEN with the support of Tera Computer. The current \PROG was
-written by the third author with the support of NSF grant
-CCR-8908355. The interface, documentation, and testing involved
-all three authors.
-
-Comments from a large group at the 1991 Dagstuhl Seminar on Code
-Generation improved \PROG's interface. Robert Giegerich and Susan
-Graham organized the workshop, and the International Conference and
-Research Center for Computer Science, Schloss Dagstuhl, provided an
-ideal environment for such collaboration. Beta-testers included Helmut
-Emmelmann, Dave Hanson, John Hauser, Hugh Redelmeier, and Bill Waite.
-
-\begin{thebibliography}{BMW87}
-
-\bibitem[AGT89]{aho-twig-toplas}
-Alfred~V. Aho, Mahadevan Ganapathi, and Steven W.~K. Tjiang.
-\newblock Code generation using tree matching and dynamic programming.
-\newblock {\em ACM Transactions on Programming Languages and Systems},
- 11(4):491--516, October 1989.
-
-\bibitem[AJ76]{aho-johnson-dp-classic}
-Alfred~V. Aho and Steven~C. Johnson.
-\newblock Optimal code generation for expression trees.
-\newblock {\em Journal of the ACM}, 23(3):458--501, July 1976.
-
-\bibitem[App87]{appel-87}
-Andrew~W. Appel.
-\newblock Concise specification of locally optimal code generators.
-\newblock Technical report CS-TR-080-87, Princeton University, 1987.
-
-\bibitem[BDB90]{balachandran-complang}
-A.~Balachandran, D.~M. Dhamdhere, and S.~Biswas.
-\newblock Efficient retargetable code generation using bottom-up tree pattern
- matching.
-\newblock {\em Computer Languages}, 15(3):127--140, 1990.
-
-\bibitem[BMW87]{wilhelm-tr}
-J\"{u}rgen B\"{o}rstler, Ulrich M\"{o}nche, and Reinhard Wilhelm.
-\newblock Table compression for tree automata.
-\newblock Technical Report Aachener Informatik-Berichte No. 87-12, RWTH Aachen,
- Fachgruppe Informatik, Aachen, Fed. Rep. of Germany, 1987.
-
-\bibitem[Cha87]{chase-popl}
-David~R. Chase.
-\newblock An improvement to bottom up tree pattern matching.
-\newblock {\em Fourteenth Annual ACM Symposium on Principles of Programming
- Languages}, pages 168--177, January 1987.
-
-\bibitem[FH91]{fraser-henry-spe-91}
-Christopher~W. Fraser and Robert~R. Henry.
-\newblock Hard-coding bottom-up code generation tables to save time and space.
-\newblock {\em Software---Practice\&Experience}, 21(1):1--12, January 1991.
-
-\bibitem[HC86]{hatcher-popl}
-Philip~J. Hatcher and Thomas~W. Christopher.
-\newblock High-quality code generation via bottom-up tree pattern matching.
-\newblock {\em Thirteenth Annual ACM Symposium on Principles of Programming
- Languages}, pages 119--130, January 1986.
-
-\bibitem[Hen89]{henry-budp}
-Robert~R. Henry.
-\newblock Encoding optimal pattern selection in a table-driven bottom-up
- tree-pattern matcher.
-\newblock Technical Report 89-02-04, University of Washington Computer Science
- Department, Seattle, WA, February 1989.
-
-\bibitem[HO82]{hoffmann-jacm}
-Christoph Hoffmann and Michael~J. O'Donnell.
-\newblock Pattern matching in trees.
-\newblock {\em Journal of the ACM}, 29(1):68--95, January 1982.
-
-\bibitem[Kro75]{kron-phd}
-H.~H. Kron.
-\newblock {\em Tree Templates and Subtree Transformational Grammars}.
-\newblock PhD thesis, UC Santa Cruz, December 1975.
-
-\bibitem[PL87]{pelegri-phd}
-Eduardo Pelegri-Llopart.
-\newblock {\em Tree Transformations in Compiler Systems}.
-\newblock PhD thesis, UC Berkeley, December 1987.
-
-\bibitem[PLG88]{pelegri-popl}
-Eduardo Pelegri-Llopart and Susan~L. Graham.
-\newblock Optimal code generation for expression trees: An application of
- {BURS} theory.
-\newblock {\em Fifteenth Annual ACM Symposium on Principles of Programming
- Languages}, pages 294--308, January 1988.
-
-\bibitem[Pro91]{proebsting-91}
-Todd~A. Proebsting.
-\newblock Simple and efficient {BURS} table generation.
-\newblock Technical report, Department of Computer Sciences, University of
- Wisconsin, 1991.
-
-\end{thebibliography}
-
-\end{document}
-
diff --git a/support/tools/Burg/LOG_CHANGES b/support/tools/Burg/LOG_CHANGES
deleted file mode 100644
index 804f00378b..0000000000
--- a/support/tools/Burg/LOG_CHANGES
+++ /dev/null
@@ -1,10 +0,0 @@
-8/20/02 -- Vikram Adve
- be.c: Replaced "char*" with "const char*" to avoid compiler warnings.
-
-9/9/03 -- John Criswell
- b.h be.c fe.h gram.y lex.c main.c map.c nontermainl.c plan.c zalloc.c:
- A cursory look through our logs and comments indicates that these are
- the only modified files. No feature enhancements have been made;
- rather, all changes either fix minor programming errors, get rid of
- warnings, ANSI-ify the code, or integrate Burg into our build system.
-
diff --git a/support/tools/Burg/Makefile b/support/tools/Burg/Makefile
deleted file mode 100644
index d1b9fe27fd..0000000000
--- a/support/tools/Burg/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-LEVEL = ../../..
-TOOLNAME = burg
-ExtraSource = gram.tab.c
-
-include $(LEVEL)/Makefile.common
-
-gram.tab.c gram.tab.h:: gram.yc
- $(VERB) $(BISON) -o gram.tab.c -d $<
-
-$(SourceDir)/lex.c: gram.tab.h
-
-clean::
- rm -rf gram.tab.h gram.tab.c core* *.aux *.log *.dvi sample sample.c tmp
-
-#$(BUILD_OBJ_DIR)/Release/lex.o $(BUILD_OBJ_DIR)/Profile/lex.o $(BUILD_OBJ_DIR)/Debug/lex.o: gram.tab.h
-
-doc.dvi: doc.tex
- latex doc; latex doc
-
-
-test:: $(TOOLEXENAME_G) sample.gr
- $(TOOLEXENAME_G) -I <sample.gr >sample.c && $(CC) $(CFLAGS) -o sample sample.c && ./sample
- $(TOOLEXENAME_G) -I sample.gr >tmp && cmp tmp sample.c
- $(TOOLEXENAME_G) -I <sample.gr -o tmp && cmp tmp sample.c
- $(TOOLEXENAME_G) -I sample.gr -o tmp && cmp tmp sample.c
- $(TOOLEXENAME_G) -I -O0 <sample.gr >tmp && cmp tmp sample.c
- $(TOOLEXENAME_G) -I -= <sample.gr >tmp && cmp tmp sample.c
- $(RM) -f tmp sample.c
diff --git a/support/tools/Burg/README b/support/tools/Burg/README
deleted file mode 100644
index bc26405727..0000000000
--- a/support/tools/Burg/README
+++ /dev/null
@@ -1,14 +0,0 @@
-To format the documentation, type "make doc.dvi" and print the result.
-
-The length of the cost vectors is fixed at 4 for reasons that are
-primarily historical. To change it, edit the definition of DELTAWIDTH
-in b.h.
-
-Burg is compiled without optimization by default to avoid problems
-with initial installation. To improve burg's performance, add '-O' to
-CFLAGS in the Makefile and rebuild burg with a high quality optimizing
-compiler.
-
-To be added to the Burg mailing list, send your preferred electronic
-mail address to cwf@research.att.com.
-
diff --git a/support/tools/Burg/b.h b/support/tools/Burg/b.h
deleted file mode 100644
index 164325dc97..0000000000
--- a/support/tools/Burg/b.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/* $Id$ */
-
-#define MAX_ARITY 2
-
-typedef int ItemSetNum;
-typedef int OperatorNum;
-typedef int NonTerminalNum;
-typedef int RuleNum;
-typedef int ArityNum;
-typedef int ERuleNum;
-
-extern NonTerminalNum last_user_nonterminal;
-extern NonTerminalNum max_nonterminal;
-extern RuleNum max_rule;
-extern ERuleNum max_erule_num;
-extern int max_arity;
-
-#ifdef __STDC__
-#define ARGS(x) x
-#else
-#define ARGS(x) ()
-#endif
-
-#ifndef NOLEX
-#define DELTAWIDTH 4
-typedef short DeltaCost[DELTAWIDTH];
-typedef short *DeltaPtr;
-extern void ASSIGNCOST ARGS((DeltaPtr, DeltaPtr));
-extern void ADDCOST ARGS((DeltaPtr, DeltaPtr));
-extern void MINUSCOST ARGS((DeltaPtr, DeltaPtr));
-extern void ZEROCOST ARGS((DeltaPtr));
-extern int LESSCOST ARGS((DeltaPtr, DeltaPtr));
-extern int EQUALCOST ARGS((DeltaPtr, DeltaPtr));
-#define PRINCIPLECOST(x) (x[0])
-#else
-#define DELTAWIDTH 1
-typedef int DeltaCost;
-typedef int DeltaPtr;
-#define ASSIGNCOST(l, r) ((l) = (r))
-#define ADDCOST(l, r) ((l) += (r))
-#define MINUSCOST(l, r) ((l) -= (r))
-#define ZEROCOST(x) ((x) = 0)
-#define LESSCOST(l, r) ((l) < (r))
-#define EQUALCOST(l, r) ((l) == (r))
-#define PRINCIPLECOST(x) (x)
-#endif /* NOLEX */
-#define NODIVERGE(c,state,nt,base) if (prevent_divergence > 0) CHECKDIVERGE(c,state,nt,base);
-
-struct list {
- void *x;
- struct list *next;
-};
-typedef struct list *List;
-
-struct intlist {
- int x;
- struct intlist *next;
-};
-typedef struct intlist *IntList;
-
-struct operator {
- char *name;
- unsigned int ref:1;
- OperatorNum num;
- ItemSetNum baseNum;
- ItemSetNum stateCount;
- ArityNum arity;
- struct table *table;
-};
-typedef struct operator *Operator;
-
-struct nonterminal {
- char *name;
- NonTerminalNum num;
- ItemSetNum baseNum;
- ItemSetNum ruleCount;
- struct plankMap *pmap;
-
- struct rule *sampleRule; /* diagnostic---gives "a" rule that with this lhs */
-};
-typedef struct nonterminal *NonTerminal;
-
-struct pattern {
- NonTerminal normalizer;
- Operator op; /* NULL if NonTerm -> NonTerm */
- NonTerminal children[MAX_ARITY];
-};
-typedef struct pattern *Pattern;
-
-struct rule {
- DeltaCost delta;
- ERuleNum erulenum;
- RuleNum num;
- RuleNum newNum;
- NonTerminal lhs;
- Pattern pat;
- unsigned int used:1;
-};
-typedef struct rule *Rule;
-
-struct item {
- DeltaCost delta;
- Rule rule;
-};
-typedef struct item Item;
-
-typedef short *Relevant; /* relevant non-terminals */
-
-typedef Item *ItemArray;
-
-struct item_set { /* indexed by NonTerminal */
- ItemSetNum num;
- ItemSetNum newNum;
- Operator op;
- struct item_set *kids[2];
- struct item_set *representative;
- Relevant relevant;
- ItemArray virgin;
- ItemArray closed;
-};
-typedef struct item_set *Item_Set;
-
-#define DIM_MAP_SIZE (1 << 8)
-#define GLOBAL_MAP_SIZE (1 << 15)
-
-struct mapping { /* should be a hash table for TS -> int */
- List *hash;
- int hash_size;
- int max_size;
- ItemSetNum count;
- Item_Set *set; /* map: int <-> Item_Set */
-};
-typedef struct mapping *Mapping;
-
-struct index_map {
- ItemSetNum max_size;
- Item_Set *class;
-};
-typedef struct index_map Index_Map;
-
-struct dimension {
- Relevant relevant;
- Index_Map index_map;
- Mapping map;
- ItemSetNum max_size;
- struct plankMap *pmap;
-};
-typedef struct dimension *Dimension;
-
-
-struct table {
- Operator op;
- List rules;
- Relevant relevant;
- Dimension dimen[MAX_ARITY]; /* 1 for each dimension */
- Item_Set *transition; /* maps local indices to global
- itemsets */
-};
-typedef struct table *Table;
-
-struct relation {
- Rule rule;
- DeltaCost chain;
- NonTerminalNum nextchain;
- DeltaCost sibling;
- int sibFlag;
- int sibComputed;
-};
-typedef struct relation *Relation;
-
-struct queue {
- List head;
- List tail;
-};
-typedef struct queue *Queue;
-
-struct plank {
- char *name;
- List fields;
- int width;
-};
-typedef struct plank *Plank;
-
-struct except {
- short index;
- short value;
-};
-typedef struct except *Exception;
-
-struct plankMap {
- List exceptions;
- int offset;
- struct stateMap *values;
-};
-typedef struct plankMap *PlankMap;
-
-struct stateMap {
- char *fieldname;
- Plank plank;
- int width;
- short *value;
-};
-typedef struct stateMap *StateMap;
-
-struct stateMapTable {
- List maps;
-};
-
-extern void CHECKDIVERGE ARGS((DeltaPtr, Item_Set, int, int));
-extern void zero ARGS((Item_Set));
-extern ItemArray newItemArray ARGS((void));
-extern ItemArray itemArrayCopy ARGS((ItemArray));
-extern Item_Set newItem_Set ARGS((Relevant));
-extern void freeItem_Set ARGS((Item_Set));
-extern Mapping newMapping ARGS((int));
-extern NonTerminal newNonTerminal ARGS((char *));
-extern int nonTerminalName ARGS((char *, int));
-extern Operator newOperator ARGS((char *, OperatorNum, ArityNum));
-extern Pattern newPattern ARGS((Operator));
-extern Rule newRule ARGS((DeltaPtr, ERuleNum, NonTerminal, Pattern));
-extern List newList ARGS((void *, List));
-extern IntList newIntList ARGS((int, IntList));
-extern int length ARGS((List));
-extern List appendList ARGS((void *, List));
-extern Table newTable ARGS((Operator));
-extern Queue newQ ARGS((void));
-extern void addQ ARGS((Queue, Item_Set));
-extern Item_Set popQ ARGS((Queue));
-extern int equivSet ARGS((Item_Set, Item_Set));
-extern Item_Set decode ARGS((Mapping, ItemSetNum));
-extern Item_Set encode ARGS((Mapping, Item_Set, int *));
-extern void build ARGS((void));
-extern Item_Set *transLval ARGS((Table, int, int));
-
-typedef void * (*ListFn) ARGS((void *));
-extern void foreachList ARGS((ListFn, List));
-extern void reveachList ARGS((ListFn, List));
-
-extern void addToTable ARGS((Table, Item_Set));
-
-extern void closure ARGS((Item_Set));
-extern void trim ARGS((Item_Set));
-extern void findChainRules ARGS((void));
-extern void findAllPairs ARGS((void));
-extern void addRelevant ARGS((Relevant, NonTerminalNum));
-
-extern void *zalloc ARGS((unsigned int));
-extern void zfree ARGS((void *));
-
-extern NonTerminal start;
-extern List rules;
-extern List chainrules;
-extern List operators;
-extern List leaves;
-extern List nonterminals;
-extern List grammarNts;
-extern Queue globalQ;
-extern Mapping globalMap;
-extern int exceptionTolerance;
-extern int prevent_divergence;
-extern int principleCost;
-extern int lexical;
-extern struct rule stub_rule;
-extern Relation *allpairs;
-extern Item_Set *sortedStates;
-extern Item_Set errorState;
-
-extern void dumpRelevant ARGS((Relevant));
-extern void dumpOperator ARGS((Operator, int));
-extern void dumpOperator_s ARGS((Operator));
-extern void dumpOperator_l ARGS((Operator));
-extern void dumpNonTerminal ARGS((NonTerminal));
-extern void dumpRule ARGS((Rule));
-extern void dumpRuleList ARGS((List));
-extern void dumpItem ARGS((Item *));
-extern void dumpItem_Set ARGS((Item_Set));
-extern void dumpMapping ARGS((Mapping));
-extern void dumpQ ARGS((Queue));
-extern void dumpIndex_Map ARGS((Index_Map *));
-extern void dumpDimension ARGS((Dimension));
-extern void dumpPattern ARGS((Pattern));
-extern void dumpTable ARGS((Table, int));
-extern void dumpTransition ARGS((Table));
-extern void dumpCost ARGS((DeltaCost));
-extern void dumpAllPairs ARGS((void));
-extern void dumpRelation ARGS((Relation));
-extern void dumpSortedStates ARGS((void));
-extern void dumpSortedRules ARGS((void));
-extern int debugTrim;
-
-#ifdef DEBUG
-#define debug(a,b) if (a) b
-#else
-#define debug(a,b)
-#endif
-extern int debugTables;
-
-#define TABLE_INCR 8
-#define STATES_INCR 64
-
-#ifdef NDEBUG
-#define assert(c) ((void) 0)
-#else
-#define assert(c) ((void) ((c) || fatal(__FILE__,__LINE__)))
-#endif
-
-extern void doStart ARGS((char *));
-extern void exit ARGS((int));
-extern int fatal ARGS((const char *, int));
-extern void yyerror ARGS((const char *));
-extern void yyerror1 ARGS((const char *));
diff --git a/support/tools/Burg/be.c b/support/tools/Burg/be.c
deleted file mode 100644
index defe948d2d..0000000000
--- a/support/tools/Burg/be.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-char rcsid_be[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-
-#define ERROR_VAL 0
-
-FILE *outfile;
-const char *prefix = "burm";
-
-static void doKids ARGS((RuleAST));
-static void doLabel ARGS((Operator));
-static void doLayout ARGS((RuleAST));
-static void doMakeTable ARGS((Operator));
-static void doVector ARGS((RuleAST));
-static void layoutNts ARGS((PatternAST));
-static void makeIndex_Map ARGS((Dimension));
-static void makePvector ARGS((void));
-static void makeState ARGS((void));
-static void printPatternAST ARGS((PatternAST));
-static void printPatternAST_int ARGS((PatternAST));
-static void setVectors ARGS((PatternAST));
-static void trailing_zeroes ARGS((int));
-static int seminal ARGS((int from, int to));
-static void printRule ARGS((RuleAST, const char *));
-
-static void
-doLabel(op) Operator op;
-{
- fprintf(outfile, "\tcase %d:\n", op->num);
-
- switch (op->arity) {
- default:
- assert(0);
- break;
- case 0:
- fprintf(outfile, "\t\treturn %d;\n", op->table->transition[0]->num);
- break;
- case 1:
- if (op->table->rules) {
- fprintf(outfile, "\t\treturn %s_%s_transition[l];\n", prefix, op->name);
- } else {
- fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
- }
- break;
- case 2:
- if (op->table->rules) {
- fprintf(outfile, "\t\treturn %s_%s_transition[%s_%s_imap_1[l]][%s_%s_imap_2[r]];\n", prefix, op->name, prefix, op->name, prefix, op->name);
- } else {
- fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
- }
- break;
- }
-}
-
-int
-opsOfArity(arity) int arity;
-{
- int c;
- List l;
-
- c = 0;
- for (l = operators; l; l = l->next) {
- Operator op = (Operator) l->x;
- if (op->arity == arity) {
- fprintf(outfile, "\tcase %d:\n", op->num);
- c++;
- }
- }
- return c;
-}
-
-static void
-trailing_zeroes(z) int z;
-{
- int i;
-
- for (i = 0; i < z; i++) {
- fprintf(outfile, ", 0");
- }
-}
-
-void
-makeLabel()
-{
- int flag;
-
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "int %s_label(%s_NODEPTR_TYPE n) {\n", prefix, prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_label(n) %s_NODEPTR_TYPE n; {\n", prefix, prefix);
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile,
- "\t%s_assert(n, %s_PANIC(\"NULL pointer passed to %s_label\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile, "\tswitch (%s_OP_LABEL(n)) {\n", prefix);
- fprintf(outfile, "\tdefault: %s_PANIC(\"Bad op %%d in %s_label\\n\", %s_OP_LABEL(n)); abort(); return 0;\n",
- prefix, prefix, prefix);
-
- flag = opsOfArity(0);
- if (flag > 0) {
- fprintf(outfile, "\t\treturn %s_STATE_LABEL(n) = %s_state(%s_OP_LABEL(n)",
- prefix, prefix, prefix);
- trailing_zeroes(max_arity);
- fprintf(outfile, ");\n");
- }
- flag = opsOfArity(1);
- if (flag > 0) {
- fprintf(outfile, "\t\treturn %s_STATE_LABEL(n) = %s_state(%s_OP_LABEL(n), %s_label(%s_LEFT_CHILD(n))",
- prefix, prefix, prefix, prefix, prefix);
- trailing_zeroes(max_arity-1);
- fprintf(outfile, ");\n");
- }
- flag = opsOfArity(2);
- if (flag > 0) {
- fprintf(outfile, "\t\treturn %s_STATE_LABEL(n) = %s_state(%s_OP_LABEL(n), %s_label(%s_LEFT_CHILD(n)), %s_label(%s_RIGHT_CHILD(n))",
- prefix, prefix, prefix, prefix, prefix, prefix, prefix);
- trailing_zeroes(max_arity-2);
- fprintf(outfile, ");\n");
-
- }
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "}\n");
-}
-
-static void
-makeState()
-{
- fprintf(outfile, "int %s_state(int op, int l, int r) {\n", prefix);
- fprintf(outfile,
- "\t%s_assert(l >= 0 && l < %d, PANIC(\"Bad state %%d passed to %s_state\\n\", l));\n",
- prefix, globalMap->count, prefix);
- fprintf(outfile,
- "\t%s_assert(r >= 0 && r < %d, PANIC(\"Bad state %%d passed to %s_state\\n\", r));\n",
- prefix, globalMap->count, prefix);
- fprintf(outfile, "\tswitch (op) {\n");
- fprintf(outfile, "\tdefault: %s_PANIC(\"Bad op %%d in %s_state\\n\", op); abort(); return 0;\n", prefix, prefix);
-
- foreachList((ListFn) doLabel, operators);
-
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "}\n");
-}
-
-static char cumBuf[4000];
-static int vecIndex;
-char vecBuf[4000];
-
-static void
-setVectors(ast) PatternAST ast;
-{
- char old[4000];
-
- switch (ast->sym->tag) {
- default:
- assert(0);
- break;
- case NONTERMINAL:
- sprintf(old, "\t\tkids[%d] = %s;\n", vecIndex, vecBuf);
- strcat(cumBuf, old);
- vecIndex++;
- return;
- case OPERATOR:
- switch (ast->sym->u.op->arity) {
- default:
- assert(0);
- break;
- case 0:
- return;
- case 1:
- strcpy(old, vecBuf);
- sprintf(vecBuf, "%s_LEFT_CHILD(%s)", prefix, old);
- setVectors((PatternAST) ast->children->x);
- strcpy(vecBuf, old);
- return;
- case 2:
- strcpy(old, vecBuf);
- sprintf(vecBuf, "%s_LEFT_CHILD(%s)", prefix, old);
- setVectors((PatternAST) ast->children->x);
-
- sprintf(vecBuf, "%s_RIGHT_CHILD(%s)", prefix, old);
- setVectors((PatternAST) ast->children->next->x);
- strcpy(vecBuf, old);
- return;
- }
- break;
- }
-}
-
-#define MAX_VECTOR 10
-
-void
-makeRuleTable()
-{
- int s,nt;
-
- fprintf(outfile, "static short %s_RuleNo[%d][%d] = {\n", prefix, globalMap->count, last_user_nonterminal-1);
- for (s = 0; s < globalMap->count; s++) {
- Item_Set ts = globalMap->set[s];
- if (s > 0) {
- fprintf(outfile, ",\n");
- }
- fprintf(outfile, "/* state %d */\n", s);
- fprintf(outfile, "{");
- for (nt = 1; nt < last_user_nonterminal; nt++) {
- if (nt > 1) {
- fprintf(outfile, ",");
- if (nt % 10 == 1) {
- fprintf(outfile, "\t/* state %d; Nonterminals %d-%d */\n", s, nt-10, nt-1);
- }
- }
- if (ts->closed[nt].rule) {
- ts->closed[nt].rule->used = 1;
- fprintf(outfile, "%5d", ts->closed[nt].rule->erulenum);
- } else {
- fprintf(outfile, "%5d", ERROR_VAL);
- }
- }
- fprintf(outfile, "}");
- }
- fprintf(outfile, "};\n");
-}
-
-static void
-makeIndex_Map(d) Dimension d;
-{
- int s;
-
- for (s = 0; s < globalMap->count; s++) {
- if (s > 0) {
- fprintf(outfile, ",");
- if (s % 10 == 0) {
- fprintf(outfile, "\t/* %d-%d */\n", s-10, s-1);
- }
- }
- fprintf(outfile, "%5d", d->map->set[d->index_map.class[s]->num]->num);
- }
- fprintf(outfile, "};\n");
-}
-
-static void
-doMakeTable(op) Operator op;
-{
- int s;
- int i,j;
- Dimension d;
-
- switch (op->arity) {
- default:
- assert(0);
- break;
- case 0:
- return;
- case 1:
- if (!op->table->rules) {
- return;
- }
- d = op->table->dimen[0];
- fprintf(outfile, "static short %s_%s_transition[%d] = {\n", prefix, op->name, globalMap->count);
- for (s = 0; s < globalMap->count; s++) {
- if (s > 0) {
- fprintf(outfile, ", ");
- if (s % 10 == 0) {
- fprintf(outfile, "\t/* %d-%d */\n", s-10, s-1);
- }
- }
- fprintf(outfile, "%5d", op->table->transition[d->map->set[d->index_map.class[s]->num]->num]->num);
- }
- fprintf(outfile, "};\n");
- break;
- case 2:
- if (!op->table->rules) {
- return;
- }
- fprintf(outfile, "static short %s_%s_imap_1[%d] = {\n", prefix, op->name, globalMap->count);
- makeIndex_Map(op->table->dimen[0]);
- fprintf(outfile, "static short %s_%s_imap_2[%d] = {\n", prefix, op->name, globalMap->count);
- makeIndex_Map(op->table->dimen[1]);
-
- fprintf(outfile, "static short %s_%s_transition[%d][%d] = {", prefix, op->name,
- op->table->dimen[0]->map->count,
- op->table->dimen[1]->map->count);
- for (i = 0; i < op->table->dimen[0]->map->count; i++) {
- if (i > 0) {
- fprintf(outfile, ",");
- }
- fprintf(outfile, "\n");
- fprintf(outfile, "{");
- for (j = 0; j < op->table->dimen[1]->map->count; j++) {
- Item_Set *ts = transLval(op->table, i, j);
- if (j > 0) {
- fprintf(outfile, ",");
- }
- fprintf(outfile, "%5d", (*ts)->num);
- }
- fprintf(outfile, "}\t/* row %d */", i);
- }
- fprintf(outfile, "\n};\n");
-
- break;
- }
-}
-
-void
-makeTables()
-{
- foreachList((ListFn) doMakeTable, operators);
-}
-
-RuleAST *pVector;
-
-void
-makeLHSmap()
-{
- int i;
-
- if (!pVector) {
- makePvector();
- }
-
- fprintf(outfile, "short %s_lhs[] = {\n", prefix);
- for (i = 0; i <= max_erule_num; i++) {
- if (pVector[i]) {
- fprintf(outfile, "\t%s_%s_NT,\n", prefix, pVector[i]->lhs);
- } else {
- fprintf(outfile, "\t0,\n");
- }
- }
- fprintf(outfile, "};\n\n");
-}
-
-static int seminal(int from, int to)
-{
- return allpairs[from][to].rule ? allpairs[from][to].rule->erulenum : 0;
-
- /*
- int tmp, last;
- tmp = 0;
- for (;;) {
- last = tmp;
- tmp = allpairs[to][from].rule ? allpairs[to][from].rule->erulenum : 0;
- if (!tmp) {
- break;
- }
- assert(pVector[tmp]);
- to = pVector[tmp]->rule->pat->children[0]->num;
- }
- return last;
- */
-}
-
-void
-makeClosureArray()
-{
- int i, j;
-
- if (!pVector) {
- makePvector();
- }
-
- fprintf(outfile, "short %s_closure[%d][%d] = {\n", prefix, last_user_nonterminal, last_user_nonterminal);
- for (i = 0; i < last_user_nonterminal; i++) {
- fprintf(outfile, "\t{");
- for (j = 0; j < last_user_nonterminal; j++) {
- if (j > 0 && j%10 == 0) {
- fprintf(outfile, "\n\t ");
- }
- fprintf(outfile, " %4d,", seminal(i,j));
- }
- fprintf(outfile, "},\n");
- }
- fprintf(outfile, "};\n");
-}
-
-void
-makeCostVector(z,d) int z; DeltaCost d;
-{
- fprintf(outfile, "\t{");
-#ifdef NOLEX
- if (z) {
- fprintf(outfile, "%5d", d);
- } else {
- fprintf(outfile, "%5d", 0);
- }
-#else
- {
- int j;
- for (j = 0; j < DELTAWIDTH; j++) {
- if (j > 0) {
- fprintf(outfile, ",");
- }
- if (z) {
- fprintf(outfile, "%5d", d[j]);
- } else {
- fprintf(outfile, "%5d", 0);
- }
- }
- }
-#endif /* NOLEX */
- fprintf(outfile, "}");
-}
-
-void
-makeCostArray()
-{
- int i;
-
- if (!pVector) {
- makePvector();
- }
-
- fprintf(outfile, "short %s_cost[][%d] = {\n", prefix, DELTAWIDTH);
- for (i = 0; i <= max_erule_num; i++) {
- makeCostVector(pVector[i], pVector[i] ? pVector[i]->rule->delta : 0);
- fprintf(outfile, ", /* ");
- printRule(pVector[i], "(none)");
- fprintf(outfile, " = %d */\n", i);
- }
- fprintf(outfile, "};\n");
-}
-
-void
-makeStateStringArray()
-{
- int s;
- int nt;
- int states;
-
- states = globalMap->count;
- fprintf(outfile, "\nconst char * %s_state_string[] = {\n", prefix);
- fprintf(outfile, "\" not a state\", /* state 0 */\n");
- for (s = 0; s < states-1; s++) {
- fprintf(outfile, "\t\"");
- printRepresentative(outfile, sortedStates[s]);
- fprintf(outfile, "\", /* state #%d */\n", s+1);
- }
- fprintf(outfile, "};\n");
-}
-
-void
-makeDeltaCostArray()
-{
- int s;
- int nt;
- int states;
-
- states = globalMap->count;
- fprintf(outfile, "\nshort %s_delta_cost[%d][%d][%d] = {\n", prefix, states, last_user_nonterminal, DELTAWIDTH);
- fprintf(outfile, "{{0}}, /* state 0 */\n");
- for (s = 0; s < states-1; s++) {
- fprintf(outfile, "{ /* state #%d: ", s+1);
- printRepresentative(outfile, sortedStates[s]);
- fprintf(outfile, " */\n");
- fprintf(outfile, "\t{0},\n");
- for (nt = 1; nt < last_user_nonterminal; nt++) {
- makeCostVector(1, sortedStates[s]->closed[nt].delta);
- fprintf(outfile, ", /* ");
- if (sortedStates[s]->closed[nt].rule) {
- int erulenum = sortedStates[s]->closed[nt].rule->erulenum;
- printRule(pVector[erulenum], "(none)");
- fprintf(outfile, " = %d */", erulenum);
- } else {
- fprintf(outfile, "(none) */");
- }
- fprintf(outfile, "\n");
- }
- fprintf(outfile, "},\n");
- }
- fprintf(outfile, "};\n");
-}
-
-static void
-printPatternAST_int(p) PatternAST p;
-{
- List l;
-
- if (p) {
- switch (p->sym->tag) {
- case NONTERMINAL:
- fprintf(outfile, "%5d,", -p->sym->u.nt->num);
- break;
- case OPERATOR:
- fprintf(outfile, "%5d,", p->sym->u.op->num);
- break;
- default:
- assert(0);
- }
- if (p->children) {
- for (l = p->children; l; l = l->next) {
- PatternAST pat = (PatternAST) l->x;
- printPatternAST_int(pat);
- }
- }
- }
-}
-
-static void
-printPatternAST(p) PatternAST p;
-{
- List l;
-
- if (p) {
- fprintf(outfile, "%s", p->op);
- if (p->children) {
- fprintf(outfile, "(");
- for (l = p->children; l; l = l->next) {
- PatternAST pat = (PatternAST) l->x;
- if (l != p->children) {
- fprintf(outfile, ", ");
- }
- printPatternAST(pat);
- }
- fprintf(outfile, ")");
- }
- }
-}
-
-static void
-layoutNts(ast) PatternAST ast;
-{
- char out[30];
-
- switch (ast->sym->tag) {
- default:
- assert(0);
- break;
- case NONTERMINAL:
- sprintf(out, "%d, ", ast->sym->u.nt->num);
- strcat(cumBuf, out);
- return;
- case OPERATOR:
- switch (ast->sym->u.op->arity) {
- default:
- assert(0);
- break;
- case 0:
- return;
- case 1:
- layoutNts((PatternAST) ast->children->x);
- return;
- case 2:
- layoutNts((PatternAST) ast->children->x);
- layoutNts((PatternAST) ast->children->next->x);
- return;
- }
- break;
- }
-}
-
-static void
-doVector(ast) RuleAST ast;
-{
- if (pVector[ast->rule->erulenum]) {
- fprintf(stderr, "ERROR: non-unique external rule number: (%d)\n", ast->rule->erulenum);
- exit(1);
- }
- pVector[ast->rule->erulenum] = ast;
-}
-
-static void
-makePvector()
-{
- pVector = (RuleAST*) zalloc((max_erule_num+1) * sizeof(RuleAST));
- foreachList((ListFn) doVector, ruleASTs);
-}
-
-static void
-doLayout(ast) RuleAST ast;
-{
- sprintf(cumBuf, "{ ");
- layoutNts(ast->pat);
- strcat(cumBuf, "0 }");
-}
-
-void
-makeNts()
-{
- int i;
- int new;
- StrTable nts;
-
- nts = newStrTable();
-
- if (!pVector) {
- makePvector();
- }
-
- for (i = 0; i <= max_erule_num; i++) {
- if (pVector[i]) {
- doLayout(pVector[i]);
- pVector[i]->nts = addString(nts, cumBuf, i, &new);
- if (new) {
- char ename[50];
-
- sprintf(ename, "%s_r%d_nts", prefix, i);
- pVector[i]->nts->ename = (char*) zalloc(strlen(ename)+1);
- strcpy(pVector[i]->nts->ename, ename);
- fprintf(outfile, "static short %s[] =", ename);
- fprintf(outfile, "%s;\n", cumBuf);
- }
- }
- }
-
- fprintf(outfile, "short *%s_nts[] = {\n", prefix);
- for (i = 0; i <= max_erule_num; i++) {
- if (pVector[i]) {
- fprintf(outfile, "\t%s,\n", pVector[i]->nts->ename);
- } else {
- fprintf(outfile, "\t0,\n");
- }
- }
- fprintf(outfile, "};\n");
-}
-
-static void
-printRule(RuleAST r, const char *d)
-{
- if (r) {
- fprintf(outfile, "%s: ", r->rule->lhs->name);
- printPatternAST(r->pat);
- } else {
- fprintf(outfile, "%s", d);
- }
-}
-
-void
-makeRuleDescArray()
-{
- int i;
-
- if (!pVector) {
- makePvector();
- }
-
- if (last_user_nonterminal != max_nonterminal) {
- /* not normal form */
- fprintf(outfile, "short %s_rule_descriptor_0[] = { 0, 0 };\n", prefix);
- } else {
- fprintf(outfile, "short %s_rule_descriptor_0[] = { 0, 1 };\n", prefix);
- }
- for (i = 1; i <= max_erule_num; i++) {
- if (pVector[i]) {
- Operator o;
- NonTerminal t;
-
- fprintf(outfile, "short %s_rule_descriptor_%d[] = {", prefix, i);
- fprintf(outfile, "%5d,", -pVector[i]->rule->lhs->num);
- printPatternAST_int(pVector[i]->pat);
- fprintf(outfile, " };\n");
- }
- }
-
- fprintf(outfile, "/* %s_rule_descriptors[0][1] = 1 iff grammar is normal form. */\n", prefix);
- fprintf(outfile, "short * %s_rule_descriptors[] = {\n", prefix);
- fprintf(outfile, "\t%s_rule_descriptor_0,\n", prefix);
- for (i = 1; i <= max_erule_num; i++) {
- if (pVector[i]) {
- fprintf(outfile, "\t%s_rule_descriptor_%d,\n", prefix, i);
- } else {
- fprintf(outfile, "\t%s_rule_descriptor_0,\n", prefix);
- }
- }
- fprintf(outfile, "};\n");
-}
-
-
-void
-makeRuleDescArray2()
-{
- int i;
-
- if (!pVector) {
- makePvector();
- }
-
- fprintf(outfile, "struct { int lhs, op, left, right; } %s_rule_struct[] = {\n", prefix);
- if (last_user_nonterminal != max_nonterminal) {
- /* not normal form */
- fprintf(outfile, "\t{-1},");
- } else {
- fprintf(outfile, "\t{0},");
- }
- fprintf(outfile, " /* 0 if normal form, -1 if not normal form */\n");
- for (i = 1; i <= max_erule_num; i++) {
- fprintf(outfile, "\t");
- if (pVector[i]) {
- Operator o;
- NonTerminal t1, t2;
-
- fprintf(outfile, "{");
- fprintf(outfile, "%5d, %5d, %5d, %5d",
- pVector[i]->rule->lhs->num,
- (o = pVector[i]->rule->pat->op) ? o->num : 0,
- (t1 = pVector[i]->rule->pat->children[0]) ? t1->num : 0,
- (t2 = pVector[i]->rule->pat->children[1]) ? t2->num : 0
- );
- fprintf(outfile, "} /* ");
- printRule(pVector[i], "0");
- fprintf(outfile, " = %d */", i);
- } else {
- fprintf(outfile, "{0}");
- }
- fprintf(outfile, ",\n");
- }
- fprintf(outfile, "};\n");
-}
-
-void
-makeStringArray()
-{
- int i;
-
- if (!pVector) {
- makePvector();
- }
-
- fprintf(outfile, "const char *%s_string[] = {\n", prefix);
- for (i = 0; i <= max_erule_num; i++) {
- fprintf(outfile, "\t");
- if (pVector[i]) {
- fprintf(outfile, "\"");
- printRule(pVector[i], "0");
- fprintf(outfile, "\"");
- } else {
- fprintf(outfile, "0");
- }
- fprintf(outfile, ",\n");
- }
- fprintf(outfile, "};\n");
- fprintf(outfile, "int %s_max_rule = %d;\n", prefix, max_erule_num);
- fprintf(outfile, "#define %s_Max_rule %d\n", prefix, max_erule_num);
-}
-
-void
-makeRule()
-{
- fprintf(outfile, "int %s_rule(int state, int goalnt) {\n", prefix);
- fprintf(outfile,
- "\t%s_assert(state >= 0 && state < %d, PANIC(\"Bad state %%d passed to %s_rule\\n\", state));\n",
- prefix, globalMap->count, prefix);
- fprintf(outfile,
- "\t%s_assert(goalnt >= 1 && goalnt < %d, PANIC(\"Bad goalnt %%d passed to %s_rule\\n\", state));\n",
- prefix, max_nonterminal, prefix);
- fprintf(outfile, "\treturn %s_RuleNo[state][goalnt-1];\n", prefix);
- fprintf(outfile, "};\n");
-}
-
-static StrTable kids;
-
-static void
-doKids(ast) RuleAST ast;
-{
- int new;
-
- vecIndex = 0;
- cumBuf[0] = 0;
- strcpy(vecBuf, "p");
- setVectors(ast->pat);
-
- ast->kids = addString(kids, cumBuf, ast->rule->erulenum, &new);
-
-}
-
-void
-makeKids()
-{
- List e;
- IntList r;
-
- kids = newStrTable();
-
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "%s_NODEPTR_TYPE * %s_kids(%s_NODEPTR_TYPE p, int rulenumber, %s_NODEPTR_TYPE *kids) {\n", prefix, prefix, prefix, prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "%s_NODEPTR_TYPE * %s_kids(p, rulenumber, kids) %s_NODEPTR_TYPE p; int rulenumber; %s_NODEPTR_TYPE *kids; {\n", prefix, prefix, prefix, prefix);
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile,
- "\t%s_assert(p, %s_PANIC(\"NULL node pointer passed to %s_kids\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile,
- "\t%s_assert(kids, %s_PANIC(\"NULL kids pointer passed to %s_kids\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile, "\tswitch (rulenumber) {\n");
- fprintf(outfile, "\tdefault:\n");
- fprintf(outfile, "\t\t%s_PANIC(\"Unknown Rule %%d in %s_kids;\\n\", rulenumber);\n", prefix, prefix);
- fprintf(outfile, "\t\tabort();\n");
- fprintf(outfile, "\t\t/* NOTREACHED */\n");
-
- foreachList((ListFn) doKids, ruleASTs);
-
- for (e = kids->elems; e; e = e->next) {
- StrTableElement el = (StrTableElement) e->x;
- for (r = el->erulenos; r; r = r->next) {
- int i = r->x;
- fprintf(outfile, "\tcase %d:\n", i);
- }
- fprintf(outfile, "%s", el->str);
- fprintf(outfile, "\t\tbreak;\n");
- }
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "\treturn kids;\n");
- fprintf(outfile, "}\n");
-}
-
-void
-makeOpLabel()
-{
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "int %s_op_label(%s_NODEPTR_TYPE p) {\n", prefix, prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_op_label(p) %s_NODEPTR_TYPE p; {\n", prefix, prefix);
- fprintf(outfile, "#endif\n");
- fprintf(outfile,
- "\t%s_assert(p, %s_PANIC(\"NULL pointer passed to %s_op_label\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile, "\treturn %s_OP_LABEL(p);\n", prefix);
- fprintf(outfile, "}\n");
-}
-
-void
-makeStateLabel()
-{
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "int %s_state_label(%s_NODEPTR_TYPE p) {\n", prefix, prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_state_label(p) %s_NODEPTR_TYPE p; {\n", prefix, prefix);
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile,
- "\t%s_assert(p, %s_PANIC(\"NULL pointer passed to %s_state_label\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile, "\treturn %s_STATE_LABEL(p);\n", prefix);
- fprintf(outfile, "}\n");
-}
-
-void
-makeChild()
-{
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "%s_NODEPTR_TYPE %s_child(%s_NODEPTR_TYPE p, int index) {\n", prefix, prefix, prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "%s_NODEPTR_TYPE %s_child(p, index) %s_NODEPTR_TYPE p; int index; {\n", prefix, prefix, prefix);
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile,
- "\t%s_assert(p, %s_PANIC(\"NULL pointer passed to %s_child\\n\"));\n",
- prefix, prefix, prefix);
- fprintf(outfile, "\tswitch (index) {\n");
- fprintf(outfile, "\tcase 0:\n");
- fprintf(outfile, "\t\treturn %s_LEFT_CHILD(p);\n", prefix);
- fprintf(outfile, "\tcase 1:\n");
- fprintf(outfile, "\t\treturn %s_RIGHT_CHILD(p);\n", prefix);
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "\t%s_PANIC(\"Bad index %%d in %s_child;\\n\", index);\n", prefix, prefix);
- fprintf(outfile, "\tabort();\n");
- fprintf(outfile, "\treturn 0;\n");
- fprintf(outfile, "}\n");
-}
-
-static Operator *opVector;
-static int maxOperator;
-
-void
-makeOperatorVector()
-{
- List l;
-
- maxOperator = 0;
- for (l = operators; l; l = l->next) {
- Operator op = (Operator) l->x;
- if (op->num > maxOperator) {
- maxOperator = op->num;
- }
- }
- opVector = (Operator*) zalloc((maxOperator+1) * sizeof(*opVector));
- for (l = operators; l; l = l->next) {
- Operator op = (Operator) l->x;
- if (opVector[op->num]) {
- fprintf(stderr, "ERROR: Non-unique external symbol number (%d)\n", op->num);
- exit(1);
- }
- opVector[op->num] = op;
- }
-}
-
-void
-makeOperators()
-{
- int i;
-
- if (!opVector) {
- makeOperatorVector();
- }
- fprintf(outfile, "const char * %s_opname[] = {\n", prefix);
- for (i = 0; i <= maxOperator; i++) {
- if (i > 0) {
- fprintf(outfile, ", /* %d */\n", i-1);
- }
- if (opVector[i]) {
- fprintf(outfile, "\t\"%s\"", opVector[i]->name);
- } else {
- fprintf(outfile, "\t0");
- }
- }
- fprintf(outfile, "\n};\n");
- fprintf(outfile, "char %s_arity[] = {\n", prefix);
- for (i = 0; i <= maxOperator; i++) {
- if (i > 0) {
- fprintf(outfile, ", /* %d */\n", i-1);
- }
- fprintf(outfile, "\t%d", opVector[i] ? opVector[i]->arity : -1);
- }
- fprintf(outfile, "\n};\n");
- fprintf(outfile, "int %s_max_op = %d;\n", prefix, maxOperator);
- fprintf(outfile, "int %s_max_state = %d;\n", prefix, globalMap->count-1);
- fprintf(outfile, "#define %s_Max_state %d\n", prefix, globalMap->count-1);
-}
-
-void
-makeDebug()
-{
- fprintf(outfile, "#ifdef DEBUG\n");
- fprintf(outfile, "int %s_debug;\n", prefix);
- fprintf(outfile, "#endif /* DEBUG */\n");
-}
-
-void
-makeSimple()
-{
- makeRuleTable();
- makeTables();
- makeRule();
- makeState();
-}
-
-void
-startOptional()
-{
- fprintf(outfile, "#ifdef %s_STATE_LABEL\n", prefix);
- fprintf(outfile, "#define %s_INCLUDE_EXTRA\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "#ifdef STATE_LABEL\n");
- fprintf(outfile, "#define %s_INCLUDE_EXTRA\n", prefix);
- fprintf(outfile, "#define %s_STATE_LABEL \tSTATE_LABEL\n", prefix);
- fprintf(outfile, "#define %s_NODEPTR_TYPE\tNODEPTR_TYPE\n", prefix);
- fprintf(outfile, "#define %s_LEFT_CHILD \tLEFT_CHILD\n", prefix);
- fprintf(outfile, "#define %s_OP_LABEL \tOP_LABEL\n", prefix);
- fprintf(outfile, "#define %s_RIGHT_CHILD \tRIGHT_CHILD\n", prefix);
- fprintf(outfile, "#endif /* STATE_LABEL */\n");
- fprintf(outfile, "#endif /* %s_STATE_LABEL */\n\n", prefix);
-
- fprintf(outfile, "#ifdef %s_INCLUDE_EXTRA\n\n", prefix);
-
-}
-
-void
-makeNonterminals()
-{
- List l;
-
- for (l = nonterminals; l; l = l->next) {
- NonTerminal nt = (NonTerminal) l->x;
- if (nt->num < last_user_nonterminal) {
- fprintf(outfile, "#define %s_%s_NT %d\n", prefix, nt->name, nt->num);
- }
- }
- fprintf(outfile, "#define %s_NT %d\n", prefix, last_user_nonterminal-1);
-}
-
-void
-makeNonterminalArray()
-{
- int i;
- List l;
- NonTerminal *nta;
-
- nta = (NonTerminal *) zalloc(sizeof(*nta) * last_user_nonterminal);
-
- for (l = nonterminals; l; l = l->next) {
- NonTerminal nt = (NonTerminal) l->x;
- if (nt->num < last_user_nonterminal) {
- nta[nt->num] = nt;
- }
- }
-
- fprintf(outfile, "const char *%s_ntname[] = {\n", prefix);
- fprintf(outfile, "\t\"Error: Nonterminals are > 0\",\n");
- for (i = 1; i < last_user_nonterminal; i++) {
- fprintf(outfile, "\t\"%s\",\n", nta[i]->name);
- }
- fprintf(outfile, "\t0\n");
- fprintf(outfile, "};\n\n");
-
- zfree(nta);
-}
-
-void
-endOptional()
-{
- fprintf(outfile, "#endif /* %s_INCLUDE_EXTRA */\n", prefix);
-}
-
-void
-startBurm()
-{
- fprintf(outfile, "#ifndef %s_PANIC\n", prefix);
- fprintf(outfile, "#define %s_PANIC\tPANIC\n", prefix);
- fprintf(outfile, "#endif /* %s_PANIC */\n", prefix);
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "extern void abort(void);\n");
- fprintf(outfile, "#else\n");
- fprintf(outfile, "extern void abort();\n");
- fprintf(outfile, "#endif\n");
- fprintf(outfile, "#ifdef NDEBUG\n");
- fprintf(outfile, "#define %s_assert(x,y)\t;\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "#define %s_assert(x,y)\tif(!(x)) {y; abort();}\n", prefix);
- fprintf(outfile, "#endif\n");
-}
-
-void
-reportDiagnostics()
-{
- List l;
-
- for (l = operators; l; l = l->next) {
- Operator op = (Operator) l->x;
- if (!op->ref) {
- fprintf(stderr, "warning: Unreferenced Operator: %s\n", op->name);
- }
- }
- for (l = rules; l; l = l->next) {
- Rule r = (Rule) l->x;
- if (!r->used && r->num < max_ruleAST) {
- fprintf(stderr, "warning: Unused Rule: #%d\n", r->erulenum);
- }
- }
- if (!start->pmap) {
- fprintf(stderr, "warning: Start Nonterminal (%s) does not appear on LHS.\n", start->name);
- }
-
- fprintf(stderr, "start symbol = \"%s\"\n", start->name);
- fprintf(stderr, "# of states = %d\n", globalMap->count-1);
- fprintf(stderr, "# of nonterminals = %d\n", max_nonterminal-1);
- fprintf(stderr, "# of user nonterminals = %d\n", last_user_nonterminal-1);
- fprintf(stderr, "# of rules = %d\n", max_rule);
- fprintf(stderr, "# of user rules = %d\n", max_ruleAST);
-}
diff --git a/support/tools/Burg/burg.shar.gz b/support/tools/Burg/burg.shar.gz
deleted file mode 100644
index 173bbfde9f..0000000000
--- a/support/tools/Burg/burg.shar.gz
+++ /dev/null
Binary files differ
diff --git a/support/tools/Burg/burs.c b/support/tools/Burg/burs.c
deleted file mode 100644
index b4f8b83d00..0000000000
--- a/support/tools/Burg/burs.c
+++ /dev/null
@@ -1,71 +0,0 @@
-char rcsid_burs[] = "$Id$";
-
-#include "b.h"
-
-Item_Set errorState;
-
-static void doLeaf ARGS((Operator));
-
-static void
-doLeaf(leaf) Operator leaf;
-{
- int new;
- List pl;
- Item_Set ts;
- Item_Set tmp;
-
- assert(leaf->arity == 0);
-
- ts = newItem_Set(leaf->table->relevant);
-
- for (pl = rules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- if (p->pat->op == leaf) {
- if (!ts->virgin[p->lhs->num].rule || p->delta < ts->virgin[p->lhs->num].delta) {
- ts->virgin[p->lhs->num].rule = p;
- ASSIGNCOST(ts->virgin[p->lhs->num].delta, p->delta);
- ts->op = leaf;
- }
- }
- }
- trim(ts);
- zero(ts);
- tmp = encode(globalMap, ts, &new);
- if (new) {
- closure(ts);
- leaf->table->transition[0] = ts;
- addQ(globalQ, ts);
- } else {
- leaf->table->transition[0] = tmp;
- freeItem_Set(ts);
- }
-}
-
-void
-build()
-{
- int new;
- List ol;
- Item_Set ts;
-
- globalQ = newQ();
- globalMap = newMapping(GLOBAL_MAP_SIZE);
-
- ts = newItem_Set(0);
- errorState = encode(globalMap, ts, &new);
- ts->closed = ts->virgin;
- addQ(globalQ, ts);
-
- foreachList((ListFn) doLeaf, leaves);
-
- debug(debugTables, printf("---initial set of states ---\n"));
- debug(debugTables, dumpMapping(globalMap));
- debug(debugTables, foreachList((ListFn) dumpItem_Set, globalQ->head));
-
- for (ts = popQ(globalQ); ts; ts = popQ(globalQ)) {
- for (ol = operators; ol; ol = ol->next) {
- Operator op = (Operator) ol->x;
- addToTable(op->table, ts);
- }
- }
-}
diff --git a/support/tools/Burg/closure.c b/support/tools/Burg/closure.c
deleted file mode 100644
index 70e16264eb..0000000000
--- a/support/tools/Burg/closure.c
+++ /dev/null
@@ -1,95 +0,0 @@
-char rcsid_closure[] = "$Id$";
-
-#include <stdio.h>
-#include "b.h"
-
-int prevent_divergence = 0;
-
-List chainrules;
-
-void
-findChainRules()
-{
- List pl;
-
- assert(!chainrules);
-
- for (pl = rules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- if (!p->pat->op) {
- chainrules = newList(p, chainrules);
- } else {
- p->pat->op->table->rules = newList(p, p->pat->op->table->rules);
- addRelevant(p->pat->op->table->relevant, p->lhs->num);
- }
- }
-}
-
-void
-zero(t) Item_Set t;
-{
- int i;
- DeltaCost base;
- int exists;
- int base_nt;
-
- assert(!t->closed);
-
- ZEROCOST(base);
- exists = 0;
- for (i = 0; i < max_nonterminal; i++) {
- if (t->virgin[i].rule) {
- if (exists) {
- if (LESSCOST(t->virgin[i].delta, base)) {
- ASSIGNCOST(base, t->virgin[i].delta);
- base_nt = i;
- }
- } else {
- ASSIGNCOST(base, t->virgin[i].delta);
- exists = 1;
- base_nt = i;
- }
- }
- }
- if (!exists) {
- return;
- }
- for (i = 0; i < max_nonterminal; i++) {
- if (t->virgin[i].rule) {
- MINUSCOST(t->virgin[i].delta, base);
- }
- NODIVERGE(t->virgin[i].delta, t, i, base_nt);
- }
-}
-
-void
-closure(t) Item_Set t;
-{
- int changes;
- List pl;
-
- assert(!t->closed);
- t->closed = itemArrayCopy(t->virgin);
-
- changes = 1;
- while (changes) {
- changes = 0;
- for (pl = chainrules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- register Item *rhs_item = &t->closed[p->pat->children[0]->num];
-
- if (rhs_item->rule) { /* rhs is active */
- DeltaCost dc;
- register Item *lhs_item = &t->closed[p->lhs->num];
-
- ASSIGNCOST(dc, rhs_item->delta);
- ADDCOST(dc, p->delta);
- if (LESSCOST(dc, lhs_item->delta) || !lhs_item->rule) {
- ASSIGNCOST(lhs_item->delta, dc);
- lhs_item->rule = p;
- changes = 1;
- }
- }
- }
- }
-}
diff --git a/support/tools/Burg/delta.c b/support/tools/Burg/delta.c
deleted file mode 100644
index d79654910f..0000000000
--- a/support/tools/Burg/delta.c
+++ /dev/null
@@ -1,143 +0,0 @@
-char rcsid_delta[] = "$Id$";
-
-#include <stdio.h>
-#include "b.h"
-#include "fe.h"
-
-int principleCost = 0;
-int lexical = 0;
-
-#ifndef NOLEX
-void
-ASSIGNCOST(l, r) DeltaPtr l; DeltaPtr r;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- l[i] = r[i];
- }
- } else {
- l[0] = r[0];
- }
-}
-
-void
-ADDCOST(l, r) DeltaPtr l; DeltaPtr r;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- l[i] += r[i];
- }
- } else {
- l[0] += r[0];
- }
-}
-
-void
-MINUSCOST(l, r) DeltaPtr l; DeltaPtr r;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- l[i] -= r[i];
- }
- } else {
- l[0] -= r[0];
- }
-}
-
-void
-ZEROCOST(x) DeltaPtr x;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- x[i] = 0;
- }
- } else {
- x[0] = 0;
- }
-}
-
-int
-LESSCOST(l, r) DeltaPtr l; DeltaPtr r;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- if (l[i] < r[i]) {
- return 1;
- } else if (l[i] > r[i]) {
- return 0;
- }
- }
- return 0;
- } else {
- return l[0] < r[0];
- }
-}
-
-int
-EQUALCOST(l, r) DeltaPtr l; DeltaPtr r;
-{
- int i;
-
- if (lexical) {
- for (i = 0; i < DELTAWIDTH; i++) {
- if (l[i] != r[i]) {
- return 0;
- }
- }
- return 1;
- } else {
- return l[0] == r[0];
- }
-}
-#endif /* NOLEX */
-
-void
-CHECKDIVERGE(c, its, nt, base) DeltaPtr c; Item_Set its; int nt; int base;
-{
- int i;
-
- if (prevent_divergence <= 0) {
- return;
- }
- if (lexical) {
-#ifndef NOLEX
- for (i = 0; i < DELTAWIDTH; i++) {
- if (c[i] > prevent_divergence) {
- char ntname[100];
- char basename[100];
- nonTerminalName(ntname, nt);
- nonTerminalName(basename, base);
- fprintf(stderr, "ERROR: The grammar appears to diverge\n");
- fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, c[i]);
- fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
- fprintf(stderr, "\tOffending Tree: ");
- printRepresentative(stderr, its);
- fprintf(stderr, "\n");
- exit(1);
- }
- }
-#endif /*NOLEX*/
- } else if (PRINCIPLECOST(c) > prevent_divergence) {
- char ntname[100];
- char basename[100];
- nonTerminalName(ntname, nt);
- nonTerminalName(basename, base);
- fprintf(stderr, "ERROR: The grammar appears to diverge\n");
- fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, PRINCIPLECOST(c));
- fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
- fprintf(stderr, "\tOffending Tree: ");
- printRepresentative(stderr, its);
- fprintf(stderr, "\n");
- exit(1);
- }
-}
diff --git a/support/tools/Burg/fe.c b/support/tools/Burg/fe.c
deleted file mode 100644
index 36b373dd65..0000000000
--- a/support/tools/Burg/fe.c
+++ /dev/null
@@ -1,403 +0,0 @@
-char rcsid_fe[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-
-int grammarflag;
-
-static int arity;
-
-List ruleASTs;
-List grammarNts;
-
-static void doBinding ARGS((Binding));
-static void doDecl ARGS((Arity));
-static NonTerminal lookup ARGS((Pattern));
-static NonTerminal normalize ARGS((PatternAST, NonTerminal, Pattern *));
-static void doEnterNonTerm ARGS((RuleAST));
-static void doRule ARGS((RuleAST));
-static void doTable ARGS((Operator));
-
-static void
-doBinding(b) Binding b;
-{
- int new;
- Symbol s;
-
- s = enter(b->name, &new);
- if (!new) {
- fprintf(stderr, "Non-unique name: %s\n", b->name);
- exit(1);
- }
- s->tag = OPERATOR;
- s->u.op = newOperator(b->name, b->opnum, arity);
- if (arity == 0) {
- leaves = newList(s->u.op, leaves);
- }
-}
-
-static void
-doDecl(a) Arity a;
-{
- if (!a) {
- return;
- }
- arity = a->arity;
- foreachList((ListFn) doBinding, a->bindings);
-}
-
-
-static List xpatterns;
-static int tcount;
-
-static NonTerminal
-lookup(p) Pattern p;
-{
- char buf[10];
- char *s;
- List l;
- NonTerminal n;
- DeltaCost dummy;
-
- for (l = xpatterns; l; l = l->next) {
- Pattern x = (Pattern) l->x;
- if (x->op == p->op
- && x->children[0] == p->children[0]
- && x->children[1] == p->children[1]) {
- return x->normalizer;
- }
- }
- sprintf(buf, "n%%%d", tcount++);
- s = (char *) zalloc(strlen(buf)+1);
- strcpy(s, buf);
- n = newNonTerminal(s);
- p->normalizer = n;
- xpatterns = newList(p, xpatterns);
- ZEROCOST(dummy);
- (void) newRule(dummy, 0, n, p);
- return n;
-}
-
-static NonTerminal
-normalize(ast, nt, patt) PatternAST ast; NonTerminal nt; Pattern *patt;
-{
- Symbol s;
- int new;
- Pattern dummy;
-
- s = enter(ast->op, &new);
- ast->sym = s;
- if (new) {
- fprintf(stderr, "Illegal use of %s --- undefined symbol\n", s->name);
- exit(1);
- return 0; /* shut up compilers */
- } else if (s->tag == NONTERMINAL) {
- if (ast->children) {
- fprintf(stderr, "Illegal use of %s, a non-terminal, as a terminal\n", s->name);
- exit(1);
- }
- *patt = newPattern(0);
- (*patt)->children[0] = s->u.nt;
- return s->u.nt;
- } else {
- s->u.op->ref = 1;
- *patt = newPattern(s->u.op);
- if (s->u.op->arity == -1) {
- if (!ast->children) {
- s->u.op->arity = 0;
- leaves = newList(s->u.op, leaves);
- } else if (!ast->children->next) {
- s->u.op->arity = 1;
- } else if (!ast->children->next->next) {
- s->u.op->arity = 2;
- } else {
- fprintf(stderr, "ERROR: Too many children (max = 2) for \"%s\"\n", s->name);
- exit(1);
- }
- if (s->u.op->arity > max_arity) {
- max_arity = s->u.op->arity;
- }
- }
- switch (s->u.op->arity) {
- default:
- assert(0);
- break;
- case 0:
- if (ast->children) {
- fprintf(stderr, "ERROR: Incorrect number of children for leaf operator, \"%s\"\n", s->name);
- exit(1);
- }
- break;
- case 1:
- if (!ast->children || ast->children->next) {
- fprintf(stderr, "ERROR: Incorrect number of children for unary operator, \"%s\"\n", s->name);
- exit(1);
- }
- (*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
- break;
- case 2:
- if (!ast->children || !ast->children->next) {
- fprintf(stderr, "ERROR: Incorrect number of children for binary operator, \"%s\"\n", s->name);
- exit(1);
- }
- (*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
- (*patt)->children[1] = normalize((PatternAST) ast->children->next->x, 0, &dummy);
- break;
- }
- if (nt) {
- (*patt)->normalizer = nt;
- return nt;
- } else {
- return lookup(*patt);
- }
- }
-}
-
-static void
-doEnterNonTerm(ast) RuleAST ast;
-{
- int new;
- Symbol s;
- DeltaCost delta;
- int i;
- IntList p;
-
-
- s = enter(ast->lhs, &new);
- if (new) {
- s->u.nt = newNonTerminal(s->name);
- s->tag = NONTERMINAL;
- } else {
- if (s->tag != NONTERMINAL) {
- fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
- exit(1);
- }
- }
- ZEROCOST(delta);
- for (p = ast->cost, i = 0; p; p = p->next, i++) {
- int x = p->x;
-#ifndef NOLEX
- if (lexical) {
- if (i < DELTAWIDTH) {
- delta[i] = x;
- }
- } else
-#endif /* NOLEX */
- {
- if (i == principleCost) {
- PRINCIPLECOST(delta) = x;
- }
- }
- }
- ast->rule = newRule(delta, ast->erulenum, s->u.nt, 0);
-}
-
-static void
-doRule(ast) RuleAST ast;
-{
- Pattern pat;
-
- (void) normalize(ast->pat, ast->rule->lhs, &pat);
- ast->rule->pat = pat;
-}
-
-static void
-doTable(op) Operator op;
-{
- op->table = newTable(op);
-}
-
-void
-doSpec(decls, rules) List decls; List rules;
-{
- foreachList((ListFn) doDecl, decls);
- debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
-
- ruleASTs = rules;
- reveachList((ListFn) doEnterNonTerm, rules);
-
- last_user_nonterminal = max_nonterminal;
-
- reveachList((ListFn) doRule, rules);
- debug(debugTables, foreachList((ListFn) dumpRule, rules));
-
- foreachList((ListFn) doTable, operators);
-}
-
-void
-doStart(name) char *name;
-{
- Symbol s;
- int new;
-
- if (start) {
- yyerror1("Redeclaration of start symbol to be ");
- fprintf(stderr, "\"%s\"\n", name);
- exit(1);
- }
- s = enter(name, &new);
- if (new) {
- s->u.nt = newNonTerminal(s->name);
- s->tag = NONTERMINAL;
- } else {
- if (s->tag != NONTERMINAL) {
- fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
- exit(1);
- }
- }
-}
-
-void
-doGrammarNts()
-{
- List l;
- int new;
-
- for (l = grammarNts; l; l = l->next) {
- char *n = (char*) l->x;
- Symbol s;
-
- s = enter(n, &new);
- if (new) {
- fprintf(stderr, "ERROR: %%gram, unused non-terminal: \"%s\"\n", n);
- exit(1);
- }
- if (s->tag != NONTERMINAL) {
- fprintf(stderr, "ERROR: %%gram, Not a non-terminal: \"%s\"\n", n);
- exit(1);
- }
- l->x = s;
- }
-}
-
-void
-doGram(nts) List nts;
-{
- if (grammarNts) {
- yyerror1("Redeclaration of %%gram\n");
- exit(1);
- }
- grammarNts = nts;
-}
-
-Arity
-newArity(ar, b) int ar; List b;
-{
- Arity a = (Arity) zalloc(sizeof(struct arity));
- a->arity = ar;
- a->bindings = b;
- return a;
-}
-
-Binding
-newBinding(name, opnum) char *name; int opnum;
-{
- Binding b = (Binding) zalloc(sizeof(struct binding));
- if (opnum == 0) {
- yyerror1("ERROR: Non-positive external symbol number, ");
- fprintf(stderr, "%d", opnum);
- exit(1);
- }
- b->name = name;
- b->opnum = opnum;
- return b;
-}
-
-PatternAST
-newPatternAST(op, children) char *op; List children;
-{
- PatternAST p = (PatternAST) zalloc(sizeof(struct patternAST));
- p->op = op;
- p->children = children;
- return p;
-}
-
-int max_ruleAST;
-
-RuleAST
-newRuleAST(lhs, pat, erulenum, cost) char *lhs; PatternAST pat; int erulenum; IntList cost;
-{
- RuleAST p = (RuleAST) zalloc(sizeof(struct ruleAST));
- p->lhs = lhs;
- p->pat = pat;
- if (erulenum <= 0) {
- yyerror1("External Rulenumber ");
- fprintf(stderr, "(%d) <= 0\n", erulenum);
- exit(1);
- }
- p->erulenum = erulenum;
- p->cost = cost;
- max_ruleAST++;
- return p;
-}
-
-void
-dumpBinding(b) Binding b;
-{
- printf("%s=%d ", b->name, b->opnum);
-}
-
-void
-dumpArity(a) Arity a;
-{
- List l;
-
- printf("Arity(%d) ", a->arity);
- for (l = a->bindings; l; l = l->next) {
- Binding b = (Binding) l->x;
- dumpBinding(b);
- }
- printf("\n");
-}
-
-void
-dumpPatternAST(p) PatternAST p;
-{
- List l;
-
- printf("%s", p->op);
- if (p->children) {
- printf("(");
- for (l = p->children; l; l = l->next) {
- PatternAST past = (PatternAST) l->x;
- dumpPatternAST(past);
- if (l->next) {
- printf(", ");
- }
- }
- printf(")");
- }
-}
-
-void
-dumpRuleAST(p) RuleAST p;
-{
- printf("%s : ", p->lhs);
- dumpPatternAST(p->pat);
- printf(" = %d (%ld)\n", p->erulenum, (long) p->cost);
-}
-
-void
-dumpDecls(decls) List decls;
-{
- List l;
-
- for (l = decls; l; l = l->next) {
- Arity a = (Arity) l->x;
- dumpArity(a);
- }
-}
-
-void
-dumpRules(rules) List rules;
-{
- List l;
-
- for (l = rules; l; l = l->next) {
- RuleAST p = (RuleAST) l->x;
- dumpRuleAST(p);
- }
-}
-
diff --git a/support/tools/Burg/fe.h b/support/tools/Burg/fe.h
deleted file mode 100644
index 1c7b2fecbf..0000000000
--- a/support/tools/Burg/fe.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $Id$ */
-
-struct binding {
- char *name;
- int opnum;
-};
-typedef struct binding *Binding;
-
-struct arity {
- int arity;
- List bindings;
-};
-typedef struct arity *Arity;
-
-struct patternAST {
- struct symbol *sym;
- char *op;
- List children;
-};
-typedef struct patternAST *PatternAST;
-
-struct ruleAST {
- char *lhs;
- PatternAST pat;
- int erulenum;
- IntList cost;
- struct rule *rule;
- struct strTableElement *kids;
- struct strTableElement *nts;
-};
-typedef struct ruleAST *RuleAST;
-
-typedef enum {
- UNKNOWN,
- OPERATOR,
- NONTERMINAL
-} TagType;
-
-struct symbol {
- char *name;
- TagType tag;
- union {
- NonTerminal nt;
- Operator op;
- } u;
-};
-typedef struct symbol *Symbol;
-
-struct strTableElement {
- char *str;
- IntList erulenos;
- char *ename;
-};
-typedef struct strTableElement *StrTableElement;
-
-struct strTable {
- List elems;
-};
-typedef struct strTable *StrTable;
-
-extern void doGrammarNts ARGS((void));
-void makeRuleDescArray ARGS((void));
-void makeDeltaCostArray ARGS((void));
-void makeStateStringArray ARGS((void));
-
-extern StrTable newStrTable ARGS((void));
-extern StrTableElement addString ARGS((StrTable, char *, int, int *));
-
-extern void doSpec ARGS((List, List));
-extern Arity newArity ARGS((int, List));
-extern Binding newBinding ARGS((char *, int));
-extern PatternAST newPatternAST ARGS((char *, List));
-extern RuleAST newRuleAST ARGS((char *, PatternAST, int, IntList));
-extern Symbol enter ARGS((char *, int *));
-extern Symbol newSymbol ARGS((char *));
-
-extern void makeDebug ARGS((void));
-extern void makeSimple ARGS((void));
-extern void makePlanks ARGS((void));
-extern void makeOpLabel ARGS((void));
-extern void makeChild ARGS((void));
-extern void makeOperators ARGS((void));
-extern void makeLabel ARGS((void));
-extern void makeString ARGS((void));
-extern void makeString ARGS((void));
-extern void makeReduce ARGS((void));
-extern void makeRuleTable ARGS((void));
-extern void makeTables ARGS((void));
-extern void makeTreecost ARGS((void));
-extern void makePrint ARGS((void));
-extern void makeRule ARGS((void));
-extern void makeNts ARGS((void));
-extern void makeKids ARGS((void));
-extern void startBurm ARGS((void));
-extern void startOptional ARGS((void));
-extern void makePlankLabel ARGS((void));
-extern void makeStateLabel ARGS((void));
-extern void makeStringArray ARGS((void));
-extern void makeNonterminalArray ARGS((void));
-extern void makeCostArray ARGS((void));
-extern void makeLHSmap ARGS((void));
-extern void makeClosureArray ARGS((void));
-extern void makeOperatorVector ARGS((void));
-extern void endOptional ARGS((void));
-extern void reportDiagnostics ARGS((void));
-extern void makeNonterminals ARGS((void));
-extern int opsOfArity ARGS((int));
-
-extern void yypurge ARGS((void));
-extern void yyfinished ARGS((void));
-
-extern void printRepresentative ARGS((FILE *, Item_Set));
-
-extern void dumpRules ARGS((List));
-extern void dumpDecls ARGS((List));
-extern void dumpRuleAST ARGS((RuleAST));
-extern void dumpPatternAST ARGS((PatternAST));
-extern void dumpArity ARGS((Arity));
-extern void dumpBinding ARGS((Binding));
-extern void dumpStrTable ARGS((StrTable));
-
-extern int yylex ARGS((void));
-extern int yyparse ARGS((void));
-
-extern int max_ruleAST;
-extern List ruleASTs;
-
-extern FILE *outfile;
-extern const char *prefix;
-extern int trimflag;
-extern int speedflag;
-extern int grammarflag;
diff --git a/support/tools/Burg/gram.yc b/support/tools/Burg/gram.yc
deleted file mode 100644
index 9d2f9f4e53..0000000000
--- a/support/tools/Burg/gram.yc
+++ /dev/null
@@ -1,91 +0,0 @@
-%{
-char rcsid_gram[] = "$Id$";
-
-#include <stdio.h>
-#include "b.h"
-#include "fe.h"
-int doGram(List);
-%}
-
-%union {
- int y_int;
- char *y_string;
- Arity y_arity;
- Binding y_binding;
- PatternAST y_patternAST;
- RuleAST y_ruleAST;
- List y_list;
- IntList y_intlist;
-}
-
-%start full
-
-%term ERROR
-%term K_TERM
-%term K_GRAM
-%term K_START
-%term K_PPERCENT
-%term INT
-%term ID
-
-%token <y_string> ID
-%token <y_int> INT
-
-%type <y_arity> decl
-%type <y_binding> binding
-%type <y_intlist> cost costtail
-%type <y_ruleAST> rule
-%type <y_patternAST> pattern
-%type <y_list> decls rules bindinglist grammarlist
-%%
-
-
-full : spec
- | spec K_PPERCENT
- { yyfinished(); }
- ;
-
-spec : decls K_PPERCENT rules
- { doSpec($1, $3); }
- ;
-
-decls : /* lambda */ { $$ = 0; }
- | decls decl { $$ = newList($2, $1); }
- ;
-
-decl : K_TERM bindinglist { $$ = newArity(-1, $2); }
- | K_GRAM grammarlist { $$ = 0; doGram($2); }
- | K_START ID { $$ = 0; doStart($2); } /* kludge */
- ;
-
-grammarlist : /* lambda */ { $$ = 0; }
- | grammarlist ID { $$ = newList($2, $1); }
- ;
-
-bindinglist : /* lambda */ { $$ = 0; }
- | bindinglist binding { $$ = newList($2, $1); }
- ;
-
-binding : ID '=' INT { $$ = newBinding($1, $3); }
- ;
-
-rules : /* lambda */ { $$ = 0; }
- | rules rule { $$ = newList($2, $1); }
- ;
-
-rule : ID ':' pattern '=' INT cost ';' { $$ = newRuleAST($1, $3, $5, $6); }
- ;
-
-pattern : ID { $$ = newPatternAST($1, 0); }
- | ID '(' pattern ')' { $$ = newPatternAST($1, newList($3,0)); }
- | ID '(' pattern ',' pattern ')' { $$ = newPatternAST($1, newList($3, newList($5, 0))); }
- ;
-
-cost : /* lambda */ { $$ = 0; }
- | '(' INT costtail ')' { $$ = newIntList($2, $3); }
- ;
-
-costtail : /* lambda */ { $$ = 0; }
- | ',' INT costtail { $$ = newIntList($2, $3); }
- | INT costtail { $$ = newIntList($1, $2); }
- ;
diff --git a/support/tools/Burg/item.c b/support/tools/Burg/item.c
deleted file mode 100644
index 4a9f4a320b..0000000000
--- a/support/tools/Burg/item.c
+++ /dev/null
@@ -1,133 +0,0 @@
-char rcsid_item[] = "$Id$";
-
-#include "b.h"
-#include <stdio.h>
-#include <string.h>
-#include "fe.h"
-
-static Item_Set fptr;
-
-ItemArray
-newItemArray()
-{
- ItemArray ia;
- ia = (ItemArray) zalloc(max_nonterminal *sizeof(*ia));
- return ia;
-}
-
-ItemArray
-itemArrayCopy(src) ItemArray src;
-{
- ItemArray dst;
-
- dst = newItemArray();
- memcpy(dst, src, max_nonterminal * sizeof(*dst));
- return dst;
-}
-
-Item_Set
-newItem_Set(relevant) Relevant relevant;
-{
- Item_Set ts;
-
- if (fptr) {
- ts = fptr;
- fptr = 0;
- memset(ts->virgin, 0, max_nonterminal * sizeof(struct item));
- if (ts->closed) {
- zfree(ts->closed);
- ts->closed = 0;
- }
- ts->num = 0;
- ts->op = 0;
- } else {
- ts = (Item_Set) zalloc(sizeof(struct item_set));
- ts->virgin = newItemArray();
- }
- ts->relevant = relevant;
- return ts;
-}
-
-void
-freeItem_Set(ts) Item_Set ts;
-{
- assert(!fptr);
- fptr = ts;
-}
-
-int
-equivSet(a, b) Item_Set a; Item_Set b;
-{
- register Relevant r;
- register int nt;
- register Item *aa = a->virgin;
- register Item *ba = b->virgin;
-
- /*
- return !bcmp(a->virgin, b->virgin, max_nonterminal * sizeof(Item));
- */
-
- r = a->relevant ? a->relevant : b->relevant;
- assert(r);
-
- if (a->op && b->op && a->op != b->op) {
- return 0;
- }
- for (; (nt = *r) != 0; r++) {
- if (aa[nt].rule != ba[nt].rule || !EQUALCOST(aa[nt].delta, ba[nt].delta)) {
- return 0;
- }
- }
- return 1;
-}
-
-void
-printRepresentative(f, s) FILE *f; Item_Set s;
-{
- if (!s) {
- return;
- }
- fprintf(f, "%s", s->op->name);
- switch (s->op->arity) {
- case 1:
- fprintf(f, "(");
- printRepresentative(f, s->kids[0]);
- fprintf(f, ")");
- break;
- case 2:
- fprintf(f, "(");
- printRepresentative(f, s->kids[0]);
- fprintf(f, ", ");
- printRepresentative(f, s->kids[1]);
- fprintf(f, ")");
- break;
- }
-}
-
-void
-dumpItem(t) Item *t;
-{
- printf("[%s #%d]", t->rule->lhs->name, t->rule->num);
- dumpCost(t->delta);
-}
-
-void
-dumpItem_Set(ts) Item_Set ts;
-{
- int i;
-
- printf("Item_Set #%d: [", ts->num);
- for (i = 1; i < max_nonterminal; i++) {
- if (ts->virgin[i].rule) {
- printf(" %d", i);
- dumpCost(ts->virgin[i].delta);
- }
- }
- printf(" ]\n");
-}
-
-void
-dumpCost(dc) DeltaCost dc;
-{
- printf("(%ld)", (long) dc);
-}
diff --git a/support/tools/Burg/lex.c b/support/tools/Burg/lex.c
deleted file mode 100644
index 85eb8a738f..0000000000
--- a/support/tools/Burg/lex.c
+++ /dev/null
@@ -1,259 +0,0 @@
-char rcsid_lex[] = "$Id$";
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-#include "gram.tab.h"
-
-static char buf[BUFSIZ];
-
-static int yyline = 1;
-
-typedef int (*ReadFn) ARGS((void));
-
-static char *StrCopy ARGS((char *));
-static int code_get ARGS((void));
-static int simple_get ARGS((void));
-static void ReadCharString ARGS((ReadFn, int));
-static void ReadCodeBlock ARGS((void));
-static void ReadOldComment ARGS((ReadFn));
-
-static char *
-StrCopy(s) char *s;
-{
- char *t = (char *)zalloc(strlen(s) + 1);
- strcpy(t,s);
- return t;
-}
-
-static int
-simple_get()
-{
- int ch;
- if ((ch = getchar()) == '\n') {
- yyline++;
- }
- return ch;
-}
-
-static int
-code_get()
-{
- int ch;
- if ((ch = getchar()) == '\n') {
- yyline++;
- }
- if (ch != EOF) {
- fputc(ch, outfile);
- }
- return ch;
-}
-
-void
-yypurge()
-{
- while (code_get() != EOF) ;
-}
-
-
-static void
-ReadCharString(rdfn, which) ReadFn rdfn; int which;
-{
- int ch;
- int backslash = 0;
- int firstline = yyline;
-
- while ((ch = rdfn()) != EOF) {
- if (ch == which && !backslash) {
- return;
- }
- if (ch == '\\' && !backslash) {
- backslash = 1;
- } else {
- backslash = 0;
- }
- }
- yyerror1("Unexpected EOF in string on line ");
- fprintf(stderr, "%d\n", firstline);
- exit(1);
-}
-
-static void
-ReadOldComment(rdfn) ReadFn rdfn;
-{
- /* will not work for comments delimiter in string */
-
- int ch;
- int starred = 0;
- int firstline = yyline;
-
- while ((ch = rdfn()) != EOF) {
- if (ch == '*') {
- starred = 1;
- } else if (ch == '/' && starred) {
- return;
- } else {
- starred = 0;
- }
- }
- yyerror1("Unexpected EOF in comment on line ");
- fprintf(stderr, "%d\n", firstline);
- exit(1);
-}
-
-static void
-ReadCodeBlock()
-{
- int ch;
- int firstline = yyline;
-
- while ((ch = getchar()) != EOF) {
- if (ch == '%') {
- ch = getchar();
- if (ch != '}') {
- yyerror("bad %%");
- }
- return;
- }
- fputc(ch, outfile);
- if (ch == '\n') {
- yyline++;
- }
- if (ch == '"' || ch == '\'') {
- ReadCharString(code_get, ch);
- } else if (ch == '/') {
- ch = getchar();
- if (ch == '*') {
- fputc(ch, outfile);
- ReadOldComment(code_get);
- continue;
- } else {
- ungetc(ch, stdin);
- }
- }
- }
- yyerror1("Unclosed block of C code started on line ");
- fprintf(stderr, "%d\n", firstline);
- exit(1);
-}
-
-static int done;
-void
-yyfinished()
-{
- done = 1;
-}
-
-int
-yylex()
-{
- int ch;
- char *ptr = buf;
-
- if (done) return 0;
- while ((ch = getchar()) != EOF) {
- switch (ch) {
- case ' ':
- case '\f':
- case '\t':
- continue;
- case '\n':
- yyline++;
- continue;
- case '(':
- case ')':
- case ',':
- case ':':
- case ';':
- case '=':
- return(ch);
- case '/':
- ch = getchar();
- if (ch == '*') {
- ReadOldComment(simple_get);
- continue;
- } else {
- ungetc(ch, stdin);
- yyerror("illegal char /");
- continue;
- }
- case '%':
- ch = getchar();
- switch (ch) {
- case '%':
- return (K_PPERCENT);
- case '{':
- ReadCodeBlock();
- continue;
- case 's':
- case 'g':
- case 't':
- do {
- if (ptr >= &buf[BUFSIZ]) {
- yyerror("ID too long");
- return(ERROR);
- } else {
- *ptr++ = ch;
- }
- ch = getchar();
- } while (isalpha(ch) || isdigit(ch) || ch == '_');
- ungetc(ch, stdin);
- *ptr = '\0';
- if (!strcmp(buf, "term")) return K_TERM;
- if (!strcmp(buf, "start")) return K_START;
- if (!strcmp(buf, "gram")) return K_GRAM;
- yyerror("illegal character after %%");
- continue;
- default:
- yyerror("illegal character after %%");
- continue;
- }
- default:
- if (isalpha(ch) ) {
- do {
- if (ptr >= &buf[BUFSIZ]) {
- yyerror("ID too long");
- return(ERROR);
- } else {
- *ptr++ = ch;
- }
- ch = getchar();
- } while (isalpha(ch) || isdigit(ch) || ch == '_');
- ungetc(ch, stdin);
- *ptr = '\0';
- yylval.y_string = StrCopy(buf);
- return(ID);
- }
- if (isdigit(ch)) {
- int val=0;
- do {
- val *= 10;
- val += (ch - '0');
- ch = getchar();
- } while (isdigit(ch));
- ungetc(ch, stdin);
- yylval.y_int = val;
- return(INT);
- }
- yyerror1("illegal char ");
- fprintf(stderr, "(\\%03o)\n", ch);
- exit(1);
- }
- }
- return(0);
-}
-
-void yyerror1(const char *str)
-{
- fprintf(stderr, "line %d: %s", yyline, str);
-}
-
-void
-yyerror(const char *str)
-{
- yyerror1(str);
- fprintf(stderr, "\n");
- exit(1);
-}
diff --git a/support/tools/Burg/list.c b/support/tools/Burg/list.c
deleted file mode 100644
index d3eefa27d0..0000000000
--- a/support/tools/Burg/list.c
+++ /dev/null
@@ -1,75 +0,0 @@
-char rcsid_list[] = "$Id$";
-
-#include "b.h"
-
-IntList
-newIntList(x, next) int x; IntList next;
-{
- IntList l;
-
- l = (IntList) zalloc(sizeof(*l));
- assert(l);
- l->x = x;
- l->next = next;
-
- return l;
-}
-
-List
-newList(x, next) void *x; List next;
-{
- List l;
-
- l = (List) zalloc(sizeof(*l));
- assert(l);
- l->x = x;
- l->next = next;
-
- return l;
-}
-
-List
-appendList(x, l) void *x; List l;
-{
- List last;
- List p;
-
- last = 0;
- for (p = l; p; p = p->next) {
- last = p;
- }
- if (last) {
- last->next = newList(x, 0);
- return l;
- } else {
- return newList(x, 0);
- }
-}
-
-void
-foreachList(f, l) ListFn f; List l;
-{
- for (; l; l = l->next) {
- (*f)(l->x);
- }
-}
-
-void
-reveachList(f, l) ListFn f; List l;
-{
- if (l) {
- reveachList(f, l->next);
- (*f)(l->x);
- }
-}
-
-int
-length(l) List l;
-{
- int c = 0;
-
- for(; l; l = l->next) {
- c++;
- }
- return c;
-}
diff --git a/support/tools/Burg/main.c b/support/tools/Burg/main.c
deleted file mode 100644
index dbfdbf4fac..0000000000
--- a/support/tools/Burg/main.c
+++ /dev/null
@@ -1,182 +0,0 @@
-char rcsid_main[] = "$Id$";
-
-#include <math.h>
-#include <stdio.h>
-#include "b.h"
-#include "fe.h"
-
-int debugTables = 0;
-static int simpleTables = 0;
-static int internals = 0;
-static int diagnostics = 0;
-
-static char *inFileName;
-static char *outFileName;
-
-static char version[] = "BURG, Version 1.0";
-
-extern int main ARGS((int argc, char **argv));
-
-int
-main(argc, argv) int argc; char **argv;
-{
- int i;
- extern int atoi ARGS((char *));
-
- for (i = 1; argv[i]; i++) {
- char **needStr = 0;
- int *needInt = 0;
-
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'V':
- fprintf(stderr, "%s\n", version);
- break;
- case 'p':
- needStr = (char**)&prefix;
- break;
- case 'o':
- needStr = &outFileName;
- break;
- case 'I':
- internals = 1;
- break;
- case 'T':
- simpleTables = 1;
- break;
- case '=':
-#ifdef NOLEX
- fprintf(stderr, "'%s' was not compiled to support lexicographic ordering\n", argv[0]);
-#else
- lexical = 1;
-#endif /* NOLEX */
- break;
- case 'O':
- needInt = &principleCost;
- break;
- case 'c':
- needInt = &prevent_divergence;
- break;
- case 'e':
- needInt = &exceptionTolerance;
- break;
- case 'd':
- diagnostics = 1;
- break;
- case 'S':
- speedflag = 1;
- break;
- case 't':
- trimflag = 1;
- break;
- case 'G':
- grammarflag = 1;
- break;
- default:
- fprintf(stderr, "Bad option (%s)\n", argv[i]);
- exit(1);
- }
- } else {
- if (inFileName) {
- fprintf(stderr, "Unexpected Filename (%s) after (%s)\n", argv[i], inFileName);
- exit(1);
- }
- inFileName = argv[i];
- }
- if (needInt || needStr) {
- char *v;
- char *opt = argv[i];
-
- if (argv[i][2]) {
- v = &argv[i][2];
- } else {
- v = argv[++i];
- if (!v) {
- fprintf(stderr, "Expection argument after %s\n", opt);
- exit(1);
- }
- }
- if (needInt) {
- *needInt = atoi(v);
- } else if (needStr) {
- *needStr = v;
- }
- }
- }
-
- if (inFileName) {
- if(freopen(inFileName, "r", stdin)==NULL) {
- fprintf(stderr, "Failed opening (%s)", inFileName);
- exit(1);
- }
- }
-
- if (outFileName) {
- if ((outfile = fopen(outFileName, "w")) == NULL) {
- fprintf(stderr, "Failed opening (%s)", outFileName);
- exit(1);
- }
- } else {
- outfile = stdout;
- }
-
-
- yyparse();
-
- if (!rules) {
- fprintf(stderr, "ERROR: No rules present\n");
- exit(1);
- }
-
- findChainRules();
- findAllPairs();
- doGrammarNts();
- build();
-
- debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
- debug(debugTables, printf("---final set of states ---\n"));
- debug(debugTables, dumpMapping(globalMap));
-
-
- startBurm();
- makeNts();
- if (simpleTables) {
- makeSimple();
- } else {
- makePlanks();
- }
-
- startOptional();
- makeLabel();
- makeKids();
-
- if (internals) {
- makeChild();
- makeOpLabel();
- makeStateLabel();
- }
- endOptional();
-
- makeOperatorVector();
- makeNonterminals();
- if (internals) {
- makeOperators();
- makeStringArray();
- makeRuleDescArray();
- makeCostArray();
- makeDeltaCostArray();
- makeStateStringArray();
- makeNonterminalArray();
- /*
- makeLHSmap();
- */
- }
- makeClosureArray();
-
- if (diagnostics) {
- reportDiagnostics();
- }
-
- yypurge();
- exit(0);
-}
diff --git a/support/tools/Burg/map.c b/support/tools/Burg/map.c
deleted file mode 100644
index 588b485eab..0000000000
--- a/support/tools/Burg/map.c
+++ /dev/null
@@ -1,135 +0,0 @@
-char rcsid_map[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-
-Mapping globalMap;
-
-static void growMapping ARGS((Mapping));
-static int hash ARGS((Item_Set, int));
-
-Mapping
-newMapping(size) int size;
-{
- Mapping m;
-
- m = (Mapping) zalloc(sizeof(struct mapping));
- assert(m);
-
- m->count = 0;
- m->hash = (List*) zalloc(size * sizeof(List));
- m->hash_size = size;
- m->max_size = STATES_INCR;
- m->set = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
- assert(m->set);
-
- return m;
-}
-
-static void
-growMapping(m) Mapping m;
-{
- Item_Set *tmp;
-
- m->max_size += STATES_INCR;
- tmp = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
- memcpy(tmp, m->set, m->count * sizeof(Item_Set));
- zfree(m->set);
- m->set = tmp;
-}
-
-static int
-hash(ts, mod) Item_Set ts; int mod;
-{
- register Item *p = ts->virgin;
- register int v;
- register Relevant r = ts->relevant;
- register int nt;
-
- if (!ts->op) {
- return 0;
- }
-
- v = 0;
- for (; (nt = *r) != 0; r++) {
- v ^= ((long)p[nt].rule) + (PRINCIPLECOST(p[nt].delta)<<4);
- }
- v >>= 4;
- v &= (mod-1);
- return v;
-}
-
-Item_Set
-encode(m, ts, new) Mapping m; Item_Set ts; int *new;
-{
- int h;
- List l;
-
- assert(m);
- assert(ts);
- assert(m->count <= m->max_size);
-
- if (grammarNts && errorState && m == globalMap) {
- List l;
- int found;
-
- found = 0;
- for (l = grammarNts; l; l = l->next) {
- Symbol s;
- s = (Symbol) l->x;
-
- if (ts->virgin[s->u.nt->num].rule) {
- found = 1;
- break;
- }
- }
- if (!found) {
- *new = 0;
- return errorState;
- }
- }
-
- *new = 0;
- h = hash(ts, m->hash_size);
- for (l = m->hash[h]; l; l = l->next) {
- Item_Set s = (Item_Set) l->x;
- if (ts->op == s->op && equivSet(ts, s)) {
- ts->num = s->num;
- return s;
- }
- }
- if (m->count >= m->max_size) {
- growMapping(m);
- }
- assert(m->count < m->max_size);
- m->set[m->count] = ts;
- ts->num = m->count++;
- *new = 1;
- m->hash[h] = newList(ts, m->hash[h]);
- return ts;
-}
-
-Item_Set
-decode(m, t) Mapping m; ItemSetNum t;
-{
- assert(m);
- assert(t);
- assert(m->count < m->max_size);
- assert(t < m->count);
-
- return m->set[t];
-}
-
-void
-dumpMapping(m) Mapping m;
-{
- int i;
-
- printf("BEGIN Mapping: Size=%d\n", m->count);
- for (i = 0; i < m->count; i++) {
- dumpItem_Set(m->set[i]);
- }
- printf("END Mapping\n");
-}
diff --git a/support/tools/Burg/nonterminal.c b/support/tools/Burg/nonterminal.c
deleted file mode 100644
index 71fd7d4944..0000000000
--- a/support/tools/Burg/nonterminal.c
+++ /dev/null
@@ -1,49 +0,0 @@
-char rcsid_nonterminal[] = "$Id$";
-
-#include "b.h"
-#include <stdio.h>
-#include <string.h>
-
-NonTerminal start;
-NonTerminalNum max_nonterminal = 1;
-NonTerminalNum last_user_nonterminal;
-List nonterminals;
-
-NonTerminal
-newNonTerminal(name) char *name;
-{
- NonTerminal nt;
-
- nt = (NonTerminal) zalloc(sizeof(struct nonterminal));
- assert(nt);
- if (max_nonterminal == 1) {
- start = nt;
- }
- nt->name = name;
- nt->num = max_nonterminal++;
- nonterminals = newList(nt, nonterminals);
-
- return nt;
-}
-
-int
-nonTerminalName(buf, i) char *buf; int i;
-{
- List l;
-
- for (l = nonterminals; l; l = l->next) {
- NonTerminal nt = (NonTerminal) l->x;
- if (nt->num == i) {
- strcpy(buf, nt->name);
- return 1;
- }
- }
- strcpy(buf, "(Unknown NonTerminal)");
- return 0;
-}
-
-void
-dumpNonTerminal(n) NonTerminal n;
-{
- printf("%s(%d)", n->name, n->num);
-}
diff --git a/support/tools/Burg/operator.c b/support/tools/Burg/operator.c
deleted file mode 100644
index a6df9e304d..0000000000
--- a/support/tools/Burg/operator.c
+++ /dev/null
@@ -1,48 +0,0 @@
-char rcsid_operator[] = "$Id$";
-
-#include "b.h"
-#include <stdio.h>
-
-int max_arity = -1;
-
-List operators;
-List leaves;
-
-Operator
-newOperator(name, num, arity) char *name; OperatorNum num; ArityNum arity;
-{
- Operator op;
-
- assert(arity <= MAX_ARITY);
- op = (Operator) zalloc(sizeof(struct operator));
- assert(op);
- op->name = name;
- op->num = num;
- op->arity = arity;
-
- operators = newList(op, operators);
-
- return op;
-}
-
-void
-dumpOperator_s(op) Operator op;
-{
- printf("Op: %s(%d)=%d\n", op->name, op->arity, op->num);
-}
-
-void
-dumpOperator(op, full) Operator op; int full;
-{
- dumpOperator_s(op);
- if (full) {
- dumpTable(op->table, 0);
- }
-}
-
-void
-dumpOperator_l(op) Operator op;
-{
- dumpOperator(op, 1);
-}
-
diff --git a/support/tools/Burg/pattern.c b/support/tools/Burg/pattern.c
deleted file mode 100644
index 472aca579d..0000000000
--- a/support/tools/Burg/pattern.c
+++ /dev/null
@@ -1,38 +0,0 @@
-char rcsid_pattern[] = "$Id$";
-
-#include <stdio.h>
-#include "b.h"
-
-Pattern
-newPattern(op) Operator op;
-{
- Pattern p;
-
- p = (Pattern) zalloc(sizeof(struct pattern));
- p->op = op;
- return p;
-}
-
-void
-dumpPattern(p) Pattern p;
-{
- int i;
-
- if (!p) {
- printf("[no-pattern]");
- return;
- }
-
- if (p->op) {
- printf("%s", p->op->name);
- if (p->op->arity > 0) {
- printf("(");
- for (i = 0; i < p->op->arity; i++) {
- printf("%s ", p->children[i]->name);
- }
- printf(")");
- }
- } else {
- printf("%s", p->children[0]->name);
- }
-}
diff --git a/support/tools/Burg/plank.c b/support/tools/Burg/plank.c
deleted file mode 100644
index 1ce006dd01..0000000000
--- a/support/tools/Burg/plank.c
+++ /dev/null
@@ -1,921 +0,0 @@
-char rcsid_plank[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "b.h"
-#include "fe.h"
-
-#define ERROR_VAL 0
-
-int speedflag = 0;
-
-Item_Set *sortedStates;
-static struct stateMapTable smt;
-int exceptionTolerance = 0;
-static int plankSize = 32;
-
-static Plank newPlank ARGS((void));
-static PlankMap newPlankMap ARGS((int));
-static StateMap newStateMap ARGS((void));
-static Exception newException ARGS((int, int));
-static void enterStateMap ARGS((PlankMap, short *, int, int *));
-static List assemblePlanks ARGS((void));
-static void assignRules ARGS((RuleAST));
-static int stateCompare ARGS((Item_Set *, Item_Set *));
-static int ruleCompare ARGS((RuleAST *, RuleAST *));
-static void renumber ARGS((void));
-static short * newVector ARGS((void));
-static int width ARGS((int));
-static PlankMap mapToPmap ARGS((Dimension));
-static void doDimPmaps ARGS((Operator));
-static void doNonTermPmaps ARGS((NonTerminal));
-static void makePmaps ARGS((void));
-static void outPlank ARGS((Plank));
-static void purgePlanks ARGS((List));
-static void inToEx ARGS((void));
-static void makePlankRuleMacros ARGS((void));
-static void makePlankRule ARGS((void));
-static void exceptionSwitch ARGS((List, const char *, const char *, const char *, int, const char *));
-static void doPlankLabel ARGS((Operator));
-static void doPlankLabelSafely ARGS((Operator));
-static void doPlankLabelMacrosSafely ARGS((Operator));
-static void makePlankState ARGS((void));
-
-static Plank
-newPlank()
-{
- Plank p;
- char buf[50];
- static int num = 0;
-
- p = (Plank) zalloc(sizeof(struct plank));
- sprintf(buf, "%s_plank_%d", prefix, num++);
- p->name = (char *) zalloc(strlen(buf)+1);
- strcpy(p->name, buf);
- return p;
-}
-
-static PlankMap
-newPlankMap(offset) int offset;
-{
- PlankMap im;
-
- im = (PlankMap) zalloc(sizeof(struct plankMap));
- im->offset = offset;
- return im;
-}
-
-static StateMap
-newStateMap()
-{
- char buf[50];
- static int num = 0;
-
- StateMap sm;
-
- sm = (StateMap) zalloc(sizeof(struct stateMap));
- sprintf(buf, "f%d", num++);
- sm->fieldname = (char *) zalloc(strlen(buf)+1);
- strcpy(sm->fieldname, buf);
- return sm;
-}
-
-static Exception
-newException(index, value) int index; int value;
-{
- Exception e;
-
- e = (Exception) zalloc(sizeof(struct except));
- e->index = index;
- e->value = value;
- return e;
-}
-
-static void
-enterStateMap(im, v, width, new) PlankMap im; short * v; int width; int *new;
-{
- int i;
- StateMap sm;
- List l;
- int size;
-
- assert(im);
- assert(v);
- assert(width > 0);
- size = globalMap->count;
-
- for (l = smt.maps; l; l = l->next) {
- int ecount;
-
- sm = (StateMap) l->x;
- ecount = 0;
- for (i = 0; i < size; i++) {
- if (v[i] != -1 && sm->value[i] != -1 && v[i] != sm->value[i]) {
- if (++ecount > exceptionTolerance) {
- goto again;
- }
- }
- }
- for (i = 0; i < size; i++) {
- assert(v[i] >= 0);
- assert(sm->value[i] >= 0);
- if (v[i] == -1) {
- continue;
- }
- if (sm->value[i] == -1) {
- sm->value[i] = v[i];
- } else if (v[i] != sm->value[i]) {
- im->exceptions = newList(newException(i,v[i]), im->exceptions);
- }
- }
- im->values = sm;
- if (width > sm->width) {
- sm->width = width;
- }
- *new = 0;
- return;
- again: ;
- }
- sm = newStateMap();
- im->values = sm;
- sm->value = v;
- sm->width = width;
- *new = 1;
- smt.maps = newList(sm, smt.maps);
-}
-
-static List
-assemblePlanks()
-{
- List planks = 0;
- Plank pl;
- List p;
- List s;
-
- for (s = smt.maps; s; s = s->next) {
- StateMap sm = (StateMap) s->x;
- for (p = planks; p; p = p->next) {
- pl = (Plank) p->x;
- if (sm->width <= plankSize - pl->width) {
- pl->width += sm->width;
- pl->fields = newList(sm, pl->fields);
- sm->plank = pl;
- goto next;
- }
- }
- pl = newPlank();
- pl->width = sm->width;
- pl->fields = newList(sm, 0);
- sm->plank = pl;
- planks = appendList(pl, planks);
- next: ;
- }
- return planks;
-}
-
-RuleAST *sortedRules;
-
-static int count;
-
-static void
-assignRules(ast) RuleAST ast;
-{
- sortedRules[count++] = ast;
-}
-
-static int
-stateCompare(s, t) Item_Set *s; Item_Set *t;
-{
- return strcmp((*s)->op->name, (*t)->op->name);
-}
-
-static int
-ruleCompare(s, t) RuleAST *s; RuleAST *t;
-{
- return strcmp((*s)->lhs, (*t)->lhs);
-}
-
-void
-dumpSortedStates()
-{
- int i;
-
- printf("dump Sorted States: ");
- for (i = 0; i < globalMap->count; i++) {
- printf("%d ", sortedStates[i]->num);
- }
- printf("\n");
-}
-
-void
-dumpSortedRules()
-{
- int i;
-
- printf("dump Sorted Rules: ");
- for (i = 0; i < max_ruleAST; i++) {
- printf("%d ", sortedRules[i]->rule->erulenum);
- }
- printf("\n");
-}
-
-static void
-renumber()
-{
- int i;
- Operator previousOp;
- NonTerminal previousLHS;
- int base_counter;
-
- sortedStates = (Item_Set*) zalloc(globalMap->count * sizeof(Item_Set));
- for (i = 1; i < globalMap->count; i++) {
- sortedStates[i-1] = globalMap->set[i];
- }
- qsort(sortedStates, globalMap->count-1, sizeof(Item_Set), (int(*)(const void *, const void *))stateCompare);
- previousOp = 0;
- for (i = 0; i < globalMap->count-1; i++) {
- sortedStates[i]->newNum = i;
- sortedStates[i]->op->stateCount++;
- if (previousOp != sortedStates[i]->op) {
- sortedStates[i]->op->baseNum = i;
- previousOp = sortedStates[i]->op;
- }
- }
-
- sortedRules = (RuleAST*) zalloc(max_ruleAST * sizeof(RuleAST));
- count = 0;
- foreachList((ListFn) assignRules, ruleASTs);
- qsort(sortedRules, max_ruleAST, sizeof(RuleAST), (int(*)(const void *, const void *))ruleCompare);
- previousLHS = 0;
- base_counter = 0;
- for (i = 0; i < max_ruleAST; i++) {
- if (previousLHS != sortedRules[i]->rule->lhs) {
- sortedRules[i]->rule->lhs->baseNum = base_counter;
- previousLHS = sortedRules[i]->rule->lhs;
- base_counter++; /* make space for 0 */
- }
- sortedRules[i]->rule->newNum = base_counter;
- sortedRules[i]->rule->lhs->ruleCount++;
- sortedRules[i]->rule->lhs->sampleRule = sortedRules[i]->rule; /* kludge for diagnostics */
- base_counter++;
- }
-}
-
-static short *
-newVector()
-{
- short *p;
- p = (short *) zalloc(globalMap->count* sizeof(short));
- return p;
-}
-
-static int
-width(v) int v;
-{
- int c;
-
- for (c = 0; v; v >>= 1) {
- c++;
- }
- return c;
-
-}
-
-static PlankMap
-mapToPmap(d) Dimension d;
-{
- PlankMap im;
- short *v;
- int i;
- int new;
-
- if (d->map->count == 1) {
- return 0;
- }
- assert(d->map->count > 1);
- im = newPlankMap(0);
- v = newVector();
- for (i = 0; i < globalMap->count-1; i++) {
- int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
- assert(index >= 0);
- v[i+1] = index;
- }
- v[0] = 0;
- enterStateMap(im, v, width(d->map->count), &new);
- if (!new) {
- zfree(v);
- }
- return im;
-}
-
-static void
-doDimPmaps(op) Operator op;
-{
- int i, j;
- Dimension d;
- short *v;
- PlankMap im;
- int new;
-
- if (!op->table->rules) {
- return;
- }
- switch (op->arity) {
- case 0:
- break;
- case 1:
- d = op->table->dimen[0];
- if (d->map->count > 1) {
- v = newVector();
- im = newPlankMap(op->baseNum);
- for (i = 0; i < globalMap->count-1; i++) {
- int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
- if (index) {
- Item_Set *ts = transLval(op->table, index, 0);
- v[i+1] = (*ts)->newNum - op->baseNum+1;
- assert(v[i+1] >= 0);
- }
- }
- enterStateMap(im, v, width(d->map->count-1), &new);
- if (!new) {
- zfree(v);
- }
- d->pmap = im;
- }
- break;
- case 2:
- if (op->table->dimen[0]->map->count == 1 && op->table->dimen[1]->map->count == 1) {
- op->table->dimen[0]->pmap = 0;
- op->table->dimen[1]->pmap = 0;
- } else if (op->table->dimen[0]->map->count == 1) {
- v = newVector();
- im = newPlankMap(op->baseNum);
- d = op->table->dimen[1];
- for (i = 0; i < globalMap->count-1; i++) {
- int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
- if (index) {
- Item_Set *ts = transLval(op->table, 1, index);
- v[i+1] = (*ts)->newNum - op->baseNum+1;
- assert(v[i+1] >= 0);
- }
- }
- enterStateMap(im, v, width(d->map->count-1), &new);
- if (!new) {
- zfree(v);
- }
- d->pmap = im;
- } else if (op->table->dimen[1]->map->count == 1) {
- v = newVector();
- im = newPlankMap(op->baseNum);
- d = op->table->dimen[0];
- for (i = 0; i < globalMap->count-1; i++) {
- int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
- if (index) {
- Item_Set *ts = transLval(op->table, index, 1);
- v[i +1] = (*ts)->newNum - op->baseNum +1;
- assert(v[i +1] >= 0);
- }
- }
- enterStateMap(im, v, width(d->map->count-1), &new);
- if (!new) {
- zfree(v);
- }
- d->pmap = im;
- } else {
- op->table->dimen[0]->pmap = mapToPmap(op->table->dimen[0]);
- op->table->dimen[1]->pmap = mapToPmap(op->table->dimen[1]);
- /* output table */
- fprintf(outfile, "static unsigned %s %s_%s_transition[%d][%d] = {",
- op->stateCount <= 255 ? "char" : "short",
- prefix,
- op->name,
- op->table->dimen[0]->map->count,
- op->table->dimen[1]->map->count);
- for (i = 0; i < op->table->dimen[0]->map->count; i++) {
- if (i > 0) {
- fprintf(outfile, ",");
- }
- fprintf(outfile, "\n{");
- for (j = 0; j < op->table->dimen[1]->map->count; j++) {
- Item_Set *ts = transLval(op->table, i, j);
- short diff;
- if (j > 0) {
- fprintf(outfile, ",");
- if (j % 10 == 0) {
- fprintf(outfile, "\t/* row %d, cols %d-%d*/\n",
- i,
- j-10,
- j-1);
- }
- }
- if ((*ts)->num > 0) {
- diff = (*ts)->newNum - op->baseNum +1;
- } else {
- diff = 0;
- }
- fprintf(outfile, "%5d", diff);
- }
- fprintf(outfile, "}\t/* row %d */", i);
- }
- fprintf(outfile, "\n};\n");
- }
- break;
- default:
- assert(0);
- }
-}
-
-static NonTerminal *ntVector;
-
-static void
-doNonTermPmaps(n) NonTerminal n;
-{
- short *v;
- PlankMap im;
- int new;
- int i;
-
- ntVector[n->num] = n;
- if (n->num >= last_user_nonterminal) {
- return;
- }
- if (n->ruleCount <= 0) {
- return;
- }
- im = newPlankMap(n->baseNum);
- v = newVector();
- for (i = 0; i < globalMap->count-1; i++) {
- Rule r = globalMap->set[sortedStates[i]->num]->closed[n->num].rule;
- if (r) {
- r->used = 1;
- v[i+1] = r->newNum - n->baseNum /*safely*/;
- assert(v[i+1] >= 0);
- }
- }
- enterStateMap(im, v, width(n->ruleCount+1), &new);
- if (!new) {
- zfree(v);
- }
- n->pmap = im;
-}
-
-static void
-makePmaps()
-{
- foreachList((ListFn) doDimPmaps, operators);
- ntVector = (NonTerminal*) zalloc((max_nonterminal) * sizeof(NonTerminal));
- foreachList((ListFn) doNonTermPmaps, nonterminals);
-}
-
-static void
-outPlank(p) Plank p;
-{
- List f;
- int i;
-
- fprintf(outfile, "static struct {\n");
-
- for (f = p->fields; f; f = f->next) {
- StateMap sm = (StateMap) f->x;
- fprintf(outfile, "\tunsigned int %s:%d;\n", sm->fieldname, sm->width);
- }
-
- fprintf(outfile, "} %s[] = {\n", p->name);
-
- for (i = 0; i < globalMap->count; i++) {
- fprintf(outfile, "\t{");
- for (f = p->fields; f; f = f->next) {
- StateMap sm = (StateMap) f->x;
- fprintf(outfile, "%4d,", sm->value[i] == -1 ? ERROR_VAL : sm->value[i]);
- }
- fprintf(outfile, "},\t/* row %d */\n", i);
- }
-
- fprintf(outfile, "};\n");
-}
-
-static void
-purgePlanks(planks) List planks;
-{
- List p;
-
- for (p = planks; p; p = p->next) {
- Plank x = (Plank) p->x;
- outPlank(x);
- }
-}
-
-static void
-inToEx()
-{
- int i;
- int counter;
-
- fprintf(outfile, "static short %s_eruleMap[] = {\n", prefix);
- counter = 0;
- for (i = 0; i < max_ruleAST; i++) {
- if (counter > 0) {
- fprintf(outfile, ",");
- if (counter % 10 == 0) {
- fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
- }
- }
- if (counter < sortedRules[i]->rule->newNum) {
- assert(counter == sortedRules[i]->rule->newNum-1);
- fprintf(outfile, "%5d", 0);
- counter++;
- if (counter > 0) {
- fprintf(outfile, ",");
- if (counter % 10 == 0) {
- fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
- }
- }
- }
- fprintf(outfile, "%5d", sortedRules[i]->rule->erulenum);
- counter++;
- }
- fprintf(outfile, "\n};\n");
-}
-
-static void
-makePlankRuleMacros()
-{
- int i;
-
- for (i = 1; i < last_user_nonterminal; i++) {
- List es;
- PlankMap im = ntVector[i]->pmap;
- fprintf(outfile, "#define %s_%s_rule(state)\t", prefix, ntVector[i]->name);
- if (im) {
- fprintf(outfile, "%s_eruleMap[", prefix);
- for (es = im->exceptions; es; es = es->next) {
- Exception e = (Exception) es->x;
- fprintf(outfile, "((state) == %d ? %d :",
- e->index, e->value);
- }
- fprintf(outfile, "%s[state].%s",
- im->values->plank->name,
- im->values->fieldname);
- for (es = im->exceptions; es; es = es->next) {
- fprintf(outfile, ")");
- }
- fprintf(outfile, " +%d]", im->offset);
-
- } else {
- /* nonterminal never appears on LHS. */
- assert(ntVector[i] == start);
- fprintf(outfile, "0");
- }
- fprintf(outfile, "\n");
- }
- fprintf(outfile, "\n");
-}
-
-static void
-makePlankRule()
-{
- int i;
-
- makePlankRuleMacros();
-
- fprintf(outfile, "#ifdef __STDC__\n");
- fprintf(outfile, "int %s_rule(int state, int goalnt) {\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_rule(state, goalnt) int state; int goalnt; {\n", prefix);
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile,
- "\t%s_assert(state >= 0 && state < %d, %s_PANIC(\"Bad state %%d passed to %s_rule\\n\", state));\n",
- prefix, globalMap->count, prefix, prefix);
- fprintf(outfile, "\tswitch(goalnt) {\n");
-
- for (i = 1; i < last_user_nonterminal; i++) {
- fprintf(outfile, "\tcase %d:\n", i);
- fprintf(outfile, "\t\treturn %s_%s_rule(state);\n", prefix, ntVector[i]->name);
- }
- fprintf(outfile, "\tdefault:\n");
- fprintf(outfile, "\t\t%s_PANIC(\"Unknown nonterminal %%d in %s_rule;\\n\", goalnt);\n", prefix, prefix);
- fprintf(outfile, "\t\tabort();\n");
- fprintf(outfile, "\t\treturn 0;\n");
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "}\n");
-}
-
-static void
-exceptionSwitch(es, sw, pre, post, offset, def) List es; const char *sw; const char *pre; const char *post; int offset; const char *def;
-{
- if (es) {
- fprintf(outfile, "\t\tswitch (%s) {\n", sw);
- for (; es; es = es->next) {
- Exception e = (Exception) es->x;
- fprintf(outfile, "\t\tcase %d: %s %d; %s\n", e->index, pre, e->value+offset, post);
- }
- if (def) {
- fprintf(outfile, "\t\tdefault: %s;\n", def);
- }
- fprintf(outfile, "\t\t}\n");
- } else {
- if (def) {
- fprintf(outfile, "\t\t%s;\n", def);
- }
- }
-}
-
-static void
-doPlankLabel(op) Operator op;
-{
- PlankMap im0;
- PlankMap im1;
- char buf[100];
-
- fprintf(outfile, "\tcase %d:\n", op->num);
- switch (op->arity) {
- case 0:
- fprintf(outfile, "\t\treturn %d;\n", op->table->transition[0]->newNum);
- break;
- case 1:
- im0 = op->table->dimen[0]->pmap;
- if (im0) {
- exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
- fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
- im0->values->plank->name, im0->values->fieldname, im0->offset);
- } else {
- Item_Set *ts = transLval(op->table, 1, 0);
- if (*ts) {
- fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
- } else {
- fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
- }
- }
- break;
- case 2:
- im0 = op->table->dimen[0]->pmap;
- im1 = op->table->dimen[1]->pmap;
- if (!im0 && !im1) {
- Item_Set *ts = transLval(op->table, 1, 1);
- if (*ts) {
- fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
- } else {
- fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
- }
- } else if (!im0) {
- exceptionSwitch(im1->exceptions, "r", "return ", "", im1->offset, 0);
- fprintf(outfile, "\t\treturn %s[r].%s + %d;\n",
- im1->values->plank->name, im1->values->fieldname, im1->offset);
- } else if (!im1) {
- exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
- fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
- im0->values->plank->name, im0->values->fieldname, im0->offset);
- } else {
- assert(im0->offset == 0);
- assert(im1->offset == 0);
- sprintf(buf, "l = %s[l].%s",
- im0->values->plank->name, im0->values->fieldname);
- exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
- sprintf(buf, "r = %s[r].%s",
- im1->values->plank->name, im1->values->fieldname);
- exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
-
- fprintf(outfile, "\t\treturn %s_%s_transition[l][r] + %d;\n",
- prefix,
- op->name,
- op->baseNum);
- }
- break;
- default:
- assert(0);
- }
-}
-
-static void
-doPlankLabelMacrosSafely(op) Operator op;
-{
- PlankMap im0;
- PlankMap im1;
-
- switch (op->arity) {
- case -1:
- fprintf(outfile, "#define %s_%s_state\t0\n", prefix, op->name);
- break;
- case 0:
- fprintf(outfile, "#define %s_%s_state", prefix, op->name);
- fprintf(outfile, "\t%d\n", op->table->transition[0]->newNum+1);
- break;
- case 1:
- fprintf(outfile, "#define %s_%s_state(l)", prefix, op->name);
- im0 = op->table->dimen[0]->pmap;
- if (im0) {
- if (im0->exceptions) {
- List es = im0->exceptions;
- assert(0);
- fprintf(outfile, "\t\tswitch (l) {\n");
- for (; es; es = es->next) {
- Exception e = (Exception) es->x;
- fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
- }
- fprintf(outfile, "\t\t}\n");
- }
- if (speedflag) {
- fprintf(outfile, "\t( %s[l].%s + %d )\n",
- im0->values->plank->name, im0->values->fieldname,
- im0->offset);
- } else {
- fprintf(outfile, "\t( (%s_TEMP = %s[l].%s) ? %s_TEMP + %d : 0 )\n",
- prefix,
- im0->values->plank->name, im0->values->fieldname,
- prefix,
- im0->offset);
- }
- } else {
- Item_Set *ts = transLval(op->table, 1, 0);
- if (*ts) {
- fprintf(outfile, "\t%d\n", (*ts)->newNum+1);
- } else {
- fprintf(outfile, "\t%d\n", 0);
- }
- }
- break;
- case 2:
- fprintf(outfile, "#define %s_%s_state(l,r)", prefix, op->name);
-
- im0 = op->table->dimen[0]->pmap;
- im1 = op->table->dimen[1]->pmap;
- if (!im0 && !im1) {
- Item_Set *ts = transLval(op->table, 1, 1);
- assert(0);
- if (*ts) {
- fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum+1);
- } else {
- fprintf(outfile, "\t\treturn %d;\n", 0);
- }
- } else if (!im0) {
- assert(0);
- if (im1->exceptions) {
- List es = im1->exceptions;
- fprintf(outfile, "\t\tswitch (r) {\n");
- for (; es; es = es->next) {
- Exception e = (Exception) es->x;
- fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im1->offset : 0);
- }
- fprintf(outfile, "\t\t}\n");
- }
- fprintf(outfile, "\t\tstate = %s[r].%s; offset = %d;\n",
- im1->values->plank->name, im1->values->fieldname, im1->offset);
- fprintf(outfile, "\t\tbreak;\n");
- } else if (!im1) {
- assert(0);
- if (im0->exceptions) {
- List es = im0->exceptions;
- fprintf(outfile, "\t\tswitch (l) {\n");
- for (; es; es = es->next) {
- Exception e = (Exception) es->x;
- fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
- }
- fprintf(outfile, "\t\t}\n");
- }
- fprintf(outfile, "\t\tstate = %s[l].%s; offset = %d;\n",
- im0->values->plank->name, im0->values->fieldname, im0->offset);
- fprintf(outfile, "\t\tbreak;\n");
- } else {
- assert(im0->offset == 0);
- assert(im1->offset == 0);
- /*
- sprintf(buf, "l = %s[l].%s",
- im0->values->plank->name, im0->values->fieldname);
- exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
- sprintf(buf, "r = %s[r].%s",
- im1->values->plank->name, im1->values->fieldname);
- exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
-
- fprintf(outfile, "\t\tstate = %s_%s_transition[l][r]; offset = %d;\n",
- prefix,
- op->name,
- op->baseNum);
- fprintf(outfile, "\t\tbreak;\n");
- */
-
- if (speedflag) {
- fprintf(outfile, "\t( %s_%s_transition[%s[l].%s][%s[r].%s] + %d)\n",
- prefix,
- op->name,
- im0->values->plank->name, im0->values->fieldname,
- im1->values->plank->name, im1->values->fieldname,
- op->baseNum);
- } else {
- fprintf(outfile, "\t( (%s_TEMP = %s_%s_transition[%s[l].%s][%s[r].%s]) ? ",
- prefix,
- prefix,
- op->name,
- im0->values->plank->name, im0->values->fieldname,
- im1->values->plank->name, im1->values->fieldname);
- fprintf(outfile, "%s_TEMP + %d : 0 )\n",
- prefix,
- op->baseNum);
- }
- }
- break;
- default:
- assert(0);
- }
-}
-static void
-doPlankLabelSafely(op) Operator op;
-{
- fprintf(outfile, "\tcase %d:\n", op->num);
- switch (op->arity) {
- case -1:
- fprintf(outfile, "\t\treturn 0;\n");
- break;
- case 0:
- fprintf(outfile, "\t\treturn %s_%s_state;\n", prefix, op->name);
- break;
- case 1:
- fprintf(outfile, "\t\treturn %s_%s_state(l);\n", prefix, op->name);
- break;
- case 2:
- fprintf(outfile, "\t\treturn %s_%s_state(l,r);\n", prefix, op->name);
- break;
- default:
- assert(0);
- }
-}
-
-static void
-makePlankState()
-{
- fprintf(outfile, "\n");
- fprintf(outfile, "int %s_TEMP;\n", prefix);
- foreachList((ListFn) doPlankLabelMacrosSafely, operators);
- fprintf(outfile, "\n");
-
- fprintf(outfile, "#ifdef __STDC__\n");
- switch (max_arity) {
- case -1:
- fprintf(stderr, "ERROR: no terminals in grammar.\n");
- exit(1);
- case 0:
- fprintf(outfile, "int %s_state(int op) {\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_state(op) int op; {\n", prefix);
- break;
- case 1:
- fprintf(outfile, "int %s_state(int op, int l) {\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_state(op, l) int op; int l; {\n", prefix);
- break;
- case 2:
- fprintf(outfile, "int %s_state(int op, int l, int r) {\n", prefix);
- fprintf(outfile, "#else\n");
- fprintf(outfile, "int %s_state(op, l, r) int op; int l; int r; {\n", prefix);
- break;
- default:
- assert(0);
- }
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile, "\tregister int %s_TEMP;\n", prefix);
-
- fprintf(outfile, "#ifndef NDEBUG\n");
-
- fprintf(outfile, "\tswitch (op) {\n");
- opsOfArity(2);
- if (max_arity >= 2) {
- fprintf(outfile,
- "\t\t%s_assert(r >= 0 && r < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", r));\n",
- prefix, globalMap->count, prefix, prefix);
- fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
- }
- opsOfArity(1);
- if (max_arity > 1) {
- fprintf(outfile,
- "\t\t%s_assert(l >= 0 && l < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", l));\n",
- prefix, globalMap->count, prefix, prefix);
- fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
- }
- opsOfArity(0);
- fprintf(outfile, "\t\tbreak;\n");
- fprintf(outfile, "\t}\n");
- fprintf(outfile, "#endif\n");
-
- fprintf(outfile, "\tswitch (op) {\n");
- fprintf(outfile,"\tdefault: %s_PANIC(\"Unknown op %%d in %s_state\\n\", op); abort(); return 0;\n",
- prefix, prefix);
- foreachList((ListFn) doPlankLabelSafely, operators);
- fprintf(outfile, "\t}\n");
-
- fprintf(outfile, "}\n");
-}
-
-void
-makePlanks()
-{
- List planks;
- renumber();
- makePmaps();
- planks = assemblePlanks();
- purgePlanks(planks);
- inToEx();
- makePlankRule();
- makePlankState();
-}
diff --git a/support/tools/Burg/queue.c b/support/tools/Burg/queue.c
deleted file mode 100644
index 76e5ea9b57..0000000000
--- a/support/tools/Burg/queue.c
+++ /dev/null
@@ -1,64 +0,0 @@
-char rcsid_queue[] = "$Id$";
-
-#include "b.h"
-#include <stdio.h>
-
-Queue globalQ;
-
-Queue
-newQ()
-{
- Queue q;
-
- q = (Queue) zalloc(sizeof(struct queue));
- assert(q);
- q->head = 0;
- q->tail = 0;
-
- return q;
-}
-
-void
-addQ(q, ts) Queue q; Item_Set ts;
-{
- List qe;
-
- assert(q);
- assert(ts);
-
- qe = newList(ts, 0);
- if (q->head) {
- assert(q->tail);
- q->tail->next = qe;
- q->tail = qe;
- } else {
- q->head = q->tail = qe;
- }
-}
-
-Item_Set
-popQ(q) Queue q;
-{
- List qe;
- Item_Set ts;
-
- assert(q);
-
- if (q->head) {
- qe = q->head;
- q->head = q->head->next;
- ts = (Item_Set) qe->x;
- zfree(qe);
- return ts;
- } else {
- return 0;
- }
-}
-
-void
-dumpQ(q) Queue q;
-{
- printf("Begin Queue\n");
- foreachList((ListFn)dumpItem_Set, q->head);
- printf("End Queue\n");
-}
diff --git a/support/tools/Burg/rule.c b/support/tools/Burg/rule.c
deleted file mode 100644
index ee5c89e893..0000000000
--- a/support/tools/Burg/rule.c
+++ /dev/null
@@ -1,49 +0,0 @@
-char rcsid_rule[] = "$Id$";
-
-#include "b.h"
-#include <stdio.h>
-
-RuleNum max_rule;
-int max_erule_num;
-
-struct rule stub_rule;
-
-List rules;
-
-Rule
-newRule(delta, erulenum, lhs, pat) DeltaPtr delta; ERuleNum erulenum; NonTerminal lhs; Pattern pat;
-{
- Rule p;
-
- p = (Rule) zalloc(sizeof(struct rule));
- assert(p);
- ASSIGNCOST(p->delta, delta);
- p->erulenum = erulenum;
- if (erulenum > max_erule_num) {
- max_erule_num = erulenum;
- }
- p->num = max_rule++;
- p->lhs = lhs;
- p->pat = pat;
-
- rules = newList(p, rules);
-
- return p;
-}
-
-void
-dumpRule(p) Rule p;
-{
- dumpNonTerminal(p->lhs);
- printf(" : ");
- dumpPattern(p->pat);
- printf(" ");
- dumpCost(p->delta);
- printf("\n");
-}
-
-void
-dumpRuleList(l) List l;
-{
- foreachList((ListFn)dumpRule, l);
-}
diff --git a/support/tools/Burg/sample.gr b/support/tools/Burg/sample.gr
deleted file mode 100644
index e1f7283b6d..0000000000
--- a/support/tools/Burg/sample.gr
+++ /dev/null
@@ -1,150 +0,0 @@
-%{
-#include <stdio.h>
-
-typedef struct node *NODEPTR_TYPE;
-
-struct node {
- int op, state_label;
- NODEPTR_TYPE left, right;
-};
-
-#define OP_LABEL(p) ((p)->op)
-#define STATE_LABEL(p) ((p)->state_label)
-#define LEFT_CHILD(p) ((p)->left)
-#define RIGHT_CHILD(p) ((p)->right)
-#define PANIC printf
-%}
-
-%start reg
-%term Assign=1 Constant=2 Fetch=3 Four=4 Mul=5 Plus=6
-%%
-con: Constant = 1 (0);
-con: Four = 2 (0);
-addr: con = 3 (0);
-addr: Plus(con,reg) = 4 (0);
-addr: Plus(con,Mul(Four,reg)) = 5 (0);
-reg: Fetch(addr) = 6 (1);
-reg: Assign(addr,reg) = 7 (1);
-
-%%
-
-#define Assign 1
-#define Constant 2
-#define Fetch 3
-#define Four 4
-#define Mul 5
-#define Plus 6
-
-#ifdef __STDC__
-#define ARGS(x) x
-#else
-#define ARGS(x) ()
-#endif
-
-NODEPTR_TYPE buildtree ARGS((int, NODEPTR_TYPE, NODEPTR_TYPE));
-void printcover ARGS((NODEPTR_TYPE, int, int));
-void printtree ARGS((NODEPTR_TYPE));
-int treecost ARGS((NODEPTR_TYPE, int, int));
-void printMatches ARGS((NODEPTR_TYPE));
-int main ARGS((void));
-
-NODEPTR_TYPE buildtree(op, left, right) int op; NODEPTR_TYPE left; NODEPTR_TYPE right; {
- NODEPTR_TYPE p;
- extern void *malloc ARGS((unsigned));
-
- p = (NODEPTR_TYPE) malloc(sizeof *p);
- p->op = op;
- p->left = left;
- p->right = right;
- return p;
-}
-
-void printcover(p, goalnt, indent) NODEPTR_TYPE p; int goalnt; int indent; {
- int eruleno = burm_rule(STATE_LABEL(p), goalnt);
- short *nts = burm_nts[eruleno];
- NODEPTR_TYPE kids[10];
- int i;
-
- if (eruleno == 0) {
- printf("no cover\n");
- return;
- }
- for (i = 0; i < indent; i++)
- printf(".");
- printf("%s\n", burm_string[eruleno]);
- burm_kids(p, eruleno, kids);
- for (i = 0; nts[i]; i++)
- printcover(kids[i], nts[i], indent+1);
-}
-
-void printtree(p) NODEPTR_TYPE p; {
- int op = burm_op_label(p);
-
- printf("%s", burm_opname[op]);
- switch (burm_arity[op]) {
- case 0:
- break;
- case 1:
- printf("(");
- printtree(burm_child(p, 0));
- printf(")");
- break;
- case 2:
- printf("(");
- printtree(burm_child(p, 0));
- printf(", ");
- printtree(burm_child(p, 1));
- printf(")");
- break;
- }
-}
-
-int treecost(p, goalnt, costindex) NODEPTR_TYPE p; int goalnt; int costindex; {
- int eruleno = burm_rule(STATE_LABEL(p), goalnt);
- int cost = burm_cost[eruleno][costindex], i;
- short *nts = burm_nts[eruleno];
- NODEPTR_TYPE kids[10];
-
- burm_kids(p, eruleno, kids);
- for (i = 0; nts[i]; i++)
- cost += treecost(kids[i], nts[i], costindex);
- return cost;
-}
-
-void printMatches(p) NODEPTR_TYPE p; {
- int nt;
- int eruleno;
-
- printf("Node 0x%lx= ", (unsigned long)p);
- printtree(p);
- printf(" matched rules:\n");
- for (nt = 1; burm_ntname[nt] != (char*)NULL; nt++)
- if ((eruleno = burm_rule(STATE_LABEL(p), nt)) != 0)
- printf("\t%s\n", burm_string[eruleno]);
-}
-
-main() {
- NODEPTR_TYPE p;
-
- p = buildtree(Assign,
- buildtree(Constant, 0, 0),
- buildtree(Fetch,
- buildtree(Plus,
- buildtree(Constant, 0, 0),
- buildtree(Mul,
- buildtree(Four, 0, 0),
- buildtree(Fetch, buildtree(Constant, 0, 0), 0)
- )
- ),
- 0
- )
- );
- printtree(p);
- printf("\n\n");
- burm_label(p);
- printcover(p, 1, 0);
- printf("\nCover cost == %d\n\n", treecost(p, 1, 0));
- printMatches(p);
- return 0;
-}
-
diff --git a/support/tools/Burg/string.c b/support/tools/Burg/string.c
deleted file mode 100644
index 9b69c3045f..0000000000
--- a/support/tools/Burg/string.c
+++ /dev/null
@@ -1,65 +0,0 @@
-char rcsid_string[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-
-static StrTableElement newStrTableElement ARGS((void));
-
-StrTable
-newStrTable()
-{
- return (StrTable) zalloc(sizeof(struct strTable));
-}
-
-static StrTableElement
-newStrTableElement()
-{
- return (StrTableElement) zalloc(sizeof(struct strTableElement));
-}
-
-void
-dumpStrTable(t) StrTable t;
-{
- List e;
- IntList r;
-
- printf("Begin StrTable\n");
- for (e = t->elems; e; e = e->next) {
- StrTableElement el = (StrTableElement) e->x;
- printf("%s: ", el->str);
- for (r = el->erulenos; r; r = r->next) {
- int i = r->x;
- printf("(%d)", i);
- }
- printf("\n");
- }
- printf("End StrTable\n");
-}
-
-StrTableElement
-addString(t, s, eruleno, new) StrTable t; char *s; int eruleno; int *new;
-{
- List l;
- StrTableElement ste;
-
- assert(t);
- for (l = t->elems; l; l = l->next) {
- StrTableElement e = (StrTableElement) l->x;
-
- assert(e);
- if (!strcmp(s, e->str)) {
- e->erulenos = newIntList(eruleno, e->erulenos);
- *new = 0;
- return e;
- }
- }
- ste = newStrTableElement();
- ste->erulenos = newIntList(eruleno, 0);
- ste->str = (char *) zalloc(strlen(s) + 1);
- strcpy(ste->str, s);
- t->elems = newList(ste, t->elems);
- *new = 1;
- return ste;
-}
diff --git a/support/tools/Burg/symtab.c b/support/tools/Burg/symtab.c
deleted file mode 100644
index 3ecab2fc5f..0000000000
--- a/support/tools/Burg/symtab.c
+++ /dev/null
@@ -1,38 +0,0 @@
-char rcsid_symtab[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-#include "fe.h"
-
-static List symtab;
-
-Symbol
-newSymbol(name) char *name;
-{
- Symbol s;
-
- s = (Symbol) zalloc(sizeof(struct symbol));
- assert(s);
- s->name = name;
- return s;
-}
-
-Symbol
-enter(name, new) char *name; int *new;
-{
- List l;
- Symbol s;
-
- *new = 0;
- for (l = symtab; l; l = l->next) {
- s = (Symbol) l->x;
- if (!strcmp(name, s->name)) {
- return s;
- }
- }
- *new = 1;
- s = newSymbol(name);
- symtab = newList(s, symtab);
- return s;
-}
diff --git a/support/tools/Burg/table.c b/support/tools/Burg/table.c
deleted file mode 100644
index 1de74f9a10..0000000000
--- a/support/tools/Burg/table.c
+++ /dev/null
@@ -1,552 +0,0 @@
-char rcsid_table[] = "$Id$";
-
-#include "b.h"
-#include <string.h>
-#include <stdio.h>
-
-static void growIndex_Map ARGS((Index_Map *));
-static Relevant newRelevant ARGS((void));
-static Dimension newDimension ARGS((Operator, int));
-static void GT_1 ARGS((Table));
-static void GT_2_0 ARGS((Table));
-static void GT_2_1 ARGS((Table));
-static void growTransition ARGS((Table, int));
-static Item_Set restrict ARGS((Dimension, Item_Set));
-static void addHP_1 ARGS((Table, Item_Set));
-static void addHP_2_0 ARGS((Table, Item_Set));
-static void addHP_2_1 ARGS((Table, Item_Set));
-static void addHyperPlane ARGS((Table, int, Item_Set));
-
-static void
-growIndex_Map(r) Index_Map *r;
-{
- Index_Map new;
-
- new.max_size = r->max_size + STATES_INCR;
- new.class = (Item_Set*) zalloc(new.max_size * sizeof(Item_Set));
- assert(new.class);
- memcpy(new.class, r->class, r->max_size * sizeof(Item_Set));
- zfree(r->class);
- *r = new;
-}
-
-static Relevant
-newRelevant()
-{
- Relevant r = (Relevant) zalloc(max_nonterminal * sizeof(*r));
- return r;
-}
-
-void
-addRelevant(r, nt) Relevant r; NonTerminalNum nt;
-{
- int i;
-
- for (i = 0; r[i]; i++) {
- if (r[i] == nt) {
- break;
- }
- }
- if (!r[i]) {
- r[i] = nt;
- }
-}
-
-static Dimension
-newDimension(op, index) Operator op; ArityNum index;
-{
- Dimension d;
- List pl;
- Relevant r;
-
- assert(op);
- assert(index >= 0 && index < op->arity);
- d = (Dimension) zalloc(sizeof(struct dimension));
- assert(d);
-
- r = d->relevant = newRelevant();
- for (pl = rules; pl; pl = pl->next) {
- Rule pr = (Rule) pl->x;
- if (pr->pat->op == op) {
- addRelevant(r, pr->pat->children[index]->num);
- }
- }
-
- d->index_map.max_size = STATES_INCR;
- d->index_map.class = (Item_Set*)
- zalloc(d->index_map.max_size * sizeof(Item_Set));
- d->map = newMapping(DIM_MAP_SIZE);
- d->max_size = TABLE_INCR;
-
- return d;
-}
-
-Table
-newTable(op) Operator op;
-{
- Table t;
- int i, size;
-
- assert(op);
-
- t = (Table) zalloc(sizeof(struct table));
- assert(t);
-
- t->op = op;
-
- for (i = 0; i < op->arity; i++) {
- t->dimen[i] = newDimension(op, i);
- }
-
- size = 1;
- for (i = 0; i < op->arity; i++) {
- size *= t->dimen[i]->max_size;
- }
- t->transition = (Item_Set*) zalloc(size * sizeof(Item_Set));
- t->relevant = newRelevant();
- assert(t->transition);
-
- return t;
-}
-
-static void
-GT_1(t) Table t;
-{
- Item_Set *ts;
- ItemSetNum oldsize = t->dimen[0]->max_size;
- ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
-
- t->dimen[0]->max_size = newsize;
-
- ts = (Item_Set*) zalloc(newsize * sizeof(Item_Set));
- assert(ts);
- memcpy(ts, t->transition, oldsize * sizeof(Item_Set));
- zfree(t->transition);
- t->transition = ts;
-}
-
-static void
-GT_2_0(t) Table t;
-{
- Item_Set *ts;
- ItemSetNum oldsize = t->dimen[0]->max_size;
- ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
- int size;
-
- t->dimen[0]->max_size = newsize;
-
- size = newsize * t->dimen[1]->max_size;
-
- ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
- assert(ts);
- memcpy(ts, t->transition, oldsize*t->dimen[1]->max_size * sizeof(Item_Set));
- zfree(t->transition);
- t->transition = ts;
-}
-
-static void
-GT_2_1(t) Table t;
-{
- Item_Set *ts;
- ItemSetNum oldsize = t->dimen[1]->max_size;
- ItemSetNum newsize = t->dimen[1]->max_size + TABLE_INCR;
- int size;
- Item_Set *from;
- Item_Set *to;
- int i1, i2;
-
- t->dimen[1]->max_size = newsize;
-
- size = newsize * t->dimen[0]->max_size;
-
- ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
- assert(ts);
-
- from = t->transition;
- to = ts;
- for (i1 = 0; i1 < t->dimen[0]->max_size; i1++) {
- for (i2 = 0; i2 < oldsize; i2++) {
- to[i2] = from[i2];
- }
- to += newsize;
- from += oldsize;
- }
- zfree(t->transition);
- t->transition = ts;
-}
-
-static void
-growTransition(t, dim) Table t; ArityNum dim;
-{
-
- assert(t);
- assert(t->op);
- assert(dim < t->op->arity);
-
- switch (t->op->arity) {
- default:
- assert(0);
- break;
- case 1:
- GT_1(t);
- return;
- case 2:
- switch (dim) {
- default:
- assert(0);
- break;
- case 0:
- GT_2_0(t);
- return;
- case 1:
- GT_2_1(t);
- return;
- }
- }
-}
-
-static Item_Set
-restrict(d, ts) Dimension d; Item_Set ts;
-{
- DeltaCost base;
- Item_Set r;
- int found;
- register Relevant r_ptr = d->relevant;
- register Item *ts_current = ts->closed;
- register Item *r_current;
- register int i;
- register int nt;
-
- ZEROCOST(base);
- found = 0;
- r = newItem_Set(d->relevant);
- r_current = r->virgin;
- for (i = 0; (nt = r_ptr[i]) != 0; i++) {
- if (ts_current[nt].rule) {
- r_current[nt].rule = &stub_rule;
- if (!found) {
- found = 1;
- ASSIGNCOST(base, ts_current[nt].delta);
- } else {
- if (LESSCOST(ts_current[nt].delta, base)) {
- ASSIGNCOST(base, ts_current[nt].delta);
- }
- }
- }
- }
-
- /* zero align */
- for (i = 0; (nt = r_ptr[i]) != 0; i++) {
- if (r_current[nt].rule) {
- ASSIGNCOST(r_current[nt].delta, ts_current[nt].delta);
- MINUSCOST(r_current[nt].delta, base);
- }
- }
- assert(!r->closed);
- r->representative = ts;
- return r;
-}
-
-static void
-addHP_1(t, ts) Table t; Item_Set ts;
-{
- List pl;
- Item_Set e;
- Item_Set tmp;
- int new;
-
- e = newItem_Set(t->relevant);
- assert(e);
- e->kids[0] = ts->representative;
- for (pl = t->rules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- if (t->op == p->pat->op && ts->virgin[p->pat->children[0]->num].rule) {
- DeltaCost dc;
- ASSIGNCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
- ADDCOST(dc, p->delta);
- if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
- e->virgin[p->lhs->num].rule = p;
- ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
- e->op = t->op;
- }
- }
- }
- trim(e);
- zero(e);
- tmp = encode(globalMap, e, &new);
- assert(ts->num < t->dimen[0]->map->max_size);
- t->transition[ts->num] = tmp;
- if (new) {
- closure(e);
- addQ(globalQ, tmp);
- } else {
- freeItem_Set(e);
- }
-}
-
-static void
-addHP_2_0(t, ts) Table t; Item_Set ts;
-{
- List pl;
- register Item_Set e;
- Item_Set tmp;
- int new;
- int i2;
-
- assert(t->dimen[1]->map->count <= t->dimen[1]->map->max_size);
- for (i2 = 0; i2 < t->dimen[1]->map->count; i2++) {
- e = newItem_Set(t->relevant);
- assert(e);
- e->kids[0] = ts->representative;
- e->kids[1] = t->dimen[1]->map->set[i2]->representative;
- for (pl = t->rules; pl; pl = pl->next) {
- register Rule p = (Rule) pl->x;
-
- if (t->op == p->pat->op
- && ts->virgin[p->pat->children[0]->num].rule
- && t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].rule){
- DeltaCost dc;
- ASSIGNCOST(dc, p->delta);
- ADDCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
- ADDCOST(dc, t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].delta);
-
- if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
- e->virgin[p->lhs->num].rule = p;
- ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
- e->op = t->op;
- }
- }
- }
- trim(e);
- zero(e);
- tmp = encode(globalMap, e, &new);
- assert(ts->num < t->dimen[0]->map->max_size);
- t->transition[ts->num * t->dimen[1]->max_size + i2] = tmp;
- if (new) {
- closure(e);
- addQ(globalQ, tmp);
- } else {
- freeItem_Set(e);
- }
- }
-}
-
-static void
-addHP_2_1(t, ts) Table t; Item_Set ts;
-{
- List pl;
- register Item_Set e;
- Item_Set tmp;
- int new;
- int i1;
-
- assert(t->dimen[0]->map->count <= t->dimen[0]->map->max_size);
- for (i1 = 0; i1 < t->dimen[0]->map->count; i1++) {
- e = newItem_Set(t->relevant);
- assert(e);
- e->kids[0] = t->dimen[0]->map->set[i1]->representative;
- e->kids[1] = ts->representative;
- for (pl = t->rules; pl; pl = pl->next) {
- register Rule p = (Rule) pl->x;
-
- if (t->op == p->pat->op
- && ts->virgin[p->pat->children[1]->num].rule
- && t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].rule){
- DeltaCost dc;
- ASSIGNCOST(dc, p->delta );
- ADDCOST(dc, ts->virgin[p->pat->children[1]->num].delta);
- ADDCOST(dc, t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].delta);
- if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
- e->virgin[p->lhs->num].rule = p;
- ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
- e->op = t->op;
- }
- }
- }
- trim(e);
- zero(e);
- tmp = encode(globalMap, e, &new);
- assert(ts->num < t->dimen[1]->map->max_size);
- t->transition[i1 * t->dimen[1]->max_size + ts->num] = tmp;
- if (new) {
- closure(e);
- addQ(globalQ, tmp);
- } else {
- freeItem_Set(e);
- }
- }
-}
-
-static void
-addHyperPlane(t, i, ts) Table t; ArityNum i; Item_Set ts;
-{
- switch (t->op->arity) {
- default:
- assert(0);
- break;
- case 1:
- addHP_1(t, ts);
- return;
- case 2:
- switch (i) {
- default:
- assert(0);
- break;
- case 0:
- addHP_2_0(t, ts);
- return;
- case 1:
- addHP_2_1(t, ts);
- return;
- }
- }
-}
-
-void
-addToTable(t, ts) Table t; Item_Set ts;
-{
- ArityNum i;
-
- assert(t);
- assert(ts);
- assert(t->op);
-
- for (i = 0; i < t->op->arity; i++) {
- Item_Set r;
- Item_Set tmp;
- int new;
-
- r = restrict(t->dimen[i], ts);
- tmp = encode(t->dimen[i]->map, r, &new);
- if (t->dimen[i]->index_map.max_size <= ts->num) {
- growIndex_Map(&t->dimen[i]->index_map);
- }
- assert(ts->num < t->dimen[i]->index_map.max_size);
- t->dimen[i]->index_map.class[ts->num] = tmp;
- if (new) {
- if (t->dimen[i]->max_size <= r->num) {
- growTransition(t, i);
- }
- addHyperPlane(t, i, r);
- } else {
- freeItem_Set(r);
- }
- }
-}
-
-Item_Set *
-transLval(t, row, col) Table t; int row; int col;
-{
- switch (t->op->arity) {
- case 0:
- assert(row == 0);
- assert(col == 0);
- return t->transition;
- case 1:
- assert(col == 0);
- return t->transition + row;
- case 2:
- return t->transition + row * t->dimen[1]->max_size + col;
- default:
- assert(0);
- }
- return 0;
-}
-
-void
-dumpRelevant(r) Relevant r;
-{
- for (; *r; r++) {
- printf("%4d", *r);
- }
-}
-
-void
-dumpIndex_Map(r) Index_Map *r;
-{
- int i;
-
- printf("BEGIN Index_Map: MaxSize (%d)\n", r->max_size);
- for (i = 0; i < globalMap->count; i++) {
- printf("\t#%d: -> %d\n", i, r->class[i]->num);
- }
- printf("END Index_Map:\n");
-}
-
-void
-dumpDimension(d) Dimension d;
-{
- printf("BEGIN Dimension:\n");
- printf("Relevant: ");
- dumpRelevant(d->relevant);
- printf("\n");
- dumpIndex_Map(&d->index_map);
- dumpMapping(d->map);
- printf("MaxSize of dimension = %d\n", d->max_size);
- printf("END Dimension\n");
-}
-
-void
-dumpTable(t, full) Table t; int full;
-{
- int i;
-
- if (!t) {
- printf("NO Table yet.\n");
- return;
- }
- printf("BEGIN Table:\n");
- if (full) {
- dumpOperator(t->op, 0);
- }
- for (i = 0; i < t->op->arity; i++) {
- printf("BEGIN dimension(%d)\n", i);
- dumpDimension(t->dimen[i]);
- printf("END dimension(%d)\n", i);
- }
- dumpTransition(t);
- printf("END Table:\n");
-}
-
-void
-dumpTransition(t) Table t;
-{
- int i,j;
-
- switch (t->op->arity) {
- case 0:
- printf("{ %d }", t->transition[0]->num);
- break;
- case 1:
- printf("{");
- for (i = 0; i < t->dimen[0]->map->count; i++) {
- if (i > 0) {
- printf(",");
- }
- printf("%5d", t->transition[i]->num);
- }
- printf("}");
- break;
- case 2:
- printf("{");
- for (i = 0; i < t->dimen[0]->map->count; i++) {
- if (i > 0) {
- printf(",");
- }
- printf("\n");
- printf("{");
- for (j = 0; j < t->dimen[1]->map->count; j++) {
- Item_Set *ts = transLval(t, i, j);
- if (j > 0) {
- printf(",");
- }
- printf("%5d", (*ts)->num);
- }
- printf("}");
- }
- printf("\n}\n");
- break;
- default:
- assert(0);
- }
-}
diff --git a/support/tools/Burg/trim.c b/support/tools/Burg/trim.c
deleted file mode 100644
index 05ee2d0f64..0000000000
--- a/support/tools/Burg/trim.c
+++ /dev/null
@@ -1,412 +0,0 @@
-char rcsid_trim[] = "$Id$";
-
-#include <stdio.h>
-#include "b.h"
-#include "fe.h"
-
-Relation *allpairs;
-
-int trimflag = 0;
-int debugTrim = 0;
-
-static void siblings ARGS((int, int));
-static void findAllNexts ARGS((void));
-static Relation *newAllPairs ARGS((void));
-
-static void
-siblings(i, j) int i; int j;
-{
- int k;
- List pl;
- DeltaCost Max;
- int foundmax;
-
- allpairs[i][j].sibComputed = 1;
-
- if (i == 1) {
- return; /* never trim start symbol */
- }
- if (i==j) {
- return;
- }
-
- ZEROCOST(Max);
- foundmax = 0;
-
- for (k = 1; k < max_nonterminal; k++) {
- DeltaCost tmp;
-
- if (k==i || k==j) {
- continue;
- }
- if (!allpairs[k][i].rule) {
- continue;
- }
- if (!allpairs[k][j].rule) {
- return;
- }
- ASSIGNCOST(tmp, allpairs[k][j].chain);
- MINUSCOST(tmp, allpairs[k][i].chain);
- if (foundmax) {
- if (LESSCOST(Max, tmp)) {
- ASSIGNCOST(Max, tmp);
- }
- } else {
- foundmax = 1;
- ASSIGNCOST(Max, tmp);
- }
- }
-
- for (pl = rules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- Operator op = p->pat->op;
- List oprule;
- DeltaCost Min;
- int foundmin;
-
- if (!op) {
- continue;
- }
- switch (op->arity) {
- case 0:
- continue;
- case 1:
- if (!allpairs[p->pat->children[0]->num ][ i].rule) {
- continue;
- }
- foundmin = 0;
- for (oprule = op->table->rules; oprule; oprule = oprule->next) {
- Rule s = (Rule) oprule->x;
- DeltaPtr Cx;
- DeltaPtr Csj;
- DeltaPtr Cpi;
- DeltaCost tmp;
-
- if (!allpairs[p->lhs->num ][ s->lhs->num].rule
- || !allpairs[s->pat->children[0]->num ][ j].rule) {
- continue;
- }
- Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
- Csj= allpairs[s->pat->children[0]->num ][ j].chain;
- Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
- ASSIGNCOST(tmp, Cx);
- ADDCOST(tmp, s->delta);
- ADDCOST(tmp, Csj);
- MINUSCOST(tmp, Cpi);
- MINUSCOST(tmp, p->delta);
- if (foundmin) {
- if (LESSCOST(tmp, Min)) {
- ASSIGNCOST(Min, tmp);
- }
- } else {
- foundmin = 1;
- ASSIGNCOST(Min, tmp);
- }
- }
- if (!foundmin) {
- return;
- }
- if (foundmax) {
- if (LESSCOST(Max, Min)) {
- ASSIGNCOST(Max, Min);
- }
- } else {
- foundmax = 1;
- ASSIGNCOST(Max, Min);
- }
- break;
- case 2:
- /* do first dimension */
- if (allpairs[p->pat->children[0]->num ][ i].rule) {
- foundmin = 0;
- for (oprule = op->table->rules; oprule; oprule = oprule->next) {
- Rule s = (Rule) oprule->x;
- DeltaPtr Cx;
- DeltaPtr Cb;
- DeltaPtr Csj;
- DeltaPtr Cpi;
- DeltaCost tmp;
-
- if (allpairs[p->lhs->num ][ s->lhs->num].rule
- && allpairs[s->pat->children[0]->num ][ j].rule
- && allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].rule) {
- Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
- Csj= allpairs[s->pat->children[0]->num ][ j].chain;
- Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
- Cb = allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].chain;
- ASSIGNCOST(tmp, Cx);
- ADDCOST(tmp, s->delta);
- ADDCOST(tmp, Csj);
- ADDCOST(tmp, Cb);
- MINUSCOST(tmp, Cpi);
- MINUSCOST(tmp, p->delta);
- if (foundmin) {
- if (LESSCOST(tmp, Min)) {
- ASSIGNCOST(Min, tmp);
- }
- } else {
- foundmin = 1;
- ASSIGNCOST(Min, tmp);
- }
- }
- }
- if (!foundmin) {
- return;
- }
- if (foundmax) {
- if (LESSCOST(Max, Min)) {
- ASSIGNCOST(Max, Min);
- }
- } else {
- foundmax = 1;
- ASSIGNCOST(Max, Min);
- }
- }
- /* do second dimension */
- if (allpairs[p->pat->children[1]->num ][ i].rule) {
- foundmin = 0;
- for (oprule = op->table->rules; oprule; oprule = oprule->next) {
- Rule s = (Rule) oprule->x;
- DeltaPtr Cx;
- DeltaPtr Cb;
- DeltaPtr Csj;
- DeltaPtr Cpi;
- DeltaCost tmp;
-
- if (allpairs[p->lhs->num ][ s->lhs->num].rule
- && allpairs[s->pat->children[1]->num ][ j].rule
- && allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].rule) {
- Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
- Csj= allpairs[s->pat->children[1]->num ][ j].chain;
- Cpi= allpairs[p->pat->children[1]->num ][ i].chain;
- Cb = allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].chain;
- ASSIGNCOST(tmp, Cx);
- ADDCOST(tmp, s->delta);
- ADDCOST(tmp, Csj);
- ADDCOST(tmp, Cb);
- MINUSCOST(tmp, Cpi);
- MINUSCOST(tmp, p->delta);
- if (foundmin) {
- if (LESSCOST(tmp, Min)) {
- ASSIGNCOST(Min, tmp);
- }
- } else {
- foundmin = 1;
- ASSIGNCOST(Min, tmp);
- }
- }
- }
- if (!foundmin) {
- return;
- }
- if (foundmax) {
- if (LESSCOST(Max, Min)) {
- ASSIGNCOST(Max, Min);
- }
- } else {
- foundmax = 1;
- ASSIGNCOST(Max, Min);
- }
- }
- break;
- default:
- assert(0);
- }
- }
- allpairs[i ][ j].sibFlag = foundmax;
- ASSIGNCOST(allpairs[i ][ j].sibling, Max);
-}
-
-static void
-findAllNexts()
-{
- int i,j;
- int last;
-
- for (i = 1; i < max_nonterminal; i++) {
- last = 0;
- for (j = 1; j < max_nonterminal; j++) {
- if (allpairs[i ][j].rule) {
- allpairs[i ][ last].nextchain = j;
- last = j;
- }
- }
- }
- /*
- for (i = 1; i < max_nonterminal; i++) {
- last = 0;
- for (j = 1; j < max_nonterminal; j++) {
- if (allpairs[i ][j].sibFlag) {
- allpairs[i ][ last].nextsibling = j;
- last = j;
- }
- }
- }
- */
-}
-
-static Relation *
-newAllPairs()
-{
- int i;
- Relation *rv;
-
- rv = (Relation*) zalloc(max_nonterminal * sizeof(Relation));
- for (i = 0; i < max_nonterminal; i++) {
- rv[i] = (Relation) zalloc(max_nonterminal * sizeof(struct relation));
- }
- return rv;
-}
-
-void
-findAllPairs()
-{
- List pl;
- int changes;
- int j;
-
- allpairs = newAllPairs();
- for (pl = chainrules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- NonTerminalNum rhs = p->pat->children[0]->num;
- NonTerminalNum lhs = p->lhs->num;
- Relation r = &allpairs[lhs ][ rhs];
-
- if (LESSCOST(p->delta, r->chain)) {
- ASSIGNCOST(r->chain, p->delta);
- r->rule = p;
- }
- }
- for (j = 1; j < max_nonterminal; j++) {
- Relation r = &allpairs[j ][ j];
- ZEROCOST(r->chain);
- r->rule = &stub_rule;
- }
- changes = 1;
- while (changes) {
- changes = 0;
- for (pl = chainrules; pl; pl = pl->next) {
- Rule p = (Rule) pl->x;
- NonTerminalNum rhs = p->pat->children[0]->num;
- NonTerminalNum lhs = p->lhs->num;
- int i;
-
- for (i = 1; i < max_nonterminal; i++) {
- Relation r = &allpairs[rhs ][ i];
- Relation s = &allpairs[lhs ][ i];
- DeltaCost dc;
- if (!r->rule) {
- continue;
- }
- ASSIGNCOST(dc, p->delta);
- ADDCOST(dc, r->chain);
- if (!s->rule || LESSCOST(dc, s->chain)) {
- s->rule = p;
- ASSIGNCOST(s->chain, dc);
- changes = 1;
- }
- }
- }
- }
- findAllNexts();
-}
-
-void
-trim(t) Item_Set t;
-{
- int m,n;
- static short *vec = 0;
- int last;
-
- assert(!t->closed);
- debug(debugTrim, printf("Begin Trim\n"));
- debug(debugTrim, dumpItem_Set(t));
-
- last = 0;
- if (!vec) {
- vec = (short*) zalloc(max_nonterminal * sizeof(*vec));
- }
- for (m = 1; m < max_nonterminal; m++) {
- if (t->virgin[m].rule) {
- vec[last++] = m;
- }
- }
- for (m = 0; m < last; m++) {
- DeltaCost tmp;
- int j;
- int i;
-
- i = vec[m];
-
- for (j = allpairs[i ][ 0].nextchain; j; j = allpairs[i ][ j].nextchain) {
-
- if (i == j) {
- continue;
- }
- if (!t->virgin[j].rule) {
- continue;
- }
- ASSIGNCOST(tmp, t->virgin[j].delta);
- ADDCOST(tmp, allpairs[i ][ j].chain);
- if (!LESSCOST(t->virgin[i].delta, tmp)) {
- t->virgin[i].rule = 0;
- ZEROCOST(t->virgin[i].delta);
- debug(debugTrim, printf("Trimmed Chain (%d,%d)\n", i,j));
- goto outer;
- }
-
- }
- if (!trimflag) {
- continue;
- }
- for (n = 0; n < last; n++) {
- j = vec[n];
- if (i == j) {
- continue;
- }
-
- if (!t->virgin[j].rule) {
- continue;
- }
-
- if (!allpairs[i][j].sibComputed) {
- siblings(i,j);
- }
- if (!allpairs[i][j].sibFlag) {
- continue;
- }
- ASSIGNCOST(tmp, t->virgin[j].delta);
- ADDCOST(tmp, allpairs[i ][ j].sibling);
- if (!LESSCOST(t->virgin[i].delta, tmp)) {
- t->virgin[i].rule = 0;
- ZEROCOST(t->virgin[i].delta);
- goto outer;
- }
- }
-
- outer: ;
- }
-
- debug(debugTrim, dumpItem_Set(t));
- debug(debugTrim, printf("End Trim\n"));
-}
-
-void
-dumpRelation(r) Relation r;
-{
- printf("{ %d %ld %d %ld }", r->rule->erulenum, (long) r->chain, r->sibFlag, (long) r->sibling);
-}
-
-void
-dumpAllPairs()
-{
- int i,j;
-
- printf("Dumping AllPairs\n");
- for (i = 1; i < max_nonterminal; i++) {
- for (j = 1; j < max_nonterminal; j++) {
- dumpRelation(&allpairs[i ][j]);
- }
- printf("\n");
- }
-}
diff --git a/support/tools/Burg/zalloc.c b/support/tools/Burg/zalloc.c
deleted file mode 100644
index 9128e4280f..0000000000
--- a/support/tools/Burg/zalloc.c
+++ /dev/null
@@ -1,35 +0,0 @@
-char rcsid_zalloc[] = "$Id$";
-
-#include <stdio.h>
-#include <string.h>
-#include "b.h"
-
-extern void exit ARGS((int));
-extern void free ARGS((void *));
-extern void *malloc ARGS((unsigned));
-
-int
-fatal(const char *name, int line)
-{
- fprintf(stderr, "assertion failed: file %s, line %d\n", name, line);
- exit(1);
- return 0;
-}
-
-void *
-zalloc(size) unsigned int size;
-{
- void *t = (void *) malloc(size);
- if (!t) {
- fprintf(stderr, "Malloc failed---PROGRAM ABORTED\n");
- exit(1);
- }
- memset(t, 0, size);
- return t;
-}
-
-void
-zfree(p) void *p;
-{
- free(p);
-}
diff --git a/support/tools/Makefile b/support/tools/Makefile
deleted file mode 100644
index 4772199c8b..0000000000
--- a/support/tools/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-LEVEL = ../..
-
-DIRS = Burg TableGen
-
-include $(LEVEL)/Makefile.common
-
diff --git a/support/tools/TableGen/CodeEmitterGen.cpp b/support/tools/TableGen/CodeEmitterGen.cpp
deleted file mode 100644
index 98976c7336..0000000000
--- a/support/tools/TableGen/CodeEmitterGen.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-//===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
-//
-// FIXME: Document.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeEmitterGen.h"
-#include "Record.h"
-#include "Support/Debug.h"
-
-void CodeEmitterGen::run(std::ostream &o) {
- std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
-
- EmitSourceFileHeader("Machine Code Emitter", o);
-
- std::string Namespace = "V9::";
- std::string ClassName = "SparcV9CodeEmitter::";
-
- //const std::string &Namespace = Inst->getValue("Namespace")->getName();
- o << "unsigned " << ClassName
- << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
- << " unsigned Value = 0;\n"
- << " DEBUG(std::cerr << MI);\n"
- << " switch (MI.getOpcode()) {\n";
- for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
- I != E; ++I) {
- Record *R = *I;
- o << " case " << Namespace << R->getName() << ": {\n"
- << " DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";
-
- BitsInit *BI = R->getValueAsBitsInit("Inst");
-
- unsigned Value = 0;
- const std::vector<RecordVal> &Vals = R->getValues();
-
- DEBUG(o << " // prefilling: ");
- // Start by filling in fixed values...
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
- if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
- Value |= B->getValue() << (e-i-1);
- DEBUG(o << B->getValue());
- } else {
- DEBUG(o << "0");
- }
- }
- DEBUG(o << "\n");
-
- DEBUG(o << " // " << *R->getValue("Inst") << "\n");
- o << " Value = " << Value << "U;\n\n";
-
- // Loop over all of the fields in the instruction determining which are the
- // operands to the instruction.
- //
- unsigned op = 0;
- std::map<std::string, unsigned> OpOrder;
- std::map<std::string, bool> OpContinuous;
- for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
- if (!Vals[i].getPrefix() && !Vals[i].getValue()->isComplete()) {
- // Is the operand continuous? If so, we can just mask and OR it in
- // instead of doing it bit-by-bit, saving a lot in runtime cost.
- const BitsInit *InstInit = BI;
- int beginBitInVar = -1, endBitInVar = -1;
- int beginBitInInst = -1, endBitInInst = -1;
- bool continuous = true;
-
- for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
- if (VarBitInit *VBI =
- dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
- TypedInit *TI = VBI->getVariable();
- if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
- // only process the current variable
- if (VI->getName() != Vals[i].getName())
- continue;
-
- if (beginBitInVar == -1)
- beginBitInVar = VBI->getBitNum();
-
- if (endBitInVar == -1)
- endBitInVar = VBI->getBitNum();
- else {
- if (endBitInVar == (int)VBI->getBitNum() + 1)
- endBitInVar = VBI->getBitNum();
- else {
- continuous = false;
- break;
- }
- }
-
- if (beginBitInInst == -1)
- beginBitInInst = bit;
- if (endBitInInst == -1)
- endBitInInst = bit;
- else {
- if (endBitInInst == bit + 1)
- endBitInInst = bit;
- else {
- continuous = false;
- break;
- }
- }
-
- // maintain same distance between bits in field and bits in
- // instruction. if the relative distances stay the same
- // throughout,
- if (beginBitInVar - (int)VBI->getBitNum() !=
- beginBitInInst - bit) {
- continuous = false;
- break;
- }
- }
- }
- }
-
- // If we have found no bit in "Inst" which comes from this field, then
- // this is not an operand!!
- if (beginBitInInst != -1) {
- o << " // op" << op << ": " << Vals[i].getName() << "\n"
- << " int64_t op" << op
- <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
- //<< " MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
- OpOrder[Vals[i].getName()] = op++;
-
- DEBUG(o << " // Var: begin = " << beginBitInVar
- << ", end = " << endBitInVar
- << "; Inst: begin = " << beginBitInInst
- << ", end = " << endBitInInst << "\n");
-
- if (continuous) {
- DEBUG(o << " // continuous: op" << OpOrder[Vals[i].getName()]
- << "\n");
-
- // Mask off the right bits
- // Low mask (ie. shift, if necessary)
- assert(endBitInVar >= 0 && "Negative shift amount in masking!");
- if (endBitInVar != 0) {
- o << " op" << OpOrder[Vals[i].getName()]
- << " >>= " << endBitInVar << ";\n";
- beginBitInVar -= endBitInVar;
- endBitInVar = 0;
- }
-
- // High mask
- o << " op" << OpOrder[Vals[i].getName()]
- << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";
-
- // Shift the value to the correct place (according to place in inst)
- assert(endBitInInst >= 0 && "Negative shift amount in inst position!");
- if (endBitInInst != 0)
- o << " op" << OpOrder[Vals[i].getName()]
- << " <<= " << endBitInInst << ";\n";
-
- // Just OR in the result
- o << " Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
- }
-
- // otherwise, will be taken care of in the loop below using this
- // value:
- OpContinuous[Vals[i].getName()] = continuous;
- }
- }
- }
-
- for (unsigned f = 0, e = Vals.size(); f != e; ++f) {
- if (Vals[f].getPrefix()) {
- BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
-
- // Scan through the field looking for bit initializers of the current
- // variable...
- for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
- if (BitInit *BI = dynamic_cast<BitInit*>(FieldInitializer->getBit(i)))
- {
- DEBUG(o << " // bit init: f: " << f << ", i: " << i << "\n");
- } else if (UnsetInit *UI =
- dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
- DEBUG(o << " // unset init: f: " << f << ", i: " << i << "\n");
- } else if (VarBitInit *VBI =
- dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
- TypedInit *TI = VBI->getVariable();
- if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
- // If the bits of the field are laid out consecutively in the
- // instruction, then instead of separately ORing in bits, just
- // mask and shift the entire field for efficiency.
- if (OpContinuous[VI->getName()]) {
- // already taken care of in the loop above, thus there is no
- // need to individually OR in the bits
-
- // for debugging, output the regular version anyway, commented
- DEBUG(o << " // Value |= getValueBit(op"
- << OpOrder[VI->getName()] << ", " << VBI->getBitNum()
- << ")" << " << " << i << ";\n");
- } else {
- o << " Value |= getValueBit(op" << OpOrder[VI->getName()]
- << ", " << VBI->getBitNum()
- << ")" << " << " << i << ";\n";
- }
- } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
- // FIXME: implement this!
- o << "FIELD INIT not implemented yet!\n";
- } else {
- o << "Error: UNIMPLEMENTED\n";
- }
- }
- }
- }
- }
-
- o << " break;\n"
- << " }\n";
- }
-
- o << " default:\n"
- << " std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
- << " abort();\n"
- << " }\n"
- << " return Value;\n"
- << "}\n";
-}
diff --git a/support/tools/TableGen/CodeEmitterGen.h b/support/tools/TableGen/CodeEmitterGen.h
deleted file mode 100644
index 4b87da5067..0000000000
--- a/support/tools/TableGen/CodeEmitterGen.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===- CodeEmitterGen.h - Code Emitter Generator ----------------*- C++ -*-===//
-//
-// FIXME: document
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CODEMITTERGEN_H
-#define CODEMITTERGEN_H
-
-#include "TableGenBackend.h"
-
-class CodeEmitterGen : public TableGenBackend {
- RecordKeeper &Records;
-public:
- CodeEmitterGen(RecordKeeper &R) : Records(R) {}
-
- // run - Output the code emitter
- void run(std::ostream &o);
-private:
- void emitMachineOpEmitter(std::ostream &o, const std::string &Namespace);
- void emitGetValueBit(std::ostream &o, const std::string &Namespace);
-};
-
-#endif
diff --git a/support/tools/TableGen/CodeGenWrappers.cpp b/support/tools/TableGen/CodeGenWrappers.cpp
deleted file mode 100644
index 61c3abc297..0000000000
--- a/support/tools/TableGen/CodeGenWrappers.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===- CodeGenWrappers.cpp - Code Generation Class Wrappers -----*- C++ -*-===//
-//
-// These classes wrap target description classes used by the various code
-// generation TableGen backends. This makes it easier to access the data and
-// provides a single place that needs to check it for validity. All of these
-// classes throw exceptions on error conditions.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenWrappers.h"
-#include "Record.h"
-
-/// getValueType - Return the MCV::ValueType that the specified TableGen record
-/// corresponds to.
-MVT::ValueType getValueType(Record *Rec) {
- return (MVT::ValueType)Rec->getValueAsInt("Value");
-}
-
-std::string getName(MVT::ValueType T) {
- switch (T) {
- case MVT::Other: return "UNKNOWN";
- case MVT::i1: return "i1";
- case MVT::i8: return "i8";
- case MVT::i16: return "i16";
- case MVT::i32: return "i32";
- case MVT::i64: return "i64";
- case MVT::i128: return "i128";
- case MVT::f32: return "f32";
- case MVT::f64: return "f64";
- case MVT::f80: return "f80";
- case MVT::f128: return "f128";
- case MVT::isVoid:return "void";
- default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
- }
-}
-
-std::string getEnumName(MVT::ValueType T) {
- switch (T) {
- case MVT::Other: return "Other";
- case MVT::i1: return "i1";
- case MVT::i8: return "i8";
- case MVT::i16: return "i16";
- case MVT::i32: return "i32";
- case MVT::i64: return "i64";
- case MVT::i128: return "i128";
- case MVT::f32: return "f32";
- case MVT::f64: return "f64";
- case MVT::f80: return "f80";
- case MVT::f128: return "f128";
- case MVT::isVoid:return "isVoid";
- default: assert(0 && "ILLEGAL VALUE TYPE!"); return "";
- }
-}
-
-
-std::ostream &operator<<(std::ostream &OS, MVT::ValueType T) {
- return OS << getName(T);
-}
-
-
-
-/// getTarget - Return the current instance of the Target class.
-///
-CodeGenTarget::CodeGenTarget() {
- std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
- if (Targets.size() != 1)
- throw std::string("ERROR: Multiple subclasses of Target defined!");
- TargetRec = Targets[0];
-
- // Read in all of the CalleeSavedRegisters...
- ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters");
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i)))
- CalleeSavedRegisters.push_back(DI->getDef());
- else
- throw "Target: " + TargetRec->getName() +
- " expected register definition in CalleeSavedRegisters list!";
-
- PointerType = getValueType(TargetRec->getValueAsDef("PointerType"));
-}
-
-
-const std::string &CodeGenTarget::getName() const {
- return TargetRec->getName();
-}
-
-Record *CodeGenTarget::getInstructionSet() const {
- return TargetRec->getValueAsDef("InstructionSet");
-}
diff --git a/support/tools/TableGen/CodeGenWrappers.h b/support/tools/TableGen/CodeGenWrappers.h
deleted file mode 100644
index 00ca3fcc60..0000000000
--- a/support/tools/TableGen/CodeGenWrappers.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- CodeGenWrappers.h - Code Generation Class Wrappers -------*- C++ -*-===//
-//
-// These classes wrap target description classes used by the various code
-// generation TableGen backends. This makes it easier to access the data and
-// provides a single place that needs to check it for validity. All of these
-// classes throw exceptions on error conditions.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CODEGENWRAPPERS_H
-#define CODEGENWRAPPERS_H
-
-#include "llvm/CodeGen/ValueTypes.h"
-#include <iosfwd>
-#include <string>
-#include <vector>
-class Record;
-class RecordKeeper;
-
-/// getValueType - Return the MVT::ValueType that the specified TableGen record
-/// corresponds to.
-MVT::ValueType getValueType(Record *Rec);
-
-std::ostream &operator<<(std::ostream &OS, MVT::ValueType T);
-std::string getName(MVT::ValueType T);
-std::string getEnumName(MVT::ValueType T);
-
-
-/// CodeGenTarget - This class corresponds to the Target class in the .td files.
-///
-class CodeGenTarget {
- Record *TargetRec;
- std::vector<Record*> CalleeSavedRegisters;
- MVT::ValueType PointerType;
-
-public:
- CodeGenTarget();
-
- Record *getTargetRecord() const { return TargetRec; }
- const std::string &getName() const;
-
- const std::vector<Record*> &getCalleeSavedRegisters() const {
- return CalleeSavedRegisters;
- }
-
- MVT::ValueType getPointerType() const { return PointerType; }
-
- // getInstructionSet - Return the InstructionSet object...
- Record *getInstructionSet() const;
-
- // getInstructionSet - Return the CodeGenInstructionSet object for this
- // target, lazily reading it from the record keeper as needed.
- // CodeGenInstructionSet *getInstructionSet -
-};
-
-#endif
diff --git a/support/tools/TableGen/FileLexer.l b/support/tools/TableGen/FileLexer.l
deleted file mode 100644
index 64ed4c625a..0000000000
--- a/support/tools/TableGen/FileLexer.l
+++ /dev/null
@@ -1,222 +0,0 @@
-/*===-- FileLexer.l - Scanner for TableGen Files ----------------*- C++ -*-===//
-//
-// This file defines a simple flex scanner for TableGen files. This is pretty
-// straight-forward, except for the magic to handle file inclusion.
-//
-//===----------------------------------------------------------------------===*/
-
-%option prefix="File"
-%option yylineno
-%option nostdinit
-%option never-interactive
-%option batch
-%option nodefault
-%option 8bit
-%option outfile="Lexer.cpp"
-%option ecs
-%option noreject
-%option noyymore
-
-%x comment
-
-%{
-#include "Record.h"
-typedef std::pair<Record*, std::vector<Init*>*> SubClassRefTy;
-#include "FileParser.h"
-
-// Global variable recording the location of the include directory
-std::string IncludeDirectory;
-
-// ParseInt - This has to handle the special case of binary numbers 0b0101
-static int ParseInt(const char *Str) {
- if (Str[0] == '0' && Str[1] == 'b')
- return strtol(Str+2, 0, 2);
- return strtol(Str, 0, 0);
-}
-
-static int CommentDepth = 0;
-
-struct IncludeRec {
- std::string Filename;
- FILE *File;
- unsigned LineNo;
- YY_BUFFER_STATE Buffer;
-
- IncludeRec(const std::string &FN, FILE *F)
- : Filename(FN), File(F), LineNo(0){
- }
-};
-
-static std::vector<IncludeRec> IncludeStack;
-
-
-std::ostream &err() {
- if (IncludeStack.empty())
- return std::cerr << "At end of input: ";
-
- for (unsigned i = 0, e = IncludeStack.size()-1; i != e; ++i)
- std::cerr << "Included from " << IncludeStack[i].Filename << ":"
- << IncludeStack[i].LineNo << ":\n";
- return std::cerr << "Parsing " << IncludeStack.back().Filename << ":"
- << Filelineno << ": ";
-}
-
-
-int Fileparse();
-
-//
-// Function: ParseFile()
-//
-// Description:
-// This function begins the parsing of the specified tablegen file.
-//
-// Inputs:
-// Filename - A string containing the name of the file to parse.
-// IncludeDir - A string containing the directory from which include
-// files can be found.
-//
-void ParseFile(const std::string &Filename, const std::string & IncludeDir) {
- FILE *F = stdin;
- if (Filename != "-") {
- F = fopen(Filename.c_str(), "r");
-
- if (F == 0) {
- std::cerr << "Could not open input file '" + Filename + "'!\n";
- exit (1);
- }
- IncludeStack.push_back(IncludeRec(Filename, F));
- } else {
- IncludeStack.push_back(IncludeRec("<stdin>", stdin));
- }
-
- //
- // Record the location of the include directory so that the lexer can find
- // it later.
- //
- IncludeDirectory = IncludeDir;
-
- Filein = F;
- Filelineno = 1;
- Fileparse();
- Filein = stdin;
-}
-
-// HandleInclude - This function is called when an include directive is
-// encountered in the input stream...
-static void HandleInclude(const char *Buffer) {
- unsigned Length = yyleng;
- assert(Buffer[Length-1] == '"');
- Buffer += strlen("include ");
- Length -= strlen("include ");
- while (*Buffer != '"') {
- ++Buffer;
- --Length;
- }
- assert(Length >= 2 && "Double quotes not found?");
- std::string Filename(Buffer+1, Buffer+Length-1);
- //std::cerr << "Filename = '" << Filename << "'\n";
-
- // Save the line number and lex buffer of the includer...
- IncludeStack.back().LineNo = Filelineno;
- IncludeStack.back().Buffer = YY_CURRENT_BUFFER;
-
- // Open the new input file...
- yyin = fopen(Filename.c_str(), "r");
- if (yyin == 0) {
- //
- // If we couldn't find the file in the current directory, look for it in
- // the include directories.
- //
- // NOTE:
- // Right now, there is only one directory. We need to eventually add
- // support for more.
- //
- Filename = IncludeDirectory + "/" + Filename;
- yyin = fopen(Filename.c_str(), "r");
- if (yyin == 0) {
- err() << "Could not find include file '" << Filename << "'!\n";
- abort();
- }
- }
-
- // Add the file to our include stack...
- IncludeStack.push_back(IncludeRec(Filename, yyin));
- Filelineno = 1; // Reset line numbering...
- //yyrestart(yyin); // Start lexing the new file...
-
- yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
-}
-
-
-// yywrap - This is called when the lexer runs out of input in one of the files.
-// Switch back to an includer if an includee has run out of input.
-//
-extern "C"
-int yywrap() {
- if (IncludeStack.back().File != stdin)
- fclose(IncludeStack.back().File);
- IncludeStack.pop_back();
- if (IncludeStack.empty()) return 1; // Top-level file is done.
-
- // Otherwise, we need to switch back to a file which included the current one.
- Filelineno = IncludeStack.back().LineNo; // Restore current line number
- yy_switch_to_buffer(IncludeStack.back().Buffer);
- return 0;
-}
-
-%}
-
-Comment \/\/.*
-
-Identifier [a-zA-Z_][0-9a-zA-Z_]*
-Integer [-+]?[0-9]+|0x[0-9a-fA-F]+|0b[01]+
-CodeFragment \[\{([^}]+|\}[^\]])*\}\]
-StringVal \"[^"]*\"
-IncludeStr include[ \t\n]+\"[^"]*\"
-
-%%
-
-{Comment} { /* Ignore comments */ }
-
-{IncludeStr} { HandleInclude(yytext); }
-{CodeFragment} { Filelval.StrVal = new std::string(yytext+2, yytext+yyleng-2);
- return CODEFRAGMENT; }
-
-int { return INT; }
-bit { return BIT; }
-bits { return BITS; }
-string { return STRING; }
-list { return LIST; }
-code { return CODE; }
-dag { return DAG; }
-
-class { return CLASS; }
-def { return DEF; }
-field { return FIELD; }
-let { return LET; }
-in { return IN; }
-
-{Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
- return ID; }
-${Identifier} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
- return VARNAME; }
-
-{StringVal} { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng-1);
- return STRVAL; }
-
-{Integer} { Filelval.IntVal = ParseInt(Filetext); return INTVAL; }
-
-[ \t\n]+ { /* Ignore whitespace */ }
-
-
-"/*" { BEGIN(comment); CommentDepth++; }
-<comment>[^*/]* /* eat anything that's not a '*' or '/' */
-<comment>"*"+[^*/]* /* eat up '*'s not followed by '/'s */
-<comment>"/*" { ++CommentDepth; }
-<comment>"/"+[^*]* /* eat up /'s not followed by *'s */
-<comment>"*"+"/" { if (!--CommentDepth) { BEGIN(INITIAL); } }
-<comment><<EOF>> { err() << "Unterminated comment!\n"; abort(); }
-
-. { return Filetext[0]; }
-
-%%
diff --git a/support/tools/TableGen/FileParser.y b/support/tools/TableGen/FileParser.y
deleted file mode 100644
index 728fcf222c..0000000000
--- a/support/tools/TableGen/FileParser.y
+++ /dev/null
@@ -1,510 +0,0 @@
-//===-- FileParser.y - Parser for TableGen files ----------------*- C++ -*-===//
-//
-// This file implements the bison parser for Table Generator files...
-//
-//===------------------------------------------------------------------------=//
-
-%{
-#include "Record.h"
-#include "Support/StringExtras.h"
-#include <algorithm>
-#include <cstdio>
-#define YYERROR_VERBOSE 1
-
-int yyerror(const char *ErrorMsg);
-int yylex();
-extern int Filelineno;
-static Record *CurRec = 0;
-
-typedef std::pair<Record*, std::vector<Init*>*> SubClassRefTy;
-
-struct LetRecord {
- std::string Name;
- std::vector<unsigned> Bits;
- Init *Value;
- bool HasBits;
- LetRecord(const std::string &N, std::vector<unsigned> *B, Init *V)
- : Name(N), Value(V), HasBits(B != 0) {
- if (HasBits) Bits = *B;
- }
-};
-
-static std::vector<std::vector<LetRecord> > LetStack;
-
-
-extern std::ostream &err();
-
-static void addValue(const RecordVal &RV) {
- if (RecordVal *ERV = CurRec->getValue(RV.getName())) {
- // The value already exists in the class, treat this as a set...
- if (ERV->setValue(RV.getValue())) {
- err() << "New definition of '" << RV.getName() << "' of type '"
- << *RV.getType() << "' is incompatible with previous "
- << "definition of type '" << *ERV->getType() << "'!\n";
- abort();
- }
- } else {
- CurRec->addValue(RV);
- }
-}
-
-static void addSuperClass(Record *SC) {
- if (CurRec->isSubClassOf(SC)) {
- err() << "Already subclass of '" << SC->getName() << "'!\n";
- abort();
- }
- CurRec->addSuperClass(SC);
-}
-
-static void setValue(const std::string &ValName,
- std::vector<unsigned> *BitList, Init *V) {
- if (!V) return ;
-
- RecordVal *RV = CurRec->getValue(ValName);
- if (RV == 0) {
- err() << "Value '" << ValName << "' unknown!\n";
- abort();
- }
-
- // If we are assigning to a subset of the bits in the value... then we must be
- // assigning to a field of BitsRecTy, which must have a BitsInit
- // initializer...
- //
- if (BitList) {
- BitsInit *CurVal = dynamic_cast<BitsInit*>(RV->getValue());
- if (CurVal == 0) {
- err() << "Value '" << ValName << "' is not a bits type!\n";
- abort();
- }
-
- // Convert the incoming value to a bits type of the appropriate size...
- Init *BI = V->convertInitializerTo(new BitsRecTy(BitList->size()));
- if (BI == 0) {
- V->convertInitializerTo(new BitsRecTy(BitList->size()));
- err() << "Initializer '" << *V << "' not compatible with bit range!\n";
- abort();
- }
-
- // We should have a BitsInit type now...
- assert(dynamic_cast<BitsInit*>(BI) != 0 || &(std::cerr << *BI) == 0);
- BitsInit *BInit = (BitsInit*)BI;
-
- BitsInit *NewVal = new BitsInit(CurVal->getNumBits());
-
- // Loop over bits, assigning values as appropriate...
- for (unsigned i = 0, e = BitList->size(); i != e; ++i) {
- unsigned Bit = (*BitList)[i];
- if (NewVal->getBit(Bit)) {
- err() << "Cannot set bit #" << Bit << " of value '" << ValName
- << "' more than once!\n";
- abort();
- }
- NewVal->setBit(Bit, BInit->getBit(i));
- }
-
- for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i)
- if (NewVal->getBit(i) == 0)
- NewVal->setBit(i, CurVal->getBit(i));
-
- V = NewVal;
- }
-
- if (RV->setValue(V)) {
- err() << "Value '" << ValName << "' of type '" << *RV->getType()
- << "' is incompatible with initializer '" << *V << "'!\n";
- abort();
- }
-}
-
-static void addSubClass(Record *SC, const std::vector<Init*> &TemplateArgs) {
- // Add all of the values in the subclass into the current class...
- const std::vector<RecordVal> &Vals = SC->getValues();
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- addValue(Vals[i]);
-
- const std::vector<std::string> &TArgs = SC->getTemplateArgs();
-
- // Ensure that an appropriate number of template arguments are specified...
- if (TArgs.size() < TemplateArgs.size()) {
- err() << "ERROR: More template args specified than expected!\n";
- abort();
- } else { // This class expects template arguments...
- // Loop over all of the template arguments, setting them to the specified
- // value or leaving them as the default as necessary.
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- if (i < TemplateArgs.size()) { // A value is specified for this temp-arg?
- // Set it now.
- setValue(TArgs[i], 0, TemplateArgs[i]);
- } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) {
- err() << "ERROR: Value not specified for template argument #"
- << i << " (" << TArgs[i] << ") of subclass '" << SC->getName()
- << "'!\n";
- abort();
- }
- }
- }
-
-
- // Since everything went well, we can now set the "superclass" list for the
- // current record.
- const std::vector<Record*> &SCs = SC->getSuperClasses();
- for (unsigned i = 0, e = SCs.size(); i != e; ++i)
- addSuperClass(SCs[i]);
- addSuperClass(SC);
-}
-
-
-%}
-
-%union {
- std::string *StrVal;
- int IntVal;
- RecTy *Ty;
- Init *Initializer;
- std::vector<Init*> *FieldList;
- std::vector<unsigned>*BitList;
- Record *Rec;
- SubClassRefTy *SubClassRef;
- std::vector<SubClassRefTy> *SubClassList;
- std::vector<std::pair<Init*, std::string> > *DagValueList;
-};
-
-%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN
-%token <IntVal> INTVAL
-%token <StrVal> ID VARNAME STRVAL CODEFRAGMENT
-
-%type <Ty> Type
-%type <Rec> ClassInst DefInst Object ObjectBody ClassID
-
-%type <SubClassRef> SubClassRef
-%type <SubClassList> ClassList ClassListNE
-%type <IntVal> OptPrefix
-%type <Initializer> Value OptValue
-%type <DagValueList> DagArgList DagArgListNE
-%type <FieldList> ValueList ValueListNE
-%type <BitList> BitList OptBitList RBitList
-%type <StrVal> Declaration OptID OptVarName
-
-%start File
-%%
-
-ClassID : ID {
- $$ = Records.getClass(*$1);
- if ($$ == 0) {
- err() << "Couldn't find class '" << *$1 << "'!\n";
- abort();
- }
- delete $1;
- };
-
-
-// TableGen types...
-Type : STRING { // string type
- $$ = new StringRecTy();
- } | BIT { // bit type
- $$ = new BitRecTy();
- } | BITS '<' INTVAL '>' { // bits<x> type
- $$ = new BitsRecTy($3);
- } | INT { // int type
- $$ = new IntRecTy();
- } | LIST '<' Type '>' { // list<x> type
- $$ = new ListRecTy($3);
- } | CODE { // code type
- $$ = new CodeRecTy();
- } | DAG { // dag type
- $$ = new DagRecTy();
- } | ClassID { // Record Type
- $$ = new RecordRecTy($1);
- };
-
-OptPrefix : /*empty*/ { $$ = 0; } | FIELD { $$ = 1; };
-
-OptValue : /*empty*/ { $$ = 0; } | '=' Value { $$ = $2; };
-
-Value : INTVAL {
- $$ = new IntInit($1);
- } | STRVAL {
- $$ = new StringInit(*$1);
- delete $1;
- } | CODEFRAGMENT {
- $$ = new CodeInit(*$1);
- delete $1;
- } | '?' {
- $$ = new UnsetInit();
- } | '{' ValueList '}' {
- BitsInit *Init = new BitsInit($2->size());
- for (unsigned i = 0, e = $2->size(); i != e; ++i) {
- struct Init *Bit = (*$2)[i]->convertInitializerTo(new BitRecTy());
- if (Bit == 0) {
- err() << "Element #" << i << " (" << *(*$2)[i]
- << ") is not convertable to a bit!\n";
- abort();
- }
- Init->setBit($2->size()-i-1, Bit);
- }
- $$ = Init;
- delete $2;
- } | ID {
- if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) {
- $$ = new VarInit(*$1, RV->getType());
- } else if (Record *D = Records.getDef(*$1)) {
- $$ = new DefInit(D);
- } else {
- err() << "Variable not defined: '" << *$1 << "'!\n";
- abort();
- }
-
- delete $1;
- } | Value '{' BitList '}' {
- $$ = $1->convertInitializerBitRange(*$3);
- if ($$ == 0) {
- err() << "Invalid bit range for value '" << *$1 << "'!\n";
- abort();
- }
- delete $3;
- } | '[' ValueList ']' {
- $$ = new ListInit(*$2);
- delete $2;
- } | Value '.' ID {
- if (!$1->getFieldType(*$3)) {
- err() << "Cannot access field '" << *$3 << "' of value '" << *$1 << "!\n";
- abort();
- }
- $$ = new FieldInit($1, *$3);
- delete $3;
- } | '(' ID DagArgList ')' {
- Record *D = Records.getDef(*$2);
- if (D == 0) {
- err() << "Invalid def '" << *$2 << "'!\n";
- abort();
- }
- $$ = new DagInit(D, *$3);
- delete $2; delete $3;
- };
-
-OptVarName : /* empty */ {
- $$ = new std::string();
- }
- | ':' VARNAME {
- $$ = $2;
- };
-
-DagArgListNE : Value OptVarName {
- $$ = new std::vector<std::pair<Init*, std::string> >();
- $$->push_back(std::make_pair($1, *$2));
- delete $2;
- }
- | DagArgListNE ',' Value OptVarName {
- $1->push_back(std::make_pair($3, *$4));
- delete $4;
- $$ = $1;
- };
-
-DagArgList : /*empty*/ {
- $$ = new std::vector<std::pair<Init*, std::string> >();
- }
- | DagArgListNE { $$ = $1; };
-
-
-RBitList : INTVAL {
- $$ = new std::vector<unsigned>();
- $$->push_back($1);
- } | INTVAL '-' INTVAL {
- if ($1 < $3 || $1 < 0 || $3 < 0) {
- err() << "Invalid bit range: " << $1 << "-" << $3 << "!\n";
- abort();
- }
- $$ = new std::vector<unsigned>();
- for (int i = $1; i >= $3; --i)
- $$->push_back(i);
- } | INTVAL INTVAL {
- $2 = -$2;
- if ($1 < $2 || $1 < 0 || $2 < 0) {
- err() << "Invalid bit range: " << $1 << "-" << $2 << "!\n";
- abort();
- }
- $$ = new std::vector<unsigned>();
- for (int i = $1; i >= $2; --i)
- $$->push_back(i);
- } | RBitList ',' INTVAL {
- ($$=$1)->push_back($3);
- } | RBitList ',' INTVAL '-' INTVAL {
- if ($3 < $5 || $3 < 0 || $5 < 0) {
- err() << "Invalid bit range: " << $3 << "-" << $5 << "!\n";
- abort();
- }
- $$ = $1;
- for (int i = $3; i >= $5; --i)
- $$->push_back(i);
- } | RBitList ',' INTVAL INTVAL {
- $4 = -$4;
- if ($3 < $4 || $3 < 0 || $4 < 0) {
- err() << "Invalid bit range: " << $3 << "-" << $4 << "!\n";
- abort();
- }
- $$ = $1;
- for (int i = $3; i >= $4; --i)
- $$->push_back(i);
- };
-
-BitList : RBitList { $$ = $1; std::reverse($1->begin(), $1->end()); };
-
-OptBitList : /*empty*/ { $$ = 0; } | '{' BitList '}' { $$ = $2; };
-
-
-
-ValueList : /*empty*/ {
- $$ = new std::vector<Init*>();
- } | ValueListNE {
- $$ = $1;
- };
-
-ValueListNE : Value {
- $$ = new std::vector<Init*>();
- $$->push_back($1);
- } | ValueListNE ',' Value {
- ($$ = $1)->push_back($3);
- };
-
-Declaration : OptPrefix Type ID OptValue {
- addValue(RecordVal(*$3, $2, $1));
- setValue(*$3, 0, $4);
- $$ = $3;
-};
-
-BodyItem : Declaration ';' {
- delete $1;
-} | LET ID OptBitList '=' Value ';' {
- setValue(*$2, $3, $5);
- delete $2;
- delete $3;
-};
-
-BodyList : /*empty*/ | BodyList BodyItem;
-Body : ';' | '{' BodyList '}';
-
-SubClassRef : ClassID {
- $$ = new SubClassRefTy($1, new std::vector<Init*>());
- } | ClassID '<' ValueListNE '>' {
- $$ = new SubClassRefTy($1, $3);
- };
-
-ClassListNE : SubClassRef {
- $$ = new std::vector<SubClassRefTy>();
- $$->push_back(*$1);
- delete $1;
- }
- | ClassListNE ',' SubClassRef {
- ($$=$1)->push_back(*$3);
- delete $3;
- };
-
-ClassList : /*empty */ {
- $$ = new std::vector<SubClassRefTy>();
- }
- | ':' ClassListNE {
- $$ = $2;
- };
-
-DeclListNE : Declaration {
- CurRec->addTemplateArg(*$1);
- delete $1;
-} | DeclListNE ',' Declaration {
- CurRec->addTemplateArg(*$3);
- delete $3;
-};
-
-TemplateArgList : '<' DeclListNE '>' {};
-OptTemplateArgList : /*empty*/ | TemplateArgList;
-
-OptID : ID { $$ = $1; } | /*empty*/ { $$ = new std::string(); };
-
-ObjectBody : OptID {
- static unsigned AnonCounter = 0;
- if ($1->empty())
- *$1 = "anonymous."+utostr(AnonCounter++);
- CurRec = new Record(*$1);
- delete $1;
- } OptTemplateArgList ClassList {
- for (unsigned i = 0, e = $4->size(); i != e; ++i) {
- addSubClass((*$4)[i].first, *(*$4)[i].second);
- // Delete the template arg values for the class
- delete (*$4)[i].second;
- }
-
- // Process any variables on the set stack...
- for (unsigned i = 0, e = LetStack.size(); i != e; ++i)
- for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j)
- setValue(LetStack[i][j].Name,
- LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0,
- LetStack[i][j].Value);
- } Body {
- CurRec->resolveReferences();
-
- // Now that all of the references have been resolved, we can delete template
- // arguments for superclasses, so they don't pollute our record, and so that
- // their names won't conflict with later uses of the name...
- for (unsigned i = 0, e = $4->size(); i != e; ++i) {
- Record *SuperClass = (*$4)[i].first;
- for (unsigned i = 0, e = SuperClass->getTemplateArgs().size(); i != e; ++i)
- CurRec->removeValue(SuperClass->getTemplateArgs()[i]);
- }
- delete $4; // Delete the class list...
-
- $$ = CurRec;
- CurRec = 0;
-};
-
-ClassInst : CLASS ObjectBody {
- if (Records.getClass($2->getName())) {
- err() << "Class '" << $2->getName() << "' already defined!\n";
- abort();
- }
- Records.addClass($$ = $2);
-};
-
-DefInst : DEF ObjectBody {
- if (!$2->getTemplateArgs().empty()) {
- err() << "Def '" << $2->getName()
- << "' is not permitted to have template arguments!\n";
- abort();
- }
- // If ObjectBody has template arguments, it's an error.
- if (Records.getDef($2->getName())) {
- err() << "Def '" << $2->getName() << "' already defined!\n";
- abort();
- }
- Records.addDef($$ = $2);
-};
-
-
-Object : ClassInst | DefInst;
-
-LETItem : ID OptBitList '=' Value {
- LetStack.back().push_back(LetRecord(*$1, $2, $4));
- delete $1; delete $2;
-};
-
-LETList : LETItem | LETList ',' LETItem;
-
-// LETCommand - A 'LET' statement start...
-LETCommand : LET { LetStack.push_back(std::vector<LetRecord>()); } LETList IN;
-
-// Support Set commands wrapping objects... both with and without braces.
-Object : LETCommand '{' ObjectList '}' {
- LetStack.pop_back();
- }
- | LETCommand Object {
- LetStack.pop_back();
- };
-
-ObjectList : Object {} | ObjectList Object {};
-
-File : ObjectList {};
-
-%%
-
-int yyerror(const char *ErrorMsg) {
- err() << "Error parsing: " << ErrorMsg << "\n";
- abort();
-}
diff --git a/support/tools/TableGen/InstrInfoEmitter.cpp b/support/tools/TableGen/InstrInfoEmitter.cpp
deleted file mode 100644
index c794cd0441..0000000000
--- a/support/tools/TableGen/InstrInfoEmitter.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
-//
-// This tablegen backend is responsible for emitting a description of the target
-// instruction set for the code generator.
-//
-//===----------------------------------------------------------------------===//
-
-#include "InstrInfoEmitter.h"
-#include "CodeGenWrappers.h"
-#include "Record.h"
-
-// runEnums - Print out enum values for all of the instructions.
-void InstrInfoEmitter::runEnums(std::ostream &OS) {
- std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
-
- if (Insts.size() == 0)
- throw std::string("No 'Instruction' subclasses defined!");
-
- std::string Namespace = Insts[0]->getValueAsString("Namespace");
-
- EmitSourceFileHeader("Target Instruction Enum Values", OS);
-
- if (!Namespace.empty())
- OS << "namespace " << Namespace << " {\n";
- OS << " enum {\n";
-
- CodeGenTarget Target;
-
- // We must emit the PHI opcode first...
- Record *InstrInfo = Target.getInstructionSet();
- Record *PHI = InstrInfo->getValueAsDef("PHIInst");
-
- OS << " " << PHI->getName() << ", \t// 0 (fixed for all targets)\n";
-
- // Print out the rest of the instructions now...
- for (unsigned i = 0, e = Insts.size(); i != e; ++i)
- if (Insts[i] != PHI)
- OS << " " << Insts[i]->getName() << ", \t// " << i+1 << "\n";
-
- OS << " };\n";
- if (!Namespace.empty())
- OS << "}\n";
-}
-
-void InstrInfoEmitter::printDefList(ListInit *LI, const std::string &Name,
- std::ostream &OS) const {
- OS << "static const unsigned " << Name << "[] = { ";
- for (unsigned j = 0, e = LI->getSize(); j != e; ++j)
- if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(j)))
- OS << getQualifiedName(DI->getDef()) << ", ";
- else
- throw "Illegal value in '" + Name + "' list!";
- OS << "0 };\n";
-}
-
-
-// run - Emit the main instruction description records for the target...
-void InstrInfoEmitter::run(std::ostream &OS) {
- EmitSourceFileHeader("Target Instruction Descriptors", OS);
- CodeGenTarget Target;
- const std::string &TargetName = Target.getName();
- Record *InstrInfo = Target.getInstructionSet();
- Record *PHI = InstrInfo->getValueAsDef("PHIInst");
-
- std::vector<Record*> Instructions =
- Records.getAllDerivedDefinitions("Instruction");
-
- // Emit all of the instruction's implicit uses and defs...
- for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
- Record *Inst = Instructions[i];
- ListInit *LI = Inst->getValueAsListInit("Uses");
- if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpUses", OS);
- LI = Inst->getValueAsListInit("Defs");
- if (LI->getSize()) printDefList(LI, Inst->getName()+"ImpDefs", OS);
- }
-
- OS << "\nstatic const TargetInstrDescriptor " << TargetName
- << "Insts[] = {\n";
- emitRecord(PHI, 0, InstrInfo, OS);
-
- for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
- if (Instructions[i] != PHI)
- emitRecord(Instructions[i], i+1, InstrInfo, OS);
- OS << "};\n";
-}
-
-void InstrInfoEmitter::emitRecord(Record *R, unsigned Num, Record *InstrInfo,
- std::ostream &OS) {
- OS << " { \"" << R->getValueAsString("Name")
- << "\",\t-1, -1, 0, false, 0, 0, 0, 0";
-
- // Emit all of the target indepedent flags...
- if (R->getValueAsBit("isReturn")) OS << "|M_RET_FLAG";
- if (R->getValueAsBit("isBranch")) OS << "|M_BRANCH_FLAG";
- if (R->getValueAsBit("isCall" )) OS << "|M_CALL_FLAG";
- if (R->getValueAsBit("isTwoAddress")) OS << "|M_2_ADDR_FLAG";
- if (R->getValueAsBit("isTerminator")) OS << "|M_TERMINATOR_FLAG";
- OS << ", 0";
-
- // Emit all of the target-specific flags...
- ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields");
- ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts");
- if (LI->getSize() != Shift->getSize())
- throw "Lengths of " + InstrInfo->getName() +
- ":(TargetInfoFields, TargetInfoPositions) must be equal!";
-
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- emitShiftedValue(R, dynamic_cast<StringInit*>(LI->getElement(i)),
- dynamic_cast<IntInit*>(Shift->getElement(i)), OS);
-
- OS << ", ";
-
- // Emit the implicit uses and defs lists...
- LI = R->getValueAsListInit("Uses");
- if (!LI->getSize())
- OS << "0, ";
- else
- OS << R->getName() << "ImpUses, ";
-
- LI = R->getValueAsListInit("Defs");
- if (!LI->getSize())
- OS << "0 ";
- else
- OS << R->getName() << "ImpDefs ";
-
- OS << " }, // Inst #" << Num << " = " << R->getName() << "\n";
-}
-
-void InstrInfoEmitter::emitShiftedValue(Record *R, StringInit *Val,
- IntInit *ShiftInt, std::ostream &OS) {
- if (Val == 0 || ShiftInt == 0)
- throw std::string("Illegal value or shift amount in TargetInfo*!");
- RecordVal *RV = R->getValue(Val->getValue());
- int Shift = ShiftInt->getValue();
-
- if (RV == 0 || RV->getValue() == 0)
- throw R->getName() + " doesn't have a field named '" + Val->getValue()+"'!";
-
- Init *Value = RV->getValue();
- if (BitInit *BI = dynamic_cast<BitInit*>(Value)) {
- if (BI->getValue()) OS << "|(1<<" << Shift << ")";
- return;
- } else if (BitsInit *BI = dynamic_cast<BitsInit*>(Value)) {
- // Convert the Bits to an integer to print...
- Init *I = BI->convertInitializerTo(new IntRecTy());
- if (I)
- if (IntInit *II = dynamic_cast<IntInit*>(I)) {
- if (II->getValue())
- OS << "|(" << II->getValue() << "<<" << Shift << ")";
- return;
- }
-
- } else if (IntInit *II = dynamic_cast<IntInit*>(Value)) {
- if (II->getValue()) OS << "|(" << II->getValue() << "<<" << Shift << ")";
- return;
- }
-
- std::cerr << "Unhandled initializer: " << *Val << "\n";
- throw "In record '" + R->getName() + "' for TSFlag emission.";
-}
diff --git a/support/tools/TableGen/InstrInfoEmitter.h b/support/tools/TableGen/InstrInfoEmitter.h
deleted file mode 100644
index 400c0db16c..0000000000
--- a/support/tools/TableGen/InstrInfoEmitter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===//
-//
-// This tablegen backend is responsible for emitting a description of the target
-// instruction set for the code generator.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef INSTRINFO_EMITTER_H
-#define INSTRINFO_EMITTER_H
-
-#include "TableGenBackend.h"
-class StringInit;
-class IntInit;
-class ListInit;
-
-class InstrInfoEmitter : public TableGenBackend {
- RecordKeeper &Records;
-public:
- InstrInfoEmitter(RecordKeeper &R) : Records(R) {}
-
- // run - Output the instruction set description, returning true on failure.
- void run(std::ostream &OS);
-
- // runEnums - Print out enum values for all of the instructions.
- void runEnums(std::ostream &OS);
-private:
- void printDefList(ListInit *LI, const std::string &Name,
- std::ostream &OS) const;
- void emitRecord(Record *R, unsigned Num, Record *InstrInfo, std::ostream &OS);
- void emitShiftedValue(Record *R, StringInit *Val, IntInit *Shift,
- std::ostream &OS);
-};
-
-#endif
diff --git a/support/tools/TableGen/InstrSelectorEmitter.cpp b/support/tools/TableGen/InstrSelectorEmitter.cpp
deleted file mode 100644
index a3c535cad4..0000000000
--- a/support/tools/TableGen/InstrSelectorEmitter.cpp
+++ /dev/null
@@ -1,1287 +0,0 @@
-//===- InstrInfoEmitter.cpp - Generate a Instruction Set Desc. ------------===//
-//
-// This tablegen backend is responsible for emitting a description of the target
-// instruction set for the code generator.
-//
-//===----------------------------------------------------------------------===//
-
-#include "InstrSelectorEmitter.h"
-#include "CodeGenWrappers.h"
-#include "Record.h"
-#include "Support/Debug.h"
-#include "Support/StringExtras.h"
-#include <set>
-
-NodeType::ArgResultTypes NodeType::Translate(Record *R) {
- const std::string &Name = R->getName();
- if (Name == "DNVT_any") return Any;
- if (Name == "DNVT_void") return Void;
- if (Name == "DNVT_val" ) return Val;
- if (Name == "DNVT_arg0") return Arg0;
- if (Name == "DNVT_arg1") return Arg1;
- if (Name == "DNVT_ptr" ) return Ptr;
- if (Name == "DNVT_i8" ) return I8;
- throw "Unknown DagNodeValType '" + Name + "'!";
-}
-
-
-//===----------------------------------------------------------------------===//
-// TreePatternNode implementation
-//
-
-/// getValueRecord - Returns the value of this tree node as a record. For now
-/// we only allow DefInit's as our leaf values, so this is used.
-Record *TreePatternNode::getValueRecord() const {
- DefInit *DI = dynamic_cast<DefInit*>(getValue());
- assert(DI && "Instruction Selector does not yet support non-def leaves!");
- return DI->getDef();
-}
-
-
-// updateNodeType - Set the node type of N to VT if VT contains information. If
-// N already contains a conflicting type, then throw an exception
-//
-bool TreePatternNode::updateNodeType(MVT::ValueType VT,
- const std::string &RecName) {
- if (VT == MVT::Other || getType() == VT) return false;
- if (getType() == MVT::Other) {
- setType(VT);
- return true;
- }
-
- throw "Type inferfence contradiction found for pattern " + RecName;
-}
-
-/// InstantiateNonterminals - If this pattern refers to any nonterminals which
-/// are not themselves completely resolved, clone the nonterminal and resolve it
-/// with the using context we provide.
-///
-void TreePatternNode::InstantiateNonterminals(InstrSelectorEmitter &ISE) {
- if (!isLeaf()) {
- for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- getChild(i)->InstantiateNonterminals(ISE);
- return;
- }
-
- // If this is a leaf, it might be a reference to a nonterminal! Check now.
- Record *R = getValueRecord();
- if (R->isSubClassOf("Nonterminal")) {
- Pattern *NT = ISE.getPattern(R);
- if (!NT->isResolved()) {
- // We found an unresolved nonterminal reference. Ask the ISE to clone
- // it for us, then update our reference to the fresh, new, resolved,
- // nonterminal.
-
- Value = new DefInit(ISE.InstantiateNonterminal(NT, getType()));
- }
- }
-}
-
-
-/// clone - Make a copy of this tree and all of its children.
-///
-TreePatternNode *TreePatternNode::clone() const {
- TreePatternNode *New;
- if (isLeaf()) {
- New = new TreePatternNode(Value);
- } else {
- std::vector<std::pair<TreePatternNode*, std::string> > CChildren;
- CChildren.reserve(Children.size());
- for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
- CChildren.push_back(std::make_pair(getChild(i)->clone(),getChildName(i)));
- New = new TreePatternNode(Operator, CChildren);
- }
- New->setType(Type);
- return New;
-}
-
-std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N) {
- if (N.isLeaf())
- return OS << N.getType() << ":" << *N.getValue();
- OS << "(" << N.getType() << ":";
- OS << N.getOperator()->getName();
-
- if (N.getNumChildren() != 0) {
- OS << " " << *N.getChild(0);
- for (unsigned i = 1, e = N.getNumChildren(); i != e; ++i)
- OS << ", " << *N.getChild(i);
- }
- return OS << ")";
-}
-
-void TreePatternNode::dump() const { std::cerr << *this; }
-
-//===----------------------------------------------------------------------===//
-// Pattern implementation
-//
-
-// Parse the specified DagInit into a TreePattern which we can use.
-//
-Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
- InstrSelectorEmitter &ise)
- : PTy(pty), ResultNode(0), TheRecord(TheRec), ISE(ise) {
-
- // First, parse the pattern...
- Tree = ParseTreePattern(RawPat);
-
- // Run the type-inference engine...
- InferAllTypes();
-
- if (PTy == Instruction || PTy == Expander) {
- // Check to make sure there is not any unset types in the tree pattern...
- if (!isResolved()) {
- std::cerr << "In pattern: " << *Tree << "\n";
- error("Could not infer all types!");
- }
-
- // Check to see if we have a top-level (set) of a register.
- if (Tree->getOperator()->getName() == "set") {
- assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
- if (!Tree->getChild(0)->isLeaf())
- error("Arg #0 of set should be a register or register class!");
- ResultNode = Tree->getChild(0);
- ResultName = Tree->getChildName(0);
- Tree = Tree->getChild(1);
- }
- }
-
- calculateArgs(Tree, "");
-}
-
-void Pattern::error(const std::string &Msg) const {
- std::string M = "In ";
- switch (PTy) {
- case Nonterminal: M += "nonterminal "; break;
- case Instruction: M += "instruction "; break;
- case Expander : M += "expander "; break;
- }
- throw M + TheRecord->getName() + ": " + Msg;
-}
-
-/// calculateArgs - Compute the list of all of the arguments to this pattern,
-/// which are the non-void leaf nodes in this pattern.
-///
-void Pattern::calculateArgs(TreePatternNode *N, const std::string &Name) {
- if (N->isLeaf() || N->getNumChildren() == 0) {
- if (N->getType() != MVT::isVoid)
- Args.push_back(std::make_pair(N, Name));
- } else {
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
- calculateArgs(N->getChild(i), N->getChildName(i));
- }
-}
-
-/// getIntrinsicType - Check to see if the specified record has an intrinsic
-/// type which should be applied to it. This infer the type of register
-/// references from the register file information, for example.
-///
-MVT::ValueType Pattern::getIntrinsicType(Record *R) const {
- // Check to see if this is a register or a register class...
- if (R->isSubClassOf("RegisterClass"))
- return getValueType(R->getValueAsDef("RegType"));
- else if (R->isSubClassOf("Nonterminal"))
- return ISE.ReadNonterminal(R)->getTree()->getType();
- else if (R->isSubClassOf("Register")) {
- std::cerr << "WARNING: Explicit registers not handled yet!\n";
- return MVT::Other;
- }
-
- error("Unknown value used: " + R->getName());
- return MVT::Other;
-}
-
-TreePatternNode *Pattern::ParseTreePattern(DagInit *Dag) {
- Record *Operator = Dag->getNodeType();
-
- if (Operator->isSubClassOf("ValueType")) {
- // If the operator is a ValueType, then this must be "type cast" of a leaf
- // node.
- if (Dag->getNumArgs() != 1)
- error("Type cast only valid for a leaf node!");
-
- Init *Arg = Dag->getArg(0);
- TreePatternNode *New;
- if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
- New = new TreePatternNode(DI);
- // If it's a regclass or something else known, set the type.
- New->setType(getIntrinsicType(DI->getDef()));
- } else if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
- New = ParseTreePattern(DI);
- } else {
- Arg->dump();
- error("Unknown leaf value for tree pattern!");
- return 0;
- }
-
- // Apply the type cast...
- New->updateNodeType(getValueType(Operator), TheRecord->getName());
- return New;
- }
-
- if (!ISE.getNodeTypes().count(Operator))
- error("Unrecognized node '" + Operator->getName() + "'!");
-
- std::vector<std::pair<TreePatternNode*, std::string> > Children;
-
- for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
- Init *Arg = Dag->getArg(i);
- if (DagInit *DI = dynamic_cast<DagInit*>(Arg)) {
- Children.push_back(std::make_pair(ParseTreePattern(DI),
- Dag->getArgName(i)));
- } else if (DefInit *DefI = dynamic_cast<DefInit*>(Arg)) {
- Record *R = DefI->getDef();
- // Direct reference to a leaf DagNode? Turn it into a DagNode if its own.
- if (R->isSubClassOf("DagNode")) {
- Dag->setArg(i, new DagInit(R,
- std::vector<std::pair<Init*, std::string> >()));
- --i; // Revisit this node...
- } else {
- Children.push_back(std::make_pair(new TreePatternNode(DefI),
- Dag->getArgName(i)));
- // If it's a regclass or something else known, set the type.
- Children.back().first->setType(getIntrinsicType(R));
- }
- } else {
- Arg->dump();
- error("Unknown leaf value for tree pattern!");
- }
- }
-
- return new TreePatternNode(Operator, Children);
-}
-
-void Pattern::InferAllTypes() {
- bool MadeChange, AnyUnset;
- do {
- MadeChange = false;
- AnyUnset = InferTypes(Tree, MadeChange);
- } while ((AnyUnset || MadeChange) && !(AnyUnset && !MadeChange));
- Resolved = !AnyUnset;
-}
-
-
-// InferTypes - Perform type inference on the tree, returning true if there
-// are any remaining untyped nodes and setting MadeChange if any changes were
-// made.
-bool Pattern::InferTypes(TreePatternNode *N, bool &MadeChange) {
- if (N->isLeaf()) return N->getType() == MVT::Other;
-
- bool AnyUnset = false;
- Record *Operator = N->getOperator();
- const NodeType &NT = ISE.getNodeType(Operator);
-
- // Check to see if we can infer anything about the argument types from the
- // return types...
- if (N->getNumChildren() != NT.ArgTypes.size())
- error("Incorrect number of children for " + Operator->getName() + " node!");
-
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- TreePatternNode *Child = N->getChild(i);
- AnyUnset |= InferTypes(Child, MadeChange);
-
- switch (NT.ArgTypes[i]) {
- case NodeType::Any: break;
- case NodeType::I8:
- MadeChange |= Child->updateNodeType(MVT::i1, TheRecord->getName());
- break;
- case NodeType::Arg0:
- MadeChange |= Child->updateNodeType(N->getChild(0)->getType(),
- TheRecord->getName());
- break;
- case NodeType::Arg1:
- MadeChange |= Child->updateNodeType(N->getChild(1)->getType(),
- TheRecord->getName());
- break;
- case NodeType::Val:
- if (Child->getType() == MVT::isVoid)
- error("Inferred a void node in an illegal place!");
- break;
- case NodeType::Ptr:
- MadeChange |= Child->updateNodeType(ISE.getTarget().getPointerType(),
- TheRecord->getName());
- break;
- case NodeType::Void:
- MadeChange |= Child->updateNodeType(MVT::isVoid, TheRecord->getName());
- break;
- default: assert(0 && "Invalid argument ArgType!");
- }
- }
-
- // See if we can infer anything about the return type now...
- switch (NT.ResultType) {
- case NodeType::Any: break;
- case NodeType::Void:
- MadeChange |= N->updateNodeType(MVT::isVoid, TheRecord->getName());
- break;
- case NodeType::I8:
- MadeChange |= N->updateNodeType(MVT::i1, TheRecord->getName());
- break;
- case NodeType::Arg0:
- MadeChange |= N->updateNodeType(N->getChild(0)->getType(),
- TheRecord->getName());
- break;
- case NodeType::Arg1:
- MadeChange |= N->updateNodeType(N->getChild(1)->getType(),
- TheRecord->getName());
- break;
- case NodeType::Ptr:
- MadeChange |= N->updateNodeType(ISE.getTarget().getPointerType(),
- TheRecord->getName());
- break;
- case NodeType::Val:
- if (N->getType() == MVT::isVoid)
- error("Inferred a void node in an illegal place!");
- break;
- default:
- assert(0 && "Unhandled type constraint!");
- break;
- }
-
- return AnyUnset | N->getType() == MVT::Other;
-}
-
-/// clone - This method is used to make an exact copy of the current pattern,
-/// then change the "TheRecord" instance variable to the specified record.
-///
-Pattern *Pattern::clone(Record *R) const {
- assert(PTy == Nonterminal && "Can only clone nonterminals");
- return new Pattern(Tree->clone(), R, Resolved, ISE);
-}
-
-
-
-std::ostream &operator<<(std::ostream &OS, const Pattern &P) {
- switch (P.getPatternType()) {
- case Pattern::Nonterminal: OS << "Nonterminal pattern "; break;
- case Pattern::Instruction: OS << "Instruction pattern "; break;
- case Pattern::Expander: OS << "Expander pattern "; break;
- }
-
- OS << P.getRecord()->getName() << ":\t";
-
- if (Record *Result = P.getResult())
- OS << Result->getName() << " = ";
- OS << *P.getTree();
-
- if (!P.isResolved())
- OS << " [not completely resolved]";
- return OS;
-}
-
-void Pattern::dump() const { std::cerr << *this; }
-
-
-
-/// getSlotName - If this is a leaf node, return the slot name that the operand
-/// will update.
-std::string Pattern::getSlotName() const {
- if (getPatternType() == Pattern::Nonterminal) {
- // Just use the nonterminal name, which will already include the type if
- // it has been cloned.
- return getRecord()->getName();
- } else {
- std::string SlotName;
- if (getResult())
- SlotName = getResult()->getName()+"_";
- else
- SlotName = "Void_";
- return SlotName + getName(getTree()->getType());
- }
-}
-
-/// getSlotName - If this is a leaf node, return the slot name that the
-/// operand will update.
-std::string Pattern::getSlotName(Record *R) {
- if (R->isSubClassOf("Nonterminal")) {
- // Just use the nonterminal name, which will already include the type if
- // it has been cloned.
- return R->getName();
- } else if (R->isSubClassOf("RegisterClass")) {
- MVT::ValueType Ty = getValueType(R->getValueAsDef("RegType"));
- return R->getName() + "_" + getName(Ty);
- } else {
- assert(0 && "Don't know how to get a slot name for this!");
- }
- return "";
-}
-
-//===----------------------------------------------------------------------===//
-// PatternOrganizer implementation
-//
-
-/// addPattern - Add the specified pattern to the appropriate location in the
-/// collection.
-void PatternOrganizer::addPattern(Pattern *P) {
- NodesForSlot &Nodes = AllPatterns[P->getSlotName()];
- if (!P->getTree()->isLeaf())
- Nodes[P->getTree()->getOperator()].push_back(P);
- else {
- // Right now we only support DefInit's with node types...
- Nodes[P->getTree()->getValueRecord()].push_back(P);
- }
-}
-
-
-
-//===----------------------------------------------------------------------===//
-// InstrSelectorEmitter implementation
-//
-
-/// ReadNodeTypes - Read in all of the node types in the current RecordKeeper,
-/// turning them into the more accessible NodeTypes data structure.
-///
-void InstrSelectorEmitter::ReadNodeTypes() {
- std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode");
- DEBUG(std::cerr << "Getting node types: ");
- for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
- Record *Node = Nodes[i];
-
- // Translate the return type...
- NodeType::ArgResultTypes RetTy =
- NodeType::Translate(Node->getValueAsDef("RetType"));
-
- // Translate the arguments...
- ListInit *Args = Node->getValueAsListInit("ArgTypes");
- std::vector<NodeType::ArgResultTypes> ArgTypes;
-
- for (unsigned a = 0, e = Args->getSize(); a != e; ++a) {
- if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a)))
- ArgTypes.push_back(NodeType::Translate(DI->getDef()));
- else
- throw "In node " + Node->getName() + ", argument is not a Def!";
-
- if (a == 0 && ArgTypes.back() == NodeType::Arg0)
- throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!";
- if (a == 1 && ArgTypes.back() == NodeType::Arg1)
- throw "In node " + Node->getName() + ", arg 1 cannot have type 'arg1'!";
- }
- if ((RetTy == NodeType::Arg0 && Args->getSize() == 0) ||
- (RetTy == NodeType::Arg1 && Args->getSize() < 2))
- throw "In node " + Node->getName() +
- ", invalid return type for node with this many operands!";
-
- // Add the node type mapping now...
- NodeTypes[Node] = NodeType(RetTy, ArgTypes);
- DEBUG(std::cerr << Node->getName() << ", ");
- }
- DEBUG(std::cerr << "DONE!\n");
-}
-
-Pattern *InstrSelectorEmitter::ReadNonterminal(Record *R) {
- Pattern *&P = Patterns[R];
- if (P) return P; // Don't reread it!
-
- DagInit *DI = R->getValueAsDag("Pattern");
- P = new Pattern(Pattern::Nonterminal, DI, R, *this);
- DEBUG(std::cerr << "Parsed " << *P << "\n");
- return P;
-}
-
-
-// ReadNonTerminals - Read in all nonterminals and incorporate them into our
-// pattern database.
-void InstrSelectorEmitter::ReadNonterminals() {
- std::vector<Record*> NTs = Records.getAllDerivedDefinitions("Nonterminal");
- for (unsigned i = 0, e = NTs.size(); i != e; ++i)
- ReadNonterminal(NTs[i]);
-}
-
-
-/// ReadInstructionPatterns - Read in all subclasses of Instruction, and process
-/// those with a useful Pattern field.
-///
-void InstrSelectorEmitter::ReadInstructionPatterns() {
- std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
- for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
- Record *Inst = Insts[i];
- if (DagInit *DI = dynamic_cast<DagInit*>(Inst->getValueInit("Pattern"))) {
- Patterns[Inst] = new Pattern(Pattern::Instruction, DI, Inst, *this);
- DEBUG(std::cerr << "Parsed " << *Patterns[Inst] << "\n");
- }
- }
-}
-
-/// ReadExpanderPatterns - Read in all expander patterns...
-///
-void InstrSelectorEmitter::ReadExpanderPatterns() {
- std::vector<Record*> Expanders = Records.getAllDerivedDefinitions("Expander");
- for (unsigned i = 0, e = Expanders.size(); i != e; ++i) {
- Record *Expander = Expanders[i];
- DagInit *DI = Expander->getValueAsDag("Pattern");
- Patterns[Expander] = new Pattern(Pattern::Expander, DI, Expander, *this);
- DEBUG(std::cerr << "Parsed " << *Patterns[Expander] << "\n");
- }
-}
-
-
-// InstantiateNonterminals - Instantiate any unresolved nonterminals with
-// information from the context that they are used in.
-//
-void InstrSelectorEmitter::InstantiateNonterminals() {
- DEBUG(std::cerr << "Instantiating nonterminals:\n");
- for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
- E = Patterns.end(); I != E; ++I)
- if (I->second->isResolved())
- I->second->InstantiateNonterminals();
-}
-
-/// InstantiateNonterminal - This method takes the nonterminal specified by
-/// NT, which should not be completely resolved, clones it, applies ResultTy
-/// to its root, then runs the type inference stuff on it. This should
-/// produce a newly resolved nonterminal, which we make a record for and
-/// return. To be extra fancy and efficient, this only makes one clone for
-/// each type it is instantiated with.
-Record *InstrSelectorEmitter::InstantiateNonterminal(Pattern *NT,
- MVT::ValueType ResultTy) {
- assert(!NT->isResolved() && "Nonterminal is already resolved!");
-
- // Check to see if we have already instantiated this pair...
- Record* &Slot = InstantiatedNTs[std::make_pair(NT, ResultTy)];
- if (Slot) return Slot;
-
- Record *New = new Record(NT->getRecord()->getName()+"_"+getName(ResultTy));
-
- // Copy over the superclasses...
- const std::vector<Record*> &SCs = NT->getRecord()->getSuperClasses();
- for (unsigned i = 0, e = SCs.size(); i != e; ++i)
- New->addSuperClass(SCs[i]);
-
- DEBUG(std::cerr << " Nonterminal '" << NT->getRecord()->getName()
- << "' for type '" << getName(ResultTy) << "', producing '"
- << New->getName() << "'\n");
-
- // Copy the pattern...
- Pattern *NewPat = NT->clone(New);
-
- // Apply the type to the root...
- NewPat->getTree()->updateNodeType(ResultTy, New->getName());
-
- // Infer types...
- NewPat->InferAllTypes();
-
- // Make sure everything is good to go now...
- if (!NewPat->isResolved())
- NewPat->error("Instantiating nonterminal did not resolve all types!");
-
- // Add the pattern to the patterns map, add the record to the RecordKeeper,
- // return the new record.
- Patterns[New] = NewPat;
- Records.addDef(New);
- return Slot = New;
-}
-
-// CalculateComputableValues - Fill in the ComputableValues map through
-// analysis of the patterns we are playing with.
-void InstrSelectorEmitter::CalculateComputableValues() {
- // Loop over all of the patterns, adding them to the ComputableValues map
- for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
- E = Patterns.end(); I != E; ++I)
- if (I->second->isResolved()) {
- // We don't want to add patterns like R32 = R32. This is a hack working
- // around a special case of a general problem, but for now we explicitly
- // forbid these patterns. They can never match anyway.
- Pattern *P = I->second;
- if (!P->getResult() || !P->getTree()->isLeaf() ||
- P->getResult() != P->getTree()->getValueRecord())
- ComputableValues.addPattern(P);
- }
-}
-
-#if 0
-// MoveIdenticalPatterns - Given a tree pattern 'P', move all of the tree
-// patterns which have the same top-level structure as P from the 'From' list to
-// the 'To' list.
-static void MoveIdenticalPatterns(TreePatternNode *P,
- std::vector<std::pair<Pattern*, TreePatternNode*> > &From,
- std::vector<std::pair<Pattern*, TreePatternNode*> > &To) {
- assert(!P->isLeaf() && "All leaves are identical!");
-
- const std::vector<TreePatternNode*> &PChildren = P->getChildren();
- for (unsigned i = 0; i != From.size(); ++i) {
- TreePatternNode *N = From[i].second;
- assert(P->getOperator() == N->getOperator() &&"Differing operators?");
- assert(PChildren.size() == N->getChildren().size() &&
- "Nodes with different arity??");
- bool isDifferent = false;
- for (unsigned c = 0, e = PChildren.size(); c != e; ++c) {
- TreePatternNode *PC = PChildren[c];
- TreePatternNode *NC = N->getChild(c);
- if (PC->isLeaf() != NC->isLeaf()) {
- isDifferent = true;
- break;
- }
-
- if (!PC->isLeaf()) {
- if (PC->getOperator() != NC->getOperator()) {
- isDifferent = true;
- break;
- }
- } else { // It's a leaf!
- if (PC->getValueRecord() != NC->getValueRecord()) {
- isDifferent = true;
- break;
- }
- }
- }
- // If it's the same as the reference one, move it over now...
- if (!isDifferent) {
- To.push_back(std::make_pair(From[i].first, N));
- From.erase(From.begin()+i);
- --i; // Don't skip an entry...
- }
- }
-}
-#endif
-
-static std::string getNodeName(Record *R) {
- RecordVal *RV = R->getValue("EnumName");
- if (RV)
- if (Init *I = RV->getValue())
- if (StringInit *SI = dynamic_cast<StringInit*>(I))
- return SI->getValue();
- return R->getName();
-}
-
-
-static void EmitPatternPredicates(TreePatternNode *Tree,
- const std::string &VarName, std::ostream &OS){
- OS << " && " << VarName << "->getNodeType() == ISD::"
- << getNodeName(Tree->getOperator());
-
- for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c)
- if (!Tree->getChild(c)->isLeaf())
- EmitPatternPredicates(Tree->getChild(c),
- VarName + "->getUse(" + utostr(c)+")", OS);
-}
-
-static void EmitPatternCosts(TreePatternNode *Tree, const std::string &VarName,
- std::ostream &OS) {
- for (unsigned c = 0, e = Tree->getNumChildren(); c != e; ++c)
- if (Tree->getChild(c)->isLeaf()) {
- OS << " + Match_"
- << Pattern::getSlotName(Tree->getChild(c)->getValueRecord()) << "("
- << VarName << "->getUse(" << c << "))";
- } else {
- EmitPatternCosts(Tree->getChild(c),
- VarName + "->getUse(" + utostr(c) + ")", OS);
- }
-}
-
-
-// EmitMatchCosters - Given a list of patterns, which all have the same root
-// pattern operator, emit an efficient decision tree to decide which one to
-// pick. This is structured this way to avoid reevaluations of non-obvious
-// subexpressions.
-void InstrSelectorEmitter::EmitMatchCosters(std::ostream &OS,
- const std::vector<std::pair<Pattern*, TreePatternNode*> > &Patterns,
- const std::string &VarPrefix,
- unsigned IndentAmt) {
- assert(!Patterns.empty() && "No patterns to emit matchers for!");
- std::string Indent(IndentAmt, ' ');
-
- // Load all of the operands of the root node into scalars for fast access
- const NodeType &ONT = getNodeType(Patterns[0].second->getOperator());
- for (unsigned i = 0, e = ONT.ArgTypes.size(); i != e; ++i)
- OS << Indent << "SelectionDAGNode *" << VarPrefix << "_Op" << i
- << " = N->getUse(" << i << ");\n";
-
- // Compute the costs of computing the various nonterminals/registers, which
- // are directly used at this level.
- OS << "\n" << Indent << "// Operand matching costs...\n";
- std::set<std::string> ComputedValues; // Avoid duplicate computations...
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
- TreePatternNode *NParent = Patterns[i].second;
- for (unsigned c = 0, e = NParent->getNumChildren(); c != e; ++c) {
- TreePatternNode *N = NParent->getChild(c);
- if (N->isLeaf()) {
- Record *VR = N->getValueRecord();
- const std::string &LeafName = VR->getName();
- std::string OpName = VarPrefix + "_Op" + utostr(c);
- std::string ValName = OpName + "_" + LeafName + "_Cost";
- if (!ComputedValues.count(ValName)) {
- OS << Indent << "unsigned " << ValName << " = Match_"
- << Pattern::getSlotName(VR) << "(" << OpName << ");\n";
- ComputedValues.insert(ValName);
- }
- }
- }
- }
- OS << "\n";
-
-
- std::string LocCostName = VarPrefix + "_Cost";
- OS << Indent << "unsigned " << LocCostName << "Min = ~0U >> 1;\n"
- << Indent << "unsigned " << VarPrefix << "_PatternMin = NoMatchPattern;\n";
-
-#if 0
- // Separate out all of the patterns into groups based on what their top-level
- // signature looks like...
- std::vector<std::pair<Pattern*, TreePatternNode*> > PatternsLeft(Patterns);
- while (!PatternsLeft.empty()) {
- // Process all of the patterns that have the same signature as the last
- // element...
- std::vector<std::pair<Pattern*, TreePatternNode*> > Group;
- MoveIdenticalPatterns(PatternsLeft.back().second, PatternsLeft, Group);
- assert(!Group.empty() && "Didn't at least pick the source pattern?");
-
-#if 0
- OS << "PROCESSING GROUP:\n";
- for (unsigned i = 0, e = Group.size(); i != e; ++i)
- OS << " " << *Group[i].first << "\n";
- OS << "\n\n";
-#endif
-
- OS << Indent << "{ // ";
-
- if (Group.size() != 1) {
- OS << Group.size() << " size group...\n";
- OS << Indent << " unsigned " << VarPrefix << "_Pattern = NoMatch;\n";
- } else {
- OS << *Group[0].first << "\n";
- OS << Indent << " unsigned " << VarPrefix << "_Pattern = "
- << Group[0].first->getRecord()->getName() << "_Pattern;\n";
- }
-
- OS << Indent << " unsigned " << LocCostName << " = ";
- if (Group.size() == 1)
- OS << "1;\n"; // Add inst cost if at individual rec
- else
- OS << "0;\n";
-
- // Loop over all of the operands, adding in their costs...
- TreePatternNode *N = Group[0].second;
- const std::vector<TreePatternNode*> &Children = N->getChildren();
-
- // If necessary, emit conditionals to check for the appropriate tree
- // structure here...
- for (unsigned i = 0, e = Children.size(); i != e; ++i) {
- TreePatternNode *C = Children[i];
- if (C->isLeaf()) {
- // We already calculated the cost for this leaf, add it in now...
- OS << Indent << " " << LocCostName << " += "
- << VarPrefix << "_Op" << utostr(i) << "_"
- << C->getValueRecord()->getName() << "_Cost;\n";
- } else {
- // If it's not a leaf, we have to check to make sure that the current
- // node has the appropriate structure, then recurse into it...
- OS << Indent << " if (" << VarPrefix << "_Op" << i
- << "->getNodeType() == ISD::" << getNodeName(C->getOperator())
- << ") {\n";
- std::vector<std::pair<Pattern*, TreePatternNode*> > SubPatterns;
- for (unsigned n = 0, e = Group.size(); n != e; ++n)
- SubPatterns.push_back(std::make_pair(Group[n].first,
- Group[n].second->getChild(i)));
- EmitMatchCosters(OS, SubPatterns, VarPrefix+"_Op"+utostr(i),
- IndentAmt + 4);
- OS << Indent << " }\n";
- }
- }
-
- // If the cost for this match is less than the minimum computed cost so far,
- // update the minimum cost and selected pattern.
- OS << Indent << " if (" << LocCostName << " < " << LocCostName << "Min) { "
- << LocCostName << "Min = " << LocCostName << "; " << VarPrefix
- << "_PatternMin = " << VarPrefix << "_Pattern; }\n";
-
- OS << Indent << "}\n";
- }
-#endif
-
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
- Pattern *P = Patterns[i].first;
- TreePatternNode *PTree = P->getTree();
- unsigned PatternCost = 1;
-
- // Check to see if there are any non-leaf elements in the pattern. If so,
- // we need to emit a predicate for this match.
- bool AnyNonLeaf = false;
- for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c)
- if (!PTree->getChild(c)->isLeaf()) {
- AnyNonLeaf = true;
- break;
- }
-
- if (!AnyNonLeaf) { // No predicate necessary, just output a scope...
- OS << " {// " << *P << "\n";
- } else {
- // We need to emit a predicate to make sure the tree pattern matches, do
- // so now...
- OS << " if (1";
- for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c)
- if (!PTree->getChild(c)->isLeaf())
- EmitPatternPredicates(PTree->getChild(c),
- VarPrefix + "_Op" + utostr(c), OS);
-
- OS << ") {\n // " << *P << "\n";
- }
-
- OS << " unsigned PatCost = " << PatternCost;
-
- for (unsigned c = 0, e = PTree->getNumChildren(); c != e; ++c)
- if (PTree->getChild(c)->isLeaf()) {
- OS << " + " << VarPrefix << "_Op" << c << "_"
- << PTree->getChild(c)->getValueRecord()->getName() << "_Cost";
- } else {
- EmitPatternCosts(PTree->getChild(c), VarPrefix + "_Op" + utostr(c), OS);
- }
- OS << ";\n";
- OS << " if (PatCost < MinCost) { MinCost = PatCost; Pattern = "
- << P->getRecord()->getName() << "_Pattern; }\n"
- << " }\n";
- }
-}
-
-static void ReduceAllOperands(TreePatternNode *N, const std::string &Name,
- std::vector<std::pair<TreePatternNode*, std::string> > &Operands,
- std::ostream &OS) {
- if (N->isLeaf()) {
- // If this is a leaf, register or nonterminal reference...
- std::string SlotName = Pattern::getSlotName(N->getValueRecord());
- OS << " ReducedValue_" << SlotName << " *" << Name << "Val = Reduce_"
- << SlotName << "(" << Name << ", MBB);\n";
- Operands.push_back(std::make_pair(N, Name+"Val"));
- } else if (N->getNumChildren() == 0) {
- // This is a reference to a leaf tree node, like an immediate or frame
- // index.
- if (N->getType() != MVT::isVoid) {
- std::string SlotName =
- getNodeName(N->getOperator()) + "_" + getName(N->getType());
- OS << " ReducedValue_" << SlotName << " *" << Name << "Val = "
- << Name << "->getValue<ReducedValue_" << SlotName << ">(ISD::"
- << SlotName << "_Slot);\n";
- Operands.push_back(std::make_pair(N, Name+"Val"));
- }
- } else {
- // Otherwise this is an interior node...
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
- std::string ChildName = Name + "_Op" + utostr(i);
- OS << " SelectionDAGNode *" << ChildName << " = " << Name
- << "->getUse(" << i << ");\n";
- ReduceAllOperands(N->getChild(i), ChildName, Operands, OS);
- }
- }
-}
-
-/// PrintExpanderOperand - Print out Arg as part of the instruction emission
-/// process for the expander pattern P. This argument may be referencing some
-/// values defined in P, or may just be physical register references or
-/// something like that. If PrintArg is true, we are printing out arguments to
-/// the BuildMI call. If it is false, we are printing the result register
-/// name.
-void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
- const std::string &NameVar,
- TreePatternNode *ArgDeclNode,
- Pattern *P, bool PrintArg,
- std::ostream &OS) {
- if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
- Record *Arg = DI->getDef();
- if (!ArgDeclNode->isLeaf() && ArgDeclNode->getNumChildren() != 0)
- P->error("Expected leaf node as argument!");
- Record *ArgDecl = ArgDeclNode->isLeaf() ? ArgDeclNode->getValueRecord() :
- ArgDeclNode->getOperator();
- if (Arg->isSubClassOf("Register")) {
- // This is a physical register reference... make sure that the instruction
- // requested a register!
- if (!ArgDecl->isSubClassOf("RegisterClass"))
- P->error("Argument mismatch for instruction pattern!");
-
- // FIXME: This should check to see if the register is in the specified
- // register class!
- if (PrintArg) OS << ".addReg(";
- OS << getQualifiedName(Arg);
- if (PrintArg) OS << ")";
- return;
- } else if (Arg->isSubClassOf("RegisterClass")) {
- // If this is a symbolic register class reference, we must be using a
- // named value.
- if (NameVar.empty()) P->error("Did not specify WHICH register to pass!");
- if (Arg != ArgDecl) P->error("Instruction pattern mismatch!");
-
- if (PrintArg) OS << ".addReg(";
- OS << NameVar;
- if (PrintArg) OS << ")";
- return;
- } else if (Arg->getName() == "frameidx") {
- if (!PrintArg) P->error("Cannot define a new frameidx value!");
- OS << ".addFrameIndex(" << NameVar << ")";
- return;
- } else if (Arg->getName() == "basicblock") {
- if (!PrintArg) P->error("Cannot define a new basicblock value!");
- OS << ".addMBB(" << NameVar << ")";
- return;
- }
- P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
- } else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
- if (!NameVar.empty())
- P->error("Illegal to specify a name for a constant initializer arg!");
-
- // Hack this check to allow R32 values with 0 as the initializer for memory
- // references... FIXME!
- if (ArgDeclNode->isLeaf() && II->getValue() == 0 &&
- ArgDeclNode->getValueRecord()->getName() == "R32") {
- OS << ".addReg(0)";
- } else {
- if (ArgDeclNode->isLeaf() || ArgDeclNode->getOperator()->getName()!="imm")
- P->error("Illegal immediate int value '" + itostr(II->getValue()) +
- "' operand!");
- OS << ".addZImm(" << II->getValue() << ")";
- }
- return;
- }
- P->error("Unknown operand type to expander!");
-}
-
-static std::string getArgName(Pattern *P, const std::string &ArgName,
- const std::vector<std::pair<TreePatternNode*, std::string> > &Operands) {
- assert(P->getNumArgs() == Operands.size() &&"Argument computation mismatch!");
- if (ArgName.empty()) return "";
-
- for (unsigned i = 0, e = P->getNumArgs(); i != e; ++i)
- if (P->getArgName(i) == ArgName)
- return Operands[i].second + "->Val";
-
- if (ArgName == P->getResultName())
- return "NewReg";
- P->error("Pattern does not define a value named $" + ArgName + "!");
- return "";
-}
-
-
-void InstrSelectorEmitter::run(std::ostream &OS) {
- // Type-check all of the node types to ensure we "understand" them.
- ReadNodeTypes();
-
- // Read in all of the nonterminals, instructions, and expanders...
- ReadNonterminals();
- ReadInstructionPatterns();
- ReadExpanderPatterns();
-
- // Instantiate any unresolved nonterminals with information from the context
- // that they are used in.
- InstantiateNonterminals();
-
- // Clear InstantiatedNTs, we don't need it anymore...
- InstantiatedNTs.clear();
-
- DEBUG(std::cerr << "Patterns acquired:\n");
- for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
- E = Patterns.end(); I != E; ++I)
- if (I->second->isResolved())
- DEBUG(std::cerr << " " << *I->second << "\n");
-
- CalculateComputableValues();
-
- EmitSourceFileHeader("Instruction Selector for the " + Target.getName() +
- " target", OS);
- OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n";
-
- // Output the slot number enums...
- OS << "\nenum { // Slot numbers...\n"
- << " LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n";
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I)
- OS << " " << I->first << "_Slot,\n";
- OS << " NumSlots\n};\n\n// Reduction value typedefs...\n";
-
- // Output the reduction value typedefs...
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I) {
-
- OS << "typedef ReducedValue<unsigned, " << I->first
- << "_Slot> ReducedValue_" << I->first << ";\n";
- }
-
- // Output the pattern enums...
- OS << "\n\n"
- << "enum { // Patterns...\n"
- << " NotComputed = 0,\n"
- << " NoMatchPattern, \n";
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I) {
- OS << " // " << I->first << " patterns...\n";
- for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
- E = I->second.end(); J != E; ++J)
- for (unsigned i = 0, e = J->second.size(); i != e; ++i)
- OS << " " << J->second[i]->getRecord()->getName() << "_Pattern,\n";
- }
- OS << "};\n\n";
-
- //===--------------------------------------------------------------------===//
- // Emit the class definition...
- //
- OS << "namespace {\n"
- << " class " << Target.getName() << "ISel {\n"
- << " SelectionDAG &DAG;\n"
- << " public:\n"
- << " X86ISel(SelectionDAG &D) : DAG(D) {}\n"
- << " void generateCode();\n"
- << " private:\n"
- << " unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n"
- << " return DAG.getMachineFunction().getSSARegMap()->createVirt"
- "ualRegister(RC);\n"
- << " }\n\n"
- << " // DAG matching methods for classes... all of these methods"
- " return the cost\n"
- << " // of producing a value of the specified class and type, which"
- " also gets\n"
- << " // added to the DAG node.\n";
-
- // Output all of the matching prototypes for slots...
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I)
- OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n";
- OS << "\n // DAG matching methods for DAG nodes...\n";
-
- // Output all of the matching prototypes for slot/node pairs
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I)
- for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
- E = I->second.end(); J != E; ++J)
- OS << " unsigned Match_" << I->first << "_" << getNodeName(J->first)
- << "(SelectionDAGNode *N);\n";
-
- // Output all of the dag reduction methods prototypes...
- OS << "\n // DAG reduction methods...\n";
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I)
- OS << " ReducedValue_" << I->first << " *Reduce_" << I->first
- << "(SelectionDAGNode *N,\n" << std::string(27+2*I->first.size(), ' ')
- << "MachineBasicBlock *MBB);\n";
- OS << " };\n}\n\n";
-
- // Emit the generateCode entry-point...
- OS << "void X86ISel::generateCode() {\n"
- << " SelectionDAGNode *Root = DAG.getRoot();\n"
- << " assert(Root->getValueType() == MVT::isVoid && "
- "\"Root of DAG produces value??\");\n\n"
- << " std::cerr << \"\\n\";\n"
- << " unsigned Cost = Match_Void_void(Root);\n"
- << " if (Cost >= ~0U >> 1) {\n"
- << " std::cerr << \"Match failed!\\n\";\n"
- << " Root->dump();\n"
- << " abort();\n"
- << " }\n\n"
- << " std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n"
- << " Reduce_Void_void(Root, 0);\n"
- << "}\n\n"
- << "//===" << std::string(70, '-') << "===//\n"
- << "// Matching methods...\n"
- << "//\n\n";
-
- //===--------------------------------------------------------------------===//
- // Emit all of the matcher methods...
- //
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I) {
- const std::string &SlotName = I->first;
- OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName
- << "(SelectionDAGNode *N) {\n"
- << " assert(N->getValueType() == MVT::"
- << getEnumName((*I->second.begin()).second[0]->getTree()->getType())
- << ");\n" << " // If we already have a cost available for " << SlotName
- << " use it!\n"
- << " if (N->getPatternFor(" << SlotName << "_Slot))\n"
- << " return N->getCostFor(" << SlotName << "_Slot);\n\n"
- << " unsigned Cost;\n"
- << " switch (N->getNodeType()) {\n"
- << " default: Cost = ~0U >> 1; // Match failed\n"
- << " N->setPatternCostFor(" << SlotName << "_Slot, NoMatchPattern, Cost, NumSlots);\n"
- << " break;\n";
-
- for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
- E = I->second.end(); J != E; ++J)
- if (!J->first->isSubClassOf("Nonterminal"))
- OS << " case ISD::" << getNodeName(J->first) << ":\tCost = Match_"
- << SlotName << "_" << getNodeName(J->first) << "(N); break;\n";
- OS << " }\n"; // End of the switch statement
-
- // Emit any patterns which have a nonterminal leaf as the RHS. These may
- // match multiple root nodes, so they cannot be handled with the switch...
- for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
- E = I->second.end(); J != E; ++J)
- if (J->first->isSubClassOf("Nonterminal")) {
- OS << " unsigned " << J->first->getName() << "_Cost = Match_"
- << getNodeName(J->first) << "(N);\n"
- << " if (" << getNodeName(J->first) << "_Cost < Cost) Cost = "
- << getNodeName(J->first) << "_Cost;\n";
- }
-
- OS << " return Cost;\n}\n\n";
-
- for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
- E = I->second.end(); J != E; ++J) {
- Record *Operator = J->first;
- bool isNonterm = Operator->isSubClassOf("Nonterminal");
- if (!isNonterm) {
- OS << "unsigned " << Target.getName() << "ISel::Match_";
- if (!isNonterm) OS << SlotName << "_";
- OS << getNodeName(Operator) << "(SelectionDAGNode *N) {\n"
- << " unsigned Pattern = NoMatchPattern;\n"
- << " unsigned MinCost = ~0U >> 1;\n";
-
- std::vector<std::pair<Pattern*, TreePatternNode*> > Patterns;
- for (unsigned i = 0, e = J->second.size(); i != e; ++i)
- Patterns.push_back(std::make_pair(J->second[i],
- J->second[i]->getTree()));
- EmitMatchCosters(OS, Patterns, "N", 2);
-
- OS << "\n N->setPatternCostFor(" << SlotName
- << "_Slot, Pattern, MinCost, NumSlots);\n"
- << " return MinCost;\n"
- << "}\n";
- }
- }
- }
-
- //===--------------------------------------------------------------------===//
- // Emit all of the reducer methods...
- //
- OS << "\n\n//===" << std::string(70, '-') << "===//\n"
- << "// Reducer methods...\n"
- << "//\n";
-
- for (PatternOrganizer::iterator I = ComputableValues.begin(),
- E = ComputableValues.end(); I != E; ++I) {
- const std::string &SlotName = I->first;
- OS << "ReducedValue_" << SlotName << " *" << Target.getName()
- << "ISel::Reduce_" << SlotName
- << "(SelectionDAGNode *N, MachineBasicBlock *MBB) {\n"
- << " ReducedValue_" << SlotName << " *Val = N->hasValue<ReducedValue_"
- << SlotName << ">(" << SlotName << "_Slot);\n"
- << " if (Val) return Val;\n"
- << " if (N->getBB()) MBB = N->getBB();\n\n"
- << " switch (N->getPatternFor(" << SlotName << "_Slot)) {\n";
-
- // Loop over all of the patterns that can produce a value for this slot...
- PatternOrganizer::NodesForSlot &NodesForSlot = I->second;
- for (PatternOrganizer::NodesForSlot::iterator J = NodesForSlot.begin(),
- E = NodesForSlot.end(); J != E; ++J)
- for (unsigned i = 0, e = J->second.size(); i != e; ++i) {
- Pattern *P = J->second[i];
- OS << " case " << P->getRecord()->getName() << "_Pattern: {\n"
- << " // " << *P << "\n";
- // Loop over the operands, reducing them...
- std::vector<std::pair<TreePatternNode*, std::string> > Operands;
- ReduceAllOperands(P->getTree(), "N", Operands, OS);
-
- // Now that we have reduced all of our operands, and have the values
- // that reduction produces, perform the reduction action for this
- // pattern.
- std::string Result;
-
- // If the pattern produces a register result, generate a new register
- // now.
- if (Record *R = P->getResult()) {
- assert(R->isSubClassOf("RegisterClass") &&
- "Only handle register class results so far!");
- OS << " unsigned NewReg = makeAnotherReg(" << Target.getName()
- << "::" << R->getName() << "RegisterClass);\n";
- Result = "NewReg";
- DEBUG(OS << " std::cerr << \"%reg\" << NewReg << \" =\t\";\n");
- } else {
- DEBUG(OS << " std::cerr << \"\t\t\";\n");
- Result = "0";
- }
-
- // Print out the pattern that matched...
- DEBUG(OS << " std::cerr << \" " << P->getRecord()->getName() <<'"');
- DEBUG(for (unsigned i = 0, e = Operands.size(); i != e; ++i)
- if (Operands[i].first->isLeaf()) {
- Record *RV = Operands[i].first->getValueRecord();
- assert(RV->isSubClassOf("RegisterClass") &&
- "Only handles registers here so far!");
- OS << " << \" %reg\" << " << Operands[i].second
- << "->Val";
- } else {
- OS << " << ' ' << " << Operands[i].second
- << "->Val";
- });
- DEBUG(OS << " << \"\\n\";\n");
-
- // Generate the reduction code appropriate to the particular type of
- // pattern that this is...
- switch (P->getPatternType()) {
- case Pattern::Instruction:
- // Instruction patterns just emit a single MachineInstr, using BuildMI
- OS << " BuildMI(MBB, " << Target.getName() << "::"
- << P->getRecord()->getName() << ", " << Operands.size();
- if (P->getResult()) OS << ", NewReg";
- OS << ")";
-
- for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
- TreePatternNode *Op = Operands[i].first;
- if (Op->isLeaf()) {
- Record *RV = Op->getValueRecord();
- assert(RV->isSubClassOf("RegisterClass") &&
- "Only handles registers here so far!");
- OS << ".addReg(" << Operands[i].second << "->Val)";
- } else if (Op->getOperator()->getName() == "imm") {
- OS << ".addZImm(" << Operands[i].second << "->Val)";
- } else if (Op->getOperator()->getName() == "basicblock") {
- OS << ".addMBB(" << Operands[i].second << "->Val)";
- } else {
- assert(0 && "Unknown value type!");
- }
- }
- OS << ";\n";
- break;
- case Pattern::Expander: {
- // Expander patterns emit one machine instr for each instruction in
- // the list of instructions expanded to.
- ListInit *Insts = P->getRecord()->getValueAsListInit("Result");
- for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) {
- DagInit *DIInst = dynamic_cast<DagInit*>(Insts->getElement(IN));
- if (!DIInst) P->error("Result list must contain instructions!");
- Record *InstRec = DIInst->getNodeType();
- Pattern *InstPat = getPattern(InstRec);
- if (!InstPat || InstPat->getPatternType() != Pattern::Instruction)
- P->error("Instruction list must contain Instruction patterns!");
-
- bool hasResult = InstPat->getResult() != 0;
- if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) {
- P->error("Incorrect number of arguments specified for inst '" +
- InstPat->getRecord()->getName() + "' in result list!");
- }
-
- // Start emission of the instruction...
- OS << " BuildMI(MBB, " << Target.getName() << "::"
- << InstRec->getName() << ", "
- << DIInst->getNumArgs()-hasResult;
- // Emit register result if necessary..
- if (hasResult) {
- std::string ArgNameVal =
- getArgName(P, DIInst->getArgName(0), Operands);
- PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
- InstPat->getResultNode(), P, false,
- OS << ", ");
- }
- OS << ")";
-
- for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){
- std::string ArgNameVal =
- getArgName(P, DIInst->getArgName(i), Operands);
-
- PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
- InstPat->getArg(i-hasResult), P, true, OS);
- }
-
- OS << ";\n";
- }
- break;
- }
- default:
- assert(0 && "Reduction of this type of pattern not implemented!");
- }
-
- OS << " Val = new ReducedValue_" << SlotName << "(" << Result<<");\n"
- << " break;\n"
- << " }\n";
- }
-
-
- OS << " default: assert(0 && \"Unknown " << SlotName << " pattern!\");\n"
- << " }\n\n N->addValue(Val); // Do not ever recalculate this\n"
- << " return Val;\n}\n\n";
- }
-}
-
diff --git a/support/tools/TableGen/InstrSelectorEmitter.h b/support/tools/TableGen/InstrSelectorEmitter.h
deleted file mode 100644
index 922aa79dfa..0000000000
--- a/support/tools/TableGen/InstrSelectorEmitter.h
+++ /dev/null
@@ -1,387 +0,0 @@
-//===- InstrInfoEmitter.h - Generate a Instruction Set Desc. ----*- C++ -*-===//
-//
-// This tablegen backend is responsible for emitting a description of the target
-// instruction set for the code generator.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef INSTRSELECTOR_EMITTER_H
-#define INSTRSELECTOR_EMITTER_H
-
-#include "TableGenBackend.h"
-#include "CodeGenWrappers.h"
-#include <vector>
-#include <map>
-#include <cassert>
-
-class DagInit;
-class Init;
-class InstrSelectorEmitter;
-
-/// NodeType - Represents Information parsed from the DagNode entries.
-///
-struct NodeType {
- enum ArgResultTypes {
- Any, // No constraint on type
- Val, // A non-void type
- Arg0, // Value matches the type of Arg0
- Arg1, // Value matches the type of Arg1
- Ptr, // Tree node is the type of the target pointer
- I8, // Always bool
- Void, // Tree node always returns void
- };
-
- ArgResultTypes ResultType;
- std::vector<ArgResultTypes> ArgTypes;
-
- NodeType(ArgResultTypes RT, std::vector<ArgResultTypes> &AT) : ResultType(RT){
- AT.swap(ArgTypes);
- }
-
- NodeType() : ResultType(Val) {}
- NodeType(const NodeType &N) : ResultType(N.ResultType), ArgTypes(N.ArgTypes){}
-
- static ArgResultTypes Translate(Record *R);
-};
-
-
-
-/// TreePatternNode - Represent a node of the tree patterns.
-///
-class TreePatternNode {
- /// Operator - The operation that this node represents... this is null if this
- /// is a leaf.
- Record *Operator;
-
- /// Type - The inferred value type...
- ///
- MVT::ValueType Type;
-
- /// Children - If this is not a leaf (Operator != 0), this is the subtrees
- /// that we contain.
- std::vector<std::pair<TreePatternNode*, std::string> > Children;
-
- /// Value - If this node is a leaf, this indicates what the thing is.
- ///
- Init *Value;
-public:
- TreePatternNode(Record *o, const std::vector<std::pair<TreePatternNode*,
- std::string> > &c)
- : Operator(o), Type(MVT::Other), Children(c), Value(0) {}
- TreePatternNode(Init *V) : Operator(0), Type(MVT::Other), Value(V) {}
-
- Record *getOperator() const {
- assert(Operator && "This is a leaf node!");
- return Operator;
- }
- MVT::ValueType getType() const { return Type; }
- void setType(MVT::ValueType T) { Type = T; }
-
- bool isLeaf() const { return Operator == 0; }
-
- unsigned getNumChildren() const { return Children.size(); }
- TreePatternNode *getChild(unsigned c) const {
- assert(Operator != 0 && "This is a leaf node!");
- assert(c < Children.size() && "Child access out of range!");
- return Children[c].first;
- }
- const std::string &getChildName(unsigned c) const {
- assert(Operator != 0 && "This is a leaf node!");
- assert(c < Children.size() && "Child access out of range!");
- return Children[c].second;
- }
-
- Init *getValue() const {
- assert(Operator == 0 && "This is not a leaf node!");
- return Value;
- }
-
- /// getValueRecord - Returns the value of this tree node as a record. For now
- /// we only allow DefInit's as our leaf values, so this is used.
- Record *getValueRecord() const;
-
- /// clone - Make a copy of this tree and all of its children.
- ///
- TreePatternNode *clone() const;
-
- void dump() const;
-
- /// InstantiateNonterminals - If this pattern refers to any nonterminals which
- /// are not themselves completely resolved, clone the nonterminal and resolve
- /// it with the using context we provide.
- void InstantiateNonterminals(InstrSelectorEmitter &ISE);
-
- /// UpdateNodeType - Set the node type of N to VT if VT contains information.
- /// If N already contains a conflicting type, then throw an exception. This
- /// returns true if any information was updated.
- ///
- bool updateNodeType(MVT::ValueType VT, const std::string &RecName);
-};
-
-std::ostream &operator<<(std::ostream &OS, const TreePatternNode &N);
-
-
-
-/// Pattern - Represent a pattern of one form or another. Currently, three
-/// types of patterns are possible: Instruction's, Nonterminals, and Expanders.
-///
-struct Pattern {
- enum PatternType {
- Nonterminal, Instruction, Expander
- };
-private:
- /// PTy - The type of pattern this is.
- ///
- PatternType PTy;
-
- /// Tree - The tree pattern which corresponds to this pattern. Note that if
- /// there was a (set) node on the outside level that it has been stripped off.
- ///
- TreePatternNode *Tree;
-
- /// Result - If this is an instruction or expander pattern, this is the
- /// register result, specified with a (set) in the pattern.
- ///
- std::string ResultName; // The name of the result value...
- TreePatternNode *ResultNode; // The leaf node for the result register...
-
- /// TheRecord - The actual TableGen record corresponding to this pattern.
- ///
- Record *TheRecord;
-
- /// Resolved - This is true of the pattern is useful in practice. In
- /// particular, some non-terminals will have non-resolvable types. When a
- /// user of the non-terminal is later found, they will have inferred a type
- /// for the result of the non-terminal, which cause a clone of an unresolved
- /// nonterminal to be made which is "resolved".
- ///
- bool Resolved;
-
- /// Args - This is a list of all of the arguments to this pattern, which are
- /// the non-void leaf nodes in this pattern.
- std::vector<std::pair<TreePatternNode*, std::string> > Args;
-
- /// ISE - the instruction selector emitter coordinating this madness.
- ///
- InstrSelectorEmitter &ISE;
-public:
-
- /// Pattern constructor - Parse the specified DagInitializer into the current
- /// record.
- Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
- InstrSelectorEmitter &ise);
-
- /// Pattern - Constructor used for cloning nonterminal patterns
- Pattern(TreePatternNode *tree, Record *rec, bool res,
- InstrSelectorEmitter &ise)
- : PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec),
- Resolved(res), ISE(ise) {
- calculateArgs(Tree, "");
- }
-
- /// getPatternType - Return what flavor of Record this pattern originated from
- ///
- PatternType getPatternType() const { return PTy; }
-
- /// getTree - Return the tree pattern which corresponds to this pattern.
- ///
- TreePatternNode *getTree() const { return Tree; }
-
- Record *getResult() const {
- return ResultNode ? ResultNode->getValueRecord() : 0;
- }
- const std::string &getResultName() const { return ResultName; }
- TreePatternNode *getResultNode() const { return ResultNode; }
-
- /// getRecord - Return the actual TableGen record corresponding to this
- /// pattern.
- ///
- Record *getRecord() const { return TheRecord; }
-
- unsigned getNumArgs() const { return Args.size(); }
- TreePatternNode *getArg(unsigned i) const {
- assert(i < Args.size() && "Argument reference out of range!");
- return Args[i].first;
- }
- Record *getArgRec(unsigned i) const {
- return getArg(i)->getValueRecord();
- }
- Init *getArgVal(unsigned i) const {
- return getArg(i)->getValue();
- }
- const std::string &getArgName(unsigned i) const {
- assert(i < Args.size() && "Argument reference out of range!");
- return Args[i].second;
- }
-
- bool isResolved() const { return Resolved; }
-
- /// InferAllTypes - Runs the type inference engine on the current pattern,
- /// stopping when nothing can be inferred, then updating the Resolved field.
- void InferAllTypes();
-
- /// InstantiateNonterminals - If this pattern refers to any nonterminals which
- /// are not themselves completely resolved, clone the nonterminal and resolve
- /// it with the using context we provide.
- void InstantiateNonterminals() {
- Tree->InstantiateNonterminals(ISE);
- }
-
- /// clone - This method is used to make an exact copy of the current pattern,
- /// then change the "TheRecord" instance variable to the specified record.
- ///
- Pattern *clone(Record *R) const;
-
- /// error - Throw an exception, prefixing it with information about this
- /// pattern.
- void error(const std::string &Msg) const;
-
- /// getSlotName - If this is a leaf node, return the slot name that the
- /// operand will update.
- std::string getSlotName() const;
- static std::string getSlotName(Record *R);
-
- void dump() const;
-
-private:
- void calculateArgs(TreePatternNode *N, const std::string &Name);
- MVT::ValueType getIntrinsicType(Record *R) const;
- TreePatternNode *ParseTreePattern(DagInit *DI);
- bool InferTypes(TreePatternNode *N, bool &MadeChange);
-};
-
-std::ostream &operator<<(std::ostream &OS, const Pattern &P);
-
-
-/// PatternOrganizer - This class represents all of the patterns which are
-/// useful for the instruction selector, neatly catagorized in a hierarchical
-/// structure.
-struct PatternOrganizer {
- /// PatternsForNode - The list of patterns which can produce a value of a
- /// particular slot type, given a particular root node in the tree. All of
- /// the patterns in this vector produce the same value type and have the same
- /// root DAG node.
- typedef std::vector<Pattern*> PatternsForNode;
-
- /// NodesForSlot - This map keeps track of all of the root DAG nodes which can
- /// lead to the production of a value for this slot. All of the patterns in
- /// this data structure produces values of the same slot.
- typedef std::map<Record*, PatternsForNode> NodesForSlot;
-
- /// AllPatterns - This data structure contains all patterns in the instruction
- /// selector.
- std::map<std::string, NodesForSlot> AllPatterns;
-
- // Forwarding functions...
- typedef std::map<std::string, NodesForSlot>::iterator iterator;
- iterator begin() { return AllPatterns.begin(); }
- iterator end() { return AllPatterns.end(); }
-
-
- /// addPattern - Add the specified pattern to the appropriate location in the
- /// collection.
- void addPattern(Pattern *P);
-};
-
-
-/// InstrSelectorEmitter - The top-level class which coordinates construction
-/// and emission of the instruction selector.
-///
-class InstrSelectorEmitter : public TableGenBackend {
- RecordKeeper &Records;
- CodeGenTarget Target;
-
- std::map<Record*, NodeType> NodeTypes;
-
- /// Patterns - a list of all of the patterns defined by the target description
- ///
- std::map<Record*, Pattern*> Patterns;
-
- /// InstantiatedNTs - A data structure to keep track of which nonterminals
- /// have been instantiated already...
- ///
- std::map<std::pair<Pattern*,MVT::ValueType>, Record*> InstantiatedNTs;
-
- /// ComputableValues - This map indicates which patterns can be used to
- /// generate a value that is used by the selector. The keys of this map
- /// implicitly define the values that are used by the selector.
- ///
- PatternOrganizer ComputableValues;
-
-public:
- InstrSelectorEmitter(RecordKeeper &R) : Records(R) {}
-
- // run - Output the instruction set description, returning true on failure.
- void run(std::ostream &OS);
-
- const CodeGenTarget &getTarget() const { return Target; }
- std::map<Record*, NodeType> &getNodeTypes() { return NodeTypes; }
- const NodeType &getNodeType(Record *R) const {
- std::map<Record*, NodeType>::const_iterator I = NodeTypes.find(R);
- assert(I != NodeTypes.end() && "Unknown node type!");
- return I->second;
- }
-
- /// getPattern - return the pattern corresponding to the specified record, or
- /// null if there is none.
- Pattern *getPattern(Record *R) const {
- std::map<Record*, Pattern*>::const_iterator I = Patterns.find(R);
- return I != Patterns.end() ? I->second : 0;
- }
-
- /// ReadNonterminal - This method parses the specified record as a
- /// nonterminal, but only if it hasn't been read in already.
- Pattern *ReadNonterminal(Record *R);
-
- /// InstantiateNonterminal - This method takes the nonterminal specified by
- /// NT, which should not be completely resolved, clones it, applies ResultTy
- /// to its root, then runs the type inference stuff on it. This should
- /// produce a newly resolved nonterminal, which we make a record for and
- /// return. To be extra fancy and efficient, this only makes one clone for
- /// each type it is instantiated with.
- Record *InstantiateNonterminal(Pattern *NT, MVT::ValueType ResultTy);
-
-private:
- // ReadNodeTypes - Read in all of the node types in the current RecordKeeper,
- // turning them into the more accessible NodeTypes data structure.
- void ReadNodeTypes();
-
- // ReadNonTerminals - Read in all nonterminals and incorporate them into our
- // pattern database.
- void ReadNonterminals();
-
- // ReadInstructionPatterns - Read in all subclasses of Instruction, and
- // process those with a useful Pattern field.
- void ReadInstructionPatterns();
-
- // ReadExpanderPatterns - Read in all of the expanded patterns.
- void ReadExpanderPatterns();
-
- // InstantiateNonterminals - Instantiate any unresolved nonterminals with
- // information from the context that they are used in.
- void InstantiateNonterminals();
-
- // CalculateComputableValues - Fill in the ComputableValues map through
- // analysis of the patterns we are playing with.
- void CalculateComputableValues();
-
- // EmitMatchCosters - Given a list of patterns, which all have the same root
- // pattern operator, emit an efficient decision tree to decide which one to
- // pick. This is structured this way to avoid reevaluations of non-obvious
- // subexpressions.
- void EmitMatchCosters(std::ostream &OS,
- const std::vector<std::pair<Pattern*, TreePatternNode*> > &Patterns,
- const std::string &VarPrefix, unsigned Indent);
-
- /// PrintExpanderOperand - Print out Arg as part of the instruction emission
- /// process for the expander pattern P. This argument may be referencing some
- /// values defined in P, or may just be physical register references or
- /// something like that. If PrintArg is true, we are printing out arguments
- /// to the BuildMI call. If it is false, we are printing the result register
- /// name.
- void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
- TreePatternNode *ArgDecl, Pattern *P,
- bool PrintArg, std::ostream &OS);
-};
-
-#endif
diff --git a/support/tools/TableGen/Makefile b/support/tools/TableGen/Makefile
deleted file mode 100644
index b06ca9b7e1..0000000000
--- a/support/tools/TableGen/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-LEVEL = ../../..
-TOOLNAME = tblgen
-USEDLIBS = support.a
-
-.PRECIOUS: FileLexer.cpp FileParser.cpp
-
-include $(LEVEL)/Makefile.common
-
-#
-# Make the source file depend on the header file. In this way, dependencies
-# (which depend on the source file) won't get generated until bison is done
-# generating the C source and header files for the parser.
-#
-FileLexer.cpp: FileParser.h
-
-clean::
- -rm -f FileParser.cpp FileParser.h FileLexer.cpp CommandLine.cpp
- -rm -f FileParser.output
diff --git a/support/tools/TableGen/Record.cpp b/support/tools/TableGen/Record.cpp
deleted file mode 100644
index 384005081e..0000000000
--- a/support/tools/TableGen/Record.cpp
+++ /dev/null
@@ -1,676 +0,0 @@
-//===- Record.cpp - Record implementation ---------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-
-#include "Record.h"
-
-//===----------------------------------------------------------------------===//
-// Type implementations
-//===----------------------------------------------------------------------===//
-
-void RecTy::dump() const { print(std::cerr); }
-
-Init *BitRecTy::convertValue(BitsInit *BI) {
- if (BI->getNumBits() != 1) return 0; // Only accept if just one bit!
- return BI->getBit(0);
-}
-
-bool BitRecTy::baseClassOf(const BitsRecTy *RHS) const {
- return RHS->getNumBits() == 1;
-}
-
-Init *BitRecTy::convertValue(IntInit *II) {
- int Val = II->getValue();
- if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit!
-
- return new BitInit(Val != 0);
-}
-
-Init *BitRecTy::convertValue(TypedInit *VI) {
- if (dynamic_cast<BitRecTy*>(VI->getType()))
- return VI; // Accept variable if it is already of bit type!
- return 0;
-}
-
-Init *BitsRecTy::convertValue(UnsetInit *UI) {
- BitsInit *Ret = new BitsInit(Size);
-
- for (unsigned i = 0; i != Size; ++i)
- Ret->setBit(i, new UnsetInit());
- return Ret;
-}
-
-Init *BitsRecTy::convertValue(BitInit *UI) {
- if (Size != 1) return 0; // Can only convert single bit...
- BitsInit *Ret = new BitsInit(1);
- Ret->setBit(0, UI);
- return Ret;
-}
-
-// convertValue from Int initializer to bits type: Split the integer up into the
-// appropriate bits...
-//
-Init *BitsRecTy::convertValue(IntInit *II) {
- int Value = II->getValue();
- // Make sure this bitfield is large enough to hold the integer value...
- if (Value >= 0) {
- if (Value & ~((1 << Size)-1))
- return 0;
- } else {
- if ((Value >> Size) != -1 || ((Value & (1 << Size-1)) == 0))
- return 0;
- }
-
- BitsInit *Ret = new BitsInit(Size);
- for (unsigned i = 0; i != Size; ++i)
- Ret->setBit(i, new BitInit(Value & (1 << i)));
-
- return Ret;
-}
-
-Init *BitsRecTy::convertValue(BitsInit *BI) {
- // If the number of bits is right, return it. Otherwise we need to expand or
- // truncate...
- if (BI->getNumBits() == Size) return BI;
- return 0;
-}
-
-Init *BitsRecTy::convertValue(TypedInit *VI) {
- if (BitsRecTy *BRT = dynamic_cast<BitsRecTy*>(VI->getType()))
- if (BRT->Size == Size) {
- BitsInit *Ret = new BitsInit(Size);
- for (unsigned i = 0; i != Size; ++i)
- Ret->setBit(i, new VarBitInit(VI, i));
- return Ret;
- }
- if (Size == 1 && dynamic_cast<BitRecTy*>(VI->getType())) {
- BitsInit *Ret = new BitsInit(1);
- Ret->setBit(0, VI);
- return Ret;
- }
-
- return 0;
-}
-
-Init *IntRecTy::convertValue(BitInit *BI) {
- return new IntInit(BI->getValue());
-}
-
-Init *IntRecTy::convertValue(BitsInit *BI) {
- int Result = 0;
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
- if (BitInit *Bit = dynamic_cast<BitInit*>(BI->getBit(i))) {
- Result |= Bit->getValue() << i;
- } else {
- return 0;
- }
- return new IntInit(Result);
-}
-
-Init *IntRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI; // Accept variable if already of the right type!
- return 0;
-}
-
-Init *StringRecTy::convertValue(TypedInit *TI) {
- if (dynamic_cast<StringRecTy*>(TI->getType()))
- return TI; // Accept variable if already of the right type!
- return 0;
-}
-
-void ListRecTy::print(std::ostream &OS) const {
- OS << "list<" << *Ty << ">";
-}
-
-Init *ListRecTy::convertValue(ListInit *LI) {
- std::vector<Init*> Elements;
-
- // Verify that all of the elements of the list are subclasses of the
- // appropriate class!
- for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
- if (Init *CI = LI->getElement(i)->convertInitializerTo(Ty))
- Elements.push_back(CI);
- else
- return 0;
-
- return new ListInit(Elements);
-}
-
-Init *ListRecTy::convertValue(TypedInit *TI) {
- // Ensure that TI is compatible with our class.
- if (ListRecTy *LRT = dynamic_cast<ListRecTy*>(TI->getType()))
- if (LRT->getElementType()->typeIsConvertibleTo(getElementType()))
- return TI;
- return 0;
-}
-
-Init *CodeRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI;
- return 0;
-}
-
-Init *DagRecTy::convertValue(TypedInit *TI) {
- if (TI->getType()->typeIsConvertibleTo(this))
- return TI;
- return 0;
-}
-
-
-void RecordRecTy::print(std::ostream &OS) const {
- OS << Rec->getName();
-}
-
-Init *RecordRecTy::convertValue(DefInit *DI) {
- // Ensure that DI is a subclass of Rec.
- if (!DI->getDef()->isSubClassOf(Rec))
- return 0;
- return DI;
-}
-
-Init *RecordRecTy::convertValue(TypedInit *TI) {
- // Ensure that TI is compatible with Rec.
- if (RecordRecTy *RRT = dynamic_cast<RecordRecTy*>(TI->getType()))
- if (RRT->getRecord()->isSubClassOf(getRecord()) ||
- RRT->getRecord() == getRecord())
- return TI;
- return 0;
-}
-
-bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
- return Rec == RHS->getRecord() || RHS->getRecord()->isSubClassOf(Rec);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Initializer implementations
-//===----------------------------------------------------------------------===//
-
-void Init::dump() const { return print(std::cerr); }
-
-Init *BitsInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
- BitsInit *BI = new BitsInit(Bits.size());
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= getNumBits()) {
- delete BI;
- return 0;
- }
- BI->setBit(i, getBit(Bits[i]));
- }
- return BI;
-}
-
-void BitsInit::print(std::ostream &OS) const {
- //if (!printInHex(OS)) return;
- //if (!printAsVariable(OS)) return;
- //if (!printAsUnset(OS)) return;
-
- OS << "{ ";
- for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
- if (i) OS << ", ";
- if (Init *Bit = getBit(e-i-1))
- Bit->print(OS);
- else
- OS << "*";
- }
- OS << " }";
-}
-
-bool BitsInit::printInHex(std::ostream &OS) const {
- // First, attempt to convert the value into an integer value...
- int Result = 0;
- for (unsigned i = 0, e = getNumBits(); i != e; ++i)
- if (BitInit *Bit = dynamic_cast<BitInit*>(getBit(i))) {
- Result |= Bit->getValue() << i;
- } else {
- return true;
- }
-
- OS << "0x" << std::hex << Result << std::dec;
- return false;
-}
-
-bool BitsInit::printAsVariable(std::ostream &OS) const {
- // Get the variable that we may be set equal to...
- assert(getNumBits() != 0);
- VarBitInit *FirstBit = dynamic_cast<VarBitInit*>(getBit(0));
- if (FirstBit == 0) return true;
- TypedInit *Var = FirstBit->getVariable();
-
- // Check to make sure the types are compatible.
- BitsRecTy *Ty = dynamic_cast<BitsRecTy*>(FirstBit->getVariable()->getType());
- if (Ty == 0) return true;
- if (Ty->getNumBits() != getNumBits()) return true; // Incompatible types!
-
- // Check to make sure all bits are referring to the right bits in the variable
- for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
- VarBitInit *Bit = dynamic_cast<VarBitInit*>(getBit(i));
- if (Bit == 0 || Bit->getVariable() != Var || Bit->getBitNum() != i)
- return true;
- }
-
- Var->print(OS);
- return false;
-}
-
-bool BitsInit::printAsUnset(std::ostream &OS) const {
- for (unsigned i = 0, e = getNumBits(); i != e; ++i)
- if (!dynamic_cast<UnsetInit*>(getBit(i)))
- return true;
- OS << "?";
- return false;
-}
-
-// resolveReferences - If there are any field references that refer to fields
-// that have been filled in, we can propagate the values now.
-//
-Init *BitsInit::resolveReferences(Record &R) {
- bool Changed = false;
- BitsInit *New = new BitsInit(getNumBits());
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- Init *B;
- Init *CurBit = getBit(i);
-
- do {
- B = CurBit;
- CurBit = CurBit->resolveReferences(R);
- Changed |= B != CurBit;
- } while (B != CurBit);
- New->setBit(i, CurBit);
- }
-
- if (Changed)
- return New;
- delete New;
- return this;
-}
-
-Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
- BitsInit *BI = new BitsInit(Bits.size());
-
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= 32) {
- delete BI;
- return 0;
- }
- BI->setBit(i, new BitInit(Value & (1 << Bits[i])));
- }
- return BI;
-}
-
-void ListInit::print(std::ostream &OS) const {
- OS << "[";
- for (unsigned i = 0, e = Values.size(); i != e; ++i) {
- if (i) OS << ", ";
- OS << *Values[i];
- }
- OS << "]";
-}
-
-Init *VarInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
- BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
- if (T == 0) return 0; // Cannot subscript a non-bits variable...
- unsigned NumBits = T->getNumBits();
-
- BitsInit *BI = new BitsInit(Bits.size());
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= NumBits) {
- delete BI;
- return 0;
- }
- BI->setBit(i, new VarBitInit(this, Bits[i]));
- }
- return BI;
-}
-
-Init *VarInit::resolveBitReference(Record &R, unsigned Bit) {
- if (R.isTemplateArg(getName()))
- return this;
-
- RecordVal *RV = R.getValue(getName());
- assert(RV && "Reference to a non-existant variable?");
- assert(dynamic_cast<BitsInit*>(RV->getValue()));
- BitsInit *BI = (BitsInit*)RV->getValue();
-
- assert(Bit < BI->getNumBits() && "Bit reference out of range!");
- Init *B = BI->getBit(Bit);
-
- if (!dynamic_cast<UnsetInit*>(B)) // If the bit is not set...
- return B; // Replace the VarBitInit with it.
- return this;
-}
-
-RecTy *VarInit::getFieldType(const std::string &FieldName) const {
- if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
- if (const RecordVal *RV = RTy->getRecord()->getValue(FieldName))
- return RV->getType();
- return 0;
-}
-
-Init *VarInit::getFieldInit(Record &R, const std::string &FieldName) const {
- if (RecordRecTy *RTy = dynamic_cast<RecordRecTy*>(getType()))
- if (const RecordVal *RV = R.getValue(VarName))
- if (Init *I = RV->getValue()->getFieldInit(R, FieldName))
- return I;
- else
- return 0;
- return 0;
-}
-
-/// resolveReferences - This method is used by classes that refer to other
-/// variables which may not be defined at the time they expression is formed.
-/// If a value is set for the variable later, this method will be called on
-/// users of the value to allow the value to propagate out.
-///
-Init *VarInit::resolveReferences(Record &R) {
- if (RecordVal *Val = R.getValue(VarName))
- if (!dynamic_cast<UnsetInit*>(Val->getValue()))
- return Val->getValue();
- return this;
-}
-
-
-Init *VarBitInit::resolveReferences(Record &R) {
- Init *I = getVariable()->resolveBitReference(R, getBitNum());
- if (I != getVariable())
- return I;
- return this;
-}
-
-RecTy *DefInit::getFieldType(const std::string &FieldName) const {
- if (const RecordVal *RV = Def->getValue(FieldName))
- return RV->getType();
- return 0;
-}
-
-Init *DefInit::getFieldInit(Record &R, const std::string &FieldName) const {
- return Def->getValue(FieldName)->getValue();
-}
-
-
-void DefInit::print(std::ostream &OS) const {
- OS << Def->getName();
-}
-
-Init *FieldInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
- BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
- if (T == 0) return 0; // Cannot subscript a non-bits field...
- unsigned NumBits = T->getNumBits();
-
- BitsInit *BI = new BitsInit(Bits.size());
- for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
- if (Bits[i] >= NumBits) {
- delete BI;
- return 0;
- }
- BI->setBit(i, new VarBitInit(this, Bits[i]));
- }
- return BI;
-}
-
-Init *FieldInit::resolveBitReference(Record &R, unsigned Bit) {
- Init *BitsVal = Rec->getFieldInit(R, FieldName);
- if (BitsVal)
- if (BitsInit *BI = dynamic_cast<BitsInit*>(BitsVal)) {
- assert(Bit < BI->getNumBits() && "Bit reference out of range!");
- Init *B = BI->getBit(Bit);
-
- if (dynamic_cast<BitInit*>(B)) // If the bit is set...
- return B; // Replace the VarBitInit with it.
- }
- return this;
-}
-
-Init *FieldInit::resolveReferences(Record &R) {
- Init *BitsVal = Rec->getFieldInit(R, FieldName);
- if (BitsVal) {
- Init *BVR = BitsVal->resolveReferences(R);
- return BVR->isComplete() ? BVR : this;
- }
- return this;
-}
-
-
-void DagInit::print(std::ostream &OS) const {
- OS << "(" << NodeTypeDef->getName();
- if (Args.size()) {
- OS << " " << *Args[0];
- if (!ArgNames[0].empty()) OS << ":$" << ArgNames[0];
- for (unsigned i = 1, e = Args.size(); i != e; ++i) {
- OS << ", " << *Args[i];
- if (!ArgNames[i].empty()) OS << ":$" << ArgNames[i];
- }
- }
- OS << ")";
-}
-
-
-//===----------------------------------------------------------------------===//
-// Other implementations
-//===----------------------------------------------------------------------===//
-
-RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P)
- : Name(N), Ty(T), Prefix(P) {
- Value = Ty->convertValue(new UnsetInit());
- assert(Value && "Cannot create unset value for current type!");
-}
-
-void RecordVal::dump() const { std::cerr << *this; }
-
-void RecordVal::print(std::ostream &OS, bool PrintSem) const {
- if (getPrefix()) OS << "field ";
- OS << *getType() << " " << getName();
- if (getValue()) {
- OS << " = " << *getValue();
- }
- if (PrintSem) OS << ";\n";
-}
-
-// resolveReferences - If there are any field references that refer to fields
-// that have been filled in, we can propagate the values now.
-//
-void Record::resolveReferences() {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- Values[i].setValue(Values[i].getValue()->resolveReferences(*this));
-}
-
-void Record::dump() const { std::cerr << *this; }
-
-std::ostream &operator<<(std::ostream &OS, const Record &R) {
- OS << R.getName();
-
- const std::vector<std::string> &TArgs = R.getTemplateArgs();
- if (!TArgs.empty()) {
- OS << "<";
- for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
- if (i) OS << ", ";
- const RecordVal *RV = R.getValue(TArgs[i]);
- assert(RV && "Template argument record not found??");
- RV->print(OS, false);
- }
- OS << ">";
- }
-
- OS << " {";
- const std::vector<Record*> &SC = R.getSuperClasses();
- if (!SC.empty()) {
- OS << "\t//";
- for (unsigned i = 0, e = SC.size(); i != e; ++i)
- OS << " " << SC[i]->getName();
- }
- OS << "\n";
-
- const std::vector<RecordVal> &Vals = R.getValues();
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
- OS << Vals[i];
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (!Vals[i].getPrefix() && !R.isTemplateArg(Vals[i].getName()))
- OS << Vals[i];
-
- return OS << "}\n";
-}
-
-/// getValueInit - Return the initializer for a value with the specified name,
-/// or throw an exception if the field does not exist.
-///
-Init *Record::getValueInit(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
- return R->getValue();
-}
-
-
-/// getValueAsString - This method looks up the specified field and returns its
-/// value as a string, throwing an exception if the field does not exist or if
-/// the value is not a string.
-///
-std::string Record::getValueAsString(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (const StringInit *SI = dynamic_cast<const StringInit*>(R->getValue()))
- return SI->getValue();
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a string initializer!";
-}
-
-/// getValueAsBitsInit - This method looks up the specified field and returns
-/// its value as a BitsInit, throwing an exception if the field does not exist
-/// or if the value is not the right type.
-///
-BitsInit *Record::getValueAsBitsInit(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (BitsInit *BI = dynamic_cast<BitsInit*>(R->getValue()))
- return BI;
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a BitsInit initializer!";
-}
-
-/// getValueAsListInit - This method looks up the specified field and returns
-/// its value as a ListInit, throwing an exception if the field does not exist
-/// or if the value is not the right type.
-///
-ListInit *Record::getValueAsListInit(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (ListInit *LI = dynamic_cast<ListInit*>(R->getValue()))
- return LI;
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a list initializer!";
-}
-
-/// getValueAsInt - This method looks up the specified field and returns its
-/// value as an int, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-int Record::getValueAsInt(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (IntInit *II = dynamic_cast<IntInit*>(R->getValue()))
- return II->getValue();
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a list initializer!";
-}
-
-/// getValueAsDef - This method looks up the specified field and returns its
-/// value as a Record, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-Record *Record::getValueAsDef(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (DefInit *DI = dynamic_cast<DefInit*>(R->getValue()))
- return DI->getDef();
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a list initializer!";
-}
-
-/// getValueAsBit - This method looks up the specified field and returns its
-/// value as a bit, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-bool Record::getValueAsBit(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (BitInit *BI = dynamic_cast<BitInit*>(R->getValue()))
- return BI->getValue();
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a bit initializer!";
-}
-
-/// getValueAsDag - This method looks up the specified field and returns its
-/// value as an Dag, throwing an exception if the field does not exist or if
-/// the value is not the right type.
-///
-DagInit *Record::getValueAsDag(const std::string &FieldName) const {
- const RecordVal *R = getValue(FieldName);
- if (R == 0 || R->getValue() == 0)
- throw "Record '" + getName() + "' does not have a field named '" +
- FieldName + "!\n";
-
- if (DagInit *DI = dynamic_cast<DagInit*>(R->getValue()))
- return DI;
- throw "Record '" + getName() + "', field '" + FieldName +
- "' does not have a dag initializer!";
-}
-
-
-void RecordKeeper::dump() const { std::cerr << *this; }
-
-std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK) {
- OS << "------------- Classes -----------------\n";
- const std::map<std::string, Record*> &Classes = RK.getClasses();
- for (std::map<std::string, Record*>::const_iterator I = Classes.begin(),
- E = Classes.end(); I != E; ++I)
- OS << "class " << *I->second;
-
- OS << "------------- Defs -----------------\n";
- const std::map<std::string, Record*> &Defs = RK.getDefs();
- for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
- E = Defs.end(); I != E; ++I)
- OS << "def " << *I->second;
- return OS;
-}
-
-
-/// getAllDerivedDefinitions - This method returns all concrete definitions
-/// that derive from the specified class name. If a class with the specified
-/// name does not exist, an error is printed and true is returned.
-std::vector<Record*>
-RecordKeeper::getAllDerivedDefinitions(const std::string &ClassName) const {
- Record *Class = Records.getClass(ClassName);
- if (!Class)
- throw "ERROR: Couldn't find the '" + ClassName + "' class!\n";
-
- std::vector<Record*> Defs;
- for (std::map<std::string, Record*>::const_iterator I = getDefs().begin(),
- E = getDefs().end(); I != E; ++I)
- if (I->second->isSubClassOf(Class))
- Defs.push_back(I->second);
-
- return Defs;
-}
diff --git a/support/tools/TableGen/Record.h b/support/tools/TableGen/Record.h
deleted file mode 100644
index 4a2fa057cf..0000000000
--- a/support/tools/TableGen/Record.h
+++ /dev/null
@@ -1,849 +0,0 @@
-//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===//
-//
-// This file defines the main TableGen data structures, including the TableGen
-// types, values, and high-level data structures.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef RECORD_H
-#define RECORD_H
-
-#include <string>
-#include <vector>
-#include <map>
-#include <iostream>
-#include <cassert>
-
-// RecTy subclasses...
-class BitRecTy;
-class BitsRecTy;
-class IntRecTy;
-class StringRecTy;
-class ListRecTy;
-class CodeRecTy;
-class DagRecTy;
-class RecordRecTy;
-
-// Init subclasses...
-class Init;
-class UnsetInit;
-class BitInit;
-class BitsInit;
-class IntInit;
-class StringInit;
-class CodeInit;
-class ListInit;
-class DefInit;
-class DagInit;
-class TypedInit;
-class VarInit;
-class FieldInit;
-class VarBitInit;
-
-// Other classes...
-class Record;
-
-//===----------------------------------------------------------------------===//
-// Type Classes
-//===----------------------------------------------------------------------===//
-
-struct RecTy {
- virtual ~RecTy() {}
-
- virtual void print(std::ostream &OS) const = 0;
- void dump() const;
-
- /// typeIsConvertibleTo - Return true if all values of 'this' type can be
- /// converted to the specified type.
- virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0;
-
-public: // These methods should only be called from subclasses of Init
- virtual Init *convertValue( UnsetInit *UI) { return 0; }
- virtual Init *convertValue( BitInit *BI) { return 0; }
- virtual Init *convertValue( BitsInit *BI) { return 0; }
- virtual Init *convertValue( IntInit *II) { return 0; }
- virtual Init *convertValue(StringInit *SI) { return 0; }
- virtual Init *convertValue( ListInit *LI) { return 0; }
- virtual Init *convertValue( CodeInit *CI) { return 0; }
- virtual Init *convertValue(VarBitInit *VB) { return 0; }
- virtual Init *convertValue( DefInit *DI) { return 0; }
- virtual Init *convertValue( DagInit *DI) { return 0; }
- virtual Init *convertValue( TypedInit *TI) { return 0; }
- virtual Init *convertValue( VarInit *VI) {
- return convertValue((TypedInit*)VI);
- }
- virtual Init *convertValue( FieldInit *FI) {
- return convertValue((TypedInit*)FI);
- }
-
-public: // These methods should only be called by subclasses of RecTy.
- // baseClassOf - These virtual methods should be overloaded to return true iff
- // all values of type 'RHS' can be converted to the 'this' type.
- virtual bool baseClassOf(const BitRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const StringRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const ListRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return false; }
- virtual bool baseClassOf(const RecordRecTy *RHS) const { return false; }
-};
-
-inline std::ostream &operator<<(std::ostream &OS, const RecTy &Ty) {
- Ty.print(OS);
- return OS;
-}
-
-
-/// BitRecTy - 'bit' - Represent a single bit
-///
-struct BitRecTy : public RecTy {
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue(BitInit *BI) { return (Init*)BI; }
- Init *convertValue(BitsInit *BI);
- Init *convertValue(IntInit *II);
- Init *convertValue(TypedInit *VI);
- Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
-
- void print(std::ostream &OS) const { OS << "bit"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const;
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
-};
-
-
-/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
-///
-class BitsRecTy : public RecTy {
- unsigned Size;
-public:
- BitsRecTy(unsigned Sz) : Size(Sz) {}
-
- unsigned getNumBits() const { return Size; }
-
- Init *convertValue(UnsetInit *UI);
- Init *convertValue(BitInit *UI);
- Init *convertValue(BitsInit *BI);
- Init *convertValue(IntInit *II);
- Init *convertValue(TypedInit *VI);
-
- void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const BitRecTy *RHS) const { return Size == 1; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const {
- return RHS->Size == Size;
- }
-};
-
-
-/// IntRecTy - 'int' - Represent an integer value of no particular size
-///
-struct IntRecTy : public RecTy {
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue(IntInit *II) { return (Init*)II; }
- Init *convertValue(BitInit *BI);
- Init *convertValue(BitsInit *BI);
- Init *convertValue(TypedInit *TI);
-
- void print(std::ostream &OS) const { OS << "int"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const BitRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const IntRecTy *RHS) const { return true; }
- virtual bool baseClassOf(const BitsRecTy *RHS) const { return true; }
-};
-
-/// StringRecTy - 'string' - Represent an string value
-///
-struct StringRecTy : public RecTy {
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue(StringInit *SI) { return (Init*)SI; }
- Init *convertValue(TypedInit *TI);
- void print(std::ostream &OS) const { OS << "string"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const StringRecTy *RHS) const { return true; }
-};
-
-/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
-/// the specified type.
-///
-class ListRecTy : public RecTy {
- RecTy *Ty;
-public:
- ListRecTy(RecTy *T) : Ty(T) {}
-
- RecTy *getElementType() const { return Ty; }
-
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue(ListInit *LI);
- Init *convertValue(TypedInit *TI);
-
- void print(std::ostream &OS) const;
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
-
- virtual bool baseClassOf(const ListRecTy *RHS) const {
- return RHS->getElementType()->typeIsConvertibleTo(Ty);
- }
-};
-
-/// CodeRecTy - 'code' - Represent an code fragment, function or method.
-///
-struct CodeRecTy : public RecTy {
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue( CodeInit *CI) { return (Init*)CI; }
- Init *convertValue(TypedInit *TI);
-
- void print(std::ostream &OS) const { OS << "code"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const CodeRecTy *RHS) const { return true; }
-};
-
-/// DagRecTy - 'dag' - Represent a dag fragment
-///
-struct DagRecTy : public RecTy {
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue( DagInit *CI) { return (Init*)CI; }
- Init *convertValue(TypedInit *TI);
-
- void print(std::ostream &OS) const { OS << "dag"; }
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const DagRecTy *RHS) const { return true; }
-};
-
-
-/// RecordRecTy - '<classname>' - Represent an instance of a class, such as:
-/// (R32 X = EAX).
-///
-class RecordRecTy : public RecTy {
- Record *Rec;
-public:
- RecordRecTy(Record *R) : Rec(R) {}
-
- Record *getRecord() const { return Rec; }
-
- Init *convertValue(UnsetInit *UI) { return (Init*)UI; }
- Init *convertValue( DefInit *DI);
- Init *convertValue(TypedInit *VI);
-
- void print(std::ostream &OS) const;
-
- bool typeIsConvertibleTo(const RecTy *RHS) const {
- return RHS->baseClassOf(this);
- }
- virtual bool baseClassOf(const RecordRecTy *RHS) const;
-};
-
-
-
-//===----------------------------------------------------------------------===//
-// Initializer Classes
-//===----------------------------------------------------------------------===//
-
-struct Init {
- virtual ~Init() {}
-
- /// isComplete - This virtual method should be overridden by values that may
- /// not be completely specified yet.
- virtual bool isComplete() const { return true; }
-
- /// print - Print out this value.
- virtual void print(std::ostream &OS) const = 0;
-
- /// dump - Debugging method that may be called through a debugger, just
- /// invokes print on cerr.
- void dump() const;
-
- /// convertInitializerTo - This virtual function is a simple call-back
- /// function that should be overridden to call the appropriate
- /// RecTy::convertValue method.
- ///
- virtual Init *convertInitializerTo(RecTy *Ty) = 0;
-
- /// convertInitializerBitRange - This method is used to implement the bitrange
- /// selection operator. Given an initializer, it selects the specified bits
- /// out, returning them as a new init of bits type. If it is not legal to use
- /// the bit subscript operator on this initializer, return null.
- ///
- virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits) {
- return 0;
- }
-
- /// getFieldType - This method is used to implement the FieldInit class.
- /// Implementors of this method should return the type of the named field if
- /// they are of record type.
- ///
- virtual RecTy *getFieldType(const std::string &FieldName) const { return 0; }
-
- /// getFieldInit - This method complements getFieldType to return the
- /// initializer for the specified field. If getFieldType returns non-null
- /// this method should return non-null, otherwise it returns null.
- ///
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const {
- return 0;
- }
-
- /// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
- /// If a value is set for the variable later, this method will be called on
- /// users of the value to allow the value to propagate out.
- ///
- virtual Init *resolveReferences(Record &R) { return this; }
-};
-
-inline std::ostream &operator<<(std::ostream &OS, const Init &I) {
- I.print(OS); return OS;
-}
-
-
-/// UnsetInit - ? - Represents an uninitialized value
-///
-struct UnsetInit : public Init {
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual bool isComplete() const { return false; }
- virtual void print(std::ostream &OS) const { OS << "?"; }
-};
-
-
-/// BitInit - true/false - Represent a concrete initializer for a bit.
-///
-class BitInit : public Init {
- bool Value;
-public:
- BitInit(bool V) : Value(V) {}
-
- bool getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); }
-};
-
-/// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value.
-/// It contains a vector of bits, whose size is determined by the type.
-///
-class BitsInit : public Init {
- std::vector<Init*> Bits;
-public:
- BitsInit(unsigned Size) : Bits(Size) {}
-
- unsigned getNumBits() const { return Bits.size(); }
-
- Init *getBit(unsigned Bit) const {
- assert(Bit < Bits.size() && "Bit index out of range!");
- return Bits[Bit];
- }
- void setBit(unsigned Bit, Init *V) {
- assert(Bit < Bits.size() && "Bit index out of range!");
- assert(Bits[Bit] == 0 && "Bit already set!");
- Bits[Bit] = V;
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
- virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual bool isComplete() const {
- for (unsigned i = 0; i != getNumBits(); ++i)
- if (!getBit(i)->isComplete()) return false;
- return true;
- }
- virtual void print(std::ostream &OS) const;
-
- virtual Init *resolveReferences(Record &R);
-
- // printXX - Print this bitstream with the specified format, returning true if
- // it is not possible.
- bool printInHex(std::ostream &OS) const;
- bool printAsVariable(std::ostream &OS) const;
- bool printAsUnset(std::ostream &OS) const;
-};
-
-
-/// IntInit - 7 - Represent an initalization by a literal integer value.
-///
-class IntInit : public Init {
- int Value;
-public:
- IntInit(int V) : Value(V) {}
-
- int getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
- virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual void print(std::ostream &OS) const { OS << Value; }
-};
-
-
-/// StringInit - "foo" - Represent an initialization by a string value.
-///
-class StringInit : public Init {
- std::string Value;
-public:
- StringInit(const std::string &V) : Value(V) {}
-
- const std::string &getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; }
-};
-
-/// CodeInit - "[{...}]" - Represent a code fragment.
-///
-class CodeInit : public Init {
- std::string Value;
-public:
- CodeInit(const std::string &V) : Value(V) {}
-
- const std::string getValue() const { return Value; }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; }
-};
-
-/// ListInit - [AL, AH, CL] - Represent a list of defs
-///
-class ListInit : public Init {
- std::vector<Init*> Values;
-public:
- ListInit(std::vector<Init*> &Vs) {
- Values.swap(Vs);
- }
-
- unsigned getSize() const { return Values.size(); }
- Init *getElement(unsigned i) const {
- assert(i < Values.size() && "List element index out of range!");
- return Values[i];
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual void print(std::ostream &OS) const;
-};
-
-
-/// TypedInit - This is the common super-class of types that have a specific,
-/// explicit, type.
-///
-class TypedInit : public Init {
- RecTy *Ty;
-public:
- TypedInit(RecTy *T) : Ty(T) {}
-
- RecTy *getType() const { return Ty; }
-
- /// resolveBitReference - This method is used to implement
- /// VarBitInit::resolveReferences. If the bit is able to be resolved, we
- /// simply return the resolved value, otherwise we return this.
- ///
- virtual Init *resolveBitReference(Record &R, unsigned Bit) = 0;
-};
-
-/// VarInit - 'Opcode' - Represent a reference to an entire variable object.
-///
-class VarInit : public TypedInit {
- std::string VarName;
-public:
- VarInit(const std::string &VN, RecTy *T) : TypedInit(T), VarName(VN) {}
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- const std::string &getName() const { return VarName; }
-
- virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual Init *resolveBitReference(Record &R, unsigned Bit);
-
- virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
-
- /// resolveReferences - This method is used by classes that refer to other
- /// variables which may not be defined at the time they expression is formed.
- /// If a value is set for the variable later, this method will be called on
- /// users of the value to allow the value to propagate out.
- ///
- virtual Init *resolveReferences(Record &R);
-
- virtual void print(std::ostream &OS) const { OS << VarName; }
-};
-
-
-/// VarBitInit - Opcode{0} - Represent access to one bit of a variable or field.
-///
-class VarBitInit : public Init {
- TypedInit *TI;
- unsigned Bit;
-public:
- VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) {
- assert(T->getType() && dynamic_cast<BitsRecTy*>(T->getType()) &&
- ((BitsRecTy*)T->getType())->getNumBits() > B &&
- "Illegal VarBitInit expression!");
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- TypedInit *getVariable() const { return TI; }
- unsigned getBitNum() const { return Bit; }
-
- virtual void print(std::ostream &OS) const {
- TI->print(OS); OS << "{" << Bit << "}";
- }
- virtual Init *resolveReferences(Record &R);
-};
-
-
-/// DefInit - AL - Represent a reference to a 'def' in the description
-///
-class DefInit : public Init {
- Record *Def;
-public:
- DefInit(Record *D) : Def(D) {}
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- Record *getDef() const { return Def; }
-
- //virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual RecTy *getFieldType(const std::string &FieldName) const;
- virtual Init *getFieldInit(Record &R, const std::string &FieldName) const;
-
- virtual void print(std::ostream &OS) const;
-};
-
-
-/// FieldInit - X.Y - Represent a reference to a subfield of a variable
-///
-class FieldInit : public TypedInit {
- Init *Rec; // Record we are referring to
- std::string FieldName; // Field we are accessing
-public:
- FieldInit(Init *R, const std::string &FN)
- : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) {
- assert(getType() && "FieldInit with non-record type!");
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
-
- virtual Init *resolveBitReference(Record &R, unsigned Bit);
-
- virtual Init *resolveReferences(Record &R);
-
- virtual void print(std::ostream &OS) const {
- Rec->print(OS); OS << "." << FieldName;
- }
-};
-
-/// DagInit - (def a, b) - Represent a DAG tree value. DAG inits are required
-/// to have Records for their first value, after that, any legal Init is
-/// possible.
-///
-class DagInit : public Init {
- Record *NodeTypeDef;
- std::vector<Init*> Args;
- std::vector<std::string> ArgNames;
-public:
- DagInit(Record *D, const std::vector<std::pair<Init*, std::string> > &args)
- : NodeTypeDef(D) {
- Args.reserve(args.size());
- ArgNames.reserve(args.size());
- for (unsigned i = 0, e = args.size(); i != e; ++i) {
- Args.push_back(args[i].first);
- ArgNames.push_back(args[i].second);
- }
- }
-
- virtual Init *convertInitializerTo(RecTy *Ty) {
- return Ty->convertValue(this);
- }
-
- Record *getNodeType() const { return NodeTypeDef; }
-
- unsigned getNumArgs() const { return Args.size(); }
- Init *getArg(unsigned Num) const {
- assert(Num < Args.size() && "Arg number out of range!");
- return Args[Num];
- }
- const std::string &getArgName(unsigned Num) const {
- assert(Num < ArgNames.size() && "Arg number out of range!");
- return ArgNames[Num];
- }
-
- void setArg(unsigned Num, Init *I) {
- assert(Num < Args.size() && "Arg number out of range!");
- Args[Num] = I;
- }
-
- virtual void print(std::ostream &OS) const;
-};
-
-//===----------------------------------------------------------------------===//
-// High-Level Classes
-//===----------------------------------------------------------------------===//
-
-class RecordVal {
- std::string Name;
- RecTy *Ty;
- unsigned Prefix;
- Init *Value;
-public:
- RecordVal(const std::string &N, RecTy *T, unsigned P);
-
- const std::string &getName() const { return Name; }
-
- unsigned getPrefix() const { return Prefix; }
- RecTy *getType() const { return Ty; }
- Init *getValue() const { return Value; }
-
- bool setValue(Init *V) {
- if (V) {
- Value = V->convertInitializerTo(Ty);
- return Value == 0;
- }
- Value = 0;
- return false;
- }
-
- void dump() const;
- void print(std::ostream &OS, bool PrintSem = true) const;
-};
-
-inline std::ostream &operator<<(std::ostream &OS, const RecordVal &RV) {
- RV.print(OS << " ");
- return OS;
-}
-
-struct Record {
- const std::string Name;
- std::vector<std::string> TemplateArgs;
- std::vector<RecordVal> Values;
- std::vector<Record*> SuperClasses;
-public:
-
- Record(const std::string &N) : Name(N) {}
- ~Record() {}
-
- const std::string &getName() const { return Name; }
- const std::vector<std::string> &getTemplateArgs() const {
- return TemplateArgs;
- }
- const std::vector<RecordVal> &getValues() const { return Values; }
- const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
-
- bool isTemplateArg(const std::string &Name) const {
- for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
- if (TemplateArgs[i] == Name) return true;
- return false;
- }
-
- const RecordVal *getValue(const std::string &Name) const {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) return &Values[i];
- return 0;
- }
- RecordVal *getValue(const std::string &Name) {
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) return &Values[i];
- return 0;
- }
-
- void addTemplateArg(const std::string &Name) {
- assert(!isTemplateArg(Name) && "Template arg already defined!");
- TemplateArgs.push_back(Name);
- }
-
- void addValue(const RecordVal &RV) {
- assert(getValue(RV.getName()) == 0 && "Value already added!");
- Values.push_back(RV);
- }
-
- void removeValue(const std::string &Name) {
- assert(getValue(Name) && "Cannot remove an entry that does not exist!");
- for (unsigned i = 0, e = Values.size(); i != e; ++i)
- if (Values[i].getName() == Name) {
- Values.erase(Values.begin()+i);
- return;
- }
- assert(0 && "Name does not exist in record!");
- }
-
- bool isSubClassOf(Record *R) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i] == R)
- return true;
- return false;
- }
-
- bool isSubClassOf(const std::string &Name) const {
- for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i)
- if (SuperClasses[i]->getName() == Name)
- return true;
- return false;
- }
-
- void addSuperClass(Record *R) {
- assert(!isSubClassOf(R) && "Already subclassing record!");
- SuperClasses.push_back(R);
- }
-
- // resolveReferences - If there are any field references that refer to fields
- // that have been filled in, we can propagate the values now.
- //
- void resolveReferences();
-
- void dump() const;
-
- //===--------------------------------------------------------------------===//
- // High-level methods useful to tablegen back-ends
- //
-
- /// getValueInit - Return the initializer for a value with the specified name,
- /// or throw an exception if the field does not exist.
- ///
- Init *getValueInit(const std::string &FieldName) const;
-
- /// getValueAsString - This method looks up the specified field and returns
- /// its value as a string, throwing an exception if the field does not exist
- /// or if the value is not a string.
- ///
- std::string getValueAsString(const std::string &FieldName) const;
-
- /// getValueAsBitsInit - This method looks up the specified field and returns
- /// its value as a BitsInit, throwing an exception if the field does not exist
- /// or if the value is not the right type.
- ///
- BitsInit *getValueAsBitsInit(const std::string &FieldName) const;
-
- /// getValueAsListInit - This method looks up the specified field and returns
- /// its value as a ListInit, throwing an exception if the field does not exist
- /// or if the value is not the right type.
- ///
- ListInit *getValueAsListInit(const std::string &FieldName) const;
-
- /// getValueAsDef - This method looks up the specified field and returns its
- /// value as a Record, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- Record *getValueAsDef(const std::string &FieldName) const;
-
- /// getValueAsBit - This method looks up the specified field and returns its
- /// value as a bit, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- bool getValueAsBit(const std::string &FieldName) const;
-
- /// getValueAsInt - This method looks up the specified field and returns its
- /// value as an int, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- int getValueAsInt(const std::string &FieldName) const;
-
- /// getValueAsDag - This method looks up the specified field and returns its
- /// value as an Dag, throwing an exception if the field does not exist or if
- /// the value is not the right type.
- ///
- DagInit *getValueAsDag(const std::string &FieldName) const;
-};
-
-std::ostream &operator<<(std::ostream &OS, const Record &R);
-
-class RecordKeeper {
- std::map<std::string, Record*> Classes, Defs;
-public:
- ~RecordKeeper() {
- for (std::map<std::string, Record*>::iterator I = Classes.begin(),
- E = Classes.end(); I != E; ++I)
- delete I->second;
- for (std::map<std::string, Record*>::iterator I = Defs.begin(),
- E = Defs.end(); I != E; ++I)
- delete I->second;
- }
-
- const std::map<std::string, Record*> &getClasses() const { return Classes; }
- const std::map<std::string, Record*> &getDefs() const { return Defs; }
-
- Record *getClass(const std::string &Name) const {
- std::map<std::string, Record*>::const_iterator I = Classes.find(Name);
- return I == Classes.end() ? 0 : I->second;
- }
- Record *getDef(const std::string &Name) const {
- std::map<std::string, Record*>::const_iterator I = Defs.find(Name);
- return I == Defs.end() ? 0 : I->second;
- }
- void addClass(Record *R) {
- assert(getClass(R->getName()) == 0 && "Class already exists!");
- Classes.insert(std::make_pair(R->getName(), R));
- }
- void addDef(Record *R) {
- assert(getDef(R->getName()) == 0 && "Def already exists!");
- Defs.insert(std::make_pair(R->getName(), R));
- }
-
- //===--------------------------------------------------------------------===//
- // High-level helper methods, useful for tablegen backends...
-
- /// getAllDerivedDefinitions - This method returns all concrete definitions
- /// that derive from the specified class name. If a class with the specified
- /// name does not exist, an exception is thrown.
- std::vector<Record*>
- getAllDerivedDefinitions(const std::string &ClassName) const;
-
-
- void dump() const;
-};
-
-std::ostream &operator<<(std::ostream &OS, const RecordKeeper &RK);
-
-extern RecordKeeper Records;
-
-#endif
diff --git a/support/tools/TableGen/RegisterInfoEmitter.cpp b/support/tools/TableGen/RegisterInfoEmitter.cpp
deleted file mode 100644
index af3efe3a9c..0000000000
--- a/support/tools/TableGen/RegisterInfoEmitter.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-//===- RegisterInfoEmitter.cpp - Generate a Register File Desc. -*- C++ -*-===//
-//
-// This tablegen backend is responsible for emitting a description of a target
-// register file for a code generator. It uses instances of the Register,
-// RegisterAliases, and RegisterClass classes to gather this information.
-//
-//===----------------------------------------------------------------------===//
-
-#include "RegisterInfoEmitter.h"
-#include "CodeGenWrappers.h"
-#include "Record.h"
-#include "Support/StringExtras.h"
-#include <set>
-
-// runEnums - Print out enum values for all of the registers.
-void RegisterInfoEmitter::runEnums(std::ostream &OS) {
- std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
-
- if (Registers.size() == 0)
- throw std::string("No 'Register' subclasses defined!");
-
- std::string Namespace = Registers[0]->getValueAsString("Namespace");
-
- EmitSourceFileHeader("Target Register Enum Values", OS);
-
- if (!Namespace.empty())
- OS << "namespace " << Namespace << " {\n";
- OS << " enum {\n NoRegister,\n";
-
- for (unsigned i = 0, e = Registers.size(); i != e; ++i)
- OS << " " << Registers[i]->getName() << ", \t// " << i+1 << "\n";
-
- OS << " };\n";
- if (!Namespace.empty())
- OS << "}\n";
-}
-
-void RegisterInfoEmitter::runHeader(std::ostream &OS) {
- EmitSourceFileHeader("Register Information Header Fragment", OS);
- const std::string &TargetName = CodeGenTarget().getName();
- std::string ClassName = TargetName + "GenRegisterInfo";
-
- OS << "#include \"llvm/Target/MRegisterInfo.h\"\n\n";
-
- OS << "struct " << ClassName << " : public MRegisterInfo {\n"
- << " " << ClassName
- << "(int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);\n"
- << " const unsigned* getCalleeSaveRegs() const;\n"
- << "};\n\n";
-
- std::vector<Record*> RegisterClasses =
- Records.getAllDerivedDefinitions("RegisterClass");
-
- OS << "namespace " << TargetName << " { // Register classes\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- if (RegisterClasses[i]->getValueAsBit("isDummyClass"))
- continue; // Ignore dummies
-
- const std::string &Name = RegisterClasses[i]->getName();
- if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes
- OS << " extern TargetRegisterClass *" << Name << "RegisterClass;\n";
- }
- OS << "} // end of namespace " << TargetName << "\n\n";
-}
-
-// RegisterInfoEmitter::run - Main register file description emitter.
-//
-void RegisterInfoEmitter::run(std::ostream &OS) {
- EmitSourceFileHeader("Register Information Source Fragment", OS);
-
- // Start out by emitting each of the register classes... to do this, we build
- // a set of registers which belong to a register class, this is to ensure that
- // each register is only in a single register class.
- //
- std::vector<Record*> RegisterClasses =
- Records.getAllDerivedDefinitions("RegisterClass");
-
- std::vector<Record*> Registers = Records.getAllDerivedDefinitions("Register");
-
- std::set<Record*> RegistersFound;
- std::vector<std::string> RegClassNames;
-
- // Loop over all of the register classes... emitting each one.
- OS << "namespace { // Register classes...\n";
-
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- Record *RC = RegisterClasses[rc];
- if (RC->getValueAsBit("isDummyClass")) continue; // Ignore dummies
-
- std::string Name = RC->getName();
- if (Name.size() > 9 && Name[9] == '.') {
- static unsigned AnonCounter = 0;
- Name = "AnonRegClass_"+utostr(AnonCounter++);
- }
-
- RegClassNames.push_back(Name);
-
- // Emit the register list now...
- OS << " // " << Name << " Register Class...\n const unsigned " << Name
- << "[] = {\n ";
- ListInit *RegList = RC->getValueAsListInit("MemberList");
- for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
- DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
- if (!RegDef) throw "Register class member is not a record!";
- Record *Reg = RegDef->getDef();
- if (!Reg->isSubClassOf("Register"))
- throw "Register Class member '" + Reg->getName() +
- " does not derive from the Register class!";
- if (RegistersFound.count(Reg))
- throw "Register '" + Reg->getName() +
- "' included in multiple register classes!";
- RegistersFound.insert(Reg);
- OS << getQualifiedName(Reg) << ", ";
- }
- OS << "\n };\n\n";
-
- OS << " struct " << Name << "Class : public TargetRegisterClass {\n"
- << " " << Name << "Class() : TargetRegisterClass("
- << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment")
- << ", " << Name << ", " << Name << " + " << RegList->getSize()
- << ") {}\n";
-
- if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods")))
- OS << CI->getValue();
- else
- throw "Expected 'code' fragment for 'Methods' value in register class '"+
- RC->getName() + "'!";
-
- OS << " } " << Name << "Instance;\n\n";
- }
-
- OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
- for (unsigned i = 0, e = RegClassNames.size(); i != e; ++i)
- OS << " &" << RegClassNames[i] << "Instance,\n";
- OS << " };\n";
-
- // Emit register class aliases...
- std::vector<Record*> RegisterAliasesRecs =
- Records.getAllDerivedDefinitions("RegisterAliases");
- std::map<Record*, std::set<Record*> > RegisterAliases;
-
- for (unsigned i = 0, e = RegisterAliasesRecs.size(); i != e; ++i) {
- Record *AS = RegisterAliasesRecs[i];
- Record *R = AS->getValueAsDef("Reg");
- ListInit *LI = AS->getValueAsListInit("Aliases");
-
- // Add information that R aliases all of the elements in the list... and
- // that everything in the list aliases R.
- for (unsigned j = 0, e = LI->getSize(); j != e; ++j) {
- DefInit *Reg = dynamic_cast<DefInit*>(LI->getElement(j));
- if (!Reg) throw "ERROR: Alias list element is not a def!";
- if (RegisterAliases[R].count(Reg->getDef()))
- std::cerr << "Warning: register alias between " << getQualifiedName(R)
- << " and " << getQualifiedName(Reg->getDef())
- << " specified multiple times!\n";
- RegisterAliases[R].insert(Reg->getDef());
-
- if (RegisterAliases[Reg->getDef()].count(R))
- std::cerr << "Warning: register alias between " << getQualifiedName(R)
- << " and " << getQualifiedName(Reg->getDef())
- << " specified multiple times!\n";
- RegisterAliases[Reg->getDef()].insert(R);
- }
- }
-
- if (!RegisterAliases.empty())
- OS << "\n\n // Register Alias Sets...\n";
-
- // Loop over all of the registers which have aliases, emitting the alias list
- // to memory.
- for (std::map<Record*, std::set<Record*> >::iterator
- I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) {
- OS << " const unsigned " << I->first->getName() << "_AliasSet[] = { ";
- for (std::set<Record*>::iterator ASI = I->second.begin(),
- E = I->second.end(); ASI != E; ++ASI)
- OS << getQualifiedName(*ASI) << ", ";
- OS << "0 };\n";
- }
-
- OS << "\n const MRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
- OS << " { \"NOREG\",\t0,\t\t0,\t0 },\n";
- // Now that register alias sets have been emitted, emit the register
- // descriptors now.
- for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
- Record *Reg = Registers[i];
- OS << " { \"";
- if (!Reg->getValueAsString("Name").empty())
- OS << Reg->getValueAsString("Name");
- else
- OS << Reg->getName();
- OS << "\",\t";
- if (RegisterAliases.count(Reg))
- OS << Reg->getName() << "_AliasSet,\t";
- else
- OS << "0,\t\t";
- OS << "0, 0 },\n";
- }
- OS << " };\n"; // End of register descriptors...
- OS << "}\n\n"; // End of anonymous namespace...
-
- CodeGenTarget Target;
-
- OS << "namespace " << Target.getName() << " { // Register classes\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- if (RegisterClasses[i]->getValueAsBit("isDummyClass"))
- continue; // Ignore dummies
-
- const std::string &Name = RegisterClasses[i]->getName();
- if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes
- OS << " TargetRegisterClass *" << Name << "RegisterClass = &"
- << Name << "Instance;\n";
- }
- OS << "} // end of namespace " << Target.getName() << "\n\n";
-
-
-
- std::string ClassName = Target.getName() + "GenRegisterInfo";
-
- // Emit the constructor of the class...
- OS << ClassName << "::" << ClassName
- << "(int CallFrameSetupOpcode, int CallFrameDestroyOpcode)\n"
- << " : MRegisterInfo(RegisterDescriptors, " << Registers.size()+1
- << ", RegisterClasses, RegisterClasses+" << RegClassNames.size() << ",\n "
- << " CallFrameSetupOpcode, CallFrameDestroyOpcode) {}\n\n";
-
- // Emit the getCalleeSaveRegs method...
- OS << "const unsigned* " << ClassName << "::getCalleeSaveRegs() const {\n"
- << " static const unsigned CalleeSaveRegs[] = {\n ";
-
- const std::vector<Record*> &CSR = Target.getCalleeSavedRegisters();
- for (unsigned i = 0, e = CSR.size(); i != e; ++i)
- OS << getQualifiedName(CSR[i]) << ", ";
- OS << " 0\n };\n return CalleeSaveRegs;\n}\n\n";
-}
diff --git a/support/tools/TableGen/RegisterInfoEmitter.h b/support/tools/TableGen/RegisterInfoEmitter.h
deleted file mode 100644
index 65a03303cd..0000000000
--- a/support/tools/TableGen/RegisterInfoEmitter.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===- RegisterInfoEmitter.h - Generate a Register File Desc. ---*- C++ -*-===//
-//
-// This tablegen backend is responsible for emitting a description of a target
-// register file for a code generator. It uses instances of the Register,
-// RegisterAliases, and RegisterClass classes to gather this information.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef REGISTER_INFO_EMITTER_H
-#define REGISTER_INFO_EMITTER_H
-
-#include "TableGenBackend.h"
-
-class RegisterInfoEmitter : public TableGenBackend {
- RecordKeeper &Records;
-public:
- RegisterInfoEmitter(RecordKeeper &R) : Records(R) {}
-
- // run - Output the register file description, returning true on failure.
- void run(std::ostream &o);
-
- // runHeader - Emit a header fragment for the register info emitter.
- void runHeader(std::ostream &o);
-
- // runEnums - Print out enum values for all of the registers.
- void runEnums(std::ostream &o);
-};
-
-#endif
diff --git a/support/tools/TableGen/TableGen.cpp b/support/tools/TableGen/TableGen.cpp
deleted file mode 100644
index 971ac9081a..0000000000
--- a/support/tools/TableGen/TableGen.cpp
+++ /dev/null
@@ -1,482 +0,0 @@
-//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
-//
-// TableGen is a tool which can be used to build up a description of something,
-// then invoke one or more "tablegen backends" to emit information about the
-// description in some predefined format. In practice, this is used by the LLVM
-// code generators to automate generation of a code generator through a
-// high-level description of the target.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Record.h"
-#include "Support/CommandLine.h"
-#include "Support/Signals.h"
-#include "Support/FileUtilities.h"
-#include "CodeEmitterGen.h"
-#include "RegisterInfoEmitter.h"
-#include "InstrInfoEmitter.h"
-#include "InstrSelectorEmitter.h"
-#include <algorithm>
-#include <cstdio>
-#include <fstream>
-
-enum ActionType {
- PrintRecords,
- GenEmitter,
- GenRegisterEnums, GenRegister, GenRegisterHeader,
- GenInstrEnums, GenInstrs, GenInstrSelector,
- PrintEnums,
- Parse,
-};
-
-namespace {
- cl::opt<ActionType>
- Action(cl::desc("Action to perform:"),
- cl::values(clEnumValN(PrintRecords, "print-records",
- "Print all records to stdout (default)"),
- clEnumValN(GenEmitter, "gen-emitter",
- "Generate machine code emitter"),
- clEnumValN(GenRegisterEnums, "gen-register-enums",
- "Generate enum values for registers"),
- clEnumValN(GenRegister, "gen-register-desc",
- "Generate a register info description"),
- clEnumValN(GenRegisterHeader, "gen-register-desc-header",
- "Generate a register info description header"),
- clEnumValN(GenInstrEnums, "gen-instr-enums",
- "Generate enum values for instructions"),
- clEnumValN(GenInstrs, "gen-instr-desc",
- "Generate instruction descriptions"),
- clEnumValN(GenInstrSelector, "gen-instr-selector",
- "Generate an instruction selector"),
- clEnumValN(PrintEnums, "print-enums",
- "Print enum values for a class"),
- clEnumValN(Parse, "parse",
- "Interpret machine code (testing only)"),
- 0));
-
- cl::opt<std::string>
- Class("class", cl::desc("Print Enum list for this class"),
- cl::value_desc("class name"));
-
- cl::opt<std::string>
- OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
- cl::init("-"));
-
- cl::opt<std::string>
- InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
-
- cl::opt<std::string>
- IncludeDir("I", cl::desc("Directory of include files"),
- cl::value_desc("directory"), cl::init(""));
-}
-
-
-void ParseFile(const std::string &Filename, const std::string & IncludeDir);
-
-RecordKeeper Records;
-
-static Init *getBit(Record *R, unsigned BitNo) {
- const std::vector<RecordVal> &V = R->getValues();
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (V[i].getPrefix()) {
- assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
- "Can only handle fields of bits<> type!");
- BitsInit *I = (BitsInit*)V[i].getValue();
- if (BitNo < I->getNumBits())
- return I->getBit(BitNo);
- BitNo -= I->getNumBits();
- }
-
- std::cerr << "Cannot find requested bit!\n";
- abort();
- return 0;
-}
-
-static unsigned getNumBits(Record *R) {
- const std::vector<RecordVal> &V = R->getValues();
- unsigned Num = 0;
- for (unsigned i = 0, e = V.size(); i != e; ++i)
- if (V[i].getPrefix()) {
- assert(dynamic_cast<BitsInit*>(V[i].getValue()) &&
- "Can only handle fields of bits<> type!");
- Num += ((BitsInit*)V[i].getValue())->getNumBits();
- }
- return Num;
-}
-
-static bool BitsAreFixed(Record *I1, Record *I2, unsigned BitNo) {
- return dynamic_cast<BitInit*>(getBit(I1, BitNo)) &&
- dynamic_cast<BitInit*>(getBit(I2, BitNo));
-}
-
-static bool BitsAreEqual(Record *I1, Record *I2, unsigned BitNo) {
- BitInit *Bit1 = dynamic_cast<BitInit*>(getBit(I1, BitNo));
- BitInit *Bit2 = dynamic_cast<BitInit*>(getBit(I2, BitNo));
-
- return Bit1 && Bit2 && Bit1->getValue() == Bit2->getValue();
-}
-
-static bool BitRangesEqual(Record *I1, Record *I2,
- unsigned Start, unsigned End) {
- for (unsigned i = Start; i != End; ++i)
- if (!BitsAreEqual(I1, I2, i))
- return false;
- return true;
-}
-
-static unsigned getFirstFixedBit(Record *R, unsigned FirstFixedBit) {
- // Look for the first bit of the pair that are required to be 0 or 1.
- while (!dynamic_cast<BitInit*>(getBit(R, FirstFixedBit)))
- ++FirstFixedBit;
- return FirstFixedBit;
-}
-
-static void FindInstDifferences(Record *I1, Record *I2,
- unsigned FirstFixedBit, unsigned MaxBits,
- unsigned &FirstVaryingBitOverall,
- unsigned &LastFixedBitOverall) {
- // Compare the first instruction to the rest of the instructions, looking for
- // fields that differ.
- //
- unsigned FirstVaryingBit = FirstFixedBit;
- while (FirstVaryingBit < MaxBits && BitsAreEqual(I1, I2, FirstVaryingBit))
- ++FirstVaryingBit;
-
- unsigned LastFixedBit = FirstVaryingBit;
- while (LastFixedBit < MaxBits && BitsAreFixed(I1, I2, LastFixedBit))
- ++LastFixedBit;
-
- if (FirstVaryingBit < FirstVaryingBitOverall)
- FirstVaryingBitOverall = FirstVaryingBit;
- if (LastFixedBit < LastFixedBitOverall)
- LastFixedBitOverall = LastFixedBit;
-}
-
-static bool getBitValue(Record *R, unsigned BitNo) {
- Init *I = getBit(R, BitNo);
- assert(dynamic_cast<BitInit*>(I) && "Bit should be fixed!");
- return ((BitInit*)I)->getValue();
-}
-
-struct BitComparator {
- unsigned BitBegin, BitEnd;
- BitComparator(unsigned B, unsigned E) : BitBegin(B), BitEnd(E) {}
-
- bool operator()(Record *R1, Record *R2) { // Return true if R1 is less than R2
- for (unsigned i = BitBegin; i != BitEnd; ++i) {
- bool V1 = getBitValue(R1, i), V2 = getBitValue(R2, i);
- if (V1 < V2)
- return true;
- else if (V2 < V1)
- return false;
- }
- return false;
- }
-};
-
-static void PrintRange(std::vector<Record*>::iterator I,
- std::vector<Record*>::iterator E) {
- while (I != E) std::cerr << **I++;
-}
-
-static bool getMemoryBit(unsigned char *M, unsigned i) {
- return (M[i/8] & (1 << (i&7))) != 0;
-}
-
-static unsigned getFirstFixedBitInSequence(std::vector<Record*>::iterator IB,
- std::vector<Record*>::iterator IE,
- unsigned StartBit) {
- unsigned FirstFixedBit = 0;
- for (std::vector<Record*>::iterator I = IB; I != IE; ++I)
- FirstFixedBit = std::max(FirstFixedBit, getFirstFixedBit(*I, StartBit));
- return FirstFixedBit;
-}
-
-// ParseMachineCode - Try to split the vector of instructions (which is
-// intentionally taken by-copy) in half, narrowing down the possible
-// instructions that we may have found. Eventually, this list will get pared
-// down to zero or one instruction, in which case we have a match or failure.
-//
-static Record *ParseMachineCode(std::vector<Record*>::iterator InstsB,
- std::vector<Record*>::iterator InstsE,
- unsigned char *M) {
- assert(InstsB != InstsE && "Empty range?");
- if (InstsB+1 == InstsE) {
- // Only a single instruction, see if we match it...
- Record *Inst = *InstsB;
- for (unsigned i = 0, e = getNumBits(Inst); i != e; ++i)
- if (BitInit *BI = dynamic_cast<BitInit*>(getBit(Inst, i)))
- if (getMemoryBit(M, i) != BI->getValue())
- throw std::string("Parse failed!\n");
- return Inst;
- }
-
- unsigned MaxBits = ~0;
- for (std::vector<Record*>::iterator I = InstsB; I != InstsE; ++I)
- MaxBits = std::min(MaxBits, getNumBits(*I));
-
- unsigned FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, 0);
- unsigned FirstVaryingBit, LastFixedBit;
- do {
- FirstVaryingBit = ~0;
- LastFixedBit = ~0;
- for (std::vector<Record*>::iterator I = InstsB+1; I != InstsE; ++I)
- FindInstDifferences(*InstsB, *I, FirstFixedBit, MaxBits,
- FirstVaryingBit, LastFixedBit);
- if (FirstVaryingBit == MaxBits) {
- std::cerr << "ERROR: Could not find bit to distinguish between "
- << "the following entries!\n";
- PrintRange(InstsB, InstsE);
- }
-
-#if 0
- std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
- << ": " << InstsE-InstsB << "\n";
-#endif
-
- FirstFixedBit = getFirstFixedBitInSequence(InstsB, InstsE, FirstVaryingBit);
- } while (FirstVaryingBit != FirstFixedBit);
-
- //std::cerr << "\n\nXXXXXXXXXXXXXXXXX\n\n";
- //PrintRange(InstsB, InstsE);
-
- // Sort the Insts list so that the entries have all of the bits in the range
- // [FirstVaryingBit,LastFixedBit) sorted. These bits are all guaranteed to be
- // set to either 0 or 1 (BitInit values), which simplifies things.
- //
- std::sort(InstsB, InstsE, BitComparator(FirstVaryingBit, LastFixedBit));
-
- // Once the list is sorted by these bits, split the bit list into smaller
- // lists, and recurse on each one.
- //
- std::vector<Record*>::iterator RangeBegin = InstsB;
- Record *Match = 0;
- while (RangeBegin != InstsE) {
- std::vector<Record*>::iterator RangeEnd = RangeBegin+1;
- while (RangeEnd != InstsE &&
- BitRangesEqual(*RangeBegin, *RangeEnd, FirstVaryingBit, LastFixedBit))
- ++RangeEnd;
-
- // We just identified a range of equal instructions. If this range is the
- // input range, we were not able to distinguish between the instructions in
- // the set. Print an error and exit!
- //
- if (RangeBegin == InstsB && RangeEnd == InstsE) {
- std::cerr << "Error: Could not distinguish among the following insts!:\n";
- PrintRange(InstsB, InstsE);
- abort();
- }
-
-#if 0
- std::cerr << "FVB: " << FirstVaryingBit << " - " << LastFixedBit
- << ": [" << RangeEnd-RangeBegin << "] - ";
- for (int i = LastFixedBit-1; i >= (int)FirstVaryingBit; --i)
- std::cerr << (int)((BitInit*)getBit(*RangeBegin, i))->getValue() << " ";
- std::cerr << "\n";
-#endif
-
- if (Record *R = ParseMachineCode(RangeBegin, RangeEnd, M)) {
- if (Match) {
- std::cerr << "Error: Multiple matches found:\n";
- PrintRange(InstsB, InstsE);
- }
-
- assert(Match == 0 && "Multiple matches??");
- Match = R;
- }
- RangeBegin = RangeEnd;
- }
-
- return Match;
-}
-
-static void PrintValue(Record *I, unsigned char *Ptr, const RecordVal &Val) {
- assert(dynamic_cast<BitsInit*>(Val.getValue()) &&
- "Can only handle undefined bits<> types!");
- BitsInit *BI = (BitsInit*)Val.getValue();
- assert(BI->getNumBits() <= 32 && "Can only handle fields up to 32 bits!");
-
- unsigned Value = 0;
- const std::vector<RecordVal> &Vals = I->getValues();
-
- // Start by filling in fixed values...
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
- if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i)))
- Value |= B->getValue() << i;
-
- // Loop over all of the fields in the instruction adding in any
- // contributions to this value (due to bit references).
- //
- unsigned Offset = 0;
- for (unsigned f = 0, e = Vals.size(); f != e; ++f)
- if (Vals[f].getPrefix()) {
- BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
- if (&Vals[f] == &Val) {
- // Read the bits directly now...
- for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
- Value |= getMemoryBit(Ptr, Offset+i) << i;
- break;
- }
-
- // Scan through the field looking for bit initializers of the current
- // variable...
- for (unsigned i = 0, e = FieldInitializer->getNumBits(); i != e; ++i)
- if (VarBitInit *VBI =
- dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
- TypedInit *TI = VBI->getVariable();
- if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
- if (VI->getName() == Val.getName())
- Value |= getMemoryBit(Ptr, Offset+i) << VBI->getBitNum();
- } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
- // FIXME: implement this!
- std::cerr << "FIELD INIT not implemented yet!\n";
- }
- }
- Offset += FieldInitializer->getNumBits();
- }
-
- std::cout << "0x" << std::hex << Value << std::dec;
-}
-
-static void PrintInstruction(Record *I, unsigned char *Ptr) {
- std::cout << "Inst " << getNumBits(I)/8 << " bytes: "
- << "\t" << I->getName() << "\t" << *I->getValue("Name")->getValue()
- << "\t";
-
- const std::vector<RecordVal> &Vals = I->getValues();
- for (unsigned i = 0, e = Vals.size(); i != e; ++i)
- if (!Vals[i].getValue()->isComplete()) {
- std::cout << Vals[i].getName() << "=";
- PrintValue(I, Ptr, Vals[i]);
- std::cout << "\t";
- }
-
- std::cout << "\n";// << *I;
-}
-
-static void ParseMachineCode() {
- // X86 code
- unsigned char Buffer[] = {
- 0x55, // push EBP
- 0x89, 0xE5, // mov EBP, ESP
- //0x83, 0xEC, 0x08, // sub ESP, 0x8
- 0xE8, 1, 2, 3, 4, // call +0x04030201
- 0x89, 0xEC, // mov ESP, EBP
- 0x5D, // pop EBP
- 0xC3, // ret
- 0x90, // nop
- 0xC9, // leave
- 0x89, 0xF6, // mov ESI, ESI
- 0x68, 1, 2, 3, 4, // push 0x04030201
- 0x5e, // pop ESI
- 0xFF, 0xD0, // call EAX
- 0xB8, 1, 2, 3, 4, // mov EAX, 0x04030201
- 0x85, 0xC0, // test EAX, EAX
- 0xF4, // hlt
- };
-
-#if 0
- // SparcV9 code
- unsigned char Buffer[] = { 0xbf, 0xe0, 0x20, 0x1f, 0x1, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0xc1, 0x0, 0x20, 0x1, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1,
- 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
- 0x0, 0x0, 0xaf, 0xe8, 0x20, 0x17
- };
-#endif
-
- std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
-
- unsigned char *BuffPtr = Buffer;
- while (1) {
- Record *R = ParseMachineCode(Insts.begin(), Insts.end(), BuffPtr);
- PrintInstruction(R, BuffPtr);
-
- unsigned Bits = getNumBits(R);
- assert((Bits & 7) == 0 && "Instruction is not an even number of bytes!");
- BuffPtr += Bits/8;
- }
-}
-
-
-int main(int argc, char **argv) {
- cl::ParseCommandLineOptions(argc, argv);
- ParseFile(InputFilename, IncludeDir);
-
- std::ostream *Out = &std::cout;
- if (OutputFilename != "-") {
- // Output to a .tmp file, because we don't actually want to overwrite the
- // output file unless the generated file is different or the specified file
- // does not exist.
- Out = new std::ofstream((OutputFilename+".tmp").c_str());
-
- if (!Out->good()) {
- std::cerr << argv[0] << ": error opening " << OutputFilename << ".tmp!\n";
- return 1;
- }
-
- // Make sure the file gets removed if *gasp* tablegen crashes...
- RemoveFileOnSignal(OutputFilename+".tmp");
- }
-
- try {
- switch (Action) {
- case PrintRecords:
- *Out << Records; // No argument, dump all contents
- break;
- case Parse:
- ParseMachineCode();
- break;
- case GenEmitter:
- CodeEmitterGen(Records).run(*Out);
- break;
-
- case GenRegisterEnums:
- RegisterInfoEmitter(Records).runEnums(*Out);
- break;
- case GenRegister:
- RegisterInfoEmitter(Records).run(*Out);
- break;
- case GenRegisterHeader:
- RegisterInfoEmitter(Records).runHeader(*Out);
- break;
-
- case GenInstrEnums:
- InstrInfoEmitter(Records).runEnums(*Out);
- break;
- case GenInstrs:
- InstrInfoEmitter(Records).run(*Out);
- break;
- case GenInstrSelector:
- InstrSelectorEmitter(Records).run(*Out);
- break;
- case PrintEnums:
- std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
- for (unsigned i = 0, e = Recs.size(); i != e; ++i)
- *Out << Recs[i] << ", ";
- *Out << "\n";
- break;
- }
- } catch (const std::string &Error) {
- std::cerr << Error << "\n";
- if (Out != &std::cout) {
- delete Out; // Close the file
- std::remove(OutputFilename.c_str()); // Remove the file, it's broken
- }
- return 1;
- }
-
- if (Out != &std::cout) {
- delete Out; // Close the file
-
- // Now that we have generated the result, check to see if we either don't
- // have the requested file, or if the requested file is different than the
- // file we generated. If so, move the generated file over the requested
- // file. Otherwise, just remove the file we just generated, so 'make'
- // doesn't try to regenerate tons of dependencies.
- //
- MoveFileOverIfUpdated(OutputFilename+".tmp", OutputFilename);
- }
- return 0;
-}
diff --git a/support/tools/TableGen/TableGenBackend.cpp b/support/tools/TableGen/TableGenBackend.cpp
deleted file mode 100644
index b86ae72ce9..0000000000
--- a/support/tools/TableGen/TableGenBackend.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-//===- TableGenBackend.cpp - Base class for TableGen Backends ---*- C++ -*-===//
-//
-// This file provides useful services for TableGen backends...
-//
-//===----------------------------------------------------------------------===//
-
-#include "TableGenBackend.h"
-#include "Record.h"
-#include <iostream>
-
-void TableGenBackend::EmitSourceFileHeader(const std::string &Desc,
- std::ostream &OS) const {
- OS << "//===- TableGen'erated file -------------------------------------*-"
- " C++ -*-===//\n//\n// " << Desc << "\n//\n// Automatically generate"
- "d file, do not edit!\n//\n//===------------------------------------"
- "----------------------------------===//\n\n";
-}
-
-/// getQualifiedName - Return the name of the specified record, with a
-/// namespace qualifier if the record contains one.
-///
-std::string TableGenBackend::getQualifiedName(Record *R) const {
- std::string Namespace = R->getValueAsString("Namespace");
- if (Namespace.empty()) return R->getName();
- return Namespace + "::" + R->getName();
-}
-
diff --git a/support/tools/TableGen/TableGenBackend.h b/support/tools/TableGen/TableGenBackend.h
deleted file mode 100644
index 8dfbaddad1..0000000000
--- a/support/tools/TableGen/TableGenBackend.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- TableGenBackend.h - Base class for TableGen Backends -----*- C++ -*-===//
-//
-// The TableGenBackend class is provided as a common interface for all TableGen
-// backends. It provides useful services and an standardized interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef TABLEGENBACKEND_H
-#define TABLEGENBACKEND_H
-
-#include <string>
-#include <iosfwd>
-class Record;
-class RecordKeeper;
-
-struct TableGenBackend {
- virtual ~TableGenBackend() {}
-
- // run - All TableGen backends should implement the run method, which should
- // be the main entry point.
- virtual void run(std::ostream &OS) = 0;
-
-
-public: // Useful helper routines...
- /// EmitSourceFileHeader - Output a LLVM style file header to the specified
- /// ostream.
- void EmitSourceFileHeader(const std::string &Desc, std::ostream &OS) const;
-
- /// getQualifiedName - Return the name of the specified record, with a
- /// namespace qualifier if the record contains one.
- std::string getQualifiedName(Record *R) const;
-};
-
-#endif