diff options
author | Chris Lattner <sabre@nondot.org> | 2003-10-05 19:32:12 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-10-05 19:32:12 +0000 |
commit | 5516347535ddf0c27cd207135ebf9ce975f30673 (patch) | |
tree | 4b89b4e60378e5864eaa0c27c1febe8246ee2805 /support/lib/Support | |
parent | 091bbbada30ef4c17e5f66b740adda0acf7cc31a (diff) | |
download | llvm-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
Diffstat (limited to 'support/lib/Support')
-rw-r--r-- | support/lib/Support/Annotation.cpp | 89 | ||||
-rw-r--r-- | support/lib/Support/CommandLine.cpp | 877 | ||||
-rw-r--r-- | support/lib/Support/ConstantRange.cpp | 243 | ||||
-rw-r--r-- | support/lib/Support/Debug.cpp | 57 | ||||
-rw-r--r-- | support/lib/Support/FileUtilities.cpp | 203 | ||||
-rw-r--r-- | support/lib/Support/LeakDetector.cpp | 82 | ||||
-rw-r--r-- | support/lib/Support/Makefile | 5 | ||||
-rw-r--r-- | support/lib/Support/Mangler.cpp | 94 | ||||
-rw-r--r-- | support/lib/Support/PluginLoader.cpp | 31 | ||||
-rw-r--r-- | support/lib/Support/Signals.cpp | 57 | ||||
-rw-r--r-- | support/lib/Support/Statistic.cpp | 99 | ||||
-rw-r--r-- | support/lib/Support/SystemUtils.cpp | 266 | ||||
-rw-r--r-- | support/lib/Support/Timer.cpp | 328 | ||||
-rw-r--r-- | support/lib/Support/ToolRunner.cpp | 374 | ||||
-rw-r--r-- | support/lib/Support/ValueHolder.cpp | 16 |
15 files changed, 0 insertions, 2821 deletions
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)); -} |