diff options
author | ed <ed@FreeBSD.org> | 2009-06-14 09:23:33 +0000 |
---|---|---|
committer | ed <ed@FreeBSD.org> | 2009-06-14 09:23:33 +0000 |
commit | db89e312d968c258aba3c79c1c398f5fb19267a3 (patch) | |
tree | 49817b316c4fdaa56d9d16ebf2555303d1a990e0 /utils | |
parent | de000e339094f8c6e06a635dac9a803861416ec6 (diff) | |
download | FreeBSD-src-db89e312d968c258aba3c79c1c398f5fb19267a3.zip FreeBSD-src-db89e312d968c258aba3c79c1c398f5fb19267a3.tar.gz |
Import LLVM r73340.
Diffstat (limited to 'utils')
-rwxr-xr-x | utils/GenLibDeps.pl | 8 | ||||
-rwxr-xr-x | utils/NewNightlyTest.pl | 31 | ||||
-rw-r--r-- | utils/TableGen/ClangDiagnosticsEmitter.cpp | 6 | ||||
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 23 | ||||
-rw-r--r-- | utils/TableGen/Record.cpp | 110 | ||||
-rw-r--r-- | utils/TableGen/Record.h | 53 | ||||
-rw-r--r-- | utils/TableGen/TGParser.cpp | 165 | ||||
-rw-r--r-- | utils/TableGen/TGParser.h | 6 | ||||
-rwxr-xr-x | utils/crosstool/ARM/build-install-linux.sh | 203 | ||||
-rwxr-xr-x | utils/crosstool/create-snapshots.sh | 41 |
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 + |