summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/utils
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/utils')
-rw-r--r--contrib/llvm/utils/FileCheck/FileCheck.cpp160
-rw-r--r--contrib/llvm/utils/FileUpdate/FileUpdate.cpp24
-rw-r--r--contrib/llvm/utils/Makefile7
-rwxr-xr-xcontrib/llvm/utils/RegressionFinder.pl186
-rw-r--r--contrib/llvm/utils/TableGen/ARMDecoderEmitter.cpp61
-rw-r--r--contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp164
-rw-r--r--contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/CallingConvEmitter.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/ClangAttrEmitter.cpp582
-rw-r--r--contrib/llvm/utils/TableGen/ClangAttrEmitter.h39
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenInstruction.cpp1
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenInstruction.h1
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenIntrinsics.h2
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenRegisters.h32
-rw-r--r--contrib/llvm/utils/TableGen/CodeGenTarget.cpp10
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelEmitter.cpp48
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelEmitter.h2
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp2
-rw-r--r--contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp7
-rw-r--r--contrib/llvm/utils/TableGen/EDEmitter.cpp59
-rw-r--r--contrib/llvm/utils/TableGen/EDEmitter.h3
-rw-r--r--contrib/llvm/utils/TableGen/FastISelEmitter.cpp24
-rw-r--r--contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp1
-rw-r--r--contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp4
-rw-r--r--contrib/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp646
-rw-r--r--contrib/llvm/utils/TableGen/NeonEmitter.cpp11
-rw-r--r--contrib/llvm/utils/TableGen/Record.cpp28
-rw-r--r--contrib/llvm/utils/TableGen/Record.h12
-rw-r--r--contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp30
-rw-r--r--contrib/llvm/utils/TableGen/TableGen.cpp98
-rw-r--r--contrib/llvm/utils/buildit/GNUmakefile16
-rwxr-xr-xcontrib/llvm/utils/buildit/build_llvm33
-rw-r--r--contrib/llvm/utils/lit/lit/ExampleTests/lit.cfg3
-rw-r--r--contrib/llvm/utils/lit/lit/ExampleTests/required-and-missing.c4
-rw-r--r--contrib/llvm/utils/lit/lit/ExampleTests/required-and-present.c2
-rw-r--r--contrib/llvm/utils/lit/lit/TestFormats.py7
-rw-r--r--contrib/llvm/utils/lit/lit/TestRunner.py86
-rw-r--r--contrib/llvm/utils/lit/lit/TestingConfig.py9
-rwxr-xr-xcontrib/llvm/utils/lit/lit/lit.py5
-rw-r--r--contrib/llvm/utils/llvm-lit/Makefile21
-rw-r--r--contrib/llvm/utils/llvm-lit/llvm-lit.in21
-rw-r--r--contrib/llvm/utils/llvm.grm4
-rwxr-xr-xcontrib/llvm/utils/llvmdo4
-rwxr-xr-xcontrib/llvm/utils/mkpatch37
-rwxr-xr-xcontrib/llvm/utils/userloc.pl216
-rw-r--r--contrib/llvm/utils/valgrind/i386-pc-linux-gnu.supp34
-rw-r--r--contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu.supp43
-rw-r--r--contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp23
-rw-r--r--contrib/llvm/utils/vim/llvm.vim10
-rw-r--r--contrib/llvm/utils/vim/vimrc129
51 files changed, 1746 insertions, 1213 deletions
diff --git a/contrib/llvm/utils/FileCheck/FileCheck.cpp b/contrib/llvm/utils/FileCheck/FileCheck.cpp
index e7cd713..cd76d44 100644
--- a/contrib/llvm/utils/FileCheck/FileCheck.cpp
+++ b/contrib/llvm/utils/FileCheck/FileCheck.cpp
@@ -49,32 +49,32 @@ NoCanonicalizeWhiteSpace("strict-whitespace",
class Pattern {
SMLoc PatternLoc;
-
+
/// FixedStr - If non-empty, this pattern is a fixed string match with the
/// specified fixed string.
StringRef FixedStr;
-
+
/// RegEx - If non-empty, this is a regex pattern.
std::string RegExStr;
-
+
/// VariableUses - Entries in this vector map to uses of a variable in the
/// pattern, e.g. "foo[[bar]]baz". In this case, the RegExStr will contain
/// "foobaz" and we'll get an entry in this vector that tells us to insert the
/// value of bar at offset 3.
std::vector<std::pair<StringRef, unsigned> > VariableUses;
-
+
/// VariableDefs - Entries in this vector map to definitions of a variable in
/// the pattern, e.g. "foo[[bar:.*]]baz". In this case, the RegExStr will
/// contain "foo(.*)baz" and VariableDefs will contain the pair "bar",1. The
/// index indicates what parenthesized value captures the variable value.
std::vector<std::pair<StringRef, unsigned> > VariableDefs;
-
+
public:
-
+
Pattern() { }
-
+
bool ParsePattern(StringRef PatternStr, SourceMgr &SM);
-
+
/// Match - Match the pattern string against the input buffer Buffer. This
/// returns the position that is matched or npos if there is no match. If
/// there is a match, the size of the matched string is returned in MatchLen.
@@ -103,19 +103,19 @@ private:
bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
PatternLoc = SMLoc::getFromPointer(PatternStr.data());
-
+
// Ignore trailing whitespace.
while (!PatternStr.empty() &&
(PatternStr.back() == ' ' || PatternStr.back() == '\t'))
PatternStr = PatternStr.substr(0, PatternStr.size()-1);
-
+
// Check that there is something on the line.
if (PatternStr.empty()) {
SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
CheckPrefix+":'", "error");
return true;
}
-
+
// Check to see if this is a fixed string, or if it has regex pieces.
if (PatternStr.size() < 2 ||
(PatternStr.find("{{") == StringRef::npos &&
@@ -123,18 +123,18 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
FixedStr = PatternStr;
return false;
}
-
+
// Paren value #0 is for the fully matched string. Any new parenthesized
// values add from their.
unsigned CurParen = 1;
-
+
// Otherwise, there is at least one regex piece. Build up the regex pattern
// by escaping scary characters in fixed strings, building up one big regex.
while (!PatternStr.empty()) {
// RegEx matches.
if (PatternStr.size() >= 2 &&
PatternStr[0] == '{' && PatternStr[1] == '{') {
-
+
// Otherwise, this is the start of a regex match. Scan for the }}.
size_t End = PatternStr.find("}}");
if (End == StringRef::npos) {
@@ -142,13 +142,13 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
"found start of regex string with no end '}}'", "error");
return true;
}
-
+
if (AddRegExToRegEx(PatternStr.substr(2, End-2), CurParen, SM))
return true;
PatternStr = PatternStr.substr(End+2);
continue;
}
-
+
// Named RegEx matches. These are of two forms: [[foo:.*]] which matches .*
// (or some other regex) and assigns it to the FileCheck variable 'foo'. The
// second form is [[foo]] which is a reference to foo. The variable name
@@ -163,14 +163,14 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
"invalid named regex reference, no ]] found", "error");
return true;
}
-
+
StringRef MatchStr = PatternStr.substr(2, End-2);
PatternStr = PatternStr.substr(End+2);
-
+
// Get the regex name (e.g. "foo").
size_t NameEnd = MatchStr.find(':');
StringRef Name = MatchStr.substr(0, NameEnd);
-
+
if (Name.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
"invalid name in named regex: empty name", "error");
@@ -187,31 +187,31 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM) {
"invalid name in named regex", "error");
return true;
}
-
+
// Name can't start with a digit.
if (isdigit(Name[0])) {
SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
"invalid name in named regex", "error");
return true;
}
-
+
// Handle [[foo]].
if (NameEnd == StringRef::npos) {
VariableUses.push_back(std::make_pair(Name, RegExStr.size()));
continue;
}
-
+
// Handle [[foo:.*]].
VariableDefs.push_back(std::make_pair(Name, CurParen));
RegExStr += '(';
++CurParen;
-
+
if (AddRegExToRegEx(MatchStr.substr(NameEnd+1), CurParen, SM))
return true;
RegExStr += ')';
}
-
+
// Handle fixed string matches.
// Find the end, which is the start of the next regex.
size_t FixedMatchEnd = PatternStr.find("{{");
@@ -260,7 +260,7 @@ bool Pattern::AddRegExToRegEx(StringRef RegexStr, unsigned &CurParen,
"invalid regex: " + Error, "error");
return true;
}
-
+
RegExStr += RegexStr.str();
CurParen += R.getNumMatches();
return false;
@@ -278,14 +278,14 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
}
// Regex match.
-
+
// If there are variable uses, we need to create a temporary string with the
// actual value.
StringRef RegExToMatch = RegExStr;
std::string TmpStr;
if (!VariableUses.empty()) {
TmpStr = RegExStr;
-
+
unsigned InsertOffset = 0;
for (unsigned i = 0, e = VariableUses.size(); i != e; ++i) {
StringMap<StringRef>::iterator it =
@@ -297,33 +297,33 @@ size_t Pattern::Match(StringRef Buffer, size_t &MatchLen,
// Look up the value and escape it so that we can plop it into the regex.
std::string Value;
AddFixedStringToRegEx(it->second, Value);
-
+
// Plop it into the regex at the adjusted offset.
TmpStr.insert(TmpStr.begin()+VariableUses[i].second+InsertOffset,
Value.begin(), Value.end());
InsertOffset += Value.size();
}
-
+
// Match the newly constructed regex.
RegExToMatch = TmpStr;
}
-
-
+
+
SmallVector<StringRef, 4> MatchInfo;
if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo))
return StringRef::npos;
-
+
// Successful regex match.
assert(!MatchInfo.empty() && "Didn't get any match");
StringRef FullMatch = MatchInfo[0];
-
+
// If this defines any variables, remember their values.
for (unsigned i = 0, e = VariableDefs.size(); i != e; ++i) {
assert(VariableDefs[i].second < MatchInfo.size() &&
"Internal paren error");
VariableTable[VariableDefs[i].first] = MatchInfo[VariableDefs[i].second];
}
-
+
MatchLen = FullMatch.size();
return FullMatch.data()-Buffer.data();
}
@@ -421,19 +421,19 @@ void Pattern::PrintFailureInfo(const SourceMgr &SM, StringRef Buffer,
struct CheckString {
/// Pat - The pattern to match.
Pattern Pat;
-
+
/// Loc - The location in the match file that the check string was specified.
SMLoc Loc;
-
+
/// IsCheckNext - This is true if this is a CHECK-NEXT: directive (as opposed
/// to a CHECK: directive.
bool IsCheckNext;
-
+
/// NotStrings - These are all of the strings that are disallowed from
/// occurring between this match string and the previous one (or start of
/// file).
std::vector<std::pair<SMLoc, Pattern> > NotStrings;
-
+
CheckString(const Pattern &P, SMLoc L, bool isCheckNext)
: Pat(P), Loc(L), IsCheckNext(isCheckNext) {}
};
@@ -443,7 +443,7 @@ struct CheckString {
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
SmallString<128> NewFile;
NewFile.reserve(MB->getBufferSize());
-
+
for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
Ptr != End; ++Ptr) {
// If C is not a horizontal whitespace, skip it.
@@ -451,18 +451,18 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
NewFile.push_back(*Ptr);
continue;
}
-
+
// Otherwise, add one space and advance over neighboring space.
NewFile.push_back(' ');
while (Ptr+1 != End &&
(Ptr[1] == ' ' || Ptr[1] == '\t'))
++Ptr;
}
-
+
// Free the old buffer and return a new one.
MemoryBuffer *MB2 =
MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());
-
+
delete MB;
return MB2;
}
@@ -477,37 +477,37 @@ static bool ReadCheckFile(SourceMgr &SM,
MemoryBuffer *F =
MemoryBuffer::getFileOrSTDIN(CheckFilename.c_str(), &ErrorStr);
if (F == 0) {
- errs() << "Could not open check file '" << CheckFilename << "': "
+ errs() << "Could not open check file '" << CheckFilename << "': "
<< ErrorStr << '\n';
return true;
}
-
+
// If we want to canonicalize whitespace, strip excess whitespace from the
// buffer containing the CHECK lines.
if (!NoCanonicalizeWhiteSpace)
F = CanonicalizeInputFile(F);
-
+
SM.AddNewSourceBuffer(F, SMLoc());
// Find all instances of CheckPrefix followed by : in the file.
StringRef Buffer = F->getBuffer();
std::vector<std::pair<SMLoc, Pattern> > NotMatches;
-
+
while (1) {
// See if Prefix occurs in the memory buffer.
Buffer = Buffer.substr(Buffer.find(CheckPrefix));
-
+
// If we didn't find a match, we're done.
if (Buffer.empty())
break;
-
+
const char *CheckPrefixStart = Buffer.data();
-
+
// When we find a check prefix, keep track of whether we find CHECK: or
// CHECK-NEXT:
bool IsCheckNext = false, IsCheckNot = false;
-
+
// Verify that the : is present after the prefix.
if (Buffer[CheckPrefix.size()] == ':') {
Buffer = Buffer.substr(CheckPrefix.size()+1);
@@ -523,11 +523,11 @@ static bool ReadCheckFile(SourceMgr &SM,
Buffer = Buffer.substr(1);
continue;
}
-
+
// Okay, we found the prefix, yay. Remember the rest of the line, but
// ignore leading and trailing whitespace.
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
-
+
// Scan ahead to the end of line.
size_t EOL = Buffer.find_first_of("\n\r");
@@ -538,10 +538,10 @@ static bool ReadCheckFile(SourceMgr &SM,
Pattern P;
if (P.ParsePattern(Buffer.substr(0, EOL), SM))
return true;
-
+
Buffer = Buffer.substr(EOL);
-
+
// Verify that CHECK-NEXT lines have at least one CHECK line before them.
if (IsCheckNext && CheckStrings.empty()) {
SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
@@ -549,34 +549,34 @@ static bool ReadCheckFile(SourceMgr &SM,
CheckPrefix+ ": line", "error");
return true;
}
-
+
// Handle CHECK-NOT.
if (IsCheckNot) {
NotMatches.push_back(std::make_pair(SMLoc::getFromPointer(Buffer.data()),
P));
continue;
}
-
-
+
+
// Okay, add the string we captured to the output vector and move on.
CheckStrings.push_back(CheckString(P,
PatternLoc,
IsCheckNext));
std::swap(NotMatches, CheckStrings.back().NotStrings);
}
-
+
if (CheckStrings.empty()) {
errs() << "error: no check strings found with prefix '" << CheckPrefix
<< ":'\n";
return true;
}
-
+
if (!NotMatches.empty()) {
errs() << "error: '" << CheckPrefix
<< "-NOT:' not supported after last check line.\n";
return true;
}
-
+
return false;
}
@@ -586,11 +586,11 @@ static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr,
// Otherwise, we have an error, emit an error message.
SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
"error");
-
+
// Print the "scanning from here" line. If the current position is at the
// end of a line, advance to the start of the next line.
Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
-
+
SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
"note");
@@ -606,9 +606,9 @@ static unsigned CountNumNewlinesBetween(StringRef Range) {
// Scan for newline.
Range = Range.substr(Range.find_first_of("\n\r"));
if (Range.empty()) return NumNewLines;
-
+
++NumNewLines;
-
+
// Handle \n\r and \r\n as a single newline.
if (Range.size() > 1 &&
(Range[1] == '\n' || Range[1] == '\r') &&
@@ -624,7 +624,7 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
SourceMgr SM;
-
+
// Read the expected strings from the check file.
std::vector<CheckString> CheckStrings;
if (ReadCheckFile(SM, CheckStrings))
@@ -635,35 +635,35 @@ int main(int argc, char **argv) {
MemoryBuffer *F =
MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), &ErrorStr);
if (F == 0) {
- errs() << "Could not open input file '" << InputFilename << "': "
+ errs() << "Could not open input file '" << InputFilename << "': "
<< ErrorStr << '\n';
return true;
}
-
+
// Remove duplicate spaces in the input file if requested.
if (!NoCanonicalizeWhiteSpace)
F = CanonicalizeInputFile(F);
-
+
SM.AddNewSourceBuffer(F, SMLoc());
-
+
/// VariableTable - This holds all the current filecheck variables.
StringMap<StringRef> VariableTable;
-
+
// Check that we have all of the expected strings, in order, in the input
// file.
StringRef Buffer = F->getBuffer();
-
+
const char *LastMatch = Buffer.data();
-
+
for (unsigned StrNo = 0, e = CheckStrings.size(); StrNo != e; ++StrNo) {
const CheckString &CheckStr = CheckStrings[StrNo];
-
+
StringRef SearchFrom = Buffer;
-
+
// Find StrNo in the file.
size_t MatchLen = 0;
Buffer = Buffer.substr(CheckStr.Pat.Match(Buffer, MatchLen, VariableTable));
-
+
// If we didn't find a match, reject the input.
if (Buffer.empty()) {
PrintCheckFailed(SM, CheckStr, SearchFrom, VariableTable);
@@ -690,7 +690,7 @@ int main(int argc, char **argv) {
"previous match was here", "note");
return 1;
}
-
+
if (NumNewLines != 1) {
SM.PrintMessage(CheckStr.Loc,
CheckPrefix+
@@ -703,7 +703,7 @@ int main(int argc, char **argv) {
return 1;
}
}
-
+
// If this match had "not strings", verify that they don't exist in the
// skipped region.
for (unsigned ChunkNo = 0, e = CheckStr.NotStrings.size();
@@ -713,20 +713,20 @@ int main(int argc, char **argv) {
MatchLen,
VariableTable);
if (Pos == StringRef::npos) continue;
-
+
SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
CheckPrefix+"-NOT: string occurred!", "error");
SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
CheckPrefix+"-NOT: pattern specified here", "note");
return 1;
}
-
+
// Otherwise, everything is good. Step over the matched text and remember
// the position after the match as the end of the last match.
Buffer = Buffer.substr(MatchLen);
LastMatch = Buffer.data();
}
-
+
return 0;
}
diff --git a/contrib/llvm/utils/FileUpdate/FileUpdate.cpp b/contrib/llvm/utils/FileUpdate/FileUpdate.cpp
index 00c2091..2cf366f 100644
--- a/contrib/llvm/utils/FileUpdate/FileUpdate.cpp
+++ b/contrib/llvm/utils/FileUpdate/FileUpdate.cpp
@@ -36,6 +36,11 @@ int main(int argc, char **argv) {
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);
+ if (OutputFilename == "-") {
+ errs() << argv[0] << ": error: Can't update standard output\n";
+ return 1;
+ }
+
// Get the input data.
std::string ErrorStr;
MemoryBuffer *In =
@@ -54,7 +59,7 @@ int main(int argc, char **argv) {
memcmp(In->getBufferStart(), Out->getBufferStart(),
Out->getBufferSize()) == 0) {
if (!Quiet)
- outs() << argv[0] << ": Not updating '" << OutputFilename
+ errs() << argv[0] << ": Not updating '" << OutputFilename
<< "', contents match input.\n";
return 0;
}
@@ -63,25 +68,20 @@ int main(int argc, char **argv) {
// Otherwise, overwrite the output.
if (!Quiet)
- outs() << argv[0] << ": Updating '" << OutputFilename
+ errs() << argv[0] << ": Updating '" << OutputFilename
<< "', contents changed.\n";
- raw_fd_ostream OutStream(OutputFilename.c_str(), ErrorStr,
- raw_fd_ostream::F_Binary);
+ tool_output_file OutStream(OutputFilename.c_str(), ErrorStr,
+ raw_fd_ostream::F_Binary);
if (!ErrorStr.empty()) {
errs() << argv[0] << ": Unable to write output '"
<< OutputFilename << "': " << ErrorStr << '\n';
return 1;
}
- OutStream.write(In->getBufferStart(), In->getBufferSize());
- OutStream.close();
+ OutStream.os().write(In->getBufferStart(), In->getBufferSize());
- if (OutStream.has_error()) {
- errs() << argv[0] << ": Could not open output file '"
- << OutputFilename << "': " << ErrorStr << '\n';
- OutStream.clear_error();
- return 1;
- }
+ // Declare success.
+ OutStream.keep();
return 0;
}
diff --git a/contrib/llvm/utils/Makefile b/contrib/llvm/utils/Makefile
index 000705e..1a4dcca 100644
--- a/contrib/llvm/utils/Makefile
+++ b/contrib/llvm/utils/Makefile
@@ -8,14 +8,15 @@
##===----------------------------------------------------------------------===##
LEVEL = ..
-PARALLEL_DIRS := TableGen fpcmp PerfectShuffle FileCheck FileUpdate count not unittest
+PARALLEL_DIRS := FileCheck FileUpdate TableGen PerfectShuffle \
+ count fpcmp llvm-lit not unittest
-EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh cvsupdate \
+EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh \
DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \
getsrcs.sh importNLT.pl llvmdo llvmgrep llvm-native-gcc \
llvm-native-gxx makellvm NightlyTest.gnuplot NightlyTest.pl \
NightlyTestTemplate.html NLT.schema OldenDataRecover.pl \
- parseNLT.pl plotNLT.pl profile.pl RegressionFinder.pl userloc.pl \
+ parseNLT.pl plotNLT.pl profile.pl \
webNLT.pl vim
include $(LEVEL)/Makefile.common
diff --git a/contrib/llvm/utils/RegressionFinder.pl b/contrib/llvm/utils/RegressionFinder.pl
deleted file mode 100755
index 86b0777..0000000
--- a/contrib/llvm/utils/RegressionFinder.pl
+++ /dev/null
@@ -1,186 +0,0 @@
-#! /usr/bin/perl
-# Script to find regressions by binary-searching a time interval in the
-# CVS tree. Written by Brian Gaeke on 2-Mar-2004.
-#
-
-require 5.6.0; # NOTE: This script not tested with earlier versions.
-use Getopt::Std;
-use POSIX;
-use Time::Local;
-use IO::Handle;
-
-sub usage {
- print STDERR <<END;
-findRegression [-I] -w WTIME -d DTIME -t TOOLS -c SCRIPT
-
-The -w, -d, -t, and -c options are required.
-Run findRegression in the top level of an LLVM tree.
-WTIME is a time when you are sure the regression does NOT exist ("Works").
-DTIME is a time when you are sure the regression DOES exist ("Doesntwork").
-WTIME and DTIME are both in the format: "YYYY/MM/DD HH:MM".
--I means run builds at WTIME and DTIME first to make sure.
-TOOLS is a comma separated list of tools to rebuild before running SCRIPT.
-SCRIPT exits 1 if the regression is present in TOOLS; 0 otherwise.
-END
- exit 1;
-}
-
-sub timeAsSeconds {
- my ($timestr) = @_;
-
- if ( $timestr =~ /(\d\d\d\d)\/(\d\d)\/(\d\d) (\d\d):(\d\d)/ ) {
- my ( $year, $mon, $mday, $hour, $min ) = ( $1, $2, $3, $4, $5 );
- return timegm( 0, $min, $hour, $mday, $mon - 1, $year );
- }
- else {
- die "** Can't parse date + time: $timestr\n";
- }
-}
-
-sub timeAsString {
- my ($secs) = @_;
- return strftime( "%Y/%m/%d %H:%M", gmtime($secs) );
-}
-
-sub run {
- my ($cmdline) = @_;
- print LOG "** Running: $cmdline\n";
- return system($cmdline);
-}
-
-sub buildLibrariesAndTools {
- run("sh /home/vadve/gaeke/scripts/run-configure");
- run("$MAKE -C lib/Support");
- run("$MAKE -C utils");
- run("$MAKE -C lib");
- foreach my $tool (@TOOLS) { run("$MAKE -C tools/$tool"); }
-}
-
-sub contains {
- my ( $file, $regex ) = @_;
- local (*FILE);
- open( FILE, "<$file" ) or die "** can't read $file: $!\n";
- while (<FILE>) {
- if (/$regex/) {
- close FILE;
- return 1;
- }
- }
- close FILE;
- return 0;
-}
-
-sub updateSources {
- my ($time) = @_;
- my $inst = "include/llvm/Instruction.h";
- unlink($inst);
- run( "cvs update -D'" . timeAsString($time) . "'" );
- if ( !contains( $inst, 'class Instruction.*Annotable' ) ) {
- run("patch -F100 -p0 < makeInstructionAnnotable.patch");
- }
-}
-
-sub regressionPresentAt {
- my ($time) = @_;
-
- updateSources($time);
- buildLibrariesAndTools();
- my $rc = run($SCRIPT);
- if ($rc) {
- print LOG "** Found that regression was PRESENT at "
- . timeAsString($time) . "\n";
- return 1;
- }
- else {
- print LOG "** Found that regression was ABSENT at "
- . timeAsString($time) . "\n";
- return 0;
- }
-}
-
-sub regressionAbsentAt {
- my ($time) = @_;
- return !regressionPresentAt($time);
-}
-
-sub closeTo {
- my ( $time1, $time2 ) = @_;
- return abs( $time1 - $time2 ) < 600; # 10 minutes seems reasonable.
-}
-
-sub halfWayPoint {
- my ( $time1, $time2 ) = @_;
- my $halfSpan = int( abs( $time1 - $time2 ) / 2 );
- if ( $time1 < $time2 ) {
- return $time1 + $halfSpan;
- }
- else {
- return $time2 + $halfSpan;
- }
-}
-
-sub checkBoundaryConditions {
- print LOG "** Checking for presence of regression at ", timeAsString($DTIME),
- "\n";
- if ( !regressionPresentAt($DTIME) ) {
- die ( "** Can't help you; $SCRIPT says regression absent at dtime: "
- . timeAsString($DTIME)
- . "\n" );
- }
- print LOG "** Checking for absence of regression at ", timeAsString($WTIME),
- "\n";
- if ( !regressionAbsentAt($WTIME) ) {
- die ( "** Can't help you; $SCRIPT says regression present at wtime: "
- . timeAsString($WTIME)
- . "\n" );
- }
-}
-
-##############################################################################
-
-# Set up log files
-open (STDERR, ">&STDOUT") || die "** Can't redirect std.err: $!\n";
-autoflush STDOUT 1;
-autoflush STDERR 1;
-open (LOG, ">RegFinder.log") || die "** can't write RegFinder.log: $!\n";
-autoflush LOG 1;
-# Check command line arguments and environment variables
-getopts('Iw:d:t:c:');
-if ( !( $opt_w && $opt_d && $opt_t && $opt_c ) ) {
- usage;
-}
-$MAKE = $ENV{'MAKE'};
-$MAKE = 'gmake' unless $MAKE;
-$WTIME = timeAsSeconds($opt_w);
-print LOG "** Assuming worked at ", timeAsString($WTIME), "\n";
-$DTIME = timeAsSeconds($opt_d);
-print LOG "** Assuming didn't work at ", timeAsString($DTIME), "\n";
-$opt_t =~ s/\s*//g;
-$SCRIPT = $opt_c;
-die "** $SCRIPT is not executable or not found\n" unless -x $SCRIPT;
-print LOG "** Checking for the regression using $SCRIPT\n";
-@TOOLS = split ( /,/, $opt_t );
-print LOG (
- "** Going to rebuild: ",
- ( join ", ", @TOOLS ),
- " before each $SCRIPT run\n"
-);
-if ($opt_I) { checkBoundaryConditions(); }
-# do the dirty work:
-while ( !closeTo( $DTIME, $WTIME ) ) {
- my $halfPt = halfWayPoint( $DTIME, $WTIME );
- print LOG "** Checking whether regression is present at ",
- timeAsString($halfPt), "\n";
- if ( regressionPresentAt($halfPt) ) {
- $DTIME = $halfPt;
- }
- else {
- $WTIME = $halfPt;
- }
-}
-# Tell them what we found
-print LOG "** Narrowed it down to:\n";
-print LOG "** Worked at: ", timeAsString($WTIME), "\n";
-print LOG "** Did not work at: ", timeAsString($DTIME), "\n";
-close LOG;
-exit 0;
diff --git a/contrib/llvm/utils/TableGen/ARMDecoderEmitter.cpp b/contrib/llvm/utils/TableGen/ARMDecoderEmitter.cpp
index 5025691..03b01f6 100644
--- a/contrib/llvm/utils/TableGen/ARMDecoderEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/ARMDecoderEmitter.cpp
@@ -49,36 +49,35 @@ using namespace llvm;
ENTRY(ARM_FORMAT_LDSTMULFRM, 10) \
ENTRY(ARM_FORMAT_LDSTEXFRM, 11) \
ENTRY(ARM_FORMAT_ARITHMISCFRM, 12) \
- ENTRY(ARM_FORMAT_EXTFRM, 13) \
- ENTRY(ARM_FORMAT_VFPUNARYFRM, 14) \
- ENTRY(ARM_FORMAT_VFPBINARYFRM, 15) \
- ENTRY(ARM_FORMAT_VFPCONV1FRM, 16) \
- ENTRY(ARM_FORMAT_VFPCONV2FRM, 17) \
- ENTRY(ARM_FORMAT_VFPCONV3FRM, 18) \
- ENTRY(ARM_FORMAT_VFPCONV4FRM, 19) \
- ENTRY(ARM_FORMAT_VFPCONV5FRM, 20) \
- ENTRY(ARM_FORMAT_VFPLDSTFRM, 21) \
- ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 22) \
- ENTRY(ARM_FORMAT_VFPMISCFRM, 23) \
- ENTRY(ARM_FORMAT_THUMBFRM, 24) \
- ENTRY(ARM_FORMAT_NEONFRM, 25) \
- ENTRY(ARM_FORMAT_NEONGETLNFRM, 26) \
- ENTRY(ARM_FORMAT_NEONSETLNFRM, 27) \
- ENTRY(ARM_FORMAT_NEONDUPFRM, 28) \
- ENTRY(ARM_FORMAT_MISCFRM, 29) \
- ENTRY(ARM_FORMAT_THUMBMISCFRM, 30) \
- ENTRY(ARM_FORMAT_NLdSt, 31) \
- ENTRY(ARM_FORMAT_N1RegModImm, 32) \
- ENTRY(ARM_FORMAT_N2Reg, 33) \
- ENTRY(ARM_FORMAT_NVCVT, 34) \
- ENTRY(ARM_FORMAT_NVecDupLn, 35) \
- ENTRY(ARM_FORMAT_N2RegVecShL, 36) \
- ENTRY(ARM_FORMAT_N2RegVecShR, 37) \
- ENTRY(ARM_FORMAT_N3Reg, 38) \
- ENTRY(ARM_FORMAT_N3RegVecSh, 39) \
- ENTRY(ARM_FORMAT_NVecExtract, 40) \
- ENTRY(ARM_FORMAT_NVecMulScalar, 41) \
- ENTRY(ARM_FORMAT_NVTBL, 42)
+ ENTRY(ARM_FORMAT_SATFRM, 13) \
+ ENTRY(ARM_FORMAT_EXTFRM, 14) \
+ ENTRY(ARM_FORMAT_VFPUNARYFRM, 15) \
+ ENTRY(ARM_FORMAT_VFPBINARYFRM, 16) \
+ ENTRY(ARM_FORMAT_VFPCONV1FRM, 17) \
+ ENTRY(ARM_FORMAT_VFPCONV2FRM, 18) \
+ ENTRY(ARM_FORMAT_VFPCONV3FRM, 19) \
+ ENTRY(ARM_FORMAT_VFPCONV4FRM, 20) \
+ ENTRY(ARM_FORMAT_VFPCONV5FRM, 21) \
+ ENTRY(ARM_FORMAT_VFPLDSTFRM, 22) \
+ ENTRY(ARM_FORMAT_VFPLDSTMULFRM, 23) \
+ ENTRY(ARM_FORMAT_VFPMISCFRM, 24) \
+ ENTRY(ARM_FORMAT_THUMBFRM, 25) \
+ ENTRY(ARM_FORMAT_MISCFRM, 26) \
+ ENTRY(ARM_FORMAT_NEONGETLNFRM, 27) \
+ ENTRY(ARM_FORMAT_NEONSETLNFRM, 28) \
+ ENTRY(ARM_FORMAT_NEONDUPFRM, 29) \
+ ENTRY(ARM_FORMAT_NLdSt, 30) \
+ ENTRY(ARM_FORMAT_N1RegModImm, 31) \
+ ENTRY(ARM_FORMAT_N2Reg, 32) \
+ ENTRY(ARM_FORMAT_NVCVT, 33) \
+ ENTRY(ARM_FORMAT_NVecDupLn, 34) \
+ ENTRY(ARM_FORMAT_N2RegVecShL, 35) \
+ ENTRY(ARM_FORMAT_N2RegVecShR, 36) \
+ ENTRY(ARM_FORMAT_N3Reg, 37) \
+ ENTRY(ARM_FORMAT_N3RegVecSh, 38) \
+ ENTRY(ARM_FORMAT_NVecExtract, 39) \
+ ENTRY(ARM_FORMAT_NVecMulScalar, 40) \
+ ENTRY(ARM_FORMAT_NVTBL, 41)
// ARM instruction format specifies the encoding used by the instruction.
#define ENTRY(n, v) n = v,
@@ -1584,7 +1583,7 @@ bool ARMDecoderEmitter::ARMDEBackend::populateInstruction(
Name == "MOVr_TC")
return false;
- // VLDMQ/VSTMQ can be hanlded with the more generic VLDMD/VSTMD.
+ // VLDMQ/VSTMQ can be handled with the more generic VLDMD/VSTMD.
if (Name == "VLDMQ" || Name == "VLDMQ_UPD" ||
Name == "VSTMQ" || Name == "VSTMQ_UPD")
return false;
diff --git a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index e1aa2bc..5583986 100644
--- a/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -199,6 +199,14 @@ static void TokenizeAsmString(StringRef AsmString,
break;
}
+ case '.':
+ if (InTok) {
+ Tokens.push_back(AsmString.slice(Prev, i));
+ }
+ Prev = i;
+ InTok = true;
+ break;
+
default:
InTok = true;
}
@@ -260,9 +268,12 @@ static bool IsAssemblerInstruction(StringRef Name,
}
if (Tokens[i][0] == '$' && !OperandNames.insert(Tokens[i]).second) {
- std::string Err = "'" + Name.str() + "': " +
- "invalid assembler instruction; tied operand '" + Tokens[i].str() + "'";
- throw TGError(CGI.TheDef->getLoc(), Err);
+ DEBUG({
+ errs() << "warning: '" << Name << "': "
+ << "ignoring instruction with tied operand '"
+ << Tokens[i].str() << "'\n";
+ });
+ return false;
}
}
@@ -271,6 +282,8 @@ static bool IsAssemblerInstruction(StringRef Name,
namespace {
+struct SubtargetFeatureInfo;
+
/// ClassInfo - Helper class for storing the information about a particular
/// class of operands which can be matched.
struct ClassInfo {
@@ -444,6 +457,9 @@ struct InstructionInfo {
/// Operands - The operands that this instruction matches.
SmallVector<Operand, 4> Operands;
+ /// Predicates - The required subtarget features to match this instruction.
+ SmallVector<SubtargetFeatureInfo*, 4> RequiredFeatures;
+
/// ConversionFnKind - The enum value which is passed to the generated
/// ConvertToMCInst to convert parsed operands into an MCInst for this
/// function.
@@ -505,6 +521,19 @@ public:
void dump();
};
+/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
+/// feature which participates in instruction matching.
+struct SubtargetFeatureInfo {
+ /// \brief The predicate record for this feature.
+ Record *TheDef;
+
+ /// \brief An unique index assigned to represent this feature.
+ unsigned Index;
+
+ /// \brief The name of the enumerated constant identifying this feature.
+ std::string EnumName;
+};
+
class AsmMatcherInfo {
public:
/// The tablegen AsmParser record.
@@ -525,6 +554,9 @@ public:
/// Map of Register records to their class information.
std::map<Record*, ClassInfo*> RegisterClasses;
+ /// Map of Predicate records to their subtarget information.
+ std::map<Record*, SubtargetFeatureInfo*> SubtargetFeatures;
+
private:
/// Map of token to class information which has already been constructed.
std::map<std::string, ClassInfo*> TokenClasses;
@@ -543,6 +575,23 @@ private:
ClassInfo *getOperandClass(StringRef Token,
const CodeGenInstruction::OperandInfo &OI);
+ /// getSubtargetFeature - Lookup or create the subtarget feature info for the
+ /// given operand.
+ SubtargetFeatureInfo *getSubtargetFeature(Record *Def) {
+ assert(Def->isSubClassOf("Predicate") && "Invalid predicate type!");
+
+ SubtargetFeatureInfo *&Entry = SubtargetFeatures[Def];
+ if (!Entry) {
+ Entry = new SubtargetFeatureInfo;
+ Entry->TheDef = Def;
+ Entry->Index = SubtargetFeatures.size() - 1;
+ Entry->EnumName = "Feature_" + Def->getName();
+ assert(Entry->Index < 32 && "Too many subtarget features!");
+ }
+
+ return Entry;
+ }
+
/// BuildRegisterClasses - Build the ClassInfo* instances for register
/// classes.
void BuildRegisterClasses(CodeGenTarget &Target,
@@ -903,7 +952,31 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
}
}
}
-
+
+ // Compute the require features.
+ ListInit *Predicates = CGI.TheDef->getValueAsListInit("Predicates");
+ for (unsigned i = 0, e = Predicates->getSize(); i != e; ++i) {
+ if (DefInit *Pred = dynamic_cast<DefInit*>(Predicates->getElement(i))) {
+ // Ignore OptForSize and OptForSpeed, they aren't really requirements,
+ // rather they are hints to isel.
+ //
+ // FIXME: Find better way to model this.
+ if (Pred->getDef()->getName() == "OptForSize" ||
+ Pred->getDef()->getName() == "OptForSpeed")
+ continue;
+
+ // FIXME: Total hack; for now, we just limit ourselves to In32BitMode
+ // and In64BitMode, because we aren't going to have the right feature
+ // masks for SSE and friends. We need to decide what we are going to do
+ // about CPU subtypes to implement this the right way.
+ if (Pred->getDef()->getName() != "In32BitMode" &&
+ Pred->getDef()->getName() != "In64BitMode")
+ continue;
+
+ II->RequiredFeatures.push_back(getSubtargetFeature(Pred->getDef()));
+ }
+ }
+
Instructions.push_back(II.take());
}
@@ -1499,6 +1572,48 @@ static void EmitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser,
OS << "}\n\n";
}
+/// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag
+/// definitions.
+static void EmitSubtargetFeatureFlagEnumeration(CodeGenTarget &Target,
+ AsmMatcherInfo &Info,
+ raw_ostream &OS) {
+ OS << "// Flags for subtarget features that participate in "
+ << "instruction matching.\n";
+ OS << "enum SubtargetFeatureFlag {\n";
+ for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+ it = Info.SubtargetFeatures.begin(),
+ ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+ SubtargetFeatureInfo &SFI = *it->second;
+ OS << " " << SFI.EnumName << " = (1 << " << SFI.Index << "),\n";
+ }
+ OS << " Feature_None = 0\n";
+ OS << "};\n\n";
+}
+
+/// EmitComputeAvailableFeatures - Emit the function to compute the list of
+/// available features given a subtarget.
+static void EmitComputeAvailableFeatures(CodeGenTarget &Target,
+ AsmMatcherInfo &Info,
+ raw_ostream &OS) {
+ std::string ClassName =
+ Info.AsmParser->getValueAsString("AsmParserClassName");
+
+ OS << "unsigned " << Target.getName() << ClassName << "::\n"
+ << "ComputeAvailableFeatures(const " << Target.getName()
+ << "Subtarget *Subtarget) const {\n";
+ OS << " unsigned Features = 0;\n";
+ for (std::map<Record*, SubtargetFeatureInfo*>::const_iterator
+ it = Info.SubtargetFeatures.begin(),
+ ie = Info.SubtargetFeatures.end(); it != ie; ++it) {
+ SubtargetFeatureInfo &SFI = *it->second;
+ OS << " if (" << SFI.TheDef->getValueAsString("CondString")
+ << ")\n";
+ OS << " Features |= " << SFI.EnumName << ";\n";
+ }
+ OS << " return Features;\n";
+ OS << "}\n\n";
+}
+
void AsmMatcherEmitter::run(raw_ostream &OS) {
CodeGenTarget Target;
Record *AsmParser = Target.getAsmParser();
@@ -1550,6 +1665,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
EmitSourceFileHeader("Assembly Matcher Source Fragment", OS);
+ // Emit the subtarget feature enumeration.
+ EmitSubtargetFeatureFlagEnumeration(Target, Info, OS);
+
// Emit the function to match a register name to number.
EmitMatchRegisterName(Target, AsmParser, OS);
@@ -1570,6 +1688,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
// Emit the subclass predicate routine.
EmitIsSubclass(Target, Info.Classes, OS);
+ // Emit the available features compute function.
+ EmitComputeAvailableFeatures(Target, Info, OS);
+
// Finally, build the match function.
size_t MaxNumOperands = 0;
@@ -1578,13 +1699,10 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
it != ie; ++it)
MaxNumOperands = std::max(MaxNumOperands, (*it)->Operands.size());
- const std::string &MatchName =
- AsmParser->getValueAsString("MatchInstructionName");
OS << "bool " << Target.getName() << ClassName << "::\n"
- << MatchName
- << "(const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
- OS.indent(MatchName.size() + 1);
- OS << "MCInst &Inst) {\n";
+ << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
+ << " &Operands,\n";
+ OS << " MCInst &Inst) {\n";
// Emit the static match table; unused classes get initalized to 0 which is
// guaranteed to be InvalidMatchClass.
@@ -1600,6 +1718,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " unsigned Opcode;\n";
OS << " ConversionKind ConvertFn;\n";
OS << " MatchClassKind Classes[" << MaxNumOperands << "];\n";
+ OS << " unsigned RequiredFeatures;\n";
OS << " } MatchTable[" << Info.Instructions.size() << "] = {\n";
for (std::vector<InstructionInfo*>::const_iterator it =
@@ -1615,11 +1734,27 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
if (i) OS << ", ";
OS << Op.Class->Name;
}
- OS << " } },\n";
+ OS << " }, ";
+
+ // Write the required features mask.
+ if (!II.RequiredFeatures.empty()) {
+ for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
+ if (i) OS << "|";
+ OS << II.RequiredFeatures[i]->EnumName;
+ }
+ } else
+ OS << "0";
+
+ OS << "},\n";
}
OS << " };\n\n";
+
+ // Emit code to get the available features.
+ OS << " // Get the current feature set.\n";
+ OS << " unsigned AvailableFeatures = getAvailableFeatures();\n\n";
+
// Emit code to compute the class list for this operand vector.
OS << " // Eliminate obvious mismatches.\n";
OS << " if (Operands.size() > " << MaxNumOperands << ")\n";
@@ -1645,6 +1780,13 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " for (const MatchEntry *it = MatchTable, "
<< "*ie = MatchTable + " << Info.Instructions.size()
<< "; it != ie; ++it) {\n";
+
+ // Emit check that the required features are available.
+ OS << " if ((AvailableFeatures & it->RequiredFeatures) "
+ << "!= it->RequiredFeatures)\n";
+ OS << " continue;\n";
+
+ // Emit check that the subclasses match.
for (unsigned i = 0; i != MaxNumOperands; ++i) {
OS << " if (!IsSubclass(Classes["
<< i << "], it->Classes[" << i << "]))\n";
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 1e95467..23f13c2 100644
--- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -115,7 +115,7 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
const AsmWriterInst *Inst = getAsmWriterInstByID(i);
- if (Inst == 0) continue; // PHI, INLINEASM, DBG_LABEL, etc.
+ if (Inst == 0) continue; // PHI, INLINEASM, PROLOG_LABEL, etc.
std::string Command;
if (Inst->Operands.empty())
diff --git a/contrib/llvm/utils/TableGen/CallingConvEmitter.cpp b/contrib/llvm/utils/TableGen/CallingConvEmitter.cpp
index 28ba2ed..7643609 100644
--- a/contrib/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -169,6 +169,8 @@ void CallingConvEmitter::EmitAction(Record *Action,
else
O << "\n" << IndentStr << " State.getTarget().getTargetData()"
"->getABITypeAlignment(LocVT.getTypeForEVT(State.getContext()))";
+ if (Action->isSubClassOf("CCAssignToStackWithShadow"))
+ O << ", " << getQualifiedName(Action->getValueAsDef("ShadowReg"));
O << ");\n" << IndentStr
<< "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
<< Counter << ", LocVT, LocInfo));\n";
diff --git a/contrib/llvm/utils/TableGen/ClangAttrEmitter.cpp b/contrib/llvm/utils/TableGen/ClangAttrEmitter.cpp
index fbdd2a7..8d3399a 100644
--- a/contrib/llvm/utils/TableGen/ClangAttrEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/ClangAttrEmitter.cpp
@@ -13,10 +13,444 @@
#include "ClangAttrEmitter.h"
#include "Record.h"
+#include "llvm/ADT/StringSwitch.h"
#include <algorithm>
+#include <cctype>
using namespace llvm;
+static const std::vector<StringRef> getValueAsListOfStrings(Record &R,
+ StringRef FieldName) {
+ ListInit *List = R.getValueAsListInit(FieldName);
+ assert (List && "Got a null ListInit");
+
+ std::vector<StringRef> Strings;
+ Strings.reserve(List->getSize());
+
+ for (ListInit::iterator i = List->begin(), e = List->end(); i != e; ++i) {
+ assert(*i && "Got a null element in a ListInit");
+ if (StringInit *S = dynamic_cast<StringInit *>(*i))
+ Strings.push_back(S->getValue());
+ else if (CodeInit *C = dynamic_cast<CodeInit *>(*i))
+ Strings.push_back(C->getValue());
+ else
+ assert(false && "Got a non-string, non-code element in a ListInit");
+ }
+
+ return Strings;
+}
+
+std::string ReadPCHRecord(StringRef type) {
+ return StringSwitch<std::string>(type)
+ .EndsWith("Decl *", "cast_or_null<" + std::string(type, 0, type.size()-1) +
+ ">(GetDecl(Record[Idx++]))")
+ .Case("QualType", "ReadTypeRecord(Idx++)")
+ .Default("Record[Idx++]");
+}
+
+// Assumes that the way to get the value is SA->getname()
+std::string WritePCHRecord(StringRef type, StringRef name) {
+ return StringSwitch<std::string>(type)
+ .EndsWith("Decl *", "AddDeclRef(" + std::string(name) +
+ ", Record);\n")
+ .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n")
+ .Default("Record.push_back(" + std::string(name) + ");\n");
+}
+
+namespace {
+ class Argument {
+ std::string lowerName, upperName;
+ StringRef attrName;
+
+ public:
+ Argument(Record &Arg, StringRef Attr)
+ : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
+ attrName(Attr) {
+ if (!lowerName.empty()) {
+ lowerName[0] = std::tolower(lowerName[0]);
+ upperName[0] = std::toupper(upperName[0]);
+ }
+ }
+ virtual ~Argument() {}
+
+ StringRef getLowerName() const { return lowerName; }
+ StringRef getUpperName() const { return upperName; }
+ StringRef getAttrName() const { return attrName; }
+
+ // These functions print the argument contents formatted in different ways.
+ virtual void writeAccessors(raw_ostream &OS) const = 0;
+ virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
+ virtual void writeCloneArgs(raw_ostream &OS) const = 0;
+ virtual void writeCtorBody(raw_ostream &OS) const {}
+ virtual void writeCtorInitializers(raw_ostream &OS) const = 0;
+ virtual void writeCtorParameters(raw_ostream &OS) const = 0;
+ virtual void writeDeclarations(raw_ostream &OS) const = 0;
+ virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
+ virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
+ virtual void writePCHWrite(raw_ostream &OS) const = 0;
+ };
+
+ class SimpleArgument : public Argument {
+ std::string type;
+
+ public:
+ SimpleArgument(Record &Arg, StringRef Attr, std::string T)
+ : Argument(Arg, Attr), type(T)
+ {}
+
+ void writeAccessors(raw_ostream &OS) const {
+ OS << " " << type << " get" << getUpperName() << "() const {\n";
+ OS << " return " << getLowerName() << ";\n";
+ OS << " }";
+ }
+ void writeCloneArgs(raw_ostream &OS) const {
+ OS << getLowerName();
+ }
+ void writeCtorInitializers(raw_ostream &OS) const {
+ OS << getLowerName() << "(" << getUpperName() << ")";
+ }
+ void writeCtorParameters(raw_ostream &OS) const {
+ OS << type << " " << getUpperName();
+ }
+ void writeDeclarations(raw_ostream &OS) const {
+ OS << type << " " << getLowerName() << ";";
+ }
+ void writePCHReadDecls(raw_ostream &OS) const {
+ std::string read = ReadPCHRecord(type);
+ OS << " " << type << " " << getLowerName() << " = " << read << ";\n";
+ }
+ void writePCHReadArgs(raw_ostream &OS) const {
+ OS << getLowerName();
+ }
+ void writePCHWrite(raw_ostream &OS) const {
+ OS << " " << WritePCHRecord(type, "SA->get" +
+ std::string(getUpperName()) + "()");
+ }
+ };
+
+ class StringArgument : public Argument {
+ public:
+ StringArgument(Record &Arg, StringRef Attr)
+ : Argument(Arg, Attr)
+ {}
+
+ void writeAccessors(raw_ostream &OS) const {
+ OS << " llvm::StringRef get" << getUpperName() << "() const {\n";
+ OS << " return llvm::StringRef(" << getLowerName() << ", "
+ << getLowerName() << "Length);\n";
+ OS << " }\n";
+ OS << " unsigned get" << getUpperName() << "Length() const {\n";
+ OS << " return " << getLowerName() << "Length;\n";
+ OS << " }\n";
+ OS << " void set" << getUpperName()
+ << "(ASTContext &C, llvm::StringRef S) {\n";
+ OS << " " << getLowerName() << "Length = S.size();\n";
+ OS << " this->" << getLowerName() << " = new (C, 1) char ["
+ << getLowerName() << "Length];\n";
+ OS << " std::memcpy(this->" << getLowerName() << ", S.data(), "
+ << getLowerName() << "Length);\n";
+ OS << " }";
+ }
+ void writeCloneArgs(raw_ostream &OS) const {
+ OS << "get" << getUpperName() << "()";
+ }
+ void writeCtorBody(raw_ostream &OS) const {
+ OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
+ << ".data(), " << getLowerName() << "Length);";
+ }
+ void writeCtorInitializers(raw_ostream &OS) const {
+ OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
+ << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
+ << "Length])";
+ }
+ void writeCtorParameters(raw_ostream &OS) const {
+ OS << "llvm::StringRef " << getUpperName();
+ }
+ void writeDeclarations(raw_ostream &OS) const {
+ OS << "unsigned " << getLowerName() << "Length;\n";
+ OS << "char *" << getLowerName() << ";";
+ }
+ void writePCHReadDecls(raw_ostream &OS) const {
+ OS << " std::string " << getLowerName() << "= ReadString(Record, Idx);\n";
+ }
+ void writePCHReadArgs(raw_ostream &OS) const {
+ OS << getLowerName();
+ }
+ void writePCHWrite(raw_ostream &OS) const {
+ OS << " AddString(SA->get" << getUpperName() << "(), Record);\n";
+ }
+ };
+
+ class AlignedArgument : public Argument {
+ public:
+ AlignedArgument(Record &Arg, StringRef Attr)
+ : Argument(Arg, Attr)
+ {}
+
+ void writeAccessors(raw_ostream &OS) const {
+ OS << " bool is" << getUpperName() << "Dependent() const;\n";
+
+ OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
+
+ OS << " bool is" << getUpperName() << "Expr() const {\n";
+ OS << " return is" << getLowerName() << "Expr;\n";
+ OS << " }\n";
+
+ OS << " Expr *get" << getUpperName() << "Expr() const {\n";
+ OS << " assert(is" << getLowerName() << "Expr);\n";
+ OS << " return " << getLowerName() << "Expr;\n";
+ OS << " }\n";
+
+ OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n";
+ OS << " assert(!is" << getLowerName() << "Expr);\n";
+ OS << " return " << getLowerName() << "Type;\n";
+ OS << " }";
+ }
+ void writeAccessorDefinitions(raw_ostream &OS) const {
+ OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
+ << "Dependent() const {\n";
+ OS << " if (is" << getLowerName() << "Expr)\n";
+ OS << " return " << getLowerName() << "Expr && (" << getLowerName()
+ << "Expr->isValueDependent() || " << getLowerName()
+ << "Expr->isTypeDependent());\n";
+ OS << " else\n";
+ OS << " return " << getLowerName()
+ << "Type->getType()->isDependentType();\n";
+ OS << "}\n";
+
+ // FIXME: Do not do the calculation here
+ // FIXME: Handle types correctly
+ // A null pointer means maximum alignment
+ // FIXME: Load the platform-specific maximum alignment, rather than
+ // 16, the x86 max.
+ OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName()
+ << "(ASTContext &Ctx) const {\n";
+ OS << " assert(!is" << getUpperName() << "Dependent());\n";
+ OS << " if (is" << getLowerName() << "Expr)\n";
+ OS << " return (" << getLowerName() << "Expr ? " << getLowerName()
+ << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)"
+ << "* Ctx.getCharWidth();\n";
+ OS << " else\n";
+ OS << " return 0; // FIXME\n";
+ OS << "}\n";
+ }
+ void writeCloneArgs(raw_ostream &OS) const {
+ OS << "is" << getLowerName() << "Expr, is" << getLowerName()
+ << "Expr ? static_cast<void*>(" << getLowerName()
+ << "Expr) : " << getLowerName()
+ << "Type";
+ }
+ void writeCtorBody(raw_ostream &OS) const {
+ OS << " if (is" << getLowerName() << "Expr)\n";
+ OS << " " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
+ << getUpperName() << ");\n";
+ OS << " else\n";
+ OS << " " << getLowerName()
+ << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
+ << ");";
+ }
+ void writeCtorInitializers(raw_ostream &OS) const {
+ OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
+ }
+ void writeCtorParameters(raw_ostream &OS) const {
+ OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
+ }
+ void writeDeclarations(raw_ostream &OS) const {
+ OS << "bool is" << getLowerName() << "Expr;\n";
+ OS << "union {\n";
+ OS << "Expr *" << getLowerName() << "Expr;\n";
+ OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
+ OS << "};";
+ }
+ void writePCHReadArgs(raw_ostream &OS) const {
+ OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
+ }
+ void writePCHReadDecls(raw_ostream &OS) const {
+ OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n";
+ OS << " void *" << getLowerName() << "Ptr;\n";
+ OS << " if (is" << getLowerName() << "Expr)\n";
+ OS << " " << getLowerName() << "Ptr = ReadExpr(DeclsCursor);\n";
+ OS << " else\n";
+ OS << " " << getLowerName()
+ << "Ptr = GetTypeSourceInfo(DeclsCursor, Record, Idx);\n";
+ }
+ void writePCHWrite(raw_ostream &OS) const {
+ OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n";
+ OS << " if (SA->is" << getUpperName() << "Expr())\n";
+ OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n";
+ OS << " else\n";
+ OS << " AddTypeSourceInfo(SA->get" << getUpperName()
+ << "Type(), Record);\n";
+ }
+ };
+
+ class VariadicArgument : public Argument {
+ std::string type;
+
+ public:
+ VariadicArgument(Record &Arg, StringRef Attr, std::string T)
+ : Argument(Arg, Attr), type(T)
+ {}
+
+ std::string getType() const { return type; }
+
+ void writeAccessors(raw_ostream &OS) const {
+ OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n";
+ OS << " " << getLowerName() << "_iterator " << getLowerName()
+ << "_begin() const {\n";
+ OS << " return " << getLowerName() << ";\n";
+ OS << " }\n";
+ OS << " " << getLowerName() << "_iterator " << getLowerName()
+ << "_end() const {\n";
+ OS << " return " << getLowerName() << " + " << getLowerName()
+ << "Size;\n";
+ OS << " }\n";
+ OS << " unsigned " << getLowerName() << "_size() const {\n"
+ << " return " << getLowerName() << "Size;\n;";
+ OS << " }";
+ }
+ void writeCloneArgs(raw_ostream &OS) const {
+ OS << getLowerName() << ", " << getLowerName() << "Size";
+ }
+ void writeCtorBody(raw_ostream &OS) const {
+ // FIXME: memcpy is not safe on non-trivial types.
+ OS << " std::memcpy(" << getLowerName() << ", " << getUpperName()
+ << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
+ }
+ void writeCtorInitializers(raw_ostream &OS) const {
+ OS << getLowerName() << "Size(" << getUpperName() << "Size), "
+ << getLowerName() << "(new (Ctx, 16) " << getType() << "["
+ << getLowerName() << "Size])";
+ }
+ void writeCtorParameters(raw_ostream &OS) const {
+ OS << getType() << " *" << getUpperName() << ", unsigned "
+ << getUpperName() << "Size";
+ }
+ void writeDeclarations(raw_ostream &OS) const {
+ OS << " unsigned " << getLowerName() << "Size;\n";
+ OS << " " << getType() << " *" << getLowerName() << ";";
+ }
+ void writePCHReadDecls(raw_ostream &OS) const {
+ OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
+ OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName()
+ << ";\n";
+ OS << " " << getLowerName() << ".reserve(" << getLowerName()
+ << "Size);\n";
+ OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
+
+ std::string read = ReadPCHRecord(type);
+ OS << " " << getLowerName() << ".push_back(" << read << ");\n";
+ }
+ void writePCHReadArgs(raw_ostream &OS) const {
+ OS << getLowerName() << ".data(), " << getLowerName() << "Size";
+ }
+ void writePCHWrite(raw_ostream &OS) const{
+ OS << " Record.push_back(SA->" << getLowerName() << "_size());\n";
+ OS << " for (" << getAttrName() << "Attr::" << getLowerName()
+ << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
+ << getLowerName() << "_end(); i != e; ++i)\n";
+ OS << " " << WritePCHRecord(type, "(*i)");
+ }
+ };
+
+ class EnumArgument : public Argument {
+ std::string type;
+ std::vector<StringRef> values, enums;
+ public:
+ EnumArgument(Record &Arg, StringRef Attr)
+ : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
+ values(getValueAsListOfStrings(Arg, "Values")),
+ enums(getValueAsListOfStrings(Arg, "Enums"))
+ {}
+
+ void writeAccessors(raw_ostream &OS) const {
+ OS << " " << type << " get" << getUpperName() << "() const {\n";
+ OS << " return " << getLowerName() << ";\n";
+ OS << " }";
+ }
+ void writeCloneArgs(raw_ostream &OS) const {
+ OS << getLowerName();
+ }
+ void writeCtorInitializers(raw_ostream &OS) const {
+ OS << getLowerName() << "(" << getUpperName() << ")";
+ }
+ void writeCtorParameters(raw_ostream &OS) const {
+ OS << type << " " << getUpperName();
+ }
+ void writeDeclarations(raw_ostream &OS) const {
+ // Calculate the various enum values
+ std::vector<StringRef> uniques(enums);
+ std::sort(uniques.begin(), uniques.end());
+ uniques.erase(std::unique(uniques.begin(), uniques.end()),
+ uniques.end());
+ // FIXME: Emit a proper error
+ assert(!uniques.empty());
+
+ std::vector<StringRef>::iterator i = uniques.begin(),
+ e = uniques.end();
+ // The last one needs to not have a comma.
+ --e;
+
+ OS << "public:\n";
+ OS << " enum " << type << " {\n";
+ for (; i != e; ++i)
+ OS << " " << *i << ",\n";
+ OS << " " << *e << "\n";
+ OS << " };\n";
+ OS << "private:\n";
+ OS << " " << type << " " << getLowerName() << ";";
+ }
+ void writePCHReadDecls(raw_ostream &OS) const {
+ OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName()
+ << "(static_cast<" << getAttrName() << "Attr::" << type
+ << ">(Record[Idx++]));\n";
+ }
+ void writePCHReadArgs(raw_ostream &OS) const {
+ OS << getLowerName();
+ }
+ void writePCHWrite(raw_ostream &OS) const {
+ OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
+ }
+ };
+}
+
+static Argument *createArgument(Record &Arg, StringRef Attr,
+ Record *Search = 0) {
+ if (!Search)
+ Search = &Arg;
+
+ Argument *Ptr = 0;
+ llvm::StringRef ArgName = Search->getName();
+
+ if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
+ else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr);
+ else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr,
+ "Expr *");
+ else if (ArgName == "FunctionArgument")
+ Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
+ else if (ArgName == "IdentifierArgument")
+ Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
+ else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
+ else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
+ else if (ArgName == "TypeArgument")
+ Ptr = new SimpleArgument(Arg, Attr, "QualType");
+ else if (ArgName == "UnsignedArgument")
+ Ptr = new SimpleArgument(Arg, Attr, "unsigned");
+ else if (ArgName == "VariadicUnsignedArgument")
+ Ptr = new VariadicArgument(Arg, Attr, "unsigned");
+
+ if (!Ptr) {
+ std::vector<Record*> Bases = Search->getSuperClasses();
+ for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
+ i != e; ++i) {
+ Ptr = createArgument(Arg, Attr, *i);
+ if (Ptr)
+ break;
+ }
+ }
+ return Ptr;
+}
+
void ClangAttrClassEmitter::run(raw_ostream &OS) {
OS << "// This file is generated by TableGen. Do not edit.\n\n";
OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n";
@@ -28,29 +462,63 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) {
i != e; ++i) {
Record &R = **i;
- if (R.getValueAsBit("DoNotEmit"))
- continue;
-
OS << "class " << R.getName() << "Attr : public Attr {\n";
- std::vector<Record*> Args = R.getValueAsListOfDefs("Args");
+ std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+ std::vector<Argument*> Args;
+ std::vector<Argument*>::iterator ai, ae;
+ Args.reserve(ArgRecords.size());
+
+ for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
+ re = ArgRecords.end();
+ ri != re; ++ri) {
+ Record &ArgRecord = **ri;
+ Argument *Arg = createArgument(ArgRecord, R.getName());
+ assert(Arg);
+ Args.push_back(Arg);
+
+ Arg->writeDeclarations(OS);
+ OS << "\n\n";
+ }
- // FIXME: Handle arguments
- assert(Args.empty() && "Can't yet handle arguments");
+ ae = Args.end();
OS << "\n public:\n";
- OS << " " << R.getName() << "Attr(";
+ OS << " " << R.getName() << "Attr(SourceLocation L, ASTContext &Ctx\n";
- // Arguments go here
+ for (ai = Args.begin(); ai != ae; ++ai) {
+ OS << " , ";
+ (*ai)->writeCtorParameters(OS);
+ OS << "\n";
+ }
- OS << ")\n";
- OS << " : Attr(attr::" << R.getName() << ")";
+ OS << " )\n";
+ OS << " : Attr(attr::" << R.getName() << ", L)\n";
- // Arguments go here
-
- OS << " {}\n\n";
+ for (ai = Args.begin(); ai != ae; ++ai) {
+ OS << " , ";
+ (*ai)->writeCtorInitializers(OS);
+ OS << "\n";
+ }
+
+ OS << " {\n";
+
+ for (ai = Args.begin(); ai != ae; ++ai) {
+ (*ai)->writeCtorBody(OS);
+ OS << "\n";
+ }
+ OS << " }\n\n";
+
+ OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
+
+ for (ai = Args.begin(); ai != ae; ++ai) {
+ (*ai)->writeAccessors(OS);
+ OS << "\n\n";
+ }
+
+ OS << R.getValueAsCode("AdditionalMembers");
+ OS << "\n\n";
- OS << " virtual Attr *clone (ASTContext &C) const;\n";
OS << " static bool classof(const Attr *A) { return A->getKind() == "
<< "attr::" << R.getName() << "; }\n";
OS << " static bool classof(const " << R.getName()
@@ -61,6 +529,34 @@ void ClangAttrClassEmitter::run(raw_ostream &OS) {
OS << "#endif\n";
}
+void ClangAttrImplEmitter::run(raw_ostream &OS) {
+ OS << "// This file is generated by TableGen. Do not edit.\n\n";
+
+ std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+ std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
+ std::vector<Argument*>::iterator ai, ae;
+
+ for (; i != e; ++i) {
+ Record &R = **i;
+ std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+ std::vector<Argument*> Args;
+ for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
+ Args.push_back(createArgument(**ri, R.getName()));
+
+ for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
+ (*ai)->writeAccessorDefinitions(OS);
+
+ OS << R.getName() << "Attr *" << R.getName()
+ << "Attr::clone(ASTContext &C) const {\n";
+ OS << " return new (C) " << R.getName() << "Attr(getLocation(), C";
+ for (ai = Args.begin(); ai != ae; ++ai) {
+ OS << ", ";
+ (*ai)->writeCloneArgs(OS);
+ }
+ OS << ");\n}\n\n";
+ }
+}
+
void ClangAttrListEmitter::run(raw_ostream &OS) {
OS << "// This file is generated by TableGen. Do not edit.\n\n";
@@ -82,3 +578,61 @@ void ClangAttrListEmitter::run(raw_ostream &OS) {
OS << "#undef LAST_ATTR\n";
OS << "#undef ATTR\n";
}
+
+void ClangAttrPCHReadEmitter::run(raw_ostream &OS) {
+ OS << "// This file is generated by TableGen. Do not edi.\n\n";
+
+ std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
+ ArgRecords;
+ std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
+ std::vector<Argument*> Args;
+ std::vector<Argument*>::iterator ri, re;
+
+ OS << " switch (Kind) {\n";
+ OS << " default:\n";
+ OS << " assert(0 && \"Unknown attribute!\");\n";
+ OS << " break;\n";
+ for (; i != e; ++i) {
+ Record &R = **i;
+ OS << " case attr::" << R.getName() << ": {\n";
+ ArgRecords = R.getValueAsListOfDefs("Args");
+ Args.clear();
+ for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
+ Argument *A = createArgument(**ai, R.getName());
+ Args.push_back(A);
+ A->writePCHReadDecls(OS);
+ }
+ OS << " New = new (*Context) " << R.getName() << "Attr(Loc, *Context";
+ for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
+ OS << ", ";
+ (*ri)->writePCHReadArgs(OS);
+ }
+ OS << ");\n";
+ OS << " break;\n";
+ OS << " }\n";
+ }
+ OS << " }\n";
+}
+
+void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) {
+ std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
+ std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
+
+ OS << " switch (A->getKind()) {\n";
+ OS << " default:\n";
+ OS << " llvm_unreachable(\"Unknown attribute kind!\");\n";
+ OS << " break;\n";
+ for (; i != e; ++i) {
+ Record &R = **i;
+ OS << " case attr::" << R.getName() << ": {\n";
+ Args = R.getValueAsListOfDefs("Args");
+ if (!Args.empty())
+ OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()
+ << "Attr>(A);\n";
+ for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
+ createArgument(**ai, R.getName())->writePCHWrite(OS);
+ OS << " break;\n";
+ OS << " }\n";
+ }
+ OS << " }\n";
+}
diff --git a/contrib/llvm/utils/TableGen/ClangAttrEmitter.h b/contrib/llvm/utils/TableGen/ClangAttrEmitter.h
index 5ce1c87..8314982 100644
--- a/contrib/llvm/utils/TableGen/ClangAttrEmitter.h
+++ b/contrib/llvm/utils/TableGen/ClangAttrEmitter.h
@@ -31,6 +31,19 @@ class ClangAttrClassEmitter : public TableGenBackend {
void run(raw_ostream &OS);
};
+/// ClangAttrImplEmitter - class emits the class method defintions for
+/// attributes for clang.
+class ClangAttrImplEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+
+ public:
+ explicit ClangAttrImplEmitter(RecordKeeper &R)
+ : Records(R)
+ {}
+
+ void run(raw_ostream &OS);
+};
+
/// ClangAttrListEmitter - class emits the enumeration list for attributes for
/// clang.
class ClangAttrListEmitter : public TableGenBackend {
@@ -44,6 +57,32 @@ class ClangAttrListEmitter : public TableGenBackend {
void run(raw_ostream &OS);
};
+/// ClangAttrPCHReadEmitter - class emits the code to read an attribute from
+/// a clang precompiled header.
+class ClangAttrPCHReadEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+
+public:
+ explicit ClangAttrPCHReadEmitter(RecordKeeper &R)
+ : Records(R)
+ {}
+
+ void run(raw_ostream &OS);
+};
+
+/// ClangAttrPCHWriteEmitter - class emits the code to read an attribute from
+/// a clang precompiled header.
+class ClangAttrPCHWriteEmitter : public TableGenBackend {
+ RecordKeeper &Records;
+
+public:
+ explicit ClangAttrPCHWriteEmitter(RecordKeeper &R)
+ : Records(R)
+ {}
+
+ void run(raw_ostream &OS);
+};
+
}
#endif
diff --git a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 878ed09..303aa6c 100644
--- a/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2197,10 +2197,10 @@ private:
if (IntInfo->ModRef >= CodeGenIntrinsic::ReadArgMem)
mayLoad = true;// These may load memory.
- if (IntInfo->ModRef >= CodeGenIntrinsic::WriteArgMem)
+ if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteArgMem)
mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
- if (IntInfo->ModRef >= CodeGenIntrinsic::WriteMem)
+ if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem)
// WriteMem intrinsics can have other strange effects.
HasSideEffects = true;
}
diff --git a/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp b/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
index 35b54a5..01a1fe1 100644
--- a/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -102,6 +102,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
isReturn = R->getValueAsBit("isReturn");
isBranch = R->getValueAsBit("isBranch");
isIndirectBranch = R->getValueAsBit("isIndirectBranch");
+ isCompare = R->getValueAsBit("isCompare");
isBarrier = R->getValueAsBit("isBarrier");
isCall = R->getValueAsBit("isCall");
canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
diff --git a/contrib/llvm/utils/TableGen/CodeGenInstruction.h b/contrib/llvm/utils/TableGen/CodeGenInstruction.h
index 946c2d0..b02d0d3 100644
--- a/contrib/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/contrib/llvm/utils/TableGen/CodeGenInstruction.h
@@ -123,6 +123,7 @@ namespace llvm {
bool isReturn;
bool isBranch;
bool isIndirectBranch;
+ bool isCompare;
bool isBarrier;
bool isCall;
bool canFoldAsLoad;
diff --git a/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h b/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
index 7e7bdf9..3208c0d 100644
--- a/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/contrib/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -60,7 +60,7 @@ namespace llvm {
// Memory mod/ref behavior of this intrinsic.
enum {
- NoMem, ReadArgMem, ReadMem, WriteArgMem, WriteMem
+ NoMem, ReadArgMem, ReadMem, ReadWriteArgMem, ReadWriteMem
} ModRef;
/// This is set to true if the intrinsic is overloaded by its argument
diff --git a/contrib/llvm/utils/TableGen/CodeGenRegisters.h b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
index 344f77f..ccd3d22 100644
--- a/contrib/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/contrib/llvm/utils/TableGen/CodeGenRegisters.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/DenseMap.h"
#include <string>
#include <vector>
+#include <set>
#include <cstdlib>
namespace llvm {
@@ -55,6 +56,37 @@ namespace llvm {
assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
abort();
}
+
+ // Returns true if RC is a strict subclass.
+ // RC is a sub-class of this class if it is a valid replacement for any
+ // instruction operand where a register of this classis required. It must
+ // satisfy these conditions:
+ //
+ // 1. All RC registers are also in this.
+ // 2. The RC spill size must not be smaller than our spill size.
+ // 3. RC spill alignment must be compatible with ours.
+ //
+ bool hasSubClass(const CodeGenRegisterClass *RC) const {
+
+ if (RC->Elements.size() > Elements.size() ||
+ (SpillAlignment && RC->SpillAlignment % SpillAlignment) ||
+ SpillSize > RC->SpillSize)
+ return false;
+
+ std::set<Record*> RegSet;
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+ Record *Reg = Elements[i];
+ RegSet.insert(Reg);
+ }
+
+ for (unsigned i = 0, e = RC->Elements.size(); i != e; ++i) {
+ Record *Reg = RC->Elements[i];
+ if (!RegSet.count(Reg))
+ return false;
+ }
+
+ return true;
+ }
CodeGenRegisterClass(Record *R);
};
diff --git a/contrib/llvm/utils/TableGen/CodeGenTarget.cpp b/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
index d8130fb..cbfe2ad 100644
--- a/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/contrib/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -333,7 +333,7 @@ void CodeGenTarget::ComputeInstrsByEnum() const {
const char *const FixedInstrs[] = {
"PHI",
"INLINEASM",
- "DBG_LABEL",
+ "PROLOG_LABEL",
"EH_LABEL",
"GC_LABEL",
"KILL",
@@ -434,7 +434,7 @@ std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
TheDef = R;
std::string DefName = R->getName();
- ModRef = WriteMem;
+ ModRef = ReadWriteMem;
isOverloaded = false;
isCommutative = false;
@@ -555,10 +555,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
ModRef = ReadArgMem;
else if (Property->getName() == "IntrReadMem")
ModRef = ReadMem;
- else if (Property->getName() == "IntrWriteArgMem")
- ModRef = WriteArgMem;
- else if (Property->getName() == "IntrWriteMem")
- ModRef = WriteMem;
+ else if (Property->getName() == "IntrReadWriteArgMem")
+ ModRef = ReadWriteArgMem;
else if (Property->getName() == "Commutative")
isCommutative = true;
else if (Property->isSubClassOf("NoCapture")) {
diff --git a/contrib/llvm/utils/TableGen/DAGISelEmitter.cpp b/contrib/llvm/utils/TableGen/DAGISelEmitter.cpp
index 04c7710..8a73404 100644
--- a/contrib/llvm/utils/TableGen/DAGISelEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelEmitter.cpp
@@ -57,51 +57,6 @@ static unsigned getResultPatternSize(TreePatternNode *P,
return Cost;
}
-//===----------------------------------------------------------------------===//
-// Predicate emitter implementation.
-//
-
-void DAGISelEmitter::EmitPredicateFunctions(raw_ostream &OS) {
- OS << "\n// Predicate functions.\n";
-
- // Walk the pattern fragments, adding them to a map, which sorts them by
- // name.
- typedef std::map<std::string, std::pair<Record*, TreePattern*> > PFsByNameTy;
- PFsByNameTy PFsByName;
-
- for (CodeGenDAGPatterns::pf_iterator I = CGP.pf_begin(), E = CGP.pf_end();
- I != E; ++I)
- PFsByName.insert(std::make_pair(I->first->getName(), *I));
-
-
- for (PFsByNameTy::iterator I = PFsByName.begin(), E = PFsByName.end();
- I != E; ++I) {
- Record *PatFragRecord = I->second.first;// Record that derives from PatFrag.
- TreePattern *P = I->second.second;
-
- // If there is a code init for this fragment, emit the predicate code.
- std::string Code = PatFragRecord->getValueAsCode("Predicate");
- if (Code.empty()) continue;
-
- if (P->getOnlyTree()->isLeaf())
- OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *N) const {\n";
- else {
- std::string ClassName =
- CGP.getSDNodeInfo(P->getOnlyTree()->getOperator()).getSDClassName();
- const char *C2 = ClassName == "SDNode" ? "N" : "inN";
-
- OS << "inline bool Predicate_" << PatFragRecord->getName()
- << "(SDNode *" << C2 << ") const {\n";
- if (ClassName != "SDNode")
- OS << " " << ClassName << " *N = cast<" << ClassName << ">(inN);\n";
- }
- OS << Code << "\n}\n";
- }
-
- OS << "\n\n";
-}
-
namespace {
// PatternSortingPredicate - return true if we prefer to match LHS before RHS.
// In particular, we want to match maximal patterns first and lowest cost within
@@ -168,9 +123,6 @@ void DAGISelEmitter::run(raw_ostream &OS) {
errs() << "\n";
});
- // FIXME: These are being used by hand written code, gross.
- EmitPredicateFunctions(OS);
-
// Add all the patterns to a temporary list so we can sort them.
std::vector<const PatternToMatch*> Patterns;
for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
diff --git a/contrib/llvm/utils/TableGen/DAGISelEmitter.h b/contrib/llvm/utils/TableGen/DAGISelEmitter.h
index 5ffdde8..2117e65 100644
--- a/contrib/llvm/utils/TableGen/DAGISelEmitter.h
+++ b/contrib/llvm/utils/TableGen/DAGISelEmitter.h
@@ -31,8 +31,6 @@ public:
// run - Output the isel, returning true on failure.
void run(raw_ostream &OS);
-private:
- void EmitPredicateFunctions(raw_ostream &OS);
};
} // End llvm namespace
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 3750bd8..dfbfe80 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains code to generate C++ code a matcher.
+// This file contains code to generate C++ code for a matcher.
//
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index eb528eb..aba6636 100644
--- a/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/contrib/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -689,8 +689,8 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
// This is a predicate or optional def operand; emit the
// 'default ops' operands.
- const DAGDefaultOperand &DefaultOp =
- CGP.getDefaultOperand(II.OperandList[InstOpNo].Rec);
+ const DAGDefaultOperand &DefaultOp
+ = CGP.getDefaultOperand(OperandNode);
for (unsigned i = 0, e = DefaultOp.DefaultOps.size(); i != e; ++i)
EmitResultOperand(DefaultOp.DefaultOps[i], InstOps);
continue;
@@ -908,6 +908,3 @@ Matcher *llvm::ConvertPatternToMatcher(const PatternToMatch &Pattern,
// Unconditional match.
return Gen.GetMatcher();
}
-
-
-
diff --git a/contrib/llvm/utils/TableGen/EDEmitter.cpp b/contrib/llvm/utils/TableGen/EDEmitter.cpp
index c5ee828..525fffb 100644
--- a/contrib/llvm/utils/TableGen/EDEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/EDEmitter.cpp
@@ -84,34 +84,6 @@ namespace {
}
};
- class StructEmitter {
- private:
- std::string Name;
- typedef std::pair<const char*, const char*> member;
- std::vector< member > Members;
- public:
- StructEmitter(const char *N) : Name(N) {
- }
- void addMember(const char *t, const char *n) {
- member m(t, n);
- Members.push_back(m);
- }
- void emit(raw_ostream &o, unsigned int &i) {
- o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
- i += 2;
-
- unsigned int index = 0;
- unsigned int numMembers = Members.size();
- for (index = 0; index < numMembers; ++index) {
- o.indent(i) << Members[index].first << " ";
- o.indent(i) << Members[index].second << ";" << "\n";
- }
-
- i -= 2;
- o.indent(i) << "};" << "\n";
- }
- };
-
class ConstantEmitter {
public:
virtual ~ConstantEmitter() { }
@@ -126,10 +98,6 @@ namespace {
const char* String;
};
public:
- LiteralConstantEmitter(const char *string) :
- IsNumber(false),
- String(string) {
- }
LiteralConstantEmitter(int number = 0) :
IsNumber(true),
Number(number) {
@@ -139,11 +107,6 @@ namespace {
Number = 0;
String = string;
}
- void set(int number) {
- IsNumber = true;
- String = NULL;
- Number = number;
- }
bool is(const char *string) {
return !strcmp(String, string);
}
@@ -339,6 +302,7 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type,
MEM("f80mem");
MEM("opaque80mem");
MEM("i128mem");
+ MEM("i256mem");
MEM("f128mem");
MEM("f256mem");
MEM("opaque512mem");
@@ -577,6 +541,7 @@ static void X86ExtractSemantics(
static int ARMFlagFromOpName(LiteralConstantEmitter *type,
const std::string &name) {
REG("GPR");
+ REG("rGPR");
REG("tcGPR");
REG("cc_out");
REG("s_cc_out");
@@ -597,6 +562,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("cps_opt");
IMM("vfp_f64imm");
IMM("vfp_f32imm");
+ IMM("memb_opt");
IMM("msr_mask");
IMM("neg_zero");
IMM("imm0_31");
@@ -605,6 +571,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("jt2block_operand");
IMM("t_imm_s4");
IMM("pclabel");
+ IMM("shift_imm");
MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I
@@ -895,21 +862,3 @@ void EDEmitter::run(raw_ostream &o) {
o << "}\n";
}
-
-void EDEmitter::runHeader(raw_ostream &o) {
- EmitSourceFileHeader("Enhanced Disassembly Info Header", o);
-
- o << "#ifndef EDInfo_" << "\n";
- o << "#define EDInfo_" << "\n";
- o << "\n";
- o << "#define EDIS_MAX_OPERANDS " << format("%d", EDIS_MAX_OPERANDS) << "\n";
- o << "#define EDIS_MAX_SYNTAXES " << format("%d", EDIS_MAX_SYNTAXES) << "\n";
- o << "\n";
-
- unsigned int i = 0;
-
- emitCommonEnums(o, i);
-
- o << "\n";
- o << "#endif" << "\n";
-}
diff --git a/contrib/llvm/utils/TableGen/EDEmitter.h b/contrib/llvm/utils/TableGen/EDEmitter.h
index 9e40a8b..e30373f 100644
--- a/contrib/llvm/utils/TableGen/EDEmitter.h
+++ b/contrib/llvm/utils/TableGen/EDEmitter.h
@@ -27,9 +27,6 @@ namespace llvm {
// run - Output the instruction table.
void run(raw_ostream &o);
-
- // runHeader - Emit a header file that allows use of the instruction table.
- void runHeader(raw_ostream &o);
};
} // End llvm namespace
diff --git a/contrib/llvm/utils/TableGen/FastISelEmitter.cpp b/contrib/llvm/utils/TableGen/FastISelEmitter.cpp
index 08fc139..6c16fcf 100644
--- a/contrib/llvm/utils/TableGen/FastISelEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/FastISelEmitter.cpp
@@ -54,6 +54,7 @@ struct OperandsSignature {
bool initialize(TreePatternNode *InstPatNode,
const CodeGenTarget &Target,
MVT::SimpleValueType VT) {
+
if (!InstPatNode->isLeaf()) {
if (InstPatNode->getOperator()->getName() == "imm") {
Operands.push_back("i");
@@ -69,6 +70,7 @@ struct OperandsSignature {
for (unsigned i = 0, e = InstPatNode->getNumChildren(); i != e; ++i) {
TreePatternNode *Op = InstPatNode->getChild(i);
+
// For now, filter out any operand with a predicate.
// For now, filter out any operand with multiple values.
if (!Op->getPredicateFns().empty() ||
@@ -105,13 +107,15 @@ struct OperandsSignature {
RC = Target.getRegisterClassForRegister(OpLeafRec);
else
return false;
- // For now, require the register operands' register classes to all
- // be the same.
+
+ // For now, this needs to be a register class of some sort.
if (!RC)
return false;
- // For now, all the operands must have the same register class.
+
+ // For now, all the operands must have the same register class or be
+ // a strict subclass of the destination.
if (DstRC) {
- if (DstRC != RC)
+ if (DstRC != RC && !DstRC->hasSubClass(RC))
return false;
} else
DstRC = RC;
@@ -208,7 +212,8 @@ class FastISelMap {
typedef std::map<MVT::SimpleValueType, PredMap> RetPredMap;
typedef std::map<MVT::SimpleValueType, RetPredMap> TypeRetPredMap;
typedef std::map<std::string, TypeRetPredMap> OpcodeTypeRetPredMap;
- typedef std::map<OperandsSignature, OpcodeTypeRetPredMap> OperandsOpcodeTypeRetPredMap;
+ typedef std::map<OperandsSignature, OpcodeTypeRetPredMap>
+ OperandsOpcodeTypeRetPredMap;
OperandsOpcodeTypeRetPredMap SimplePatterns;
@@ -260,7 +265,7 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op);
if (II.OperandList.empty())
continue;
-
+
// For now, ignore multi-instruction patterns.
bool MultiInsts = false;
for (unsigned i = 0, e = Dst->getNumChildren(); i != e; ++i) {
@@ -287,6 +292,10 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
if (!DstRC)
continue;
} else {
+ // If this isn't a leaf, then continue since the register classes are
+ // a bit too complicated for now.
+ if (!Dst->getChild(1)->isLeaf()) continue;
+
DefInit *SR = dynamic_cast<DefInit*>(Dst->getChild(1)->getLeafValue());
if (SR)
SubRegNo = getQualifiedName(SR->getDef());
@@ -371,7 +380,8 @@ void FastISelMap::CollectPatterns(CodeGenDAGPatterns &CGP) {
SubRegNo,
PhysRegInputs
};
- assert(!SimplePatterns[Operands][OpcodeName][VT][RetVT].count(PredicateCheck) &&
+ assert(!SimplePatterns[Operands][OpcodeName][VT][RetVT]
+ .count(PredicateCheck) &&
"Duplicate pattern!");
SimplePatterns[Operands][OpcodeName][VT][RetVT][PredicateCheck] = Memo;
}
diff --git a/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp b/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
index f28af15..4d3aa5e 100644
--- a/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -270,6 +270,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
if (Inst.isReturn) OS << "|(1<<TID::Return)";
if (Inst.isBranch) OS << "|(1<<TID::Branch)";
if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)";
+ if (Inst.isCompare) OS << "|(1<<TID::Compare)";
if (Inst.isBarrier) OS << "|(1<<TID::Barrier)";
if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)";
if (Inst.isCall) OS << "|(1<<TID::Call)";
diff --git a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
index d7a9051..ba30d97 100644
--- a/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -545,7 +545,7 @@ EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
OS << "switch (iid) {\n";
OS << "default:\n return UnknownModRefBehavior;\n";
for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
- if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem)
+ if (Ints[i].ModRef == CodeGenIntrinsic::ReadWriteMem)
continue;
OS << "case " << TargetPrefix << "Intrinsic::" << Ints[i].EnumName
<< ":\n";
@@ -559,7 +559,7 @@ EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
case CodeGenIntrinsic::ReadMem:
OS << " return OnlyReadsMemory;\n";
break;
- case CodeGenIntrinsic::WriteArgMem:
+ case CodeGenIntrinsic::ReadWriteArgMem:
OS << " return AccessesArguments;\n";
break;
}
diff --git a/contrib/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp b/contrib/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
index da2d54f..8b81e14 100644
--- a/contrib/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
@@ -33,6 +33,7 @@ namespace {
/// Typedefs
typedef std::vector<Record*> RecordVector;
+typedef std::vector<const DagInit*> DagVector;
typedef std::vector<std::string> StrVector;
//===----------------------------------------------------------------------===//
@@ -49,7 +50,7 @@ const unsigned Indent4 = TabWidth*4;
const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED";
// Name for the "sink" option.
-const char * const SinkOptionName = "AutoGeneratedSinkOption";
+const char * const SinkOptionName = "SinkOption";
//===----------------------------------------------------------------------===//
/// Helper functions
@@ -109,11 +110,6 @@ void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) {
throw GetOperatorName(d) + ": too few arguments!";
}
-// IsDagEmpty - is this DAG marked with an empty marker?
-bool IsDagEmpty (const DagInit& d) {
- return GetOperatorName(d) == "empty_dag_marker";
-}
-
// EscapeVariableName - Escape commas and other symbols not allowed
// in the C++ variable names. Makes it possible to use options named
// like "Wa," (useful for prefix options).
@@ -188,21 +184,25 @@ void apply(F Fun, T0& Arg0, T1& Arg1) {
/// documentation for detailed description of differences.
namespace OptionType {
- enum OptionType { Alias, Switch, Parameter, ParameterList,
- Prefix, PrefixList};
+ enum OptionType { Alias, Switch, SwitchList,
+ Parameter, ParameterList, Prefix, PrefixList };
bool IsAlias(OptionType t) {
return (t == Alias);
}
bool IsList (OptionType t) {
- return (t == ParameterList || t == PrefixList);
+ return (t == SwitchList || t == ParameterList || t == PrefixList);
}
bool IsSwitch (OptionType t) {
return (t == Switch);
}
+ bool IsSwitchList (OptionType t) {
+ return (t == SwitchList);
+ }
+
bool IsParameter (OptionType t) {
return (t == Parameter || t == Prefix);
}
@@ -214,6 +214,8 @@ OptionType::OptionType stringToOptionType(const std::string& T) {
return OptionType::Alias;
else if (T == "switch_option")
return OptionType::Switch;
+ else if (T == "switch_list_option")
+ return OptionType::SwitchList;
else if (T == "parameter_option")
return OptionType::Parameter;
else if (T == "parameter_list_option")
@@ -228,10 +230,9 @@ OptionType::OptionType stringToOptionType(const std::string& T) {
namespace OptionDescriptionFlags {
enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2,
- ReallyHidden = 0x4, Extern = 0x8,
- OneOrMore = 0x10, Optional = 0x20,
- CommaSeparated = 0x40, ForwardNotSplit = 0x80,
- ZeroOrMore = 0x100 };
+ ReallyHidden = 0x4, OneOrMore = 0x8,
+ Optional = 0x10, CommaSeparated = 0x20,
+ ForwardNotSplit = 0x40, ZeroOrMore = 0x80 };
}
/// OptionDescription - Represents data contained in a single
@@ -256,7 +257,13 @@ struct OptionDescription {
/// GenVariableName - Returns the variable name used in the
/// generated C++ code.
- std::string GenVariableName() const;
+ std::string GenVariableName() const
+ { return "autogenerated::" + GenOptionType() + EscapeVariableName(Name); }
+
+ /// GenPlainVariableName - Returns the variable name without the namespace
+ /// prefix.
+ std::string GenPlainVariableName() const
+ { return GenOptionType() + EscapeVariableName(Name); }
/// Merge - Merge two option descriptions.
void Merge (const OptionDescription& other);
@@ -273,9 +280,6 @@ struct OptionDescription {
bool isCommaSeparated() const;
void setCommaSeparated();
- bool isExtern() const;
- void setExtern();
-
bool isForwardNotSplit() const;
void setForwardNotSplit();
@@ -300,12 +304,23 @@ struct OptionDescription {
bool isSwitch() const
{ return OptionType::IsSwitch(this->Type); }
+ bool isSwitchList() const
+ { return OptionType::IsSwitchList(this->Type); }
+
bool isParameter() const
{ return OptionType::IsParameter(this->Type); }
bool isList() const
{ return OptionType::IsList(this->Type); }
+ bool isParameterList() const
+ { return (OptionType::IsList(this->Type)
+ && !OptionType::IsSwitchList(this->Type)); }
+
+private:
+
+ // GenOptionType - Helper function used by GenVariableName().
+ std::string GenOptionType() const;
};
void OptionDescription::CheckConsistency() const {
@@ -359,13 +374,6 @@ void OptionDescription::setForwardNotSplit() {
Flags |= OptionDescriptionFlags::ForwardNotSplit;
}
-bool OptionDescription::isExtern() const {
- return Flags & OptionDescriptionFlags::Extern;
-}
-void OptionDescription::setExtern() {
- Flags |= OptionDescriptionFlags::Extern;
-}
-
bool OptionDescription::isRequired() const {
return Flags & OptionDescriptionFlags::Required;
}
@@ -417,6 +425,8 @@ const char* OptionDescription::GenTypeDeclaration() const {
return "cl::list<std::string>";
case OptionType::Switch:
return "cl::opt<bool>";
+ case OptionType::SwitchList:
+ return "cl::list<bool>";
case OptionType::Parameter:
case OptionType::Prefix:
default:
@@ -424,20 +434,21 @@ const char* OptionDescription::GenTypeDeclaration() const {
}
}
-std::string OptionDescription::GenVariableName() const {
- const std::string& EscapedName = EscapeVariableName(Name);
+std::string OptionDescription::GenOptionType() const {
switch (Type) {
case OptionType::Alias:
- return "AutoGeneratedAlias_" + EscapedName;
+ return "Alias_";
case OptionType::PrefixList:
case OptionType::ParameterList:
- return "AutoGeneratedList_" + EscapedName;
+ return "List_";
case OptionType::Switch:
- return "AutoGeneratedSwitch_" + EscapedName;
+ return "Switch_";
+ case OptionType::SwitchList:
+ return "SwitchList_";
case OptionType::Prefix:
case OptionType::Parameter:
default:
- return "AutoGeneratedParameter_" + EscapedName;
+ return "Parameter_";
}
}
@@ -457,9 +468,11 @@ public:
// wrong type.
const OptionDescription& FindSwitch(const std::string& OptName) const;
const OptionDescription& FindParameter(const std::string& OptName) const;
- const OptionDescription& FindList(const std::string& OptName) const;
+ const OptionDescription& FindParameterList(const std::string& OptName) const;
const OptionDescription&
FindListOrParameter(const std::string& OptName) const;
+ const OptionDescription&
+ FindParameterListOrParameter(const std::string& OptName) const;
/// insertDescription - Insert new OptionDescription into
/// OptionDescriptions list
@@ -489,10 +502,10 @@ OptionDescriptions::FindSwitch(const std::string& OptName) const {
}
const OptionDescription&
-OptionDescriptions::FindList(const std::string& OptName) const {
+OptionDescriptions::FindParameterList(const std::string& OptName) const {
const OptionDescription& OptDesc = this->FindOption(OptName);
- if (!OptDesc.isList())
- throw OptName + ": incorrect option type - should be a list!";
+ if (!OptDesc.isList() || OptDesc.isSwitchList())
+ throw OptName + ": incorrect option type - should be a parameter list!";
return OptDesc;
}
@@ -513,6 +526,16 @@ OptionDescriptions::FindListOrParameter(const std::string& OptName) const {
return OptDesc;
}
+const OptionDescription&
+OptionDescriptions::FindParameterListOrParameter
+(const std::string& OptName) const {
+ const OptionDescription& OptDesc = this->FindOption(OptName);
+ if ((!OptDesc.isList() && !OptDesc.isParameter()) || OptDesc.isSwitchList())
+ throw OptName
+ + ": incorrect option type - should be a parameter list or parameter!";
+ return OptDesc;
+}
+
void OptionDescriptions::InsertDescription (const OptionDescription& o) {
container_type::iterator I = Descriptions.find(o.Name);
if (I != Descriptions.end()) {
@@ -586,7 +609,6 @@ void InvokeDagInitHandler(const FunctionObject* const Obj,
((Obj)->*(h))(Dag, IndentLevel, O);
}
-
template <typename H>
typename HandlerTable<H>::HandlerMap HandlerTable<H>::Handlers_;
@@ -615,7 +637,6 @@ public:
: optDesc_(OD)
{
if (!staticMembersInitialized_) {
- AddHandler("extern", &CollectOptionProperties::onExtern);
AddHandler("help", &CollectOptionProperties::onHelp);
AddHandler("hidden", &CollectOptionProperties::onHidden);
AddHandler("init", &CollectOptionProperties::onInit);
@@ -644,11 +665,6 @@ private:
/// Option property handlers --
/// Methods that handle option properties such as (help) or (hidden).
- void onExtern (const DagInit& d) {
- CheckNumberOfArguments(d, 0);
- optDesc_.setExtern();
- }
-
void onHelp (const DagInit& d) {
CheckNumberOfArguments(d, 1);
optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0)));
@@ -666,8 +682,8 @@ private:
void onCommaSeparated (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (!optDesc_.isList())
- throw "'comma_separated' is valid only on list options!";
+ if (!optDesc_.isParameterList())
+ throw "'comma_separated' is valid only on parameter list options!";
optDesc_.setCommaSeparated();
}
@@ -709,7 +725,7 @@ private:
void onZeroOrMore (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (OptionType::IsList(optDesc_.Type))
+ if (optDesc_.isList())
llvm::errs() << "Warning: specifying the 'zero_or_more' property "
"on a list option has no effect.\n";
@@ -720,7 +736,7 @@ private:
void onOptional (const DagInit& d) {
CheckNumberOfArguments(d, 0);
- if (!OptionType::IsList(optDesc_.Type))
+ if (!optDesc_.isList())
llvm::errs() << "Warning: specifying the 'optional' property"
"on a non-list option has no effect.\n";
@@ -734,7 +750,7 @@ private:
if (val < 2)
throw "Error in the 'multi_val' property: "
"the value must be greater than 1!";
- if (!OptionType::IsList(optDesc_.Type))
+ if (!optDesc_.isParameterList())
throw "The multi_val property is valid only on list options!";
optDesc_.MultiVal = val;
}
@@ -761,16 +777,16 @@ public:
OptionDescription OD(Type, Name);
- if (!OD.isExtern())
- CheckNumberOfArguments(d, 2);
+ CheckNumberOfArguments(d, 2);
if (OD.isAlias()) {
// Aliases store the aliased option name in the 'Help' field.
OD.Help = InitPtrToString(d.getArg(1));
}
- else if (!OD.isExtern()) {
+ else {
processOptionProperties(d, OD);
}
+
OptDescs_.InsertDescription(OD);
}
@@ -789,15 +805,14 @@ private:
/// CollectOptionDescriptions - Collects option properties from all
/// OptionLists.
-void CollectOptionDescriptions (RecordVector::const_iterator B,
- RecordVector::const_iterator E,
+void CollectOptionDescriptions (const RecordVector& V,
OptionDescriptions& OptDescs)
{
// For every OptionList:
- for (; B!=E; ++B) {
- RecordVector::value_type T = *B;
+ for (RecordVector::const_iterator B = V.begin(),
+ E = V.end(); B!=E; ++B) {
// Throws an exception if the value does not exist.
- ListInit* PropList = T->getValueAsListInit("options");
+ ListInit* PropList = (*B)->getValueAsListInit("options");
// For every option description in this list:
// collect the information and
@@ -831,11 +846,7 @@ struct ToolDescription : public RefCountedBase<ToolDescription> {
// Default ctor here is needed because StringMap can only store
// DefaultConstructible objects
- ToolDescription ()
- : CmdLine(0), Actions(0), OutFileOption("-o"),
- Flags(0), OnEmpty(0)
- {}
- ToolDescription (const std::string& n)
+ ToolDescription (const std::string &n = "")
: Name(n), CmdLine(0), Actions(0), OutFileOption("-o"),
Flags(0), OnEmpty(0)
{}
@@ -974,12 +985,12 @@ private:
/// CollectToolDescriptions - Gather information about tool properties
/// from the parsed TableGen data (basically a wrapper for the
/// CollectToolProperties function object).
-void CollectToolDescriptions (RecordVector::const_iterator B,
- RecordVector::const_iterator E,
+void CollectToolDescriptions (const RecordVector& Tools,
ToolDescriptions& ToolDescs)
{
// Iterate over a properties list of every Tool definition
- for (;B!=E;++B) {
+ for (RecordVector::const_iterator B = Tools.begin(),
+ E = Tools.end(); B!=E; ++B) {
const Record* T = *B;
// Throws an exception if the value does not exist.
ListInit* PropList = T->getValueAsListInit("properties");
@@ -995,30 +1006,17 @@ void CollectToolDescriptions (RecordVector::const_iterator B,
/// FillInEdgeVector - Merge all compilation graph definitions into
/// one single edge list.
-void FillInEdgeVector(RecordVector::const_iterator B,
- RecordVector::const_iterator E, RecordVector& Out) {
- for (; B != E; ++B) {
- const ListInit* edges = (*B)->getValueAsListInit("edges");
-
- for (unsigned i = 0; i < edges->size(); ++i)
- Out.push_back(edges->getElementAsRecord(i));
- }
-}
-
-/// CalculatePriority - Calculate the priority of this plugin.
-int CalculatePriority(RecordVector::const_iterator B,
- RecordVector::const_iterator E) {
- int priority = 0;
+void FillInEdgeVector(const RecordVector& CompilationGraphs,
+ DagVector& Out) {
+ for (RecordVector::const_iterator B = CompilationGraphs.begin(),
+ E = CompilationGraphs.end(); B != E; ++B) {
+ const ListInit* Edges = (*B)->getValueAsListInit("edges");
- if (B != E) {
- priority = static_cast<int>((*B)->getValueAsInt("priority"));
-
- if (++B != E)
- throw "More than one 'PluginPriority' instance found: "
- "most probably an error!";
+ for (ListInit::const_iterator B = Edges->begin(),
+ E = Edges->end(); B != E; ++B) {
+ Out.push_back(&InitPtrToDag(*B));
+ }
}
-
- return priority;
}
/// NotInGraph - Helper function object for FilterNotInGraph.
@@ -1038,18 +1036,18 @@ public:
/// FilterNotInGraph - Filter out from ToolDescs all Tools not
/// mentioned in the compilation graph definition.
-void FilterNotInGraph (const RecordVector& EdgeVector,
+void FilterNotInGraph (const DagVector& EdgeVector,
ToolDescriptions& ToolDescs) {
// List all tools mentioned in the graph.
llvm::StringSet<> ToolsInGraph;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("b");
+ const DagInit* Edge = *B;
+ const std::string& NodeA = InitPtrToString(Edge->getArg(0));
+ const std::string& NodeB = InitPtrToString(Edge->getArg(1));
if (NodeA != "root")
ToolsInGraph.insert(NodeA);
@@ -1079,10 +1077,8 @@ void FillInToolToLang (const ToolDescriptions& ToolDescs,
}
/// TypecheckGraph - Check that names for output and input languages
-/// on all edges do match. This doesn't do much when the information
-/// about the whole graph is not available (i.e. when compiling most
-/// plugins).
-void TypecheckGraph (const RecordVector& EdgeVector,
+/// on all edges do match.
+void TypecheckGraph (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs) {
StringMap<StringSet<> > ToolToInLang;
StringMap<std::string> ToolToOutLang;
@@ -1091,11 +1087,11 @@ void TypecheckGraph (const RecordVector& EdgeVector,
StringMap<std::string>::iterator IAE = ToolToOutLang.end();
StringMap<StringSet<> >::iterator IBE = ToolToInLang.end();
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("b");
+ const DagInit* Edge = *B;
+ const std::string& NodeA = InitPtrToString(Edge->getArg(0));
+ const std::string& NodeB = InitPtrToString(Edge->getArg(1));
StringMap<std::string>::iterator IA = ToolToOutLang.find(NodeA);
StringMap<StringSet<> >::iterator IB = ToolToInLang.find(NodeB);
@@ -1234,10 +1230,15 @@ public:
}
};
+/// IsOptionalEdge - Validate that the 'optional_edge' has proper structure.
+bool IsOptionalEdge (const DagInit& Edg) {
+ return (GetOperatorName(Edg) == "optional_edge") && (Edg.getNumArgs() > 2);
+}
+
/// CheckForSuperfluousOptions - Check that there are no side
/// effect-free options (specified only in the OptionList). Otherwise,
/// output a warning.
-void CheckForSuperfluousOptions (const RecordVector& Edges,
+void CheckForSuperfluousOptions (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs,
const OptionDescriptions& OptDescs) {
llvm::StringSet<> nonSuperfluousOptions;
@@ -1255,13 +1256,13 @@ void CheckForSuperfluousOptions (const RecordVector& Edges,
// Add all options mentioned in the 'case' clauses of the
// OptionalEdges of the compilation graph to the set of
// non-superfluous options.
- for (RecordVector::const_iterator B = Edges.begin(), E = Edges.end();
- B != E; ++B) {
- const Record* Edge = *B;
- DagInit& Weight = *Edge->getValueAsDag("weight");
-
- if (!IsDagEmpty(Weight))
+ for (DagVector::const_iterator B = EdgeVector.begin(),
+ E = EdgeVector.end(); B != E; ++B) {
+ const DagInit& Edge = **B;
+ if (IsOptionalEdge(Edge)) {
+ const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id());
+ }
}
// Check that all options in OptDescs belong to the set of
@@ -1440,7 +1441,7 @@ bool EmitCaseTest2Args(const std::string& TestName,
return true;
}
else if (TestName == "element_in_list") {
- const OptionDescription& OptDesc = OptDescs.FindList(OptName);
+ const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName);
const std::string& VarName = OptDesc.GenVariableName();
O << "std::find(" << VarName << ".begin(),\n";
O.indent(IndentLevel + Indent1)
@@ -1815,6 +1816,24 @@ void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName,
}
+/// EmitForEachListElementCycleHeader - Emit common code for iterating through
+/// all elements of a list. Helper function used by
+/// EmitForwardOptionPropertyHandlingCode.
+void EmitForEachListElementCycleHeader (const OptionDescription& D,
+ unsigned IndentLevel,
+ raw_ostream& O) {
+ unsigned IndentLevel1 = IndentLevel + Indent1;
+
+ O.indent(IndentLevel)
+ << "for (" << D.GenTypeDeclaration()
+ << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
+ O.indent(IndentLevel)
+ << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
+ O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
+ << ".getPosition(B - " << D.GenVariableName()
+ << ".begin());\n";
+}
+
/// EmitForwardOptionPropertyHandlingCode - Helper function used to
/// implement EmitActionHandler. Emits code for
/// handling the (forward) and (forward_as) option properties.
@@ -1855,14 +1874,7 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
<< D.GenVariableName() << "));\n";
break;
case OptionType::PrefixList:
- O.indent(IndentLevel)
- << "for (" << D.GenTypeDeclaration()
- << "::iterator B = " << D.GenVariableName() << ".begin(),\n";
- O.indent(IndentLevel)
- << "E = " << D.GenVariableName() << ".end(); B != E;) {\n";
- O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
- << ".getPosition(B - " << D.GenVariableName()
- << ".begin());\n";
+ EmitForEachListElementCycleHeader(D, IndentLevel, O);
O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
<< Name << "\" + " << "*B));\n";
O.indent(IndentLevel1) << "++B;\n";
@@ -1875,14 +1887,7 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
O.indent(IndentLevel) << "}\n";
break;
case OptionType::ParameterList:
- O.indent(IndentLevel)
- << "for (" << D.GenTypeDeclaration() << "::iterator B = "
- << D.GenVariableName() << ".begin(),\n";
- O.indent(IndentLevel) << "E = " << D.GenVariableName()
- << ".end() ; B != E;) {\n";
- O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName()
- << ".getPosition(B - " << D.GenVariableName()
- << ".begin());\n";
+ EmitForEachListElementCycleHeader(D, IndentLevel, O);
O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
<< Name << "\"));\n";
@@ -1893,6 +1898,13 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D,
O.indent(IndentLevel) << "}\n";
break;
+ case OptionType::SwitchList:
+ EmitForEachListElementCycleHeader(D, IndentLevel, O);
+ O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \""
+ << Name << "\"));\n";
+ O.indent(IndentLevel1) << "++B;\n";
+ O.indent(IndentLevel) << "}\n";
+ break;
case OptionType::Alias:
default:
throw "Aliases are not allowed in tool option descriptions!";
@@ -1908,10 +1920,10 @@ struct ActionHandlingCallbackBase
unsigned IndentLevel, raw_ostream& O) const
{
O.indent(IndentLevel)
- << "throw std::runtime_error(\"" <<
- (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0))
- : "Unknown error!")
+ << "PrintError(\""
+ << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!")
<< "\");\n";
+ O.indent(IndentLevel) << "return 1;\n";
}
void onWarningDag(const DagInit& d,
@@ -1926,7 +1938,6 @@ struct ActionHandlingCallbackBase
/// EmitActionHandlersCallback - Emit code that handles actions. Used by
/// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler().
-
class EmitActionHandlersCallback;
typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler)
@@ -1997,7 +2008,12 @@ class EmitActionHandlersCallback :
{
CheckNumberOfArguments(Dag, 1);
const std::string& Name = InitPtrToString(Dag.getArg(0));
- const OptionDescription& D = OptDescs.FindListOrParameter(Name);
+ const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
+
+ if (D.isSwitchList()) {
+ throw std::runtime_error
+ ("forward_value is not allowed with switch_list");
+ }
if (D.isParameter()) {
O.indent(IndentLevel) << "vec.push_back(std::make_pair("
@@ -2005,8 +2021,9 @@ class EmitActionHandlersCallback :
<< D.GenVariableName() << "));\n";
}
else {
- O.indent(IndentLevel) << "for (cl::list<std::string>::iterator B = "
- << D.GenVariableName() << ".begin(), \n";
+ O.indent(IndentLevel) << "for (" << D.GenTypeDeclaration()
+ << "::iterator B = " << D.GenVariableName()
+ << ".begin(), \n";
O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName()
<< ".end(); B != E; ++B)\n";
O.indent(IndentLevel) << "{\n";
@@ -2026,7 +2043,7 @@ class EmitActionHandlersCallback :
CheckNumberOfArguments(Dag, 2);
const std::string& Name = InitPtrToString(Dag.getArg(0));
const std::string& Hook = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D = OptDescs.FindListOrParameter(Name);
+ const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name);
O.indent(IndentLevel) << "vec.push_back(std::make_pair("
<< D.GenVariableName() << ".getPosition("
@@ -2099,25 +2116,32 @@ class EmitActionHandlersCallback :
};
void EmitGenerateActionMethodHeader(const ToolDescription& D,
- bool IsJoin, raw_ostream& O)
+ bool IsJoin, bool Naked,
+ raw_ostream& O)
{
+ O.indent(Indent1) << "int GenerateAction(Action& Out,\n";
+
if (IsJoin)
- O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
+ O.indent(Indent2) << "const PathVector& inFiles,\n";
else
- O.indent(Indent1) << "Action GenerateAction(const sys::Path& inFile,\n";
+ O.indent(Indent2) << "const sys::Path& inFile,\n";
- O.indent(Indent2) << "bool HasChildren,\n";
+ O.indent(Indent2) << "const bool HasChildren,\n";
O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
O.indent(Indent1) << "{\n";
- O.indent(Indent2) << "std::string cmd;\n";
- O.indent(Indent2) << "std::string out_file;\n";
- O.indent(Indent2) << "std::vector<std::pair<unsigned, std::string> > vec;\n";
- O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
- O.indent(Indent2) << "bool no_out_file = false;\n";
- O.indent(Indent2) << "const char* output_suffix = \""
- << D.OutputSuffix << "\";\n";
+
+ if (!Naked) {
+ O.indent(Indent2) << "std::string cmd;\n";
+ O.indent(Indent2) << "std::string out_file;\n";
+ O.indent(Indent2)
+ << "std::vector<std::pair<unsigned, std::string> > vec;\n";
+ O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n";
+ O.indent(Indent2) << "bool no_out_file = false;\n";
+ O.indent(Indent2) << "std::string output_suffix(\""
+ << D.OutputSuffix << "\");\n";
+ }
}
// EmitGenerateActionMethod - Emit either a normal or a "join" version of the
@@ -2126,7 +2150,7 @@ void EmitGenerateActionMethod (const ToolDescription& D,
const OptionDescriptions& OptDescs,
bool IsJoin, raw_ostream& O) {
- EmitGenerateActionMethodHeader(D, IsJoin, O);
+ EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O);
if (!D.CmdLine)
throw "Tool " + D.Name + " has no cmd_line property!";
@@ -2173,25 +2197,29 @@ void EmitGenerateActionMethod (const ToolDescription& D,
O.indent(Indent3) << "out_file = this->OutFilename("
<< (IsJoin ? "sys::Path(),\n" : "inFile,\n");
- O.indent(Indent4) << "TempDir, stop_compilation, output_suffix).str();\n\n";
+ O.indent(Indent4) <<
+ "TempDir, stop_compilation, output_suffix.c_str()).str();\n\n";
O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n";
O.indent(Indent2) << "}\n\n";
// Handle the Sink property.
+ std::string SinkOption("autogenerated::");
+ SinkOption += SinkOptionName;
if (D.isSink()) {
- O.indent(Indent2) << "if (!" << SinkOptionName << ".empty()) {\n";
+ O.indent(Indent2) << "if (!" << SinkOption << ".empty()) {\n";
O.indent(Indent3) << "for (cl::list<std::string>::iterator B = "
- << SinkOptionName << ".begin(), E = " << SinkOptionName
+ << SinkOption << ".begin(), E = " << SinkOption
<< ".end(); B != E; ++B)\n";
- O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOptionName
- << ".getPosition(B - " << SinkOptionName
+ O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOption
+ << ".getPosition(B - " << SinkOption
<< ".begin()), *B));\n";
O.indent(Indent2) << "}\n";
}
- O.indent(Indent2) << "return Action(cmd, this->SortArgs(vec), "
+ O.indent(Indent2) << "Out.Construct(cmd, this->SortArgs(vec), "
<< "stop_compilation, out_file);\n";
+ O.indent(Indent2) << "return 0;\n";
O.indent(Indent1) << "}\n\n";
}
@@ -2201,14 +2229,11 @@ void EmitGenerateActionMethods (const ToolDescription& ToolDesc,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
if (!ToolDesc.isJoin()) {
- O.indent(Indent1) << "Action GenerateAction(const PathVector& inFiles,\n";
- O.indent(Indent2) << "bool HasChildren,\n";
- O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n";
- O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n";
- O.indent(Indent2) << "const LanguageMap& LangMap) const\n";
- O.indent(Indent1) << "{\n";
- O.indent(Indent2) << "throw std::runtime_error(\"" << ToolDesc.Name
+ EmitGenerateActionMethodHeader(ToolDesc, /* IsJoin = */ true,
+ /* Naked = */ true, O);
+ O.indent(Indent2) << "PrintError(\"" << ToolDesc.Name
<< " is not a Join tool!\");\n";
+ O.indent(Indent2) << "return -1;\n";
O.indent(Indent1) << "}\n\n";
}
else {
@@ -2321,8 +2346,7 @@ void EmitToolClassDefinition (const ToolDescription& D,
/// EmitOptionDefinitions - Iterate over a list of option descriptions
/// and emit registration code.
void EmitOptionDefinitions (const OptionDescriptions& descs,
- bool HasSink, bool HasExterns,
- raw_ostream& O)
+ bool HasSink, raw_ostream& O)
{
std::vector<OptionDescription> Aliases;
@@ -2336,16 +2360,8 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
continue;
}
- if (val.isExtern())
- O << "extern ";
-
O << val.GenTypeDeclaration() << ' '
- << val.GenVariableName();
-
- if (val.isExtern()) {
- O << ";\n";
- continue;
- }
+ << val.GenPlainVariableName();
O << "(\"" << val.Name << "\"\n";
@@ -2396,7 +2412,7 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
const OptionDescription& val = *B;
O << val.GenTypeDeclaration() << ' '
- << val.GenVariableName()
+ << val.GenPlainVariableName()
<< "(\"" << val.Name << '\"';
const OptionDescription& D = descs.FindOption(val.Help);
@@ -2407,9 +2423,7 @@ void EmitOptionDefinitions (const OptionDescriptions& descs,
// Emit the sink option.
if (HasSink)
- O << (HasExterns ? "extern cl" : "cl")
- << "::list<std::string> " << SinkOptionName
- << (HasExterns ? ";\n" : "(cl::Sink);\n");
+ O << "cl::list<std::string> " << SinkOptionName << "(cl::Sink);\n";
O << '\n';
}
@@ -2492,8 +2506,15 @@ class EmitPreprocessOptionsCallback :
O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n";
for (ListInit::const_iterator B = List.begin(), E = List.end();
B != E; ++B) {
- O.indent(IndentLevel) << OptDesc.GenVariableName() << ".push_back(\""
- << InitPtrToString(*B) << "\");\n";
+ const Init* CurElem = *B;
+ if (OptDesc.isSwitchList())
+ CheckBooleanConstant(CurElem);
+
+ O.indent(IndentLevel)
+ << OptDesc.GenVariableName() << ".push_back(\""
+ << (OptDesc.isSwitchList() ? CurElem->getAsString()
+ : InitPtrToString(CurElem))
+ << "\");\n";
}
}
else if (OptDesc.isSwitch()) {
@@ -2561,11 +2582,11 @@ public:
};
-/// EmitPreprocessOptions - Emit the PreprocessOptionsLocal() function.
+/// EmitPreprocessOptions - Emit the PreprocessOptions() function.
void EmitPreprocessOptions (const RecordKeeper& Records,
const OptionDescriptions& OptDecs, raw_ostream& O)
{
- O << "void PreprocessOptionsLocal() {\n";
+ O << "int PreprocessOptions () {\n";
const RecordVector& OptionPreprocessors =
Records.getAllDerivedDefinitions("OptionPreprocessor");
@@ -2578,58 +2599,101 @@ void EmitPreprocessOptions (const RecordKeeper& Records,
false, OptDecs, O);
}
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";
O << "}\n\n";
}
-/// EmitPopulateLanguageMap - Emit the PopulateLanguageMapLocal() function.
-void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
+class DoEmitPopulateLanguageMap;
+typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler)
+(const DagInit& D);
+
+class DoEmitPopulateLanguageMap
+: public HandlerTable<DoEmitPopulateLanguageMapHandler>
{
- O << "void PopulateLanguageMapLocal(LanguageMap& langMap) {\n";
+private:
+ raw_ostream& O_;
- // Get the relevant field out of RecordKeeper
- const Record* LangMapRecord = Records.getDef("LanguageMap");
+public:
+
+ explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) {
+ if (!staticMembersInitialized_) {
+ AddHandler("lang_to_suffixes",
+ &DoEmitPopulateLanguageMap::onLangToSuffixes);
+
+ staticMembersInitialized_ = true;
+ }
+ }
- // It is allowed for a plugin to have no language map.
- if (LangMapRecord) {
+ void operator() (Init* I) {
+ InvokeDagInitHandler(this, I);
+ }
- ListInit* LangsToSuffixesList = LangMapRecord->getValueAsListInit("map");
- if (!LangsToSuffixesList)
- throw "Error in the language map definition!";
+private:
- for (unsigned i = 0; i < LangsToSuffixesList->size(); ++i) {
- const Record* LangToSuffixes = LangsToSuffixesList->getElementAsRecord(i);
+ void onLangToSuffixes (const DagInit& d) {
+ CheckNumberOfArguments(d, 2);
- const std::string& Lang = LangToSuffixes->getValueAsString("lang");
- const ListInit* Suffixes = LangToSuffixes->getValueAsListInit("suffixes");
+ const std::string& Lang = InitPtrToString(d.getArg(0));
+ Init* Suffixes = d.getArg(1);
- for (unsigned i = 0; i < Suffixes->size(); ++i)
- O.indent(Indent1) << "langMap[\""
- << InitPtrToString(Suffixes->getElement(i))
- << "\"] = \"" << Lang << "\";\n";
+ // Second argument to lang_to_suffixes is either a single string...
+ if (typeid(*Suffixes) == typeid(StringInit)) {
+ O_.indent(Indent1) << "langMap[\"" << InitPtrToString(Suffixes)
+ << "\"] = \"" << Lang << "\";\n";
+ }
+ // ...or a list of strings.
+ else {
+ const ListInit& Lst = InitPtrToList(Suffixes);
+ assert(Lst.size() != 0);
+ for (ListInit::const_iterator B = Lst.begin(), E = Lst.end();
+ B != E; ++B) {
+ O_.indent(Indent1) << "langMap[\"" << InitPtrToString(*B)
+ << "\"] = \"" << Lang << "\";\n";
+ }
}
}
+};
+
+/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function.
+void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O)
+{
+ O << "int PopulateLanguageMap (LanguageMap& langMap) {\n";
+
+ // For each LangMap:
+ const RecordVector& LangMaps =
+ Records.getAllDerivedDefinitions("LanguageMap");
+
+ for (RecordVector::const_iterator B = LangMaps.begin(),
+ E = LangMaps.end(); B!=E; ++B) {
+ ListInit* LangMap = (*B)->getValueAsListInit("map");
+ std::for_each(LangMap->begin(), LangMap->end(),
+ DoEmitPopulateLanguageMap(O));
+ }
+
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";
O << "}\n\n";
}
-/// IncDecWeight - Helper function passed to EmitCaseConstructHandler()
-/// by EmitEdgeClass().
-void IncDecWeight (const Init* i, unsigned IndentLevel,
- raw_ostream& O) {
+/// EmitEdgePropertyHandlerCallback - Emits code that handles edge
+/// properties. Helper function passed to EmitCaseConstructHandler() by
+/// EmitEdgeClass().
+void EmitEdgePropertyHandlerCallback (const Init* i, unsigned IndentLevel,
+ raw_ostream& O) {
const DagInit& d = InitPtrToDag(i);
const std::string& OpName = GetOperatorName(d);
if (OpName == "inc_weight") {
O.indent(IndentLevel) << "ret += ";
}
- else if (OpName == "dec_weight") {
- O.indent(IndentLevel) << "ret -= ";
- }
else if (OpName == "error") {
CheckNumberOfArguments(d, 1);
- O.indent(IndentLevel) << "throw std::runtime_error(\""
+ O.indent(IndentLevel) << "PrintError(\""
<< InitPtrToString(d.getArg(0))
<< "\");\n";
+ O.indent(IndentLevel) << "return -1;\n";
return;
}
else {
@@ -2646,7 +2710,7 @@ void IncDecWeight (const Init* i, unsigned IndentLevel,
/// EmitEdgeClass - Emit a single Edge# class.
void EmitEdgeClass (unsigned N, const std::string& Target,
- DagInit* Case, const OptionDescriptions& OptDescs,
+ const DagInit& Case, const OptionDescriptions& OptDescs,
raw_ostream& O) {
// Class constructor.
@@ -2657,40 +2721,48 @@ void EmitEdgeClass (unsigned N, const std::string& Target,
// Function Weight().
O.indent(Indent1)
- << "unsigned Weight(const InputLanguagesSet& InLangs) const {\n";
+ << "int Weight(const InputLanguagesSet& InLangs) const {\n";
O.indent(Indent2) << "unsigned ret = 0;\n";
// Handle the 'case' construct.
- EmitCaseConstructHandler(Case, Indent2, IncDecWeight, false, OptDescs, O);
+ EmitCaseConstructHandler(&Case, Indent2, EmitEdgePropertyHandlerCallback,
+ false, OptDescs, O);
O.indent(Indent2) << "return ret;\n";
O.indent(Indent1) << "}\n\n};\n\n";
}
/// EmitEdgeClasses - Emit Edge* classes that represent graph edges.
-void EmitEdgeClasses (const RecordVector& EdgeVector,
+void EmitEdgeClasses (const DagVector& EdgeVector,
const OptionDescriptions& OptDescs,
raw_ostream& O) {
int i = 0;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeB = Edge->getValueAsString("b");
- DagInit& Weight = *Edge->getValueAsDag("weight");
+ const DagInit& Edge = **B;
+ const std::string& Name = GetOperatorName(Edge);
+
+ if (Name == "optional_edge") {
+ assert(IsOptionalEdge(Edge));
+ const std::string& NodeB = InitPtrToString(Edge.getArg(1));
+
+ const DagInit& Weight = InitPtrToDag(Edge.getArg(2));
+ EmitEdgeClass(i, NodeB, Weight, OptDescs, O);
+ }
+ else if (Name != "edge") {
+ throw "Unknown edge class: '" + Name + "'!";
+ }
- if (!IsDagEmpty(Weight))
- EmitEdgeClass(i, NodeB, &Weight, OptDescs, O);
++i;
}
}
-/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraphLocal()
-/// function.
-void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
+/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function.
+void EmitPopulateCompilationGraph (const DagVector& EdgeVector,
const ToolDescriptions& ToolDescs,
raw_ostream& O)
{
- O << "void PopulateCompilationGraphLocal(CompilationGraph& G) {\n";
+ O << "int PopulateCompilationGraph (CompilationGraph& G) {\n";
for (ToolDescriptions::const_iterator B = ToolDescs.begin(),
E = ToolDescs.end(); B != E; ++B)
@@ -2701,24 +2773,27 @@ void EmitPopulateCompilationGraph (const RecordVector& EdgeVector,
// Insert edges.
int i = 0;
- for (RecordVector::const_iterator B = EdgeVector.begin(),
+ for (DagVector::const_iterator B = EdgeVector.begin(),
E = EdgeVector.end(); B != E; ++B) {
- const Record* Edge = *B;
- const std::string& NodeA = Edge->getValueAsString("a");
- const std::string& NodeB = Edge->getValueAsString("b");
- DagInit& Weight = *Edge->getValueAsDag("weight");
+ const DagInit& Edge = **B;
+ const std::string& NodeA = InitPtrToString(Edge.getArg(0));
+ const std::string& NodeB = InitPtrToString(Edge.getArg(1));
- O.indent(Indent1) << "G.insertEdge(\"" << NodeA << "\", ";
+ O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", ";
- if (IsDagEmpty(Weight))
- O << "new SimpleEdge(\"" << NodeB << "\")";
- else
+ if (IsOptionalEdge(Edge))
O << "new Edge" << i << "()";
+ else
+ O << "new SimpleEdge(\"" << NodeB << "\")";
+
+ O << "))\n";
+ O.indent(Indent2) << "return ret;\n";
- O << ");\n";
++i;
}
+ O << '\n';
+ O.indent(Indent1) << "return 0;\n";
O << "}\n\n";
}
@@ -2762,7 +2837,8 @@ public:
CheckNumberOfArguments(Dag, 2);
const std::string& OptName = InitPtrToString(Dag.getArg(0));
const std::string& HookName = InitPtrToString(Dag.getArg(1));
- const OptionDescription& D = OptDescs_.FindOption(OptName);
+ const OptionDescription& D =
+ OptDescs_.FindParameterListOrParameter(OptName);
HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook
: HookInfo::ArgHook);
@@ -2827,9 +2903,6 @@ public:
this->onCmdLine(InitPtrToString(Arg));
}
- void operator()(const DagInit* Test, unsigned, bool) {
- this->operator()(Test);
- }
void operator()(const Init* Statement, unsigned) {
this->operator()(Statement);
}
@@ -2873,7 +2946,6 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
if (HookNames.empty())
return;
- O << "namespace hooks {\n";
for (HookInfoMap::const_iterator B = HookNames.begin(),
E = HookNames.end(); B != E; ++B) {
const char* HookName = B->first();
@@ -2892,23 +2964,6 @@ void EmitHookDeclarations(const ToolDescriptions& ToolDescs,
O <<");\n";
}
- O << "}\n\n";
-}
-
-/// EmitRegisterPlugin - Emit code to register this plugin.
-void EmitRegisterPlugin(int Priority, raw_ostream& O) {
- O << "struct Plugin : public llvmc::BasePlugin {\n\n";
- O.indent(Indent1) << "int Priority() const { return "
- << Priority << "; }\n\n";
- O.indent(Indent1) << "void PreprocessOptions() const\n";
- O.indent(Indent1) << "{ PreprocessOptionsLocal(); }\n\n";
- O.indent(Indent1) << "void PopulateLanguageMap(LanguageMap& langMap) const\n";
- O.indent(Indent1) << "{ PopulateLanguageMapLocal(langMap); }\n\n";
- O.indent(Indent1)
- << "void PopulateCompilationGraph(CompilationGraph& graph) const\n";
- O.indent(Indent1) << "{ PopulateCompilationGraphLocal(graph); }\n"
- << "};\n\n"
- << "static llvmc::RegisterPlugin<Plugin> RP;\n\n";
}
/// EmitIncludes - Emit necessary #include directives and some
@@ -2916,8 +2971,7 @@ void EmitRegisterPlugin(int Priority, raw_ostream& O) {
void EmitIncludes(raw_ostream& O) {
O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n"
<< "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n"
- << "#include \"llvm/CompilerDriver/ForceLinkageMacros.h\"\n"
- << "#include \"llvm/CompilerDriver/Plugin.h\"\n"
+ << "#include \"llvm/CompilerDriver/Error.h\"\n"
<< "#include \"llvm/CompilerDriver/Tool.h\"\n\n"
<< "#include \"llvm/Support/CommandLine.h\"\n"
@@ -2931,21 +2985,17 @@ void EmitIncludes(raw_ostream& O) {
<< "using namespace llvm;\n"
<< "using namespace llvmc;\n\n"
- << "extern cl::opt<std::string> OutputFilename;\n\n"
-
<< "inline const char* checkCString(const char* s)\n"
<< "{ return s == NULL ? \"\" : s; }\n\n";
}
-/// PluginData - Holds all information about a plugin.
-struct PluginData {
+/// DriverData - Holds all information about the driver.
+struct DriverData {
OptionDescriptions OptDescs;
- bool HasSink;
- bool HasExterns;
ToolDescriptions ToolDescs;
- RecordVector Edges;
- int Priority;
+ DagVector Edges;
+ bool HasSink;
};
/// HasSink - Go through the list of tool descriptions and check if
@@ -2959,46 +3009,27 @@ bool HasSink(const ToolDescriptions& ToolDescs) {
return false;
}
-/// HasExterns - Go through the list of option descriptions and check
-/// if there are any external options.
-bool HasExterns(const OptionDescriptions& OptDescs) {
- for (OptionDescriptions::const_iterator B = OptDescs.begin(),
- E = OptDescs.end(); B != E; ++B)
- if (B->second.isExtern())
- return true;
-
- return false;
-}
-
-/// CollectPluginData - Collect tool and option properties,
-/// compilation graph edges and plugin priority from the parse tree.
-void CollectPluginData (const RecordKeeper& Records, PluginData& Data) {
+/// CollectDriverData - Collect compilation graph edges, tool properties and
+/// option properties from the parse tree.
+void CollectDriverData (const RecordKeeper& Records, DriverData& Data) {
// Collect option properties.
const RecordVector& OptionLists =
Records.getAllDerivedDefinitions("OptionList");
- CollectOptionDescriptions(OptionLists.begin(), OptionLists.end(),
- Data.OptDescs);
+ CollectOptionDescriptions(OptionLists, Data.OptDescs);
// Collect tool properties.
const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool");
- CollectToolDescriptions(Tools.begin(), Tools.end(), Data.ToolDescs);
+ CollectToolDescriptions(Tools, Data.ToolDescs);
Data.HasSink = HasSink(Data.ToolDescs);
- Data.HasExterns = HasExterns(Data.OptDescs);
// Collect compilation graph edges.
const RecordVector& CompilationGraphs =
Records.getAllDerivedDefinitions("CompilationGraph");
- FillInEdgeVector(CompilationGraphs.begin(), CompilationGraphs.end(),
- Data.Edges);
-
- // Calculate the priority of this plugin.
- const RecordVector& Priorities =
- Records.getAllDerivedDefinitions("PluginPriority");
- Data.Priority = CalculatePriority(Priorities.begin(), Priorities.end());
+ FillInEdgeVector(CompilationGraphs, Data.Edges);
}
-/// CheckPluginData - Perform some sanity checks on the collected data.
-void CheckPluginData(PluginData& Data) {
+/// CheckDriverData - Perform some sanity checks on the collected data.
+void CheckDriverData(DriverData& Data) {
// Filter out all tools not mentioned in the compilation graph.
FilterNotInGraph(Data.Edges, Data.ToolDescs);
@@ -3010,24 +3041,24 @@ void CheckPluginData(PluginData& Data) {
CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs);
}
-void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
+void EmitDriverCode(const DriverData& Data, raw_ostream& O) {
// Emit file header.
EmitIncludes(O);
// Emit global option registration code.
- EmitOptionDefinitions(Data.OptDescs, Data.HasSink, Data.HasExterns, O);
+ O << "namespace llvmc {\n"
+ << "namespace autogenerated {\n\n";
+ EmitOptionDefinitions(Data.OptDescs, Data.HasSink, O);
+ O << "} // End namespace autogenerated.\n"
+ << "} // End namespace llvmc.\n\n";
// Emit hook declarations.
+ O << "namespace hooks {\n";
EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O);
+ O << "} // End namespace hooks.\n\n";
O << "namespace {\n\n";
-
- // Emit PreprocessOptionsLocal() function.
- EmitPreprocessOptions(Records, Data.OptDescs, O);
-
- // Emit PopulateLanguageMapLocal() function
- // (language map maps from file extensions to language names).
- EmitPopulateLanguageMap(Records, O);
+ O << "using namespace llvmc::autogenerated;\n\n";
// Emit Tool classes.
for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(),
@@ -3037,18 +3068,23 @@ void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
// Emit Edge# classes.
EmitEdgeClasses(Data.Edges, Data.OptDescs, O);
- // Emit PopulateCompilationGraphLocal() function.
- EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
-
- // Emit code for plugin registration.
- EmitRegisterPlugin(Data.Priority, O);
-
O << "} // End anonymous namespace.\n\n";
- // Force linkage magic.
O << "namespace llvmc {\n";
- O << "LLVMC_FORCE_LINKAGE_DECL(LLVMC_PLUGIN_NAME) {}\n";
- O << "}\n";
+ O << "namespace autogenerated {\n\n";
+
+ // Emit PreprocessOptions() function.
+ EmitPreprocessOptions(Records, Data.OptDescs, O);
+
+ // Emit PopulateLanguageMap() function
+ // (language map maps from file extensions to language names).
+ EmitPopulateLanguageMap(Records, O);
+
+ // Emit PopulateCompilationGraph() function.
+ EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O);
+
+ O << "} // End namespace autogenerated.\n";
+ O << "} // End namespace llvmc.\n\n";
// EOF
}
@@ -3060,13 +3096,13 @@ void EmitPluginCode(const PluginData& Data, raw_ostream& O) {
/// run - The back-end entry point.
void LLVMCConfigurationEmitter::run (raw_ostream &O) {
try {
- PluginData Data;
+ DriverData Data;
- CollectPluginData(Records, Data);
- CheckPluginData(Data);
+ CollectDriverData(Records, Data);
+ CheckDriverData(Data);
- this->EmitSourceFileHeader("LLVMC Configuration Library", O);
- EmitPluginCode(Data, O);
+ this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O);
+ EmitDriverCode(Data, O);
} catch (std::exception& Error) {
throw Error.what() + std::string(" - usually this means a syntax error.");
diff --git a/contrib/llvm/utils/TableGen/NeonEmitter.cpp b/contrib/llvm/utils/TableGen/NeonEmitter.cpp
index 3516d31..0a12f37 100644
--- a/contrib/llvm/utils/TableGen/NeonEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/NeonEmitter.cpp
@@ -145,6 +145,9 @@ static char ModType(const char mod, char type, bool &quad, bool &poly,
type = 'f';
usgn = false;
break;
+ case 'g':
+ quad = false;
+ break;
case 'w':
type = Widen(type);
quad = true;
@@ -686,15 +689,15 @@ static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
bool cnst = false;
bool pntr = false;
- // base type to get the type string for.
+ // Base type to get the type string for.
char type = ClassifyType(typestr, quad, poly, usgn);
// Based on the modifying character, change the type and width if necessary.
type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
-
+
if (usgn)
ret |= 0x08;
- if (quad)
+ if (quad && proto[1] != 'g')
ret |= 0x10;
switch (type) {
@@ -1016,6 +1019,8 @@ static unsigned RangeFromType(StringRef typestr) {
throw "unhandled type!";
break;
}
+ assert(0 && "unreachable");
+ return 0;
}
/// runHeader - Emit a file with sections defining:
diff --git a/contrib/llvm/utils/TableGen/Record.cpp b/contrib/llvm/utils/TableGen/Record.cpp
index d2cf379..dc79358 100644
--- a/contrib/llvm/utils/TableGen/Record.cpp
+++ b/contrib/llvm/utils/TableGen/Record.cpp
@@ -628,23 +628,6 @@ std::string UnOpInit::getAsString() const {
return Result + "(" + LHS->getAsString() + ")";
}
-RecTy *UnOpInit::getFieldType(const std::string &FieldName) const {
- switch (getOpcode()) {
- default: assert(0 && "Unknown unop");
- case CAST: {
- RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
- if (RecordType) {
- RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
- if (Field) {
- return Field->getType();
- }
- }
- break;
- }
- }
- return 0;
-}
-
Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
switch (getOpcode()) {
default: assert(0 && "Unknown binop");
@@ -1046,6 +1029,17 @@ std::string TernOpInit::getAsString() const {
+ RHS->getAsString() + ")";
}
+RecTy *TypedInit::getFieldType(const std::string &FieldName) const {
+ RecordRecTy *RecordType = dynamic_cast<RecordRecTy *>(getType());
+ if (RecordType) {
+ RecordVal *Field = RecordType->getRecord()->getValue(FieldName);
+ if (Field) {
+ return Field->getType();
+ }
+ }
+ return 0;
+}
+
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable...
diff --git a/contrib/llvm/utils/TableGen/Record.h b/contrib/llvm/utils/TableGen/Record.h
index 8f9fd95..d6f37ee 100644
--- a/contrib/llvm/utils/TableGen/Record.h
+++ b/contrib/llvm/utils/TableGen/Record.h
@@ -535,6 +535,12 @@ public:
virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
virtual Init *convertInitListSlice(const std::vector<unsigned> &Elements);
+ /// getFieldType - This method is used to implement the FieldInit class.
+ /// Implementors of this method should return the type of the named field if
+ /// they are of record type.
+ ///
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+
/// resolveBitReference - This method is used to implement
/// VarBitInit::resolveReferences. If the bit is able to be resolved, we
/// simply return the resolved value, otherwise we return null.
@@ -835,12 +841,6 @@ public:
virtual Init *resolveReferences(Record &R, const RecordVal *RV);
- /// getFieldType - This method is used to implement the FieldInit class.
- /// Implementors of this method should return the type of the named field if
- /// they are of record type.
- ///
- virtual RecTy *getFieldType(const std::string &FieldName) const;
-
virtual std::string getAsString() const;
};
diff --git a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index a3ca0bc..6f06705 100644
--- a/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/contrib/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -119,16 +119,6 @@ void RegisterInfoEmitter::runHeader(raw_ostream &OS) {
OS << "} // End llvm namespace \n";
}
-bool isSubRegisterClass(const CodeGenRegisterClass &RC,
- std::set<Record*> &RegSet) {
- for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
- Record *Reg = RC.Elements[i];
- if (!RegSet.count(Reg))
- return false;
- }
- return true;
-}
-
static void addSuperReg(Record *R, Record *S,
std::map<Record*, std::set<Record*>, LessRecord> &SubRegs,
std::map<Record*, std::set<Record*>, LessRecord> &SuperRegs,
@@ -498,12 +488,6 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
// Give the register class a legal C name if it's anonymous.
std::string Name = RC.TheDef->getName();
- std::set<Record*> RegSet;
- for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
- Record *Reg = RC.Elements[i];
- RegSet.insert(Reg);
- }
-
OS << " // " << Name
<< " Register Class sub-classes...\n"
<< " static const TargetRegisterClass* const "
@@ -513,21 +497,9 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) {
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
- // RC2 is a sub-class of RC if it is a valid replacement for any
- // instruction operand where an RC register is required. It must satisfy
- // these conditions:
- //
- // 1. All RC2 registers are also in RC.
- // 2. The RC2 spill size must not be smaller that the RC spill size.
- // 3. RC2 spill alignment must be compatible with RC.
- //
// Sub-classes are used to determine if a virtual register can be used
// as an instruction operand, or if it must be copied first.
-
- if (rc == rc2 || RC2.Elements.size() > RC.Elements.size() ||
- (RC.SpillAlignment && RC2.SpillAlignment % RC.SpillAlignment) ||
- RC.SpillSize > RC2.SpillSize || !isSubRegisterClass(RC2, RegSet))
- continue;
+ if (rc == rc2 || !RC.hasSubClass(&RC2)) continue;
if (!Empty) OS << ", ";
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
diff --git a/contrib/llvm/utils/TableGen/TableGen.cpp b/contrib/llvm/utils/TableGen/TableGen.cpp
index 7a4f74f..5e3e282 100644
--- a/contrib/llvm/utils/TableGen/TableGen.cpp
+++ b/contrib/llvm/utils/TableGen/TableGen.cpp
@@ -55,7 +55,10 @@ enum ActionType {
GenDisassembler,
GenCallingConv,
GenClangAttrClasses,
+ GenClangAttrImpl,
GenClangAttrList,
+ GenClangAttrPCHRead,
+ GenClangAttrPCHWrite,
GenClangDiagsDefs,
GenClangDiagGroups,
GenClangDeclNodes,
@@ -67,7 +70,7 @@ enum ActionType {
GenIntrinsic,
GenTgtIntrinsic,
GenLLVMCConf,
- GenEDHeader, GenEDInfo,
+ GenEDInfo,
GenArmNeon,
GenArmNeonSema,
PrintEnums
@@ -116,8 +119,14 @@ namespace {
"Generate target intrinsic information"),
clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
"Generate clang attribute clases"),
+ clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
+ "Generate clang attribute implementations"),
clEnumValN(GenClangAttrList, "gen-clang-attr-list",
"Generate a clang attribute list"),
+ clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read",
+ "Generate clang PCH attribute reader"),
+ clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
+ "Generate clang PCH attribute writer"),
clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
"Generate Clang diagnostics definitions"),
clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
@@ -128,8 +137,6 @@ namespace {
"Generate Clang AST statement nodes"),
clEnumValN(GenLLVMCConf, "gen-llvmc",
"Generate LLVMC configuration library"),
- clEnumValN(GenEDHeader, "gen-enhanced-disassembly-header",
- "Generate enhanced disassembly info header"),
clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
"Generate enhanced disassembly info"),
clEnumValN(GenArmNeon, "gen-arm-neon",
@@ -209,116 +216,119 @@ int main(int argc, char **argv) {
return 1;
std::string Error;
- raw_fd_ostream Out(OutputFilename.c_str(), Error);
+ tool_output_file Out(OutputFilename.c_str(), Error);
if (!Error.empty()) {
errs() << argv[0] << ": error opening " << OutputFilename
<< ":" << Error << "\n";
return 1;
}
- // Make sure the file gets removed if *gasp* tablegen crashes...
- sys::RemoveFileOnSignal(sys::Path(OutputFilename));
-
try {
switch (Action) {
case PrintRecords:
- Out << Records; // No argument, dump all contents
+ Out.os() << Records; // No argument, dump all contents
break;
case GenEmitter:
- CodeEmitterGen(Records).run(Out);
+ CodeEmitterGen(Records).run(Out.os());
break;
case GenRegisterEnums:
- RegisterInfoEmitter(Records).runEnums(Out);
+ RegisterInfoEmitter(Records).runEnums(Out.os());
break;
case GenRegister:
- RegisterInfoEmitter(Records).run(Out);
+ RegisterInfoEmitter(Records).run(Out.os());
break;
case GenRegisterHeader:
- RegisterInfoEmitter(Records).runHeader(Out);
+ RegisterInfoEmitter(Records).runHeader(Out.os());
break;
case GenInstrEnums:
- InstrEnumEmitter(Records).run(Out);
+ InstrEnumEmitter(Records).run(Out.os());
break;
case GenInstrs:
- InstrInfoEmitter(Records).run(Out);
+ InstrInfoEmitter(Records).run(Out.os());
break;
case GenCallingConv:
- CallingConvEmitter(Records).run(Out);
+ CallingConvEmitter(Records).run(Out.os());
break;
case GenAsmWriter:
- AsmWriterEmitter(Records).run(Out);
+ AsmWriterEmitter(Records).run(Out.os());
break;
case GenARMDecoder:
- ARMDecoderEmitter(Records).run(Out);
+ ARMDecoderEmitter(Records).run(Out.os());
break;
case GenAsmMatcher:
- AsmMatcherEmitter(Records).run(Out);
+ AsmMatcherEmitter(Records).run(Out.os());
break;
case GenClangAttrClasses:
- ClangAttrClassEmitter(Records).run(Out);
+ ClangAttrClassEmitter(Records).run(Out.os());
+ break;
+ case GenClangAttrImpl:
+ ClangAttrImplEmitter(Records).run(Out.os());
break;
case GenClangAttrList:
- ClangAttrListEmitter(Records).run(Out);
+ ClangAttrListEmitter(Records).run(Out.os());
+ break;
+ case GenClangAttrPCHRead:
+ ClangAttrPCHReadEmitter(Records).run(Out.os());
+ break;
+ case GenClangAttrPCHWrite:
+ ClangAttrPCHWriteEmitter(Records).run(Out.os());
break;
case GenClangDiagsDefs:
- ClangDiagsDefsEmitter(Records, ClangComponent).run(Out);
+ ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os());
break;
case GenClangDiagGroups:
- ClangDiagGroupsEmitter(Records).run(Out);
+ ClangDiagGroupsEmitter(Records).run(Out.os());
break;
case GenClangDeclNodes:
- ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out);
- ClangDeclContextEmitter(Records).run(Out);
+ ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os());
+ ClangDeclContextEmitter(Records).run(Out.os());
break;
case GenClangStmtNodes:
- ClangASTNodesEmitter(Records, "Stmt", "").run(Out);
+ ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os());
break;
case GenDisassembler:
- DisassemblerEmitter(Records).run(Out);
+ DisassemblerEmitter(Records).run(Out.os());
break;
case GenOptParserDefs:
- OptParserEmitter(Records, true).run(Out);
+ OptParserEmitter(Records, true).run(Out.os());
break;
case GenOptParserImpl:
- OptParserEmitter(Records, false).run(Out);
+ OptParserEmitter(Records, false).run(Out.os());
break;
case GenDAGISel:
- DAGISelEmitter(Records).run(Out);
+ DAGISelEmitter(Records).run(Out.os());
break;
case GenFastISel:
- FastISelEmitter(Records).run(Out);
+ FastISelEmitter(Records).run(Out.os());
break;
case GenSubtarget:
- SubtargetEmitter(Records).run(Out);
+ SubtargetEmitter(Records).run(Out.os());
break;
case GenIntrinsic:
- IntrinsicEmitter(Records).run(Out);
+ IntrinsicEmitter(Records).run(Out.os());
break;
case GenTgtIntrinsic:
- IntrinsicEmitter(Records, true).run(Out);
+ IntrinsicEmitter(Records, true).run(Out.os());
break;
case GenLLVMCConf:
- LLVMCConfigurationEmitter(Records).run(Out);
- break;
- case GenEDHeader:
- EDEmitter(Records).runHeader(Out);
+ LLVMCConfigurationEmitter(Records).run(Out.os());
break;
case GenEDInfo:
- EDEmitter(Records).run(Out);
+ EDEmitter(Records).run(Out.os());
break;
case GenArmNeon:
- NeonEmitter(Records).run(Out);
+ NeonEmitter(Records).run(Out.os());
break;
case GenArmNeonSema:
- NeonEmitter(Records).runHeader(Out);
+ NeonEmitter(Records).runHeader(Out.os());
break;
case PrintEnums:
{
std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
for (unsigned i = 0, e = Recs.size(); i != e; ++i)
- Out << Recs[i]->getName() << ", ";
- Out << "\n";
+ Out.os() << Recs[i]->getName() << ", ";
+ Out.os() << "\n";
break;
}
default:
@@ -326,6 +336,8 @@ int main(int argc, char **argv) {
return 1;
}
+ // Declare success.
+ Out.keep();
return 0;
} catch (const TGError &Error) {
@@ -340,7 +352,5 @@ int main(int argc, char **argv) {
errs() << argv[0] << ": Unknown unexpected exception occurred.\n";
}
- if (OutputFilename != "-")
- std::remove(OutputFilename.c_str()); // Remove the file, it's broken
return 1;
}
diff --git a/contrib/llvm/utils/buildit/GNUmakefile b/contrib/llvm/utils/buildit/GNUmakefile
index d17585f..54577e2 100644
--- a/contrib/llvm/utils/buildit/GNUmakefile
+++ b/contrib/llvm/utils/buildit/GNUmakefile
@@ -49,8 +49,9 @@ endif
# Default to not install libLTO.dylib.
INSTALL_LIBLTO := no
-# Default to do a native build, not a cross-build for an ARM host.
+# Default to do a native build, not a cross-build for an ARM host or simulator.
ARM_HOSTED_BUILD := no
+IOS_SIM_BUILD := no
ifndef RC_ProjectSourceVersion
RC_ProjectSourceVersion = 9999
@@ -66,11 +67,18 @@ install: $(OBJROOT) $(SYMROOT) $(DSTROOT)
$(SRC)/utils/buildit/build_llvm "$(RC_ARCHS)" "$(TARGETS)" \
$(SRC) $(PREFIX) $(DSTROOT) $(SYMROOT) \
$(ENABLE_ASSERTIONS) $(LLVM_OPTIMIZED) $(INSTALL_LIBLTO) \
- $(ARM_HOSTED_BUILD) \
+ $(ARM_HOSTED_BUILD) $(IOS_SIM_BUILD) \
$(RC_ProjectSourceVersion) $(RC_ProjectSourceSubversion)
EmbeddedHosted:
- $(MAKE) ARM_HOSTED_BUILD=yes PREFIX=/usr install
+ $(MAKE) ARM_HOSTED_BUILD=yes PREFIX=/usr/local install
+
+# When building for the iOS simulator, MACOSX_DEPLOYMENT_TARGET is not set
+# by default, but it needs to be set when building tools that run on the host
+# (e.g., tblgen), so set it here.
+EmbeddedSim:
+ export MACOSX_DEPLOYMENT_TARGET=`sw_vers -productVersion`; \
+ $(MAKE) IOS_SIM_BUILD=yes PREFIX=$(SDKROOT)/usr/local install
# installhdrs does nothing, because the headers aren't useful until
# the compiler is installed.
@@ -120,4 +128,4 @@ clean:
$(OBJROOT) $(SYMROOT) $(DSTROOT):
mkdir -p $@
-.PHONY: install installsrc clean EmbeddedHosted
+.PHONY: install installsrc clean EmbeddedHosted EmbeddedSim
diff --git a/contrib/llvm/utils/buildit/build_llvm b/contrib/llvm/utils/buildit/build_llvm
index 37ef16e..39ec1cc 100755
--- a/contrib/llvm/utils/buildit/build_llvm
+++ b/contrib/llvm/utils/buildit/build_llvm
@@ -49,11 +49,14 @@ INSTALL_LIBLTO="$9"
# A yes/no parameter that controls whether to cross-build for an ARM host.
ARM_HOSTED_BUILD="${10}"
+# A yes/no parameter that controls whether to cross-build for the iOS simulator
+IOS_SIM_BUILD="${11}"
+
# The version number of the submission, e.g. 1007.
-LLVM_SUBMIT_VERSION="${11}"
+LLVM_SUBMIT_VERSION="${12}"
# The subversion number of the submission, e.g. 03.
-LLVM_SUBMIT_SUBVERSION="${12}"
+LLVM_SUBMIT_SUBVERSION="${13}"
# The current working directory is where the build will happen. It may already
# contain a partial result of an interrupted build, in which case this script
@@ -97,7 +100,7 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then
# Try to use the platform llvm-gcc. Fall back to gcc if it's not available.
for prog in gcc g++ ; do
P=$DIR/bin/arm-apple-darwin$DARWIN_VERS-${prog}
- T=`xcrun -find llvm-${prog}`
+ T=`xcrun -sdk $SDKROOT -find llvm-${prog}`
if [ "x$T" = "x" ] ; then
T=`xcrun -sdk $SDKROOT -find ${prog}`
fi
@@ -124,6 +127,10 @@ fi
if [ "$ARM_HOSTED_BUILD" = yes ]; then
configure_opts="--enable-targets=arm --host=arm-apple-darwin10 \
--target=arm-apple-darwin10 --build=i686-apple-darwin10"
+elif [ "$IOS_SIM_BUILD" = yes ]; then
+ # Use a non-standard "darwin_sim" host triple to trigger a cross-build.
+ configure_opts="--enable-targets=x86 --host=i686-apple-darwin_sim \
+ --build=i686-apple-darwin10"
else
configure_opts="--enable-targets=arm,x86,powerpc,cbe"
fi
@@ -317,9 +324,20 @@ if [ "$INSTALL_LIBLTO" = "yes" ]; then
mkdir -p $DT_HOME/lib
mv lib/libLTO.dylib $DT_HOME/lib/libLTO.dylib
+ # Save a copy of the unstripped dylib
+ mkdir -p $SYM_DIR/Developer/usr/lib
+ cp $DT_HOME/lib/libLTO.dylib $SYM_DIR/Developer/usr/lib/libLTO.dylib
+
# Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or
# PPC objects!
strip -arch all -Sl $DT_HOME/lib/libLTO.dylib
+
+ if [ "x$DISABLE_USR_LINKS" == "x" ]; then
+ # Add a symlink in /usr/lib for B&I.
+ mkdir -p $DEST_DIR/usr/lib/
+ (cd $DEST_DIR/usr/lib && \
+ ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib)
+ fi
else
rm -f lib/libLTO.dylib
fi
@@ -350,15 +368,6 @@ chgrp -R wheel $DEST_DIR
rm -rf $DEST_DIR$DEST_ROOT/docs
################################################################################
-# symlinks so that B&I can find things
-
-if [ "$INSTALL_LIBLTO" = "yes" ]; then
- mkdir -p $DEST_DIR/usr/lib/
- cd $DEST_DIR/usr/lib && \
- ln -s ../../Developer/usr/lib/libLTO.dylib ./libLTO.dylib
-fi
-
-################################################################################
# w00t! Done!
exit 0
diff --git a/contrib/llvm/utils/lit/lit/ExampleTests/lit.cfg b/contrib/llvm/utils/lit/lit/ExampleTests/lit.cfg
index dbd574f..20ee37d 100644
--- a/contrib/llvm/utils/lit/lit/ExampleTests/lit.cfg
+++ b/contrib/llvm/utils/lit/lit/ExampleTests/lit.cfg
@@ -21,3 +21,6 @@ config.test_exec_root = None
# target_triple: Used by ShTest and TclTest formats for XFAIL checks.
config.target_triple = 'foo'
+
+# available_features: Used by ShTest and TclTest formats for REQUIRES checks.
+config.available_features = ['some-feature-name']
diff --git a/contrib/llvm/utils/lit/lit/ExampleTests/required-and-missing.c b/contrib/llvm/utils/lit/lit/ExampleTests/required-and-missing.c
new file mode 100644
index 0000000..47ba72e
--- /dev/null
+++ b/contrib/llvm/utils/lit/lit/ExampleTests/required-and-missing.c
@@ -0,0 +1,4 @@
+// This test shouldn't be run, the required feature is missing.
+//
+// RUN: false
+// REQUIRES: some-missing-feature-name
diff --git a/contrib/llvm/utils/lit/lit/ExampleTests/required-and-present.c b/contrib/llvm/utils/lit/lit/ExampleTests/required-and-present.c
new file mode 100644
index 0000000..2a09e08
--- /dev/null
+++ b/contrib/llvm/utils/lit/lit/ExampleTests/required-and-present.c
@@ -0,0 +1,2 @@
+// RUN: true
+// REQUIRES: some-feature-name
diff --git a/contrib/llvm/utils/lit/lit/TestFormats.py b/contrib/llvm/utils/lit/lit/TestFormats.py
index e52d0e4..7ffbd2b 100644
--- a/contrib/llvm/utils/lit/lit/TestFormats.py
+++ b/contrib/llvm/utils/lit/lit/TestFormats.py
@@ -1,14 +1,21 @@
import os
+import platform
import Test
import TestRunner
import Util
+kIsWindows = platform.system() == 'Windows'
+
class GoogleTest(object):
def __init__(self, test_sub_dir, test_suffix):
self.test_sub_dir = str(test_sub_dir)
self.test_suffix = str(test_suffix)
+ # On Windows, assume tests will also end in '.exe'.
+ if kIsWindows:
+ self.test_suffix += '.exe'
+
def getGTestTests(self, path, litConfig, localConfig):
"""getGTestTests(path) - [name]
diff --git a/contrib/llvm/utils/lit/lit/TestRunner.py b/contrib/llvm/utils/lit/lit/TestRunner.py
index cdf1c93..0eb51a8 100644
--- a/contrib/llvm/utils/lit/lit/TestRunner.py
+++ b/contrib/llvm/utils/lit/lit/TestRunner.py
@@ -312,11 +312,6 @@ def executeTclScriptInternal(test, litConfig, tmpBase, commands, cwd):
out,err,exitCode = executeCommand(command, cwd=cwd,
env=test.config.environment)
- # Tcl commands fail on standard error output.
- if err:
- exitCode = 1
- out = 'Command has output on stderr!\n\n' + out
-
return out,err,exitCode
else:
results = []
@@ -328,11 +323,6 @@ def executeTclScriptInternal(test, litConfig, tmpBase, commands, cwd):
out = err = ''
- # Tcl commands fail on standard error output.
- if [True for _,_,err,res in results if err]:
- exitCode = 1
- out += 'Command has output on stderr!\n\n'
-
for i,(cmd, cmd_out, cmd_err, res) in enumerate(results):
out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args))
out += 'Command %d Result: %r\n' % (i, res)
@@ -422,6 +412,7 @@ def parseIntegratedTestScript(test, normalize_slashes=False):
script = []
xfails = []
xtargets = []
+ requires = []
for ln in open(sourcepath):
if 'RUN:' in ln:
# Isolate the command to run.
@@ -442,6 +433,9 @@ def parseIntegratedTestScript(test, normalize_slashes=False):
elif 'XTARGET:' in ln:
items = ln[ln.index('XTARGET:') + 8:].split(',')
xtargets.extend([s.strip() for s in items])
+ elif 'REQUIRES:' in ln:
+ items = ln[ln.index('REQUIRES:') + 9:].split(',')
+ requires.extend([s.strip() for s in items])
elif 'END.' in ln:
# Check for END. lines.
if ln[ln.index('END.'):].strip() == 'END.':
@@ -461,27 +455,42 @@ def parseIntegratedTestScript(test, normalize_slashes=False):
if not script:
return (Test.UNRESOLVED, "Test has no run line!")
+ # Check for unterminated run lines.
if script[-1][-1] == '\\':
return (Test.UNRESOLVED, "Test has unterminated run lines (with '\\')")
+ # Check that we have the required features:
+ missing_required_features = [f for f in requires
+ if f not in test.config.available_features]
+ if missing_required_features:
+ msg = ', '.join(missing_required_features)
+ return (Test.UNSUPPORTED,
+ "Test requires the following features: %s" % msg)
+
isXFail = isExpectedFail(xfails, xtargets, test.suite.config.target_triple)
return script,isXFail,tmpBase,execdir
-def formatTestOutput(status, out, err, exitCode, script):
+def formatTestOutput(status, out, err, exitCode, failDueToStderr, script):
output = StringIO.StringIO()
print >>output, "Script:"
print >>output, "--"
print >>output, '\n'.join(script)
print >>output, "--"
- print >>output, "Exit Code: %r" % exitCode
- print >>output, "Command Output (stdout):"
- print >>output, "--"
- output.write(out)
- print >>output, "--"
- print >>output, "Command Output (stderr):"
- print >>output, "--"
- output.write(err)
- print >>output, "--"
+ print >>output, "Exit Code: %r" % exitCode,
+ if failDueToStderr:
+ print >>output, "(but there was output on stderr)"
+ else:
+ print >>output
+ if out:
+ print >>output, "Command Output (stdout):"
+ print >>output, "--"
+ output.write(out)
+ print >>output, "--"
+ if err:
+ print >>output, "Command Output (stderr):"
+ print >>output, "--"
+ output.write(err)
+ print >>output, "--"
return (status, output.getvalue())
def executeTclTest(test, litConfig):
@@ -506,18 +515,30 @@ def executeTclTest(test, litConfig):
if len(res) == 2:
return res
+ # Test for failure. In addition to the exit code, Tcl commands are
+ # considered to fail if there is any standard error output.
out,err,exitCode = res
if isXFail:
- ok = exitCode != 0
- status = (Test.XPASS, Test.XFAIL)[ok]
+ ok = exitCode != 0 or err
+ if ok:
+ status = Test.XFAIL
+ else:
+ status = Test.XPASS
else:
- ok = exitCode == 0
- status = (Test.FAIL, Test.PASS)[ok]
+ ok = exitCode == 0 and not err
+ if ok:
+ status = Test.PASS
+ else:
+ status = Test.FAIL
if ok:
return (status,'')
- return formatTestOutput(status, out, err, exitCode, script)
+ # Set a flag for formatTestOutput so it can explain why the test was
+ # considered to have failed, despite having an exit code of 0.
+ failDueToStderr = exitCode == 0 and err
+
+ return formatTestOutput(status, out, err, exitCode, failDueToStderr, script)
def executeShTest(test, litConfig, useExternalSh):
if test.config.unsupported:
@@ -545,12 +566,21 @@ def executeShTest(test, litConfig, useExternalSh):
out,err,exitCode = res
if isXFail:
ok = exitCode != 0
- status = (Test.XPASS, Test.XFAIL)[ok]
+ if ok:
+ status = Test.XFAIL
+ else:
+ status = Test.XPASS
else:
ok = exitCode == 0
- status = (Test.FAIL, Test.PASS)[ok]
+ if ok:
+ status = Test.PASS
+ else:
+ status = Test.FAIL
if ok:
return (status,'')
- return formatTestOutput(status, out, err, exitCode, script)
+ # Sh tests are not considered to fail just from stderr output.
+ failDueToStderr = False
+
+ return formatTestOutput(status, out, err, exitCode, failDueToStderr, script)
diff --git a/contrib/llvm/utils/lit/lit/TestingConfig.py b/contrib/llvm/utils/lit/lit/TestingConfig.py
index dd905ef..5c1b273 100644
--- a/contrib/llvm/utils/lit/lit/TestingConfig.py
+++ b/contrib/llvm/utils/lit/lit/TestingConfig.py
@@ -28,7 +28,8 @@ class TestingConfig:
on_clone = None,
test_exec_root = None,
test_source_root = None,
- excludes = [])
+ excludes = [],
+ available_features = [])
if os.path.exists(path):
# FIXME: Improve detection and error reporting of errors in the
@@ -54,7 +55,8 @@ class TestingConfig:
def __init__(self, parent, name, suffixes, test_format,
environment, substitutions, unsupported, on_clone,
- test_exec_root, test_source_root, excludes):
+ test_exec_root, test_source_root, excludes,
+ available_features):
self.parent = parent
self.name = str(name)
self.suffixes = set(suffixes)
@@ -66,6 +68,7 @@ class TestingConfig:
self.test_exec_root = test_exec_root
self.test_source_root = test_source_root
self.excludes = set(excludes)
+ self.available_features = set(available_features)
def clone(self, path):
# FIXME: Chain implementations?
@@ -75,7 +78,7 @@ class TestingConfig:
self.environment, self.substitutions,
self.unsupported, self.on_clone,
self.test_exec_root, self.test_source_root,
- self.excludes)
+ self.excludes, self.available_features)
if cfg.on_clone:
cfg.on_clone(self, cfg, path)
return cfg
diff --git a/contrib/llvm/utils/lit/lit/lit.py b/contrib/llvm/utils/lit/lit/lit.py
index db0653f..13d2630 100755
--- a/contrib/llvm/utils/lit/lit/lit.py
+++ b/contrib/llvm/utils/lit/lit/lit.py
@@ -358,8 +358,7 @@ def load_test_suite(inputs):
from LitTestCase import LitTestCase
return unittest.TestSuite([LitTestCase(test, litConfig) for test in tests])
-def main():
- # Bump the GIL check interval, its more important to get any one thread to a
+def main(builtinParameters = {}): # Bump the GIL check interval, its more important to get any one thread to a
# blocking operation (hopefully exec) than to try and unblock other threads.
#
# FIXME: This is a hack.
@@ -469,7 +468,7 @@ def main():
inputs = args
# Create the user defined parameters.
- userParams = {}
+ userParams = dict(builtinParameters)
for entry in opts.userParameters:
if '=' not in entry:
name,val = entry,''
diff --git a/contrib/llvm/utils/llvm-lit/Makefile b/contrib/llvm/utils/llvm-lit/Makefile
new file mode 100644
index 0000000..702591f
--- /dev/null
+++ b/contrib/llvm/utils/llvm-lit/Makefile
@@ -0,0 +1,21 @@
+##===- utils/llvm-lit/Makefile -----------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+include $(LEVEL)/Makefile.common
+
+all:: $(ToolDir)/llvm-lit
+
+$(ToolDir)/llvm-lit: llvm-lit.in $(ToolDir)/.dir
+ $(Echo) "Creating 'llvm-lit' script..."
+ $(Verb)sed -e "s#@LLVM_SOURCE_DIR@#$(LLVM_SRC_ROOT)#g" \
+ -e "s#@LLVM_BINARY_DIR@#$(LLVM_OBJ_ROOT)#g" \
+ $< > $@
+ $(Verb)chmod +x $@
diff --git a/contrib/llvm/utils/llvm-lit/llvm-lit.in b/contrib/llvm/utils/llvm-lit/llvm-lit.in
new file mode 100644
index 0000000..3ff2c24
--- /dev/null
+++ b/contrib/llvm/utils/llvm-lit/llvm-lit.in
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+import os
+import sys
+
+# Variables configured at build time.
+llvm_source_root = "@LLVM_SOURCE_DIR@"
+llvm_obj_root = "@LLVM_BINARY_DIR@"
+
+# Make sure we can find the lit package.
+sys.path.append(os.path.join(llvm_source_root, 'utils', 'lit'))
+
+# Set up some builtin parameters, so that by default the LLVM test suite
+# configuration file knows how to find the object tree.
+builtin_parameters = {
+ 'llvm_site_config' : os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
+ }
+
+if __name__=='__main__':
+ import lit
+ lit.main(builtin_parameters)
diff --git a/contrib/llvm/utils/llvm.grm b/contrib/llvm/utils/llvm.grm
index fa0dcd1..9d6bdf7 100644
--- a/contrib/llvm/utils/llvm.grm
+++ b/contrib/llvm/utils/llvm.grm
@@ -8,6 +8,8 @@ It is strictly syntax-based, and makes no attempt to generate
IR that is semantically valid. Most of the IR produced doesn't
pass the Verifier.
+TODO: Metadata, in all its forms
+
*)
I ::= "title: LLVM assembly language\n"
@@ -90,6 +92,8 @@ GVInternalLinkage
| dllexport
| common
| private
+ | "linker_private"
+ | "linker_private_weak"
;
GVExternalLinkage
diff --git a/contrib/llvm/utils/llvmdo b/contrib/llvm/utils/llvmdo
index 4a7e05a..bcfc221 100755
--- a/contrib/llvm/utils/llvmdo
+++ b/contrib/llvm/utils/llvmdo
@@ -76,8 +76,6 @@ fi
shift;
paths_to_ignore="\
- -path */CVS -o \
- -path */CVS/* -o \
-path */.svn/ -o \
-path */.svn/* -o \
-path docs/doxygen/* -o \
@@ -130,7 +128,6 @@ files_to_match="\
-o -name llvmgrep \
-o -name check-each-file \
-o -name codgen-diff \
- -o -name cvsupdate \
-o -name llvm-native-gcc \
-o -name llvm-native-gxx \
-o -name makellvm \
@@ -153,7 +150,6 @@ files_to_ignore="\
-name \.* \
-o -name *~ \
-o -name #* \
- -o -name *.cvs \
-o -name configure \
-o -name slow.ll \
-o -name *libtool* \
diff --git a/contrib/llvm/utils/mkpatch b/contrib/llvm/utils/mkpatch
deleted file mode 100755
index 2741563..0000000
--- a/contrib/llvm/utils/mkpatch
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# This script makes a patch for LLVM ensuring the correct diff options and
-# putting the files in a standard review order.
-
-
-function error {
- retcode="$?"
- echo "mkpatch: error: $1 ($retcode)"
- exit 1
-}
-
-if [ ! -e llvm.spec.in ] ; then
- error "Please change directory to the LLVM top source directory"
-fi
-if [ "$#" -ne 1 ] ; then
- error "usage: utils/mkpatch [PATCH_NAME]"
-fi
-NAME="$1"
-echo "mkpatch: Generating differences on top level files"
-svn diff -N -x -u > "$NAME".patch.raw 2>&1
-echo "mkpatch: Generating differences on all directories"
-svn diff -x -u >> "$NAME".patch.raw 2>&1 \
- autoconf docs utils include lib/System lib/Support lib/VMCore lib/AsmParser \
- lib/Bitcode lib/Analysis lib/Transforms lib/CodeGen lib/Target \
- lib/ExecutionEngine lib/Linker lib/MC \
- tools test unittests runtime projects examples Xcode
-
-echo "mkpatch: Removing cruft from the patch file"
-sed -e '/^[?] .*/d' -e '/^cvs diff: Diffing/d' "$NAME".patch.raw | awk '\
-BEGIN { deleting = 0; } \
-/^Index: .*[.]cvs$/ { deleting = 1; fname=substr($0,7); \
- print "Skipping: ", fname > "/dev/stderr"; } \
-/^Index:.*/ && !/^Index: .*[.]cvs$/ { deleting = 0; } \
-{ if (! deleting) { print; } } ' > "$NAME".patch || \
- error "sed/awk cleanup failed"
-
diff --git a/contrib/llvm/utils/userloc.pl b/contrib/llvm/utils/userloc.pl
deleted file mode 100755
index 4da2f40..0000000
--- a/contrib/llvm/utils/userloc.pl
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/perl -w
-#
-# Program: userloc.pl
-#
-# Synopsis: This program uses "cvs annotate" to get a summary of how many lines
-# of code the various developres are responsible for. It takes one
-# argument, the directory to process. If the argument is not specified
-# then the cwd is used. The directory must be an LLVM tree checked out
-# from cvs.
-#
-# Syntax: userloc.pl [-tag=tag|-html... <directory>...
-#
-# Options:
-# -tag=tag
-# Use "tag" to select the revision (as per cvs -r option)
-# -filedetails
-# Report details about lines of code in each file for each user
-# -html
-# Generate HTML output instead of text output
-# -topdir
-# Specify where the top llvm source directory is. Otherwise the
-# llvm-config tool is used to find it.
-# Directories:
-# The directories passed after the options should be relative paths to
-# directories of interest from the top of the llvm source tree, e.g. "lib"
-# or "include", etc.
-
-die "Usage userloc.pl [-tag=tag|-html] <directories>..."
- if ($#ARGV < 0);
-
-my $tag = "";
-my $html = 0;
-my $debug = 0;
-my $filedetails = "";
-my $srcroot = "";
-while ( defined($ARGV[0]) && substr($ARGV[0],0,1) eq '-' )
-{
- if ($ARGV[0] =~ /-tag=.*/) {
- $tag = $ARGV[0];
- $tag =~ s#-tag=(.*)#$1#;
- } elsif ($ARGV[0] =~ /-filedetails/) {
- $filedetails = 1;
- } elsif ($ARGV[0] eq "-html") {
- $html = 1;
- } elsif ($ARGV[0] eq "-debug") {
- $debug = 1;
- } elsif ($ARGV[0] eq "-topdir") {
- shift; $srcroot = $ARGV[0]; shift;
- } else {
- die "Invalid option: $ARGV[0]";
- }
- shift;
-}
-
-if (length($srcroot) == 0) {
- chomp($srcroot = `llvm-config --src-root`);
-}
-if (! -d "$srcroot") {
- die "Invalid source root: $srcroot\n";
-}
-chdir($srcroot);
-my $llvmdo = "$srcroot/utils/llvmdo -topdir '$srcroot'";
-my %Stats;
-my %FileStats;
-
-my $annotate = "cvs -z6 annotate -lf ";
-if (length($tag) > 0)
-{
- $annotate = $annotate . " -r" . $tag;
-}
-
-sub GetCVSFiles
-{
- my $d = $_[0];
- my $files ="";
- open FILELIST,
- "$llvmdo -dirs \"$d\" -code-only echo |" || die "Can't get list of files with llvmdo";
- while ( defined($line = <FILELIST>) ) {
- chomp($file = $line);
- print "File: $file\n" if ($debug);
- $files = "$files $file";
- }
- return $files;
-}
-
-sub ScanDir
-{
- my $Dir = $_[0];
- my $files = GetCVSFiles($Dir);
-
- open (DATA,"$annotate $files 2>&1 |")
- || die "Can't read cvs annotation data";
-
- my $curfile = "";
- while ( defined($line = <DATA>) )
- {
- chomp($line);
- if ($line =~ '^Annotations for.*') {
- $curfile = $line;
- $curfile =~ s#^Annotations for ([[:print:]]*)#$1#;
- print "Scanning: $curfile\n" if ($debug);
- } elsif ($line =~ /^[0-9.]*[ \t]*\([^)]*\):/) {
- $uname = $line;
- $uname =~ s#^[0-9.]*[ \t]*\(([a-zA-Z0-9_.-]*) [^)]*\):.*#$1#;
- $Stats{$uname}++;
- if ($filedetails) {
- $FileStats{$uname} = {} unless exists $FileStats{$uname};
- ${$FileStats{$uname}}{$curfile}++;
- }
- }
- }
- close DATA;
-}
-
-sub printStats
-{
- my $dir = $_[0];
- my $hash = $_[1];
- my $user;
- my $total = 0;
-
- foreach $user (keys %Stats) { $total += $Stats{$user}; }
-
- if ($html) {
- print "<p>Total Source Lines: $total<br/></p>\n";
- print "<table>";
- print " <tr><th style=\"text-align:right\">LOC</th>\n";
- print " <th style=\"text-align:right\">\%LOC</th>\n";
- print " <th style=\"text-align:left\">User</th>\n";
- print "</tr>\n";
- }
-
- foreach $user ( sort keys %Stats )
- {
- my $v = $Stats{$user};
- if (defined($v))
- {
- if ($html) {
- printf "<tr><td style=\"text-align:right\">%d</td><td style=\"text-align:right\">(%4.1f%%)</td><td style=\"text-align:left\">", $v, (100.0/$total)*$v;
- if ($filedetails) {
- print "<a href=\"#$user\">$user</a></td></tr>";
- } else {
- print $user,"</td></tr>";
- }
- } else {
- printf "%8d (%4.1f%%) %s\n", $v, (100.0/$total)*$v, $user;
- }
- }
- }
- print "</table>\n" if ($html);
-
- if ($filedetails) {
- foreach $user (sort keys %FileStats) {
- my $total = 0;
- foreach $file (sort keys %{$FileStats{$user}}) {
- $total += ${$FileStats{$user}}{$file}
- }
- if ($html) {
- print "<table><tr><th style=\"text-align:left\" colspan=\"3\"><a name=\"$user\">$user</a></th></tr>\n";
- } else {
- print $user,":\n";
- }
- foreach $file (sort keys %{$FileStats{$user}}) {
- my $v = ${$FileStats{$user}}{$file};
- if ($html) {
- printf "<tr><td style=\"text-align:right\">&nbsp;&nbsp;%d</td><td
- style=\"text-align:right\">&nbsp;%4.1f%%</td><td
- style=\"text-align:left\">%s</td></tr>",$v, (100.0/$total)*$v,$file;
- } else {
- printf "%8d (%4.1f%%) %s\n", $v, (100.0/$total)*$v, $file;
- }
- }
- if ($html) { print "</table>\n"; }
- }
- }
-}
-
-
-if ($html)
-{
-print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
-print "<html>\n<head>\n";
-print " <title>LLVM LOC Based On CVS Annotation</title>\n";
-print " <link rel=\"stylesheet\" href=\"llvm.css\" type=\"text/css\"/>\n";
-print "</head>\n";
-print "<body><div class=\"doc_title\">LLVM LOC Based On CVS Annotation</div>\n";
-print "<p>This document shows the total lines of code per user in each\n";
-print "LLVM directory. Lines of code are attributed by the user that last\n";
-print "committed the line. This does not necessarily reflect authorship.</p>\n";
-}
-
-my @DIRS;
-if ($#ARGV > 0) {
- @DIRS = @ARGV;
-} else {
- push @DIRS, 'include';
- push @DIRS, 'lib';
- push @DIRS, 'tools';
- push @DIRS, 'runtime';
- push @DIRS, 'docs';
- push @DIRS, 'test';
- push @DIRS, 'utils';
- push @DIRS, 'examples';
- push @DIRS, 'projects/Stacker';
- push @DIRS, 'projects/sample';
- push @DIRS, 'autoconf';
-}
-
-for $Index ( 0 .. $#DIRS) {
- print "Scanning Dir: $DIRS[$Index]\n" if ($debug);
- ScanDir($DIRS[$Index]);
-}
-
-printStats;
-
-print "</body></html>\n" if ($html) ;
diff --git a/contrib/llvm/utils/valgrind/i386-pc-linux-gnu.supp b/contrib/llvm/utils/valgrind/i386-pc-linux-gnu.supp
index f8fd99a..c9f68a0 100644
--- a/contrib/llvm/utils/valgrind/i386-pc-linux-gnu.supp
+++ b/contrib/llvm/utils/valgrind/i386-pc-linux-gnu.supp
@@ -5,3 +5,37 @@
fun:_ZN83_GLOBAL_*PassRegistrar12RegisterPassERKN4llvm8PassInfoE
fun:_ZN4llvm8PassInfo12registerPassEv
}
+
+# Python false positives according to
+# http://svn.python.org/projects/python/trunk/Misc/README.valgrind
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ obj:/usr/bin/python2.5
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ obj:/usr/bin/python2.5
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ obj:/usr/bin/python2.5
+}
+
+{
+ We don't care if as leaks
+ Memcheck:Leak
+ obj:/usr/bin/as
+}
+
+{
+ We don't care if python leaks
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/bin/python2.5
+}
diff --git a/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu.supp b/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu.supp
index f8fd99a..f5aae99 100644
--- a/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu.supp
+++ b/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu.supp
@@ -2,6 +2,45 @@
False leak under RegisterPass
Memcheck:Leak
...
- fun:_ZN83_GLOBAL_*PassRegistrar12RegisterPassERKN4llvm8PassInfoE
- fun:_ZN4llvm8PassInfo12registerPassEv
+ fun:_ZN4llvm12PassRegistry12registerPassERKNS_8PassInfoE
+}
+
+# Python false positives according to
+# http://svn.python.org/projects/python/trunk/Misc/README.valgrind
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ obj:/usr/bin/python2.5
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value8
+ obj:/usr/bin/python2.5
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ obj:/usr/bin/python2.5
+}
+
+{
+ We don't care if as leaks
+ Memcheck:Leak
+ obj:/usr/bin/as
+}
+
+{
+ We don't care if grep leaks
+ Memcheck:Leak
+ obj:/bin/grep
+}
+
+{
+ We don't care if python leaks
+ Memcheck:Leak
+ fun:malloc
+ obj:/usr/bin/python2.5
}
diff --git a/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp b/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
deleted file mode 100644
index a86be6c..0000000
--- a/contrib/llvm/utils/valgrind/x86_64-pc-linux-gnu_gcc-4.3.3.supp
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- libstdcxx_overlapped_memcpy_in_stable_sort_1
- Memcheck:Overlap
- fun:memcpy
- ...
- fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
-}
-
-{
- libstdcxx_overlapped_memcpy_in_stable_sort_2
- Memcheck:Overlap
- fun:memcpy
- ...
- fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm5ValueEjESt6vectorIS7_SaIS7_EEEEN12_GLOBAL__N_116CstSortPredicateEEvT_SF_T0_
-}
-
-{
- libstdcxx_overlapped_memcpy_in_stable_sort_3
- Memcheck:Overlap
- fun:memcpy
- ...
- fun:_ZSt11stable_sortIN9__gnu_cxx17__normal_iteratorIPSt4pairIPKN4llvm4TypeEjESt6vectorIS7_SaIS7_EEEEPFbRKS7_SE_EEvT_SH_T0_
-}
diff --git a/contrib/llvm/utils/vim/llvm.vim b/contrib/llvm/utils/vim/llvm.vim
index 518aa04..acebc20 100644
--- a/contrib/llvm/utils/vim/llvm.vim
+++ b/contrib/llvm/utils/vim/llvm.vim
@@ -1,7 +1,7 @@
" Vim syntax file
" Language: llvm
" Maintainer: The LLVM team, http://llvm.org/
-" Version: $Revision: 97271 $
+" Version: $Revision: 112382 $
if version < 600
syntax clear
@@ -57,14 +57,12 @@ syn keyword llvmKeyword module asm align tail to
syn keyword llvmKeyword addrspace section alias sideeffect c gc
syn keyword llvmKeyword target datalayout triple
syn keyword llvmKeyword blockaddress
-syn keyword llvmKeyword union
" Obsolete keywords.
-syn keyword llvmError uninitialized implementation
-syn keyword llvmError getresult big little endian begin end
+syn keyword llvmError getresult begin end
" Misc syntax.
-syn match llvmIgnore /[%@]\d\+\>/
+syn match llvmNoName /[%@]\d\+\>/
syn match llvmNumber /-\?\<\d\+\>/
syn match llvmFloat /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/
syn match llvmFloat /\<0x\x\+\>/
@@ -99,7 +97,7 @@ if version >= 508 || !exists("did_c_syn_inits")
HiLink llvmKeyword Keyword
HiLink llvmBoolean Boolean
HiLink llvmFloat Float
- HiLink llvmIgnore Ignore
+ HiLink llvmNoName Identifier
HiLink llvmConstant Constant
HiLink llvmSpecialComment SpecialComment
HiLink llvmError Error
diff --git a/contrib/llvm/utils/vim/vimrc b/contrib/llvm/utils/vim/vimrc
index 63108f2..1f314c2 100644
--- a/contrib/llvm/utils/vim/vimrc
+++ b/contrib/llvm/utils/vim/vimrc
@@ -1,5 +1,5 @@
" LLVM coding guidelines conformance for VIM
-" $Revision: 97273 $
+" $Revision: 112982 $
"
" Maintainer: The LLVM Team, http://llvm.org
" WARNING: Read before you source in all these commands and macros! Some
@@ -91,3 +91,130 @@ augroup END
"set showmode
"set incsearch
"set ruler
+
+" Clang code-completion support. This is highly experimental!
+
+" A path to a clang executable.
+let g:clang_path = "clang++"
+
+" A list of options to add to the clang commandline, for example to add
+" include paths, predefined macros, and language options.
+let g:clang_opts = [
+ \ "-x","c++",
+ \ "-D__STDC_LIMIT_MACROS=1","-D__STDC_CONSTANT_MACROS=1",
+ \ "-Iinclude" ]
+
+function! ClangComplete(findstart, base)
+ if a:findstart == 1
+ " In findstart mode, look for the beginning of the current identifier.
+ let l:line = getline('.')
+ let l:start = col('.') - 1
+ while l:start > 0 && l:line[l:start - 1] =~ '\i'
+ let l:start -= 1
+ endwhile
+ return l:start
+ endif
+
+ " Get the current line and column numbers.
+ let l:l = line('.')
+ let l:c = col('.')
+
+ " Build a clang commandline to do code completion on stdin.
+ let l:the_command = shellescape(g:clang_path) .
+ \ " -cc1 -code-completion-at=-:" . l:l . ":" . l:c
+ for l:opt in g:clang_opts
+ let l:the_command .= " " . shellescape(l:opt)
+ endfor
+
+ " Copy the contents of the current buffer into a string for stdin.
+ " TODO: The extra space at the end is for working around clang's
+ " apparent inability to do code completion at the very end of the
+ " input.
+ " TODO: Is it better to feed clang the entire file instead of truncating
+ " it at the current line?
+ let l:process_input = join(getline(1, l:l), "\n") . " "
+
+ " Run it!
+ let l:input_lines = split(system(l:the_command, l:process_input), "\n")
+
+ " Parse the output.
+ for l:input_line in l:input_lines
+ " Vim's substring operator is annoyingly inconsistent with python's.
+ if l:input_line[:11] == 'COMPLETION: '
+ let l:value = l:input_line[12:]
+
+ " Chop off anything after " : ", if present, and move it to the menu.
+ let l:menu = ""
+ let l:spacecolonspace = stridx(l:value, " : ")
+ if l:spacecolonspace != -1
+ let l:menu = l:value[l:spacecolonspace+3:]
+ let l:value = l:value[:l:spacecolonspace-1]
+ endif
+
+ " Chop off " (Hidden)", if present, and move it to the menu.
+ let l:hidden = stridx(l:value, " (Hidden)")
+ if l:hidden != -1
+ let l:menu .= " (Hidden)"
+ let l:value = l:value[:l:hidden-1]
+ endif
+
+ " Handle "Pattern". TODO: Make clang less weird.
+ if l:value == "Pattern"
+ let l:value = l:menu
+ let l:pound = stridx(l:value, "#")
+ " Truncate the at the first [#, <#, or {#.
+ if l:pound != -1
+ let l:value = l:value[:l:pound-2]
+ endif
+ endif
+
+ " Filter out results which don't match the base string.
+ if a:base != ""
+ if l:value[:strlen(a:base)-1] != a:base
+ continue
+ end
+ endif
+
+ " TODO: Don't dump the raw input into info, though it's nice for now.
+ " TODO: The kind string?
+ let l:item = {
+ \ "word": l:value,
+ \ "menu": l:menu,
+ \ "info": l:input_line,
+ \ "dup": 1 }
+
+ " Report a result.
+ if complete_add(l:item) == 0
+ return []
+ endif
+ if complete_check()
+ return []
+ endif
+
+ elseif l:input_line[:9] == "OVERLOAD: "
+ " An overload candidate. Use a crazy hack to get vim to
+ " display the results. TODO: Make this better.
+ let l:value = l:input_line[10:]
+ let l:item = {
+ \ "word": " ",
+ \ "menu": l:value,
+ \ "info": l:input_line,
+ \ "dup": 1}
+
+ " Report a result.
+ if complete_add(l:item) == 0
+ return []
+ endif
+ if complete_check()
+ return []
+ endif
+
+ endif
+ endfor
+
+
+ return []
+endfunction ClangComplete
+
+" Uncomment this to enable the highly-broken autocompletion support.
+"set omnifunc=ClangComplete
OpenPOWER on IntegriCloud