Changes in directory llvm/utils/TableGen:
FileLexer.l updated: 1.28 -> 1.29 FileParser.y updated: 1.41 -> 1.42 Record.cpp updated: 1.52 -> 1.53 Record.h updated: 1.56 -> 1.57 --- Log message: Generalize the previous binary operator support and add a string concatenation operation. This implements Regression/TableGen/strconcat.td. --- Diffs of the changes: (+109 -38) FileLexer.l | 1 FileParser.y | 22 ++++----------- Record.cpp | 84 ++++++++++++++++++++++++++++++++++++++++++++++++----------- Record.h | 40 +++++++++++++++++++++++----- 4 files changed, 109 insertions(+), 38 deletions(-) Index: llvm/utils/TableGen/FileLexer.l diff -u llvm/utils/TableGen/FileLexer.l:1.28 llvm/utils/TableGen/FileLexer.l:1.29 --- llvm/utils/TableGen/FileLexer.l:1.28 Fri Mar 3 13:34:28 2006 +++ llvm/utils/TableGen/FileLexer.l Fri Mar 31 15:53:49 2006 @@ -202,6 +202,7 @@ !sra { return SRATOK; } !srl { return SRLTOK; } !shl { return SHLTOK; } +!strconcat { return STRCONCATTOK; } {Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng); Index: llvm/utils/TableGen/FileParser.y diff -u llvm/utils/TableGen/FileParser.y:1.41 llvm/utils/TableGen/FileParser.y:1.42 --- llvm/utils/TableGen/FileParser.y:1.41 Thu Mar 30 16:50:40 2006 +++ llvm/utils/TableGen/FileParser.y Fri Mar 31 15:53:49 2006 @@ -200,7 +200,7 @@ }; %token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN -%token SHLTOK SRATOK SRLTOK +%token SHLTOK SRATOK SRLTOK STRCONCATTOK %token <IntVal> INTVAL %token <StrVal> ID VARNAME STRVAL CODEFRAGMENT @@ -352,23 +352,13 @@ } delete $3; } | SHLTOK '(' Value ',' Value ')' { - $$ = $3->getBinaryOp(Init::SHL, $5); - if ($$ == 0) { - err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n"; - exit(1); - } + $$ = (new BinOpInit(BinOpInit::SHL, $3, $5))->Fold(); } | SRATOK '(' Value ',' Value ')' { - $$ = $3->getBinaryOp(Init::SRA, $5); - if ($$ == 0) { - err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n"; - exit(1); - } + $$ = (new BinOpInit(BinOpInit::SRA, $3, $5))->Fold(); } | SRLTOK '(' Value ',' Value ')' { - $$ = $3->getBinaryOp(Init::SRL, $5); - if ($$ == 0) { - err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n"; - exit(1); - } + $$ = (new BinOpInit(BinOpInit::SRL, $3, $5))->Fold(); + } | STRCONCATTOK '(' Value ',' Value ')' { + $$ = (new BinOpInit(BinOpInit::STRCONCAT, $3, $5))->Fold(); }; OptVarName : /* empty */ { Index: llvm/utils/TableGen/Record.cpp diff -u llvm/utils/TableGen/Record.cpp:1.52 llvm/utils/TableGen/Record.cpp:1.53 --- llvm/utils/TableGen/Record.cpp:1.52 Thu Mar 30 16:50:40 2006 +++ llvm/utils/TableGen/Record.cpp Fri Mar 31 15:53:49 2006 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// // +// Implement the tablegen record classes. // //===----------------------------------------------------------------------===// @@ -125,6 +126,19 @@ return 0; } +Init *StringRecTy::convertValue(BinOpInit *BO) { + if (BO->getOpcode() == BinOpInit::STRCONCAT) { + Init *L = BO->getLHS()->convertInitializerTo(this); + Init *R = BO->getRHS()->convertInitializerTo(this); + if (L == 0 || R == 0) return 0; + if (L != BO->getLHS() || R != BO->getRHS()) + return new BinOpInit(BinOpInit::STRCONCAT, L, R); + return BO; + } + return 0; +} + + Init *StringRecTy::convertValue(TypedInit *TI) { if (dynamic_cast<StringRecTy*>(TI->getType())) return TI; // Accept variable if already of the right type! @@ -299,21 +313,6 @@ return this; } -Init *IntInit::getBinaryOp(BinaryOp Op, Init *RHS) { - IntInit *RHSi = dynamic_cast<IntInit*>(RHS); - if (RHSi == 0) return 0; - - int NewValue; - switch (Op) { - default: assert(0 && "Unknown binop"); - case SHL: NewValue = Value << RHSi->getValue(); break; - case SRA: NewValue = Value >> RHSi->getValue(); break; - case SRL: NewValue = (unsigned)Value >> (unsigned)RHSi->getValue(); break; - } - return new IntInit(NewValue); -} - - Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) { BitsInit *BI = new BitsInit(Bits.size()); @@ -368,6 +367,61 @@ OS << "]"; } +Init *BinOpInit::Fold() { + switch (getOpcode()) { + default: assert(0 && "Unknown binop"); + case STRCONCAT: { + StringInit *LHSs = dynamic_cast<StringInit*>(LHS); + StringInit *RHSs = dynamic_cast<StringInit*>(RHS); + if (LHSs && RHSs) + return new StringInit(LHSs->getValue() + RHSs->getValue()); + break; + } + case SHL: + case SRA: + case SRL: { + IntInit *LHSi = dynamic_cast<IntInit*>(LHS); + IntInit *RHSi = dynamic_cast<IntInit*>(RHS); + if (LHSi && RHSi) { + int LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); + int Result; + switch (getOpcode()) { + default: assert(0 && "Bad opcode!"); + case SHL: Result = LHSv << RHSv; break; + case SRA: Result = LHSv >> RHSv; break; + case SRL: Result = (unsigned)LHSv >> (unsigned)RHSv; break; + } + return new IntInit(Result); + } + break; + } + } + return this; +} + +Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) { + Init *lhs = LHS->resolveReferences(R, RV); + Init *rhs = RHS->resolveReferences(R, RV); + + if (LHS != lhs || RHS != rhs) + return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(); + return Fold(); +} + +void BinOpInit::print(std::ostream &OS) const { + switch (Opc) { + case SHL: OS << "!shl"; break; + case SRA: OS << "!sra"; break; + case SRL: OS << "!srl"; break; + case STRCONCAT: OS << "!strconcat"; break; + } + OS << "("; + LHS->print(OS); + OS << ", "; + RHS->print(OS); + OS << ")"; +} + 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... Index: llvm/utils/TableGen/Record.h diff -u llvm/utils/TableGen/Record.h:1.56 llvm/utils/TableGen/Record.h:1.57 --- llvm/utils/TableGen/Record.h:1.56 Thu Mar 30 16:50:40 2006 +++ llvm/utils/TableGen/Record.h Fri Mar 31 15:53:49 2006 @@ -42,6 +42,7 @@ class StringInit; class CodeInit; class ListInit; +class BinOpInit; class DefInit; class DagInit; class TypedInit; @@ -75,6 +76,7 @@ virtual Init *convertValue( IntInit *II) { return 0; } virtual Init *convertValue(StringInit *SI) { return 0; } virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( BinOpInit *UI) { return 0; } virtual Init *convertValue( CodeInit *CI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } @@ -231,6 +233,7 @@ virtual Init *convertValue( IntInit *II) { return 0; } virtual Init *convertValue(StringInit *SI) { return (Init*)SI; } virtual Init *convertValue( ListInit *LI) { return 0; } + virtual Init *convertValue( BinOpInit *BO); virtual Init *convertValue( CodeInit *CI) { return 0; } virtual Init *convertValue(VarBitInit *VB) { return 0; } virtual Init *convertValue( DefInit *DI) { return 0; } @@ -465,11 +468,6 @@ return 0; } - enum BinaryOp { SHL, SRA, SRL }; - virtual Init *getBinaryOp(BinaryOp Op, Init *RHS) { - return 0; - } - /// resolveReferences - This method is used by classes that refer to other /// variables which may not be defined at the time they expression is formed. /// If a value is set for the variable later, this method will be called on @@ -570,8 +568,6 @@ } virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits); - virtual Init *getBinaryOp(BinaryOp Op, Init *RHS); - virtual void print(std::ostream &OS) const { OS << Value; } }; @@ -639,6 +635,36 @@ virtual void print(std::ostream &OS) const; }; +/// BinOpInit - !op (X, Y) - Combine two inits. +/// +class BinOpInit : public Init { +public: + enum BinaryOp { SHL, SRA, SRL, STRCONCAT }; +private: + BinaryOp Opc; + Init *LHS, *RHS; +public: + BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) { + } + + BinaryOp getOpcode() const { return Opc; } + Init *getLHS() const { return LHS; } + Init *getRHS() const { return RHS; } + + // Fold - If possible, fold this to a simpler init. Return this if not + // possible to fold. + Init *Fold(); + + virtual Init *convertInitializerTo(RecTy *Ty) { + return Ty->convertValue(this); + } + + virtual Init *resolveReferences(Record &R, const RecordVal *RV); + + virtual void print(std::ostream &OS) const; +}; + + /// TypedInit - This is the common super-class of types that have a specific, /// explicit, type. _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits