summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-14 09:23:33 +0000
committered <ed@FreeBSD.org>2009-06-14 09:23:33 +0000
commitdb89e312d968c258aba3c79c1c398f5fb19267a3 (patch)
tree49817b316c4fdaa56d9d16ebf2555303d1a990e0 /utils
parentde000e339094f8c6e06a635dac9a803861416ec6 (diff)
downloadFreeBSD-src-db89e312d968c258aba3c79c1c398f5fb19267a3.zip
FreeBSD-src-db89e312d968c258aba3c79c1c398f5fb19267a3.tar.gz
Import LLVM r73340.
Diffstat (limited to 'utils')
-rwxr-xr-xutils/GenLibDeps.pl8
-rwxr-xr-xutils/NewNightlyTest.pl31
-rw-r--r--utils/TableGen/ClangDiagnosticsEmitter.cpp6
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp23
-rw-r--r--utils/TableGen/Record.cpp110
-rw-r--r--utils/TableGen/Record.h53
-rw-r--r--utils/TableGen/TGParser.cpp165
-rw-r--r--utils/TableGen/TGParser.h6
-rwxr-xr-xutils/crosstool/ARM/build-install-linux.sh203
-rwxr-xr-xutils/crosstool/create-snapshots.sh41
10 files changed, 588 insertions, 58 deletions
diff --git a/utils/GenLibDeps.pl b/utils/GenLibDeps.pl
index 73f3e71..6d0b13e 100755
--- a/utils/GenLibDeps.pl
+++ b/utils/GenLibDeps.pl
@@ -38,6 +38,10 @@ if (!$FLAT) {
die "Can't find 'dot'" if (! -x "$DotPath");
}
+if (defined($ENV{NM})) {
+ chomp($nmPath=$ENV{NM});
+}
+
if (!defined($nmPath) || $nmPath eq "") {
chomp($nmPath=`which nm`);
die "Can't find 'nm'" if (! -x "$nmPath");
@@ -96,7 +100,7 @@ sub gen_one_entry {
print " <dt><b>$lib</b</dt><dd><ul>\n";
}
open UNDEFS,
- "$nmPath -g -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |";
+ "$nmPath -u $Directory/$lib | sed -e 's/^[ 0]* U //' | sort | uniq |";
my %DepLibs;
while (<UNDEFS>) {
chomp;
@@ -116,7 +120,7 @@ sub gen_one_entry {
close UNDEFS or die "nm failed";
unless(keys %DepLibs) {
# above failed
- open UNDEFS, "$nmPath -g -u $Directory/$lib |";
+ open UNDEFS, "$nmPath -u $Directory/$lib |";
while (<UNDEFS>) {
# to bypass non-working sed
if (' ' eq substr($_,0,2) and index($_,'U ')) {
diff --git a/utils/NewNightlyTest.pl b/utils/NewNightlyTest.pl
index a40b3f1..feac974 100755
--- a/utils/NewNightlyTest.pl
+++ b/utils/NewNightlyTest.pl
@@ -11,8 +11,6 @@ use Socket;
# regressions and performance changes. Submits this information
# to llvm.org where it is placed into the nightlytestresults database.
#
-# Modified heavily by Patrick Jenkins, July 2006
-#
# Syntax: NightlyTest.pl [OPTIONS] [CVSROOT BUILDDIR WEBDIR]
# where
# OPTIONS may include one or more of the following:
@@ -26,10 +24,12 @@ use Socket;
# -nodejagnu Do not run feature or regression tests
# -parallel Run parallel jobs with GNU Make (see -parallel-jobs).
# -parallel-jobs The number of parallel Make jobs to use (default is two).
+# -with-clang Checkout Clang source into tools/clang.
# -release Build an LLVM Release version
# -release-asserts Build an LLVM ReleaseAsserts version
# -enable-llcbeta Enable testing of beta features in llc.
# -enable-lli Enable testing of lli (interpreter) features, default is off
+# -disable-pic Disable building with Position Independent Code.
# -disable-llc Disable LLC tests in the nightly tester.
# -disable-jit Disable JIT tests in the nightly tester.
# -disable-cbe Disable C backend tests in the nightly tester.
@@ -98,7 +98,7 @@ use Socket;
##############################################################
my $HOME = $ENV{'HOME'};
my $SVNURL = $ENV{"SVNURL"};
-$SVNURL = 'https://llvm.org/svn/llvm-project' unless $SVNURL;
+$SVNURL = 'http://llvm.org/svn/llvm-project' unless $SVNURL;
my $CVSRootDir = $ENV{'CVSROOT'};
$CVSRootDir = "/home/vadve/shared/PublicCVS" unless $CVSRootDir;
my $BuildDir = $ENV{'BUILDDIR'};
@@ -145,6 +145,7 @@ while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
if (/^-norunningtests$/) { next; } # Backward compatibility, ignored.
if (/^-parallel-jobs$/) { $PARALLELJOBS = "$ARGV[0]"; shift; next;}
if (/^-parallel$/) { $MAKEOPTS = "$MAKEOPTS -j$PARALLELJOBS -l3.0"; next; }
+ if (/^-with-clang$/) { $WITHCLANG = 1; next; }
if (/^-release$/) { $MAKEOPTS = "$MAKEOPTS ENABLE_OPTIMIZED=1 ".
"OPTIMIZE_OPTION=-O2"; $BUILDTYPE="release"; next;}
if (/^-release-asserts$/){ $MAKEOPTS = "$MAKEOPTS ENABLE_OPTIMIZED=1 ".
@@ -152,6 +153,7 @@ while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) {
"OPTIMIZE_OPTION=-O2";
$BUILDTYPE="release-asserts"; next;}
if (/^-enable-llcbeta$/) { $PROGTESTOPTS .= " ENABLE_LLCBETA=1"; next; }
+ if (/^-disable-pic$/) { $CONFIGUREARGS .= " --enable-pic=no"; next; }
if (/^-enable-lli$/) { $PROGTESTOPTS .= " ENABLE_LLI=1";
$CONFIGUREARGS .= " --enable-lli"; next; }
if (/^-disable-llc$/) { $PROGTESTOPTS .= " DISABLE_LLC=1";
@@ -534,13 +536,20 @@ ChangeDir( $BuildDir, "checkout directory" );
if (!$NOCHECKOUT) {
if ( $VERBOSE ) { print "CHECKOUT STAGE:\n"; }
if ($USESVN) {
- my $SVNCMD = "$NICE svn co $SVNURL";
- if ($VERBOSE) {
- print "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " .
+ my $SVNCMD = "$NICE svn co --non-interactive $SVNURL";
+ if ($VERBOSE) {
+ print "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " .
+ "$SVNCMD/test-suite/trunk llvm-test ) > $COLog 2>&1\n";
+ }
+ system "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " .
"$SVNCMD/test-suite/trunk llvm-test ) > $COLog 2>&1\n";
- }
- system "( time -p $SVNCMD/llvm/trunk llvm; cd llvm/projects ; " .
- "$SVNCMD/test-suite/trunk llvm-test ) > $COLog 2>&1\n";
+ if ($WITHCLANG) {
+ my $SVNCMD = "$NICE svn co --non-interactive $SVNURL/cfe/trunk";
+ if ($VERBOSE) {
+ print "( time -p cd llvm/tools ; $SVNCMD clang ) > $COLog 2>&1\n";
+ }
+ system "( time -p cd llvm/tools ; $SVNCMD clang ) > $COLog 2>&1\n";
+ }
} else {
my $CVSOPT = "";
$CVSOPT = "-z3" # Use compression if going over ssh.
@@ -611,7 +620,7 @@ if (!$NOCVSSTATS) {
if ($VERBOSE) { print "CHANGE HISTORY ANALYSIS STAGE\n"; }
if ($USESVN) {
- @SVNHistory = split /<logentry/, `svn log --xml --verbose -r{$DATE}:HEAD`;
+ @SVNHistory = split /<logentry/, `svn log --non-interactive --xml --verbose -r{$DATE}:HEAD`;
# Skip very first entry because it is the XML header cruft
shift @SVNHistory;
my $Now = time();
@@ -717,9 +726,11 @@ if (!$NOCHECKOUT && !$NOBUILD) {
"> $BuildLog 2>&1";
if ( $VERBOSE ) {
print "BUILD STAGE:\n";
+ print "(time -p $NICE $MAKECMD clean) >> $BuildLog 2>&1\n";
print "(time -p $NICE $MAKECMD $MAKEOPTS) >> $BuildLog 2>&1\n";
}
# Build the entire tree, capturing the output into $BuildLog
+ system "(time -p $NICE $MAKECMD clean) >> $BuildLog 2>&1";
system "(time -p $NICE $MAKECMD $MAKEOPTS) >> $BuildLog 2>&1";
}
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index 919ae9b..a4a5698 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -65,6 +65,12 @@ void ClangDiagsDefsEmitter::run(std::ostream &OS) {
} else {
OS << ", 0";
}
+
+ // SFINAE bit
+ if (R.getValueAsBit("SFINAE"))
+ OS << ", true";
+ else
+ OS << ", false";
OS << ")\n";
}
}
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index db76dab..e668468 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2007,9 +2007,28 @@ void CodeGenDAGPatterns::ParsePatterns() {
Pattern = new TreePattern(Patterns[i], Tree, true, *this);
else {
std::vector<Init*> Values;
- for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j)
+ RecTy *ListTy = 0;
+ for (unsigned j = 0, ee = Tree->getNumArgs(); j != ee; ++j) {
Values.push_back(Tree->getArg(j));
- ListInit *LI = new ListInit(Values);
+ TypedInit *TArg = dynamic_cast<TypedInit*>(Tree->getArg(j));
+ if (TArg == 0) {
+ cerr << "In dag: " << Tree->getAsString();
+ cerr << " -- Untyped argument in pattern\n";
+ assert(0 && "Untyped argument in pattern");
+ }
+ if (ListTy != 0) {
+ ListTy = resolveTypes(ListTy, TArg->getType());
+ if (ListTy == 0) {
+ cerr << "In dag: " << Tree->getAsString();
+ cerr << " -- Incompatible types in pattern arguments\n";
+ assert(0 && "Incompatible types in pattern arguments");
+ }
+ }
+ else {
+ ListTy = TArg->getType();
+ }
+ }
+ ListInit *LI = new ListInit(Values, new ListRecTy(ListTy));
Pattern = new TreePattern(Patterns[i], LI, true, *this);
}
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index 45804b9..c62e21b 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -189,7 +189,12 @@ Init *ListRecTy::convertValue(ListInit *LI) {
else
return 0;
- return new ListInit(Elements);
+ ListRecTy *LType = dynamic_cast<ListRecTy*>(LI->getType());
+ if (LType == 0) {
+ return 0;
+ }
+
+ return new ListInit(Elements, new ListRecTy(Ty));
}
Init *ListRecTy::convertValue(TypedInit *TI) {
@@ -270,6 +275,57 @@ bool RecordRecTy::baseClassOf(const RecordRecTy *RHS) const {
}
+/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// Return 0 if no such type exists.
+///
+RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
+ if (!T1->typeIsConvertibleTo(T2)) {
+ if (!T2->typeIsConvertibleTo(T1)) {
+ // If one is a Record type, check superclasses
+ RecordRecTy *RecTy1 = dynamic_cast<RecordRecTy*>(T1);
+ if (RecTy1) {
+ // See if T2 inherits from a type T1 also inherits from
+ const std::vector<Record *> &T1SuperClasses = RecTy1->getRecord()->getSuperClasses();
+ for(std::vector<Record *>::const_iterator i = T1SuperClasses.begin(),
+ iend = T1SuperClasses.end();
+ i != iend;
+ ++i) {
+ RecordRecTy *SuperRecTy1 = new RecordRecTy(*i);
+ RecTy *NewType1 = resolveTypes(SuperRecTy1, T2);
+ if (NewType1 != 0) {
+ if (NewType1 != SuperRecTy1) {
+ delete SuperRecTy1;
+ }
+ return NewType1;
+ }
+ }
+ }
+ RecordRecTy *RecTy2 = dynamic_cast<RecordRecTy*>(T2);
+ if (RecTy2) {
+ // See if T1 inherits from a type T2 also inherits from
+ const std::vector<Record *> &T2SuperClasses = RecTy2->getRecord()->getSuperClasses();
+ for(std::vector<Record *>::const_iterator i = T2SuperClasses.begin(),
+ iend = T2SuperClasses.end();
+ i != iend;
+ ++i) {
+ RecordRecTy *SuperRecTy2 = new RecordRecTy(*i);
+ RecTy *NewType2 = resolveTypes(T1, SuperRecTy2);
+ if (NewType2 != 0) {
+ if (NewType2 != SuperRecTy2) {
+ delete SuperRecTy2;
+ }
+ return NewType2;
+ }
+ }
+ }
+ return 0;
+ }
+ return T2;
+ }
+ return T1;
+}
+
+
//===----------------------------------------------------------------------===//
// Initializer implementations
//===----------------------------------------------------------------------===//
@@ -398,7 +454,7 @@ Init *ListInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
return 0;
Vals.push_back(getElement(Elements[i]));
}
- return new ListInit(Vals);
+ return new ListInit(Vals, getType());
}
Record *ListInit::getElementAsRecord(unsigned i) const {
@@ -426,10 +482,20 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) {
}
if (Changed)
- return new ListInit(Resolved);
+ return new ListInit(Resolved, getType());
return this;
}
+Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV,
+ unsigned Elt) {
+ if (Elt >= getSize())
+ return 0; // Out of range reference.
+ Init *E = getElement(Elt);
+ if (!dynamic_cast<UnsetInit*>(E)) // If the element is set
+ return E; // Replace the VarListElementInit with it.
+ return 0;
+}
+
std::string ListInit::getAsString() const {
std::string Result = "[";
for (unsigned i = 0, e = Values.size(); i != e; ++i) {
@@ -538,7 +604,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
assert(0 && "Empty list in cdr");
return 0;
}
- ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end());
+ ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), LHSl->getType());
return Result;
}
break;
@@ -553,6 +619,16 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
return new IntInit(0);
}
}
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+ if (LHSs) {
+ if (LHSs->getValue().empty()) {
+ return new IntInit(1);
+ }
+ else {
+ return new IntInit(0);
+ }
+ }
+
break;
}
}
@@ -665,8 +741,8 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
if (Record *D = Records.getDef(Name))
return new DefInit(D);
- cerr << "Variable not defined: '" + Name + "'\n";
- assert(0 && "Variable not found");
+ cerr << "Variable not defined in !nameconcat: '" + Name + "'\n";
+ assert(0 && "Variable not found in !nameconcat");
return 0;
}
break;
@@ -848,7 +924,7 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
delete NewOp;
}
}
- return new ListInit(NewList);
+ return new ListInit(NewList, MHSl->getType());
}
}
return 0;
@@ -932,9 +1008,25 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) {
Init *lhs = LHS->resolveReferences(R, RV);
+
+ if (Opc == IF && lhs != LHS) {
+ IntInit *Value = dynamic_cast<IntInit*>(lhs);
+ if (Value != 0) {
+ // Short-circuit
+ if (Value->getValue()) {
+ Init *mhs = MHS->resolveReferences(R, RV);
+ return (new TernOpInit(getOpcode(), lhs, mhs, RHS, getType()))->Fold(&R, 0);
+ }
+ else {
+ Init *rhs = RHS->resolveReferences(R, RV);
+ return (new TernOpInit(getOpcode(), lhs, MHS, rhs, getType()))->Fold(&R, 0);
+ }
+ }
+ }
+
Init *mhs = MHS->resolveReferences(R, RV);
Init *rhs = RHS->resolveReferences(R, RV);
-
+
if (LHS != lhs || MHS != mhs || RHS != rhs)
return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0);
return Fold(&R, 0);
@@ -978,7 +1070,7 @@ Init *TypedInit::convertInitListSlice(const std::vector<unsigned> &Elements) {
ListInits.reserve(Elements.size());
for (unsigned i = 0, e = Elements.size(); i != e; ++i)
ListInits.push_back(new VarListElementInit(this, Elements[i]));
- return new ListInit(ListInits);
+ return new ListInit(ListInits, T);
}
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 4284cab..ac06cae 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -442,7 +442,10 @@ public:
virtual bool baseClassOf(const RecordRecTy *RHS) const;
};
-
+/// resolveTypes - Find a common type that T1 and T2 convert to.
+/// Return 0 if no such type exists.
+///
+RecTy *resolveTypes(RecTy *T1, RecTy *T2);
//===----------------------------------------------------------------------===//
// Initializer Classes
@@ -618,10 +621,10 @@ public:
/// IntInit - 7 - Represent an initalization by a literal integer value.
///
-class IntInit : public Init {
+class IntInit : public TypedInit {
int64_t Value;
public:
- explicit IntInit(int64_t V) : Value(V) {}
+ explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {}
int64_t getValue() const { return Value; }
@@ -631,6 +634,25 @@ public:
virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
virtual std::string getAsString() 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.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) {
+ assert(0 && "Illegal bit reference off int");
+ return 0;
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt) {
+ assert(0 && "Illegal element reference off int");
+ return 0;
+ }
};
@@ -688,17 +710,18 @@ public:
/// ListInit - [AL, AH, CL] - Represent a list of defs
///
-class ListInit : public Init {
+class ListInit : public TypedInit {
std::vector<Init*> Values;
public:
typedef std::vector<Init*>::iterator iterator;
typedef std::vector<Init*>::const_iterator const_iterator;
- explicit ListInit(std::vector<Init*> &Vs) {
+ explicit ListInit(std::vector<Init*> &Vs, RecTy *EltTy)
+ : TypedInit(new ListRecTy(EltTy)) {
Values.swap(Vs);
}
- explicit ListInit(iterator Start, iterator End)
- : Values(Start, End) {}
+ explicit ListInit(iterator Start, iterator End, RecTy *EltTy)
+ : TypedInit(new ListRecTy(EltTy)), Values(Start, End) {}
unsigned getSize() const { return Values.size(); }
Init *getElement(unsigned i) const {
@@ -730,6 +753,22 @@ public:
inline size_t size () const { return Values.size(); }
inline bool empty() const { return Values.empty(); }
+
+ /// 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.
+ ///
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit) {
+ assert(0 && "Illegal bit reference off list");
+ return 0;
+ }
+
+ /// resolveListElementReference - This method is used to implement
+ /// VarListElementInit::resolveReferences. If the list element is resolvable
+ /// now, we return the resolved value, otherwise we return null.
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt);
};
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index fc6f29f..cdd2857 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include <algorithm>
+#include <sstream>
#include "TGParser.h"
#include "Record.h"
@@ -396,7 +397,7 @@ ParseSubClassReference(Record *CurRec, bool isDefm) {
return Result;
}
- Result.TemplateArgs = ParseValueList(CurRec);
+ Result.TemplateArgs = ParseValueList(CurRec, Result.Rec);
if (Result.TemplateArgs.empty()) {
Result.Rec = 0; // Error parsing value list.
return Result;
@@ -438,7 +439,7 @@ ParseSubMultiClassReference(MultiClass *CurMC) {
return Result;
}
- Result.TemplateArgs = ParseValueList(&CurMC->Rec);
+ Result.TemplateArgs = ParseValueList(&CurMC->Rec, &Result.MC->Rec);
if (Result.TemplateArgs.empty()) {
Result.MC = 0; // Error parsing value list.
return Result;
@@ -728,21 +729,28 @@ Init *TGParser::ParseOperation(Record *CurRec) {
|| Code == UnOpInit::CDR
|| Code == UnOpInit::LNULL) {
ListInit *LHSl = dynamic_cast<ListInit*>(LHS);
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
TypedInit *LHSt = dynamic_cast<TypedInit*>(LHS);
- if (LHSl == 0 && LHSt == 0) {
- TokError("expected list type argument in unary operator");
+ if (LHSl == 0 && LHSs == 0 && LHSt == 0) {
+ TokError("expected list or string type argument in unary operator");
return 0;
}
if (LHSt) {
ListRecTy *LType = dynamic_cast<ListRecTy*>(LHSt->getType());
- if (LType == 0) {
- TokError("expected list type argumnet in unary operator");
+ StringRecTy *SType = dynamic_cast<StringRecTy*>(LHSt->getType());
+ if (LType == 0 && SType == 0) {
+ TokError("expected list or string type argumnet in unary operator");
return 0;
}
}
if (Code == UnOpInit::CAR
|| Code == UnOpInit::CDR) {
+ if (LHSl == 0 && LHSt == 0) {
+ TokError("expected list type argumnet in unary operator");
+ return 0;
+ }
+
if (LHSl && LHSl->getSize() == 0) {
TokError("empty list argument in unary operator");
return 0;
@@ -1011,7 +1019,7 @@ RecTy *TGParser::ParseOperatorType(void) {
/// SimpleValue ::= SRLTOK '(' Value ',' Value ')'
/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
///
-Init *TGParser::ParseSimpleValue(Record *CurRec) {
+Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) {
Init *R = 0;
switch (Lex.getCode()) {
default: TokError("Unknown token when parsing a value"); break;
@@ -1043,15 +1051,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
TokError("expected non-empty value list");
return 0;
}
- std::vector<Init*> ValueList = ParseValueList(CurRec);
- if (ValueList.empty()) return 0;
-
- if (Lex.getCode() != tgtok::greater) {
- TokError("expected '>' at end of value list");
- return 0;
- }
- Lex.Lex(); // eat the '>'
-
+
// This is a CLASS<initvalslist> expression. This is supposed to synthesize
// a new anonymous definition, deriving from CLASS<initvalslist> with no
// body.
@@ -1060,6 +1060,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
Error(NameLoc, "Expected a class name, got '" + Name + "'");
return 0;
}
+
+ std::vector<Init*> ValueList = ParseValueList(CurRec, Class);
+ if (ValueList.empty()) return 0;
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected '>' at end of value list");
+ return 0;
+ }
+ Lex.Lex(); // eat the '>'
// Create the new record, set it as CurRec temporarily.
static unsigned AnonCounter = 0;
@@ -1108,8 +1117,22 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
Lex.Lex(); // eat the '['
std::vector<Init*> Vals;
+ RecTy *DeducedEltTy = 0;
+ ListRecTy *GivenListTy = 0;
+
+ if (ItemType != 0) {
+ ListRecTy *ListType = dynamic_cast<ListRecTy*>(ItemType);
+ if (ListType == 0) {
+ std::stringstream s;
+ s << "Type mismatch for list, expected list type, got "
+ << ItemType->getAsString();
+ TokError(s.str());
+ }
+ GivenListTy = ListType;
+ }
+
if (Lex.getCode() != tgtok::r_square) {
- Vals = ParseValueList(CurRec);
+ Vals = ParseValueList(CurRec, 0, GivenListTy ? GivenListTy->getElementType() : 0);
if (Vals.empty()) return 0;
}
if (Lex.getCode() != tgtok::r_square) {
@@ -1117,7 +1140,77 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
return 0;
}
Lex.Lex(); // eat the ']'
- return new ListInit(Vals);
+
+ RecTy *GivenEltTy = 0;
+ if (Lex.getCode() == tgtok::less) {
+ // Optional list element type
+ Lex.Lex(); // eat the '<'
+
+ GivenEltTy = ParseType();
+ if (GivenEltTy == 0) {
+ // Couldn't parse element type
+ return 0;
+ }
+
+ if (Lex.getCode() != tgtok::greater) {
+ TokError("expected '>' at end of list element type");
+ return 0;
+ }
+ Lex.Lex(); // eat the '>'
+ }
+
+ // Check elements
+ RecTy *EltTy = 0;
+ for (std::vector<Init *>::iterator i = Vals.begin(), ie = Vals.end();
+ i != ie;
+ ++i) {
+ TypedInit *TArg = dynamic_cast<TypedInit*>(*i);
+ if (TArg == 0) {
+ TokError("Untyped list element");
+ return 0;
+ }
+ if (EltTy != 0) {
+ EltTy = resolveTypes(EltTy, TArg->getType());
+ if (EltTy == 0) {
+ TokError("Incompatible types in list elements");
+ return 0;
+ }
+ }
+ else {
+ EltTy = TArg->getType();
+ }
+ }
+
+ if (GivenEltTy != 0) {
+ if (EltTy != 0) {
+ // Verify consistency
+ if (!EltTy->typeIsConvertibleTo(GivenEltTy)) {
+ TokError("Incompatible types in list elements");
+ return 0;
+ }
+ }
+ EltTy = GivenEltTy;
+ }
+
+ if (EltTy == 0) {
+ if (ItemType == 0) {
+ TokError("No type for list");
+ return 0;
+ }
+ DeducedEltTy = GivenListTy->getElementType();
+ }
+ else {
+ // Make sure the deduced type is compatible with the given type
+ if (GivenListTy) {
+ if (!EltTy->typeIsConvertibleTo(GivenListTy->getElementType())) {
+ TokError("Element type mismatch for list");
+ return 0;
+ }
+ }
+ DeducedEltTy = EltTy;
+ }
+
+ return new ListInit(Vals, DeducedEltTy);
}
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
Lex.Lex(); // eat the '('
@@ -1193,8 +1286,8 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
/// ValueSuffix ::= '[' BitList ']'
/// ValueSuffix ::= '.' ID
///
-Init *TGParser::ParseValue(Record *CurRec) {
- Init *Result = ParseSimpleValue(CurRec);
+Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) {
+ Init *Result = ParseSimpleValue(CurRec, ItemType);
if (Result == 0) return 0;
// Parse the suffixes now if present.
@@ -1299,15 +1392,31 @@ TGParser::ParseDagArgList(Record *CurRec) {
///
/// ValueList ::= Value (',' Value)
///
-std::vector<Init*> TGParser::ParseValueList(Record *CurRec) {
+std::vector<Init*> TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, RecTy *EltTy) {
std::vector<Init*> Result;
- Result.push_back(ParseValue(CurRec));
+ RecTy *ItemType = EltTy;
+ int ArgN = 0;
+ if (ArgsRec != 0 && EltTy == 0) {
+ const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+ const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+ assert(RV && "Template argument record not found??");
+ ItemType = RV->getType();
+ ++ArgN;
+ }
+ Result.push_back(ParseValue(CurRec, ItemType));
if (Result.back() == 0) return std::vector<Init*>();
while (Lex.getCode() == tgtok::comma) {
Lex.Lex(); // Eat the comma
- Result.push_back(ParseValue(CurRec));
+ if (ArgsRec != 0 && EltTy == 0) {
+ const std::vector<std::string> &TArgs = ArgsRec->getTemplateArgs();
+ const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]);
+ assert(RV && "Template argument record not found??");
+ ItemType = RV->getType();
+ ++ArgN;
+ }
+ Result.push_back(ParseValue(CurRec, ItemType));
if (Result.back() == 0) return std::vector<Init*>();
}
@@ -1362,7 +1471,7 @@ std::string TGParser::ParseDeclaration(Record *CurRec,
if (Lex.getCode() == tgtok::equal) {
Lex.Lex();
TGLoc ValLoc = Lex.getLoc();
- Init *Val = ParseValue(CurRec);
+ Init *Val = ParseValue(CurRec, Type);
if (Val == 0 ||
SetValue(CurRec, ValLoc, DeclName, std::vector<unsigned>(), Val))
return "";
@@ -1440,7 +1549,13 @@ bool TGParser::ParseBodyItem(Record *CurRec) {
return TokError("expected '=' in let expression");
Lex.Lex(); // eat the '='.
- Init *Val = ParseValue(CurRec);
+ RecordVal *Field = CurRec->getValue(FieldName);
+ if (Field == 0)
+ return TokError("Value '" + FieldName + "' unknown!");
+
+ RecTy *Type = Field->getType();
+
+ Init *Val = ParseValue(CurRec, Type);
if (Val == 0) return true;
if (Lex.getCode() != tgtok::semi)
diff --git a/utils/TableGen/TGParser.h b/utils/TableGen/TGParser.h
index f03052e..3af467d 100644
--- a/utils/TableGen/TGParser.h
+++ b/utils/TableGen/TGParser.h
@@ -93,9 +93,9 @@ private: // Parser methods.
Init *ParseIDValue(Record *CurRec);
Init *ParseIDValue(Record *CurRec, const std::string &Name, TGLoc NameLoc);
- Init *ParseSimpleValue(Record *CurRec);
- Init *ParseValue(Record *CurRec);
- std::vector<Init*> ParseValueList(Record *CurRec);
+ Init *ParseSimpleValue(Record *CurRec, RecTy *ItemType = 0);
+ Init *ParseValue(Record *CurRec, RecTy *ItemType = 0);
+ std::vector<Init*> ParseValueList(Record *CurRec, Record *ArgsRec = 0, RecTy *EltTy = 0);
std::vector<std::pair<llvm::Init*, std::string> > ParseDagArgList(Record *);
bool ParseOptionalRangeList(std::vector<unsigned> &Ranges);
bool ParseOptionalBitList(std::vector<unsigned> &Ranges);
diff --git a/utils/crosstool/ARM/build-install-linux.sh b/utils/crosstool/ARM/build-install-linux.sh
new file mode 100755
index 0000000..33833b5
--- /dev/null
+++ b/utils/crosstool/ARM/build-install-linux.sh
@@ -0,0 +1,203 @@
+#!/bin/bash
+#
+# Compiles and installs a Linux/x86_64 -> Linux/ARM crosstool based on LLVM and
+# LLVM-GCC-4.2 using SVN snapshots in provided tarballs.
+
+set -o nounset
+set -o errexit
+
+echo -n "Welcome to LLVM Linux/X86_64 -> Linux/ARM crosstool "
+echo "builder/installer; some steps will require sudo privileges."
+
+readonly INSTALL_ROOT="${INSTALL_ROOT:-/usr/local}"
+# Both $USER and root *must* have read/write access to this dir.
+readonly SCRATCH_ROOT=$(mktemp -d "${TMPDIR:-/tmp}/llvm-project.XXXXXX")
+readonly SRC_ROOT="${SCRATCH_ROOT}/src"
+readonly OBJ_ROOT="${SCRATCH_ROOT}/obj"
+
+readonly CROSS_HOST="x86_64-unknown-linux-gnu"
+readonly CROSS_TARGET="arm-none-linux-gnueabi"
+
+readonly CODE_SOURCERY="${INSTALL_ROOT}/codesourcery"
+readonly CODE_SOURCERY_PKG_PATH="${CODE_SOURCERY_PKG_PATH:-${HOME}/codesourcery}"
+readonly CODE_SOURCERY_HTTP="http://www.codesourcery.com/sgpp/lite/arm/portal/package1787/public"
+readonly CODE_SOURCERY_PKG="arm-2007q3-51-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2"
+readonly CODE_SOURCERY_ROOT="${CODE_SOURCERY}/arm-2007q3"
+readonly CODE_SOURCERY_BIN="${CODE_SOURCERY_ROOT}/bin"
+# Make sure ${CROSS_TARGET}-* binutils are in command path
+export PATH="${CODE_SOURCERY_BIN}:${PATH}"
+
+readonly CROSS_TARGET_AS="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-as"
+readonly CROSS_TARGET_LD="${CODE_SOURCERY_BIN}/${CROSS_TARGET}-ld"
+
+readonly SYSROOT="${CODE_SOURCERY_ROOT}/${CROSS_TARGET}/libc"
+
+readonly LLVM_PROJECT="${INSTALL_ROOT}/llvm-project"
+readonly LLVM_INSTALL_ROOT="${LLVM_PROJECT}/${CROSS_HOST}/${CROSS_TARGET}"
+readonly LLVM_PKG_PATH="${LLVM_PKG_PATH:-${HOME}/llvm-project/snapshots}"
+
+# Latest SVN revision known to be working in this configuration.
+readonly LLVM_DEFAULT_REV="70786"
+
+readonly LLVM_PKG="llvm-${LLVM_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
+readonly LLVM_SRC_DIR="${SRC_ROOT}/llvm"
+readonly LLVM_OBJ_DIR="${OBJ_ROOT}/llvm"
+readonly LLVM_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm"
+
+readonly LLVMGCC_PKG="llvm-gcc-4.2-${LLVMGCC_SVN_REV:-${LLVM_DEFAULT_REV}}.tar.bz2"
+readonly LLVMGCC_SRC_DIR="${SRC_ROOT}/llvm-gcc-4.2"
+readonly LLVMGCC_OBJ_DIR="${OBJ_ROOT}/llvm-gcc-4.2"
+readonly LLVMGCC_INSTALL_DIR="${LLVM_INSTALL_ROOT}/llvm-gcc-4.2"
+
+readonly MAKE_OPTS="-j2"
+
+# Verify we aren't going to install into an existing directory as this might
+# create problems as we won't have a clean install.
+verifyNotDir() {
+ if [[ -d $1 ]]; then
+ echo "Install dir $1 already exists; remove it to continue."
+ exit
+ fi
+}
+
+# Params:
+# $1: directory to be created
+# $2: optional mkdir command prefix, e.g. "sudo"
+createDir() {
+ if [[ ! -e $1 ]]; then
+ ${2:-} mkdir -p $1
+ elif [[ -e $1 && ! -d $1 ]]; then
+ echo "$1 exists but is not a directory; exiting."
+ exit 3
+ fi
+}
+
+sudoCreateDir() {
+ createDir $1 sudo
+ sudo chown ${USER} $1
+}
+
+# Prints out and runs the command, but without logging -- intended for use with
+# lightweight commands that don't have useful output to parse, e.g. mkdir, tar,
+# etc.
+runCommand() {
+ local message="$1"
+ shift
+ echo "=> $message"
+ echo "==> Running: $*"
+ $*
+}
+
+runAndLog() {
+ local message="$1"
+ local log_file="$2"
+ shift 2
+ echo "=> $message; log in $log_file"
+ echo "==> Running: $*"
+ # Pop-up a terminal with the output of the current command?
+ # e.g.: xterm -e /bin/bash -c "$* >| tee $log_file"
+ $* &> $log_file
+ if [[ $? != 0 ]]; then
+ echo "Error occurred: see most recent log file for details."
+ exit
+ fi
+}
+
+installCodeSourcery() {
+ # Create CodeSourcery dir, if necessary.
+ verifyNotDir ${CODE_SOURCERY}
+ sudoCreateDir ${CODE_SOURCERY}
+
+ # Unpack the tarball.
+ if [[ ! -d ${CODE_SOURCERY_ROOT} ]]; then
+ cd ${CODE_SOURCERY}
+ if [[ -e ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG} ]]; then
+ runCommand "Unpacking CodeSourcery in ${CODE_SOURCERY}" \
+ tar jxf ${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}
+ else
+ echo -n "CodeSourcery tarball not found in "
+ echo "${CODE_SOURCERY_PKG_PATH}/${CODE_SOURCERY_PKG}"
+ echo -n "Fix the path or download it from "
+ echo "${CODE_SOURCERY_HTTP}/${CROSS_TARGET}/${CODE_SOURCERY_PKG}"
+ exit
+ fi
+ else
+ echo "CodeSourcery install dir already exists."
+ fi
+
+ # Verify our CodeSourcery toolchain installation.
+ if [[ ! -d "${SYSROOT}" ]]; then
+ echo -n "Error: CodeSourcery does not contain libc for ${CROSS_TARGET}: "
+ echo "${SYSROOT} not found."
+ exit
+ fi
+
+ for tool in ${CROSS_TARGET_AS} ${CROSS_TARGET_LD}; do
+ if [[ ! -e $tool ]]; then
+ echo "${tool} not found; exiting."
+ exit
+ fi
+ done
+}
+
+installLLVM() {
+ verifyNotDir ${LLVM_INSTALL_DIR}
+ sudoCreateDir ${LLVM_INSTALL_DIR}
+
+ # Unpack LLVM tarball; should create the directory "llvm".
+ cd ${SRC_ROOT}
+ runCommand "Unpacking LLVM" tar jxf ${LLVM_PKG_PATH}/${LLVM_PKG}
+
+ # Configure, build, and install LLVM.
+ createDir ${LLVM_OBJ_DIR}
+ cd ${LLVM_OBJ_DIR}
+ runAndLog "Configuring LLVM" ${LLVM_OBJ_DIR}/llvm-configure.log \
+ ${LLVM_SRC_DIR}/configure \
+ --disable-jit \
+ --enable-optimized \
+ --prefix=${LLVM_INSTALL_DIR} \
+ --target=${CROSS_TARGET} \
+ --with-llvmgccdir=${LLVMGCC_INSTALL_DIR}
+ runAndLog "Building LLVM" ${LLVM_OBJ_DIR}/llvm-build.log \
+ make ${MAKE_OPTS}
+ runAndLog "Installing LLVM" ${LLVM_OBJ_DIR}/llvm-install.log \
+ make ${MAKE_OPTS} install
+}
+
+installLLVMGCC() {
+ verifyNotDir ${LLVMGCC_INSTALL_DIR}
+ sudoCreateDir ${LLVMGCC_INSTALL_DIR}
+
+ # Unpack LLVM-GCC tarball; should create the directory "llvm-gcc-4.2".
+ cd ${SRC_ROOT}
+ runCommand "Unpacking LLVM-GCC" tar jxf ${LLVM_PKG_PATH}/${LLVMGCC_PKG}
+
+ # Configure, build, and install LLVM-GCC.
+ createDir ${LLVMGCC_OBJ_DIR}
+ cd ${LLVMGCC_OBJ_DIR}
+ runAndLog "Configuring LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-configure.log \
+ ${LLVMGCC_SRC_DIR}/configure \
+ --enable-languages=c,c++ \
+ --enable-llvm=${LLVM_INSTALL_DIR} \
+ --prefix=${LLVMGCC_INSTALL_DIR} \
+ --program-prefix=llvm- \
+ --target=${CROSS_TARGET} \
+ --with-gnu-as=${CROSS_TARGET_AS} \
+ --with-gnu-ld=${CROSS_TARGET_LD} \
+ --with-sysroot=${SYSROOT}
+ runAndLog "Building LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-build.log \
+ make
+ runAndLog "Installing LLVM-GCC" ${LLVMGCC_OBJ_DIR}/llvmgcc-install.log \
+ make install
+}
+
+echo "Building in ${SCRATCH_ROOT}; installing in ${INSTALL_ROOT}"
+
+createDir ${SRC_ROOT}
+createDir ${OBJ_ROOT}
+
+installCodeSourcery
+installLLVM
+installLLVMGCC
+
+echo "Done."
diff --git a/utils/crosstool/create-snapshots.sh b/utils/crosstool/create-snapshots.sh
new file mode 100755
index 0000000..7c640bc
--- /dev/null
+++ b/utils/crosstool/create-snapshots.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Creates LLVM SVN snapshots: llvm-$REV.tar.bz2 and llvm-gcc-4.2-$REV.tar.bz2,
+# where $REV is an SVN revision of LLVM. This is used for creating stable
+# tarballs which can be used to build known-to-work crosstools.
+#
+# Syntax:
+# $0 [REV] -- grabs the revision $REV from SVN; if not specified, grabs the
+# latest SVN revision.
+
+set -o nounset
+set -o errexit
+
+readonly REV="${1:-HEAD}"
+
+runOnModule() {
+ local module=$1
+ local log="${module}.log"
+ echo "Running: svn co -r ${REV} ${module}; log in ${log}"
+ svn co -r ${REV} http://llvm.org/svn/llvm-project/${module}/trunk ${module} \
+ > ${log} 2>&1
+
+ # Delete all the ".svn" dirs; they take quite a lot of space.
+ echo "Cleaning up .svn dirs"
+ find ${module} -type d -name \.svn -print0 | xargs -0 /bin/rm -rf
+
+ # Create "module-revision.tar.bz2" packages from the SVN checkout dirs.
+ local revision=$(grep "Checked out revision" ${log} | \
+ sed 's/[^0-9]\+\([0-9]\+\)[^0-9]\+/\1/')
+ local tarball="${module}-${revision}.tar.bz2"
+ echo "Creating tarball: ${tarball}"
+ tar cjf ${tarball} ${module}
+
+ echo "Cleaning SVN checkout dir ${module}"
+ rm -rf ${module} ${log}
+}
+
+for module in "llvm" "llvm-gcc-4.2"; do
+ runOnModule ${module}
+done
+
OpenPOWER on IntegriCloud