From sabre at nondot.org Mon Nov 19 01:38:58 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 19 Nov 2007 07:38:58 -0000 Subject: [llvm-commits] [llvm] r44226 - in /llvm/trunk/utils/TableGen: TGLexer.cpp TGLexer.h Message-ID: <200711190738.lAJ7cwdd023740@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 19 01:38:58 2007 New Revision: 44226 URL: http://llvm.org/viewvc/llvm-project?rev=44226&view=rev Log: Add carat diagnostics to tblgen lexer errors. Modified: llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGLexer.h Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44226&r1=44225&r2=44226&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Mon Nov 19 01:38:58 2007 @@ -37,14 +37,20 @@ delete CurBuf; } +/// ReturnError - Set the error to the specified string at the specified +/// location. This is defined to always return YYERROR. +int TGLexer::ReturnError(const char *Loc, const std::string &Msg) { + PrintError(Loc, Msg); + return YYERROR; +} -std::ostream &TGLexer::err() { +std::ostream &TGLexer::err() const { PrintIncludeStack(*cerr.stream()); return *cerr.stream(); } -void TGLexer::PrintIncludeStack(std::ostream &OS) { +void TGLexer::PrintIncludeStack(std::ostream &OS) const { for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i) OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier() << ":" << IncludeStack[i].LineNo << ":\n"; @@ -52,6 +58,30 @@ << CurLineNo << ": "; } +/// PrintError - Print the error at the specified location. +void TGLexer::PrintError(const char *ErrorLoc, const std::string &Msg) const { + err() << Msg << "\n"; + assert(ErrorLoc && "Location not specified!"); + + // Scan backward to find the start of the line. + const char *LineStart = ErrorLoc; + while (LineStart != CurBuf->getBufferStart() && + LineStart[-1] != '\n' && LineStart[-1] != '\r') + --LineStart; + // Get the end of the line. + const char *LineEnd = ErrorLoc; + while (LineEnd != CurBuf->getBufferEnd() && + LineEnd[0] != '\n' && LineEnd[0] != '\r') + ++LineEnd; + // Print out the line. + cerr << std::string(LineStart, LineEnd) << "\n"; + // Print out spaces before the carat. + const char *Pos = LineStart; + while (Pos != ErrorLoc) + cerr << (*Pos == '\t' ? '\t' : ' '); + cerr << "^\n"; +} + int TGLexer::getNextChar() { char CurChar = *CurPtr++; switch (CurChar) { @@ -139,13 +169,11 @@ while (*CurPtr != '"') { // If we hit the end of the buffer, report an error. - if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) { - TheError = "End of file in string literal"; - return YYERROR; - } else if (*CurPtr == '\n' || *CurPtr == '\r') { - TheError = "End of line in string literal"; - return YYERROR; - } + if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) + return ReturnError(StrStart, "End of file in string literal"); + + if (*CurPtr == '\n' || *CurPtr == '\r') + return ReturnError(StrStart, "End of line in string literal"); ++CurPtr; } @@ -210,10 +238,11 @@ /// comes next and enter the include. bool TGLexer::LexInclude() { // The token after the include must be a string. + const char *TokStart = CurPtr-7; int Tok = LexToken(); if (Tok == YYERROR) return true; if (Tok != STRVAL) { - TheError = "Expected filename after include"; + PrintError(TokStart, "Expected filename after include"); return true; } @@ -231,7 +260,7 @@ } if (NewBuf == 0) { - TheError = "Could not find include file '" + Filename + "'"; + PrintError(TokStart, "Could not find include file '" + Filename + "'"); return true; } @@ -265,6 +294,7 @@ /// SkipCComment - This skips C-style /**/ comments. The only difference from C /// is that we allow nesting. bool TGLexer::SkipCComment() { + const char *CommentStart = CurPtr-1; ++CurPtr; // skip the star. unsigned CommentDepth = 1; @@ -272,7 +302,7 @@ int CurChar = getNextChar(); switch (CurChar) { case EOF: - TheError = "Unterminated comment!"; + PrintError(CommentStart, "Unterminated comment!"); return true; case '*': // End of the comment? @@ -306,10 +336,10 @@ while (isxdigit(CurPtr[0])) ++CurPtr; - if (CurPtr == NumStart) { - TheError = "Invalid hexadecimal number"; - return YYERROR; - } + // Requires at least one hex digit. + if (CurPtr == NumStart) + return ReturnError(CurPtr-2, "Invalid hexadecimal number"); + Filelval.IntVal = strtoll(NumStart, 0, 16); return INTVAL; } else if (CurPtr[0] == 'b') { @@ -317,11 +347,10 @@ NumStart = CurPtr; while (CurPtr[0] == '0' || CurPtr[0] == '1') ++CurPtr; - - if (CurPtr == NumStart) { - TheError = "Invalid binary number"; - return YYERROR; - } + + // Requires at least one binary digit. + if (CurPtr == NumStart) + return ReturnError(CurPtr-2, "Invalid binary number"); Filelval.IntVal = strtoll(NumStart, 0, 2); return INTVAL; } @@ -360,8 +389,7 @@ } } - TheError = "Invalid Code Block"; - return YYERROR; + return ReturnError(CodeStart-2, "Unterminated Code Block"); } /// LexExclaim - Lex '!' and '![a-zA-Z]+'. @@ -382,8 +410,7 @@ if (Len == 3 && !memcmp(Start, "shl", 3)) return SHLTOK; if (Len == 9 && !memcmp(Start, "strconcat", 9)) return STRCONCATTOK; - TheError = "Unknown operator"; - return YYERROR; + return ReturnError(Start-1, "Unknown operator"); } //===----------------------------------------------------------------------===// @@ -431,9 +458,7 @@ int Filelex() { assert(TheLexer && "No lexer setup yet!"); int Tok = TheLexer->LexToken(); - if (Tok == YYERROR) { - err() << TheLexer->getError() << "\n"; + if (Tok == YYERROR) exit(1); - } return Tok; } Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=44226&r1=44225&r2=44226&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Mon Nov 19 01:38:58 2007 @@ -40,8 +40,6 @@ // IncludeDirectories - This is the list of directories we should search for // include files in. std::vector IncludeDirectories; - - std::string TheError; public: TGLexer(MemoryBuffer *StartBuf); ~TGLexer(); @@ -52,11 +50,14 @@ int LexToken(); - const std::string getError() const { return TheError; } + void PrintError(const char *Loc, const std::string &Msg) const; + + std::ostream &err() const; + void PrintIncludeStack(std::ostream &OS) const; - std::ostream &err(); - void PrintIncludeStack(std::ostream &OS); private: + int ReturnError(const char *Loc, const std::string &Msg); + int getNextChar(); void SkipBCPLComment(); bool SkipCComment(); From sabre at nondot.org Mon Nov 19 01:43:52 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 19 Nov 2007 07:43:52 -0000 Subject: [llvm-commits] [llvm] r44227 - in /llvm/trunk/utils/TableGen: TGLexer.cpp TGLexer.h Message-ID: <200711190743.lAJ7hqJR023919@zion.cs.uiuc.edu> Author: lattner Date: Mon Nov 19 01:43:52 2007 New Revision: 44227 URL: http://llvm.org/viewvc/llvm-project?rev=44227&view=rev Log: Record the start of the current token, for use in error reporting. Modified: llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGLexer.h Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44227&r1=44226&r2=44227&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Mon Nov 19 01:43:52 2007 @@ -27,6 +27,7 @@ TGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) { CurPtr = CurBuf->getBufferStart(); + TokStart = 0; } TGLexer::~TGLexer() { @@ -76,8 +77,7 @@ // Print out the line. cerr << std::string(LineStart, LineEnd) << "\n"; // Print out spaces before the carat. - const char *Pos = LineStart; - while (Pos != ErrorLoc) + for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos) cerr << (*Pos == '\t' ? '\t' : ' '); cerr << "^\n"; } @@ -122,6 +122,7 @@ } int TGLexer::LexToken() { + TokStart = CurPtr; // This always consumes at least one character. int CurChar = getNextChar(); @@ -238,11 +239,10 @@ /// comes next and enter the include. bool TGLexer::LexInclude() { // The token after the include must be a string. - const char *TokStart = CurPtr-7; int Tok = LexToken(); if (Tok == YYERROR) return true; if (Tok != STRVAL) { - PrintError(TokStart, "Expected filename after include"); + PrintError(getTokenStart(), "Expected filename after include"); return true; } @@ -260,7 +260,8 @@ } if (NewBuf == 0) { - PrintError(TokStart, "Could not find include file '" + Filename + "'"); + PrintError(getTokenStart(), + "Could not find include file '" + Filename + "'"); return true; } Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=44227&r1=44226&r2=44227&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Mon Nov 19 01:43:52 2007 @@ -40,6 +40,7 @@ // IncludeDirectories - This is the list of directories we should search for // include files in. std::vector IncludeDirectories; + const char *TokStart; public: TGLexer(MemoryBuffer *StartBuf); ~TGLexer(); @@ -50,7 +51,10 @@ int LexToken(); - void PrintError(const char *Loc, const std::string &Msg) const; + typedef const char* LocationTy; + LocationTy getTokenStart() const { return TokStart; } + + void PrintError(LocationTy Loc, const std::string &Msg) const; std::ostream &err() const; void PrintIncludeStack(std::ostream &OS) const; From resistor at mac.com Mon Nov 19 01:44:43 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 19 Nov 2007 07:44:43 -0000 Subject: [llvm-commits] [llvm] r44228 - /llvm/trunk/docs/tutorial/JITTutorial2.html Message-ID: <200711190744.lAJ7ii1X023958@zion.cs.uiuc.edu> Author: resistor Date: Mon Nov 19 01:44:43 2007 New Revision: 44228 URL: http://llvm.org/viewvc/llvm-project?rev=44228&view=rev Log: Fix a factually incorrect statement pointed out by Max Hailperin. Modified: llvm/trunk/docs/tutorial/JITTutorial2.html Modified: llvm/trunk/docs/tutorial/JITTutorial2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=44228&r1=44227&r2=44228&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Mon Nov 19 01:44:43 2007 @@ -47,7 +47,7 @@

The above is a graphical representation of a program in LLVM IR. It places each basic block on a node of a graph, and uses directed edges to indicate flow control. These blocks will be serialized when written to a text or bitcode file, but it is often useful conceptually to think of them as a graph. Again, if you are unsure about the code in the diagram, you should skim through the LLVM Language Reference Manual and convince yourself that it is, in fact, the GCD algorithm.

-

The first part of our code is the same as from first tutorial. The same basic setup is required: creating a module, verifying it, and running the PrintModulePass on it. Even the first segment of makeLLVMModule() looks the same, because gcd happens to have the same prototype as our mul_add function.

+

The first part of our code is practically the same as from the first tutorial. The same basic setup is required: creating a module, verifying it, and running the PrintModulePass on it. Even the first segment of makeLLVMModule() looks essentially the same, except that gcd takes one more parameter than mul_add.





From baldrick at free.fr  Mon Nov 19 09:04:41 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 19 Nov 2007 15:04:41 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44229 -
	/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Message-ID: <200711191504.lAJF4fIj018939@zion.cs.uiuc.edu>

Author: baldrick
Date: Mon Nov 19 09:04:41 2007
New Revision: 44229

URL: http://llvm.org/viewvc/llvm-project?rev=44229&view=rev
Log:
Add attributes corresponding to gcc's nothrow and
noreturn.  Get attributes via flags_from_decl_or_type.

Modified:
    llvm-gcc-4.0/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=44229&r1=44228&r2=44229&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Mon Nov 19 09:04:41 2007
@@ -988,12 +988,22 @@
   ParamAttrsVector Attrs;
   uint16_t RAttributes = ParamAttr::None;
 
+  int flags = flags_from_decl_or_type(decl ? decl : type);
+
   // Check for 'const' function attribute
-  if (decl && TREE_READONLY(decl))
+  if (flags & ECF_CONST)
     RAttributes |= ParamAttr::Const;
 
+  // Check for 'noreturn' function attribute
+  if (flags & ECF_NORETURN)
+    RAttributes |= ParamAttr::NoReturn;
+
+  // Check for 'nounwind' function attribute
+  if (flags & ECF_NOTHROW)
+    RAttributes |= ParamAttr::NoUnwind;
+
   // Check for 'pure' function attribute
-  if (decl && DECL_IS_PURE(decl))
+  if (flags & ECF_PURE)
     RAttributes |= ParamAttr::Pure;
 
   // Compute whether the result needs to be zext or sext'd




From baldrick at free.fr  Mon Nov 19 09:05:12 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 19 Nov 2007 15:05:12 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44230 -
	/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Message-ID: <200711191505.lAJF5C3k018973@zion.cs.uiuc.edu>

Author: baldrick
Date: Mon Nov 19 09:05:10 2007
New Revision: 44230

URL: http://llvm.org/viewvc/llvm-project?rev=44230&view=rev
Log:
Add attributes corresponding to gcc's nothrow and
noreturn.  Get attributes via flags_from_decl_or_type.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44230&r1=44229&r2=44230&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Mon Nov 19 09:05:10 2007
@@ -1023,12 +1023,22 @@
   ParamAttrsVector Attrs;
   uint16_t RAttributes = ParamAttr::None;
 
+  int flags = flags_from_decl_or_type(decl ? decl : type);
+
   // Check for 'const' function attribute
-  if (decl && TREE_READONLY(decl))
+  if (flags & ECF_CONST)
     RAttributes |= ParamAttr::Const;
 
+  // Check for 'noreturn' function attribute
+  if (flags & ECF_NORETURN)
+    RAttributes |= ParamAttr::NoReturn;
+
+  // Check for 'nounwind' function attribute
+  if (flags & ECF_NOTHROW)
+    RAttributes |= ParamAttr::NoUnwind;
+
   // Check for 'pure' function attribute
-  if (decl && DECL_IS_PURE(decl))
+  if (flags & ECF_PURE)
     RAttributes |= ParamAttr::Pure;
 
   // Compute whether the result needs to be zext or sext'd




From baldrick at free.fr  Mon Nov 19 09:06:19 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 19 Nov 2007 15:06:19 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44231 -
	/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
Message-ID: <200711191506.lAJF6JVJ019025@zion.cs.uiuc.edu>

Author: baldrick
Date: Mon Nov 19 09:06:19 2007
New Revision: 44231

URL: http://llvm.org/viewvc/llvm-project?rev=44231&view=rev
Log:
Workaround PR1146 by eliminating silly bitcasting in
calls due to disagreements over attributes.

Modified:
    llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=44231&r1=44230&r2=44231&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Nov 19 09:06:19 2007
@@ -33,6 +33,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h" // FIXME: Remove once PR1146 is done.
 #include "llvm/Module.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Support/MathExtras.h"
@@ -2648,20 +2649,31 @@
 
   Value *Callee = Emit(TREE_OPERAND(exp, 0), 0);
 
-  if (TREE_OPERAND(exp, 2)) {
-    // This is a direct call to a function using a static chain.  We need to
-    // change the function type to one with an extra parameter for the chain.
-    assert(fndecl && "Indirect static chain call!");
-    tree function_type = TYPE_MAIN_VARIANT(TREE_TYPE(fndecl));
-    tree static_chain = TREE_OPERAND(exp, 2);
-
-    unsigned CallingConv;
-    const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type,
-                                                           fndecl,
-                                                           static_chain,
-                                                           CallingConv);
-    Callee = CastToType(Instruction::BitCast, Callee, PointerType::get(Ty));
-  }
+  // Avoid this kind of thing while waiting for PR1146 to be fixed:
+  //
+  //   call void bitcast (void (i32* noalias , i32*)* @_Z3fooPiPVi
+  //     to void (i32*, i32*)*)( i32* %x, i32* %y )
+  //
+  // The problem is that some attributes like noalias are only stored in the
+  // GCC function declaration and are not available from the function type.
+  // Converting the function type to LLVM results in an LLVM function type
+  // without the attributes.  The function declaration however is turned into
+  // an LLVM function type with the attributes present.  The discrepancy in
+  // the types results in the bitcast.  The solution is to bitcast back to the
+  // type of the function declaration.  Once PR1146 is done this logic will only
+  // be needed for nested functions (-> TREE_OPERAND(exp, 2) is not NULL) - they
+  // get an extra parameter.
+  assert(TREE_TYPE (TREE_OPERAND (exp, 0)) &&
+         TREE_CODE(TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+         && "Not calling a function pointer?");
+  tree function_type = TREE_TYPE(TREE_TYPE (TREE_OPERAND (exp, 0)));
+  unsigned CallingConv;
+  const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type,
+                                                         fndecl,
+                                                         TREE_OPERAND(exp, 2),
+                                                         CallingConv);
+  Callee = BitCastToType(IntrinsicInst::StripPointerCasts(Callee),
+                         PointerType::get(Ty));
 
   //EmitCall(exp, DestLoc);
   Value *Result = EmitCallOf(Callee, exp, DestLoc);
@@ -2857,7 +2869,7 @@
       ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)));
     }
   }
-  
+
   // Compile stuff like:
   //   %tmp = call float (...)* bitcast (float ()* @foo to float (...)*)( )
   // to:




From baldrick at free.fr  Mon Nov 19 09:07:38 2007
From: baldrick at free.fr (Duncan Sands)
Date: Mon, 19 Nov 2007 15:07:38 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44232 -
	/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
Message-ID: <200711191507.lAJF7c7F019084@zion.cs.uiuc.edu>

Author: baldrick
Date: Mon Nov 19 09:07:37 2007
New Revision: 44232

URL: http://llvm.org/viewvc/llvm-project?rev=44232&view=rev
Log:
Workaround PR1146 by eliminating silly bitcasting in
calls due to disagreements over attributes.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=44232&r1=44231&r2=44232&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Mon Nov 19 09:07:37 2007
@@ -33,6 +33,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h" // FIXME: Remove once PR1146 is done.
 #include "llvm/Module.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Support/MathExtras.h"
@@ -2165,20 +2166,31 @@
 
   Value *Callee = Emit(TREE_OPERAND(exp, 0), 0);
 
-  if (TREE_OPERAND(exp, 2)) {
-    // This is a direct call to a function using a static chain.  We need to
-    // change the function type to one with an extra parameter for the chain.
-    assert(fndecl && "Indirect static chain call!");
-    tree function_type = TYPE_MAIN_VARIANT(TREE_TYPE(fndecl));
-    tree static_chain = TREE_OPERAND(exp, 2);
-
-    unsigned CallingConv;
-    const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type,
-                                                           fndecl,
-                                                           static_chain,
-                                                           CallingConv);
-    Callee = BitCastToType(Callee, PointerType::get(Ty));
-  }
+  // Avoid this kind of thing while waiting for PR1146 to be fixed:
+  //
+  //   call void bitcast (void (i32* noalias , i32*)* @_Z3fooPiPVi
+  //     to void (i32*, i32*)*)( i32* %x, i32* %y )
+  //
+  // The problem is that some attributes like noalias are only stored in the
+  // GCC function declaration and are not available from the function type.
+  // Converting the function type to LLVM results in an LLVM function type
+  // without the attributes.  The function declaration however is turned into
+  // an LLVM function type with the attributes present.  The discrepancy in
+  // the types results in the bitcast.  The solution is to bitcast back to the
+  // type of the function declaration.  Once PR1146 is done this logic will only
+  // be needed for nested functions (-> TREE_OPERAND(exp, 2) is not NULL) - they
+  // get an extra parameter.
+  assert(TREE_TYPE (TREE_OPERAND (exp, 0)) &&
+         TREE_CODE(TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+         && "Not calling a function pointer?");
+  tree function_type = TREE_TYPE(TREE_TYPE (TREE_OPERAND (exp, 0)));
+  unsigned CallingConv;
+  const Type *Ty = TheTypeConverter->ConvertFunctionType(function_type,
+                                                         fndecl,
+                                                         TREE_OPERAND(exp, 2),
+                                                         CallingConv);
+  Callee = BitCastToType(IntrinsicInst::StripPointerCasts(Callee),
+                         PointerType::get(Ty));
 
   //EmitCall(exp, DestLoc);
   Value *Result = EmitCallOf(Callee, exp, DestLoc);
@@ -2388,7 +2400,7 @@
       ABIConverter.HandleArgument(TREE_TYPE(TREE_VALUE(arg)));
     }
   }
-  
+
   // Compile stuff like:
   //   %tmp = call float (...)* bitcast (float ()* @foo to float (...)*)( )
   // to:




From djg at cray.com  Mon Nov 19 09:15:03 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 19 Nov 2007 15:15:03 -0000
Subject: [llvm-commits] [llvm] r44233 - in /llvm/trunk:
 lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
 test/CodeGen/X86/split-vector-rem.ll
Message-ID: <200711191515.lAJFF3s9019427@zion.cs.uiuc.edu>

Author: djg
Date: Mon Nov 19 09:15:03 2007
New Revision: 44233

URL: http://llvm.org/viewvc/llvm-project?rev=44233&view=rev
Log:
Add support in SplitVectorOp for remainder operators.

Added:
    llvm/trunk/test/CodeGen/X86/split-vector-rem.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44233&r1=44232&r2=44233&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 19 09:15:03 2007
@@ -6341,7 +6341,10 @@
   case ISD::FPOW:
   case ISD::AND:
   case ISD::OR:
-  case ISD::XOR: {
+  case ISD::XOR:
+  case ISD::UREM:
+  case ISD::SREM:
+  case ISD::FREM: {
     SDOperand LL, LH, RL, RH;
     SplitVectorOp(Node->getOperand(0), LL, LH);
     SplitVectorOp(Node->getOperand(1), RL, RH);

Added: llvm/trunk/test/CodeGen/X86/split-vector-rem.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/split-vector-rem.ll?rev=44233&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/split-vector-rem.ll (added)
+++ llvm/trunk/test/CodeGen/X86/split-vector-rem.ll Mon Nov 19 09:15:03 2007
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep div | count 16
+; RUN: llvm-as < %s | llc -march=x86-64 | grep fmodf | count 8
+
+define <8 x i32> @foo(<8 x i32> %t, <8 x i32> %u) {
+	%m = srem <8 x i32> %t, %u
+	ret <8 x i32> %m
+}
+define <8 x i32> @bar(<8 x i32> %t, <8 x i32> %u) {
+	%m = urem <8 x i32> %t, %u
+	ret <8 x i32> %m
+}
+define <8 x float> @qux(<8 x float> %t, <8 x float> %u) {
+	%m = frem <8 x float> %t, %u
+	ret <8 x float> %m
+}




From djg at cray.com  Mon Nov 19 09:30:21 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 19 Nov 2007 15:30:21 -0000
Subject: [llvm-commits] [llvm] r44234 - in /llvm/trunk:
 include/llvm/ADT/StringMap.h
 include/llvm/Analysis/ScalarEvolutionExpressions.h
 include/llvm/Bitcode/Serialize.h lib/Bitcode/Reader/BitcodeReader.cpp
 lib/Bitcode/Writer/BitcodeWriterPass.cpp
 lib/Transforms/Scalar/CorrelatedExprs.cpp
Message-ID: <200711191530.lAJFULjP020115@zion.cs.uiuc.edu>

Author: djg
Date: Mon Nov 19 09:30:20 2007
New Revision: 44234

URL: http://llvm.org/viewvc/llvm-project?rev=44234&view=rev
Log:
Add explicit keywords.

Modified:
    llvm/trunk/include/llvm/ADT/StringMap.h
    llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h
    llvm/trunk/include/llvm/Bitcode/Serialize.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriterPass.cpp
    llvm/trunk/lib/Transforms/Scalar/CorrelatedExprs.cpp

Modified: llvm/trunk/include/llvm/ADT/StringMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/StringMap.h (original)
+++ llvm/trunk/include/llvm/ADT/StringMap.h Mon Nov 19 09:30:20 2007
@@ -28,7 +28,7 @@
 class StringMapEntryBase {
   unsigned StrLen;
 public:
-  StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+  explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
   
   unsigned getKeyLength() const { return StrLen; }
 };
@@ -55,7 +55,7 @@
   unsigned NumTombstones;
   unsigned ItemSize;
 protected:
-  StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
+  explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {
     // Initialize the map with zero buckets to allocation.
     TheTable = 0;
     NumBuckets = 0;
@@ -115,7 +115,7 @@
 class StringMapEntry : public StringMapEntryBase {
   ValueTy Val;
 public:
-  StringMapEntry(unsigned StrLen)
+  explicit StringMapEntry(unsigned StrLen)
     : StringMapEntryBase(StrLen), Val() {}
   StringMapEntry(unsigned StrLen, const ValueTy &V)
     : StringMapEntryBase(StrLen), Val(V) {}
@@ -204,7 +204,7 @@
   typedef StringMapEntry MapEntryTy;
 public:
   StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
-  StringMap(unsigned InitialSize)
+  explicit StringMap(unsigned InitialSize)
     : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
   
   AllocatorTy &getAllocator() { return Allocator; }
@@ -314,8 +314,8 @@
 protected:
   StringMapImpl::ItemBucket *Ptr;
 public:
-  StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
-                         bool NoAdvance = false)
+  explicit StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+                                  bool NoAdvance = false)
   : Ptr(Bucket) {
     if (!NoAdvance) AdvancePastEmptyBuckets();
   }

Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original)
+++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Mon Nov 19 09:30:20 2007
@@ -285,7 +285,7 @@
   class SCEVAddExpr : public SCEVCommutativeExpr {
     friend class ScalarEvolution;
 
-    SCEVAddExpr(const std::vector &ops)
+    explicit SCEVAddExpr(const std::vector &ops)
       : SCEVCommutativeExpr(scAddExpr, ops) {
     }
 
@@ -305,7 +305,7 @@
   class SCEVMulExpr : public SCEVCommutativeExpr {
     friend class ScalarEvolution;
 
-    SCEVMulExpr(const std::vector &ops)
+    explicit SCEVMulExpr(const std::vector &ops)
       : SCEVCommutativeExpr(scMulExpr, ops) {
     }
 
@@ -468,7 +468,7 @@
     friend class ScalarEvolution;
 
     Value *V;
-    SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
+    explicit SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
 
   protected:
     ~SCEVUnknown();

Modified: llvm/trunk/include/llvm/Bitcode/Serialize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialize.h?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/Serialize.h (original)
+++ llvm/trunk/include/llvm/Bitcode/Serialize.h Mon Nov 19 09:30:20 2007
@@ -31,7 +31,7 @@
   MapTy PtrMap;
   
 public:
-  Serializer(BitstreamWriter& stream);
+  explicit Serializer(BitstreamWriter& stream);
   ~Serializer();
   
   template 

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Nov 19 09:30:20 2007
@@ -123,7 +123,7 @@
     void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
   public:
     Use Op;
-    ConstantPlaceHolder(const Type *Ty)
+    explicit ConstantPlaceHolder(const Type *Ty)
       : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
         Op(UndefValue::get(Type::Int32Ty), this) {
     }

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriterPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriterPass.cpp?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriterPass.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriterPass.cpp Mon Nov 19 09:30:20 2007
@@ -20,7 +20,8 @@
     std::ostream &Out;                 // ostream to print on
   public:
     static char ID; // Pass identifcation, replacement for typeid
-    WriteBitcodePass(std::ostream &o) : ModulePass((intptr_t) &ID), Out(o) {}
+    explicit WriteBitcodePass(std::ostream &o)
+      : ModulePass((intptr_t) &ID), Out(o) {}
     
     const char *getPassName() const { return "Bitcode Writer"; }
     

Modified: llvm/trunk/lib/Transforms/Scalar/CorrelatedExprs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedExprs.cpp?rev=44234&r1=44233&r2=44234&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/CorrelatedExprs.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/CorrelatedExprs.cpp Mon Nov 19 09:30:20 2007
@@ -57,7 +57,7 @@
     Value *Val;          // Relation to what value?
     unsigned Rel;        // SetCC or ICmp relation, or Add if no information
   public:
-    Relation(Value *V) : Val(V), Rel(Instruction::Add) {}
+    explicit Relation(Value *V) : Val(V), Rel(Instruction::Add) {}
     bool operator<(const Relation &R) const { return Val < R.Val; }
     Value *getValue() const { return Val; }
     unsigned getRelation() const { return Rel; }
@@ -112,7 +112,7 @@
     //
     Value *Replacement;
   public:
-    ValueInfo(const Type *Ty)
+    explicit ValueInfo(const Type *Ty)
       : Bounds(Ty->isInteger() ? cast(Ty)->getBitWidth()  : 32), 
                Replacement(0) {}
 
@@ -146,7 +146,7 @@
         return *I;
 
       // Insert and return the new relationship...
-      return *Relationships.insert(I, V);
+      return *Relationships.insert(I, Relation(V));
     }
 
     const Relation *requestRelation(Value *V) const {
@@ -176,7 +176,7 @@
     typedef std::map ValueMapTy;
     ValueMapTy ValueMap;
   public:
-    RegionInfo(BasicBlock *bb) : BB(bb) {}
+    explicit RegionInfo(BasicBlock *bb) : BB(bb) {}
 
     // getEntryBlock - Return the block that dominates all of the members of
     // this region.




From djg at cray.com  Mon Nov 19 09:36:20 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 19 Nov 2007 15:36:20 -0000
Subject: [llvm-commits] [llvm] r44235 -
	/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
Message-ID: <200711191536.lAJFaKoA020384@zion.cs.uiuc.edu>

Author: djg
Date: Mon Nov 19 09:36:19 2007
New Revision: 44235

URL: http://llvm.org/viewvc/llvm-project?rev=44235&view=rev
Log:
Fix a typo in a comment.

Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=44235&r1=44234&r2=44235&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Mon Nov 19 09:36:19 2007
@@ -180,7 +180,7 @@
 
     // CopyFromReg - This node indicates that the input value is a virtual or
     // physical register that is defined outside of the scope of this
-    // SelectionDAG.  The register is available from the RegSDNode object.
+    // SelectionDAG.  The register is available from the RegisterSDNode object.
     CopyFromReg,
 
     // UNDEF - An undefined node




From resistor at mac.com  Mon Nov 19 10:10:59 2007
From: resistor at mac.com (Owen Anderson)
Date: Mon, 19 Nov 2007 16:10:59 -0000
Subject: [llvm-commits] [llvm] r44236 -
	/llvm/trunk/docs/tutorial/JITTutorial2.html
Message-ID: <200711191610.lAJGAxxc021814@zion.cs.uiuc.edu>

Author: resistor
Date: Mon Nov 19 10:10:59 2007
New Revision: 44236

URL: http://llvm.org/viewvc/llvm-project?rev=44236&view=rev
Log:
Teach me to do stuff late at night.

Modified:
    llvm/trunk/docs/tutorial/JITTutorial2.html

Modified: llvm/trunk/docs/tutorial/JITTutorial2.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=44236&r1=44235&r2=44236&view=diff

==============================================================================
--- llvm/trunk/docs/tutorial/JITTutorial2.html (original)
+++ llvm/trunk/docs/tutorial/JITTutorial2.html Mon Nov 19 10:10:59 2007
@@ -47,7 +47,7 @@
 
 

The above is a graphical representation of a program in LLVM IR. It places each basic block on a node of a graph, and uses directed edges to indicate flow control. These blocks will be serialized when written to a text or bitcode file, but it is often useful conceptually to think of them as a graph. Again, if you are unsure about the code in the diagram, you should skim through the LLVM Language Reference Manual and convince yourself that it is, in fact, the GCD algorithm.

-

The first part of our code is practically the same as from the first tutorial. The same basic setup is required: creating a module, verifying it, and running the PrintModulePass on it. Even the first segment of makeLLVMModule() looks essentially the same, except that gcd takes one more parameter than mul_add.

+

The first part of our code is practically the same as from the first tutorial. The same basic setup is required: creating a module, verifying it, and running the PrintModulePass on it. Even the first segment of makeLLVMModule() looks essentially the same, except that gcd takes one fewer parameter than mul_add.





From lauro.venancio at gmail.com  Mon Nov 19 12:44:47 2007
From: lauro.venancio at gmail.com (Lauro Ramos Venancio)
Date: Mon, 19 Nov 2007 18:44:47 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44238 -
	/llvm-gcc-4.2/trunk/gcc/config/arm/arm.h
Message-ID: <200711191844.lAJIilVv030340@zion.cs.uiuc.edu>

Author: laurov
Date: Mon Nov 19 12:44:45 2007
New Revision: 44238

URL: http://llvm.org/viewvc/llvm-project?rev=44238&view=rev
Log:
ARM inline asm extension: use ASM_COMMENT_START instead of '@'.


Modified:
    llvm-gcc-4.2/trunk/gcc/config/arm/arm.h

Modified: llvm-gcc-4.2/trunk/gcc/config/arm/arm.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/arm/arm.h?rev=44238&r1=44237&r2=44238&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/arm/arm.h (original)
+++ llvm-gcc-4.2/trunk/gcc/config/arm/arm.h Mon Nov 19 12:44:45 2007
@@ -2723,7 +2723,7 @@
      TODO: %r prints out REGISTER_PREFIX reg_names[arg]  */
 #define LLVM_ASM_EXTENSIONS(ESCAPED_CHAR, ASM, RESULT)	\
   else if ((ESCAPED_CHAR) == '@') {       		\
-    (RESULT) += '@';                                    \
+    (RESULT) += ASM_COMMENT_START;                      \
   }
 
 /* LLVM LOCAL end */




From clattner at apple.com  Mon Nov 19 14:17:36 2007
From: clattner at apple.com (Chris Lattner)
Date: Mon, 19 Nov 2007 12:17:36 -0800
Subject: [llvm-commits] [llvm-gcc-4.2] r44238 -
	/llvm-gcc-4.2/trunk/gcc/config/arm/arm.h
In-Reply-To: <200711191844.lAJIilVv030340@zion.cs.uiuc.edu>
References: <200711191844.lAJIilVv030340@zion.cs.uiuc.edu>
Message-ID: <0D766A5C-E4FD-4B10-A6BD-EAC3ED646C27@apple.com>


On Nov 19, 2007, at 10:44 AM, Lauro Ramos Venancio wrote:

> Author: laurov
> Date: Mon Nov 19 12:44:45 2007
> New Revision: 44238
>
> URL: http://llvm.org/viewvc/llvm-project?rev=44238&view=rev
> Log:
> ARM inline asm extension: use ASM_COMMENT_START instead of '@'.

Thanks Lauro!

-Chris


From sabre at nondot.org  Mon Nov 19 14:21:32 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 19 Nov 2007 20:21:32 -0000
Subject: [llvm-commits] [llvm] r44239 -
	/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200711192021.lAJKLXLB002708@zion.cs.uiuc.edu>

Author: lattner
Date: Mon Nov 19 14:21:32 2007
New Revision: 44239

URL: http://llvm.org/viewvc/llvm-project?rev=44239&view=rev
Log:
Implement splitting of UNDEF nodes. This is the first step towards fixing PR1811

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44239&r1=44238&r2=44239&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 19 14:21:32 2007
@@ -6265,6 +6265,10 @@
     Node->dump(&DAG);
 #endif
     assert(0 && "Unhandled operation in SplitVectorOp!");
+  case ISD::UNDEF:
+    Lo = DAG.getNode(ISD::UNDEF, NewVT_Lo);
+    Hi = DAG.getNode(ISD::UNDEF, NewVT_Hi);
+    break;
   case ISD::BUILD_PAIR:
     Lo = Node->getOperand(0);
     Hi = Node->getOperand(1);




From djg at cray.com  Mon Nov 19 14:46:24 2007
From: djg at cray.com (Dan Gohman)
Date: Mon, 19 Nov 2007 20:46:24 -0000
Subject: [llvm-commits] [llvm] r44240 - in /llvm/trunk:
 include/llvm/Analysis/Dominators.h include/llvm/BasicBlock.h
 include/llvm/Target/TargetMachine.h lib/Target/PowerPC/PPCTargetMachine.cpp
 lib/Target/PowerPC/PPCTargetMachine.h lib/VMCore/BasicBlock.cpp
Message-ID: <200711192046.lAJKkOd3003827@zion.cs.uiuc.edu>

Author: djg
Date: Mon Nov 19 14:46:23 2007
New Revision: 44240

URL: http://llvm.org/viewvc/llvm-project?rev=44240&view=rev
Log:
Remove meaningless qualifiers from return types, avoiding compiler warnings.

Modified:
    llvm/trunk/include/llvm/Analysis/Dominators.h
    llvm/trunk/include/llvm/BasicBlock.h
    llvm/trunk/include/llvm/Target/TargetMachine.h
    llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
    llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h
    llvm/trunk/lib/VMCore/BasicBlock.cpp

Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
+++ llvm/trunk/include/llvm/Analysis/Dominators.h Mon Nov 19 14:46:23 2007
@@ -345,7 +345,7 @@
 
   /// isReachableFromEntry - Return true if A is dominated by the entry
   /// block of the function containing it.
-  const bool isReachableFromEntry(NodeT* A) {
+  bool isReachableFromEntry(NodeT* A) {
     assert (!this->isPostDominator() 
             && "This is not implemented for post dominators");
     return dominates(&A->getParent()->front(), A);

Modified: llvm/trunk/include/llvm/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/BasicBlock.h?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/include/llvm/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/BasicBlock.h Mon Nov 19 14:46:23 2007
@@ -93,7 +93,7 @@
   /// null pointer back.
   ///
   TerminatorInst *getTerminator();
-  const TerminatorInst *const getTerminator() const;
+  const TerminatorInst *getTerminator() const;
   
   /// Returns a pointer to the first instructon in this block that is not a 
   /// PHINode instruction. When adding instruction to the beginning of the

Modified: llvm/trunk/include/llvm/Target/TargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetMachine.h (original)
+++ llvm/trunk/include/llvm/Target/TargetMachine.h Mon Nov 19 14:46:23 2007
@@ -187,7 +187,7 @@
 
   /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
   /// on this target.  User flag overrides.
-  virtual const bool getEnableTailMergeDefault() const { return true; }
+  virtual bool getEnableTailMergeDefault() const { return true; }
 
   /// addPassesToEmitFile - Add passes to the specified pass manager to get the
   /// specified file emitted.  Typically this will involve several steps of code
@@ -325,7 +325,7 @@
 
   /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
   /// on this target.  User flag overrides.
-  virtual const bool getEnableTailMergeDefault() const { return true; }
+  virtual bool getEnableTailMergeDefault() const { return true; }
 };
 
 } // End llvm namespace

Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp Mon Nov 19 14:46:23 2007
@@ -101,7 +101,7 @@
 
 /// Override this for PowerPC.  Tail merging happily breaks up instruction issue
 /// groups, which typically degrades performance.
-const bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; }
+bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; }
 
 PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS) 
   : PPCTargetMachine(M, FS, false) {

Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.h Mon Nov 19 14:46:23 2007
@@ -73,7 +73,7 @@
                               bool DumpAsm, MachineCodeEmitter &MCE);
   virtual bool addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
                                     bool DumpAsm, MachineCodeEmitter &MCE);
-  virtual const bool getEnableTailMergeDefault() const;
+  virtual bool getEnableTailMergeDefault() const;
 };
 
 /// PPC32TargetMachine - PowerPC 32-bit target machine.

Modified: llvm/trunk/lib/VMCore/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/BasicBlock.cpp?rev=44240&r1=44239&r2=44240&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/BasicBlock.cpp (original)
+++ llvm/trunk/lib/VMCore/BasicBlock.cpp Mon Nov 19 14:46:23 2007
@@ -134,7 +134,7 @@
   return dyn_cast(&InstList.back());
 }
 
-const TerminatorInst *const BasicBlock::getTerminator() const {
+const TerminatorInst *BasicBlock::getTerminator() const {
   if (InstList.empty()) return 0;
   return dyn_cast(&InstList.back());
 }




From lauro.venancio at gmail.com  Mon Nov 19 14:49:31 2007
From: lauro.venancio at gmail.com (Lauro Ramos Venancio)
Date: Mon, 19 Nov 2007 20:49:31 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44241 - in /llvm-gcc-4.0/trunk/gcc:
 config/arm/arm.h llvm-convert.cpp
Message-ID: <200711192049.lAJKnVQk004059@zion.cs.uiuc.edu>

Author: laurov
Date: Mon Nov 19 14:49:31 2007
New Revision: 44241

URL: http://llvm.org/viewvc/llvm-project?rev=44241&view=rev
Log:
ARM: Implement the '%@' inline asm extension.


Modified:
    llvm-gcc-4.0/trunk/gcc/config/arm/arm.h
    llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp

Modified: llvm-gcc-4.0/trunk/gcc/config/arm/arm.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/arm/arm.h?rev=44241&r1=44240&r2=44241&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/config/arm/arm.h (original)
+++ llvm-gcc-4.0/trunk/gcc/config/arm/arm.h Mon Nov 19 14:49:31 2007
@@ -2925,6 +2925,15 @@
 
 /* Doing struct copy by partial-word loads and stores is not a good idea on ARM. */
 #define TARGET_LLVM_MIN_BYTES_COPY_BY_MEMCPY 4
+
+/* These are a couple of extensions to the asm formats
+     %@ prints out ASM_COMMENT_START
+     TODO: %r prints out REGISTER_PREFIX reg_names[arg]  */
+#define LLVM_ASM_EXTENSIONS(ESCAPED_CHAR, ASM, RESULT)	\
+  else if ((ESCAPED_CHAR) == '@') {       		\
+    (RESULT) += ASM_COMMENT_START;                      \
+  }
+
 /* APPLE LOCAL end llvm */
 
 #endif /* ! GCC_ARM_H */

Modified: llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp?rev=44241&r1=44240&r2=44241&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Mon Nov 19 14:49:31 2007
@@ -3831,7 +3831,11 @@
         Result += '%';
       } else if (EscapedChar == '=') {     // Unique ID for the asm instance.
         Result += utostr(InlineAsmNum);
-      } else if (ISALPHA(EscapedChar)) {
+      }
+#ifdef LLVM_ASM_EXTENSIONS
+      LLVM_ASM_EXTENSIONS(EscapedChar, InStr, Result)
+#endif
+      else if (ISALPHA(EscapedChar)) {
         // % followed by a letter and some digits. This outputs an operand in a
         // special way depending on the letter.  We turn this into LLVM ${N:o}
         // syntax.




From sabre at nondot.org  Mon Nov 19 15:16:54 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 19 Nov 2007 21:16:54 -0000
Subject: [llvm-commits] [llvm] r44242 -
	/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200711192116.lAJLGs7K005552@zion.cs.uiuc.edu>

Author: lattner
Date: Mon Nov 19 15:16:54 2007
New Revision: 44242

URL: http://llvm.org/viewvc/llvm-project?rev=44242&view=rev
Log:
Implement vector expand support for shuffle_vector.  This fixes PR1811.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44242&r1=44241&r2=44242&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 19 15:16:54 2007
@@ -6286,6 +6286,41 @@
                                        TLI.getPointerTy()));
     break;
   }
+  case ISD::VECTOR_SHUFFLE: {
+    // Build the low part.
+    SDOperand Mask = Node->getOperand(2);
+    SmallVector Ops;
+    MVT::ValueType PtrVT = TLI.getPointerTy();
+    
+    // Insert all of the elements from the input that are needed.  We use 
+    // buildvector of extractelement here because the input vectors will have
+    // to be legalized, so this makes the code simpler.
+    for (unsigned i = 0; i != NewNumElts_Lo; ++i) {
+      unsigned Idx = cast(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+    Ops.clear();
+    
+    for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) {
+      unsigned Idx = cast(Mask.getOperand(i))->getValue();
+      SDOperand InVec = Node->getOperand(0);
+      if (Idx >= NumElements) {
+        InVec = Node->getOperand(1);
+        Idx -= NumElements;
+      }
+      Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec,
+                                DAG.getConstant(Idx, PtrVT)));
+    }
+    Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size());
+    break;
+  }
   case ISD::BUILD_VECTOR: {
     SmallVector LoOps(Node->op_begin(), 
                                     Node->op_begin()+NewNumElts_Lo);




From sabre at nondot.org  Mon Nov 19 15:38:03 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 19 Nov 2007 21:38:03 -0000
Subject: [llvm-commits] [llvm] r44243 -
	/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Message-ID: <200711192138.lAJLc4gA006733@zion.cs.uiuc.edu>

Author: lattner
Date: Mon Nov 19 15:38:03 2007
New Revision: 44243

URL: http://llvm.org/viewvc/llvm-project?rev=44243&view=rev
Log:
ExpandUnalignedLoad doesn't handle vectors right at all apparently.
Fix a couple of problems:
1. Don't assume the VT-1 is a VT that is half the size.
2. Treat vectors of FP in the vector path, not the FP path.

This has a couple of remaining problems before it will work with
the code in PR1811: the code below this change assumes that it can
use extload/shift/or to construct the result, which isn't right for
vectors.

This also doesn't handle vectors of 1 or vectors that aren't pow-2.

Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44243&r1=44242&r2=44243&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon Nov 19 15:38:03 2007
@@ -619,13 +619,13 @@
   SDOperand Ptr = LD->getBasePtr();
   MVT::ValueType VT = LD->getValueType(0);
   MVT::ValueType LoadedVT = LD->getLoadedVT();
-  if (MVT::isFloatingPoint(VT)) {
+  if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT)) {
     // Expand to a (misaligned) integer load of the same size,
     // then bitconvert to floating point.
     MVT::ValueType intVT;
-    if (LoadedVT==MVT::f64)
+    if (LoadedVT == MVT::f64)
       intVT = MVT::i64;
-    else if (LoadedVT==MVT::f32)
+    else if (LoadedVT == MVT::f32)
       intVT = MVT::i32;
     else
       assert(0 && "Unaligned load of unsupported floating point type");
@@ -641,11 +641,25 @@
     return DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other), 
                        Ops, 2);
   }
-  assert(MVT::isInteger(LoadedVT) && "Unaligned load of unsupported type.");
-  MVT::ValueType NewLoadedVT = LoadedVT - 1;
-  int NumBits = MVT::getSizeInBits(NewLoadedVT);
-  int Alignment = LD->getAlignment();
-  int IncrementSize = NumBits / 8;
+  assert((MVT::isInteger(LoadedVT) || MVT::isVector(LoadedVT)) &&
+         "Unaligned load of unsupported type.");
+
+  // Compute the new VT that is half the size of the old one.  We either have an
+  // integer MVT or we have a vector MVT.
+  unsigned NumBits = MVT::getSizeInBits(LoadedVT);
+  MVT::ValueType NewLoadedVT;
+  if (!MVT::isVector(LoadedVT)) {
+    NewLoadedVT = MVT::getIntegerType(NumBits/2);
+  } else {
+    // FIXME: This is not right for <1 x anything> it is also not right for
+    // non-power-of-two vectors.
+    NewLoadedVT = MVT::getVectorType(MVT::getVectorElementType(LoadedVT),
+                                     MVT::getVectorNumElements(LoadedVT)/2);
+  }
+  NumBits >>= 1;
+  
+  unsigned Alignment = LD->getAlignment();
+  unsigned IncrementSize = NumBits / 8;
   ISD::LoadExtType HiExtType = LD->getExtensionType();
 
   // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD.




From sabre at nondot.org  Mon Nov 19 15:43:22 2007
From: sabre at nondot.org (Chris Lattner)
Date: Mon, 19 Nov 2007 21:43:22 -0000
Subject: [llvm-commits] [llvm] r44244 -
 /llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll
Message-ID: <200711192143.lAJLhMx2007242@zion.cs.uiuc.edu>

Author: lattner
Date: Mon Nov 19 15:43:22 2007
New Revision: 44244

URL: http://llvm.org/viewvc/llvm-project?rev=44244&view=rev
Log:
Testcase for PR1811

Added:
    llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll

Added: llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll?rev=44244&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2007-11-19-VectorSplitting.ll Mon Nov 19 15:43:22 2007
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llc 
+; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g3
+; RUN: llvm-as < %s | llc -march=ppc32 -mcpu=g5
+; PR1811
+
+define void @execute_shader(<4 x float>* %OUT, <4 x float>* %IN, <4 x float>*
+%CONST) {
+entry:
+        %input2 = load <4 x float>* null, align 16               ; <<4 x float>>
+       	%shuffle7 = shufflevector <4 x float> %input2, <4 x float> < float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+00 >, <4 x i32> < i32 2, i32 2, i32 2, i32 2 >		; <<4 x float>> [#uses=1]
+
+        %mul1 = mul <4 x float> %shuffle7, zeroinitializer              ; <<4 x
+        %add2 = add <4 x float> %mul1, %input2          ; <<4 x float>>
+        store <4 x float> %add2, <4 x float>* null, align 16
+        ret void
+}




From criswell at uiuc.edu  Mon Nov 19 15:44:41 2007
From: criswell at uiuc.edu (John Criswell)
Date: Mon, 19 Nov 2007 21:44:41 -0000
Subject: [llvm-commits] [poolalloc] r44245 - in /poolalloc/branches/SVA/lib:
 DSA/Local.cpp DSA/Makefile PoolAllocate/Makefile
 PoolAllocate/TransformFunctionBody.cpp
Message-ID: <200711192144.lAJLifQa007318@zion.cs.uiuc.edu>

Author: criswell
Date: Mon Nov 19 15:44:41 2007
New Revision: 44245

URL: http://llvm.org/viewvc/llvm-project?rev=44245&view=rev
Log:
Recognize malloc() and free() as allocators and deallocators, even in
kernel mode.
Build object files for linking with the SAFECode tool.
Use the correct type for pools when running in kernel and non-kernel mode.

Modified:
    poolalloc/branches/SVA/lib/DSA/Local.cpp
    poolalloc/branches/SVA/lib/DSA/Makefile
    poolalloc/branches/SVA/lib/PoolAllocate/Makefile
    poolalloc/branches/SVA/lib/PoolAllocate/TransformFunctionBody.cpp

Modified: poolalloc/branches/SVA/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/Local.cpp?rev=44245&r1=44244&r2=44245&view=diff

==============================================================================
--- poolalloc/branches/SVA/lib/DSA/Local.cpp (original)
+++ poolalloc/branches/SVA/lib/DSA/Local.cpp Mon Nov 19 15:44:41 2007
@@ -1802,6 +1802,7 @@
   AllocList.push_back("__alloc_bootmem");
   AllocList.push_back(" __get_free_pages");
   AllocList.push_back("pseudo_alloc");
+  AllocList.push_back("malloc");
 
 #if 0
   FreeList.push_back("kfree");
@@ -1810,6 +1811,7 @@
   FreeList.push_back("free_pages");
   FreeList.push_back("kmem_cache_free");
   FreeList.push_back("pseudo_free");
+  FreeList.push_back("free");
 
   //figure out all system call numbers
   Function* lrs = M.getNamedFunction("llva_register_syscall");

Modified: poolalloc/branches/SVA/lib/DSA/Makefile
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/Makefile?rev=44245&r1=44244&r2=44245&view=diff

==============================================================================
--- poolalloc/branches/SVA/lib/DSA/Makefile (original)
+++ poolalloc/branches/SVA/lib/DSA/Makefile Mon Nov 19 15:44:41 2007
@@ -8,8 +8,8 @@
 ##===----------------------------------------------------------------------===##
 LEVEL = ../..
 SHARED_LIBRARY=1
-LOADABLE_MODULE = 1
-DONT_BUILD_RELINKED=1
+#LOADABLE_MODULE = 1
+#DONT_BUILD_RELINKED=1
 LIBRARYNAME = LLVMDataStructure
 
 include $(LEVEL)/Makefile.common

Modified: poolalloc/branches/SVA/lib/PoolAllocate/Makefile
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/PoolAllocate/Makefile?rev=44245&r1=44244&r2=44245&view=diff

==============================================================================
--- poolalloc/branches/SVA/lib/PoolAllocate/Makefile (original)
+++ poolalloc/branches/SVA/lib/PoolAllocate/Makefile Mon Nov 19 15:44:41 2007
@@ -7,8 +7,8 @@
 # Give the name of a library.  This will build a dynamic version.
 #
 SHARED_LIBRARY=1
-LOADABLE_MODULE = 1
-DONT_BUILD_RELINKED=1
+#LOADABLE_MODULE = 1
+#DONT_BUILD_RELINKED=1
 LIBRARYNAME=poolalloc
 
 #

Modified: poolalloc/branches/SVA/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/PoolAllocate/TransformFunctionBody.cpp?rev=44245&r1=44244&r2=44245&view=diff

==============================================================================
--- poolalloc/branches/SVA/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/branches/SVA/lib/PoolAllocate/TransformFunctionBody.cpp Mon Nov 19 15:44:41 2007
@@ -649,7 +649,11 @@
 	  //Dinakar we need pooldescriptors for allocas in the callee if it escapes
 	  BasicBlock::iterator InsertPt = TheCall->getParent()->getParent()->front().begin();
 	  Type *VoidPtrTy = PointerType::get(Type::SByteTy);
+#ifdef SAFECODE
+	  ArgVal =  new AllocaInst(ArrayType::get(VoidPtrTy, 50), 0, "PD", InsertPt);
+#else
 	  ArgVal =  new AllocaInst(ArrayType::get(VoidPtrTy, 16), 0, "PD", InsertPt);
+#endif
 	  Value *ElSize = ConstantInt::get(Type::UIntTy,0);
 	  Value *Align  = ConstantInt::get(Type::UIntTy,0);
 	  new CallInst(PAInfo.PoolInit, make_vector(ArgVal, ElSize, Align, 0),"", TheCall);




From nicholas at mxc.ca  Tue Nov 20 02:24:45 2007
From: nicholas at mxc.ca (Nick Lewycky)
Date: Tue, 20 Nov 2007 08:24:45 -0000
Subject: [llvm-commits] [llvm] r44248 - in /llvm/trunk:
 lib/Analysis/ScalarEvolution.cpp
 test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
Message-ID: <200711200824.lAK8Oj4f004729@zion.cs.uiuc.edu>

Author: nicholas
Date: Tue Nov 20 02:24:44 2007
New Revision: 44248

URL: http://llvm.org/viewvc/llvm-project?rev=44248&view=rev
Log:
Be more careful when transforming | to +. Patch from Wojciech Matyjewicz.

Added:
    llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44248&r1=44247&r2=44248&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 20 02:24:44 2007
@@ -1484,25 +1484,27 @@
     case Instruction::SDiv:
       return SE.getSDivExpr(getSCEV(I->getOperand(0)),
                             getSCEV(I->getOperand(1)));
-      break;
-
     case Instruction::Sub:
       return SE.getMinusSCEV(getSCEV(I->getOperand(0)),
                              getSCEV(I->getOperand(1)));
     case Instruction::Or:
       // If the RHS of the Or is a constant, we may have something like:
-      // X*4+1 which got turned into X*4|1.  Handle this as an add so loop
+      // X*4+1 which got turned into X*4|1.  Handle this as an Add so loop
       // optimizations will transparently handle this case.
+      //
+      // In order for this transformation to be safe, the LHS must be of the
+      // form X*(2^n) and the Or constant must be less than 2^n.
+
       if (ConstantInt *CI = dyn_cast(I->getOperand(1))) {
         SCEVHandle LHS = getSCEV(I->getOperand(0));
         APInt CommonFact(GetConstantFactor(LHS));
         assert(!CommonFact.isMinValue() &&
                "Common factor should at least be 1!");
-        if (CommonFact.ugt(CI->getValue())) {
-          // If the LHS is a multiple that is larger than the RHS, use +.
+        const APInt &CIVal = CI->getValue();
+        if (CommonFact.countTrailingZeros() >=
+            (CIVal.getBitWidth() - CIVal.countLeadingZeros()))
           return SE.getAddExpr(LHS,
                                getSCEV(I->getOperand(1)));
-        }
       }
       break;
     case Instruction::Xor:

Added: llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll?rev=44248&view=auto

==============================================================================
--- llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll (added)
+++ llvm/trunk/test/Analysis/ScalarEvolution/2007-11-18-OrInstruction.ll Tue Nov 20 02:24:44 2007
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | opt -analyze -scalar-evolution 2>&1 | grep -e '-->  %b'
+; PR1810
+
+define void @fun() {
+entry:
+        br label %header
+header:
+        %i = phi i32 [ 1, %entry ], [ %i.next, %body ]
+        %cond = icmp eq i32 %i, 10
+        br i1 %cond, label %exit, label %body
+body:
+        %a = mul i32 %i, 5
+        %b = or i32 %a, 1
+        %i.next = add i32 %i, 1
+        br label %header
+exit:        
+        ret void
+}




From nicholas at mxc.ca  Tue Nov 20 02:44:50 2007
From: nicholas at mxc.ca (Nick Lewycky)
Date: Tue, 20 Nov 2007 08:44:50 -0000
Subject: [llvm-commits] [llvm] r44249 -
	/llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Message-ID: <200711200844.lAK8io0Q012901@zion.cs.uiuc.edu>

Author: nicholas
Date: Tue Nov 20 02:44:50 2007
New Revision: 44249

URL: http://llvm.org/viewvc/llvm-project?rev=44249&view=rev
Log:
Small cleanup. Use APInt::getHighBitsSet method instead of shift left.
"setcc" -> "icmp op" in comments. No functionality change.

Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44249&r1=44248&r2=44249&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Tue Nov 20 02:44:50 2007
@@ -1207,7 +1207,7 @@
     SCEVHandle ComputeIterationCount(const Loop *L);
 
     /// ComputeLoadConstantCompareIterationCount - Given an exit condition of
-    /// 'setcc load X, cst', try to see if we can compute the trip count.
+    /// 'icmp op load X, cst', try to see if we can compute the trip count.
     SCEVHandle ComputeLoadConstantCompareIterationCount(LoadInst *LI,
                                                         Constant *RHS,
                                                         const Loop *L,
@@ -1418,13 +1418,12 @@
     if (!V.isMinValue())
       return V;
     else   // Zero is a multiple of everything.
-      return APInt(C->getBitWidth(), 1).shl(C->getBitWidth()-1);
+      return APInt::getHighBitsSet(C->getBitWidth(), 1);
   }
 
-  if (SCEVTruncateExpr *T = dyn_cast(S)) {
+  if (SCEVTruncateExpr *T = dyn_cast(S))
     return GetConstantFactor(T->getOperand()).trunc(
                                cast(T->getType())->getBitWidth());
-  }
   if (SCEVZeroExtendExpr *E = dyn_cast(S))
     return GetConstantFactor(E->getOperand()).zext(
                                cast(E->getType())->getBitWidth());
@@ -1787,7 +1786,7 @@
 }
 
 /// ComputeLoadConstantCompareIterationCount - Given an exit condition of
-/// 'setcc load X, cst', try to se if we can compute the trip count.
+/// 'icmp op load X, cst', try to se if we can compute the trip count.
 SCEVHandle ScalarEvolutionsImpl::
 ComputeLoadConstantCompareIterationCount(LoadInst *LI, Constant *RHS,
                                          const Loop *L, 




From baldrick at free.fr  Tue Nov 20 08:09:30 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 20 Nov 2007 14:09:30 -0000
Subject: [llvm-commits] [llvm] r44250 - in /llvm/trunk/lib:
 Bitcode/Reader/BitcodeReader.cpp VMCore/Function.cpp
Message-ID: <200711201409.lAKE9U7q027281@zion.cs.uiuc.edu>

Author: baldrick
Date: Tue Nov 20 08:09:29 2007
New Revision: 44250

URL: http://llvm.org/viewvc/llvm-project?rev=44250&view=rev
Log:
In order for parameter attribute uniquing to make
any sense it is important that ParamAttr::None gets
treated the same as not supplying an attribute at
all.  Rather than stripping ParamAttr::None out of
the list of attributes, assert if ParamAttr::None
is seen.  Fix up the bitcode reader which liked to
insert ParamAttr::None all over the place.  Patch
based on one by T?r?k Edwin.

Modified:
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/VMCore/Function.cpp

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=44250&r1=44249&r2=44250&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Nov 20 08:09:29 2007
@@ -232,17 +232,15 @@
       if (Record.size() & 1)
         return Error("Invalid ENTRY record");
 
-      ParamAttrsWithIndex PAWI;
       for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
-        PAWI.index = Record[i];
-        PAWI.attrs = Record[i+1];
-        Attrs.push_back(PAWI);
+        if (Record[i+1] != ParamAttr::None)
+          Attrs.push_back(ParamAttrsWithIndex::get(Record[i], Record[i+1]));
       }
-      ParamAttrs.push_back(ParamAttrsList::get(Attrs));
+      ParamAttrs.push_back(Attrs.empty() ? NULL : ParamAttrsList::get(Attrs));
       Attrs.clear();
       break;
     }
-    }    
+    }
   }
 }
 

Modified: llvm/trunk/lib/VMCore/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44250&r1=44249&r2=44250&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Function.cpp (original)
+++ llvm/trunk/lib/VMCore/Function.cpp Tue Nov 20 08:09:29 2007
@@ -129,8 +129,12 @@
 ParamAttrsList::get(const ParamAttrsVector &attrVec) {
   assert(!attrVec.empty() && "Illegal to create empty ParamAttrsList");
 #ifndef NDEBUG
-  for (unsigned i = 1, e = attrVec.size(); i < e; ++i)
-    assert(attrVec[i-1].index < attrVec[i].index && "Misordered ParamAttrsList!");
+  for (unsigned i = 0, e = attrVec.size(); i < e; ++i) {
+    assert(attrVec[i].attrs != ParamAttr::None
+           && "Pointless parameter attribute!");
+    assert((!i || attrVec[i-1].index < attrVec[i].index)
+           && "Misordered ParamAttrsList!");
+  }
 #endif
   ParamAttrsList key(attrVec);
   FoldingSetNodeID ID;




From baldrick at free.fr  Tue Nov 20 08:09:44 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 20 Nov 2007 14:09:44 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44251 -
	/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Message-ID: <200711201409.lAKE9iYM027300@zion.cs.uiuc.edu>

Author: baldrick
Date: Tue Nov 20 08:09:44 2007
New Revision: 44251

URL: http://llvm.org/viewvc/llvm-project?rev=44251&view=rev
Log:
Don't push ParamAttr::None.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44251&r1=44250&r2=44251&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Tue Nov 20 08:09:44 2007
@@ -1051,8 +1051,9 @@
         RAttributes |= ParamAttr::SExt;
     }
   }
-  
-  Attrs.push_back(ParamAttrsWithIndex::get(0, RAttributes));
+
+  if (RAttributes != ParamAttr::None)
+    Attrs.push_back(ParamAttrsWithIndex::get(0, RAttributes));
   
   // If this is a struct-return function, the dest loc is passed in as a
   // pointer.  Mark that pointer as structret.




From baldrick at free.fr  Tue Nov 20 08:11:23 2007
From: baldrick at free.fr (Duncan Sands)
Date: Tue, 20 Nov 2007 14:11:23 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44252 -
	/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Message-ID: <200711201411.lAKEBNnH027389@zion.cs.uiuc.edu>

Author: baldrick
Date: Tue Nov 20 08:11:21 2007
New Revision: 44252

URL: http://llvm.org/viewvc/llvm-project?rev=44252&view=rev
Log:
Don't push ParamAttr::None.

Modified:
    llvm-gcc-4.0/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=44252&r1=44251&r2=44252&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Tue Nov 20 08:11:21 2007
@@ -1016,8 +1016,9 @@
         RAttributes |= ParamAttr::SExt;
     }
   }
-  
-  Attrs.push_back(ParamAttrsWithIndex::get(0, RAttributes));
+
+  if (RAttributes != ParamAttr::None)
+    Attrs.push_back(ParamAttrsWithIndex::get(0, RAttributes));
   
   // If this is a struct-return function, the dest loc is passed in as a
   // pointer.  Mark that pointer as structret.




From sabre at nondot.org  Tue Nov 20 13:37:38 2007
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 20 Nov 2007 19:37:38 -0000
Subject: [llvm-commits] [test-suite] r44256 -
 /test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c
Message-ID: <200711201937.lAKJbcUT010100@zion.cs.uiuc.edu>

Author: lattner
Date: Tue Nov 20 13:37:38 2007
New Revision: 44256

URL: http://llvm.org/viewvc/llvm-project?rev=44256&view=rev
Log:
get this working on darwin/ppc.

Modified:
    test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c

Modified: test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c?rev=44256&r1=44255&r2=44256&view=diff

==============================================================================
--- test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c (original)
+++ test-suite/trunk/SingleSource/Benchmarks/Misc/oourafft.c Tue Nov 20 13:37:38 2007
@@ -1,8 +1,10 @@
 #include 
-#include 
 #include 
 #include 
 #include 
+#ifndef __APPLE__ // memalign
+#include 
+#endif
 
 /* random number generator, 0 <= RND < 1 */
 #define RND(p) ((*(p) = (*(p) * 7141 + 54773) % 259200) * (1.0 / 259200.0))
@@ -35,14 +37,25 @@
   t_overhead = t_end - t_start;
 
   /* Prepare aux data */
+#ifndef __APPLE__  /* Darwin always 16-byte aligns malloc data */
   ip = memalign(16, sqrt(N)*sizeof(int));
   w  = memalign(16, 2*N*5/4*sizeof(double));
+#else
+  ip = malloc(sqrt(N)*sizeof(int));
+  w  = malloc(2*N*5/4*sizeof(double));
+#endif
   makewt(N >> 1, ip, w);
   
   /* Allocate buffers */
+#ifndef __APPLE__  /* Darwin always 16-byte aligns malloc data */
   ref = memalign(16, 2*N*sizeof(double));
   cmp = memalign(16, 2*N*sizeof(double));
   src = memalign(16, 2*N*sizeof(double));
+#else
+  ref = malloc(2*N*sizeof(double));
+  cmp = malloc(2*N*sizeof(double));
+  src = malloc(2*N*sizeof(double));
+#endif
   
   /* Perform sanity check of FFT */
   putdata(0, 2*N - 1, ref);




From sabre at nondot.org  Tue Nov 20 16:25:16 2007
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 20 Nov 2007 22:25:16 -0000
Subject: [llvm-commits] [llvm] r44257 - in /llvm/trunk/utils/TableGen:
	Record.cpp Record.h
Message-ID: <200711202225.lAKMPGuX018665@zion.cs.uiuc.edu>

Author: lattner
Date: Tue Nov 20 16:25:16 2007
New Revision: 44257

URL: http://llvm.org/viewvc/llvm-project?rev=44257&view=rev
Log:
Add the ability to convert a tblgen type to a string.

Modified:
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h

Modified: llvm/trunk/utils/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=44257&r1=44256&r2=44257&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Tue Nov 20 16:25:16 2007
@@ -14,6 +14,7 @@
 #include "Record.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Streams.h"
+#include "llvm/ADT/StringExtras.h"
 #include 
 
 using namespace llvm;
@@ -46,6 +47,10 @@
   return 0;
 }
 
+std::string BitsRecTy::getAsString() const {
+  return "bits<" + utostr(Size) + ">";
+}
+
 Init *BitsRecTy::convertValue(UnsetInit *UI) {
   BitsInit *Ret = new BitsInit(Size);
 
@@ -146,6 +151,10 @@
   return 0;
 }
 
+std::string ListRecTy::getAsString() const {
+  return "list<" + Ty->getAsString() + ">";
+}
+
 void ListRecTy::print(std::ostream &OS) const {
   OS << "list<" << *Ty << ">";
 }
@@ -196,6 +205,9 @@
   return 0;
 }
 
+std::string RecordRecTy::getAsString() const {
+  return Rec->getName();
+}
 
 void RecordRecTy::print(std::ostream &OS) const {
   OS << Rec->getName();

Modified: llvm/trunk/utils/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=44257&r1=44256&r2=44257&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Tue Nov 20 16:25:16 2007
@@ -62,6 +62,7 @@
 struct RecTy {
   virtual ~RecTy() {}
 
+  virtual std::string getAsString() const = 0;
   virtual void print(std::ostream &OS) const = 0;
   void dump() const;
 
@@ -127,6 +128,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
+  std::string getAsString() const { return "bit"; }
   void print(std::ostream &OS) const { OS << "bit"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -169,7 +171,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
-
+  std::string getAsString() const;
   void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -208,7 +210,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
-
+  std::string getAsString() const { return "int"; }
   void print(std::ostream &OS) const { OS << "int"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -245,6 +247,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
+  std::string getAsString() const { return "string"; }
   void print(std::ostream &OS) const { OS << "string"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -288,6 +291,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
+  std::string getAsString() const;
   void print(std::ostream &OS) const;
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -325,7 +329,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
-
+  std::string getAsString() const { return "code"; }
   void print(std::ostream &OS) const { OS << "code"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -360,6 +364,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
+  std::string getAsString() const { return "dag"; }
   void print(std::ostream &OS) const { OS << "dag"; }
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {
@@ -402,6 +407,7 @@
   virtual Init *convertValue(   VarInit *VI) { return RecTy::convertValue(VI);}
   virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);}
 
+  std::string getAsString() const;
   void print(std::ostream &OS) const;
 
   bool typeIsConvertibleTo(const RecTy *RHS) const {




From dalej at apple.com  Tue Nov 20 17:24:42 2007
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 20 Nov 2007 23:24:42 -0000
Subject: [llvm-commits] [llvm] r44258 - in /llvm/trunk/lib:
 CodeGen/DwarfWriter.cpp Target/PowerPC/PPCAsmPrinter.cpp
 Target/PowerPC/PPCTargetAsmInfo.cpp Target/TargetAsmInfo.cpp
 Target/X86/X86ATTAsmPrinter.cpp Target/X86/X86AsmPrinter.cpp
 Target/X86/X86TargetAsmInfo.cpp
Message-ID: <200711202324.lAKNOg9e021649@zion.cs.uiuc.edu>

Author: johannes
Date: Tue Nov 20 17:24:42 2007
New Revision: 44258

URL: http://llvm.org/viewvc/llvm-project?rev=44258&view=rev
Log:
Fix .eh table linkage issues on Darwin.  Some EH support
for Darwin PPC, but it's not fully working yet.


Modified:
    llvm/trunk/lib/CodeGen/DwarfWriter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
    llvm/trunk/lib/Target/TargetAsmInfo.cpp
    llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
    llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
    llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp

Modified: llvm/trunk/lib/CodeGen/DwarfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DwarfWriter.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/DwarfWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/DwarfWriter.cpp Tue Nov 20 17:24:42 2007
@@ -2764,12 +2764,15 @@
     bool hasCalls;
     bool hasLandingPads;
     std::vector Moves;
+    Function::LinkageTypes linkage;
 
     FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P,
                         bool hC, bool hL,
-                        const std::vector &M):
+                        const std::vector &M,
+                        Function::LinkageTypes l):
       FnName(FN), Number(Num), PersonalityIndex(P),
-      hasCalls(hC), hasLandingPads(hL), Moves(M) { }
+      hasCalls(hC), hasLandingPads(hL), Moves(M),
+      linkage(l) { }
   };
 
   std::vector EHFrames;
@@ -2867,15 +2870,25 @@
     Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
 
     // Externally visible entry into the functions eh frame info.
-    if (const char *GlobalDirective = TAI->getGlobalDirective())
-      O << GlobalDirective << EHFrameInfo.FnName << "\n";
-    
+    // If the corresponding function is static, this should not be
+    // externally visible.
+    if (EHFrameInfo.linkage != Function::InternalLinkage) {
+      if (const char *GlobalEHDirective = TAI->getGlobalEHDirective())
+        O << GlobalEHDirective << EHFrameInfo.FnName << "\n";
+    }
+
     // If there are no calls then you can't unwind.
     if (!EHFrameInfo.hasCalls) { 
       O << EHFrameInfo.FnName << " = 0\n";
     } else {
       O << EHFrameInfo.FnName << ":\n";
-      
+
+      // If corresponding function is weak definition, this should be too.
+      if ((EHFrameInfo.linkage == Function::WeakLinkage || 
+           EHFrameInfo.linkage == Function::LinkOnceLinkage) &&
+          TAI->getWeakDefDirective())
+        O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n";
+
       // EH frame header.
       EmitDifference("eh_frame_end", EHFrameInfo.Number,
                      "eh_frame_begin", EHFrameInfo.Number, true);
@@ -3362,7 +3375,8 @@
                                     MMI->getPersonalityIndex(),
                                     MF->getFrameInfo()->hasCalls(),
                                     !MMI->getLandingPads().empty(),
-                                    MMI->getFrameMoves()));
+                                    MMI->getFrameMoves(),
+                                    MF->getFunction()->getLinkage()));
   }
 };
 

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Tue Nov 20 17:24:42 2007
@@ -322,10 +322,11 @@
   struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter {
   
     DwarfWriter DW;
+    MachineModuleInfo *MMI;
 
     DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
                      const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T) {
+      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
     }
 
     virtual const char *getPassName() const {
@@ -774,11 +775,13 @@
 /// method to print assembly for each instruction.
 ///
 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
-  DW.SetModuleInfo(&getAnalysis());
+  // We need this for Personality functions.
+  MMI = &getAnalysis();
+  DW.SetModuleInfo(MMI);
 
   SetupMachineFunction(MF);
   O << "\n\n";
-  
+
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
@@ -1054,6 +1057,15 @@
 
   O << "\n";
 
+  if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI) {
+    // Add the (possibly multiple) personalities to the set of global values.
+    const std::vector& Personalities = MMI->getPersonalities();
+
+    for (std::vector::const_iterator I = Personalities.begin(),
+           E = Personalities.end(); I != E; ++I)
+      if (*I) GVStubs.insert("_" + (*I)->getName());
+  }
+
   // Output stubs for external and common global variables.
   if (!GVStubs.empty()) {
     SwitchToDataSection(".non_lazy_symbol_pointer");

Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCTargetAsmInfo.cpp Tue Nov 20 17:24:42 2007
@@ -43,7 +43,6 @@
   PrivateGlobalPrefix = "L";
   ConstantPoolSection = "\t.const\t";
   JumpTableDataSection = ".const";
-  GlobalDirective = "\t.globl\t";
   CStringSection = "\t.cstring";
   FourByteConstantSection = "\t.literal4\n";
   EightByteConstantSection = "\t.literal8\n";
@@ -56,6 +55,7 @@
     StaticDtorsSection = ".mod_term_func";
   }
   UsedDirective = "\t.no_dead_strip\t";
+  WeakDefDirective = "\t.weak_definition\t";
   WeakRefDirective = "\t.weak_reference\t";
   HiddenDirective = "\t.private_extern\t";
   SupportsExceptionHandling = false;
@@ -66,6 +66,7 @@
   DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
   DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
   DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
+  GlobalEHDirective = "\t.globl\t";
   DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
   DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
   DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";

Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Tue Nov 20 17:24:42 2007
@@ -75,6 +75,7 @@
   HasDotTypeDotSizeDirective(true),
   UsedDirective(0),
   WeakRefDirective(0),
+  WeakDefDirective(0),
   HiddenDirective("\t.hidden\t"),
   ProtectedDirective("\t.protected\t"),
   AbsoluteDebugSectionOffsets(false),
@@ -89,6 +90,7 @@
   DwarfInfoSection(".debug_info"),
   DwarfLineSection(".debug_line"),
   DwarfFrameSection(".debug_frame"),
+  GlobalEHDirective(0),
   DwarfPubNamesSection(".debug_pubnames"),
   DwarfPubTypesSection(".debug_pubtypes"),
   DwarfStrSection(".debug_str"),

Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Tue Nov 20 17:24:42 2007
@@ -124,7 +124,7 @@
       // FIXME: This should be parameterized somewhere.
       EmitAlignment(4, F, 0, true, 0x90);
       O << "\t.globl\t" << CurrentFnName << "\n";
-      O << "\t.weak_definition\t" << CurrentFnName << "\n";
+      O << TAI->getWeakDefDirective() << CurrentFnName << "\n";
     } else if (Subtarget->isTargetCygMing()) {
       EmitAlignment(4, F);     // FIXME: This should be parameterized somewhere.
       O << "\t.globl\t" << CurrentFnName << "\n";

Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Tue Nov 20 17:24:42 2007
@@ -214,7 +214,7 @@
     case GlobalValue::WeakLinkage:
       if (Subtarget->isTargetDarwin()) {
         O << "\t.globl\t" << name << "\n"
-          << "\t.weak_definition " << name << "\n";
+          << TAI->getWeakDefDirective() << name << "\n";
         SwitchToDataSection(".section __DATA,__const_coal,coalesced", I);
       } else if (Subtarget->isTargetCygMing()) {
         std::string SectionName(".section\t.data$linkonce." +

Modified: llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp?rev=44258&r1=44257&r2=44258&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetAsmInfo.cpp Tue Nov 20 17:24:42 2007
@@ -76,6 +76,7 @@
     SetDirective = "\t.set";
     PCSymbol = ".";
     UsedDirective = "\t.no_dead_strip\t";
+    WeakDefDirective = "\t.weak_definition\t";
     WeakRefDirective = "\t.weak_reference\t";
     HiddenDirective = "\t.private_extern\t";
     
@@ -92,6 +93,7 @@
     DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
     DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
     DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
+    GlobalEHDirective = "\t.globl\t";
     DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
     DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
     DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";




From dalej at apple.com  Tue Nov 20 17:25:17 2007
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 20 Nov 2007 23:25:17 -0000
Subject: [llvm-commits] [llvm] r44259 -
	/llvm/trunk/include/llvm/Target/TargetAsmInfo.h
Message-ID: <200711202325.lAKNPI98021731@zion.cs.uiuc.edu>

Author: johannes
Date: Tue Nov 20 17:25:17 2007
New Revision: 44259

URL: http://llvm.org/viewvc/llvm-project?rev=44259&view=rev
Log:
File missing from previous patch.


Modified:
    llvm/trunk/include/llvm/Target/TargetAsmInfo.h

Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=44259&r1=44258&r2=44259&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Tue Nov 20 17:25:17 2007
@@ -260,6 +260,10 @@
     /// global as being a weak undefined symbol.
     const char *WeakRefDirective;         // Defaults to null.
     
+    /// WeakDefDirective - This directive, if non-null, is used to declare a
+    /// global as being a weak defined symbol.
+    const char *WeakDefDirective;         // Defaults to null.
+    
     /// HiddenDirective - This directive, if non-null, is used to declare a
     /// global or function as having hidden visibility.
     const char *HiddenDirective;          // Defaults to "\t.hidden\t".
@@ -300,6 +304,11 @@
     ///
     bool DwarfRequiresFrameSection; // Defaults to true.
 
+    /// GlobalEHDirective - This is the directive used to make exception frame
+    /// tables globally visible.
+    ///
+    const char *GlobalEHDirective;          // Defaults to NULL.
+
     /// DwarfSectionOffsetDirective - Special section offset directive.
     const char* DwarfSectionOffsetDirective; // Defaults to NULL
     
@@ -543,6 +552,9 @@
     const char *getWeakRefDirective() const {
       return WeakRefDirective;
     }
+    const char *getWeakDefDirective() const {
+      return WeakDefDirective;
+    }
     const char *getHiddenDirective() const {
       return HiddenDirective;
     }
@@ -570,6 +582,9 @@
     bool doesDwarfRequireFrameSection() const {
       return DwarfRequiresFrameSection;
     }
+    const char *getGlobalEHDirective() const {
+      return GlobalEHDirective;
+    }
     const char *getDwarfSectionOffsetDirective() const {
       return DwarfSectionOffsetDirective;
     }    




From dalej at apple.com  Tue Nov 20 17:45:11 2007
From: dalej at apple.com (Dale Johannesen)
Date: Tue, 20 Nov 2007 15:45:11 -0800
Subject: [llvm-commits] [llvm] r44258 - in /llvm/trunk/lib:
	CodeGen/DwarfWriter.cpp Target/PowerPC/PPCAsmPrinter.cpp
	Target/PowerPC/PPCTargetAsmInfo.cpp Target/TargetAsmInfo.cpp
	Target/X86/X86ATTAsmPrinter.cpp Target/X86/X86AsmPrinter.cpp
	Target/X86/X86TargetAsmInfo.cpp
In-Reply-To: <200711202324.lAKNOg9e021649@zion.cs.uiuc.edu>
References: <200711202324.lAKNOg9e021649@zion.cs.uiuc.edu>
Message-ID: <75261DA7-C91F-4FAF-BC1F-B187E1933475@apple.com>

On Nov 20, 2007, at 3:24 PM, Dale Johannesen wrote:

> Fix .eh table linkage issues on Darwin.

To explain what this is doing a bit:
On Darwin .eh tables are not magically associated with the  
corresponding function; they are separately relocatable entities in  
the linker, with no particular attachment to the function, and need  
relocation similar to the function.

When the EH stuff was done originally, part of this problem was  
handled by adding

     /// GlobalDirective - This is the directive used to declare a  
global entity.
     ///
     const char *GlobalDirective;          // Defaults to NULL.

in TargetAsmInfo.h.  However, that's not really what it meant; the  
only place this was used was in DwarfWriter,
where it was used to emit linkage for .eh tables, if it existed; and  
the only target that defined it was PPC Darwin.  Defining it for  
Linux would likely lead to linkage problems.  In the meantime, the  
Mips target has innocently defined and used GlobalDirective as  
documented, for emission of variables and functions and things like  
that, so now we have Confusion.

I have cloned the original GlobalDirective to GlobalEHDirective in an  
attempt to make it clearer what's going on.  GlobalDirective remains,  
with the documented meaning, and is now used only by the Mips target.

This changes the behavior of the Mips target regarding .eh tables for  
global and static functions; they used to get .global directives and  
now they do not.  I am not familiar with this target; my guess is  
this is the right thing to do (follows Linux).  If it is not,  
defining GlobalEHDirective for that target is probably right (I think  
it likely that emitting .globl for tables associated with static  
functions was always a bug).



From cfr at adobe.com  Tue Nov 20 18:37:57 2007
From: cfr at adobe.com (Chuck Rose III)
Date: Wed, 21 Nov 2007 00:37:57 -0000
Subject: [llvm-commits] [llvm] r44260 - in /llvm/trunk: lib/System/Win32/
 utils/TableGen/ win32/ win32/Analysis/ win32/Archive/ win32/AsmParser/
 win32/Bitcode/ win32/CBackend/ win32/CodeGen/ win32/Configure/
 win32/ExecutionEngine/ win32/Fibonacci/ win32/Linker/ win32/Support/
 win32/System/ win32/TableGen/ win32/Target/ win32/Transforms/ win32/VMCore/
 win32/bugpoint/ win32/llc/ win32/lli/ win32/llvm-ar/ win32/llvm-as/
 win32/llvm-bcanalyzer/ win32/llvm-dis/ win32/llvm-ld/ win32/llvm-link/
 win32/llvm-nm/ win32/llvm-prof/ win32/llv...
Message-ID: <200711210037.lAL0bwjH025531@zion.cs.uiuc.edu>

Author: cfr
Date: Tue Nov 20 18:37:56 2007
New Revision: 44260

URL: http://llvm.org/viewvc/llvm-project?rev=44260&view=rev
Log:
This change does a couple of things.  First it gets the Visual Studio builds working. 
I added the lexing files to the VStudio projects and removed the .l files from the 
VStudio projects.  There was a problem with use of strtoll in TGLexer.cpp and Chris
suggested switching to strtol, so that's included here.

Additionally, this checkin adds minimal x64 builds to the VStudio builds.  Build issues
related to x64 in the windows specific files for DynamicLibrary.inc and Singals.inc
are worked around, but not ultimately solved.  Binaries used to be stored in

..\win32\{Debug|Release}

but are now kept in

..\win32\bin\{win32|x64}\{Debug|Release}

intermediate files will continue to be stored in the individual project directories under 
win32.  

Some names will likely change in the future to reflect that the vstudio projects
are no longer 32-bit only, but I wanted to get things up and running today so kept away
from bigger restructuring.


Modified:
    llvm/trunk/lib/System/Win32/DynamicLibrary.inc
    llvm/trunk/lib/System/Win32/Signals.inc
    llvm/trunk/utils/TableGen/TGLexer.cpp
    llvm/trunk/win32/Analysis/Analysis.vcproj
    llvm/trunk/win32/Archive/Archive.vcproj
    llvm/trunk/win32/AsmParser/AsmParser.vcproj
    llvm/trunk/win32/Bitcode/Bitcode.vcproj
    llvm/trunk/win32/CBackend/CBackend.vcproj
    llvm/trunk/win32/CodeGen/CodeGen.vcproj
    llvm/trunk/win32/Configure/Configure.vcproj
    llvm/trunk/win32/ExecutionEngine/ExecutionEngine.vcproj
    llvm/trunk/win32/Fibonacci/Fibonacci.vcproj
    llvm/trunk/win32/Linker/Linker.vcproj
    llvm/trunk/win32/Support/Support.vcproj
    llvm/trunk/win32/System/System.vcproj
    llvm/trunk/win32/TableGen/TableGen.vcproj
    llvm/trunk/win32/Target/Target.vcproj
    llvm/trunk/win32/Transforms/Transforms.vcproj
    llvm/trunk/win32/VMCore/VMCore.vcproj
    llvm/trunk/win32/bugpoint/bugpoint.vcproj
    llvm/trunk/win32/dobison.cmd
    llvm/trunk/win32/llc/llc.vcproj
    llvm/trunk/win32/lli/lli.vcproj
    llvm/trunk/win32/llvm-ar/llvm-ar.vcproj
    llvm/trunk/win32/llvm-as/llvm-as.vcproj
    llvm/trunk/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj
    llvm/trunk/win32/llvm-dis/llvm-dis.vcproj
    llvm/trunk/win32/llvm-ld/llvm-ld.vcproj
    llvm/trunk/win32/llvm-link/llvm-link.vcproj
    llvm/trunk/win32/llvm-nm/llvm-nm.vcproj
    llvm/trunk/win32/llvm-prof/llvm-prof.vcproj
    llvm/trunk/win32/llvm-ranlib/llvm-ranlib.vcproj
    llvm/trunk/win32/llvm.sln
    llvm/trunk/win32/opt/opt.vcproj
    llvm/trunk/win32/x86/x86.vcproj

Modified: llvm/trunk/lib/System/Win32/DynamicLibrary.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Win32/DynamicLibrary.inc?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/lib/System/Win32/DynamicLibrary.inc (original)
+++ llvm/trunk/lib/System/Win32/DynamicLibrary.inc Tue Nov 20 18:37:56 2007
@@ -37,9 +37,15 @@
 
 static std::vector OpenedHandles;
 
+#ifdef _WIN64
+  typedef DWORD64 ModuleBaseType;
+#else
+  typedef ULONG ModuleBaseType;
+#endif
+
 extern "C" {
   static BOOL CALLBACK ELM_Callback(PSTR  ModuleName,
-                                    ULONG ModuleBase,
+                                    ModuleBaseType ModuleBase,
                                     ULONG ModuleSize,
                                     PVOID UserContext)
   {

Modified: llvm/trunk/lib/System/Win32/Signals.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/System/Win32/Signals.inc?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/lib/System/Win32/Signals.inc (original)
+++ llvm/trunk/lib/System/Win32/Signals.inc Tue Nov 20 18:37:56 2007
@@ -177,7 +177,11 @@
 static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
   try {
     Cleanup();
-
+    
+#ifdef _WIN64
+  // TODO: provide a x64 friendly version of the following
+#else
+    
     // Initialize the STACKFRAME structure.
     STACKFRAME StackFrame;
     memset(&StackFrame, 0, sizeof(StackFrame));
@@ -251,6 +255,9 @@
 
       fputc('\n', stderr);
     }
+
+#endif
+
   } catch (...) {
       assert(!"Crashed in LLVMUnhandledExceptionFilter");
   }

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Tue Nov 20 18:37:56 2007
@@ -341,7 +341,8 @@
       if (CurPtr == NumStart)
         return ReturnError(CurPtr-2, "Invalid hexadecimal number");
 
-      Filelval.IntVal = strtoll(NumStart, 0, 16);
+      Filelval.IntVal = strtol(NumStart, 0, 16);
+
       return INTVAL;
     } else if (CurPtr[0] == 'b') {
       ++CurPtr;
@@ -352,7 +353,8 @@
       // Requires at least one binary digit.
       if (CurPtr == NumStart)
         return ReturnError(CurPtr-2, "Invalid binary number");
-      Filelval.IntVal = strtoll(NumStart, 0, 2);
+
+      Filelval.IntVal = strtol(NumStart, 0, 2);
       return INTVAL;
     }
   }
@@ -365,7 +367,8 @@
   
   while (isdigit(CurPtr[0]))
     ++CurPtr;
-  Filelval.IntVal = strtoll(NumStart, 0, 10);
+
+  Filelval.IntVal = strtol(NumStart, 0, 10);
   return INTVAL;
 }
 

Modified: llvm/trunk/win32/Analysis/Analysis.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Analysis/Analysis.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/Analysis/Analysis.vcproj (original)
+++ llvm/trunk/win32/Analysis/Analysis.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 			
+			
+			
 				
 					
 				
 				
 					
 				
-			
-			
 				
 					
 				
 				
 					
 				
 			
@@ -221,6 +364,10 @@
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
 			
+			
+			
 			
@@ -233,10 +380,6 @@
 			Name="Generated Files"
 			>
 			
-			
-			
 			

Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Bitcode/Bitcode.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/Bitcode/Bitcode.vcproj (original)
+++ llvm/trunk/win32/Bitcode/Bitcode.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
@@ -93,6 +96,85 @@
 				Name="VCPostBuildEventTool"
 			/>
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
@@ -116,6 +198,17 @@
 						Outputs=""$(ProjectDir)..\llvm\Config\config.h""
 					/>
 				
+				
+					
+				
 			
 			
 				
+				
+					
+				
 			
 			
 				
+				
+					
+				
 			
 			
 				
+				
+					
+				
 			
 			
 				
+				
+					
+				
 			
 		
 		
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 				
+				
+					
+				
+				
+					
+				
 			
 			
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/Linker/Linker.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Linker/Linker.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/Linker/Linker.vcproj (original)
+++ llvm/trunk/win32/Linker/Linker.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
@@ -236,6 +379,14 @@
 						Name="VCCLCompilerTool"
 					/>
 				
+				
+					
+				
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 	
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
@@ -211,16 +388,16 @@
 				>
 			
 			
 				
 					
 				
 				
 					
 				
-			
-			
 				
 					
 				
 				
 					
 				
 			
@@ -286,6 +459,10 @@
 				RelativePath="..\..\utils\TableGen\TableGenBackend.cpp"
 				>
 			
+			
+			
 		
 		
 			
+			
+			
 		
 		
 			
 				
 					
 				
 				
 					
 				
-			
-			
 				
 					
 				
 				
 					
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+		
 	
 	
 	
 	
 		
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 					
+					
+						
+					
+					
+						
+					
 				
 				
+		
 	
 	
 	
 	
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	
@@ -223,18 +366,40 @@
 					
 				
 				
+					
+				
+				
 					
+				
+				
+					

Modified: llvm/trunk/win32/bugpoint/bugpoint.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/bugpoint/bugpoint.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/bugpoint/bugpoint.vcproj (original)
+++ llvm/trunk/win32/bugpoint/bugpoint.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/dobison.cmd
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/dobison.cmd?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/dobison.cmd (original)
+++ llvm/trunk/win32/dobison.cmd Tue Nov 20 18:37:56 2007
@@ -4,6 +4,7 @@
 rem   mode - either debug or release
 rem   target - generated parser file name without extension
 rem   source - input to bison
+rem   headercopydir - directory to receive a copy of the header
 
 if "%2"=="debug" (set flags=-tvdo) else (set flags=-vdo)
 
@@ -12,7 +13,11 @@
 if errorlevel 1 goto nobison
 
 rem Run bison.
+echo bison -p%1 %flags%%3.cpp %4
+echo move %3.hpp %3.h
 bison -p%1 %flags%%3.cpp %4 && move %3.hpp %3.h
+echo copy %3.h %5
+copy %3.h %5
 exit
 
 :nobison

Modified: llvm/trunk/win32/llc/llc.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llc/llc.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llc/llc.vcproj (original)
+++ llvm/trunk/win32/llc/llc.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/lli/lli.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/lli/lli.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/lli/lli.vcproj (original)
+++ llvm/trunk/win32/lli/lli.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-ar/llvm-ar.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-ar/llvm-ar.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-ar/llvm-ar.vcproj (original)
+++ llvm/trunk/win32/llvm-ar/llvm-ar.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-as/llvm-as.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-as/llvm-as.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-as/llvm-as.vcproj (original)
+++ llvm/trunk/win32/llvm-as/llvm-as.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj (original)
+++ llvm/trunk/win32/llvm-bcanalyzer/llvm-bcanalyzer.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-dis/llvm-dis.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-dis/llvm-dis.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-dis/llvm-dis.vcproj (original)
+++ llvm/trunk/win32/llvm-dis/llvm-dis.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-ld/llvm-ld.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-ld/llvm-ld.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-ld/llvm-ld.vcproj (original)
+++ llvm/trunk/win32/llvm-ld/llvm-ld.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-link/llvm-link.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-link/llvm-link.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-link/llvm-link.vcproj (original)
+++ llvm/trunk/win32/llvm-link/llvm-link.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-nm/llvm-nm.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-nm/llvm-nm.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-nm/llvm-nm.vcproj (original)
+++ llvm/trunk/win32/llvm-nm/llvm-nm.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-prof/llvm-prof.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-prof/llvm-prof.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-prof/llvm-prof.vcproj (original)
+++ llvm/trunk/win32/llvm-prof/llvm-prof.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm-ranlib/llvm-ranlib.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm-ranlib/llvm-ranlib.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm-ranlib/llvm-ranlib.vcproj (original)
+++ llvm/trunk/win32/llvm-ranlib/llvm-ranlib.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/llvm.sln
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/llvm.sln?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/llvm.sln (original)
+++ llvm/trunk/win32/llvm.sln Tue Nov 20 18:37:56 2007
@@ -16,8 +16,9 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Fibonacci", "Fibonacci\Fibonacci.vcproj", "{48FB551D-E37E-42EC-BC97-FF7219774867}"
@@ -26,14 +27,14 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
-		{76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A}
-		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C}
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExecutionEngine", "ExecutionEngine\ExecutionEngine.vcproj", "{76295AE8-A083-460E-9F80-6F2B8923264A}"
@@ -42,8 +43,8 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VMCore", "VMCore\VMCore.vcproj", "{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}"
@@ -52,8 +53,8 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Target", "Target\Target.vcproj", "{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}"
@@ -71,9 +72,9 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "System", "System\System.vcproj", "{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}"
@@ -91,8 +92,8 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x86", "x86\x86.vcproj", "{144EEBF6-8C9B-4473-B715-2C821666AF6C}"
@@ -101,10 +102,10 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
-		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
 		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
+		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Transforms", "Transforms\Transforms.vcproj", "{C59374C1-9FC0-4147-B836-327DFDC52D99}"
@@ -113,9 +114,9 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{339C2249-26B6-4172-B484-85653029AF57} = {339C2249-26B6-4172-B484-85653029AF57}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Configure", "Configure\Configure.vcproj", "{19514E48-456C-4B9D-8637-F2285476461E}"
@@ -130,15 +131,15 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
-		{76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A}
-		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C}
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{76295AE8-A083-460E-9F80-6F2B8923264A} = {76295AE8-A083-460E-9F80-6F2B8923264A}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llc", "llc\llc.vcproj", "{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}"
@@ -147,15 +148,15 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
-		{057777CD-DED5-46DF-BF9A-6B76DE212549} = {057777CD-DED5-46DF-BF9A-6B76DE212549}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
-		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C} = {144EEBF6-8C9B-4473-B715-2C821666AF6C}
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{057777CD-DED5-46DF-BF9A-6B76DE212549} = {057777CD-DED5-46DF-BF9A-6B76DE212549}
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-dis", "llvm-dis\llvm-dis.vcproj", "{B13476BC-30AB-4EA0-BC1E-212C0A459405}"
@@ -164,11 +165,11 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-as", "llvm-as\llvm-as.vcproj", "{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}"
@@ -177,12 +178,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
-		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982}
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AsmParser", "AsmParser\AsmParser.vcproj", "{3DC216F5-1DDD-478A-84F8-C124E5C31982}"
@@ -200,12 +201,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ranlib", "llvm-ranlib\llvm-ranlib.vcproj", "{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}"
@@ -214,12 +215,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-link", "llvm-link\llvm-link.vcproj", "{5E249789-49E1-4600-B12B-8AD2BB6439B2}"
@@ -228,12 +229,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Linker", "Linker\Linker.vcproj", "{342CF48F-760A-4040-A9A1-7D75AA2471CE}"
@@ -242,9 +243,9 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CBackend", "CBackend\CBackend.vcproj", "{057777CD-DED5-46DF-BF9A-6B76DE212549}"
@@ -253,8 +254,8 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opt", "opt\opt.vcproj", "{006D8B41-C3C7-4448-85E1-AF8907E591E5}"
@@ -263,14 +264,14 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-bcanalyzer", "llvm-bcanalyzer\llvm-bcanalyzer.vcproj", "{E0B1E329-BE3E-456D-B372-5F397BE42C84}"
@@ -279,10 +280,10 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ld", "llvm-ld\llvm-ld.vcproj", "{64D8AA46-88DB-41F4-B837-053AE02406B8}"
@@ -291,16 +292,16 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-nm", "llvm-nm\llvm-nm.vcproj", "{5FF862CE-80A0-4B48-A80B-68AE325A0432}"
@@ -309,12 +310,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-prof", "llvm-prof\llvm-prof.vcproj", "{ACBE81D9-64B1-4133-823A-807A4E60B454}"
@@ -323,12 +324,12 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bugpoint", "bugpoint\bugpoint.vcproj", "{57249192-8E29-4D85-8B7A-FEFF1760B1DA}"
@@ -337,16 +338,16 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
-		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
-		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
-		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
-		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
-		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
-		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
-		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982} = {3DC216F5-1DDD-478A-84F8-C124E5C31982}
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{C59374C1-9FC0-4147-B836-327DFDC52D99} = {C59374C1-9FC0-4147-B836-327DFDC52D99}
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE} = {342CF48F-760A-4040-A9A1-7D75AA2471CE}
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
+		{28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508}
+		{0622E827-8464-489D-8B1C-B0B496F35C08} = {0622E827-8464-489D-8B1C-B0B496F35C08}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Bitcode", "Bitcode\Bitcode.vcproj", "{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}"
@@ -364,202 +365,355 @@
 		Release.AspNetCompiler.Debug = "False"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}
+		{19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E}
 	EndProjectSection
 EndProject
 Global
-	GlobalSection(DPCodeReviewSolutionGUID) = preSolution
-		DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
-	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Configure|Win32 = Configure|Win32
+		Configure|x64 = Configure|x64
 		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
 		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Configure|Win32.ActiveCfg = Release|Win32
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Configure|Win32.Build.0 = Release|Win32
+		{28AA9146-3482-4F41-9CC6-407B1D258508}.Configure|x64.ActiveCfg = Release|Win32
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Debug|Win32.ActiveCfg = Debug|Win32
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Debug|Win32.Build.0 = Debug|Win32
+		{28AA9146-3482-4F41-9CC6-407B1D258508}.Debug|x64.ActiveCfg = Debug|x64
+		{28AA9146-3482-4F41-9CC6-407B1D258508}.Debug|x64.Build.0 = Debug|x64
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Release|Win32.ActiveCfg = Release|Win32
 		{28AA9146-3482-4F41-9CC6-407B1D258508}.Release|Win32.Build.0 = Release|Win32
+		{28AA9146-3482-4F41-9CC6-407B1D258508}.Release|x64.ActiveCfg = Release|x64
+		{28AA9146-3482-4F41-9CC6-407B1D258508}.Release|x64.Build.0 = Release|x64
 		{339C2249-26B6-4172-B484-85653029AF57}.Configure|Win32.ActiveCfg = Release|Win32
 		{339C2249-26B6-4172-B484-85653029AF57}.Configure|Win32.Build.0 = Release|Win32
+		{339C2249-26B6-4172-B484-85653029AF57}.Configure|x64.ActiveCfg = Release|Win32
 		{339C2249-26B6-4172-B484-85653029AF57}.Debug|Win32.ActiveCfg = Debug|Win32
 		{339C2249-26B6-4172-B484-85653029AF57}.Debug|Win32.Build.0 = Debug|Win32
+		{339C2249-26B6-4172-B484-85653029AF57}.Debug|x64.ActiveCfg = Debug|x64
+		{339C2249-26B6-4172-B484-85653029AF57}.Debug|x64.Build.0 = Debug|x64
 		{339C2249-26B6-4172-B484-85653029AF57}.Release|Win32.ActiveCfg = Release|Win32
 		{339C2249-26B6-4172-B484-85653029AF57}.Release|Win32.Build.0 = Release|Win32
+		{339C2249-26B6-4172-B484-85653029AF57}.Release|x64.ActiveCfg = Release|x64
+		{339C2249-26B6-4172-B484-85653029AF57}.Release|x64.Build.0 = Release|x64
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Configure|Win32.ActiveCfg = Release|Win32
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Configure|Win32.Build.0 = Release|Win32
+		{48FB551D-E37E-42EC-BC97-FF7219774867}.Configure|x64.ActiveCfg = Release|Win32
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Debug|Win32.ActiveCfg = Debug|Win32
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Debug|Win32.Build.0 = Debug|Win32
+		{48FB551D-E37E-42EC-BC97-FF7219774867}.Debug|x64.ActiveCfg = Debug|x64
+		{48FB551D-E37E-42EC-BC97-FF7219774867}.Debug|x64.Build.0 = Debug|x64
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Release|Win32.ActiveCfg = Release|Win32
 		{48FB551D-E37E-42EC-BC97-FF7219774867}.Release|Win32.Build.0 = Release|Win32
+		{48FB551D-E37E-42EC-BC97-FF7219774867}.Release|x64.ActiveCfg = Release|x64
+		{48FB551D-E37E-42EC-BC97-FF7219774867}.Release|x64.Build.0 = Release|x64
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Configure|Win32.ActiveCfg = Release|Win32
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Configure|Win32.Build.0 = Release|Win32
+		{76295AE8-A083-460E-9F80-6F2B8923264A}.Configure|x64.ActiveCfg = Release|Win32
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Debug|Win32.ActiveCfg = Debug|Win32
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Debug|Win32.Build.0 = Debug|Win32
+		{76295AE8-A083-460E-9F80-6F2B8923264A}.Debug|x64.ActiveCfg = Debug|x64
+		{76295AE8-A083-460E-9F80-6F2B8923264A}.Debug|x64.Build.0 = Debug|x64
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Release|Win32.ActiveCfg = Release|Win32
 		{76295AE8-A083-460E-9F80-6F2B8923264A}.Release|Win32.Build.0 = Release|Win32
+		{76295AE8-A083-460E-9F80-6F2B8923264A}.Release|x64.ActiveCfg = Release|x64
+		{76295AE8-A083-460E-9F80-6F2B8923264A}.Release|x64.Build.0 = Release|x64
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Configure|Win32.ActiveCfg = Release|Win32
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Configure|Win32.Build.0 = Release|Win32
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Configure|x64.ActiveCfg = Release|Win32
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Debug|Win32.ActiveCfg = Debug|Win32
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Debug|Win32.Build.0 = Debug|Win32
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Debug|x64.ActiveCfg = Debug|x64
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Debug|x64.Build.0 = Debug|x64
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|Win32.ActiveCfg = Release|Win32
 		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|Win32.Build.0 = Release|Win32
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|x64.ActiveCfg = Release|x64
+		{45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|x64.Build.0 = Release|x64
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Configure|Win32.ActiveCfg = Release|Win32
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Configure|Win32.Build.0 = Release|Win32
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Configure|x64.ActiveCfg = Release|Win32
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Debug|Win32.ActiveCfg = Debug|Win32
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Debug|Win32.Build.0 = Debug|Win32
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Debug|x64.ActiveCfg = Debug|x64
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Debug|x64.Build.0 = Debug|x64
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|Win32.ActiveCfg = Release|Win32
 		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|Win32.Build.0 = Release|Win32
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|x64.ActiveCfg = Release|x64
+		{059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|x64.Build.0 = Release|x64
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Configure|Win32.ActiveCfg = Release|Win32
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Configure|Win32.Build.0 = Release|Win32
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Configure|x64.ActiveCfg = Release|Win32
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Debug|Win32.ActiveCfg = Debug|Win32
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Debug|Win32.Build.0 = Debug|Win32
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Debug|x64.ActiveCfg = Debug|x64
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Debug|x64.Build.0 = Debug|x64
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|Win32.ActiveCfg = Release|Win32
 		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|Win32.Build.0 = Release|Win32
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|x64.ActiveCfg = Release|x64
+		{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|x64.Build.0 = Release|x64
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Configure|Win32.ActiveCfg = Release|Win32
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Configure|Win32.Build.0 = Release|Win32
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Configure|x64.ActiveCfg = Release|Win32
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Debug|Win32.Build.0 = Debug|Win32
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Debug|x64.ActiveCfg = Debug|x64
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Debug|x64.Build.0 = Debug|x64
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|Win32.ActiveCfg = Release|Win32
 		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|Win32.Build.0 = Release|Win32
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|x64.ActiveCfg = Release|x64
+		{0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|x64.Build.0 = Release|x64
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Configure|Win32.ActiveCfg = Release|Win32
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Configure|Win32.Build.0 = Release|Win32
+		{0622E827-8464-489D-8B1C-B0B496F35C08}.Configure|x64.ActiveCfg = Release|Win32
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Debug|Win32.Build.0 = Debug|Win32
+		{0622E827-8464-489D-8B1C-B0B496F35C08}.Debug|x64.ActiveCfg = Debug|x64
+		{0622E827-8464-489D-8B1C-B0B496F35C08}.Debug|x64.Build.0 = Debug|x64
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Release|Win32.ActiveCfg = Release|Win32
 		{0622E827-8464-489D-8B1C-B0B496F35C08}.Release|Win32.Build.0 = Release|Win32
+		{0622E827-8464-489D-8B1C-B0B496F35C08}.Release|x64.ActiveCfg = Release|x64
+		{0622E827-8464-489D-8B1C-B0B496F35C08}.Release|x64.Build.0 = Release|x64
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Configure|Win32.ActiveCfg = Release|Win32
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Configure|Win32.Build.0 = Release|Win32
+		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Configure|x64.ActiveCfg = Release|Win32
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Debug|Win32.Build.0 = Debug|Win32
+		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Debug|x64.ActiveCfg = Debug|x64
+		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Debug|x64.Build.0 = Debug|x64
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|Win32.ActiveCfg = Release|Win32
 		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|Win32.Build.0 = Release|Win32
+		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|x64.ActiveCfg = Release|x64
+		{144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|x64.Build.0 = Release|x64
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Configure|Win32.ActiveCfg = Release|Win32
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Configure|Win32.Build.0 = Release|Win32
+		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Configure|x64.ActiveCfg = Release|Win32
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Debug|Win32.Build.0 = Debug|Win32
+		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Debug|x64.ActiveCfg = Debug|x64
+		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Debug|x64.Build.0 = Debug|x64
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|Win32.ActiveCfg = Release|Win32
 		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|Win32.Build.0 = Release|Win32
+		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|x64.ActiveCfg = Release|x64
+		{C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|x64.Build.0 = Release|x64
 		{19514E48-456C-4B9D-8637-F2285476461E}.Configure|Win32.ActiveCfg = Configure|Win32
 		{19514E48-456C-4B9D-8637-F2285476461E}.Configure|Win32.Build.0 = Configure|Win32
+		{19514E48-456C-4B9D-8637-F2285476461E}.Configure|x64.ActiveCfg = Configure|Win32
 		{19514E48-456C-4B9D-8637-F2285476461E}.Debug|Win32.ActiveCfg = Configure|Win32
 		{19514E48-456C-4B9D-8637-F2285476461E}.Debug|Win32.Build.0 = Configure|Win32
+		{19514E48-456C-4B9D-8637-F2285476461E}.Debug|x64.ActiveCfg = Configure|x64
+		{19514E48-456C-4B9D-8637-F2285476461E}.Debug|x64.Build.0 = Configure|x64
 		{19514E48-456C-4B9D-8637-F2285476461E}.Release|Win32.ActiveCfg = Configure|Win32
 		{19514E48-456C-4B9D-8637-F2285476461E}.Release|Win32.Build.0 = Configure|Win32
+		{19514E48-456C-4B9D-8637-F2285476461E}.Release|x64.ActiveCfg = Configure|x64
+		{19514E48-456C-4B9D-8637-F2285476461E}.Release|x64.Build.0 = Configure|x64
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Configure|Win32.ActiveCfg = Release|Win32
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Configure|Win32.Build.0 = Release|Win32
+		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Configure|x64.ActiveCfg = Release|Win32
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Debug|Win32.Build.0 = Debug|Win32
+		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Debug|x64.ActiveCfg = Debug|x64
+		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Debug|x64.Build.0 = Debug|x64
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|Win32.ActiveCfg = Release|Win32
 		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|Win32.Build.0 = Release|Win32
+		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|x64.ActiveCfg = Release|x64
+		{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|x64.Build.0 = Release|x64
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Configure|Win32.ActiveCfg = Release|Win32
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Configure|Win32.Build.0 = Release|Win32
+		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Configure|x64.ActiveCfg = Release|Win32
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Debug|Win32.Build.0 = Debug|Win32
+		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Debug|x64.ActiveCfg = Debug|x64
+		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Debug|x64.Build.0 = Debug|x64
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|Win32.ActiveCfg = Release|Win32
 		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|Win32.Build.0 = Release|Win32
+		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|x64.ActiveCfg = Release|x64
+		{ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|x64.Build.0 = Release|x64
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Configure|Win32.ActiveCfg = Release|Win32
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Configure|Win32.Build.0 = Release|Win32
+		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Configure|x64.ActiveCfg = Release|Win32
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Debug|Win32.Build.0 = Debug|Win32
+		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Debug|x64.ActiveCfg = Debug|x64
+		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Debug|x64.Build.0 = Debug|x64
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|Win32.ActiveCfg = Release|Win32
 		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|Win32.Build.0 = Release|Win32
+		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|x64.ActiveCfg = Release|x64
+		{B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|x64.Build.0 = Release|x64
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Configure|Win32.ActiveCfg = Release|Win32
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Configure|Win32.Build.0 = Release|Win32
+		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Configure|x64.ActiveCfg = Release|Win32
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Debug|Win32.Build.0 = Debug|Win32
+		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Debug|x64.ActiveCfg = Debug|x64
+		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Debug|x64.Build.0 = Debug|x64
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|Win32.ActiveCfg = Release|Win32
 		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|Win32.Build.0 = Release|Win32
+		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|x64.ActiveCfg = Release|x64
+		{4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|x64.Build.0 = Release|x64
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Configure|Win32.ActiveCfg = Release|Win32
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Configure|Win32.Build.0 = Release|Win32
+		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Configure|x64.ActiveCfg = Release|Win32
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Debug|Win32.ActiveCfg = Debug|Win32
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Debug|Win32.Build.0 = Debug|Win32
+		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Debug|x64.ActiveCfg = Debug|x64
+		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Debug|x64.Build.0 = Debug|x64
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|Win32.ActiveCfg = Release|Win32
 		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|Win32.Build.0 = Release|Win32
+		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|x64.ActiveCfg = Release|x64
+		{3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|x64.Build.0 = Release|x64
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Configure|Win32.ActiveCfg = Release|Win32
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Configure|Win32.Build.0 = Release|Win32
+		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Configure|x64.ActiveCfg = Release|Win32
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Debug|Win32.Build.0 = Debug|Win32
+		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Debug|x64.ActiveCfg = Debug|x64
+		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Debug|x64.Build.0 = Debug|x64
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|Win32.ActiveCfg = Release|Win32
 		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|Win32.Build.0 = Release|Win32
+		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|x64.ActiveCfg = Release|x64
+		{0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|x64.Build.0 = Release|x64
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Configure|Win32.ActiveCfg = Release|Win32
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Configure|Win32.Build.0 = Release|Win32
+		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Configure|x64.ActiveCfg = Release|Win32
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Debug|Win32.ActiveCfg = Debug|Win32
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Debug|Win32.Build.0 = Debug|Win32
+		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Debug|x64.ActiveCfg = Debug|x64
+		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Debug|x64.Build.0 = Debug|x64
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|Win32.ActiveCfg = Release|Win32
 		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|Win32.Build.0 = Release|Win32
+		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|x64.ActiveCfg = Release|x64
+		{BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|x64.Build.0 = Release|x64
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Configure|Win32.ActiveCfg = Release|Win32
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Configure|Win32.Build.0 = Release|Win32
+		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Configure|x64.ActiveCfg = Release|Win32
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Debug|Win32.Build.0 = Debug|Win32
+		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Debug|x64.ActiveCfg = Debug|x64
+		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Debug|x64.Build.0 = Debug|x64
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|Win32.ActiveCfg = Release|Win32
 		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|Win32.Build.0 = Release|Win32
+		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|x64.ActiveCfg = Release|x64
+		{5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|x64.Build.0 = Release|x64
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Configure|Win32.ActiveCfg = Release|Win32
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Configure|Win32.Build.0 = Release|Win32
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Configure|x64.ActiveCfg = Release|Win32
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Debug|Win32.ActiveCfg = Debug|Win32
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Debug|Win32.Build.0 = Debug|Win32
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Debug|x64.ActiveCfg = Debug|x64
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Debug|x64.Build.0 = Debug|x64
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|Win32.ActiveCfg = Release|Win32
 		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|Win32.Build.0 = Release|Win32
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|x64.ActiveCfg = Release|x64
+		{342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|x64.Build.0 = Release|x64
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Configure|Win32.ActiveCfg = Release|Win32
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Configure|Win32.Build.0 = Release|Win32
+		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Configure|x64.ActiveCfg = Release|Win32
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Debug|Win32.ActiveCfg = Debug|Win32
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Debug|Win32.Build.0 = Debug|Win32
+		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Debug|x64.ActiveCfg = Debug|x64
+		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Debug|x64.Build.0 = Debug|x64
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|Win32.ActiveCfg = Release|Win32
 		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|Win32.Build.0 = Release|Win32
+		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|x64.ActiveCfg = Release|x64
+		{057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|x64.Build.0 = Release|x64
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Configure|Win32.ActiveCfg = Release|Win32
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Configure|Win32.Build.0 = Release|Win32
+		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Configure|x64.ActiveCfg = Release|Win32
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug|Win32.ActiveCfg = Debug|Win32
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug|Win32.Build.0 = Debug|Win32
+		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug|x64.ActiveCfg = Debug|x64
+		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug|x64.Build.0 = Debug|x64
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|Win32.ActiveCfg = Release|Win32
 		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|Win32.Build.0 = Release|Win32
+		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|x64.ActiveCfg = Release|x64
+		{006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|x64.Build.0 = Release|x64
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Configure|Win32.ActiveCfg = Release|Win32
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Configure|Win32.Build.0 = Release|Win32
+		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Configure|x64.ActiveCfg = Release|Win32
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug|Win32.Build.0 = Debug|Win32
+		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug|x64.ActiveCfg = Debug|x64
+		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug|x64.Build.0 = Debug|x64
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|Win32.ActiveCfg = Release|Win32
 		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|Win32.Build.0 = Release|Win32
+		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|x64.ActiveCfg = Release|x64
+		{E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|x64.Build.0 = Release|x64
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Configure|Win32.ActiveCfg = Release|Win32
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Configure|Win32.Build.0 = Release|Win32
+		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Configure|x64.ActiveCfg = Release|Win32
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug|Win32.Build.0 = Debug|Win32
+		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug|x64.ActiveCfg = Debug|x64
+		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug|x64.Build.0 = Debug|x64
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|Win32.ActiveCfg = Release|Win32
 		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|Win32.Build.0 = Release|Win32
+		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|x64.ActiveCfg = Release|x64
+		{64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|x64.Build.0 = Release|x64
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Configure|Win32.ActiveCfg = Release|Win32
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Configure|Win32.Build.0 = Release|Win32
+		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Configure|x64.ActiveCfg = Release|Win32
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug|Win32.Build.0 = Debug|Win32
+		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug|x64.ActiveCfg = Debug|x64
+		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug|x64.Build.0 = Debug|x64
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|Win32.ActiveCfg = Release|Win32
 		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|Win32.Build.0 = Release|Win32
+		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|x64.ActiveCfg = Release|x64
+		{5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|x64.Build.0 = Release|x64
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Configure|Win32.ActiveCfg = Release|Win32
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Configure|Win32.Build.0 = Release|Win32
+		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Configure|x64.ActiveCfg = Release|Win32
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug|Win32.ActiveCfg = Debug|Win32
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug|Win32.Build.0 = Debug|Win32
+		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug|x64.ActiveCfg = Debug|x64
+		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug|x64.Build.0 = Debug|x64
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|Win32.ActiveCfg = Release|Win32
 		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|Win32.Build.0 = Release|Win32
+		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|x64.ActiveCfg = Release|x64
+		{ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|x64.Build.0 = Release|x64
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Configure|Win32.ActiveCfg = Release|Win32
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Configure|Win32.Build.0 = Release|Win32
+		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Configure|x64.ActiveCfg = Release|Win32
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug|Win32.Build.0 = Debug|Win32
+		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug|x64.ActiveCfg = Debug|x64
+		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug|x64.Build.0 = Debug|x64
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|Win32.ActiveCfg = Release|Win32
 		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|Win32.Build.0 = Release|Win32
+		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|x64.ActiveCfg = Release|x64
+		{57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|x64.Build.0 = Release|x64
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Configure|Win32.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Configure|Win32.Build.0 = Release|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Configure|x64.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Debug|Win32.Build.0 = Debug|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Debug|x64.ActiveCfg = Debug|x64
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Debug|x64.Build.0 = Debug|x64
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Release|Win32.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Release|Win32.Build.0 = Release|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Release|x64.ActiveCfg = Release|x64
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Release|x64.Build.0 = Release|x64
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Configure|Win32.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Configure|Win32.Build.0 = Release|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Configure|x64.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Debug|Win32.Build.0 = Debug|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Debug|x64.ActiveCfg = Debug|x64
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Debug|x64.Build.0 = Debug|x64
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Release|Win32.ActiveCfg = Release|Win32
 		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Release|Win32.Build.0 = Release|Win32
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Release|x64.ActiveCfg = Release|x64
+		{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 	EndGlobalSection
+	GlobalSection(DPCodeReviewSolutionGUID) = preSolution
+		DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}
+	EndGlobalSection
 EndGlobal

Modified: llvm/trunk/win32/opt/opt.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/opt/opt.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/opt/opt.vcproj (original)
+++ llvm/trunk/win32/opt/opt.vcproj Tue Nov 20 18:37:56 2007
@@ -10,14 +10,17 @@
 		
+		
 	
 	
 	
 	
 		
 		
 		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
 	
 	
 	

Modified: llvm/trunk/win32/x86/x86.vcproj
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/x86/x86.vcproj?rev=44260&r1=44259&r2=44260&view=diff

==============================================================================
--- llvm/trunk/win32/x86/x86.vcproj (original)
+++ llvm/trunk/win32/x86/x86.vcproj Tue Nov 20 18:37:56 2007
@@ -11,14 +11,88 @@
 		
+		
 	
 	
 	
 	
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
 		
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+			
+		
+		
 			
 			
+				
+				
+					
@@ -182,7 +336,18 @@
 					
+				
+				
+					




From dalej at apple.com  Tue Nov 20 18:45:00 2007
From: dalej at apple.com (Dale Johannesen)
Date: Wed, 21 Nov 2007 00:45:00 -0000
Subject: [llvm-commits] [llvm] r44261 -
	/llvm/trunk/lib/Target/TargetAsmInfo.cpp
Message-ID: <200711210045.lAL0j0tm025904@zion.cs.uiuc.edu>

Author: johannes
Date: Tue Nov 20 18:45:00 2007
New Revision: 44261

URL: http://llvm.org/viewvc/llvm-project?rev=44261&view=rev
Log:
Fix compiler warning.


Modified:
    llvm/trunk/lib/Target/TargetAsmInfo.cpp

Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=44261&r1=44260&r2=44261&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Tue Nov 20 18:45:00 2007
@@ -85,12 +85,12 @@
   SupportsDebugInformation(false),
   SupportsExceptionHandling(false),
   DwarfRequiresFrameSection(true),
+  GlobalEHDirective(0),
   DwarfSectionOffsetDirective(0),
   DwarfAbbrevSection(".debug_abbrev"),
   DwarfInfoSection(".debug_info"),
   DwarfLineSection(".debug_line"),
   DwarfFrameSection(".debug_frame"),
-  GlobalEHDirective(0),
   DwarfPubNamesSection(".debug_pubnames"),
   DwarfPubTypesSection(".debug_pubtypes"),
   DwarfStrSection(".debug_str"),




From nicholas at mxc.ca  Tue Nov 20 23:21:55 2007
From: nicholas at mxc.ca (Nick Lewycky)
Date: Wed, 21 Nov 2007 05:21:55 -0000
Subject: [llvm-commits] [llvm] r44262 -
	/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
Message-ID: <200711210521.lAL5LtXd005870@zion.cs.uiuc.edu>

Author: nicholas
Date: Tue Nov 20 23:21:54 2007
New Revision: 44262

URL: http://llvm.org/viewvc/llvm-project?rev=44262&view=rev
Log:
typo

Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=44262&r1=44261&r2=44262&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Tue Nov 20 23:21:54 2007
@@ -151,7 +151,7 @@
   BranchInst *BI = dyn_cast(OrigHeader->getTerminator());
   if (!BI)
     return false;
-  assert (BI->isConditional() && "Branch Instruction is not condiitional");
+  assert (BI->isConditional() && "Branch Instruction is not conditional");
 
   // Updating PHInodes in loops with multiple exits adds complexity. 
   // Keep it simple, and restrict loop rotation to loops with one exit only.




From baldrick at free.fr  Wed Nov 21 10:43:20 2007
From: baldrick at free.fr (Duncan Sands)
Date: Wed, 21 Nov 2007 16:43:20 -0000
Subject: [llvm-commits] [llvm] r44263 - in /llvm/trunk:
 lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
 test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll
Message-ID: <200711211643.lALGhL2v009695@zion.cs.uiuc.edu>

Author: baldrick
Date: Wed Nov 21 10:43:19 2007
New Revision: 44263

URL: http://llvm.org/viewvc/llvm-project?rev=44263&view=rev
Log:
Fix a bug in which node A is replaced by node B, but later
node A gets back into the DAG again because it was hiding in
one of the node maps: make sure that node replacement happens
in those maps too.

Added:
    llvm/trunk/test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44263&r1=44262&r2=44263&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Wed Nov 21 10:43:19 2007
@@ -92,7 +92,11 @@
   /// ExpandedNodes - For nodes that need to be expanded this map indicates
   /// which operands are the expanded version of the input.
   DenseMap > ExpandedNodes;
-  
+
+  /// ReplacedNodes - For nodes that have been replaced with another,
+  /// indicates the replacement node to use.
+  DenseMap ReplacedNodes;
+
   /// Worklist - This defines a worklist of nodes to process.  In order to be
   /// pushed onto this worklist, all operands of a node must have already been
   /// processed.
@@ -112,12 +116,15 @@
   void MarkNewNodes(SDNode *N);
   
   void ReplaceLegalValueWith(SDOperand From, SDOperand To);
-  
+
+  void RemapNode(SDOperand &N);
+
   SDOperand GetPromotedOp(SDOperand Op) {
-    Op = PromotedNodes[Op];
-    assert(Op.Val && "Operand wasn't promoted?");
-    return Op;
-  }    
+    SDOperand &PromotedOp = PromotedNodes[Op];
+    RemapNode(PromotedOp);
+    assert(PromotedOp.Val && "Operand wasn't promoted?");
+    return PromotedOp;
+  }
   void SetPromotedOp(SDOperand Op, SDOperand Result);
 
   /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final
@@ -397,7 +404,11 @@
   // Anything that used the old node should now use the new one.  Note that this
   // can potentially cause recursive merging.
   DAG.ReplaceAllUsesOfValueWith(From, To);
-  
+
+  // The old node may still be present in ExpandedNodes or PromotedNodes.
+  // Inform them about the replacement.
+  ReplacedNodes[From] = To;
+
   // Since we just made an unstructured update to the DAG, which could wreak
   // general havoc on anything that once used N and now uses Res, walk all users
   // of the result, updating their flags.
@@ -414,6 +425,16 @@
   }
 }
 
+/// RemapNode - If the specified value was already legalized to another value,
+/// replace it by that value.
+void DAGTypeLegalizer::RemapNode(SDOperand &N) {
+  DenseMap::iterator I = ReplacedNodes.find(N);
+  if (I != ReplacedNodes.end()) {
+    RemapNode(I->second);
+    N = I->second;
+  }
+}
+
 void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
   if (Result.Val->getNodeId() == NewNode) 
     MarkNewNodes(Result.Val);
@@ -426,6 +447,8 @@
 void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo, 
                                      SDOperand &Hi) {
   std::pair &Entry = ExpandedNodes[Op];
+  RemapNode(Entry.first);
+  RemapNode(Entry.second);
   assert(Entry.first.Val && "Operand isn't expanded");
   Lo = Entry.first;
   Hi = Entry.second;

Added: llvm/trunk/test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll?rev=44263&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll (added)
+++ llvm/trunk/test/CodeGen/Generic/2007-11-21-UndeadIllegalNode.ll Wed Nov 21 10:43:19 2007
@@ -0,0 +1,161 @@
+; RUN: llvm-as < %s | llc -o -
+; XFAIL: *
+; Un-XFAIL this once LegalizeDAGTypes is turned on.
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32"
+target triple = "i686-pc-linux-gnu"
+	%struct.RETURN = type { i32, i32 }
+	%struct.ada__finalization__controlled = type { %struct.system__finalization_root__root_controlled }
+	%struct.ada__streams__root_stream_type = type { %struct.ada__tags__dispatch_table* }
+	%struct.ada__strings__unbounded__string_access = type { i8*, %struct.RETURN* }
+	%struct.ada__strings__unbounded__unbounded_string = type { %struct.ada__finalization__controlled, %struct.ada__strings__unbounded__string_access, i32 }
+	%struct.ada__tags__dispatch_table = type { [1 x i32] }
+	%struct.exception = type { i8, i8, i32, i8*, i8*, i32, i8* }
+	%struct.system__finalization_root__root_controlled = type { %struct.ada__streams__root_stream_type, %struct.system__finalization_root__root_controlled*, %struct.system__finalization_root__root_controlled* }
+	%struct.system__standard_library__exception_data = type { i8, i8, i32, i32, %struct.system__standard_library__exception_data*, i32, void ()* }
+ at C.495.7639 = internal constant %struct.RETURN { i32 1, i32 16 }		; <%struct.RETURN*> [#uses=1]
+ at ada__strings__index_error = external global %struct.exception		; <%struct.exception*> [#uses=1]
+ at .str5 = internal constant [16 x i8] c"a-strunb.adb:690"		; <[16 x i8]*> [#uses=1]
+
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32)
+
+declare void @ada__strings__unbounded__realloc_for_chunk(%struct.ada__strings__unbounded__unbounded_string*, i32)
+
+declare void @__gnat_raise_exception(%struct.system__standard_library__exception_data*, i64)
+
+define void @ada__strings__unbounded__insert__2(%struct.ada__strings__unbounded__unbounded_string* %source, i32 %before, i64 %new_item.0.0) {
+entry:
+	%tmp24636 = lshr i64 %new_item.0.0, 32		;  [#uses=1]
+	%tmp24637 = trunc i64 %tmp24636 to i32		;  [#uses=1]
+	%tmp24638 = inttoptr i32 %tmp24637 to %struct.RETURN*		; <%struct.RETURN*> [#uses=2]
+	%tmp25 = getelementptr %struct.RETURN* %tmp24638, i32 0, i32 0		;  [#uses=1]
+	%tmp26 = load i32* %tmp25, align 4		;  [#uses=1]
+	%tmp29 = getelementptr %struct.RETURN* %tmp24638, i32 0, i32 1		;  [#uses=1]
+	%tmp30 = load i32* %tmp29, align 4		;  [#uses=1]
+	%tmp63 = getelementptr %struct.ada__strings__unbounded__unbounded_string* %source, i32 0, i32 1, i32 1		; <%struct.RETURN**> [#uses=5]
+	%tmp64 = load %struct.RETURN** %tmp63, align 4		; <%struct.RETURN*> [#uses=1]
+	%tmp65 = getelementptr %struct.RETURN* %tmp64, i32 0, i32 0		;  [#uses=1]
+	%tmp66 = load i32* %tmp65, align 4		;  [#uses=1]
+	%tmp67 = icmp sgt i32 %tmp66, %before		;  [#uses=1]
+	br i1 %tmp67, label %bb77, label %bb
+
+bb:		; preds = %entry
+	%tmp71 = getelementptr %struct.ada__strings__unbounded__unbounded_string* %source, i32 0, i32 2		;  [#uses=4]
+	%tmp72 = load i32* %tmp71, align 4		;  [#uses=1]
+	%tmp73 = add i32 %tmp72, 1		;  [#uses=1]
+	%tmp74 = icmp slt i32 %tmp73, %before		;  [#uses=1]
+	br i1 %tmp74, label %bb77, label %bb84
+
+bb77:		; preds = %bb, %entry
+	tail call void @__gnat_raise_exception( %struct.system__standard_library__exception_data* bitcast (%struct.exception* @ada__strings__index_error to %struct.system__standard_library__exception_data*), i64 or (i64 zext (i32 ptrtoint ([16 x i8]* @.str5 to i32) to i64), i64 shl (i64 zext (i32 ptrtoint (%struct.RETURN* @C.495.7639 to i32) to i64), i64 32)) )
+	unreachable
+
+bb84:		; preds = %bb
+	%tmp93 = sub i32 %tmp30, %tmp26		;  [#uses=2]
+	%tmp9394 = sext i32 %tmp93 to i36		;  [#uses=1]
+	%tmp95 = shl i36 %tmp9394, 3		;  [#uses=1]
+	%tmp96 = add i36 %tmp95, 8		;  [#uses=2]
+	%tmp97 = icmp sgt i36 %tmp96, -1		;  [#uses=1]
+	%tmp100 = select i1 %tmp97, i36 %tmp96, i36 0		;  [#uses=2]
+	%tmp101 = icmp slt i36 %tmp100, 17179869177		;  [#uses=1]
+	%tmp100.cast = trunc i36 %tmp100 to i32		;  [#uses=1]
+	%min102 = select i1 %tmp101, i32 %tmp100.cast, i32 -8		;  [#uses=1]
+	tail call void @ada__strings__unbounded__realloc_for_chunk( %struct.ada__strings__unbounded__unbounded_string* %source, i32 %min102 )
+	%tmp148 = load i32* %tmp71, align 4		;  [#uses=4]
+	%tmp152 = add i32 %tmp93, 1		;  [#uses=2]
+	%tmp153 = icmp sgt i32 %tmp152, -1		;  [#uses=1]
+	%max154 = select i1 %tmp153, i32 %tmp152, i32 0		;  [#uses=5]
+	%tmp155 = add i32 %tmp148, %max154		;  [#uses=5]
+	%tmp315 = getelementptr %struct.ada__strings__unbounded__unbounded_string* %source, i32 0, i32 1, i32 0		;  [#uses=4]
+	%tmp328 = load %struct.RETURN** %tmp63, align 4		; <%struct.RETURN*> [#uses=1]
+	%tmp329 = getelementptr %struct.RETURN* %tmp328, i32 0, i32 0		;  [#uses=1]
+	%tmp330 = load i32* %tmp329, align 4		;  [#uses=4]
+	%tmp324 = add i32 %max154, %before		;  [#uses=3]
+	%tmp331 = sub i32 %tmp324, %tmp330		;  [#uses=1]
+	%tmp349 = sub i32 %before, %tmp330		;  [#uses=1]
+	%tmp356 = icmp sgt i32 %tmp331, %tmp349		;  [#uses=1]
+	%tmp431 = icmp sgt i32 %tmp324, %tmp155		;  [#uses=2]
+	br i1 %tmp356, label %bb420, label %bb359
+
+bb359:		; preds = %bb84
+	br i1 %tmp431, label %bb481, label %bb382
+
+bb382:		; preds = %bb382, %bb359
+	%indvar = phi i32 [ 0, %bb359 ], [ %indvar.next, %bb382 ]		;  [#uses=2]
+	%max379.pn = phi i32 [ %max154, %bb359 ], [ %L492b.0, %bb382 ]		;  [#uses=1]
+	%before.pn = phi i32 [ %before, %bb359 ], [ 1, %bb382 ]		;  [#uses=1]
+	%L492b.0 = add i32 %before.pn, %max379.pn		;  [#uses=3]
+	%tmp386 = load %struct.RETURN** %tmp63, align 4		; <%struct.RETURN*> [#uses=1]
+	%tmp387 = getelementptr %struct.RETURN* %tmp386, i32 0, i32 0		;  [#uses=1]
+	%tmp388 = load i32* %tmp387, align 4		;  [#uses=2]
+	%tmp392 = load i8** %tmp315, align 4		;  [#uses=2]
+	%R493b.0 = add i32 %indvar, %before		;  [#uses=1]
+	%tmp405 = sub i32 %R493b.0, %tmp388		;  [#uses=1]
+	%tmp406 = getelementptr i8* %tmp392, i32 %tmp405		;  [#uses=1]
+	%tmp407 = load i8* %tmp406, align 1		;  [#uses=1]
+	%tmp408 = sub i32 %L492b.0, %tmp388		;  [#uses=1]
+	%tmp409 = getelementptr i8* %tmp392, i32 %tmp408		;  [#uses=1]
+	store i8 %tmp407, i8* %tmp409, align 1
+	%tmp414 = icmp eq i32 %L492b.0, %tmp155		;  [#uses=1]
+	%indvar.next = add i32 %indvar, 1		;  [#uses=1]
+	br i1 %tmp414, label %bb481, label %bb382
+
+bb420:		; preds = %bb84
+	br i1 %tmp431, label %bb481, label %bb436.preheader
+
+bb436.preheader:		; preds = %bb420
+	%tmp4468 = load i8** %tmp315, align 4		;  [#uses=2]
+	%tmp4599 = sub i32 %tmp148, %tmp330		;  [#uses=1]
+	%tmp46010 = getelementptr i8* %tmp4468, i32 %tmp4599		;  [#uses=1]
+	%tmp46111 = load i8* %tmp46010, align 1		;  [#uses=1]
+	%tmp46212 = sub i32 %tmp155, %tmp330		;  [#uses=1]
+	%tmp46313 = getelementptr i8* %tmp4468, i32 %tmp46212		;  [#uses=1]
+	store i8 %tmp46111, i8* %tmp46313, align 1
+	%exitcond14 = icmp eq i32 %tmp155, %tmp324		;  [#uses=1]
+	br i1 %exitcond14, label %bb481, label %bb.nph
+
+bb.nph:		; preds = %bb436.preheader
+	%tmp5 = sub i32 %tmp148, %before		;  [#uses=1]
+	br label %bb478
+
+bb478:		; preds = %bb478, %bb.nph
+	%indvar6422 = phi i32 [ 0, %bb.nph ], [ %indvar.next643, %bb478 ]		;  [#uses=1]
+	%indvar.next643 = add i32 %indvar6422, 1		;  [#uses=4]
+	%L490b.0 = sub i32 %tmp155, %indvar.next643		;  [#uses=1]
+	%R491b.0 = sub i32 %tmp148, %indvar.next643		;  [#uses=1]
+	%tmp440 = load %struct.RETURN** %tmp63, align 4		; <%struct.RETURN*> [#uses=1]
+	%tmp441 = getelementptr %struct.RETURN* %tmp440, i32 0, i32 0		;  [#uses=1]
+	%tmp442 = load i32* %tmp441, align 4		;  [#uses=2]
+	%tmp446 = load i8** %tmp315, align 4		;  [#uses=2]
+	%tmp459 = sub i32 %R491b.0, %tmp442		;  [#uses=1]
+	%tmp460 = getelementptr i8* %tmp446, i32 %tmp459		;  [#uses=1]
+	%tmp461 = load i8* %tmp460, align 1		;  [#uses=1]
+	%tmp462 = sub i32 %L490b.0, %tmp442		;  [#uses=1]
+	%tmp463 = getelementptr i8* %tmp446, i32 %tmp462		;  [#uses=1]
+	store i8 %tmp461, i8* %tmp463, align 1
+	%exitcond = icmp eq i32 %indvar.next643, %tmp5		;  [#uses=1]
+	br i1 %exitcond, label %bb481, label %bb478
+
+bb481:		; preds = %bb478, %bb436.preheader, %bb420, %bb382, %bb359
+	%tmp577 = add i32 %before, -1		;  [#uses=3]
+	%tmp578 = add i32 %max154, %tmp577		;  [#uses=2]
+	%tmp581 = icmp sge i32 %tmp578, %tmp577		;  [#uses=1]
+	%max582 = select i1 %tmp581, i32 %tmp578, i32 %tmp577		;  [#uses=1]
+	%tmp584 = sub i32 %max582, %before		;  [#uses=1]
+	%tmp585 = add i32 %tmp584, 1		;  [#uses=2]
+	%tmp586 = icmp sgt i32 %tmp585, -1		;  [#uses=1]
+	%max587 = select i1 %tmp586, i32 %tmp585, i32 0		;  [#uses=1]
+	%tmp591 = load %struct.RETURN** %tmp63, align 4		; <%struct.RETURN*> [#uses=1]
+	%tmp592 = getelementptr %struct.RETURN* %tmp591, i32 0, i32 0		;  [#uses=1]
+	%tmp593 = load i32* %tmp592, align 4		;  [#uses=1]
+	%tmp597 = load i8** %tmp315, align 4		;  [#uses=1]
+	%tmp600621 = trunc i64 %new_item.0.0 to i32		;  [#uses=1]
+	%tmp600622 = inttoptr i32 %tmp600621 to i8*		;  [#uses=1]
+	%tmp601 = sub i32 %before, %tmp593		;  [#uses=1]
+	%tmp602 = getelementptr i8* %tmp597, i32 %tmp601		;  [#uses=1]
+	tail call void @llvm.memcpy.i32( i8* %tmp602, i8* %tmp600622, i32 %max587, i32 1 )
+	%tmp606 = load i32* %tmp71, align 4		;  [#uses=1]
+	%tmp613 = add i32 %tmp606, %max154		;  [#uses=1]
+	store i32 %tmp613, i32* %tmp71, align 4
+	ret void
+}




From clattner at apple.com  Wed Nov 21 12:12:59 2007
From: clattner at apple.com (Chris Lattner)
Date: Wed, 21 Nov 2007 10:12:59 -0800
Subject: [llvm-commits] [llvm-testresults] Grawp-PIC i386 nightly tester
	results
In-Reply-To: <200711211443.lALEhVg8004156@zion.cs.uiuc.edu>
References: <200711211443.lALEhVg8004156@zion.cs.uiuc.edu>
Message-ID: <4AD3F818-1C40-4115-90AB-D381158CBC68@apple.com>

Hi Chuck,

Your patch yesterday to change strtoll to strtol caused these  
testsuite regressions:

On Nov 21, 2007, at 6:43 AM, Apache wrote:
> New Test Failures:
> test/CodeGen/ARM/pack.ll [DEJAGNU]
> test/CodeGen/ARM/rev.ll [DEJAGNU]
> test/TableGen/2006-09-18-LargeInt.td [DEJAGNU]

For example, this .td file:

// RUN: tblgen %s | grep -- -65536

def X {
   int Y = 0xFFFF0000;
}

Should print:

def X {
   int Y = -65536;
}

With your change, it prints:

def X {
   int Y = 2147483647;
}

Please fix or revert asap,

-Chris


From cfr at adobe.com  Wed Nov 21 13:36:26 2007
From: cfr at adobe.com (Chuck Rose III)
Date: Wed, 21 Nov 2007 19:36:26 -0000
Subject: [llvm-commits] [llvm] r44264 -
	/llvm/trunk/utils/TableGen/TGLexer.cpp
Message-ID: <200711211936.lALJaRwJ018956@zion.cs.uiuc.edu>

Author: cfr
Date: Wed Nov 21 13:36:25 2007
New Revision: 44264

URL: http://llvm.org/viewvc/llvm-project?rev=44264&view=rev
Log:
Switching back to strtoll. Including config.h.  On VStudio builds, this overrides strtoll.

Modified:
    llvm/trunk/utils/TableGen/TGLexer.cpp

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44264&r1=44263&r2=44264&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Wed Nov 21 13:36:25 2007
@@ -18,6 +18,7 @@
 #include "llvm/Support/MemoryBuffer.h"
 typedef std::pair*> SubClassRefTy;
 #include "FileParser.h"
+#include "llvm/Config/config.h"
 #include 
 using namespace llvm;
 
@@ -341,7 +342,7 @@
       if (CurPtr == NumStart)
         return ReturnError(CurPtr-2, "Invalid hexadecimal number");
 
-      Filelval.IntVal = strtol(NumStart, 0, 16);
+      Filelval.IntVal = strtoll(NumStart, 0, 16);
 
       return INTVAL;
     } else if (CurPtr[0] == 'b') {
@@ -354,7 +355,7 @@
       if (CurPtr == NumStart)
         return ReturnError(CurPtr-2, "Invalid binary number");
 
-      Filelval.IntVal = strtol(NumStart, 0, 2);
+      Filelval.IntVal = strtoll(NumStart, 0, 2);
       return INTVAL;
     }
   }
@@ -368,7 +369,7 @@
   while (isdigit(CurPtr[0]))
     ++CurPtr;
 
-  Filelval.IntVal = strtol(NumStart, 0, 10);
+  Filelval.IntVal = strtoll(NumStart, 0, 10);
   return INTVAL;
 }
 




From clattner at apple.com  Wed Nov 21 16:11:23 2007
From: clattner at apple.com (Chris Lattner)
Date: Wed, 21 Nov 2007 14:11:23 -0800
Subject: [llvm-commits] [llvm] r44264
	-	/llvm/trunk/utils/TableGen/TGLexer.cpp
In-Reply-To: <200711211936.lALJaRwJ018956@zion.cs.uiuc.edu>
References: <200711211936.lALJaRwJ018956@zion.cs.uiuc.edu>
Message-ID: <18FA3FA2-90C8-4044-8551-4418CE29C3B1@apple.com>

Thanks!

-Chris

http://nondot.org/sabre
http://llvm.org

On Nov 21, 2007, at 11:36 AM, Chuck Rose III  wrote:

> Author: cfr
> Date: Wed Nov 21 13:36:25 2007
> New Revision: 44264
>
> URL: http://llvm.org/viewvc/llvm-project?rev=44264&view=rev
> Log:
> Switching back to strtoll. Including config.h.  On VStudio builds,  
> this overrides strtoll.
>
> Modified:
>    llvm/trunk/utils/TableGen/TGLexer.cpp
>
> Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44264&r1=44263&r2=44264&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
> +++ llvm/trunk/utils/TableGen/TGLexer.cpp Wed Nov 21 13:36:25 2007
> @@ -18,6 +18,7 @@
> #include "llvm/Support/MemoryBuffer.h"
> typedef std::pair*>  
> SubClassRefTy;
> #include "FileParser.h"
> +#include "llvm/Config/config.h"
> #include 
> using namespace llvm;
>
> @@ -341,7 +342,7 @@
>       if (CurPtr == NumStart)
>         return ReturnError(CurPtr-2, "Invalid hexadecimal number");
>
> -      Filelval.IntVal = strtol(NumStart, 0, 16);
> +      Filelval.IntVal = strtoll(NumStart, 0, 16);
>
>       return INTVAL;
>     } else if (CurPtr[0] == 'b') {
> @@ -354,7 +355,7 @@
>       if (CurPtr == NumStart)
>         return ReturnError(CurPtr-2, "Invalid binary number");
>
> -      Filelval.IntVal = strtol(NumStart, 0, 2);
> +      Filelval.IntVal = strtoll(NumStart, 0, 2);
>       return INTVAL;
>     }
>   }
> @@ -368,7 +369,7 @@
>   while (isdigit(CurPtr[0]))
>     ++CurPtr;
>
> -  Filelval.IntVal = strtol(NumStart, 0, 10);
> +  Filelval.IntVal = strtoll(NumStart, 0, 10);
>   return INTVAL;
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


From nicholas at mxc.ca  Wed Nov 21 21:07:43 2007
From: nicholas at mxc.ca (Nick Lewycky)
Date: Thu, 22 Nov 2007 03:07:43 -0000
Subject: [llvm-commits] [llvm] r44267 - in /llvm/trunk:
 lib/Analysis/IPA/Andersens.cpp
 test/Analysis/Andersens/2007-11-19-InlineAsm.ll
Message-ID: <200711220307.lAM37hUk010655@zion.cs.uiuc.edu>

Author: nicholas
Date: Wed Nov 21 21:07:37 2007
New Revision: 44267

URL: http://llvm.org/viewvc/llvm-project?rev=44267&view=rev
Log:
Create nodes for inline asm so that we don't crash looking for the node later.

Added:
    llvm/trunk/test/Analysis/Andersens/2007-11-19-InlineAsm.ll
Modified:
    llvm/trunk/lib/Analysis/IPA/Andersens.cpp

Modified: llvm/trunk/lib/Analysis/IPA/Andersens.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/Andersens.cpp?rev=44267&r1=44266&r2=44267&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original)
+++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Wed Nov 21 21:07:37 2007
@@ -668,6 +668,14 @@
         if (AllocationInst *AI = dyn_cast(&*II))
           ObjectNodes[AI] = NumObjects++;
       }
+
+      // Calls to inline asm need to be added as well because the callee isn't
+      // referenced anywhere else.
+      if (CallInst *CI = dyn_cast(&*II)) {
+        Value *Callee = CI->getCalledValue();
+        if (isa(Callee))
+          ValueNodes[Callee] = NumObjects++;
+      }
     }
   }
 

Added: llvm/trunk/test/Analysis/Andersens/2007-11-19-InlineAsm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/Andersens/2007-11-19-InlineAsm.ll?rev=44267&view=auto

==============================================================================
--- llvm/trunk/test/Analysis/Andersens/2007-11-19-InlineAsm.ll (added)
+++ llvm/trunk/test/Analysis/Andersens/2007-11-19-InlineAsm.ll Wed Nov 21 21:07:37 2007
@@ -0,0 +1,8 @@
+; RUN: llvm-as < %s | opt -anders-aa -disable-output
+
+define void @x(i16 %Y) {
+entry:
+  %tmp = call i16 asm "bswap $0", "=r,r"(i16 %Y)
+  ret void
+}
+




From nicholas at mxc.ca  Thu Nov 22 01:59:41 2007
From: nicholas at mxc.ca (Nick Lewycky)
Date: Thu, 22 Nov 2007 07:59:41 -0000
Subject: [llvm-commits] [llvm] r44268 -
	/llvm/trunk/lib/Analysis/ScalarEvolution.cpp
Message-ID: <200711220759.lAM7xfVL027872@zion.cs.uiuc.edu>

Author: nicholas
Date: Thu Nov 22 01:59:40 2007
New Revision: 44268

URL: http://llvm.org/viewvc/llvm-project?rev=44268&view=rev
Log:
Instead of calculating constant factors, calculate the number of trailing
bits. Patch from Wojciech Matyjewicz.

Modified:
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44268&r1=44267&r2=44268&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Thu Nov 22 01:59:40 2007
@@ -1410,62 +1410,60 @@
   return SE.getUnknown(PN);
 }
 
-/// GetConstantFactor - Determine the largest constant factor that S has.  For
-/// example, turn {4,+,8} -> 4.    (S umod result) should always equal zero.
-static APInt GetConstantFactor(SCEVHandle S) {
-  if (SCEVConstant *C = dyn_cast(S)) {
-    const APInt& V = C->getValue()->getValue();
-    if (!V.isMinValue())
-      return V;
-    else   // Zero is a multiple of everything.
-      return APInt::getHighBitsSet(C->getBitWidth(), 1);
-  }
+/// GetMinTrailingZeros - Determine the minimum number of zero bits that S is
+/// guaranteed to end in (at every loop iteration).  It is, at the same time,
+/// the minimum number of times S is divisible by 2.  For example, given {4,+,8}
+/// it returns 2.  If S is guaranteed to be 0, it returns the bitwidth of S.
+static uint32_t GetMinTrailingZeros(SCEVHandle S) {
+  if (SCEVConstant *C = dyn_cast(S))
+    // APInt::countTrailingZeros() returns the number of trailing zeros in its
+    // internal representation, which length may be greater than the represented
+    // value bitwidth. This is why we use a min operation here.
+    return std::min(C->getValue()->getValue().countTrailingZeros(),
+                    C->getBitWidth());
 
   if (SCEVTruncateExpr *T = dyn_cast(S))
-    return GetConstantFactor(T->getOperand()).trunc(
-                               cast(T->getType())->getBitWidth());
-  if (SCEVZeroExtendExpr *E = dyn_cast(S))
-    return GetConstantFactor(E->getOperand()).zext(
-                               cast(E->getType())->getBitWidth());
-  if (SCEVSignExtendExpr *E = dyn_cast(S))
-    return GetConstantFactor(E->getOperand()).sext(
-                               cast(E->getType())->getBitWidth());
-  
+    return std::min(GetMinTrailingZeros(T->getOperand()), T->getBitWidth());
+
+  if (SCEVZeroExtendExpr *E = dyn_cast(S)) {
+    uint32_t OpRes = GetMinTrailingZeros(E->getOperand());
+    return OpRes == E->getOperand()->getBitWidth() ? E->getBitWidth() : OpRes;
+  }
+
+  if (SCEVSignExtendExpr *E = dyn_cast(S)) {
+    uint32_t OpRes = GetMinTrailingZeros(E->getOperand());
+    return OpRes == E->getOperand()->getBitWidth() ? E->getBitWidth() : OpRes;
+  }
+
   if (SCEVAddExpr *A = dyn_cast(S)) {
-    // The result is the min of all operands.
-    APInt Res(GetConstantFactor(A->getOperand(0)));
-    for (unsigned i = 1, e = A->getNumOperands(); 
-         i != e && Res.ugt(APInt(Res.getBitWidth(),1)); ++i) {
-      APInt Tmp(GetConstantFactor(A->getOperand(i)));
-      Res = APIntOps::umin(Res, Tmp);
-    }
-    return Res;
+    // The result is the min of all operands results.
+    uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0));
+    for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i)
+      MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i)));
+    return MinOpRes;
   }
 
   if (SCEVMulExpr *M = dyn_cast(S)) {
-    // The result is the product of all the operands.
-    APInt Res(GetConstantFactor(M->getOperand(0)));
-    for (unsigned i = 1, e = M->getNumOperands(); i != e; ++i) {
-      APInt Tmp(GetConstantFactor(M->getOperand(i)));
-      Res *= Tmp;
-    }
-    return Res;
+    // The result is the sum of all operands results.
+    uint32_t SumOpRes = GetMinTrailingZeros(M->getOperand(0));
+    uint32_t BitWidth = M->getBitWidth();
+    for (unsigned i = 1, e = M->getNumOperands();
+         SumOpRes != BitWidth && i != e; ++i)
+      SumOpRes = std::min(SumOpRes + GetMinTrailingZeros(M->getOperand(i)),
+                          BitWidth);
+    return SumOpRes;
   }
-    
+
   if (SCEVAddRecExpr *A = dyn_cast(S)) {
-    // For now, we just handle linear expressions.
-    if (A->getNumOperands() == 2) {
-      // We want the GCD between the start and the stride value.
-      APInt Start(GetConstantFactor(A->getOperand(0)));
-      if (Start == 1) 
-        return Start;
-      APInt Stride(GetConstantFactor(A->getOperand(1)));
-      return APIntOps::GreatestCommonDivisor(Start, Stride);
-    }
+    // The result is the min of all operands results.
+    uint32_t MinOpRes = GetMinTrailingZeros(A->getOperand(0));
+    for (unsigned i = 1, e = A->getNumOperands(); MinOpRes && i != e; ++i)
+      MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(A->getOperand(i)));
+    return MinOpRes;
   }
-  
-  // SCEVSDivExpr, SCEVUnknown.
-  return APInt(S->getBitWidth(), 1);
+
+  // SCEVSDivExpr, SCEVUnknown
+  return 0;
 }
 
 /// createSCEV - We know that there is no SCEV for the specified value.
@@ -1493,17 +1491,12 @@
       //
       // In order for this transformation to be safe, the LHS must be of the
       // form X*(2^n) and the Or constant must be less than 2^n.
-
       if (ConstantInt *CI = dyn_cast(I->getOperand(1))) {
         SCEVHandle LHS = getSCEV(I->getOperand(0));
-        APInt CommonFact(GetConstantFactor(LHS));
-        assert(!CommonFact.isMinValue() &&
-               "Common factor should at least be 1!");
         const APInt &CIVal = CI->getValue();
-        if (CommonFact.countTrailingZeros() >=
+        if (GetMinTrailingZeros(LHS) >=
             (CIVal.getBitWidth() - CIVal.countLeadingZeros()))
-          return SE.getAddExpr(LHS,
-                               getSCEV(I->getOperand(1)));
+          return SE.getAddExpr(LHS, getSCEV(I->getOperand(1)));
       }
       break;
     case Instruction::Xor:




From baldrick at free.fr  Thu Nov 22 03:34:24 2007
From: baldrick at free.fr (Duncan Sands)
Date: Thu, 22 Nov 2007 09:34:24 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44269 -
	/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Message-ID: <200711220934.lAM9YPR3007759@zion.cs.uiuc.edu>

Author: baldrick
Date: Thu Nov 22 03:34:20 2007
New Revision: 44269

URL: http://llvm.org/viewvc/llvm-project?rev=44269&view=rev
Log:
Struct return functions cannot be const/pure because
they write the result via the sret pointer argument.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44269&r1=44268&r2=44269&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Nov 22 03:34:20 2007
@@ -1019,29 +1019,35 @@
   TARGET_ADJUST_LLVM_CC(CallingConv, type);
 #endif
 
-  // Compute attributes for return type (and function attributes)
+  // Compute attributes for return type (and function attributes).
   ParamAttrsVector Attrs;
   uint16_t RAttributes = ParamAttr::None;
 
   int flags = flags_from_decl_or_type(decl ? decl : type);
 
-  // Check for 'const' function attribute
+  // Check for 'const' function attribute.
   if (flags & ECF_CONST)
-    RAttributes |= ParamAttr::Const;
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'const'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::Const;
 
-  // Check for 'noreturn' function attribute
+  // Check for 'noreturn' function attribute.
   if (flags & ECF_NORETURN)
     RAttributes |= ParamAttr::NoReturn;
 
-  // Check for 'nounwind' function attribute
+  // Check for 'nounwind' function attribute.
   if (flags & ECF_NOTHROW)
     RAttributes |= ParamAttr::NoUnwind;
 
-  // Check for 'pure' function attribute
+  // Check for 'pure' function attribute.
   if (flags & ECF_PURE)
-    RAttributes |= ParamAttr::Pure;
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'pure'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::Pure;
 
-  // Compute whether the result needs to be zext or sext'd
+  // Compute whether the result needs to be zext or sext'd.
   if (isa(RetTy.get())) {
     tree ResultTy = TREE_TYPE(type);  
     if (TREE_INT_CST_LOW(TYPE_SIZE(ResultTy)) < INT_TYPE_SIZE) {




From baldrick at free.fr  Thu Nov 22 03:39:30 2007
From: baldrick at free.fr (Duncan Sands)
Date: Thu, 22 Nov 2007 09:39:30 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44270 -
	/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Message-ID: <200711220939.lAM9dUS2008002@zion.cs.uiuc.edu>

Author: baldrick
Date: Thu Nov 22 03:39:28 2007
New Revision: 44270

URL: http://llvm.org/viewvc/llvm-project?rev=44270&view=rev
Log:
Struct return functions cannot be const/pure because
they write the result via the sret pointer argument.

Modified:
    llvm-gcc-4.0/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=44270&r1=44269&r2=44270&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Thu Nov 22 03:39:28 2007
@@ -984,29 +984,35 @@
   TARGET_ADJUST_LLVM_CC(CallingConv, type);
 #endif
 
-  // Compute attributes for return type (and function attributes)
+  // Compute attributes for return type (and function attributes).
   ParamAttrsVector Attrs;
   uint16_t RAttributes = ParamAttr::None;
 
   int flags = flags_from_decl_or_type(decl ? decl : type);
 
-  // Check for 'const' function attribute
+  // Check for 'const' function attribute.
   if (flags & ECF_CONST)
-    RAttributes |= ParamAttr::Const;
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'const'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::Const;
 
-  // Check for 'noreturn' function attribute
+  // Check for 'noreturn' function attribute.
   if (flags & ECF_NORETURN)
     RAttributes |= ParamAttr::NoReturn;
 
-  // Check for 'nounwind' function attribute
+  // Check for 'nounwind' function attribute.
   if (flags & ECF_NOTHROW)
     RAttributes |= ParamAttr::NoUnwind;
 
-  // Check for 'pure' function attribute
+  // Check for 'pure' function attribute.
   if (flags & ECF_PURE)
-    RAttributes |= ParamAttr::Pure;
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'pure'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::Pure;
 
-  // Compute whether the result needs to be zext or sext'd
+  // Compute whether the result needs to be zext or sext'd.
   if (isa(RetTy.get())) {
     tree ResultTy = TREE_TYPE(type);  
     if (TREE_INT_CST_LOW(TYPE_SIZE(ResultTy)) < INT_TYPE_SIZE) {




From baldrick at free.fr  Thu Nov 22 14:23:01 2007
From: baldrick at free.fr (Duncan Sands)
Date: Thu, 22 Nov 2007 20:23:01 -0000
Subject: [llvm-commits] [llvm-gcc-4.0] r44271 -
	/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
Message-ID: <200711222023.lAMKN1OF005165@zion.cs.uiuc.edu>

Author: baldrick
Date: Thu Nov 22 14:22:59 2007
New Revision: 44271

URL: http://llvm.org/viewvc/llvm-project?rev=44271&view=rev
Log:
Fix needed due to parameter attribute renaming:
const -> readnone; pure -> readonly.

Modified:
    llvm-gcc-4.0/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.0/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/llvm-types.cpp?rev=44271&r1=44270&r2=44271&view=diff

==============================================================================
--- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Thu Nov 22 14:22:59 2007
@@ -990,13 +990,6 @@
 
   int flags = flags_from_decl_or_type(decl ? decl : type);
 
-  // Check for 'const' function attribute.
-  if (flags & ECF_CONST)
-    // Since they write the return value through a pointer,
-    // 'sret' functions cannot be 'const'.
-    if (!ABIConverter.isStructReturn())
-      RAttributes |= ParamAttr::Const;
-
   // Check for 'noreturn' function attribute.
   if (flags & ECF_NORETURN)
     RAttributes |= ParamAttr::NoReturn;
@@ -1005,12 +998,19 @@
   if (flags & ECF_NOTHROW)
     RAttributes |= ParamAttr::NoUnwind;
 
-  // Check for 'pure' function attribute.
+  // Check for 'readnone' function attribute.
+  if (flags & ECF_CONST)
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'readnone'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::ReadNone;
+
+  // Check for 'readonly' function attribute.
   if (flags & ECF_PURE)
     // Since they write the return value through a pointer,
-    // 'sret' functions cannot be 'pure'.
+    // 'sret' functions cannot be 'readonly'.
     if (!ABIConverter.isStructReturn())
-      RAttributes |= ParamAttr::Pure;
+      RAttributes |= ParamAttr::ReadOnly;
 
   // Compute whether the result needs to be zext or sext'd.
   if (isa(RetTy.get())) {




From baldrick at free.fr  Thu Nov 22 14:23:01 2007
From: baldrick at free.fr (Duncan Sands)
Date: Thu, 22 Nov 2007 20:23:01 -0000
Subject: [llvm-commits] [llvm-gcc-4.2] r44272 -
	/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
Message-ID: <200711222023.lAMKN1rk005173@zion.cs.uiuc.edu>

Author: baldrick
Date: Thu Nov 22 14:23:01 2007
New Revision: 44272

URL: http://llvm.org/viewvc/llvm-project?rev=44272&view=rev
Log:
Fix needed due to parameter attribute renaming:
const -> readnone; pure -> readonly.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-types.cpp

Modified: llvm-gcc-4.2/trunk/gcc/llvm-types.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-types.cpp?rev=44272&r1=44271&r2=44272&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Thu Nov 22 14:23:01 2007
@@ -1025,13 +1025,6 @@
 
   int flags = flags_from_decl_or_type(decl ? decl : type);
 
-  // Check for 'const' function attribute.
-  if (flags & ECF_CONST)
-    // Since they write the return value through a pointer,
-    // 'sret' functions cannot be 'const'.
-    if (!ABIConverter.isStructReturn())
-      RAttributes |= ParamAttr::Const;
-
   // Check for 'noreturn' function attribute.
   if (flags & ECF_NORETURN)
     RAttributes |= ParamAttr::NoReturn;
@@ -1040,12 +1033,19 @@
   if (flags & ECF_NOTHROW)
     RAttributes |= ParamAttr::NoUnwind;
 
-  // Check for 'pure' function attribute.
+  // Check for 'readnone' function attribute.
+  if (flags & ECF_CONST)
+    // Since they write the return value through a pointer,
+    // 'sret' functions cannot be 'readnone'.
+    if (!ABIConverter.isStructReturn())
+      RAttributes |= ParamAttr::ReadNone;
+
+  // Check for 'readonly' function attribute.
   if (flags & ECF_PURE)
     // Since they write the return value through a pointer,
-    // 'sret' functions cannot be 'pure'.
+    // 'sret' functions cannot be 'readonly'.
     if (!ABIConverter.isStructReturn())
-      RAttributes |= ParamAttr::Pure;
+      RAttributes |= ParamAttr::ReadOnly;
 
   // Compute whether the result needs to be zext or sext'd.
   if (isa(RetTy.get())) {




From baldrick at free.fr  Thu Nov 22 14:23:05 2007
From: baldrick at free.fr (Duncan Sands)
Date: Thu, 22 Nov 2007 20:23:05 -0000
Subject: [llvm-commits] [llvm] r44273 - in /llvm/trunk: docs/LangRef.html
 include/llvm/ParameterAttributes.h lib/AsmParser/LLLexer.cpp
 lib/AsmParser/llvmAsmParser.y lib/VMCore/Function.cpp
 lib/VMCore/Verifier.cpp
Message-ID: <200711222023.lAMKN6pC005194@zion.cs.uiuc.edu>

Author: baldrick
Date: Thu Nov 22 14:23:04 2007
New Revision: 44273

URL: http://llvm.org/viewvc/llvm-project?rev=44273&view=rev
Log:
Rename the 'const' parameter attribute to 'readnone',
and the 'pure' parameter attribute to 'readonly'.
Names suggested by DannyB.

Modified:
    llvm/trunk/docs/LangRef.html
    llvm/trunk/include/llvm/ParameterAttributes.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/llvmAsmParser.y
    llvm/trunk/lib/VMCore/Function.cpp
    llvm/trunk/lib/VMCore/Verifier.cpp

Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=44273&r1=44272&r2=44273&view=diff

==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Thu Nov 22 14:23:04 2007
@@ -813,13 +813,13 @@
     
nest
This indicates that the parameter can be excised using the trampoline intrinsics.
-
pure
+
readonly
This function attribute indicates that the function has no side-effects - except for producing a return value. The value returned must only depend on - the function arguments and/or global variables. It may use values obtained - by dereferencing pointers.
-
const
-
A const function has the same restrictions as a pure + except for producing a return value or throwing an exception. The value + returned must only depend on the function arguments and/or global variables. + It may use values obtained by dereferencing pointers.
+
readnone
+
A readnone function has the same restrictions as a readonly function, but in addition it is not allowed to dereference any pointer arguments or global variables. Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=44273&r1=44272&r2=44273&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Thu Nov 22 14:23:04 2007 @@ -39,8 +39,8 @@ NoAlias = 1 << 6, ///< Considered to not alias after call ByVal = 1 << 7, ///< Pass structure by value Nest = 1 << 8, ///< Nested function static chain - Pure = 1 << 9, ///< Function is pure - Const = 1 << 10 ///< Function is const + ReadNone = 1 << 9, ///< Function does not access memory + ReadOnly = 1 << 10 ///< Function only reads from memory }; } Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=44273&r1=44272&r2=44273&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Thu Nov 22 14:23:04 2007 @@ -484,8 +484,8 @@ KEYWORD("noalias", NOALIAS); KEYWORD("byval", BYVAL); KEYWORD("nest", NEST); - KEYWORD("pure", PURE); - KEYWORD("const", CONST); + KEYWORD("readnone", READNONE); + KEYWORD("readonly", READONLY); KEYWORD("type", TYPE); KEYWORD("opaque", OPAQUE); Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=44273&r1=44272&r2=44273&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original) +++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Thu Nov 22 14:23:04 2007 @@ -1090,7 +1090,7 @@ // Function Attributes %token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST -%token CONST PURE +%token READNONE READONLY // Visibility Styles %token DEFAULT HIDDEN PROTECTED @@ -1234,8 +1234,8 @@ | NOUNWIND { $$ = ParamAttr::NoUnwind; } | ZEROEXT { $$ = ParamAttr::ZExt; } | SIGNEXT { $$ = ParamAttr::SExt; } - | PURE { $$ = ParamAttr::Pure; } - | CONST { $$ = ParamAttr::Const; } + | READNONE { $$ = ParamAttr::ReadNone; } + | READONLY { $$ = ParamAttr::ReadOnly; } ; OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; } Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44273&r1=44272&r2=44273&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Thu Nov 22 14:23:04 2007 @@ -108,10 +108,10 @@ Result += "byval "; if (Attrs & ParamAttr::Nest) Result += "nest "; - if (Attrs & ParamAttr::Pure) - Result += "pure "; - if (Attrs & ParamAttr::Const) - Result += "const "; + if (Attrs & ParamAttr::ReadNone) + Result += "readnone "; + if (Attrs & ParamAttr::ReadOnly) + Result += "readonly "; return Result; } Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=44273&r1=44272&r2=44273&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Thu Nov 22 14:23:04 2007 @@ -399,7 +399,7 @@ const uint16_t ParameterIncompatible = ParamAttr::NoReturn | ParamAttr::NoUnwind | - ParamAttr::Const | ParamAttr::Pure; + ParamAttr::ReadNone | ParamAttr::ReadOnly; const uint16_t MutuallyIncompatible[3] = { ParamAttr::ByVal | ParamAttr::InReg | @@ -407,7 +407,7 @@ ParamAttr::ZExt | ParamAttr::SExt, - ParamAttr::Pure | ParamAttr::Const + ParamAttr::ReadNone | ParamAttr::ReadOnly }; const uint16_t IntegerTypeOnly = From sabre at nondot.org Thu Nov 22 14:49:07 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 20:49:07 -0000 Subject: [llvm-commits] [llvm] r44274 - in /llvm/trunk/utils/TableGen: FileParser.cpp.cvs FileParser.h.cvs FileParser.y FileParser.y.cvs Makefile TGLexer.cpp TGLexer.h TGParser.cpp TGParser.h TableGen.cpp Message-ID: <200711222049.lAMKn8EG006169@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 14:49:04 2007 New Revision: 44274 URL: http://llvm.org/viewvc/llvm-project?rev=44274&view=rev Log: Rewrite the tblgen parser in a recursive descent style, eliminating the bison parser. This makes the parser much easier to understand, eliminates a ton of global variables, and gives tblgen nice caret diagnostics. It is also faster, but tblgen probably doesn't care about performance. There are a couple of FIXMEs which I will take care of next. Added: llvm/trunk/utils/TableGen/TGParser.cpp llvm/trunk/utils/TableGen/TGParser.h Removed: llvm/trunk/utils/TableGen/FileParser.cpp.cvs llvm/trunk/utils/TableGen/FileParser.h.cvs llvm/trunk/utils/TableGen/FileParser.y llvm/trunk/utils/TableGen/FileParser.y.cvs Modified: llvm/trunk/utils/TableGen/Makefile llvm/trunk/utils/TableGen/TGLexer.cpp llvm/trunk/utils/TableGen/TGLexer.h llvm/trunk/utils/TableGen/TableGen.cpp Removed: llvm/trunk/utils/TableGen/FileParser.cpp.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FileParser.cpp.cvs?rev=44273&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/FileParser.cpp.cvs (original) +++ llvm/trunk/utils/TableGen/FileParser.cpp.cvs (removed) @@ -1,2106 +0,0 @@ - -/* A Bison parser, made from /Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y - by GNU Bison version 1.28 */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define yyparse Fileparse -#define yylex Filelex -#define yyerror Fileerror -#define yylval Filelval -#define yychar Filechar -#define yydebug Filedebug -#define yynerrs Filenerrs -#define INT 257 -#define BIT 258 -#define STRING 259 -#define BITS 260 -#define LIST 261 -#define CODE 262 -#define DAG 263 -#define CLASS 264 -#define DEF 265 -#define MULTICLASS 266 -#define DEFM 267 -#define FIELD 268 -#define LET 269 -#define IN 270 -#define CONCATTOK 271 -#define SHLTOK 272 -#define SRATOK 273 -#define SRLTOK 274 -#define STRCONCATTOK 275 -#define INTVAL 276 -#define ID 277 -#define VARNAME 278 -#define STRVAL 279 -#define CODEFRAGMENT 280 - -#line 14 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" - -#include "Record.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Streams.h" -#include -#include -#define YYERROR_VERBOSE 1 - -int yyerror(const char *ErrorMsg); -int yylex(); - -namespace llvm { - struct MultiClass { - Record Rec; // Placeholder for template args and Name. - std::vector DefPrototypes; - - MultiClass(const std::string &Name) : Rec(Name) {} - }; - - -static std::map MultiClasses; - -extern int Filelineno; -static MultiClass *CurMultiClass = 0; // Set while parsing a multiclass. -static std::string *CurDefmPrefix = 0; // Set while parsing defm. -static Record *CurRec = 0; -static bool ParsingTemplateArgs = false; - -typedef std::pair*> SubClassRefTy; - -struct LetRecord { - std::string Name; - std::vector Bits; - Init *Value; - bool HasBits; - LetRecord(const std::string &N, std::vector *B, Init *V) - : Name(N), Value(V), HasBits(B != 0) { - if (HasBits) Bits = *B; - } -}; - -static std::vector > LetStack; - - -extern std::ostream &err(); - -/// getActiveRec - If inside a def/class definition, return the def/class. -/// Otherwise, if within a multidef, return it. -static Record *getActiveRec() { - return CurRec ? CurRec : &CurMultiClass->Rec; -} - -static void addValue(const RecordVal &RV) { - Record *TheRec = getActiveRec(); - - if (RecordVal *ERV = TheRec->getValue(RV.getName())) { - // The value already exists in the class, treat this as a set... - if (ERV->setValue(RV.getValue())) { - err() << "New definition of '" << RV.getName() << "' of type '" - << *RV.getType() << "' is incompatible with previous " - << "definition of type '" << *ERV->getType() << "'!\n"; - exit(1); - } - } else { - TheRec->addValue(RV); - } -} - -static void addSuperClass(Record *SC) { - if (CurRec->isSubClassOf(SC)) { - err() << "Already subclass of '" << SC->getName() << "'!\n"; - exit(1); - } - CurRec->addSuperClass(SC); -} - -static void setValue(const std::string &ValName, - std::vector *BitList, Init *V) { - if (!V) return; - - Record *TheRec = getActiveRec(); - RecordVal *RV = TheRec->getValue(ValName); - if (RV == 0) { - err() << "Value '" << ValName << "' unknown!\n"; - exit(1); - } - - // Do not allow assignments like 'X = X'. This will just cause infinite loops - // in the resolution machinery. - if (!BitList) - if (VarInit *VI = dynamic_cast(V)) - if (VI->getName() == ValName) - return; - - // If we are assigning to a subset of the bits in the value... then we must be - // assigning to a field of BitsRecTy, which must have a BitsInit - // initializer... - // - if (BitList) { - BitsInit *CurVal = dynamic_cast(RV->getValue()); - if (CurVal == 0) { - err() << "Value '" << ValName << "' is not a bits type!\n"; - exit(1); - } - - // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->convertInitializerTo(new BitsRecTy(BitList->size())); - if (BI == 0) { - V->convertInitializerTo(new BitsRecTy(BitList->size())); - err() << "Initializer '" << *V << "' not compatible with bit range!\n"; - exit(1); - } - - // We should have a BitsInit type now... - assert(dynamic_cast(BI) != 0 || (cerr << *BI).stream() == 0); - BitsInit *BInit = (BitsInit*)BI; - - BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); - - // Loop over bits, assigning values as appropriate... - for (unsigned i = 0, e = BitList->size(); i != e; ++i) { - unsigned Bit = (*BitList)[i]; - if (NewVal->getBit(Bit)) { - err() << "Cannot set bit #" << Bit << " of value '" << ValName - << "' more than once!\n"; - exit(1); - } - NewVal->setBit(Bit, BInit->getBit(i)); - } - - for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) - if (NewVal->getBit(i) == 0) - NewVal->setBit(i, CurVal->getBit(i)); - - V = NewVal; - } - - if (RV->setValue(V)) { - err() << "Value '" << ValName << "' of type '" << *RV->getType() - << "' is incompatible with initializer '" << *V << "'!\n"; - exit(1); - } -} - -// addSubClass - Add SC as a subclass to CurRec, resolving TemplateArgs as SC's -// template arguments. -static void addSubClass(Record *SC, const std::vector &TemplateArgs) { - // Add all of the values in the subclass into the current class... - const std::vector &Vals = SC->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - addValue(Vals[i]); - - const std::vector &TArgs = SC->getTemplateArgs(); - - // Ensure that an appropriate number of template arguments are specified... - if (TArgs.size() < TemplateArgs.size()) { - err() << "ERROR: More template args specified than expected!\n"; - exit(1); - } - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateArgs.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateArgs[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() - << "'!\n"; - exit(1); - } - } - - // Since everything went well, we can now set the "superclass" list for the - // current record. - const std::vector &SCs = SC->getSuperClasses(); - for (unsigned i = 0, e = SCs.size(); i != e; ++i) - addSuperClass(SCs[i]); - addSuperClass(SC); -} - -} // End llvm namespace - -using namespace llvm; - - -#line 210 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -typedef union { - std::string* StrVal; - int IntVal; - llvm::RecTy* Ty; - llvm::Init* Initializer; - std::vector* FieldList; - std::vector* BitList; - llvm::Record* Rec; - std::vector* RecList; - SubClassRefTy* SubClassRef; - std::vector* SubClassList; - std::vector >* DagValueList; -} YYSTYPE; -#include - -#ifndef __cplusplus -#ifndef __STDC__ -#define const -#endif -#endif - - - -#define YYFINAL 194 -#define YYFLAG -32768 -#define YYNTBASE 42 - -#define YYTRANSLATE(x) ((unsigned)(x) <= 280 ? yytranslate[x] : 91) - -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, - 37, 2, 2, 38, 40, 35, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 39, 41, 27, - 29, 28, 30, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 33, 2, 34, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 31, 2, 32, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 -}; - -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 4, 6, 11, 13, 18, 20, 22, 24, - 25, 27, 28, 31, 33, 35, 37, 39, 41, 43, - 47, 52, 57, 61, 65, 70, 75, 82, 89, 96, - 103, 110, 111, 114, 117, 122, 123, 125, 127, 131, - 134, 138, 144, 149, 151, 152, 156, 157, 159, 161, - 165, 170, 173, 180, 181, 184, 186, 190, 192, 197, - 199, 203, 204, 207, 209, 213, 217, 218, 220, 222, - 223, 225, 227, 229, 230, 234, 235, 236, 243, 247, - 249, 251, 254, 256, 257, 258, 267, 268, 275, 277, - 279, 281, 283, 288, 290, 294, 295, 300, 305, 308, - 310, 313 -}; - -static const short yyrhs[] = { 23, - 0, 5, 0, 4, 0, 6, 27, 22, 28, 0, - 3, 0, 7, 27, 43, 28, 0, 8, 0, 9, - 0, 42, 0, 0, 14, 0, 0, 29, 47, 0, - 23, 0, 46, 0, 22, 0, 25, 0, 26, 0, - 30, 0, 31, 54, 32, 0, 23, 27, 55, 28, - 0, 47, 31, 52, 32, 0, 33, 54, 34, 0, - 47, 35, 23, 0, 36, 46, 50, 37, 0, 47, - 33, 52, 34, 0, 17, 36, 47, 38, 47, 37, - 0, 18, 36, 47, 38, 47, 37, 0, 19, 36, - 47, 38, 47, 37, 0, 20, 36, 47, 38, 47, - 37, 0, 21, 36, 47, 38, 47, 37, 0, 0, - 39, 24, 0, 47, 48, 0, 49, 38, 47, 48, - 0, 0, 49, 0, 22, 0, 22, 40, 22, 0, - 22, 22, 0, 51, 38, 22, 0, 51, 38, 22, - 40, 22, 0, 51, 38, 22, 22, 0, 51, 0, - 0, 31, 52, 32, 0, 0, 55, 0, 47, 0, - 55, 38, 47, 0, 44, 43, 23, 45, 0, 56, - 41, 0, 15, 23, 53, 29, 47, 41, 0, 0, - 58, 57, 0, 41, 0, 31, 58, 32, 0, 42, - 0, 42, 27, 55, 28, 0, 60, 0, 61, 38, - 60, 0, 0, 39, 61, 0, 56, 0, 63, 38, - 56, 0, 27, 63, 28, 0, 0, 64, 0, 23, - 0, 0, 66, 0, 67, 0, 67, 0, 0, 62, - 71, 59, 0, 0, 0, 10, 68, 73, 65, 74, - 70, 0, 11, 69, 70, 0, 75, 0, 76, 0, - 77, 76, 0, 23, 0, 0, 0, 12, 78, 80, - 65, 81, 31, 77, 32, 0, 0, 13, 23, 83, - 39, 60, 41, 0, 72, 0, 75, 0, 79, 0, - 82, 0, 23, 53, 29, 47, 0, 85, 0, 86, - 38, 85, 0, 0, 15, 88, 86, 16, 0, 87, - 31, 89, 32, 0, 87, 84, 0, 84, 0, 89, - 84, 0, 89, 0 -}; - -#endif - -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 246, 268, 270, 272, 274, 276, 278, 280, 282, 286, - 286, 288, 288, 290, 313, 315, 317, 320, 323, 325, - 338, 366, 373, 376, 383, 386, 394, 396, 398, 400, - 402, 406, 409, 413, 418, 424, 427, 430, 433, 446, - 460, 462, 475, 491, 493, 493, 497, 499, 503, 506, - 510, 527, 529, 535, 535, 536, 536, 538, 540, 544, - 549, 554, 557, 561, 564, 569, 570, 570, 572, 572, - 574, 581, 599, 624, 638, 643, 645, 647, 651, 661, - 675, 678, 682, 693, 695, 697, 702, 702, 776, 776, - 777, 777, 779, 784, 784, 787, 787, 790, 793, 797, - 797, 799 -}; -#endif - - -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) - -static const char * const yytname[] = { "$","error","$undefined.","INT","BIT", -"STRING","BITS","LIST","CODE","DAG","CLASS","DEF","MULTICLASS","DEFM","FIELD", -"LET","IN","CONCATTOK","SHLTOK","SRATOK","SRLTOK","STRCONCATTOK","INTVAL","ID", -"VARNAME","STRVAL","CODEFRAGMENT","'<'","'>'","'='","'?'","'{'","'}'","'['", -"']'","'.'","'('","')'","','","':'","'-'","';'","ClassID","Type","OptPrefix", -"OptValue","IDValue","Value","OptVarName","DagArgListNE","DagArgList","RBitList", -"BitList","OptBitList","ValueList","ValueListNE","Declaration","BodyItem","BodyList", -"Body","SubClassRef","ClassListNE","ClassList","DeclListNE","TemplateArgList", -"OptTemplateArgList","OptID","ObjectName","ClassName","DefName","ObjectBody", -"@1","ClassInst","@2","@3","DefInst","MultiClassDef","MultiClassBody","MultiClassName", -"MultiClassInst","@4","@5","DefMInst","@6","Object","LETItem","LETList","LETCommand", -"@7","ObjectList","File", NULL -}; -#endif - -static const short yyr1[] = { 0, - 42, 43, 43, 43, 43, 43, 43, 43, 43, 44, - 44, 45, 45, 46, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 48, 48, 49, 49, 50, 50, 51, 51, 51, - 51, 51, 51, 52, 53, 53, 54, 54, 55, 55, - 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, - 61, 62, 62, 63, 63, 64, 65, 65, 66, 66, - 67, 68, 69, 71, 70, 73, 74, 72, 75, 76, - 77, 77, 78, 80, 81, 79, 83, 82, 84, 84, - 84, 84, 85, 86, 86, 88, 87, 84, 84, 89, - 89, 90 -}; - -static const short yyr2[] = { 0, - 1, 1, 1, 4, 1, 4, 1, 1, 1, 0, - 1, 0, 2, 1, 1, 1, 1, 1, 1, 3, - 4, 4, 3, 3, 4, 4, 6, 6, 6, 6, - 6, 0, 2, 2, 4, 0, 1, 1, 3, 2, - 3, 5, 4, 1, 0, 3, 0, 1, 1, 3, - 4, 2, 6, 0, 2, 1, 3, 1, 4, 1, - 3, 0, 2, 1, 3, 3, 0, 1, 1, 0, - 1, 1, 1, 0, 3, 0, 0, 6, 3, 1, - 1, 2, 1, 0, 0, 8, 0, 6, 1, 1, - 1, 1, 4, 1, 3, 0, 4, 4, 2, 1, - 2, 1 -}; - -static const short yydefact[] = { 0, - 70, 70, 0, 0, 96, 89, 90, 91, 92, 100, - 0, 102, 69, 71, 72, 76, 73, 62, 83, 84, - 87, 0, 0, 99, 101, 67, 0, 74, 79, 67, - 0, 45, 94, 0, 0, 10, 68, 77, 1, 58, - 60, 63, 0, 85, 0, 0, 0, 97, 0, 98, - 11, 0, 64, 0, 62, 0, 0, 54, 56, 75, - 0, 0, 38, 44, 0, 0, 95, 5, 3, 2, - 0, 0, 7, 8, 9, 0, 66, 10, 78, 0, - 0, 0, 0, 0, 16, 14, 17, 18, 19, 47, - 47, 0, 15, 49, 0, 61, 10, 0, 88, 40, - 0, 0, 46, 93, 0, 0, 12, 65, 0, 0, - 0, 0, 0, 0, 0, 48, 0, 14, 36, 0, - 0, 0, 59, 0, 0, 57, 0, 55, 80, 81, - 0, 39, 41, 0, 0, 0, 51, 0, 0, 0, - 0, 0, 0, 20, 23, 32, 37, 0, 0, 0, - 24, 50, 45, 52, 86, 82, 43, 0, 4, 6, - 13, 0, 0, 0, 0, 0, 21, 0, 34, 0, - 25, 22, 26, 0, 42, 0, 0, 0, 0, 0, - 33, 32, 0, 27, 28, 29, 30, 31, 35, 0, - 53, 0, 0, 0 -}; - -static const short yydefgoto[] = { 40, - 76, 52, 137, 93, 94, 169, 147, 148, 64, 65, - 47, 115, 116, 53, 128, 97, 60, 41, 42, 28, - 54, 37, 38, 14, 15, 16, 18, 29, 43, 6, - 26, 55, 7, 130, 131, 20, 8, 30, 61, 9, - 31, 10, 33, 34, 11, 22, 12, 192 -}; - -static const short yypact[] = { 147, - -17, -17, 8, 12,-32768,-32768,-32768,-32768,-32768,-32768, - 3, 147,-32768,-32768,-32768,-32768,-32768, -13,-32768,-32768, --32768, 17, 147,-32768,-32768, 21, 58,-32768,-32768, 21, - 45, 55,-32768, -5, -3, 77,-32768,-32768,-32768, 68, --32768, 64, -4,-32768, 58, 84, 81,-32768, 17,-32768, --32768, 16,-32768, 13, -13, 43, 58,-32768,-32768,-32768, - 88, 74, 10, 83, 93, 43,-32768,-32768,-32768,-32768, - 100, 104,-32768,-32768,-32768, 110,-32768, 77,-32768, 117, - 125, 127, 128, 129,-32768, 139,-32768,-32768,-32768, 43, - 43, 132,-32768, 59, 14,-32768, 40, 156,-32768,-32768, - 146, 148,-32768, 59, 149, 16, 140,-32768, 43, 43, - 43, 43, 43, 43, 141, 134, 142,-32768, 43, 84, - 84, 151,-32768, 43, 152,-32768, 136,-32768,-32768,-32768, - 6,-32768, 35, 150, 153, 43,-32768, 70, 76, 85, - 91, 97, 39,-32768,-32768, 54, 144, 143, 154, 145, --32768, 59, 55,-32768,-32768,-32768,-32768, 161,-32768,-32768, - 59, 43, 43, 43, 43, 43,-32768, 160,-32768, 43, --32768,-32768,-32768, 158,-32768, 103, 106, 111, 114, 119, --32768, 54, 43,-32768,-32768,-32768,-32768,-32768,-32768, 47, --32768, 185, 188,-32768 -}; - -static const short yypgoto[] = { -50, - 86,-32768,-32768, 98, -66, 7,-32768,-32768,-32768, -8, - 38, 102, -55, -48,-32768,-32768,-32768, 26,-32768,-32768, --32768,-32768, 164,-32768, 193,-32768,-32768, 155,-32768,-32768, --32768,-32768, -95, 65,-32768,-32768,-32768,-32768,-32768,-32768, --32768, -7, 157,-32768,-32768,-32768, 174,-32768 -}; - - -#define YYLAST 210 - - -static const short yytable[] = { 104, - 95, 75, 129, 24, 25, 13, 1, 2, 3, 4, - 48, 5, 1, 2, 3, 4, 2, 5, 68, 69, - 70, 71, 72, 73, 74, 27, 58, 25, 50, 108, - 19, 100, 49, 23, 21, 129, 59, 155, 39, 32, - 77, 123, 138, 139, 140, 141, 142, 36, 127, 101, - 78, 124, 146, 51, 125, 75, 157, 152, 143, 80, - 81, 82, 83, 84, 85, 86, 167, 87, 88, 161, - 62, 126, 89, 90, 158, 91, 124, 120, 92, 121, - 39, 122, 96, 45, 120, 46, 121, 191, 122, 120, - 51, 121, 168, 122, 56, 176, 177, 178, 179, 180, - 120, 57, 121, 182, 122, 63, 120, 162, 121, 66, - 122, 149, 150, 163, 99, 120, 190, 121, 98, 122, - 102, 120, 164, 121, 103, 122, 105, 120, 165, 121, - 106, 122, 107, 120, 166, 121, 120, 122, 121, 184, - 122, 120, 185, 121, 120, 122, 121, 186, 122, 120, - 187, 121, 109, 122, 118, 188, 1, 2, 3, 4, - 110, 5, 111, 112, 113, 114, 2, 132, 136, 133, - 134, 124, 144, 151, 153, 145, 154, 159, 173, 171, - 160, 170, 175, 181, 193, 172, 183, 194, 189, 119, - 174, 135, 117, 44, 17, 156, 35, 0, 0, 0, - 0, 0, 0, 0, 0, 67, 0, 0, 0, 79 -}; - -static const short yycheck[] = { 66, - 56, 52, 98, 11, 12, 23, 10, 11, 12, 13, - 16, 15, 10, 11, 12, 13, 11, 15, 3, 4, - 5, 6, 7, 8, 9, 39, 31, 35, 32, 78, - 23, 22, 38, 31, 23, 131, 41, 32, 23, 23, - 28, 28, 109, 110, 111, 112, 113, 27, 97, 40, - 38, 38, 119, 14, 15, 106, 22, 124, 114, 17, - 18, 19, 20, 21, 22, 23, 28, 25, 26, 136, - 45, 32, 30, 31, 40, 33, 38, 31, 36, 33, - 23, 35, 57, 39, 31, 31, 33, 41, 35, 31, - 14, 33, 39, 35, 27, 162, 163, 164, 165, 166, - 31, 38, 33, 170, 35, 22, 31, 38, 33, 29, - 35, 120, 121, 38, 41, 31, 183, 33, 31, 35, - 38, 31, 38, 33, 32, 35, 27, 31, 38, 33, - 27, 35, 23, 31, 38, 33, 31, 35, 33, 37, - 35, 31, 37, 33, 31, 35, 33, 37, 35, 31, - 37, 33, 36, 35, 23, 37, 10, 11, 12, 13, - 36, 15, 36, 36, 36, 27, 11, 22, 29, 22, - 22, 38, 32, 23, 23, 34, 41, 28, 34, 37, - 28, 38, 22, 24, 0, 32, 29, 0, 182, 92, - 153, 106, 91, 30, 2, 131, 23, -1, -1, -1, - -1, -1, -1, -1, -1, 49, -1, -1, -1, 55 -}; -/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison.simple" -/* This file comes from bison-1.28. */ - -/* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ - -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include -#endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible at ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ -#endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc -#endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY -2 -#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ -#define YYFAIL goto yyerrlab -#define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ - yychar1 = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -#ifndef YYPURE -#define YYLEX yylex() -#endif - -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif - -/* If nonreentrant, generate the variables here */ - -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ - -#ifndef YYINITDEPTH -#define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ - -#if YYMAXDEPTH == 0 -#undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 -#endif - -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#else /* __cplusplus */ - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) -{ - register char *t = to; - register char *f = from; - register int i = count; - - while (i-- > 0) - *t++ = *f++; -} - -#endif -#endif - -#line 217 "/usr/share/bison.simple" - -/* The user can define YYPARSE_PARAM as the name of an argument to be passed - into yyparse. The argument should have type void *. - It should actually point to an object. - Grammar actions can access the variable by casting it - to the proper pointer type. */ - -#ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ - -/* Prevent warning if -Wstrict-prototypes. */ -#ifdef __GNUC__ -#ifdef YYPARSE_PARAM -int yyparse (void *); -#else -int yyparse (void); -#endif -#endif - -int -yyparse(YYPARSE_PARAM_ARG) - YYPARSE_PARAM_DECL -{ - register int yystate; - register int yyn; - register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ - -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) -#else -#define YYPOPSTACK (yyvsp--, yyssp--) -#endif - - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; - -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ - - int yylen; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss - 1; - yyvsp = yyvs; -#ifdef YYLSP_NEEDED - yylsp = yyls; -#endif - -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; - - if (yyssp >= yyss + yystacksize - 1) - { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; - -#ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif -#else /* no yyoverflow */ - /* Extend the stack our own way. */ - if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } - yystacksize *= 2; - if (yystacksize > YYMAXDEPTH) - yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif -#endif /* no yyoverflow */ - - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; -#endif - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif - - if (yyssp >= yyss + yystacksize - 1) - YYABORT; - } - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif - - goto yybackup; - yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* yychar is either YYEMPTY or YYEOF - or a valid token in external form. */ - - if (yychar == YYEMPTY) - { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif - yychar = YYLEX; - } - - /* Convert token to internal form (in yychar1) for indexing tables with */ - - if (yychar <= 0) /* This means end of input. */ - { - yychar1 = 0; - yychar = YYEOF; /* Don't call YYLEX any more */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif - } - else - { - yychar1 = YYTRANSLATE(yychar); - -#if YYDEBUG != 0 - if (yydebug) - { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT - YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); - } -#endif - } - - yyn += yychar1; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) - goto yydefault; - - yyn = yytable[yyn]; - - /* yyn is what to do for this token type in this state. - Negative => reduce, -yyn is rule number. - Positive => shift, yyn is new state. - New state is final state => don't bother to shift, - just return success. - 0, or most negative number => error. */ - - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrlab; - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; - - yystate = yyn; - goto yynewstate; - -/* Do the default action for the current state. */ -yydefault: - - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - -/* Do a reduction. yyn is the number of a rule to reduce with. */ -yyreduce: - yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ - -#if YYDEBUG != 0 - if (yydebug) - { - int i; - - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); - - /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); - } -#endif - - - switch (yyn) { - -case 1: -#line 246 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (CurDefmPrefix) { - // If CurDefmPrefix is set, we're parsing a defm, which means that this is - // actually the name of a multiclass. - MultiClass *MC = MultiClasses[*yyvsp[0].StrVal]; - if (MC == 0) { - err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n"; - exit(1); - } - yyval.Rec = &MC->Rec; - } else { - yyval.Rec = Records.getClass(*yyvsp[0].StrVal); - } - if (yyval.Rec == 0) { - err() << "Couldn't find class '" << *yyvsp[0].StrVal << "'!\n"; - exit(1); - } - delete yyvsp[0].StrVal; - ; - break;} -case 2: -#line 268 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // string type - yyval.Ty = new StringRecTy(); - ; - break;} -case 3: -#line 270 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // bit type - yyval.Ty = new BitRecTy(); - ; - break;} -case 4: -#line 272 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // bits type - yyval.Ty = new BitsRecTy(yyvsp[-1].IntVal); - ; - break;} -case 5: -#line 274 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // int type - yyval.Ty = new IntRecTy(); - ; - break;} -case 6: -#line 276 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // list type - yyval.Ty = new ListRecTy(yyvsp[-1].Ty); - ; - break;} -case 7: -#line 278 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // code type - yyval.Ty = new CodeRecTy(); - ; - break;} -case 8: -#line 280 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // dag type - yyval.Ty = new DagRecTy(); - ; - break;} -case 9: -#line 282 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ // Record Type - yyval.Ty = new RecordRecTy(yyvsp[0].Rec); - ; - break;} -case 10: -#line 286 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.IntVal = 0; ; - break;} -case 11: -#line 286 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.IntVal = 1; ; - break;} -case 12: -#line 288 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.Initializer = 0; ; - break;} -case 13: -#line 288 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.Initializer = yyvsp[0].Initializer; ; - break;} -case 14: -#line 290 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (const RecordVal *RV = (CurRec ? CurRec->getValue(*yyvsp[0].StrVal) : 0)) { - yyval.Initializer = new VarInit(*yyvsp[0].StrVal, RV->getType()); - } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*yyvsp[0].StrVal)) { - const RecordVal *RV = CurRec->getValue(CurRec->getName()+":"+*yyvsp[0].StrVal); - assert(RV && "Template arg doesn't exist??"); - yyval.Initializer = new VarInit(CurRec->getName()+":"+*yyvsp[0].StrVal, RV->getType()); - } else if (CurMultiClass && - CurMultiClass->Rec.isTemplateArg(CurMultiClass->Rec.getName()+"::"+*yyvsp[0].StrVal)) { - std::string Name = CurMultiClass->Rec.getName()+"::"+*yyvsp[0].StrVal; - const RecordVal *RV = CurMultiClass->Rec.getValue(Name); - assert(RV && "Template arg doesn't exist??"); - yyval.Initializer = new VarInit(Name, RV->getType()); - } else if (Record *D = Records.getDef(*yyvsp[0].StrVal)) { - yyval.Initializer = new DefInit(D); - } else { - err() << "Variable not defined: '" << *yyvsp[0].StrVal << "'!\n"; - exit(1); - } - - delete yyvsp[0].StrVal; -; - break;} -case 15: -#line 313 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = yyvsp[0].Initializer; - ; - break;} -case 16: -#line 315 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new IntInit(yyvsp[0].IntVal); - ; - break;} -case 17: -#line 317 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new StringInit(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - ; - break;} -case 18: -#line 320 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new CodeInit(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - ; - break;} -case 19: -#line 323 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new UnsetInit(); - ; - break;} -case 20: -#line 325 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - BitsInit *Init = new BitsInit(yyvsp[-1].FieldList->size()); - for (unsigned i = 0, e = yyvsp[-1].FieldList->size(); i != e; ++i) { - struct Init *Bit = (*yyvsp[-1].FieldList)[i]->convertInitializerTo(new BitRecTy()); - if (Bit == 0) { - err() << "Element #" << i << " (" << *(*yyvsp[-1].FieldList)[i] - << ") is not convertable to a bit!\n"; - exit(1); - } - Init->setBit(yyvsp[-1].FieldList->size()-i-1, Bit); - } - yyval.Initializer = Init; - delete yyvsp[-1].FieldList; - ; - break;} -case 21: -#line 338 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - // This is a CLASS expression. This is supposed to synthesize - // a new anonymous definition, deriving from CLASS with no - // body. - Record *Class = Records.getClass(*yyvsp[-3].StrVal); - if (!Class) { - err() << "Expected a class, got '" << *yyvsp[-3].StrVal << "'!\n"; - exit(1); - } - delete yyvsp[-3].StrVal; - - static unsigned AnonCounter = 0; - Record *OldRec = CurRec; // Save CurRec. - - // Create the new record, set it as CurRec temporarily. - CurRec = new Record("anonymous.val."+utostr(AnonCounter++)); - addSubClass(Class, *yyvsp[-1].FieldList); // Add info about the subclass to CurRec. - delete yyvsp[-1].FieldList; // Free up the template args. - - CurRec->resolveReferences(); - - Records.addDef(CurRec); - - // The result of the expression is a reference to the new record. - yyval.Initializer = new DefInit(CurRec); - - // Restore the old CurRec - CurRec = OldRec; - ; - break;} -case 22: -#line 366 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = yyvsp[-3].Initializer->convertInitializerBitRange(*yyvsp[-1].BitList); - if (yyval.Initializer == 0) { - err() << "Invalid bit range for value '" << *yyvsp[-3].Initializer << "'!\n"; - exit(1); - } - delete yyvsp[-1].BitList; - ; - break;} -case 23: -#line 373 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new ListInit(*yyvsp[-1].FieldList); - delete yyvsp[-1].FieldList; - ; - break;} -case 24: -#line 376 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (!yyvsp[-2].Initializer->getFieldType(*yyvsp[0].StrVal)) { - err() << "Cannot access field '" << *yyvsp[0].StrVal << "' of value '" << *yyvsp[-2].Initializer << "!\n"; - exit(1); - } - yyval.Initializer = new FieldInit(yyvsp[-2].Initializer, *yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - ; - break;} -case 25: -#line 383 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = new DagInit(yyvsp[-2].Initializer, *yyvsp[-1].DagValueList); - delete yyvsp[-1].DagValueList; - ; - break;} -case 26: -#line 386 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - std::reverse(yyvsp[-1].BitList->begin(), yyvsp[-1].BitList->end()); - yyval.Initializer = yyvsp[-3].Initializer->convertInitListSlice(*yyvsp[-1].BitList); - if (yyval.Initializer == 0) { - err() << "Invalid list slice for value '" << *yyvsp[-3].Initializer << "'!\n"; - exit(1); - } - delete yyvsp[-1].BitList; - ; - break;} -case 27: -#line 394 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = (new BinOpInit(BinOpInit::CONCAT, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold(); - ; - break;} -case 28: -#line 396 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = (new BinOpInit(BinOpInit::SHL, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold(); - ; - break;} -case 29: -#line 398 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = (new BinOpInit(BinOpInit::SRA, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold(); - ; - break;} -case 30: -#line 400 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = (new BinOpInit(BinOpInit::SRL, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold(); - ; - break;} -case 31: -#line 402 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Initializer = (new BinOpInit(BinOpInit::STRCONCAT, yyvsp[-3].Initializer, yyvsp[-1].Initializer))->Fold(); - ; - break;} -case 32: -#line 406 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.StrVal = new std::string(); - ; - break;} -case 33: -#line 409 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.StrVal = yyvsp[0].StrVal; - ; - break;} -case 34: -#line 413 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.DagValueList = new std::vector >(); - yyval.DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); - delete yyvsp[0].StrVal; - ; - break;} -case 35: -#line 418 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyvsp[-3].DagValueList->push_back(std::make_pair(yyvsp[-1].Initializer, *yyvsp[0].StrVal)); - delete yyvsp[0].StrVal; - yyval.DagValueList = yyvsp[-3].DagValueList; - ; - break;} -case 36: -#line 424 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.DagValueList = new std::vector >(); - ; - break;} -case 37: -#line 427 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.DagValueList = yyvsp[0].DagValueList; ; - break;} -case 38: -#line 430 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.BitList = new std::vector(); - yyval.BitList->push_back(yyvsp[0].IntVal); - ; - break;} -case 39: -#line 433 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { - err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; - exit(1); - } - yyval.BitList = new std::vector(); - if (yyvsp[-2].IntVal < yyvsp[0].IntVal) { - for (int i = yyvsp[-2].IntVal; i <= yyvsp[0].IntVal; ++i) - yyval.BitList->push_back(i); - } else { - for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) - yyval.BitList->push_back(i); - } - ; - break;} -case 40: -#line 446 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyvsp[0].IntVal = -yyvsp[0].IntVal; - if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { - err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; - exit(1); - } - yyval.BitList = new std::vector(); - if (yyvsp[-1].IntVal < yyvsp[0].IntVal) { - for (int i = yyvsp[-1].IntVal; i <= yyvsp[0].IntVal; ++i) - yyval.BitList->push_back(i); - } else { - for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) - yyval.BitList->push_back(i); - } - ; - break;} -case 41: -#line 460 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - (yyval.BitList=yyvsp[-2].BitList)->push_back(yyvsp[0].IntVal); - ; - break;} -case 42: -#line 462 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (yyvsp[-2].IntVal < 0 || yyvsp[0].IntVal < 0) { - err() << "Invalid range: " << yyvsp[-2].IntVal << "-" << yyvsp[0].IntVal << "!\n"; - exit(1); - } - yyval.BitList = yyvsp[-4].BitList; - if (yyvsp[-2].IntVal < yyvsp[0].IntVal) { - for (int i = yyvsp[-2].IntVal; i <= yyvsp[0].IntVal; ++i) - yyval.BitList->push_back(i); - } else { - for (int i = yyvsp[-2].IntVal; i >= yyvsp[0].IntVal; --i) - yyval.BitList->push_back(i); - } - ; - break;} -case 43: -#line 475 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyvsp[0].IntVal = -yyvsp[0].IntVal; - if (yyvsp[-1].IntVal < 0 || yyvsp[0].IntVal < 0) { - err() << "Invalid range: " << yyvsp[-1].IntVal << "-" << yyvsp[0].IntVal << "!\n"; - exit(1); - } - yyval.BitList = yyvsp[-3].BitList; - if (yyvsp[-1].IntVal < yyvsp[0].IntVal) { - for (int i = yyvsp[-1].IntVal; i <= yyvsp[0].IntVal; ++i) - yyval.BitList->push_back(i); - } else { - for (int i = yyvsp[-1].IntVal; i >= yyvsp[0].IntVal; --i) - yyval.BitList->push_back(i); - } - ; - break;} -case 44: -#line 491 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.BitList = yyvsp[0].BitList; std::reverse(yyvsp[0].BitList->begin(), yyvsp[0].BitList->end()); ; - break;} -case 45: -#line 493 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.BitList = 0; ; - break;} -case 46: -#line 493 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.BitList = yyvsp[-1].BitList; ; - break;} -case 47: -#line 497 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.FieldList = new std::vector(); - ; - break;} -case 48: -#line 499 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.FieldList = yyvsp[0].FieldList; - ; - break;} -case 49: -#line 503 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.FieldList = new std::vector(); - yyval.FieldList->push_back(yyvsp[0].Initializer); - ; - break;} -case 50: -#line 506 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - (yyval.FieldList = yyvsp[-2].FieldList)->push_back(yyvsp[0].Initializer); - ; - break;} -case 51: -#line 510 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - std::string DecName = *yyvsp[-1].StrVal; - if (ParsingTemplateArgs) { - if (CurRec) { - DecName = CurRec->getName() + ":" + DecName; - } else { - assert(CurMultiClass); - } - if (CurMultiClass) - DecName = CurMultiClass->Rec.getName() + "::" + DecName; - } - - addValue(RecordVal(DecName, yyvsp[-2].Ty, yyvsp[-3].IntVal)); - setValue(DecName, 0, yyvsp[0].Initializer); - yyval.StrVal = new std::string(DecName); -; - break;} -case 52: -#line 527 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - delete yyvsp[-1].StrVal; -; - break;} -case 53: -#line 529 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - setValue(*yyvsp[-4].StrVal, yyvsp[-3].BitList, yyvsp[-1].Initializer); - delete yyvsp[-4].StrVal; - delete yyvsp[-3].BitList; -; - break;} -case 58: -#line 538 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.SubClassRef = new SubClassRefTy(yyvsp[0].Rec, new std::vector()); - ; - break;} -case 59: -#line 540 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.SubClassRef = new SubClassRefTy(yyvsp[-3].Rec, yyvsp[-1].FieldList); - ; - break;} -case 60: -#line 544 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.SubClassList = new std::vector(); - yyval.SubClassList->push_back(*yyvsp[0].SubClassRef); - delete yyvsp[0].SubClassRef; - ; - break;} -case 61: -#line 549 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - (yyval.SubClassList=yyvsp[-2].SubClassList)->push_back(*yyvsp[0].SubClassRef); - delete yyvsp[0].SubClassRef; - ; - break;} -case 62: -#line 554 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.SubClassList = new std::vector(); - ; - break;} -case 63: -#line 557 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.SubClassList = yyvsp[0].SubClassList; - ; - break;} -case 64: -#line 561 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - getActiveRec()->addTemplateArg(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; -; - break;} -case 65: -#line 564 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - getActiveRec()->addTemplateArg(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; -; - break;} -case 66: -#line 569 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} -case 69: -#line 572 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.StrVal = yyvsp[0].StrVal; ; - break;} -case 70: -#line 572 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ yyval.StrVal = new std::string(); ; - break;} -case 71: -#line 574 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - static unsigned AnonCounter = 0; - if (yyvsp[0].StrVal->empty()) - *yyvsp[0].StrVal = "anonymous."+utostr(AnonCounter++); - yyval.StrVal = yyvsp[0].StrVal; -; - break;} -case 72: -#line 581 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - // If a class of this name already exists, it must be a forward ref. - if ((CurRec = Records.getClass(*yyvsp[0].StrVal))) { - // If the body was previously defined, this is an error. - if (!CurRec->getValues().empty() || - !CurRec->getSuperClasses().empty() || - !CurRec->getTemplateArgs().empty()) { - err() << "Class '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - } else { - // If this is the first reference to this class, create and add it. - CurRec = new Record(*yyvsp[0].StrVal); - Records.addClass(CurRec); - } - delete yyvsp[0].StrVal; -; - break;} -case 73: -#line 599 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - CurRec = new Record(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; - - if (!CurMultiClass) { - // Top-level def definition. - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - Records.addDef(CurRec); - } else { - // Otherwise, a def inside a multiclass, add it to the multiclass. - for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) - if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) { - err() << "def '" << CurRec->getName() - << "' already defined in this multiclass!\n"; - exit(1); - } - CurMultiClass->DefPrototypes.push_back(CurRec); - } -; - break;} -case 74: -#line 624 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - for (unsigned i = 0, e = yyvsp[0].SubClassList->size(); i != e; ++i) { - addSubClass((*yyvsp[0].SubClassList)[i].first, *(*yyvsp[0].SubClassList)[i].second); - // Delete the template arg values for the class - delete (*yyvsp[0].SubClassList)[i].second; - } - delete yyvsp[0].SubClassList; // Delete the class list. - - // Process any variables on the let stack. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - ; - break;} -case 75: -#line 638 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Rec = CurRec; - CurRec = 0; - ; - break;} -case 76: -#line 643 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - ParsingTemplateArgs = true; - ; - break;} -case 77: -#line 645 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - ParsingTemplateArgs = false; - ; - break;} -case 78: -#line 647 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Rec = yyvsp[0].Rec; - ; - break;} -case 79: -#line 651 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - if (CurMultiClass == 0) // Def's in multiclasses aren't really defs. - yyvsp[0].Rec->resolveReferences(); - - // If ObjectBody has template arguments, it's an error. - assert(yyvsp[0].Rec->getTemplateArgs().empty() && "How'd this get template args?"); - yyval.Rec = yyvsp[0].Rec; -; - break;} -case 80: -#line 661 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.Rec = yyvsp[0].Rec; - // Copy the template arguments for the multiclass into the def. - const std::vector &TArgs = CurMultiClass->Rec.getTemplateArgs(); - - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]); - assert(RV && "Template arg doesn't exist?"); - yyval.Rec->addValue(*RV); - } -; - break;} -case 81: -#line 675 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.RecList = new std::vector(); - yyval.RecList->push_back(yyvsp[0].Rec); -; - break;} -case 82: -#line 678 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - yyval.RecList->push_back(yyvsp[0].Rec); -; - break;} -case 83: -#line 682 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - MultiClass *&MCE = MultiClasses[*yyvsp[0].StrVal]; - if (MCE) { - err() << "multiclass '" << *yyvsp[0].StrVal << "' already defined!\n"; - exit(1); - } - MCE = CurMultiClass = new MultiClass(*yyvsp[0].StrVal); - delete yyvsp[0].StrVal; -; - break;} -case 84: -#line 693 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - ParsingTemplateArgs = true; - ; - break;} -case 85: -#line 695 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - ParsingTemplateArgs = false; - ; - break;} -case 86: -#line 697 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - CurMultiClass = 0; -; - break;} -case 87: -#line 702 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ CurDefmPrefix = yyvsp[0].StrVal; ; - break;} -case 88: -#line 702 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - // To instantiate a multiclass, we need to first get the multiclass, then - // instantiate each def contained in the multiclass with the SubClassRef - // template parameters. - MultiClass *MC = MultiClasses[yyvsp[-1].SubClassRef->first->getName()]; - assert(MC && "Didn't lookup multiclass correctly?"); - std::vector &TemplateVals = *yyvsp[-1].SubClassRef->second; - delete yyvsp[-1].SubClassRef; - - // Verify that the correct number of template arguments were specified. - const std::vector &TArgs = MC->Rec.getTemplateArgs(); - if (TArgs.size() < TemplateVals.size()) { - err() << "ERROR: More template args specified than multiclass expects!\n"; - exit(1); - } - - // Loop over all the def's in the multiclass, instantiating each one. - for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { - Record *DefProto = MC->DefPrototypes[i]; - - // Add the suffix to the defm name to get the new name. - assert(CurRec == 0 && "A def is current?"); - CurRec = new Record(*yyvsp[-4].StrVal + DefProto->getName()); - - addSubClass(DefProto, std::vector()); - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateVals.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateVals[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of multiclassclass '" - << MC->Rec.getName() << "'!\n"; - exit(1); - } - } - - // If the mdef is inside a 'let' expression, add to each def. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined, " - << "instantiating defm '" << *yyvsp[-4].StrVal << "' with subdef '" - << DefProto->getName() << "'!\n"; - exit(1); - } - Records.addDef(CurRec); - - CurRec->resolveReferences(); - - CurRec = 0; - } - - delete &TemplateVals; - delete yyvsp[-4].StrVal; - CurDefmPrefix = 0; -; - break;} -case 89: -#line 776 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} -case 90: -#line 776 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} -case 93: -#line 779 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - LetStack.back().push_back(LetRecord(*yyvsp[-3].StrVal, yyvsp[-2].BitList, yyvsp[0].Initializer)); - delete yyvsp[-3].StrVal; delete yyvsp[-2].BitList; -; - break;} -case 96: -#line 787 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ LetStack.push_back(std::vector()); ; - break;} -case 98: -#line 790 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - LetStack.pop_back(); - ; - break;} -case 99: -#line 793 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{ - LetStack.pop_back(); - ; - break;} -case 100: -#line 797 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} -case 101: -#line 797 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" -{; - break;} -} - /* the action file gets copied in in place of this dollarsign */ -#line 543 "/usr/share/bison.simple" - - yyvsp -= yylen; - yyssp -= yylen; -#ifdef YYLSP_NEEDED - yylsp -= yylen; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - - *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } -#endif - - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTBASE] + *yyssp; - if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTBASE]; - - goto yynewstate; - -yyerrlab: /* here on detecting error */ - - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ - { - ++yynerrs; - -#ifdef YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (yyn > YYFLAG && yyn < YYLAST) - { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) - { - strcpy(msg, "parse error"); - - if (count < 5) - { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; - } - } - yyerror(msg); - free(msg); - } - else - yyerror ("parse error; also virtual memory exceeded"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); - } - - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ - - if (yyerrstatus == 3) - { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ - - /* return failure if at end of input */ - if (yychar == YYEOF) - YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - - yychar = YYEMPTY; - } - - /* Else will try to reuse lookahead token - after shifting the error token. */ - - yyerrstatus = 3; /* Each real token shifted decrements this */ - - goto yyerrhandle; - -yyerrdefault: /* current state does not do anything special for the error token. */ - -#if 0 - /* This is wrong; only states that explicitly want error tokens - should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; -#endif - -yyerrpop: /* pop the current state because it cannot handle the error token */ - - if (yyssp == yyss) YYABORT; - yyvsp--; - yystate = *--yyssp; -#ifdef YYLSP_NEEDED - yylsp--; -#endif - -#if YYDEBUG != 0 - if (yydebug) - { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); - } -#endif - -yyerrhandle: - - yyn = yypact[yystate]; - if (yyn == YYFLAG) - goto yyerrdefault; - - yyn += YYTERROR; - if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) - goto yyerrdefault; - - yyn = yytable[yyn]; - if (yyn < 0) - { - if (yyn == YYFLAG) - goto yyerrpop; - yyn = -yyn; - goto yyreduce; - } - else if (yyn == 0) - goto yyerrpop; - - if (yyn == YYFINAL) - YYACCEPT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif - - *++yyvsp = yylval; -#ifdef YYLSP_NEEDED - *++yylsp = yylloc; -#endif - - yystate = yyn; - goto yynewstate; - - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 1; -} -#line 801 "/Volumes/ProjectsDisk/cvs/llvm/utils/TableGen/FileParser.y" - - -int yyerror(const char *ErrorMsg) { - err() << "Error parsing: " << ErrorMsg << "\n"; - exit(1); -} Removed: llvm/trunk/utils/TableGen/FileParser.h.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FileParser.h.cvs?rev=44273&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/FileParser.h.cvs (original) +++ llvm/trunk/utils/TableGen/FileParser.h.cvs (removed) @@ -1,40 +0,0 @@ -typedef union { - std::string* StrVal; - int IntVal; - llvm::RecTy* Ty; - llvm::Init* Initializer; - std::vector* FieldList; - std::vector* BitList; - llvm::Record* Rec; - std::vector* RecList; - SubClassRefTy* SubClassRef; - std::vector* SubClassList; - std::vector >* DagValueList; -} YYSTYPE; -#define INT 257 -#define BIT 258 -#define STRING 259 -#define BITS 260 -#define LIST 261 -#define CODE 262 -#define DAG 263 -#define CLASS 264 -#define DEF 265 -#define MULTICLASS 266 -#define DEFM 267 -#define FIELD 268 -#define LET 269 -#define IN 270 -#define CONCATTOK 271 -#define SHLTOK 272 -#define SRATOK 273 -#define SRLTOK 274 -#define STRCONCATTOK 275 -#define INTVAL 276 -#define ID 277 -#define VARNAME 278 -#define STRVAL 279 -#define CODEFRAGMENT 280 - - -extern YYSTYPE Filelval; Removed: llvm/trunk/utils/TableGen/FileParser.y URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FileParser.y?rev=44273&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/FileParser.y (original) +++ llvm/trunk/utils/TableGen/FileParser.y (removed) @@ -1,806 +0,0 @@ -//===-- FileParser.y - Parser for TableGen files ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the bison parser for Table Generator files... -// -//===----------------------------------------------------------------------===// - -%{ -#include "Record.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Streams.h" -#include -#include -#define YYERROR_VERBOSE 1 - -int yyerror(const char *ErrorMsg); -int yylex(); - -namespace llvm { - struct MultiClass { - Record Rec; // Placeholder for template args and Name. - std::vector DefPrototypes; - - MultiClass(const std::string &Name) : Rec(Name) {} - }; - - -static std::map MultiClasses; - -extern int Filelineno; -static MultiClass *CurMultiClass = 0; // Set while parsing a multiclass. -static std::string *CurDefmPrefix = 0; // Set while parsing defm. -static Record *CurRec = 0; -static bool ParsingTemplateArgs = false; - -typedef std::pair*> SubClassRefTy; - -struct LetRecord { - std::string Name; - std::vector Bits; - Init *Value; - bool HasBits; - LetRecord(const std::string &N, std::vector *B, Init *V) - : Name(N), Value(V), HasBits(B != 0) { - if (HasBits) Bits = *B; - } -}; - -static std::vector > LetStack; - - -extern std::ostream &err(); - -/// getActiveRec - If inside a def/class definition, return the def/class. -/// Otherwise, if within a multidef, return it. -static Record *getActiveRec() { - return CurRec ? CurRec : &CurMultiClass->Rec; -} - -static void addValue(const RecordVal &RV) { - Record *TheRec = getActiveRec(); - - if (RecordVal *ERV = TheRec->getValue(RV.getName())) { - // The value already exists in the class, treat this as a set... - if (ERV->setValue(RV.getValue())) { - err() << "New definition of '" << RV.getName() << "' of type '" - << *RV.getType() << "' is incompatible with previous " - << "definition of type '" << *ERV->getType() << "'!\n"; - exit(1); - } - } else { - TheRec->addValue(RV); - } -} - -static void addSuperClass(Record *SC) { - if (CurRec->isSubClassOf(SC)) { - err() << "Already subclass of '" << SC->getName() << "'!\n"; - exit(1); - } - CurRec->addSuperClass(SC); -} - -static void setValue(const std::string &ValName, - std::vector *BitList, Init *V) { - if (!V) return; - - Record *TheRec = getActiveRec(); - RecordVal *RV = TheRec->getValue(ValName); - if (RV == 0) { - err() << "Value '" << ValName << "' unknown!\n"; - exit(1); - } - - // Do not allow assignments like 'X = X'. This will just cause infinite loops - // in the resolution machinery. - if (!BitList) - if (VarInit *VI = dynamic_cast(V)) - if (VI->getName() == ValName) - return; - - // If we are assigning to a subset of the bits in the value... then we must be - // assigning to a field of BitsRecTy, which must have a BitsInit - // initializer... - // - if (BitList) { - BitsInit *CurVal = dynamic_cast(RV->getValue()); - if (CurVal == 0) { - err() << "Value '" << ValName << "' is not a bits type!\n"; - exit(1); - } - - // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->convertInitializerTo(new BitsRecTy(BitList->size())); - if (BI == 0) { - V->convertInitializerTo(new BitsRecTy(BitList->size())); - err() << "Initializer '" << *V << "' not compatible with bit range!\n"; - exit(1); - } - - // We should have a BitsInit type now... - assert(dynamic_cast(BI) != 0 || (cerr << *BI).stream() == 0); - BitsInit *BInit = (BitsInit*)BI; - - BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); - - // Loop over bits, assigning values as appropriate... - for (unsigned i = 0, e = BitList->size(); i != e; ++i) { - unsigned Bit = (*BitList)[i]; - if (NewVal->getBit(Bit)) { - err() << "Cannot set bit #" << Bit << " of value '" << ValName - << "' more than once!\n"; - exit(1); - } - NewVal->setBit(Bit, BInit->getBit(i)); - } - - for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) - if (NewVal->getBit(i) == 0) - NewVal->setBit(i, CurVal->getBit(i)); - - V = NewVal; - } - - if (RV->setValue(V)) { - err() << "Value '" << ValName << "' of type '" << *RV->getType() - << "' is incompatible with initializer '" << *V << "'!\n"; - exit(1); - } -} - -// addSubClass - Add SC as a subclass to CurRec, resolving TemplateArgs as SC's -// template arguments. -static void addSubClass(Record *SC, const std::vector &TemplateArgs) { - // Add all of the values in the subclass into the current class... - const std::vector &Vals = SC->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - addValue(Vals[i]); - - const std::vector &TArgs = SC->getTemplateArgs(); - - // Ensure that an appropriate number of template arguments are specified... - if (TArgs.size() < TemplateArgs.size()) { - err() << "ERROR: More template args specified than expected!\n"; - exit(1); - } - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateArgs.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateArgs[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() - << "'!\n"; - exit(1); - } - } - - // Since everything went well, we can now set the "superclass" list for the - // current record. - const std::vector &SCs = SC->getSuperClasses(); - for (unsigned i = 0, e = SCs.size(); i != e; ++i) - addSuperClass(SCs[i]); - addSuperClass(SC); -} - -} // End llvm namespace - -using namespace llvm; - -%} - -%union { - std::string* StrVal; - int IntVal; - llvm::RecTy* Ty; - llvm::Init* Initializer; - std::vector* FieldList; - std::vector* BitList; - llvm::Record* Rec; - std::vector* RecList; - SubClassRefTy* SubClassRef; - std::vector* SubClassList; - std::vector >* DagValueList; -}; - -%token INT BIT STRING BITS LIST CODE DAG CLASS DEF MULTICLASS DEFM FIELD LET IN -%token CONCATTOK SHLTOK SRATOK SRLTOK STRCONCATTOK -%token INTVAL -%token ID VARNAME STRVAL CODEFRAGMENT - -%type Type -%type ClassInst DefInst MultiClassDef ObjectBody ClassID -%type MultiClassBody - -%type SubClassRef -%type ClassList ClassListNE -%type OptPrefix -%type Value OptValue IDValue -%type DagArgList DagArgListNE -%type ValueList ValueListNE -%type BitList OptBitList RBitList -%type Declaration OptID OptVarName ObjectName - -%start File - -%% - -ClassID : ID { - if (CurDefmPrefix) { - // If CurDefmPrefix is set, we're parsing a defm, which means that this is - // actually the name of a multiclass. - MultiClass *MC = MultiClasses[*$1]; - if (MC == 0) { - err() << "Couldn't find class '" << *$1 << "'!\n"; - exit(1); - } - $$ = &MC->Rec; - } else { - $$ = Records.getClass(*$1); - } - if ($$ == 0) { - err() << "Couldn't find class '" << *$1 << "'!\n"; - exit(1); - } - delete $1; - }; - - -// TableGen types... -Type : STRING { // string type - $$ = new StringRecTy(); - } | BIT { // bit type - $$ = new BitRecTy(); - } | BITS '<' INTVAL '>' { // bits type - $$ = new BitsRecTy($3); - } | INT { // int type - $$ = new IntRecTy(); - } | LIST '<' Type '>' { // list type - $$ = new ListRecTy($3); - } | CODE { // code type - $$ = new CodeRecTy(); - } | DAG { // dag type - $$ = new DagRecTy(); - } | ClassID { // Record Type - $$ = new RecordRecTy($1); - }; - -OptPrefix : /*empty*/ { $$ = 0; } | FIELD { $$ = 1; }; - -OptValue : /*empty*/ { $$ = 0; } | '=' Value { $$ = $2; }; - -IDValue : ID { - if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) { - $$ = new VarInit(*$1, RV->getType()); - } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*$1)) { - const RecordVal *RV = CurRec->getValue(CurRec->getName()+":"+*$1); - assert(RV && "Template arg doesn't exist??"); - $$ = new VarInit(CurRec->getName()+":"+*$1, RV->getType()); - } else if (CurMultiClass && - CurMultiClass->Rec.isTemplateArg(CurMultiClass->Rec.getName()+"::"+*$1)) { - std::string Name = CurMultiClass->Rec.getName()+"::"+*$1; - const RecordVal *RV = CurMultiClass->Rec.getValue(Name); - assert(RV && "Template arg doesn't exist??"); - $$ = new VarInit(Name, RV->getType()); - } else if (Record *D = Records.getDef(*$1)) { - $$ = new DefInit(D); - } else { - err() << "Variable not defined: '" << *$1 << "'!\n"; - exit(1); - } - - delete $1; -}; - -Value : IDValue { - $$ = $1; - } | INTVAL { - $$ = new IntInit($1); - } | STRVAL { - $$ = new StringInit(*$1); - delete $1; - } | CODEFRAGMENT { - $$ = new CodeInit(*$1); - delete $1; - } | '?' { - $$ = new UnsetInit(); - } | '{' ValueList '}' { - BitsInit *Init = new BitsInit($2->size()); - for (unsigned i = 0, e = $2->size(); i != e; ++i) { - struct Init *Bit = (*$2)[i]->convertInitializerTo(new BitRecTy()); - if (Bit == 0) { - err() << "Element #" << i << " (" << *(*$2)[i] - << ") is not convertable to a bit!\n"; - exit(1); - } - Init->setBit($2->size()-i-1, Bit); - } - $$ = Init; - delete $2; - } | ID '<' ValueListNE '>' { - // This is a CLASS expression. This is supposed to synthesize - // a new anonymous definition, deriving from CLASS with no - // body. - Record *Class = Records.getClass(*$1); - if (!Class) { - err() << "Expected a class, got '" << *$1 << "'!\n"; - exit(1); - } - delete $1; - - static unsigned AnonCounter = 0; - Record *OldRec = CurRec; // Save CurRec. - - // Create the new record, set it as CurRec temporarily. - CurRec = new Record("anonymous.val."+utostr(AnonCounter++)); - addSubClass(Class, *$3); // Add info about the subclass to CurRec. - delete $3; // Free up the template args. - - CurRec->resolveReferences(); - - Records.addDef(CurRec); - - // The result of the expression is a reference to the new record. - $$ = new DefInit(CurRec); - - // Restore the old CurRec - CurRec = OldRec; - } | Value '{' BitList '}' { - $$ = $1->convertInitializerBitRange(*$3); - if ($$ == 0) { - err() << "Invalid bit range for value '" << *$1 << "'!\n"; - exit(1); - } - delete $3; - } | '[' ValueList ']' { - $$ = new ListInit(*$2); - delete $2; - } | Value '.' ID { - if (!$1->getFieldType(*$3)) { - err() << "Cannot access field '" << *$3 << "' of value '" << *$1 << "!\n"; - exit(1); - } - $$ = new FieldInit($1, *$3); - delete $3; - } | '(' IDValue DagArgList ')' { - $$ = new DagInit($2, *$3); - delete $3; - } | Value '[' BitList ']' { - std::reverse($3->begin(), $3->end()); - $$ = $1->convertInitListSlice(*$3); - if ($$ == 0) { - err() << "Invalid list slice for value '" << *$1 << "'!\n"; - exit(1); - } - delete $3; - } | CONCATTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::CONCAT, $3, $5))->Fold(); - } | SHLTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SHL, $3, $5))->Fold(); - } | SRATOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SRA, $3, $5))->Fold(); - } | SRLTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SRL, $3, $5))->Fold(); - } | STRCONCATTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::STRCONCAT, $3, $5))->Fold(); - }; - -OptVarName : /* empty */ { - $$ = new std::string(); - } - | ':' VARNAME { - $$ = $2; - }; - -DagArgListNE : Value OptVarName { - $$ = new std::vector >(); - $$->push_back(std::make_pair($1, *$2)); - delete $2; - } - | DagArgListNE ',' Value OptVarName { - $1->push_back(std::make_pair($3, *$4)); - delete $4; - $$ = $1; - }; - -DagArgList : /*empty*/ { - $$ = new std::vector >(); - } - | DagArgListNE { $$ = $1; }; - - -RBitList : INTVAL { - $$ = new std::vector(); - $$->push_back($1); - } | INTVAL '-' INTVAL { - if ($1 < 0 || $3 < 0) { - err() << "Invalid range: " << $1 << "-" << $3 << "!\n"; - exit(1); - } - $$ = new std::vector(); - if ($1 < $3) { - for (int i = $1; i <= $3; ++i) - $$->push_back(i); - } else { - for (int i = $1; i >= $3; --i) - $$->push_back(i); - } - } | INTVAL INTVAL { - $2 = -$2; - if ($1 < 0 || $2 < 0) { - err() << "Invalid range: " << $1 << "-" << $2 << "!\n"; - exit(1); - } - $$ = new std::vector(); - if ($1 < $2) { - for (int i = $1; i <= $2; ++i) - $$->push_back(i); - } else { - for (int i = $1; i >= $2; --i) - $$->push_back(i); - } - } | RBitList ',' INTVAL { - ($$=$1)->push_back($3); - } | RBitList ',' INTVAL '-' INTVAL { - if ($3 < 0 || $5 < 0) { - err() << "Invalid range: " << $3 << "-" << $5 << "!\n"; - exit(1); - } - $$ = $1; - if ($3 < $5) { - for (int i = $3; i <= $5; ++i) - $$->push_back(i); - } else { - for (int i = $3; i >= $5; --i) - $$->push_back(i); - } - } | RBitList ',' INTVAL INTVAL { - $4 = -$4; - if ($3 < 0 || $4 < 0) { - err() << "Invalid range: " << $3 << "-" << $4 << "!\n"; - exit(1); - } - $$ = $1; - if ($3 < $4) { - for (int i = $3; i <= $4; ++i) - $$->push_back(i); - } else { - for (int i = $3; i >= $4; --i) - $$->push_back(i); - } - }; - -BitList : RBitList { $$ = $1; std::reverse($1->begin(), $1->end()); }; - -OptBitList : /*empty*/ { $$ = 0; } | '{' BitList '}' { $$ = $2; }; - - - -ValueList : /*empty*/ { - $$ = new std::vector(); - } | ValueListNE { - $$ = $1; - }; - -ValueListNE : Value { - $$ = new std::vector(); - $$->push_back($1); - } | ValueListNE ',' Value { - ($$ = $1)->push_back($3); - }; - -Declaration : OptPrefix Type ID OptValue { - std::string DecName = *$3; - if (ParsingTemplateArgs) { - if (CurRec) { - DecName = CurRec->getName() + ":" + DecName; - } else { - assert(CurMultiClass); - } - if (CurMultiClass) - DecName = CurMultiClass->Rec.getName() + "::" + DecName; - } - - addValue(RecordVal(DecName, $2, $1)); - setValue(DecName, 0, $4); - $$ = new std::string(DecName); -}; - -BodyItem : Declaration ';' { - delete $1; -} | LET ID OptBitList '=' Value ';' { - setValue(*$2, $3, $5); - delete $2; - delete $3; -}; - -BodyList : /*empty*/ | BodyList BodyItem; -Body : ';' | '{' BodyList '}'; - -SubClassRef : ClassID { - $$ = new SubClassRefTy($1, new std::vector()); - } | ClassID '<' ValueListNE '>' { - $$ = new SubClassRefTy($1, $3); - }; - -ClassListNE : SubClassRef { - $$ = new std::vector(); - $$->push_back(*$1); - delete $1; - } - | ClassListNE ',' SubClassRef { - ($$=$1)->push_back(*$3); - delete $3; - }; - -ClassList : /*empty */ { - $$ = new std::vector(); - } - | ':' ClassListNE { - $$ = $2; - }; - -DeclListNE : Declaration { - getActiveRec()->addTemplateArg(*$1); - delete $1; -} | DeclListNE ',' Declaration { - getActiveRec()->addTemplateArg(*$3); - delete $3; -}; - -TemplateArgList : '<' DeclListNE '>' {}; -OptTemplateArgList : /*empty*/ | TemplateArgList; - -OptID : ID { $$ = $1; } | /*empty*/ { $$ = new std::string(); }; - -ObjectName : OptID { - static unsigned AnonCounter = 0; - if ($1->empty()) - *$1 = "anonymous."+utostr(AnonCounter++); - $$ = $1; -}; - -ClassName : ObjectName { - // If a class of this name already exists, it must be a forward ref. - if ((CurRec = Records.getClass(*$1))) { - // If the body was previously defined, this is an error. - if (!CurRec->getValues().empty() || - !CurRec->getSuperClasses().empty() || - !CurRec->getTemplateArgs().empty()) { - err() << "Class '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - } else { - // If this is the first reference to this class, create and add it. - CurRec = new Record(*$1); - Records.addClass(CurRec); - } - delete $1; -}; - -DefName : ObjectName { - CurRec = new Record(*$1); - delete $1; - - if (!CurMultiClass) { - // Top-level def definition. - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - Records.addDef(CurRec); - } else { - // Otherwise, a def inside a multiclass, add it to the multiclass. - for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) - if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) { - err() << "def '" << CurRec->getName() - << "' already defined in this multiclass!\n"; - exit(1); - } - CurMultiClass->DefPrototypes.push_back(CurRec); - } -}; - -ObjectBody : ClassList { - for (unsigned i = 0, e = $1->size(); i != e; ++i) { - addSubClass((*$1)[i].first, *(*$1)[i].second); - // Delete the template arg values for the class - delete (*$1)[i].second; - } - delete $1; // Delete the class list. - - // Process any variables on the let stack. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - } Body { - $$ = CurRec; - CurRec = 0; - }; - -ClassInst : CLASS ClassName { - ParsingTemplateArgs = true; - } OptTemplateArgList { - ParsingTemplateArgs = false; - } ObjectBody { - $$ = $6; - }; - -DefInst : DEF DefName ObjectBody { - if (CurMultiClass == 0) // Def's in multiclasses aren't really defs. - $3->resolveReferences(); - - // If ObjectBody has template arguments, it's an error. - assert($3->getTemplateArgs().empty() && "How'd this get template args?"); - $$ = $3; -}; - -// MultiClassDef - A def instance specified inside a multiclass. -MultiClassDef : DefInst { - $$ = $1; - // Copy the template arguments for the multiclass into the def. - const std::vector &TArgs = CurMultiClass->Rec.getTemplateArgs(); - - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]); - assert(RV && "Template arg doesn't exist?"); - $$->addValue(*RV); - } -}; - -// MultiClassBody - Sequence of def's that are instantiated when a multiclass is -// used. -MultiClassBody : MultiClassDef { - $$ = new std::vector(); - $$->push_back($1); -} | MultiClassBody MultiClassDef { - $$->push_back($2); -}; - -MultiClassName : ID { - MultiClass *&MCE = MultiClasses[*$1]; - if (MCE) { - err() << "multiclass '" << *$1 << "' already defined!\n"; - exit(1); - } - MCE = CurMultiClass = new MultiClass(*$1); - delete $1; -}; - -// MultiClass - Multiple definitions. -MultiClassInst : MULTICLASS MultiClassName { - ParsingTemplateArgs = true; - } OptTemplateArgList { - ParsingTemplateArgs = false; - }'{' MultiClassBody '}' { - CurMultiClass = 0; -}; - -// DefMInst - Instantiate a multiclass. -DefMInst : DEFM ID { CurDefmPrefix = $2; } ':' SubClassRef ';' { - // To instantiate a multiclass, we need to first get the multiclass, then - // instantiate each def contained in the multiclass with the SubClassRef - // template parameters. - MultiClass *MC = MultiClasses[$5->first->getName()]; - assert(MC && "Didn't lookup multiclass correctly?"); - std::vector &TemplateVals = *$5->second; - delete $5; - - // Verify that the correct number of template arguments were specified. - const std::vector &TArgs = MC->Rec.getTemplateArgs(); - if (TArgs.size() < TemplateVals.size()) { - err() << "ERROR: More template args specified than multiclass expects!\n"; - exit(1); - } - - // Loop over all the def's in the multiclass, instantiating each one. - for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { - Record *DefProto = MC->DefPrototypes[i]; - - // Add the suffix to the defm name to get the new name. - assert(CurRec == 0 && "A def is current?"); - CurRec = new Record(*$2 + DefProto->getName()); - - addSubClass(DefProto, std::vector()); - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateVals.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateVals[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of multiclassclass '" - << MC->Rec.getName() << "'!\n"; - exit(1); - } - } - - // If the mdef is inside a 'let' expression, add to each def. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined, " - << "instantiating defm '" << *$2 << "' with subdef '" - << DefProto->getName() << "'!\n"; - exit(1); - } - Records.addDef(CurRec); - - CurRec->resolveReferences(); - - CurRec = 0; - } - - delete &TemplateVals; - delete $2; - CurDefmPrefix = 0; -}; - -Object : ClassInst {} | DefInst {}; -Object : MultiClassInst | DefMInst; - -LETItem : ID OptBitList '=' Value { - LetStack.back().push_back(LetRecord(*$1, $2, $4)); - delete $1; delete $2; -}; - -LETList : LETItem | LETList ',' LETItem; - -// LETCommand - A 'LET' statement start... -LETCommand : LET { LetStack.push_back(std::vector()); } LETList IN; - -// Support Set commands wrapping objects... both with and without braces. -Object : LETCommand '{' ObjectList '}' { - LetStack.pop_back(); - } - | LETCommand Object { - LetStack.pop_back(); - }; - -ObjectList : Object {} | ObjectList Object {}; - -File : ObjectList; - -%% - -int yyerror(const char *ErrorMsg) { - err() << "Error parsing: " << ErrorMsg << "\n"; - exit(1); -} Removed: llvm/trunk/utils/TableGen/FileParser.y.cvs URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FileParser.y.cvs?rev=44273&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/FileParser.y.cvs (original) +++ llvm/trunk/utils/TableGen/FileParser.y.cvs (removed) @@ -1,806 +0,0 @@ -//===-- FileParser.y - Parser for TableGen files ----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the bison parser for Table Generator files... -// -//===----------------------------------------------------------------------===// - -%{ -#include "Record.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Streams.h" -#include -#include -#define YYERROR_VERBOSE 1 - -int yyerror(const char *ErrorMsg); -int yylex(); - -namespace llvm { - struct MultiClass { - Record Rec; // Placeholder for template args and Name. - std::vector DefPrototypes; - - MultiClass(const std::string &Name) : Rec(Name) {} - }; - - -static std::map MultiClasses; - -extern int Filelineno; -static MultiClass *CurMultiClass = 0; // Set while parsing a multiclass. -static std::string *CurDefmPrefix = 0; // Set while parsing defm. -static Record *CurRec = 0; -static bool ParsingTemplateArgs = false; - -typedef std::pair*> SubClassRefTy; - -struct LetRecord { - std::string Name; - std::vector Bits; - Init *Value; - bool HasBits; - LetRecord(const std::string &N, std::vector *B, Init *V) - : Name(N), Value(V), HasBits(B != 0) { - if (HasBits) Bits = *B; - } -}; - -static std::vector > LetStack; - - -extern std::ostream &err(); - -/// getActiveRec - If inside a def/class definition, return the def/class. -/// Otherwise, if within a multidef, return it. -static Record *getActiveRec() { - return CurRec ? CurRec : &CurMultiClass->Rec; -} - -static void addValue(const RecordVal &RV) { - Record *TheRec = getActiveRec(); - - if (RecordVal *ERV = TheRec->getValue(RV.getName())) { - // The value already exists in the class, treat this as a set... - if (ERV->setValue(RV.getValue())) { - err() << "New definition of '" << RV.getName() << "' of type '" - << *RV.getType() << "' is incompatible with previous " - << "definition of type '" << *ERV->getType() << "'!\n"; - exit(1); - } - } else { - TheRec->addValue(RV); - } -} - -static void addSuperClass(Record *SC) { - if (CurRec->isSubClassOf(SC)) { - err() << "Already subclass of '" << SC->getName() << "'!\n"; - exit(1); - } - CurRec->addSuperClass(SC); -} - -static void setValue(const std::string &ValName, - std::vector *BitList, Init *V) { - if (!V) return; - - Record *TheRec = getActiveRec(); - RecordVal *RV = TheRec->getValue(ValName); - if (RV == 0) { - err() << "Value '" << ValName << "' unknown!\n"; - exit(1); - } - - // Do not allow assignments like 'X = X'. This will just cause infinite loops - // in the resolution machinery. - if (!BitList) - if (VarInit *VI = dynamic_cast(V)) - if (VI->getName() == ValName) - return; - - // If we are assigning to a subset of the bits in the value... then we must be - // assigning to a field of BitsRecTy, which must have a BitsInit - // initializer... - // - if (BitList) { - BitsInit *CurVal = dynamic_cast(RV->getValue()); - if (CurVal == 0) { - err() << "Value '" << ValName << "' is not a bits type!\n"; - exit(1); - } - - // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->convertInitializerTo(new BitsRecTy(BitList->size())); - if (BI == 0) { - V->convertInitializerTo(new BitsRecTy(BitList->size())); - err() << "Initializer '" << *V << "' not compatible with bit range!\n"; - exit(1); - } - - // We should have a BitsInit type now... - assert(dynamic_cast(BI) != 0 || (cerr << *BI).stream() == 0); - BitsInit *BInit = (BitsInit*)BI; - - BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); - - // Loop over bits, assigning values as appropriate... - for (unsigned i = 0, e = BitList->size(); i != e; ++i) { - unsigned Bit = (*BitList)[i]; - if (NewVal->getBit(Bit)) { - err() << "Cannot set bit #" << Bit << " of value '" << ValName - << "' more than once!\n"; - exit(1); - } - NewVal->setBit(Bit, BInit->getBit(i)); - } - - for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) - if (NewVal->getBit(i) == 0) - NewVal->setBit(i, CurVal->getBit(i)); - - V = NewVal; - } - - if (RV->setValue(V)) { - err() << "Value '" << ValName << "' of type '" << *RV->getType() - << "' is incompatible with initializer '" << *V << "'!\n"; - exit(1); - } -} - -// addSubClass - Add SC as a subclass to CurRec, resolving TemplateArgs as SC's -// template arguments. -static void addSubClass(Record *SC, const std::vector &TemplateArgs) { - // Add all of the values in the subclass into the current class... - const std::vector &Vals = SC->getValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - addValue(Vals[i]); - - const std::vector &TArgs = SC->getTemplateArgs(); - - // Ensure that an appropriate number of template arguments are specified... - if (TArgs.size() < TemplateArgs.size()) { - err() << "ERROR: More template args specified than expected!\n"; - exit(1); - } - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateArgs.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateArgs[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of subclass '" << SC->getName() - << "'!\n"; - exit(1); - } - } - - // Since everything went well, we can now set the "superclass" list for the - // current record. - const std::vector &SCs = SC->getSuperClasses(); - for (unsigned i = 0, e = SCs.size(); i != e; ++i) - addSuperClass(SCs[i]); - addSuperClass(SC); -} - -} // End llvm namespace - -using namespace llvm; - -%} - -%union { - std::string* StrVal; - int IntVal; - llvm::RecTy* Ty; - llvm::Init* Initializer; - std::vector* FieldList; - std::vector* BitList; - llvm::Record* Rec; - std::vector* RecList; - SubClassRefTy* SubClassRef; - std::vector* SubClassList; - std::vector >* DagValueList; -}; - -%token INT BIT STRING BITS LIST CODE DAG CLASS DEF MULTICLASS DEFM FIELD LET IN -%token CONCATTOK SHLTOK SRATOK SRLTOK STRCONCATTOK -%token INTVAL -%token ID VARNAME STRVAL CODEFRAGMENT - -%type Type -%type ClassInst DefInst MultiClassDef ObjectBody ClassID -%type MultiClassBody - -%type SubClassRef -%type ClassList ClassListNE -%type OptPrefix -%type Value OptValue IDValue -%type DagArgList DagArgListNE -%type ValueList ValueListNE -%type BitList OptBitList RBitList -%type Declaration OptID OptVarName ObjectName - -%start File - -%% - -ClassID : ID { - if (CurDefmPrefix) { - // If CurDefmPrefix is set, we're parsing a defm, which means that this is - // actually the name of a multiclass. - MultiClass *MC = MultiClasses[*$1]; - if (MC == 0) { - err() << "Couldn't find class '" << *$1 << "'!\n"; - exit(1); - } - $$ = &MC->Rec; - } else { - $$ = Records.getClass(*$1); - } - if ($$ == 0) { - err() << "Couldn't find class '" << *$1 << "'!\n"; - exit(1); - } - delete $1; - }; - - -// TableGen types... -Type : STRING { // string type - $$ = new StringRecTy(); - } | BIT { // bit type - $$ = new BitRecTy(); - } | BITS '<' INTVAL '>' { // bits type - $$ = new BitsRecTy($3); - } | INT { // int type - $$ = new IntRecTy(); - } | LIST '<' Type '>' { // list type - $$ = new ListRecTy($3); - } | CODE { // code type - $$ = new CodeRecTy(); - } | DAG { // dag type - $$ = new DagRecTy(); - } | ClassID { // Record Type - $$ = new RecordRecTy($1); - }; - -OptPrefix : /*empty*/ { $$ = 0; } | FIELD { $$ = 1; }; - -OptValue : /*empty*/ { $$ = 0; } | '=' Value { $$ = $2; }; - -IDValue : ID { - if (const RecordVal *RV = (CurRec ? CurRec->getValue(*$1) : 0)) { - $$ = new VarInit(*$1, RV->getType()); - } else if (CurRec && CurRec->isTemplateArg(CurRec->getName()+":"+*$1)) { - const RecordVal *RV = CurRec->getValue(CurRec->getName()+":"+*$1); - assert(RV && "Template arg doesn't exist??"); - $$ = new VarInit(CurRec->getName()+":"+*$1, RV->getType()); - } else if (CurMultiClass && - CurMultiClass->Rec.isTemplateArg(CurMultiClass->Rec.getName()+"::"+*$1)) { - std::string Name = CurMultiClass->Rec.getName()+"::"+*$1; - const RecordVal *RV = CurMultiClass->Rec.getValue(Name); - assert(RV && "Template arg doesn't exist??"); - $$ = new VarInit(Name, RV->getType()); - } else if (Record *D = Records.getDef(*$1)) { - $$ = new DefInit(D); - } else { - err() << "Variable not defined: '" << *$1 << "'!\n"; - exit(1); - } - - delete $1; -}; - -Value : IDValue { - $$ = $1; - } | INTVAL { - $$ = new IntInit($1); - } | STRVAL { - $$ = new StringInit(*$1); - delete $1; - } | CODEFRAGMENT { - $$ = new CodeInit(*$1); - delete $1; - } | '?' { - $$ = new UnsetInit(); - } | '{' ValueList '}' { - BitsInit *Init = new BitsInit($2->size()); - for (unsigned i = 0, e = $2->size(); i != e; ++i) { - struct Init *Bit = (*$2)[i]->convertInitializerTo(new BitRecTy()); - if (Bit == 0) { - err() << "Element #" << i << " (" << *(*$2)[i] - << ") is not convertable to a bit!\n"; - exit(1); - } - Init->setBit($2->size()-i-1, Bit); - } - $$ = Init; - delete $2; - } | ID '<' ValueListNE '>' { - // This is a CLASS expression. This is supposed to synthesize - // a new anonymous definition, deriving from CLASS with no - // body. - Record *Class = Records.getClass(*$1); - if (!Class) { - err() << "Expected a class, got '" << *$1 << "'!\n"; - exit(1); - } - delete $1; - - static unsigned AnonCounter = 0; - Record *OldRec = CurRec; // Save CurRec. - - // Create the new record, set it as CurRec temporarily. - CurRec = new Record("anonymous.val."+utostr(AnonCounter++)); - addSubClass(Class, *$3); // Add info about the subclass to CurRec. - delete $3; // Free up the template args. - - CurRec->resolveReferences(); - - Records.addDef(CurRec); - - // The result of the expression is a reference to the new record. - $$ = new DefInit(CurRec); - - // Restore the old CurRec - CurRec = OldRec; - } | Value '{' BitList '}' { - $$ = $1->convertInitializerBitRange(*$3); - if ($$ == 0) { - err() << "Invalid bit range for value '" << *$1 << "'!\n"; - exit(1); - } - delete $3; - } | '[' ValueList ']' { - $$ = new ListInit(*$2); - delete $2; - } | Value '.' ID { - if (!$1->getFieldType(*$3)) { - err() << "Cannot access field '" << *$3 << "' of value '" << *$1 << "!\n"; - exit(1); - } - $$ = new FieldInit($1, *$3); - delete $3; - } | '(' IDValue DagArgList ')' { - $$ = new DagInit($2, *$3); - delete $3; - } | Value '[' BitList ']' { - std::reverse($3->begin(), $3->end()); - $$ = $1->convertInitListSlice(*$3); - if ($$ == 0) { - err() << "Invalid list slice for value '" << *$1 << "'!\n"; - exit(1); - } - delete $3; - } | CONCATTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::CONCAT, $3, $5))->Fold(); - } | SHLTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SHL, $3, $5))->Fold(); - } | SRATOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SRA, $3, $5))->Fold(); - } | SRLTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::SRL, $3, $5))->Fold(); - } | STRCONCATTOK '(' Value ',' Value ')' { - $$ = (new BinOpInit(BinOpInit::STRCONCAT, $3, $5))->Fold(); - }; - -OptVarName : /* empty */ { - $$ = new std::string(); - } - | ':' VARNAME { - $$ = $2; - }; - -DagArgListNE : Value OptVarName { - $$ = new std::vector >(); - $$->push_back(std::make_pair($1, *$2)); - delete $2; - } - | DagArgListNE ',' Value OptVarName { - $1->push_back(std::make_pair($3, *$4)); - delete $4; - $$ = $1; - }; - -DagArgList : /*empty*/ { - $$ = new std::vector >(); - } - | DagArgListNE { $$ = $1; }; - - -RBitList : INTVAL { - $$ = new std::vector(); - $$->push_back($1); - } | INTVAL '-' INTVAL { - if ($1 < 0 || $3 < 0) { - err() << "Invalid range: " << $1 << "-" << $3 << "!\n"; - exit(1); - } - $$ = new std::vector(); - if ($1 < $3) { - for (int i = $1; i <= $3; ++i) - $$->push_back(i); - } else { - for (int i = $1; i >= $3; --i) - $$->push_back(i); - } - } | INTVAL INTVAL { - $2 = -$2; - if ($1 < 0 || $2 < 0) { - err() << "Invalid range: " << $1 << "-" << $2 << "!\n"; - exit(1); - } - $$ = new std::vector(); - if ($1 < $2) { - for (int i = $1; i <= $2; ++i) - $$->push_back(i); - } else { - for (int i = $1; i >= $2; --i) - $$->push_back(i); - } - } | RBitList ',' INTVAL { - ($$=$1)->push_back($3); - } | RBitList ',' INTVAL '-' INTVAL { - if ($3 < 0 || $5 < 0) { - err() << "Invalid range: " << $3 << "-" << $5 << "!\n"; - exit(1); - } - $$ = $1; - if ($3 < $5) { - for (int i = $3; i <= $5; ++i) - $$->push_back(i); - } else { - for (int i = $3; i >= $5; --i) - $$->push_back(i); - } - } | RBitList ',' INTVAL INTVAL { - $4 = -$4; - if ($3 < 0 || $4 < 0) { - err() << "Invalid range: " << $3 << "-" << $4 << "!\n"; - exit(1); - } - $$ = $1; - if ($3 < $4) { - for (int i = $3; i <= $4; ++i) - $$->push_back(i); - } else { - for (int i = $3; i >= $4; --i) - $$->push_back(i); - } - }; - -BitList : RBitList { $$ = $1; std::reverse($1->begin(), $1->end()); }; - -OptBitList : /*empty*/ { $$ = 0; } | '{' BitList '}' { $$ = $2; }; - - - -ValueList : /*empty*/ { - $$ = new std::vector(); - } | ValueListNE { - $$ = $1; - }; - -ValueListNE : Value { - $$ = new std::vector(); - $$->push_back($1); - } | ValueListNE ',' Value { - ($$ = $1)->push_back($3); - }; - -Declaration : OptPrefix Type ID OptValue { - std::string DecName = *$3; - if (ParsingTemplateArgs) { - if (CurRec) { - DecName = CurRec->getName() + ":" + DecName; - } else { - assert(CurMultiClass); - } - if (CurMultiClass) - DecName = CurMultiClass->Rec.getName() + "::" + DecName; - } - - addValue(RecordVal(DecName, $2, $1)); - setValue(DecName, 0, $4); - $$ = new std::string(DecName); -}; - -BodyItem : Declaration ';' { - delete $1; -} | LET ID OptBitList '=' Value ';' { - setValue(*$2, $3, $5); - delete $2; - delete $3; -}; - -BodyList : /*empty*/ | BodyList BodyItem; -Body : ';' | '{' BodyList '}'; - -SubClassRef : ClassID { - $$ = new SubClassRefTy($1, new std::vector()); - } | ClassID '<' ValueListNE '>' { - $$ = new SubClassRefTy($1, $3); - }; - -ClassListNE : SubClassRef { - $$ = new std::vector(); - $$->push_back(*$1); - delete $1; - } - | ClassListNE ',' SubClassRef { - ($$=$1)->push_back(*$3); - delete $3; - }; - -ClassList : /*empty */ { - $$ = new std::vector(); - } - | ':' ClassListNE { - $$ = $2; - }; - -DeclListNE : Declaration { - getActiveRec()->addTemplateArg(*$1); - delete $1; -} | DeclListNE ',' Declaration { - getActiveRec()->addTemplateArg(*$3); - delete $3; -}; - -TemplateArgList : '<' DeclListNE '>' {}; -OptTemplateArgList : /*empty*/ | TemplateArgList; - -OptID : ID { $$ = $1; } | /*empty*/ { $$ = new std::string(); }; - -ObjectName : OptID { - static unsigned AnonCounter = 0; - if ($1->empty()) - *$1 = "anonymous."+utostr(AnonCounter++); - $$ = $1; -}; - -ClassName : ObjectName { - // If a class of this name already exists, it must be a forward ref. - if ((CurRec = Records.getClass(*$1))) { - // If the body was previously defined, this is an error. - if (!CurRec->getValues().empty() || - !CurRec->getSuperClasses().empty() || - !CurRec->getTemplateArgs().empty()) { - err() << "Class '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - } else { - // If this is the first reference to this class, create and add it. - CurRec = new Record(*$1); - Records.addClass(CurRec); - } - delete $1; -}; - -DefName : ObjectName { - CurRec = new Record(*$1); - delete $1; - - if (!CurMultiClass) { - // Top-level def definition. - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined!\n"; - exit(1); - } - Records.addDef(CurRec); - } else { - // Otherwise, a def inside a multiclass, add it to the multiclass. - for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) - if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) { - err() << "def '" << CurRec->getName() - << "' already defined in this multiclass!\n"; - exit(1); - } - CurMultiClass->DefPrototypes.push_back(CurRec); - } -}; - -ObjectBody : ClassList { - for (unsigned i = 0, e = $1->size(); i != e; ++i) { - addSubClass((*$1)[i].first, *(*$1)[i].second); - // Delete the template arg values for the class - delete (*$1)[i].second; - } - delete $1; // Delete the class list. - - // Process any variables on the let stack. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - } Body { - $$ = CurRec; - CurRec = 0; - }; - -ClassInst : CLASS ClassName { - ParsingTemplateArgs = true; - } OptTemplateArgList { - ParsingTemplateArgs = false; - } ObjectBody { - $$ = $6; - }; - -DefInst : DEF DefName ObjectBody { - if (CurMultiClass == 0) // Def's in multiclasses aren't really defs. - $3->resolveReferences(); - - // If ObjectBody has template arguments, it's an error. - assert($3->getTemplateArgs().empty() && "How'd this get template args?"); - $$ = $3; -}; - -// MultiClassDef - A def instance specified inside a multiclass. -MultiClassDef : DefInst { - $$ = $1; - // Copy the template arguments for the multiclass into the def. - const std::vector &TArgs = CurMultiClass->Rec.getTemplateArgs(); - - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - const RecordVal *RV = CurMultiClass->Rec.getValue(TArgs[i]); - assert(RV && "Template arg doesn't exist?"); - $$->addValue(*RV); - } -}; - -// MultiClassBody - Sequence of def's that are instantiated when a multiclass is -// used. -MultiClassBody : MultiClassDef { - $$ = new std::vector(); - $$->push_back($1); -} | MultiClassBody MultiClassDef { - $$->push_back($2); -}; - -MultiClassName : ID { - MultiClass *&MCE = MultiClasses[*$1]; - if (MCE) { - err() << "multiclass '" << *$1 << "' already defined!\n"; - exit(1); - } - MCE = CurMultiClass = new MultiClass(*$1); - delete $1; -}; - -// MultiClass - Multiple definitions. -MultiClassInst : MULTICLASS MultiClassName { - ParsingTemplateArgs = true; - } OptTemplateArgList { - ParsingTemplateArgs = false; - }'{' MultiClassBody '}' { - CurMultiClass = 0; -}; - -// DefMInst - Instantiate a multiclass. -DefMInst : DEFM ID { CurDefmPrefix = $2; } ':' SubClassRef ';' { - // To instantiate a multiclass, we need to first get the multiclass, then - // instantiate each def contained in the multiclass with the SubClassRef - // template parameters. - MultiClass *MC = MultiClasses[$5->first->getName()]; - assert(MC && "Didn't lookup multiclass correctly?"); - std::vector &TemplateVals = *$5->second; - delete $5; - - // Verify that the correct number of template arguments were specified. - const std::vector &TArgs = MC->Rec.getTemplateArgs(); - if (TArgs.size() < TemplateVals.size()) { - err() << "ERROR: More template args specified than multiclass expects!\n"; - exit(1); - } - - // Loop over all the def's in the multiclass, instantiating each one. - for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { - Record *DefProto = MC->DefPrototypes[i]; - - // Add the suffix to the defm name to get the new name. - assert(CurRec == 0 && "A def is current?"); - CurRec = new Record(*$2 + DefProto->getName()); - - addSubClass(DefProto, std::vector()); - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - if (i < TemplateVals.size()) { // A value is specified for this temp-arg? - // Set it now. - setValue(TArgs[i], 0, TemplateVals[i]); - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - err() << "ERROR: Value not specified for template argument #" - << i << " (" << TArgs[i] << ") of multiclassclass '" - << MC->Rec.getName() << "'!\n"; - exit(1); - } - } - - // If the mdef is inside a 'let' expression, add to each def. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - setValue(LetStack[i][j].Name, - LetStack[i][j].HasBits ? &LetStack[i][j].Bits : 0, - LetStack[i][j].Value); - - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) { - err() << "def '" << CurRec->getName() << "' already defined, " - << "instantiating defm '" << *$2 << "' with subdef '" - << DefProto->getName() << "'!\n"; - exit(1); - } - Records.addDef(CurRec); - - CurRec->resolveReferences(); - - CurRec = 0; - } - - delete &TemplateVals; - delete $2; - CurDefmPrefix = 0; -}; - -Object : ClassInst {} | DefInst {}; -Object : MultiClassInst | DefMInst; - -LETItem : ID OptBitList '=' Value { - LetStack.back().push_back(LetRecord(*$1, $2, $4)); - delete $1; delete $2; -}; - -LETList : LETItem | LETList ',' LETItem; - -// LETCommand - A 'LET' statement start... -LETCommand : LET { LetStack.push_back(std::vector()); } LETList IN; - -// Support Set commands wrapping objects... both with and without braces. -Object : LETCommand '{' ObjectList '}' { - LetStack.pop_back(); - } - | LETCommand Object { - LetStack.pop_back(); - }; - -ObjectList : Object {} | ObjectList Object {}; - -File : ObjectList; - -%% - -int yyerror(const char *ErrorMsg) { - err() << "Error parsing: " << ErrorMsg << "\n"; - exit(1); -} Modified: llvm/trunk/utils/TableGen/Makefile URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Makefile?rev=44274&r1=44273&r2=44274&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Makefile (original) +++ llvm/trunk/utils/TableGen/Makefile Thu Nov 22 14:49:04 2007 @@ -11,20 +11,8 @@ TOOLNAME = tblgen NO_INSTALL = 1; USEDLIBS = LLVMSupport.a LLVMSystem.a -EXTRA_DIST = FileParser.cpp.cvs FileParser.h.cvs FileParser.y.cvs REQUIRES_EH := 1 REQUIRES_RTTI := 1 include $(LEVEL)/Makefile.common -# Disable -pedantic for tblgen -CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts)) -CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts)) - -# -# Make the source file depend on the header file. In this way, dependencies -# (which depend on the source file) won't get generated until bison is done -# generating the C source and header files for the parser. -# -$(ObjDir)/TGLexer.o : $(PROJ_SRC_DIR)/FileParser.h - Modified: llvm/trunk/utils/TableGen/TGLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=44274&r1=44273&r2=44274&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.cpp (original) +++ llvm/trunk/utils/TableGen/TGLexer.cpp Thu Nov 22 14:49:04 2007 @@ -12,20 +12,13 @@ //===----------------------------------------------------------------------===// #include "TGLexer.h" -#include "Record.h" #include "llvm/Support/Streams.h" -#include "Record.h" #include "llvm/Support/MemoryBuffer.h" -typedef std::pair*> SubClassRefTy; -#include "FileParser.h" +#include #include "llvm/Config/config.h" #include using namespace llvm; -// FIXME: REMOVE THIS. -#define YYEOF 0 -#define YYERROR -2 - TGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) { CurPtr = CurBuf->getBufferStart(); TokStart = 0; @@ -40,18 +33,12 @@ } /// ReturnError - Set the error to the specified string at the specified -/// location. This is defined to always return YYERROR. -int TGLexer::ReturnError(const char *Loc, const std::string &Msg) { +/// location. This is defined to always return tgtok::Error. +tgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) { PrintError(Loc, Msg); - return YYERROR; -} - -std::ostream &TGLexer::err() const { - PrintIncludeStack(*cerr.stream()); - return *cerr.stream(); + return tgtok::Error; } - void TGLexer::PrintIncludeStack(std::ostream &OS) const { for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i) OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier() @@ -62,7 +49,8 @@ /// PrintError - Print the error at the specified location. void TGLexer::PrintError(const char *ErrorLoc, const std::string &Msg) const { - err() << Msg << "\n"; + PrintIncludeStack(*cerr.stream()); + cerr << Msg << "\n"; assert(ErrorLoc && "Location not specified!"); // Scan backward to find the start of the line. @@ -122,7 +110,7 @@ } } -int TGLexer::LexToken() { +tgtok::TokKind TGLexer::LexToken() { TokStart = CurPtr; // This always consumes at least one character. int CurChar = getNextChar(); @@ -133,9 +121,23 @@ if (isalpha(CurChar) || CurChar == '_') return LexIdentifier(); - // Unknown character, return the char itself. - return (unsigned char)CurChar; - case EOF: return YYEOF; + // Unknown character, emit an error. + return ReturnError(TokStart, "Unexpected character"); + case EOF: return tgtok::Eof; + case ':': return tgtok::colon; + case ';': return tgtok::semi; + case '.': return tgtok::period; + case ',': return tgtok::comma; + case '<': return tgtok::less; + case '>': return tgtok::greater; + case ']': return tgtok::r_square; + case '{': return tgtok::l_brace; + case '}': return tgtok::r_brace; + case '(': return tgtok::l_paren; + case ')': return tgtok::r_paren; + case '=': return tgtok::equal; + case '?': return tgtok::question; + case 0: case ' ': case '\t': @@ -150,9 +152,9 @@ SkipBCPLComment(); else if (*CurPtr == '*') { if (SkipCComment()) - return YYERROR; - } else // Otherwise, return this / as a token. - return CurChar; + return tgtok::Error; + } else // Otherwise, this is an error. + return ReturnError(TokStart, "Unexpected character"); return LexToken(); case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': @@ -166,7 +168,7 @@ } /// LexString - Lex "[^"]*" -int TGLexer::LexString() { +tgtok::TokKind TGLexer::LexString() { const char *StrStart = CurPtr; while (*CurPtr != '"') { @@ -180,14 +182,14 @@ ++CurPtr; } - Filelval.StrVal = new std::string(StrStart, CurPtr); + CurStrVal.assign(StrStart, CurPtr); ++CurPtr; - return STRVAL; + return tgtok::StrVal; } -int TGLexer::LexVarName() { +tgtok::TokKind TGLexer::LexVarName() { if (!isalpha(CurPtr[0]) && CurPtr[0] != '_') - return '$'; // Invalid varname. + return ReturnError(TokStart, "Invalid variable name"); // Otherwise, we're ok, consume the rest of the characters. const char *VarNameStart = CurPtr++; @@ -195,14 +197,14 @@ while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') ++CurPtr; - Filelval.StrVal = new std::string(VarNameStart, CurPtr); - return VARNAME; + CurStrVal.assign(VarNameStart, CurPtr); + return tgtok::VarName; } -int TGLexer::LexIdentifier() { +tgtok::TokKind TGLexer::LexIdentifier() { // The first letter is [a-zA-Z_]. - const char *IdentStart = CurPtr-1; + const char *IdentStart = TokStart; // Match the rest of the identifier regex: [0-9a-zA-Z_]* while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') @@ -211,45 +213,45 @@ // Check to see if this identifier is a keyword. unsigned Len = CurPtr-IdentStart; - if (Len == 3 && !memcmp(IdentStart, "int", 3)) return INT; - if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return BIT; - if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return BITS; - if (Len == 6 && !memcmp(IdentStart, "string", 6)) return STRING; - if (Len == 4 && !memcmp(IdentStart, "list", 4)) return LIST; - if (Len == 4 && !memcmp(IdentStart, "code", 4)) return CODE; - if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return DAG; - - if (Len == 5 && !memcmp(IdentStart, "class", 5)) return CLASS; - if (Len == 3 && !memcmp(IdentStart, "def", 3)) return DEF; - if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return DEFM; - if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) return MULTICLASS; - if (Len == 5 && !memcmp(IdentStart, "field", 5)) return FIELD; - if (Len == 3 && !memcmp(IdentStart, "let", 3)) return LET; - if (Len == 2 && !memcmp(IdentStart, "in", 2)) return IN; + if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int; + if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit; + if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits; + if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String; + if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List; + if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code; + if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag; + + if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class; + if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def; + if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm; + if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) + return tgtok::MultiClass; + if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field; + if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let; + if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In; if (Len == 7 && !memcmp(IdentStart, "include", 7)) { - if (LexInclude()) return YYERROR; - return LexToken(); + if (LexInclude()) return tgtok::Error; + return Lex(); } - Filelval.StrVal = new std::string(IdentStart, CurPtr); - return ID; + CurStrVal.assign(IdentStart, CurPtr); + return tgtok::Id; } /// LexInclude - We just read the "include" token. Get the string token that /// comes next and enter the include. bool TGLexer::LexInclude() { // The token after the include must be a string. - int Tok = LexToken(); - if (Tok == YYERROR) return true; - if (Tok != STRVAL) { - PrintError(getTokenStart(), "Expected filename after include"); + tgtok::TokKind Tok = LexToken(); + if (Tok == tgtok::Error) return true; + if (Tok != tgtok::StrVal) { + PrintError(getLoc(), "Expected filename after include"); return true; } // Get the string. - std::string Filename = *Filelval.StrVal; - delete Filelval.StrVal; + std::string Filename = CurStrVal; // Try to find the file. MemoryBuffer *NewBuf = MemoryBuffer::getFile(&Filename[0], Filename.size()); @@ -261,8 +263,7 @@ } if (NewBuf == 0) { - PrintError(getTokenStart(), - "Could not find include file '" + Filename + "'"); + PrintError(getLoc(), "Could not find include file '" + Filename + "'"); return true; } @@ -296,7 +297,6 @@ /// SkipCComment - This skips C-style /**/ comments. The only difference from C /// is that we allow nesting. bool TGLexer::SkipCComment() { - const char *CommentStart = CurPtr-1; ++CurPtr; // skip the star. unsigned CommentDepth = 1; @@ -304,7 +304,7 @@ int CurChar = getNextChar(); switch (CurChar) { case EOF: - PrintError(CommentStart, "Unterminated comment!"); + PrintError(TokStart, "Unterminated comment!"); return true; case '*': // End of the comment? @@ -328,13 +328,11 @@ /// [-+]?[0-9]+ /// 0x[0-9a-fA-F]+ /// 0b[01]+ -int TGLexer::LexNumber() { - const char *NumStart = CurPtr-1; - +tgtok::TokKind TGLexer::LexNumber() { if (CurPtr[-1] == '0') { if (CurPtr[0] == 'x') { ++CurPtr; - NumStart = CurPtr; + const char *NumStart = CurPtr; while (isxdigit(CurPtr[0])) ++CurPtr; @@ -342,42 +340,41 @@ if (CurPtr == NumStart) return ReturnError(CurPtr-2, "Invalid hexadecimal number"); - Filelval.IntVal = strtoll(NumStart, 0, 16); - - return INTVAL; + CurIntVal = strtoll(NumStart, 0, 16); + return tgtok::IntVal; } else if (CurPtr[0] == 'b') { ++CurPtr; - NumStart = CurPtr; + const char *NumStart = CurPtr; while (CurPtr[0] == '0' || CurPtr[0] == '1') ++CurPtr; // Requires at least one binary digit. if (CurPtr == NumStart) return ReturnError(CurPtr-2, "Invalid binary number"); - - Filelval.IntVal = strtoll(NumStart, 0, 2); - return INTVAL; + CurIntVal = strtoll(NumStart, 0, 2); + return tgtok::IntVal; } } // Check for a sign without a digit. - if (CurPtr[-1] == '-' || CurPtr[-1] == '+') { - if (!isdigit(CurPtr[0])) - return CurPtr[-1]; + if (!isdigit(CurPtr[0])) { + if (CurPtr[-1] == '-') + return tgtok::minus; + else if (CurPtr[-1] == '+') + return tgtok::plus; } while (isdigit(CurPtr[0])) ++CurPtr; - - Filelval.IntVal = strtoll(NumStart, 0, 10); - return INTVAL; + CurIntVal = strtoll(TokStart, 0, 10); + return tgtok::IntVal; } /// LexBracket - We just read '['. If this is a code block, return it, /// otherwise return the bracket. Match: '[' and '[{ ( [^}]+ | }[^]] )* }]' -int TGLexer::LexBracket() { +tgtok::TokKind TGLexer::LexBracket() { if (CurPtr[0] != '{') - return '['; + return tgtok::l_square; ++CurPtr; const char *CodeStart = CurPtr; while (1) { @@ -389,8 +386,8 @@ Char = getNextChar(); if (Char == EOF) break; if (Char == ']') { - Filelval.StrVal = new std::string(CodeStart, CurPtr-2); - return CODEFRAGMENT; + CurStrVal.assign(CodeStart, CurPtr-2); + return tgtok::CodeFragment; } } @@ -398,9 +395,9 @@ } /// LexExclaim - Lex '!' and '![a-zA-Z]+'. -int TGLexer::LexExclaim() { +tgtok::TokKind TGLexer::LexExclaim() { if (!isalpha(*CurPtr)) - return '!'; + return ReturnError(CurPtr-1, "Invalid \"!operator\""); const char *Start = CurPtr++; while (isalpha(*CurPtr)) @@ -409,61 +406,12 @@ // Check to see which operator this is. unsigned Len = CurPtr-Start; - if (Len == 3 && !memcmp(Start, "con", 3)) return CONCATTOK; - if (Len == 3 && !memcmp(Start, "sra", 3)) return SRATOK; - if (Len == 3 && !memcmp(Start, "srl", 3)) return SRLTOK; - if (Len == 3 && !memcmp(Start, "shl", 3)) return SHLTOK; - if (Len == 9 && !memcmp(Start, "strconcat", 9)) return STRCONCATTOK; + if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; + if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; + if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; + if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; + if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; return ReturnError(Start-1, "Unknown operator"); } -//===----------------------------------------------------------------------===// -// Interfaces used by the Bison parser. -//===----------------------------------------------------------------------===// - -int Fileparse(); -static TGLexer *TheLexer; - -namespace llvm { - -std::ostream &err() { - return TheLexer->err(); -} - -/// ParseFile - this function begins the parsing of the specified tablegen -/// file. -/// -void ParseFile(const std::string &Filename, - const std::vector &IncludeDirs) { - std::string ErrorStr; - MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(&Filename[0], Filename.size(), - &ErrorStr); - if (F == 0) { - cerr << "Could not open input file '" + Filename + "': " << ErrorStr <<"\n"; - exit(1); - } - - assert(!TheLexer && "Lexer isn't reentrant yet!"); - TheLexer = new TGLexer(F); - - // Record the location of the include directory so that the lexer can find - // it later. - TheLexer->setIncludeDirs(IncludeDirs); - - Fileparse(); - - // Cleanup - delete TheLexer; - TheLexer = 0; -} -} // End llvm namespace - - -int Filelex() { - assert(TheLexer && "No lexer setup yet!"); - int Tok = TheLexer->LexToken(); - if (Tok == YYERROR) - exit(1); - return Tok; -} Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=44274&r1=44273&r2=44274&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Thu Nov 22 14:49:04 2007 @@ -20,12 +20,49 @@ namespace llvm { class MemoryBuffer; + +namespace tgtok { + enum TokKind { + // Markers + Eof, Error, + + // Tokens with no info. + minus, plus, // - + + l_square, r_square, // [ ] + l_brace, r_brace, // { } + l_paren, r_paren, // ( ) + less, greater, // < > + colon, semi, // ; : + comma, period, // , . + equal, question, // = ? + + // Keywords. + Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List, + MultiClass, String, + + // !keywords. + XConcat, XSRA, XSRL, XSHL, XStrConcat, + + // Integer value. + IntVal, + + // String valued tokens. + Id, StrVal, VarName, CodeFragment + }; +} +/// TGLexer - TableGen Lexer class. class TGLexer { const char *CurPtr; unsigned CurLineNo; MemoryBuffer *CurBuf; + // Information about the current token. + const char *TokStart; + tgtok::TokKind CurCode; + std::string CurStrVal; // This is valid for ID, STRVAL, VARNAME, CODEFRAGMENT + int CurIntVal; // This is valid for INTVAL. + /// IncludeRec / IncludeStack - This captures the current set of include /// directives we are nested within. struct IncludeRec { @@ -40,7 +77,6 @@ // IncludeDirectories - This is the list of directories we should search for // include files in. std::vector IncludeDirectories; - const char *TokStart; public: TGLexer(MemoryBuffer *StartBuf); ~TGLexer(); @@ -49,29 +85,46 @@ IncludeDirectories = Dirs; } - int LexToken(); + tgtok::TokKind Lex() { + return CurCode = LexToken(); + } + + tgtok::TokKind getCode() const { return CurCode; } - typedef const char* LocationTy; - LocationTy getTokenStart() const { return TokStart; } + const std::string &getCurStrVal() const { + assert((CurCode == tgtok::Id || CurCode == tgtok::StrVal || + CurCode == tgtok::VarName || CurCode == tgtok::CodeFragment) && + "This token doesn't have a string value"); + return CurStrVal; + } + int getCurIntVal() const { + assert(CurCode == tgtok::IntVal && "This token isn't an integer"); + return CurIntVal; + } - void PrintError(LocationTy Loc, const std::string &Msg) const; + typedef const char* LocTy; + LocTy getLoc() const { return TokStart; } + + void PrintError(LocTy Loc, const std::string &Msg) const; - std::ostream &err() const; void PrintIncludeStack(std::ostream &OS) const; private: - int ReturnError(const char *Loc, const std::string &Msg); + /// LexToken - Read the next token and return its code. + tgtok::TokKind LexToken(); + + tgtok::TokKind ReturnError(const char *Loc, const std::string &Msg); int getNextChar(); void SkipBCPLComment(); bool SkipCComment(); - int LexIdentifier(); + tgtok::TokKind LexIdentifier(); bool LexInclude(); - int LexString(); - int LexVarName(); - int LexNumber(); - int LexBracket(); - int LexExclaim(); + tgtok::TokKind LexString(); + tgtok::TokKind LexVarName(); + tgtok::TokKind LexNumber(); + tgtok::TokKind LexBracket(); + tgtok::TokKind LexExclaim(); }; } // end namespace llvm Added: llvm/trunk/utils/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=44274&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.cpp (added) +++ llvm/trunk/utils/TableGen/TGParser.cpp Thu Nov 22 14:49:04 2007 @@ -0,0 +1,1372 @@ +//===- TGParser.cpp - Parser for TableGen Files ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implement the Parser for TableGen. +// +//===----------------------------------------------------------------------===// + +#include "TGParser.h" +#include "Record.h" +#include "llvm/ADT/StringExtras.h" +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Support Code for the Semantic Actions. +//===----------------------------------------------------------------------===// + +namespace llvm { +struct MultiClass { + Record Rec; // Placeholder for template args and Name. + std::vector DefPrototypes; + + MultiClass(const std::string &Name) : Rec(Name) {} +}; + +struct SubClassReference { + TGParser::LocTy RefLoc; + Record *Rec; + std::vector TemplateArgs; + SubClassReference() : RefLoc(0), Rec(0) {} + + bool isInvalid() const { return Rec == 0; } +}; + +} // end namespace llvm + +bool TGParser::AddValue(Record *CurRec, LocTy Loc, const RecordVal &RV) { + if (CurRec == 0) + CurRec = &CurMultiClass->Rec; + + if (RecordVal *ERV = CurRec->getValue(RV.getName())) { + // The value already exists in the class, treat this as a set. + if (ERV->setValue(RV.getValue())) + return Error(Loc, "New definition of '" + RV.getName() + "' of type '" + + RV.getType()->getAsString() + "' is incompatible with " + + "previous definition of type '" + + ERV->getType()->getAsString() + "'"); + } else { + CurRec->addValue(RV); + } + return false; +} + +/// SetValue - +/// Return true on error, false on success. +bool TGParser::SetValue(Record *CurRec, LocTy Loc, const std::string &ValName, + const std::vector &BitList, Init *V) { + if (!V) return false; + + if (CurRec == 0) CurRec = &CurMultiClass->Rec; + + RecordVal *RV = CurRec->getValue(ValName); + if (RV == 0) + return Error(Loc, "Value '" + ValName + "' unknown!"); + + // Do not allow assignments like 'X = X'. This will just cause infinite loops + // in the resolution machinery. + if (BitList.empty()) + if (VarInit *VI = dynamic_cast(V)) + if (VI->getName() == ValName) + return false; + + // If we are assigning to a subset of the bits in the value... then we must be + // assigning to a field of BitsRecTy, which must have a BitsInit + // initializer. + // + if (!BitList.empty()) { + BitsInit *CurVal = dynamic_cast(RV->getValue()); + if (CurVal == 0) + return Error(Loc, "Value '" + ValName + "' is not a bits type"); + + // Convert the incoming value to a bits type of the appropriate size... + Init *BI = V->convertInitializerTo(new BitsRecTy(BitList.size())); + if (BI == 0) { + V->convertInitializerTo(new BitsRecTy(BitList.size())); + return Error(Loc, "Initializer is not compatible with bit range"); + } + + // We should have a BitsInit type now. + BitsInit *BInit = dynamic_cast(BI); + assert(BInit != 0); + + BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); + + // Loop over bits, assigning values as appropriate. + for (unsigned i = 0, e = BitList.size(); i != e; ++i) { + unsigned Bit = BitList[i]; + if (NewVal->getBit(Bit)) + return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" + + ValName + "' more than once"); + NewVal->setBit(Bit, BInit->getBit(i)); + } + + for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) + if (NewVal->getBit(i) == 0) + NewVal->setBit(i, CurVal->getBit(i)); + + V = NewVal; + } + + if (RV->setValue(V)) + return Error(Loc, "Value '" + ValName + "' of type '" + + RV->getType()->getAsString() + + "' is incompatible with initializer ''"); // FIXME: Add init! + return false; +} + +/// AddSubClass - Add SubClass as a subclass to CurRec, resolving its template +/// args as SubClass's template arguments. +bool TGParser::AddSubClass(Record *CurRec, class SubClassReference &SubClass) { + Record *SC = SubClass.Rec; + // Add all of the values in the subclass into the current class. + const std::vector &Vals = SC->getValues(); + for (unsigned i = 0, e = Vals.size(); i != e; ++i) + if (AddValue(CurRec, SubClass.RefLoc, Vals[i])) + return true; + + const std::vector &TArgs = SC->getTemplateArgs(); + + // Ensure that an appropriate number of template arguments are specified. + if (TArgs.size() < SubClass.TemplateArgs.size()) + return Error(SubClass.RefLoc, "More template args specified than expected"); + + // Loop over all of the template arguments, setting them to the specified + // value or leaving them as the default if necessary. + for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { + if (i < SubClass.TemplateArgs.size()) { + // If a value is specified for this template arg, set it now. + if (SetValue(CurRec, SubClass.RefLoc, TArgs[i], std::vector(), + SubClass.TemplateArgs[i])) + return true; + + // Resolve it next. + CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); + + // Now remove it. + CurRec->removeValue(TArgs[i]); + + } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { + return Error(SubClass.RefLoc,"Value not specified for template argument #" + + utostr(i) + " (" + TArgs[i] + ") of subclass '" + + SC->getName() + "'!"); + } + } + + // Since everything went well, we can now set the "superclass" list for the + // current record. + const std::vector &SCs = SC->getSuperClasses(); + for (unsigned i = 0, e = SCs.size(); i != e; ++i) { + if (CurRec->isSubClassOf(SCs[i])) + return Error(SubClass.RefLoc, + "Already subclass of '" + SCs[i]->getName() + "'!\n"); + CurRec->addSuperClass(SCs[i]); + } + + if (CurRec->isSubClassOf(SC)) + return Error(SubClass.RefLoc, + "Already subclass of '" + SC->getName() + "'!\n"); + CurRec->addSuperClass(SC); + return false; +} + +//===----------------------------------------------------------------------===// +// Parser Code +//===----------------------------------------------------------------------===// + +/// isObjectStart - Return true if this is a valid first token for an Object. +static bool isObjectStart(tgtok::TokKind K) { + return K == tgtok::Class || K == tgtok::Def || + K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass; +} + +/// ParseObjectName - If an object name is specified, return it. Otherwise, +/// return an anonymous name. +/// ObjectName ::= ID +/// ObjectName ::= /*empty*/ +/// +std::string TGParser::ParseObjectName() { + if (Lex.getCode() == tgtok::Id) { + std::string Ret = Lex.getCurStrVal(); + Lex.Lex(); + return Ret; + } + + static unsigned AnonCounter = 0; + return "anonymous."+utostr(AnonCounter++); +} + + +/// ParseClassID - Parse and resolve a reference to a class name. This returns +/// null on error. +/// +/// ClassID ::= ID +/// +Record *TGParser::ParseClassID() { + if (Lex.getCode() != tgtok::Id) { + TokError("expected name for ClassID"); + return 0; + } + + Record *Result = Records.getClass(Lex.getCurStrVal()); + if (Result == 0) + TokError("Couldn't find class '" + Lex.getCurStrVal() + "'"); + + Lex.Lex(); + return Result; +} + +Record *TGParser::ParseDefmID() { + if (Lex.getCode() != tgtok::Id) { + TokError("expected multiclass name"); + return 0; + } + + MultiClass *MC = MultiClasses[Lex.getCurStrVal()]; + if (MC == 0) { + TokError("Couldn't find multiclass '" + Lex.getCurStrVal() + "'"); + return 0; + } + + Lex.Lex(); + return &MC->Rec; +} + + + +/// ParseSubClassReference - Parse a reference to a subclass or to a templated +/// subclass. This returns a SubClassRefTy with a null Record* on error. +/// +/// SubClassRef ::= ClassID +/// SubClassRef ::= ClassID '<' ValueList '>' +/// +SubClassReference TGParser:: +ParseSubClassReference(Record *CurRec, bool isDefm) { + SubClassReference Result; + Result.RefLoc = Lex.getLoc(); + + if (isDefm) + Result.Rec = ParseDefmID(); + else + Result.Rec = ParseClassID(); + if (Result.Rec == 0) return Result; + + // If there is no template arg list, we're done. + if (Lex.getCode() != tgtok::less) + return Result; + Lex.Lex(); // Eat the '<' + + if (Lex.getCode() == tgtok::greater) { + TokError("subclass reference requires a non-empty list of template values"); + Result.Rec = 0; + return Result; + } + + Result.TemplateArgs = ParseValueList(CurRec); + if (Result.TemplateArgs.empty()) { + Result.Rec = 0; // Error parsing value list. + return Result; + } + + if (Lex.getCode() != tgtok::greater) { + TokError("expected '>' in template value list"); + Result.Rec = 0; + return Result; + } + Lex.Lex(); + + return Result; +} + +/// ParseRangePiece - Parse a bit/value range. +/// RangePiece ::= INTVAL +/// RangePiece ::= INTVAL '-' INTVAL +/// RangePiece ::= INTVAL INTVAL +bool TGParser::ParseRangePiece(std::vector &Ranges) { + assert(Lex.getCode() == tgtok::IntVal && "Invalid range"); + int Start = Lex.getCurIntVal(); + int End; + + if (Start < 0) + return TokError("invalid range, cannot be negative"); + + switch (Lex.Lex()) { // eat first character. + default: + Ranges.push_back(Start); + return false; + case tgtok::minus: + if (Lex.Lex() != tgtok::IntVal) { + TokError("expected integer value as end of range"); + return true; + } + End = Lex.getCurIntVal(); + break; + case tgtok::IntVal: + End = -Lex.getCurIntVal(); + break; + } + if (End < 0) + return TokError("invalid range, cannot be negative"); + Lex.Lex(); + + // Add to the range. + if (Start < End) { + for (; Start <= End; ++Start) + Ranges.push_back(Start); + } else { + for (; Start >= End; --Start) + Ranges.push_back(Start); + } + return false; +} + +/// ParseRangeList - Parse a list of scalars and ranges into scalar values. +/// +/// RangeList ::= RangePiece (',' RangePiece)* +/// +std::vector TGParser::ParseRangeList() { + std::vector Result; + + // Parse the first piece. + if (ParseRangePiece(Result)) + return std::vector(); + while (Lex.getCode() == tgtok::comma) { + Lex.Lex(); // Eat the comma. + + // Parse the next range piece. + if (ParseRangePiece(Result)) + return std::vector(); + } + return Result; +} + +/// ParseOptionalRangeList - Parse either a range list in <>'s or nothing. +/// OptionalRangeList ::= '<' RangeList '>' +/// OptionalRangeList ::= /*empty*/ +bool TGParser::ParseOptionalRangeList(std::vector &Ranges) { + if (Lex.getCode() != tgtok::less) + return false; + + LocTy StartLoc = Lex.getLoc(); + Lex.Lex(); // eat the '<' + + // Parse the range list. + Ranges = ParseRangeList(); + if (Ranges.empty()) return true; + + if (Lex.getCode() != tgtok::greater) { + TokError("expected '>' at end of range list"); + return Error(StartLoc, "to match this '<'"); + } + Lex.Lex(); // eat the '>'. + return false; +} + +/// ParseOptionalBitList - Parse either a bit list in {}'s or nothing. +/// OptionalBitList ::= '{' RangeList '}' +/// OptionalBitList ::= /*empty*/ +bool TGParser::ParseOptionalBitList(std::vector &Ranges) { + if (Lex.getCode() != tgtok::l_brace) + return false; + + LocTy StartLoc = Lex.getLoc(); + Lex.Lex(); // eat the '{' + + // Parse the range list. + Ranges = ParseRangeList(); + if (Ranges.empty()) return true; + + if (Lex.getCode() != tgtok::r_brace) { + TokError("expected '}' at end of bit list"); + return Error(StartLoc, "to match this '{'"); + } + Lex.Lex(); // eat the '}'. + return false; +} + + +/// ParseType - Parse and return a tblgen type. This returns null on error. +/// +/// Type ::= STRING // string type +/// Type ::= BIT // bit type +/// Type ::= BITS '<' INTVAL '>' // bits type +/// Type ::= INT // int type +/// Type ::= LIST '<' Type '>' // list type +/// Type ::= CODE // code type +/// Type ::= DAG // dag type +/// Type ::= ClassID // Record Type +/// +RecTy *TGParser::ParseType() { + switch (Lex.getCode()) { + default: TokError("Unknown token when expecting a type"); return 0; + case tgtok::String: Lex.Lex(); return new StringRecTy(); + case tgtok::Bit: Lex.Lex(); return new BitRecTy(); + case tgtok::Int: Lex.Lex(); return new IntRecTy(); + case tgtok::Code: Lex.Lex(); return new CodeRecTy(); + case tgtok::Dag: Lex.Lex(); return new DagRecTy(); + case tgtok::Id: + if (Record *R = ParseClassID()) return new RecordRecTy(R); + return 0; + case tgtok::Bits: { + if (Lex.Lex() != tgtok::less) { // Eat 'bits' + TokError("expected '<' after bits type"); + return 0; + } + if (Lex.Lex() != tgtok::IntVal) { // Eat '<' + TokError("expected integer in bits type"); + return 0; + } + unsigned Val = Lex.getCurIntVal(); + if (Lex.Lex() != tgtok::greater) { // Eat count. + TokError("expected '>' at end of bits type"); + return 0; + } + Lex.Lex(); // Eat '>' + return new BitsRecTy(Val); + } + case tgtok::List: { + if (Lex.Lex() != tgtok::less) { // Eat 'bits' + TokError("expected '<' after list type"); + return 0; + } + Lex.Lex(); // Eat '<' + RecTy *SubType = ParseType(); + if (SubType == 0) return 0; + + if (Lex.getCode() != tgtok::greater) { + TokError("expected '>' at end of list type"); + return 0; + } + Lex.Lex(); // Eat '>' + return new ListRecTy(SubType); + } + } +} + +/// ParseIDValue - Parse an ID as a value and decode what it means. +/// +/// IDValue ::= ID [def local value] +/// IDValue ::= ID [def template arg] +/// IDValue ::= ID [multiclass local value] +/// IDValue ::= ID [multiclass template argument] +/// IDValue ::= ID [def name] +/// +Init *TGParser::ParseIDValue(Record *CurRec) { + assert(Lex.getCode() == tgtok::Id && "Expected ID in ParseIDValue"); + std::string Name = Lex.getCurStrVal(); + LocTy Loc = Lex.getLoc(); + Lex.Lex(); + return ParseIDValue(CurRec, Name, Loc); +} + +/// ParseIDValue - This is just like ParseIDValue above, but it assumes the ID +/// has already been read. +Init *TGParser::ParseIDValue(Record *CurRec, + const std::string &Name, LocTy NameLoc) { + if (CurRec) { + if (const RecordVal *RV = CurRec->getValue(Name)) + return new VarInit(Name, RV->getType()); + + std::string TemplateArgName = CurRec->getName()+":"+Name; + if (CurRec->isTemplateArg(TemplateArgName)) { + const RecordVal *RV = CurRec->getValue(TemplateArgName); + assert(RV && "Template arg doesn't exist??"); + return new VarInit(TemplateArgName, RV->getType()); + } + } + + if (CurMultiClass) { + std::string MCName = CurMultiClass->Rec.getName()+"::"+Name; + if (CurMultiClass->Rec.isTemplateArg(MCName)) { + const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); + assert(RV && "Template arg doesn't exist??"); + return new VarInit(MCName, RV->getType()); + } + } + + if (Record *D = Records.getDef(Name)) + return new DefInit(D); + + Error(NameLoc, "Variable not defined: '" + Name + "'"); + return 0; +} + +/// ParseSimpleValue - Parse a tblgen value. This returns null on error. +/// +/// SimpleValue ::= IDValue +/// SimpleValue ::= INTVAL +/// SimpleValue ::= STRVAL +/// SimpleValue ::= CODEFRAGMENT +/// SimpleValue ::= '?' +/// SimpleValue ::= '{' ValueList '}' +/// SimpleValue ::= ID '<' ValueListNE '>' +/// SimpleValue ::= '[' ValueList ']' +/// SimpleValue ::= '(' IDValue DagArgList ')' +/// SimpleValue ::= CONCATTOK '(' Value ',' Value ')' +/// SimpleValue ::= SHLTOK '(' Value ',' Value ')' +/// SimpleValue ::= SRATOK '(' Value ',' Value ')' +/// SimpleValue ::= SRLTOK '(' Value ',' Value ')' +/// SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')' +/// +Init *TGParser::ParseSimpleValue(Record *CurRec) { + Init *R = 0; + switch (Lex.getCode()) { + default: TokError("Unknown token when parsing a value"); break; + case tgtok::IntVal: R = new IntInit(Lex.getCurIntVal()); Lex.Lex(); break; + case tgtok::StrVal: R = new StringInit(Lex.getCurStrVal()); Lex.Lex(); break; + case tgtok::CodeFragment: + R = new CodeInit(Lex.getCurStrVal()); Lex.Lex(); break; + case tgtok::question: R = new UnsetInit(); Lex.Lex(); break; + case tgtok::Id: { + LocTy NameLoc = Lex.getLoc(); + std::string Name = Lex.getCurStrVal(); + if (Lex.Lex() != tgtok::less) // consume the Id. + return ParseIDValue(CurRec, Name, NameLoc); // Value ::= IDValue + + // Value ::= ID '<' ValueListNE '>' + if (Lex.Lex() == tgtok::greater) { + TokError("expected non-empty value list"); + return 0; + } + std::vector 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 expression. This is supposed to synthesize + // a new anonymous definition, deriving from CLASS with no + // body. + Record *Class = Records.getClass(Name); + if (!Class) { + Error(NameLoc, "Expected a class name, got '" + Name + "'"); + return 0; + } + + // Create the new record, set it as CurRec temporarily. + static unsigned AnonCounter = 0; + Record *NewRec = new Record("anonymous.val."+utostr(AnonCounter++)); + SubClassReference SCRef; + SCRef.RefLoc = NameLoc; + SCRef.Rec = Class; + SCRef.TemplateArgs = ValueList; + // Add info about the subclass to NewRec. + if (AddSubClass(NewRec, SCRef)) + return 0; + NewRec->resolveReferences(); + Records.addDef(NewRec); + + // The result of the expression is a reference to the new record. + return new DefInit(NewRec); + } + case tgtok::l_brace: { // Value ::= '{' ValueList '}' + LocTy BraceLoc = Lex.getLoc(); + Lex.Lex(); // eat the '{' + std::vector Vals; + + if (Lex.getCode() != tgtok::r_brace) { + Vals = ParseValueList(CurRec); + if (Vals.empty()) return 0; + } + if (Lex.getCode() != tgtok::r_brace) { + TokError("expected '}' at end of bit list value"); + return 0; + } + Lex.Lex(); // eat the '}' + + BitsInit *Result = new BitsInit(Vals.size()); + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy()); + if (Bit == 0) { + // FIXME: Include value in error. + Error(BraceLoc, "Element #" + utostr(i) + " ("/* << *Vals[i] + <<*/ ") is not convertable to a bit"); + return 0; + } + Result->setBit(Vals.size()-i-1, Bit); + } + return Result; + } + case tgtok::l_square: { // Value ::= '[' ValueList ']' + Lex.Lex(); // eat the '[' + std::vector Vals; + + if (Lex.getCode() != tgtok::r_square) { + Vals = ParseValueList(CurRec); + if (Vals.empty()) return 0; + } + if (Lex.getCode() != tgtok::r_square) { + TokError("expected ']' at end of list value"); + return 0; + } + Lex.Lex(); // eat the ']' + return new ListInit(Vals); + } + case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' + Lex.Lex(); // eat the '(' + Init *Operator = ParseIDValue(CurRec); + if (Operator == 0) return 0; + + std::vector > DagArgs; + if (Lex.getCode() != tgtok::r_paren) { + DagArgs = ParseDagArgList(CurRec); + if (DagArgs.empty()) return 0; + } + + if (Lex.getCode() != tgtok::r_paren) { + TokError("expected ')' in dag init"); + return 0; + } + Lex.Lex(); // eat the ')' + + return new DagInit(Operator, DagArgs); + } + case tgtok::XConcat: + case tgtok::XSRA: + case tgtok::XSRL: + case tgtok::XSHL: + case tgtok::XStrConcat: { // Value ::= !binop '(' Value ',' Value ')' + BinOpInit::BinaryOp Code; + switch (Lex.getCode()) { + default: assert(0 && "Unhandled code!"); + case tgtok::XConcat: Code = BinOpInit::CONCAT; break; + case tgtok::XSRA: Code = BinOpInit::SRA; break; + case tgtok::XSRL: Code = BinOpInit::SRL; break; + case tgtok::XSHL: Code = BinOpInit::SHL; break; + case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break; + } + Lex.Lex(); // eat the operation + if (Lex.getCode() != tgtok::l_paren) { + TokError("expected '(' after binary operator"); + return 0; + } + Lex.Lex(); // eat the '(' + + Init *LHS = ParseValue(CurRec); + if (LHS == 0) return 0; + + if (Lex.getCode() != tgtok::comma) { + TokError("expected ',' in binary operator"); + return 0; + } + Lex.Lex(); // eat the ',' + + Init *RHS = ParseValue(CurRec); + if (RHS == 0) return 0; + + if (Lex.getCode() != tgtok::r_paren) { + TokError("expected ')' in binary operator"); + return 0; + } + Lex.Lex(); // eat the ')' + return (new BinOpInit(Code, LHS, RHS))->Fold(); + } + } + + return R; +} + +/// ParseValue - Parse a tblgen value. This returns null on error. +/// +/// Value ::= SimpleValue ValueSuffix* +/// ValueSuffix ::= '{' BitList '}' +/// ValueSuffix ::= '[' BitList ']' +/// ValueSuffix ::= '.' ID +/// +Init *TGParser::ParseValue(Record *CurRec) { + Init *Result = ParseSimpleValue(CurRec); + if (Result == 0) return 0; + + // Parse the suffixes now if present. + while (1) { + switch (Lex.getCode()) { + default: return Result; + case tgtok::l_brace: { + LocTy CurlyLoc = Lex.getLoc(); + Lex.Lex(); // eat the '{' + std::vector Ranges = ParseRangeList(); + if (Ranges.empty()) return 0; + + // Reverse the bitlist. + std::reverse(Ranges.begin(), Ranges.end()); + Result = Result->convertInitializerBitRange(Ranges); + if (Result == 0) { + Error(CurlyLoc, "Invalid bit range for value"); + return 0; + } + + // Eat the '}'. + if (Lex.getCode() != tgtok::r_brace) { + TokError("expected '}' at end of bit range list"); + return 0; + } + Lex.Lex(); + break; + } + case tgtok::l_square: { + LocTy SquareLoc = Lex.getLoc(); + Lex.Lex(); // eat the '[' + std::vector Ranges = ParseRangeList(); + if (Ranges.empty()) return 0; + + Result = Result->convertInitListSlice(Ranges); + if (Result == 0) { + Error(SquareLoc, "Invalid range for list slice"); + return 0; + } + + // Eat the ']'. + if (Lex.getCode() != tgtok::r_square) { + TokError("expected ']' at end of list slice"); + return 0; + } + Lex.Lex(); + break; + } + case tgtok::period: + if (Lex.Lex() != tgtok::Id) { // eat the . + TokError("expected field identifier after '.'"); + return 0; + } + if (!Result->getFieldType(Lex.getCurStrVal())) { + // FIXME INCLUDE VALUE IN ERROR. + TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + + /*<< *$1 <<*/ "'"); + return 0; + } + Result = new FieldInit(Result, Lex.getCurStrVal()); + Lex.Lex(); // eat field name + break; + } + } +} + +/// ParseDagArgList - Parse the argument list for a dag literal expression. +/// +/// ParseDagArgList ::= Value (':' VARNAME)? +/// ParseDagArgList ::= ParseDagArgList ',' Value (':' VARNAME)? +std::vector > +TGParser::ParseDagArgList(Record *CurRec) { + std::vector > Result; + + while (1) { + Init *Val = ParseValue(CurRec); + if (Val == 0) return std::vector >(); + + // If the variable name is present, add it. + std::string VarName; + if (Lex.getCode() == tgtok::colon) { + if (Lex.Lex() != tgtok::VarName) { // eat the ':' + TokError("expected variable name in dag literal"); + return std::vector >(); + } + VarName = Lex.getCurStrVal(); + Lex.Lex(); // eat the VarName. + } + + Result.push_back(std::make_pair(Val, VarName)); + + if (Lex.getCode() != tgtok::comma) break; + Lex.Lex(); // eat the ',' + } + + return Result; +} + + +/// ParseValueList - Parse a comma separated list of values, returning them as a +/// vector. Note that this always expects to be able to parse at least one +/// value. It returns an empty list if this is not possible. +/// +/// ValueList ::= Value (',' Value) +/// +std::vector TGParser::ParseValueList(Record *CurRec) { + std::vector Result; + Result.push_back(ParseValue(CurRec)); + if (Result.back() == 0) return std::vector(); + + while (Lex.getCode() == tgtok::comma) { + Lex.Lex(); // Eat the comma + + Result.push_back(ParseValue(CurRec)); + if (Result.back() == 0) return std::vector(); + } + + return Result; +} + + + +/// ParseDeclaration - Read a declaration, returning the name of field ID, or an +/// empty string on error. This can happen in a number of different context's, +/// including within a def or in the template args for a def (which which case +/// CurRec will be non-null) and within the template args for a multiclass (in +/// which case CurRec will be null, but CurMultiClass will be set). This can +/// also happen within a def that is within a multiclass, which will set both +/// CurRec and CurMultiClass. +/// +/// Declaration ::= FIELD? Type ID ('=' Value)? +/// +std::string TGParser::ParseDeclaration(Record *CurRec, + bool ParsingTemplateArgs) { + // Read the field prefix if present. + bool HasField = Lex.getCode() == tgtok::Field; + if (HasField) Lex.Lex(); + + RecTy *Type = ParseType(); + if (Type == 0) return ""; + + if (Lex.getCode() != tgtok::Id) { + TokError("Expected identifier in declaration"); + return ""; + } + + LocTy IdLoc = Lex.getLoc(); + std::string DeclName = Lex.getCurStrVal(); + Lex.Lex(); + + if (ParsingTemplateArgs) { + if (CurRec) { + DeclName = CurRec->getName() + ":" + DeclName; + } else { + assert(CurMultiClass); + } + if (CurMultiClass) + DeclName = CurMultiClass->Rec.getName() + "::" + DeclName; + } + + // Add the value. + if (AddValue(CurRec, IdLoc, RecordVal(DeclName, Type, HasField))) + return ""; + + // If a value is present, parse it. + if (Lex.getCode() == tgtok::equal) { + Lex.Lex(); + LocTy ValLoc = Lex.getLoc(); + Init *Val = ParseValue(CurRec); + if (Val == 0 || + SetValue(CurRec, ValLoc, DeclName, std::vector(), Val)) + return ""; + } + + return DeclName; +} + +/// ParseTemplateArgList - Read a template argument list, which is a non-empty +/// sequence of template-declarations in <>'s. If CurRec is non-null, these are +/// template args for a def, which may or may not be in a multiclass. If null, +/// these are the template args for a multiclass. +/// +/// TemplateArgList ::= '<' Declaration (',' Declaration)* '>' +/// +bool TGParser::ParseTemplateArgList(Record *CurRec) { + assert(Lex.getCode() == tgtok::less && "Not a template arg list!"); + Lex.Lex(); // eat the '<' + + Record *TheRecToAddTo = CurRec ? CurRec : &CurMultiClass->Rec; + + // Read the first declaration. + std::string TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); + if (TemplArg.empty()) + return true; + + TheRecToAddTo->addTemplateArg(TemplArg); + + while (Lex.getCode() == tgtok::comma) { + Lex.Lex(); // eat the ',' + + // Read the following declarations. + TemplArg = ParseDeclaration(CurRec, true/*templateargs*/); + if (TemplArg.empty()) + return true; + TheRecToAddTo->addTemplateArg(TemplArg); + } + + if (Lex.getCode() != tgtok::greater) + return TokError("expected '>' at end of template argument list"); + Lex.Lex(); // eat the '>'. + return false; +} + + +/// ParseBodyItem - Parse a single item at within the body of a def or class. +/// +/// BodyItem ::= Declaration ';' +/// BodyItem ::= LET ID OptionalBitList '=' Value ';' +bool TGParser::ParseBodyItem(Record *CurRec) { + if (Lex.getCode() != tgtok::Let) { + if (ParseDeclaration(CurRec, false).empty()) + return true; + + if (Lex.getCode() != tgtok::semi) + return TokError("expected ';' after declaration"); + Lex.Lex(); + return false; + } + + // LET ID OptionalRangeList '=' Value ';' + if (Lex.Lex() != tgtok::Id) + return TokError("expected field identifier after let"); + + LocTy IdLoc = Lex.getLoc(); + std::string FieldName = Lex.getCurStrVal(); + Lex.Lex(); // eat the field name. + + std::vector BitList; + if (ParseOptionalBitList(BitList)) + return true; + std::reverse(BitList.begin(), BitList.end()); + + if (Lex.getCode() != tgtok::equal) + return TokError("expected '=' in let expression"); + Lex.Lex(); // eat the '='. + + Init *Val = ParseValue(CurRec); + if (Val == 0) return true; + + if (Lex.getCode() != tgtok::semi) + return TokError("expected ';' after let expression"); + Lex.Lex(); + + return SetValue(CurRec, IdLoc, FieldName, BitList, Val); +} + +/// ParseBody - Read the body of a class or def. Return true on error, false on +/// success. +/// +/// Body ::= ';' +/// Body ::= '{' BodyList '}' +/// BodyList BodyItem* +/// +bool TGParser::ParseBody(Record *CurRec) { + // If this is a null definition, just eat the semi and return. + if (Lex.getCode() == tgtok::semi) { + Lex.Lex(); + return false; + } + + if (Lex.getCode() != tgtok::l_brace) + return TokError("Expected ';' or '{' to start body"); + // Eat the '{'. + Lex.Lex(); + + while (Lex.getCode() != tgtok::r_brace) + if (ParseBodyItem(CurRec)) + return true; + + // Eat the '}'. + Lex.Lex(); + return false; +} + +/// ParseObjectBody - Parse the body of a def or class. This consists of an +/// optional ClassList followed by a Body. CurRec is the current def or class +/// that is being parsed. +/// +/// ObjectBody ::= BaseClassList Body +/// BaseClassList ::= /*empty*/ +/// BaseClassList ::= ':' BaseClassListNE +/// BaseClassListNE ::= SubClassRef (',' SubClassRef)* +/// +bool TGParser::ParseObjectBody(Record *CurRec) { + // If there is a baseclass list, read it. + if (Lex.getCode() == tgtok::colon) { + Lex.Lex(); + + // Read all of the subclasses. + SubClassReference SubClass = ParseSubClassReference(CurRec, false); + while (1) { + // Check for error. + if (SubClass.Rec == 0) return true; + + // Add it. + if (AddSubClass(CurRec, SubClass)) + return true; + + if (Lex.getCode() != tgtok::comma) break; + Lex.Lex(); // eat ','. + SubClass = ParseSubClassReference(CurRec, false); + } + } + + // Process any variables on the let stack. + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) + if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name, + LetStack[i][j].Bits, LetStack[i][j].Value)) + return true; + + return ParseBody(CurRec); +} + + +/// ParseDef - Parse and return a top level or multiclass def, return the record +/// corresponding to it. This returns null on error. +/// +/// DefInst ::= DEF ObjectName ObjectBody +/// +llvm::Record *TGParser::ParseDef(MultiClass *CurMultiClass) { + LocTy DefLoc = Lex.getLoc(); + assert(Lex.getCode() == tgtok::Def && "Unknown tok"); + Lex.Lex(); // Eat the 'def' token. + + // Parse ObjectName and make a record for it. + Record *CurRec = new Record(ParseObjectName()); + + if (!CurMultiClass) { + // Top-level def definition. + + // Ensure redefinition doesn't happen. + if (Records.getDef(CurRec->getName())) { + Error(DefLoc, "def '" + CurRec->getName() + "' already defined"); + return 0; + } + Records.addDef(CurRec); + } else { + // Otherwise, a def inside a multiclass, add it to the multiclass. + for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i) + if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) { + Error(DefLoc, "def '" + CurRec->getName() + + "' already defined in this multiclass!"); + return 0; + } + CurMultiClass->DefPrototypes.push_back(CurRec); + } + + if (ParseObjectBody(CurRec)) + return 0; + + if (CurMultiClass == 0) // Def's in multiclasses aren't really defs. + CurRec->resolveReferences(); + + // If ObjectBody has template arguments, it's an error. + assert(CurRec->getTemplateArgs().empty() && "How'd this get template args?"); + return CurRec; +} + + +/// ParseClass - Parse a tblgen class definition. +/// +/// ClassInst ::= CLASS ID TemplateArgList? ObjectBody +/// +bool TGParser::ParseClass() { + assert(Lex.getCode() == tgtok::Class && "Unexpected token!"); + Lex.Lex(); + + if (Lex.getCode() != tgtok::Id) + return TokError("expected class name after 'class' keyword"); + + Record *CurRec = Records.getClass(Lex.getCurStrVal()); + if (CurRec) { + // If the body was previously defined, this is an error. + if (!CurRec->getValues().empty() || + !CurRec->getSuperClasses().empty() || + !CurRec->getTemplateArgs().empty()) + return TokError("Class '" + CurRec->getName() + "' already defined"); + } else { + // If this is the first reference to this class, create and add it. + CurRec = new Record(Lex.getCurStrVal()); + Records.addClass(CurRec); + } + Lex.Lex(); // eat the name. + + // If there are template args, parse them. + if (Lex.getCode() == tgtok::less) + if (ParseTemplateArgList(CurRec)) + return true; + + // Finally, parse the object body. + return ParseObjectBody(CurRec); +} + +/// ParseLetList - Parse a non-empty list of assignment expressions into a list +/// of LetRecords. +/// +/// LetList ::= LetItem (',' LetItem)* +/// LetItem ::= ID OptionalRangeList '=' Value +/// +std::vector TGParser::ParseLetList() { + std::vector Result; + + while (1) { + if (Lex.getCode() != tgtok::Id) { + TokError("expected identifier in let definition"); + return std::vector(); + } + std::string Name = Lex.getCurStrVal(); + LocTy NameLoc = Lex.getLoc(); + Lex.Lex(); // Eat the identifier. + + // Check for an optional RangeList. + std::vector Bits; + if (ParseOptionalRangeList(Bits)) + return std::vector(); + std::reverse(Bits.begin(), Bits.end()); + + if (Lex.getCode() != tgtok::equal) { + TokError("expected '=' in let expression"); + return std::vector(); + } + Lex.Lex(); // eat the '='. + + Init *Val = ParseValue(0); + if (Val == 0) return std::vector(); + + // Now that we have everything, add the record. + Result.push_back(LetRecord(Name, Bits, Val, NameLoc)); + + if (Lex.getCode() != tgtok::comma) + return Result; + Lex.Lex(); // eat the comma. + } +} + +/// ParseTopLevelLet - Parse a 'let' at top level. This can be a couple of +/// different related productions. +/// +/// Object ::= LET LetList IN '{' ObjectList '}' +/// Object ::= LET LetList IN Object +/// +bool TGParser::ParseTopLevelLet() { + assert(Lex.getCode() == tgtok::Let && "Unexpected token"); + Lex.Lex(); + + // Add this entry to the let stack. + std::vector LetInfo = ParseLetList(); + if (LetInfo.empty()) return true; + LetStack.push_back(LetInfo); + + if (Lex.getCode() != tgtok::In) + return TokError("expected 'in' at end of top-level 'let'"); + Lex.Lex(); + + // If this is a scalar let, just handle it now + if (Lex.getCode() != tgtok::l_brace) { + // LET LetList IN Object + if (ParseObject()) + return true; + } else { // Object ::= LETCommand '{' ObjectList '}' + LocTy BraceLoc = Lex.getLoc(); + // Otherwise, this is a group let. + Lex.Lex(); // eat the '{'. + + // Parse the object list. + if (ParseObjectList()) + return true; + + if (Lex.getCode() != tgtok::r_brace) { + TokError("expected '}' at end of top level let command"); + return Error(BraceLoc, "to match this '{'"); + } + Lex.Lex(); + } + + // Outside this let scope, this let block is not active. + LetStack.pop_back(); + return false; +} + +/// ParseMultiClassDef - Parse a def in a multiclass context. +/// +/// MultiClassDef ::= DefInst +/// +bool TGParser::ParseMultiClassDef(MultiClass *CurMC) { + if (Lex.getCode() != tgtok::Def) + return TokError("expected 'def' in multiclass body"); + + Record *D = ParseDef(CurMC); + if (D == 0) return true; + + // Copy the template arguments for the multiclass into the def. + const std::vector &TArgs = CurMC->Rec.getTemplateArgs(); + + for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { + const RecordVal *RV = CurMC->Rec.getValue(TArgs[i]); + assert(RV && "Template arg doesn't exist?"); + D->addValue(*RV); + } + + return false; +} + +/// ParseMultiClass - Parse a multiclass definition. +/// +/// MultiClassInst ::= MULTICLASS ID TemplateArgList? '{' MultiClassDef+ '}' +/// +bool TGParser::ParseMultiClass() { + assert(Lex.getCode() == tgtok::MultiClass && "Unexpected token"); + Lex.Lex(); // Eat the multiclass token. + + if (Lex.getCode() != tgtok::Id) + return TokError("expected identifier after multiclass for name"); + std::string Name = Lex.getCurStrVal(); + + if (MultiClasses.count(Name)) + return TokError("multiclass '" + Name + "' already defined"); + + CurMultiClass = MultiClasses[Name] = new MultiClass(Name); + Lex.Lex(); // Eat the identifier. + + // If there are template args, parse them. + if (Lex.getCode() == tgtok::less) + if (ParseTemplateArgList(0)) + return true; + + if (Lex.getCode() != tgtok::l_brace) + return TokError("expected '{' in multiclass definition"); + + if (Lex.Lex() == tgtok::r_brace) // eat the '{'. + return TokError("multiclass must contain at least one def"); + + while (Lex.getCode() != tgtok::r_brace) + if (ParseMultiClassDef(CurMultiClass)) + return true; + + Lex.Lex(); // eat the '}'. + + CurMultiClass = 0; + return false; +} + +/// ParseDefm - Parse the instantiation of a multiclass. +/// +/// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' +/// +bool TGParser::ParseDefm() { + assert(Lex.getCode() == tgtok::Defm && "Unexpected token!"); + if (Lex.Lex() != tgtok::Id) // eat the defm. + return TokError("expected identifier after defm"); + + LocTy DefmPrefixLoc = Lex.getLoc(); + std::string DefmPrefix = Lex.getCurStrVal(); + if (Lex.Lex() != tgtok::colon) + return TokError("expected ':' after defm identifier"); + + // eat the colon. + Lex.Lex(); + + LocTy SubClassLoc = Lex.getLoc(); + SubClassReference Ref = ParseSubClassReference(0, true); + if (Ref.Rec == 0) return true; + + if (Lex.getCode() != tgtok::semi) + return TokError("expected ';' at end of defm"); + Lex.Lex(); + + // To instantiate a multiclass, we need to first get the multiclass, then + // instantiate each def contained in the multiclass with the SubClassRef + // template parameters. + MultiClass *MC = MultiClasses[Ref.Rec->getName()]; + assert(MC && "Didn't lookup multiclass correctly?"); + std::vector &TemplateVals = Ref.TemplateArgs; + + // Verify that the correct number of template arguments were specified. + const std::vector &TArgs = MC->Rec.getTemplateArgs(); + if (TArgs.size() < TemplateVals.size()) + return Error(SubClassLoc, + "more template args specified than multiclass expects"); + + // Loop over all the def's in the multiclass, instantiating each one. + for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { + Record *DefProto = MC->DefPrototypes[i]; + + // Add the suffix to the defm name to get the new name. + Record *CurRec = new Record(DefmPrefix + DefProto->getName()); + + SubClassReference Ref; + Ref.RefLoc = DefmPrefixLoc; + Ref.Rec = DefProto; + AddSubClass(CurRec, Ref); + + // Loop over all of the template arguments, setting them to the specified + // value or leaving them as the default if necessary. + for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { + if (i < TemplateVals.size()) { // A value is specified for this temp-arg? + // Set it now. + if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector(), + TemplateVals[i])) + return true; + + // Resolve it next. + CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); + + // Now remove it. + CurRec->removeValue(TArgs[i]); + + } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { + return Error(SubClassLoc, "value not specified for template argument #"+ + utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" + + MC->Rec.getName() + "'"); + } + } + + // If the mdef is inside a 'let' expression, add to each def. + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) + if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name, + LetStack[i][j].Bits, LetStack[i][j].Value)) { + Error(DefmPrefixLoc, "when instantiating this defm"); + return true; + } + + + // Ensure redefinition doesn't happen. + if (Records.getDef(CurRec->getName())) + return Error(DefmPrefixLoc, "def '" + CurRec->getName() + + "' already defined, instantiating defm with subdef '" + + DefProto->getName() + "'"); + Records.addDef(CurRec); + CurRec->resolveReferences(); + } + + return false; +} + +/// ParseObject +/// Object ::= ClassInst +/// Object ::= DefInst +/// Object ::= MultiClassInst +/// Object ::= DefMInst +/// Object ::= LETCommand '{' ObjectList '}' +/// Object ::= LETCommand Object +bool TGParser::ParseObject() { + switch (Lex.getCode()) { + default: assert(0 && "This is not an object"); + case tgtok::Let: return ParseTopLevelLet(); + case tgtok::Def: return ParseDef(0) == 0; + case tgtok::Defm: return ParseDefm(); + case tgtok::Class: return ParseClass(); + case tgtok::MultiClass: return ParseMultiClass(); + } +} + +/// ParseObjectList +/// ObjectList :== Object* +bool TGParser::ParseObjectList() { + while (isObjectStart(Lex.getCode())) { + if (ParseObject()) + return true; + } + return false; +} + + +bool TGParser::ParseFile() { + Lex.Lex(); // Prime the lexer. + if (ParseObjectList()) return true; + + // If we have unread input at the end of the file, report it. + if (Lex.getCode() == tgtok::Eof) + return false; + + return TokError("Unexpected input at top level"); +} + Added: llvm/trunk/utils/TableGen/TGParser.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.h?rev=44274&view=auto ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.h (added) +++ llvm/trunk/utils/TableGen/TGParser.h Thu Nov 22 14:49:04 2007 @@ -0,0 +1,109 @@ +//===- TGParser.h - Parser for TableGen Files -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class represents the Parser for tablegen files. +// +//===----------------------------------------------------------------------===// + +#ifndef TGPARSER_H +#define TGPARSER_H + +#include "TGLexer.h" +#include + +namespace llvm { + class Record; + class RecordVal; + class RecTy; + class Init; + struct MultiClass; + struct SubClassReference; + + struct LetRecord { + std::string Name; + std::vector Bits; + Init *Value; + TGLexer::LocTy Loc; + LetRecord(const std::string &N, const std::vector &B, Init *V, + TGLexer::LocTy L) + : Name(N), Bits(B), Value(V), Loc(L) { + } + }; + +class TGParser { + TGLexer Lex; + std::vector > LetStack; + std::map MultiClasses; + + /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the + /// current value. + MultiClass *CurMultiClass; +public: + typedef TGLexer::LocTy LocTy; + + TGParser(MemoryBuffer *StartBuf) : Lex(StartBuf), CurMultiClass(0) {} + + void setIncludeDirs(const std::vector &D){Lex.setIncludeDirs(D);} + + /// ParseFile - Main entrypoint for parsing a tblgen file. These parser + /// routines return true on error, or false on success. + bool ParseFile(); + + bool Error(LocTy L, const std::string &Msg) const { + Lex.PrintError(L, Msg); + return true; + } + bool TokError(const std::string &Msg) const { + return Error(Lex.getLoc(), Msg); + } +private: // Semantic analysis methods. + bool AddValue(Record *TheRec, LocTy Loc, const RecordVal &RV); + bool SetValue(Record *TheRec, LocTy Loc, const std::string &ValName, + const std::vector &BitList, Init *V); + bool AddSubClass(Record *Rec, class SubClassReference &SubClass); + +private: // Parser methods. + bool ParseObjectList(); + bool ParseObject(); + bool ParseClass(); + bool ParseMultiClass(); + bool ParseMultiClassDef(MultiClass *CurMC); + bool ParseDefm(); + bool ParseTopLevelLet(); + std::vector ParseLetList(); + + Record *ParseDef(MultiClass *CurMultiClass); + bool ParseObjectBody(Record *CurRec); + bool ParseBody(Record *CurRec); + bool ParseBodyItem(Record *CurRec); + + bool ParseTemplateArgList(Record *CurRec); + std::string ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs); + + SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm); + + Init *ParseIDValue(Record *CurRec); + Init *ParseIDValue(Record *CurRec, const std::string &Name, LocTy NameLoc); + Init *ParseSimpleValue(Record *CurRec); + Init *ParseValue(Record *CurRec); + std::vector ParseValueList(Record *CurRec); + std::vector > ParseDagArgList(Record *); + bool ParseOptionalRangeList(std::vector &Ranges); + bool ParseOptionalBitList(std::vector &Ranges); + std::vector ParseRangeList(); + bool ParseRangePiece(std::vector &Ranges); + RecTy *ParseType(); + std::string ParseObjectName(); + Record *ParseClassID(); + Record *ParseDefmID(); +}; + +} // end namespace llvm + +#endif Modified: llvm/trunk/utils/TableGen/TableGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TableGen.cpp?rev=44274&r1=44273&r2=44274&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TableGen.cpp (original) +++ llvm/trunk/utils/TableGen/TableGen.cpp Thu Nov 22 14:49:04 2007 @@ -16,10 +16,12 @@ //===----------------------------------------------------------------------===// #include "Record.h" +#include "TGParser.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Streams.h" #include "llvm/System/Signals.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/MemoryBuffer.h" #include "CallingConvEmitter.h" #include "CodeEmitterGen.h" #include "RegisterInfoEmitter.h" @@ -93,16 +95,35 @@ cl::value_desc("directory"), cl::Prefix); } -namespace llvm { - void ParseFile(const std::string &Filename, - const std::vector &IncludeDirs); -} - RecordKeeper llvm::Records; +/// ParseFile - this function begins the parsing of the specified tablegen +/// file. +static bool ParseFile(const std::string &Filename, + const std::vector &IncludeDirs) { + std::string ErrorStr; + MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(&Filename[0], Filename.size(), + &ErrorStr); + if (F == 0) { + cerr << "Could not open input file '" + Filename + "': " << ErrorStr <<"\n"; + return true; + } + + TGParser Parser(F); + + // Record the location of the include directory so that the lexer can find + // it later. + Parser.setIncludeDirs(IncludeDirs); + + return Parser.ParseFile(); +} + int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); - ParseFile(InputFilename, IncludeDirs); + + // Parse the input file. + if (ParseFile(InputFilename, IncludeDirs)) + return 1; std::ostream *Out = cout.stream(); if (OutputFilename != "-") { From sabre at nondot.org Thu Nov 22 14:51:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 20:51:34 -0000 Subject: [llvm-commits] [llvm] r44275 - in /llvm/trunk/utils/TableGen: Record.cpp Record.h Message-ID: <200711222051.lAMKpY1G006288@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 14:51:34 2007 New Revision: 44275 URL: http://llvm.org/viewvc/llvm-project?rev=44275&view=rev Log: eliminate a bunch of print methods that are duplicate with the getAsString() method. Modified: llvm/trunk/utils/TableGen/Record.cpp llvm/trunk/utils/TableGen/Record.h Modified: llvm/trunk/utils/TableGen/Record.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=44275&r1=44274&r2=44275&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.cpp (original) +++ llvm/trunk/utils/TableGen/Record.cpp Thu Nov 22 14:51:34 2007 @@ -155,10 +155,6 @@ return "list<" + Ty->getAsString() + ">"; } -void ListRecTy::print(std::ostream &OS) const { - OS << "list<" << *Ty << ">"; -} - Init *ListRecTy::convertValue(ListInit *LI) { std::vector Elements; @@ -209,10 +205,6 @@ return Rec->getName(); } -void RecordRecTy::print(std::ostream &OS) const { - OS << Rec->getName(); -} - Init *RecordRecTy::convertValue(DefInit *DI) { // Ensure that DI is a subclass of Rec. if (!DI->getDef()->isSubClassOf(Rec)) Modified: llvm/trunk/utils/TableGen/Record.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=44275&r1=44274&r2=44275&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.h (original) +++ llvm/trunk/utils/TableGen/Record.h Thu Nov 22 14:51:34 2007 @@ -63,7 +63,7 @@ virtual ~RecTy() {} virtual std::string getAsString() const = 0; - virtual void print(std::ostream &OS) const = 0; + void print(std::ostream &OS) const { OS << getAsString(); } void dump() const; /// typeIsConvertibleTo - Return true if all values of 'this' type can be @@ -129,7 +129,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const { return "bit"; } - void print(std::ostream &OS) const { OS << "bit"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -172,7 +171,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const; - void print(std::ostream &OS) const { OS << "bits<" << Size << ">"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -211,7 +209,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const { return "int"; } - void print(std::ostream &OS) const { OS << "int"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -248,7 +245,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const { return "string"; } - void print(std::ostream &OS) const { OS << "string"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -292,7 +288,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const; - void print(std::ostream &OS) const; bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -330,7 +325,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const { return "code"; } - void print(std::ostream &OS) const { OS << "code"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -365,7 +359,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const { return "dag"; } - void print(std::ostream &OS) const { OS << "dag"; } bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); @@ -408,7 +401,6 @@ virtual Init *convertValue( FieldInit *FI) { return RecTy::convertValue(FI);} std::string getAsString() const; - void print(std::ostream &OS) const; bool typeIsConvertibleTo(const RecTy *RHS) const { return RHS->baseClassOf(this); From sabre at nondot.org Thu Nov 22 15:05:25 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 21:05:25 -0000 Subject: [llvm-commits] [llvm] r44276 - in /llvm/trunk/utils/TableGen: Record.cpp Record.h Message-ID: <200711222105.lAML5PO2006959@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 15:05:25 2007 New Revision: 44276 URL: http://llvm.org/viewvc/llvm-project?rev=44276&view=rev Log: change the Init print methods to return strings, and implement print in terms of that. Modified: llvm/trunk/utils/TableGen/Record.cpp llvm/trunk/utils/TableGen/Record.h Modified: llvm/trunk/utils/TableGen/Record.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=44276&r1=44275&r2=44276&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.cpp (original) +++ llvm/trunk/utils/TableGen/Record.cpp Thu Nov 22 15:05:25 2007 @@ -244,20 +244,20 @@ return BI; } -void BitsInit::print(std::ostream &OS) const { +std::string BitsInit::getAsString() const { //if (!printInHex(OS)) return; //if (!printAsVariable(OS)) return; //if (!printAsUnset(OS)) return; - OS << "{ "; + std::string Result = "{ "; for (unsigned i = 0, e = getNumBits(); i != e; ++i) { - if (i) OS << ", "; + if (i) Result += ", "; if (Init *Bit = getBit(e-i-1)) - Bit->print(OS); + Result += Bit->getAsString(); else - OS << "*"; + Result += "*"; } - OS << " }"; + return Result + " }"; } bool BitsInit::printInHex(std::ostream &OS) const { @@ -330,6 +330,10 @@ return this; } +std::string IntInit::getAsString() const { + return itostr(Value); +} + Init *IntInit::convertInitializerBitRange(const std::vector &Bits) { BitsInit *BI = new BitsInit(Bits.size()); @@ -382,13 +386,13 @@ return this; } -void ListInit::print(std::ostream &OS) const { - OS << "["; +std::string ListInit::getAsString() const { + std::string Result = "["; for (unsigned i = 0, e = Values.size(); i != e; ++i) { - if (i) OS << ", "; - OS << *Values[i]; + if (i) Result += ", "; + Result += Values[i]->getAsString(); } - OS << "]"; + return Result + "]"; } Init *BinOpInit::Fold() { @@ -464,19 +468,16 @@ return Fold(); } -void BinOpInit::print(std::ostream &OS) const { +std::string BinOpInit::getAsString() const { + std::string Result; switch (Opc) { - case CONCAT: OS << "!con"; break; - 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 << ")"; + case CONCAT: Result = "!con"; break; + case SHL: Result = "!shl"; break; + case SRA: Result = "!sra"; break; + case SRL: Result = "!srl"; break; + case STRCONCAT: Result = "!strconcat"; break; + } + return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; } Init *TypedInit::convertInitializerBitRange(const std::vector &Bits) { @@ -579,6 +580,9 @@ return this; } +std::string VarBitInit::getAsString() const { + return TI->getAsString() + "{" + utostr(Bit) + "}"; +} Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) { if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum())) @@ -586,6 +590,10 @@ return this; } +std::string VarListElementInit::getAsString() const { + return TI->getAsString() + "[" + utostr(Element) + "]"; +} + Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) { if (Init *I = getVariable()->resolveListElementReference(R, RV, getElementNum())) @@ -618,8 +626,8 @@ } -void DefInit::print(std::ostream &OS) const { - OS << Def->getName(); +std::string DefInit::getAsString() const { + return Def->getName(); } Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV, @@ -679,17 +687,17 @@ } -void DagInit::print(std::ostream &OS) const { - OS << "(" << *Val; +std::string DagInit::getAsString() const { + std::string Result = "(" + Val->getAsString(); if (Args.size()) { - OS << " " << *Args[0]; - if (!ArgNames[0].empty()) OS << ":$" << ArgNames[0]; + Result += " " + Args[0]->getAsString(); + if (!ArgNames[0].empty()) Result += ":$" + ArgNames[0]; for (unsigned i = 1, e = Args.size(); i != e; ++i) { - OS << ", " << *Args[i]; - if (!ArgNames[i].empty()) OS << ":$" << ArgNames[i]; + Result += ", " + Args[i]->getAsString(); + if (!ArgNames[i].empty()) Result += ":$" + ArgNames[i]; } } - OS << ")"; + return Result + ")"; } Modified: llvm/trunk/utils/TableGen/Record.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=44276&r1=44275&r2=44276&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/Record.h (original) +++ llvm/trunk/utils/TableGen/Record.h Thu Nov 22 15:05:25 2007 @@ -429,7 +429,10 @@ virtual bool isComplete() const { return true; } /// print - Print out this value. - virtual void print(std::ostream &OS) const = 0; + void print(std::ostream &OS) const { OS << getAsString(); } + + /// getAsString - Convert this value to a string form. + virtual std::string getAsString() const = 0; /// dump - Debugging method that may be called through a debugger, just /// invokes print on cerr. @@ -497,7 +500,7 @@ } virtual bool isComplete() const { return false; } - virtual void print(std::ostream &OS) const { OS << "?"; } + virtual std::string getAsString() const { return "?"; } }; @@ -514,7 +517,7 @@ return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << (Value ? "1" : "0"); } + virtual std::string getAsString() const { return Value ? "1" : "0"; } }; /// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. @@ -547,7 +550,7 @@ if (!getBit(i)->isComplete()) return false; return true; } - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV); @@ -573,7 +576,7 @@ } virtual Init *convertInitializerBitRange(const std::vector &Bits); - virtual void print(std::ostream &OS) const { OS << Value; } + virtual std::string getAsString() const; }; @@ -590,7 +593,7 @@ return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << "\"" << Value << "\""; } + virtual std::string getAsString() const { return "\"" + Value + "\""; } }; /// CodeInit - "[{...}]" - Represent a code fragment. @@ -606,7 +609,7 @@ return Ty->convertValue(this); } - virtual void print(std::ostream &OS) const { OS << "[{" << Value << "}]"; } + virtual std::string getAsString() const { return "[{" + Value + "}]"; } }; /// ListInit - [AL, AH, CL] - Represent a list of defs @@ -639,7 +642,7 @@ /// virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; }; /// BinOpInit - !op (X, Y) - Combine two inits. @@ -668,7 +671,7 @@ virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; }; @@ -728,7 +731,7 @@ /// virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const { OS << VarName; } + virtual std::string getAsString() const { return VarName; } }; @@ -751,9 +754,7 @@ TypedInit *getVariable() const { return TI; } unsigned getBitNum() const { return Bit; } - virtual void print(std::ostream &OS) const { - TI->print(OS); OS << "{" << Bit << "}"; - } + virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV); }; @@ -786,9 +787,7 @@ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt); - virtual void print(std::ostream &OS) const { - TI->print(OS); OS << "[" << Element << "]"; - } + virtual std::string getAsString() const; virtual Init *resolveReferences(Record &R, const RecordVal *RV); }; @@ -810,7 +809,7 @@ virtual RecTy *getFieldType(const std::string &FieldName) const; virtual Init *getFieldInit(Record &R, const std::string &FieldName) const; - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; }; @@ -836,8 +835,8 @@ virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const { - Rec->print(OS); OS << "." << FieldName; + virtual std::string getAsString() const { + return Rec->getAsString() + "." + FieldName; } }; @@ -887,7 +886,7 @@ virtual Init *resolveReferences(Record &R, const RecordVal *RV); - virtual void print(std::ostream &OS) const; + virtual std::string getAsString() const; }; //===----------------------------------------------------------------------===// From sabre at nondot.org Thu Nov 22 15:06:59 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 21:06:59 -0000 Subject: [llvm-commits] [llvm] r44277 - /llvm/trunk/utils/TableGen/TGParser.cpp Message-ID: <200711222107.lAML70m9007080@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 15:06:59 2007 New Revision: 44277 URL: http://llvm.org/viewvc/llvm-project?rev=44277&view=rev Log: resolve the last fixme's in the new tblgen parser. Modified: llvm/trunk/utils/TableGen/TGParser.cpp Modified: llvm/trunk/utils/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=44277&r1=44276&r2=44277&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGParser.cpp (original) +++ llvm/trunk/utils/TableGen/TGParser.cpp Thu Nov 22 15:06:59 2007 @@ -116,7 +116,7 @@ if (RV->setValue(V)) return Error(Loc, "Value '" + ValName + "' of type '" + RV->getType()->getAsString() + - "' is incompatible with initializer ''"); // FIXME: Add init! + "' is incompatible with initializer '" + V->getAsString() +"'"); return false; } @@ -586,9 +586,8 @@ for (unsigned i = 0, e = Vals.size(); i != e; ++i) { Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy()); if (Bit == 0) { - // FIXME: Include value in error. - Error(BraceLoc, "Element #" + utostr(i) + " ("/* << *Vals[i] - <<*/ ") is not convertable to a bit"); + Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+ + ") is not convertable to a bit"); return 0; } Result->setBit(Vals.size()-i-1, Bit); @@ -737,9 +736,8 @@ return 0; } if (!Result->getFieldType(Lex.getCurStrVal())) { - // FIXME INCLUDE VALUE IN ERROR. TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + - /*<< *$1 <<*/ "'"); + Result->getAsString() + "'"); return 0; } Result = new FieldInit(Result, Lex.getCurStrVal()); From baldrick at free.fr Thu Nov 22 15:40:06 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 22 Nov 2007 21:40:06 -0000 Subject: [llvm-commits] [llvm] r44278 - in /llvm/trunk: lib/Transforms/Scalar/ADCE.cpp test/Transforms/ADCE/dce_pure_invoke.ll Message-ID: <200711222140.lAMLe6Cm009012@zion.cs.uiuc.edu> Author: baldrick Date: Thu Nov 22 15:40:06 2007 New Revision: 44278 URL: http://llvm.org/viewvc/llvm-project?rev=44278&view=rev Log: Readonly/readnone functions are allowed to throw exceptions, so don't turn invokes of them into calls. Modified: llvm/trunk/lib/Transforms/Scalar/ADCE.cpp llvm/trunk/test/Transforms/ADCE/dce_pure_invoke.ll Modified: llvm/trunk/lib/Transforms/Scalar/ADCE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ADCE.cpp?rev=44278&r1=44277&r2=44278&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/ADCE.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/ADCE.cpp Thu Nov 22 15:40:06 2007 @@ -34,7 +34,7 @@ STATISTIC(NumBlockRemoved, "Number of basic blocks removed"); STATISTIC(NumInstRemoved , "Number of instructions removed"); -STATISTIC(NumCallRemoved , "Number of calls and invokes removed"); +STATISTIC(NumCallRemoved , "Number of calls removed"); namespace { //===----------------------------------------------------------------------===// @@ -184,32 +184,6 @@ AliasAnalysis &AA = getAnalysis(); - - // Iterate over all invokes in the function, turning invokes into calls if - // they cannot throw. - for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) - if (InvokeInst *II = dyn_cast(BB->getTerminator())) - if (Function *F = II->getCalledFunction()) - if (AA.onlyReadsMemory(F)) { - // The function cannot unwind. Convert it to a call with a branch - // after it to the normal destination. - SmallVector Args(II->op_begin()+3, II->op_end()); - CallInst *NewCall = new CallInst(F, Args.begin(), Args.end(), "", II); - NewCall->takeName(II); - NewCall->setCallingConv(II->getCallingConv()); - II->replaceAllUsesWith(NewCall); - new BranchInst(II->getNormalDest(), II); - - // Update PHI nodes in the unwind destination - II->getUnwindDest()->removePredecessor(BB); - BB->getInstList().erase(II); - - if (NewCall->use_empty()) { - BB->getInstList().erase(NewCall); - ++NumCallRemoved; - } - } - // Iterate over all of the instructions in the function, eliminating trivially // dead instructions, and marking instructions live that are known to be // needed. Perform the walk in depth first order so that we avoid marking any Modified: llvm/trunk/test/Transforms/ADCE/dce_pure_invoke.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/dce_pure_invoke.ll?rev=44278&r1=44277&r2=44278&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ADCE/dce_pure_invoke.ll (original) +++ llvm/trunk/test/Transforms/ADCE/dce_pure_invoke.ll Thu Nov 22 15:40:06 2007 @@ -1,13 +1,15 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -adce | llvm-dis | not grep null +; RUN: llvm-as < %s | opt -adce | llvm-dis | grep null -declare int %strlen(sbyte*) +declare i32 @strlen(i8*) readnone -int %test() { - ;; Dead call should be deleted! - invoke int %strlen(sbyte *null) to label %Cont unwind label %Other -Cont: - ret int 0 -Other: - ret int 1 -} +define i32 @test() { + ; invoke of pure function should not be deleted! + invoke i32 @strlen( i8* null ) readnone + to label %Cont unwind label %Other ; :1 [#uses=0] + +Cont: ; preds = %0 + ret i32 0 +Other: ; preds = %0 + ret i32 1 +} From baldrick at free.fr Thu Nov 22 15:43:27 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 22 Nov 2007 21:43:27 -0000 Subject: [llvm-commits] [llvm] r44279 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/pure-const-dce.ll Message-ID: <200711222143.lAMLhSDt009340@zion.cs.uiuc.edu> Author: baldrick Date: Thu Nov 22 15:43:27 2007 New Revision: 44279 URL: http://llvm.org/viewvc/llvm-project?rev=44279&view=rev Log: Teach alias analysis about readnone/readonly functions. Based on a patch by T?r?k Edwin. Added: llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=44279&r1=44278&r2=44279&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Thu Nov 22 15:43:27 2007 @@ -952,6 +952,12 @@ if (Ptr != OnlyReadsMemoryTable->end() && strcmp(*Ptr, NamePtr) == 0) return OnlyReadsMemory; + const ParamAttrsList *Attrs = F->getFunctionType()->getParamAttrs(); + if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadNone)) + return DoesNotAccessMemory; + if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadOnly)) + return OnlyReadsMemory; + return UnknownModRefBehavior; } Added: llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll?rev=44279&view=auto ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll (added) +++ llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll Thu Nov 22 15:43:27 2007 @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2 +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure | not count 2 +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone | count 4 + at g = global i32 0 ; [#uses=1] + +define i32 @test() { +entry: + %tmp0 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp1 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp2 = call i32 @TestNone( i32 7 ) ; [#uses=1] + store i32 1, i32* @g + %tmp3 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp4 = call i32 @TestConst( i32 5 ) readnone ; [#uses=1] + %tmp5 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp6 = call i32 @TestPure( i32 6 ) readonly ; [#uses=1] + %tmp7 = call i32 @TestNone( i32 7 ) ; [#uses=1] + %tmp8 = call i32 @TestNone( i32 7 ) ; [#uses=1] + %sum0 = add i32 %tmp0, %tmp1 ; [#uses=1] + %sum1 = add i32 %sum0, %tmp2 ; [#uses=1] + %sum2 = add i32 %sum1, %tmp3 ; [#uses=1] + %sum3 = add i32 %sum2, %tmp4 ; [#uses=1] + %sum4 = add i32 %sum3, %tmp5 ; [#uses=1] + %sum5 = add i32 %sum4, %tmp6 ; [#uses=1] + %sum6 = add i32 %sum5, %tmp7 ; [#uses=1] + %sum7 = add i32 %sum6, %tmp8 ; [#uses=1] + ret i32 %sum7 +} + +declare i32 @TestConst(i32) readnone + +declare i32 @TestPure(i32) readonly + +declare i32 @TestNone(i32) From baldrick at free.fr Thu Nov 22 16:25:00 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 22 Nov 2007 22:25:00 -0000 Subject: [llvm-commits] [llvm] r44280 - in /llvm/trunk: lib/Transforms/Scalar/SimplifyCFG.cpp test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll Message-ID: <200711222225.lAMMP0Lg011988@zion.cs.uiuc.edu> Author: baldrick Date: Thu Nov 22 16:24:59 2007 New Revision: 44280 URL: http://llvm.org/viewvc/llvm-project?rev=44280&view=rev Log: Turn invokes of nounwind functions into ordinary calls. Added: llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp?rev=44280&r1=44279&r2=44280&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Thu Nov 22 16:24:59 2007 @@ -71,6 +71,28 @@ } } +/// ChangeToCall - Convert the specified invoke into a normal call. +static void ChangeToCall(InvokeInst *II) { + BasicBlock *BB = II->getParent(); + SmallVector Args(II->op_begin()+3, II->op_end()); + CallInst *NewCall = new CallInst(II->getCalledValue(), Args.begin(), + Args.end(), "", II); + NewCall->takeName(II); + NewCall->setCallingConv(II->getCallingConv()); + NewCall->setParamAttrs(II->getParamAttrs()); + II->replaceAllUsesWith(NewCall); + + // Follow the call by a branch to the normal destination. + new BranchInst(II->getNormalDest(), II); + + // Update PHI nodes in the unwind destination + II->getUnwindDest()->removePredecessor(BB); + BB->getInstList().erase(II); + + if (NewCall->use_empty()) + BB->getInstList().erase(NewCall); +} + /// IsNoReturn - Return true if the specified call is to a no-return function. static bool IsNoReturn(const CallInst *CI) { if (const ParamAttrsList *Attrs = CI->getParamAttrs()) @@ -90,6 +112,25 @@ return false; } +/// IsNoUnwind - Return true if the specified invoke is to a no-unwind function. +static bool IsNoUnwind(const InvokeInst *II) { + if (const ParamAttrsList *Attrs = II->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + + if (const Function *Callee = II->getCalledFunction()) { + if (const ParamAttrsList *Attrs = Callee->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + + const FunctionType *FT = Callee->getFunctionType(); + if (const ParamAttrsList *Attrs = FT->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + } + return false; +} + static bool MarkAliveBlocks(BasicBlock *BB, SmallPtrSet &Reachable) { @@ -106,7 +147,7 @@ // Do a quick scan of the basic block, turning any obviously unreachable // instructions into LLVM unreachable insts. The instruction combining pass - // canonnicalizes unreachable insts into stores to null or undef. + // canonicalizes unreachable insts into stores to null or undef. for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E;++BBI){ if (CallInst *CI = dyn_cast(BBI)) { if (IsNoReturn(CI)) { @@ -131,6 +172,13 @@ } } + // Turn invokes that call 'nounwind' functions into ordinary calls. + if (InvokeInst *II = dyn_cast(BB->getTerminator())) + if (IsNoUnwind(II)) { + ChangeToCall(II); + Changed = true; + } + Changed |= ConstantFoldTerminator(BB); for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) Worklist.push_back(*SI); Added: llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll?rev=44280&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll (added) +++ llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll Thu Nov 22 16:24:59 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | not grep invoke + +declare i32 @func(i8*) nounwind + +define i32 @test() { + invoke i32 @func( i8* null ) nounwind + to label %Cont unwind label %Other ; :1 [#uses=0] + +Cont: ; preds = %0 + ret i32 0 + +Other: ; preds = %0 + ret i32 1 +} From asl at math.spbu.ru Thu Nov 22 16:30:12 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Thu, 22 Nov 2007 22:30:12 -0000 Subject: [llvm-commits] [llvm] r44281 - /llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Message-ID: <200711222230.lAMMUC0N012262@zion.cs.uiuc.edu> Author: asl Date: Thu Nov 22 16:30:10 2007 New Revision: 44281 URL: http://llvm.org/viewvc/llvm-project?rev=44281&view=rev Log: Don't crash on bogus llvm.noinline. This is first part of PR1817 (preventing reduction) Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=44281&r1=44280&r2=44281&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Thu Nov 22 16:30:10 2007 @@ -59,6 +59,10 @@ if (GV == 0) return false; + // Don't crash on invalid code + if (!GV->hasInitializer()) + return false; + const ConstantArray *InitList = dyn_cast(GV->getInitializer()); if (InitList == 0) From sabre at nondot.org Thu Nov 22 17:19:05 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 23:19:05 -0000 Subject: [llvm-commits] [llvm] r44282 - /llvm/trunk/utils/TableGen/TGLexer.h Message-ID: <200711222319.lAMNJ6Dj014794@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 17:19:05 2007 New Revision: 44282 URL: http://llvm.org/viewvc/llvm-project?rev=44282&view=rev Log: add missing #include Modified: llvm/trunk/utils/TableGen/TGLexer.h Modified: llvm/trunk/utils/TableGen/TGLexer.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=44282&r1=44281&r2=44282&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/TGLexer.h (original) +++ llvm/trunk/utils/TableGen/TGLexer.h Thu Nov 22 17:19:05 2007 @@ -17,6 +17,7 @@ #include #include #include +#include namespace llvm { class MemoryBuffer; From sabre at nondot.org Thu Nov 22 17:43:30 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 23:43:30 -0000 Subject: [llvm-commits] [llvm] r44283 - /llvm/trunk/include/llvm/Instructions.h Message-ID: <200711222343.lAMNhUA2016122@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 17:43:29 2007 New Revision: 44283 URL: http://llvm.org/viewvc/llvm-project?rev=44283&view=rev Log: add some static icmpinst predicates. Modified: llvm/trunk/include/llvm/Instructions.h Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=44283&r1=44282&r2=44283&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Thu Nov 22 17:43:29 2007 @@ -640,24 +640,34 @@ /// @brief Return the signed version of the predicate. static Predicate getSignedPredicate(Predicate pred); - /// This also tests for commutativity. If isEquality() returns true then - /// the predicate is also commutative. - /// @returns true if the predicate of this instruction is EQ or NE. - /// @brief Determine if this is an equality predicate. + /// isEquality - Return true if this predicate is either EQ or NE. This also + /// tests for commutativity. + static bool isEquality(Predicate P) { + return P == ICMP_EQ || P == ICMP_NE; + } + + /// isEquality - Return true if this predicate is either EQ or NE. This also + /// tests for commutativity. bool isEquality() const { - return SubclassData == ICMP_EQ || SubclassData == ICMP_NE; + return isEquality(getPredicate()); } /// @returns true if the predicate of this ICmpInst is commutative /// @brief Determine if this relation is commutative. bool isCommutative() const { return isEquality(); } - /// @returns true if the predicate is relational (not EQ or NE). - /// @brief Determine if this a relational predicate. + /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// bool isRelational() const { return !isEquality(); } + /// isRelational - Return true if the predicate is relational (not EQ or NE). + /// + static bool isRelational(Predicate P) { + return !isEquality(P); + } + /// @returns true if the predicate of this ICmpInst is signed, false otherwise /// @brief Determine if this instruction's predicate is signed. bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); } From sabre at nondot.org Thu Nov 22 17:47:13 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 22 Nov 2007 23:47:13 -0000 Subject: [llvm-commits] [llvm] r44284 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll Message-ID: <200711222347.lAMNlDZB016582@zion.cs.uiuc.edu> Author: lattner Date: Thu Nov 22 17:47:13 2007 New Revision: 44284 URL: http://llvm.org/viewvc/llvm-project?rev=44284&view=rev Log: Fix PR1817. Added: llvm/trunk/test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44284&r1=44283&r2=44284&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Thu Nov 22 17:47:13 2007 @@ -3463,7 +3463,12 @@ LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE && RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE && LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE && - RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE) { + RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE && + + // Don't try to fold ICMP_SLT + ICMP_ULT. + (ICmpInst::isEquality(LHSCC) || ICmpInst::isEquality(RHSCC) || + ICmpInst::isSignedPredicate(LHSCC) == + ICmpInst::isSignedPredicate(RHSCC))) { // Ensure that the larger constant is on the RHS. ICmpInst::Predicate GT = ICmpInst::isSignedPredicate(LHSCC) ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; Added: llvm/trunk/test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll?rev=44284&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2007-11-22-IcmpCrash.ll Thu Nov 22 17:47:13 2007 @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output +; PR1817 + +define i1 @test1(i32 %X) { + %A = icmp slt i32 %X, 10 + %B = icmp ult i32 %X, 10 + %C = and i1 %A, %B + ret i1 %C +} + +define i1 @test2(i32 %X) { + %A = icmp slt i32 %X, 10 + %B = icmp ult i32 %X, 10 + %C = or i1 %A, %B + ret i1 %C +} From zhousheng00 at gmail.com Thu Nov 22 20:34:11 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Fri, 23 Nov 2007 10:34:11 +0800 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] Message-ID: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> Hi, Here is the patch to make llvm-gcc/llvm-g++ emit llvm.pow.* when errno disabled. Thanks for revewing. Sheng. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071123/d26a1e8b/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: INTRINSIC_POW.patch Type: text/x-patch Size: 3337 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071123/d26a1e8b/attachment.bin From sabre at nondot.org Fri Nov 23 02:46:23 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 08:46:23 -0000 Subject: [llvm-commits] [llvm] r44286 - in /llvm/trunk: lib/Analysis/ScalarEvolution.cpp test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll Message-ID: <200711230846.lAN8kNgo021896@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 02:46:22 2007 New Revision: 44286 URL: http://llvm.org/viewvc/llvm-project?rev=44286&view=rev Log: Fix a bug where we'd try to find a scev value for a bitcast operand, even though the bitcast operand did not have integer type. This fixes PR1814. Added: llvm/trunk/test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44286&r1=44285&r2=44286&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri Nov 23 02:46:22 2007 @@ -1470,6 +1470,9 @@ /// Analyze the expression. /// SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) { + if (!isa(V->getType())) + return SE.getUnknown(V); + if (Instruction *I = dyn_cast(V)) { switch (I->getOpcode()) { case Instruction::Add: @@ -2076,6 +2079,11 @@ if (Constant *C = dyn_cast(Op)) { Operands.push_back(C); } else { + // If any of the operands is non-constant and if they are + // non-integer, don't even try to analyze them with scev techniques. + if (!isa(Op->getType())) + return V; + SCEVHandle OpV = getSCEVAtScope(getSCEV(Op), L); if (SCEVConstant *SC = dyn_cast(OpV)) Operands.push_back(ConstantExpr::getIntegerCast(SC->getValue(), Added: llvm/trunk/test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll?rev=44286&view=auto ============================================================================== --- llvm/trunk/test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll (added) +++ llvm/trunk/test/Transforms/IndVarsSimplify/2007-11-23-BitcastCrash.ll Fri Nov 23 02:46:22 2007 @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | opt -indvars -disable-output +; PR1814 +target datalayout = "e-p:32:32-f64:32:64-i64:32:64-f80:32:32" + +define void @FuncAt1938470480(i32, i32, i32, i32, i32, i32, i32, i32, i64, i64, i64, i64, i64, i64, i64, i64, i1, i1, i1, i1, i1, i1) { +EntryBlock: + br label %asmBlockAt738ab7f3 + +asmBlockAt738ab9b0: ; preds = %asmBlockAt738ab7f3 + %.lcssa6 = phi i64 [ %23, %asmBlockAt738ab7f3 ] ; [#uses=0] + ret void + +asmBlockAt738ab7f3: ; preds = %asmBlockAt738ab7f3, %EntryBlock + %ebp95 = phi i32 [ 128, %EntryBlock ], [ %24, %asmBlockAt738ab7f3 ] ; [#uses=2] + sub <4 x i16> zeroinitializer, zeroinitializer ; <<4 x i16>>:22 [#uses=1] + bitcast <4 x i16> %22 to i64 ; :23 [#uses=1] + add i32 %ebp95, -64 ; :24 [#uses=1] + icmp ult i32 %ebp95, 64 ; :25 [#uses=1] + br i1 %25, label %asmBlockAt738ab9b0, label %asmBlockAt738ab7f3 +} From baldrick at free.fr Fri Nov 23 03:10:17 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 23 Nov 2007 09:10:17 -0000 Subject: [llvm-commits] [llvm] r44287 - /llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Message-ID: <200711230910.lAN9AHL8023058@zion.cs.uiuc.edu> Author: baldrick Date: Fri Nov 23 03:10:17 2007 New Revision: 44287 URL: http://llvm.org/viewvc/llvm-project?rev=44287&view=rev Log: Remove some logic I thoughtlessly copied over from the old ADCE implementation (there it was correct because the transform was being done for read-only functions). Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp?rev=44287&r1=44286&r2=44287&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Fri Nov 23 03:10:17 2007 @@ -88,9 +88,6 @@ // Update PHI nodes in the unwind destination II->getUnwindDest()->removePredecessor(BB); BB->getInstList().erase(II); - - if (NewCall->use_empty()) - BB->getInstList().erase(NewCall); } /// IsNoReturn - Return true if the specified call is to a no-return function. From baldrick at free.fr Fri Nov 23 03:48:26 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 23 Nov 2007 10:48:26 +0100 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] In-Reply-To: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> References: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> Message-ID: <200711231048.27891.baldrick@free.fr> Hi Sheng, > Here is the patch to make llvm-gcc/llvm-g++ emit llvm.pow.* when errno > disabled. thanks for doing this. Yet I have to wonder whether there's any point to using the llvm.pow.* intrinsic, or for that intrinsic to exist. LLVM doesn't seem to do anything with it, so presumably the only reason for it is so that LLVM knows that it is "pure". But nowadays gcc tells LLVM that directly. Look: #include double f(double x, double y) { return pow(x,y); } If you compile it with -fno-math-errno then pow gets declared as declare double @pow(double, double) nounwind readonly [I'm not sure why it is marked readonly rather than readnone]. [If you don't use -fno-math-errno then it is not declared readonly, which is correct because it can set errno]. Since yesterday, alias analysis knows how to deal with readonly and readnone functions. So all the benefit you would get from the intrinsic is already there! So how about removing the llvm.pow.* intrinsic and other ones like it instead? Ciao, Duncan. From zhousheng00 at gmail.com Fri Nov 23 04:30:51 2007 From: zhousheng00 at gmail.com (Zhou Sheng) Date: Fri, 23 Nov 2007 18:30:51 +0800 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] In-Reply-To: <200711231048.27891.baldrick@free.fr> References: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> <200711231048.27891.baldrick@free.fr> Message-ID: <8abe0dc60711230230r191be694seaf34cd3ed89ae2f@mail.gmail.com> Hi Ciao, Another benefit I can imagine is that using llvm.pow.* will make code more effective than using @pow. As llvm began to support apfloat, and as the llvm LangRef says "You can use llvm.pow on any floating point or vector of floating point type. Not all targets support all types however", we may get chance to optimize the lR code by using llvm.pow.* . For example, That will avoid code like: %tmp1 = fpext %x to double %tmp2 = fpext %y to double %tmp3 = call @pow(%tmp1, %tmp2) %result = fptrunc %tmp3 to SomeSmallFloatingType // The above code (the fpext/fptrunc stuff) also might block other optimizations. And in optimization pass, we may have chance to minimize the fp size. Sheng. 2007/11/23, Duncan Sands : > > Hi Sheng, > > > Here is the patch to make llvm-gcc/llvm-g++ emit llvm.pow.* when errno > > disabled. > > thanks for doing this. Yet I have to wonder whether there's any point > to using the llvm.pow.* intrinsic, or for that intrinsic to exist. > LLVM doesn't seem to do anything with it, so presumably the only > reason for it is so that LLVM knows that it is "pure". But nowadays > gcc tells LLVM that directly. Look: > > #include > double f(double x, double y) { > return pow(x,y); > } > > If you compile it with -fno-math-errno then pow gets declared as > > declare double @pow(double, double) nounwind readonly > > [I'm not sure why it is marked readonly rather than readnone]. > [If you don't use -fno-math-errno then it is not declared readonly, > which is correct because it can set errno]. > Since yesterday, alias analysis knows how to deal with readonly > and readnone functions. So all the benefit you would get from > the intrinsic is already there! > > So how about removing the llvm.pow.* intrinsic and other ones like it > instead? > > Ciao, > > Duncan. > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071123/62dd8f20/attachment.html From baldrick at free.fr Fri Nov 23 05:52:22 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 23 Nov 2007 12:52:22 +0100 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] In-Reply-To: <200711231048.27891.baldrick@free.fr> References: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> <200711231048.27891.baldrick@free.fr> Message-ID: <200711231252.23495.baldrick@free.fr> > If you compile it with -fno-math-errno then pow gets declared as > > declare double @pow(double, double) nounwind readonly > > [I'm not sure why it is marked readonly rather than readnone]. PS: it seems that it is marked readonly because the result depends on the floating point rounding mode, i.e. pow can be considered to read to (global) rounding mode. If you compile with -ffast-math then pow is declared readnone. This sort of subtle distinction seems quite important to me, and I'm not sure LLVM was making it before. From baldrick at free.fr Fri Nov 23 05:57:06 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 23 Nov 2007 12:57:06 +0100 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] In-Reply-To: <8abe0dc60711230230r191be694seaf34cd3ed89ae2f@mail.gmail.com> References: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> <200711231048.27891.baldrick@free.fr> <8abe0dc60711230230r191be694seaf34cd3ed89ae2f@mail.gmail.com> Message-ID: <200711231257.07141.baldrick@free.fr> Hi, > Another benefit I can imagine is that using llvm.pow.* will make code more > effective than using @pow. > As llvm began to support apfloat, and as the llvm LangRef says "You can use > llvm.pow on any floating point or vector of floating point type. Not all > targets support all types however", we may get chance to optimize the lR > code by using llvm.pow.* . > > For example, That will avoid code like: > > %tmp1 = fpext %x to double > %tmp2 = fpext %y to double > %tmp3 = call @pow(%tmp1, %tmp2) > %result = fptrunc %tmp3 to SomeSmallFloatingType // > > The above code (the fpext/fptrunc stuff) also might block other > optimizations. > And in optimization pass, we may have chance to minimize the fp size. maybe such things are possible, but does "pow" need to be an intrinsic in order to do them? Check SimplifyLibCalls.cpp. Also, even if we decide to keep the llvm.pow.* intrinsics, it seems to me that we don't need to have gcc emit it: if LLVM sees a call to "pow" with the right prototype, and the call is marked "readnone" (maybe "readonly") then it LLVM could automatically turn it into a call to llvm.pow.*. Ciao, Duncan. From clattner at apple.com Fri Nov 23 12:42:32 2007 From: clattner at apple.com (Chris Lattner) Date: Fri, 23 Nov 2007 10:42:32 -0800 Subject: [llvm-commits] [llvm-gcc-4.0]Patch to make llvm-gcc emit llvm.pow/sin/cos.* [for review] In-Reply-To: <8abe0dc60711230230r191be694seaf34cd3ed89ae2f@mail.gmail.com> References: <8abe0dc60711221834m654d59f9tb93658542381f74f@mail.gmail.com> <200711231048.27891.baldrick@free.fr> <8abe0dc60711230230r191be694seaf34cd3ed89ae2f@mail.gmail.com> Message-ID: <037B9E23-F0F7-48C4-ABD6-BA2586697D8C@apple.com> > Another benefit I can imagine is that using llvm.pow.* will make > code more effective than using @pow. > As llvm began to support apfloat, and as the llvm LangRef says "You > can use llvm.pow on any floating point or vector of floating point > type. Not all targets support all types however", we may get chance > to optimize the lR code by using llvm.pow.* . > > For example, That will avoid code like: > > %tmp1 = fpext %x to double > %tmp2 = fpext %y to double > %tmp3 = call @pow(%tmp1, %tmp2) > %result = fptrunc %tmp3 to SomeSmallFloatingType // > > The above code (the fpext/fptrunc stuff) also might block other > optimizations. > And in optimization pass, we may have chance to minimize the fp size. Duncan is right: there is no advantage of llvm.pow here over pow/powf, etc. LLVM optimization passes can and do hack on standard libc functions (see simplifylibcalls pass). The only advantage of llvm.pow.* is that it applies to vector operands as well as scalars. -Chris -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071123/0b12a75f/attachment.html From baldrick at free.fr Fri Nov 23 13:30:28 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 23 Nov 2007 19:30:28 -0000 Subject: [llvm-commits] [llvm] r44288 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/GlobalsModRef/chaining-analysis.ll test/Analysis/LoadVN/call_cse.ll test/Analysis/LoadVN/call_pure_function.ll test/Transforms/ADCE/dce_pure_call.ll test/Transforms/LICM/call_sink_const_function.ll test/Transforms/LICM/call_sink_pure_function.ll test/Transforms/LoopRotate/pr1154.ll Message-ID: <200711231930.lANJUTvT019911@zion.cs.uiuc.edu> Author: baldrick Date: Fri Nov 23 13:30:27 2007 New Revision: 44288 URL: http://llvm.org/viewvc/llvm-project?rev=44288&view=rev Log: Ding dong, the DoesntAccessMemoryFns and OnlyReadsMemoryFns tables are dead! We get more, and more accurate, information from gcc via the readnone and readonly function attributes. Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp llvm/trunk/test/Analysis/GlobalsModRef/chaining-analysis.ll llvm/trunk/test/Analysis/LoadVN/call_cse.ll llvm/trunk/test/Analysis/LoadVN/call_pure_function.ll llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll llvm/trunk/test/Transforms/LICM/call_sink_const_function.ll llvm/trunk/test/Transforms/LICM/call_sink_pure_function.ll llvm/trunk/test/Transforms/LoopRotate/pr1154.ll Modified: llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Fri Nov 23 13:30:27 2007 @@ -810,85 +810,9 @@ return MayAlias; } -namespace { - struct VISIBILITY_HIDDEN StringCompare { - bool operator()(const char *LHS, const char *RHS) { - return strcmp(LHS, RHS) < 0; - } - }; -} - -// Note that this list cannot contain libm functions (such as acos and sqrt) -// that set errno on a domain or other error. -static const char *DoesntAccessMemoryFns[] = { - "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl", - "trunc", "truncf", "truncl", "ldexp", - - "atan", "atanf", "atanl", "atan2", "atan2f", "atan2l", - "cbrt", - "cos", "cosf", "cosl", - "exp", "expf", "expl", - "hypot", - "sin", "sinf", "sinl", - "tan", "tanf", "tanl", "tanh", "tanhf", "tanhl", - - "floor", "floorf", "floorl", "ceil", "ceilf", "ceill", - - // ctype.h - "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", "isprint" - "ispunct", "isspace", "isupper", "isxdigit", "tolower", "toupper", - - // wctype.h" - "iswalnum", "iswalpha", "iswcntrl", "iswdigit", "iswgraph", "iswlower", - "iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit", - - "iswctype", "towctrans", "towlower", "towupper", - - "btowc", "wctob", - - "isinf", "isnan", "finite", - - // C99 math functions - "copysign", "copysignf", "copysignd", - "nexttoward", "nexttowardf", "nexttowardd", - "nextafter", "nextafterf", "nextafterd", - - // ISO C99: - "__signbit", "__signbitf", "__signbitl", -}; - - -static const char *OnlyReadsMemoryFns[] = { - "atoi", "atol", "atof", "atoll", "atoq", "a64l", - "bcmp", "memcmp", "memchr", "memrchr", "wmemcmp", "wmemchr", - - // Strings - "strcmp", "strcasecmp", "strcoll", "strncmp", "strncasecmp", - "strchr", "strcspn", "strlen", "strpbrk", "strrchr", "strspn", "strstr", - "index", "rindex", - - // Wide char strings - "wcschr", "wcscmp", "wcscoll", "wcscspn", "wcslen", "wcsncmp", "wcspbrk", - "wcsrchr", "wcsspn", "wcsstr", - - // glibc - "alphasort", "alphasort64", "versionsort", "versionsort64", - - // C99 - "nan", "nanf", "nand", - - // File I/O - "feof", "ferror", "fileno", - "feof_unlocked", "ferror_unlocked", "fileno_unlocked" -}; - -static ManagedStatic > NoMemoryTable; -static ManagedStatic > OnlyReadsMemoryTable; - static ManagedStatic NoMemoryIntrinsics; static ManagedStatic OnlyReadsMemoryIntrinsics; - AliasAnalysis::ModRefBehavior BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS, std::vector *Info) { @@ -896,19 +820,6 @@ static bool Initialized = false; if (!Initialized) { - NoMemoryTable->insert(NoMemoryTable->end(), - DoesntAccessMemoryFns, - array_endof(DoesntAccessMemoryFns)); - - OnlyReadsMemoryTable->insert(OnlyReadsMemoryTable->end(), - OnlyReadsMemoryFns, - array_endof(OnlyReadsMemoryFns)); - - // Sort the table the first time through. - std::sort(NoMemoryTable->begin(), NoMemoryTable->end(), StringCompare()); - std::sort(OnlyReadsMemoryTable->begin(), OnlyReadsMemoryTable->end(), - StringCompare()); - NoMemoryIntrinsics->resize(Intrinsic::num_intrinsics); OnlyReadsMemoryIntrinsics->resize(Intrinsic::num_intrinsics); #define GET_MODREF_BEHAVIOR @@ -927,30 +838,6 @@ return UnknownModRefBehavior; } - - ValueName *Name = F->getValueName(); - if (!Name) - return UnknownModRefBehavior; - - unsigned NameLen = Name->getKeyLength(); - const char *NamePtr = Name->getKeyData(); - - // If there is an embedded nul character in the function name, we can never - // match it. - if (strlen(NamePtr) != NameLen) - return UnknownModRefBehavior; - - std::vector::iterator Ptr = - std::lower_bound(NoMemoryTable->begin(), NoMemoryTable->end(), - NamePtr, StringCompare()); - if (Ptr != NoMemoryTable->end() && strcmp(*Ptr, NamePtr) == 0) - return DoesNotAccessMemory; - - Ptr = std::lower_bound(OnlyReadsMemoryTable->begin(), - OnlyReadsMemoryTable->end(), - NamePtr, StringCompare()); - if (Ptr != OnlyReadsMemoryTable->end() && strcmp(*Ptr, NamePtr) == 0) - return OnlyReadsMemory; const ParamAttrsList *Attrs = F->getFunctionType()->getParamAttrs(); if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadNone)) Modified: llvm/trunk/test/Analysis/GlobalsModRef/chaining-analysis.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/GlobalsModRef/chaining-analysis.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Analysis/GlobalsModRef/chaining-analysis.ll (original) +++ llvm/trunk/test/Analysis/GlobalsModRef/chaining-analysis.ll Fri Nov 23 13:30:27 2007 @@ -1,20 +1,20 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -globalsmodref-aa -load-vn -gcse | llvm-dis | not grep load +; RUN: llvm-as < %s | opt -globalsmodref-aa -load-vn -gcse | llvm-dis | not grep load -; This test requires the use of previous analyses to determine that +; This test requires the use of previous analyses to determine that ; doesnotmodX does not modify X (because 'sin' doesn't). -%X = internal global int 4 + at X = internal global i32 4 ; [#uses=2] -declare double %sin(double) +declare double @sin(double) readnone -int %test(int *%P) { - store int 12, int* %X - call double %doesnotmodX(double 1.0) - %V = load int* %X - ret int %V +define i32 @test(i32* %P) { + store i32 12, i32* @X + call double @doesnotmodX( double 1.000000e+00 ) ; :1 [#uses=0] + %V = load i32* @X ; [#uses=1] + ret i32 %V } -double %doesnotmodX(double %V) { - %V2 = call double %sin(double %V) - ret double %V2 +define double @doesnotmodX(double %V) { + %V2 = call double @sin( double %V ) readnone ; [#uses=1] + ret double %V2 } Modified: llvm/trunk/test/Analysis/LoadVN/call_cse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoadVN/call_cse.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Analysis/LoadVN/call_cse.ll (original) +++ llvm/trunk/test/Analysis/LoadVN/call_cse.ll Fri Nov 23 13:30:27 2007 @@ -1,11 +1,12 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -basicaa -load-vn -gcse -instcombine | llvm-dis | not grep sub -declare int %strlen(sbyte*) +; RUN: llvm-as < %s | opt -basicaa -load-vn -gcse -instcombine | llvm-dis | not grep sub -int %test(sbyte* %P) { - %X = call int %strlen(sbyte* %P) - %A = add int %X, 14 - %Y = call int %strlen(sbyte* %P) - %Z = sub int %X, %Y - %B = add int %A, %Z - ret int %B +declare i32 @strlen(i8*) readonly + +define i32 @test(i8* %P) { + %X = call i32 @strlen( i8* %P ) readonly ; [#uses=2] + %A = add i32 %X, 14 ; [#uses=1] + %Y = call i32 @strlen( i8* %P ) readonly ; [#uses=1] + %Z = sub i32 %X, %Y ; [#uses=1] + %B = add i32 %A, %Z ; [#uses=1] + ret i32 %B } Modified: llvm/trunk/test/Analysis/LoadVN/call_pure_function.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/LoadVN/call_pure_function.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Analysis/LoadVN/call_pure_function.ll (original) +++ llvm/trunk/test/Analysis/LoadVN/call_pure_function.ll Fri Nov 23 13:30:27 2007 @@ -1,13 +1,14 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -basicaa -load-vn -gcse -instcombine | llvm-dis | not grep sub -declare int %strlen(sbyte*) -declare void %use(int %X) +; RUN: llvm-as < %s | opt -basicaa -load-vn -gcse -instcombine | llvm-dis | not grep sub -sbyte %test(sbyte* %P, sbyte* %Q) { - %A = load sbyte* %Q - %X = call int %strlen(sbyte* %P) - %B = load sbyte* %Q ;; CSE with A. - call void %use(int %X) ;; make strlen not dead +declare i32 @strlen(i8*) readonly - %C = sub sbyte %A, %B - ret sbyte %C +declare void @use(i32) + +define i8 @test(i8* %P, i8* %Q) { + %A = load i8* %Q ; [#uses=1] + %X = call i32 @strlen( i8* %P ) readonly ; [#uses=1] + %B = load i8* %Q ; [#uses=1] + call void @use( i32 %X ) + %C = sub i8 %A, %B ; [#uses=1] + ret i8 %C } Modified: llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll (original) +++ llvm/trunk/test/Transforms/ADCE/dce_pure_call.ll Fri Nov 23 13:30:27 2007 @@ -1,9 +1,8 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -adce | llvm-dis | not grep call +; RUN: llvm-as < %s | opt -adce | llvm-dis | not grep call -declare int %strlen(sbyte*) +declare i32 @strlen(i8*) readonly -void %test() { - ;; Dead call should be deleted! - call int %strlen(sbyte *null) +define void @test() { + call i32 @strlen( i8* null ) readonly ; :1 [#uses=0] ret void } Modified: llvm/trunk/test/Transforms/LICM/call_sink_const_function.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/call_sink_const_function.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LICM/call_sink_const_function.ll (original) +++ llvm/trunk/test/Transforms/LICM/call_sink_const_function.ll Fri Nov 23 13:30:27 2007 @@ -1,16 +1,17 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -basicaa -licm | llvm-dis | %prcontext sin 1 | grep Out: -declare double %sin(double) -declare void %foo() +; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | %prcontext sin 1 | grep Out: -double %test(double %X) { - br label %Loop +declare double @sin(double) readnone + +declare void @foo() -Loop: - call void %foo() ;; Unknown effects! +define double @test(double %X) { + br label %Loop - %A = call double %sin(double %X) ;; Can still hoist/sink call - br bool true, label %Loop, label %Out +Loop: ; preds = %Loop, %0 + call void @foo( ) + %A = call double @sin( double %X ) readnone ; [#uses=1] + br i1 true, label %Loop, label %Out -Out: +Out: ; preds = %Loop ret double %A } Modified: llvm/trunk/test/Transforms/LICM/call_sink_pure_function.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/call_sink_pure_function.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LICM/call_sink_pure_function.ll (original) +++ llvm/trunk/test/Transforms/LICM/call_sink_pure_function.ll Fri Nov 23 13:30:27 2007 @@ -1,14 +1,16 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -basicaa -licm | llvm-dis | %prcontext strlen 1 | grep Out: -declare int %strlen(sbyte*) -declare void %foo() +; RUN: llvm-as < %s | opt -basicaa -licm | llvm-dis | %prcontext strlen 1 | grep Out: -int %test(sbyte* %P) { +declare i32 @strlen(i8*) readonly + +declare void @foo() + +define i32 @test(i8* %P) { br label %Loop -Loop: - %A = call int %strlen(sbyte* %P) ;; Can hoist/sink call - br bool false, label %Loop, label %Out +Loop: ; preds = %Loop, %0 + %A = call i32 @strlen( i8* %P ) readonly ; [#uses=1] + br i1 false, label %Loop, label %Out -Out: - ret int %A +Out: ; preds = %Loop + ret i32 %A } Modified: llvm/trunk/test/Transforms/LoopRotate/pr1154.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopRotate/pr1154.ll?rev=44288&r1=44287&r2=44288&view=diff ============================================================================== --- llvm/trunk/test/Transforms/LoopRotate/pr1154.ll (original) +++ llvm/trunk/test/Transforms/LoopRotate/pr1154.ll Fri Nov 23 13:30:27 2007 @@ -1,13 +1,12 @@ -; RUN: llvm-upgrade < %s | llvm-as | opt -std-compile-opts | llvm-dis | \ +; RUN: llvm-as < %s | opt -std-compile-opts | llvm-dis | \ ; RUN: %prcontext strstr 2 | grep -v declare | grep bb36.outer: -; END. @str = internal constant [68 x i8] c"Dot. date. datum. 123. Some more doubtful demonstration dummy data.\00" ; <[68 x i8]*> [#uses=1] @str1 = internal constant [5 x i8] c"ummy\00" ; <[5 x i8]*> [#uses=1] @str2 = internal constant [6 x i8] c" data\00" ; <[6 x i8]*> [#uses=1] @str3 = internal constant [3 x i8] c"by\00" ; <[3 x i8]*> [#uses=1] -i32 @stringSearch_Clib(i32 %count) { +define i32 @stringSearch_Clib(i32 %count) { entry: %count_addr = alloca i32 ; [#uses=2] %retval = alloca i32, align 4 ; [#uses=2] @@ -17,11 +16,11 @@ %j = alloca i32, align 4 ; [#uses=4] %p = alloca i8*, align 4 ; [#uses=6] %b = alloca [68 x i8], align 16 ; <[68 x i8]*> [#uses=6] - "alloca point" = bitcast i32 0 to i32 ; [#uses=0] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] store i32 %count, i32* %count_addr store i32 0, i32* %c %b1 = bitcast [68 x i8]* %b to i8* ; [#uses=1] - %tmp2 = getelementptr [68 x i8]* @str, i32 0, i32 0 ; [#uses=1] + %tmp2 = getelementptr [68 x i8]* @str, i64 0, i64 0 ; [#uses=1] call void @llvm.memcpy.i32( i8* %b1, i8* %tmp2, i32 68, i32 1 ) store i32 0, i32* %j br label %bb41 @@ -34,13 +33,13 @@ bb4: ; preds = %bb36 %b5 = bitcast [68 x i8]* %b to i8* ; [#uses=1] - %tmp6 = getelementptr [5 x i8]* @str1, i32 0, i32 0 ; [#uses=1] - %tmp7 = call i8* @strstr( i8* %b5, i8* %tmp6 ) ; [#uses=1] + %tmp6 = getelementptr [5 x i8]* @str1, i64 0, i64 0 ; [#uses=1] + %tmp7 = call i8* @strstr( i8* %b5, i8* %tmp6 ) readonly ; [#uses=1] store i8* %tmp7, i8** %p %tmp8 = load i8** %p ; [#uses=1] - %ttmp8 = icmp ne i8* %tmp8, null ; :0 [#uses=1] - %ttmp10 = zext i1 %ttmp8 to i8 ; :1 [#uses=1] - %ttmp7 = icmp ne i8 %ttmp10, 0 ; :2 [#uses=1] + %ttmp8 = icmp ne i8* %tmp8, null ; [#uses=1] + %ttmp10 = zext i1 %ttmp8 to i8 ; [#uses=1] + %ttmp7 = icmp ne i8 %ttmp10, 0 ; [#uses=1] br i1 %ttmp7, label %cond_true, label %cond_next cond_true: ; preds = %bb4 @@ -56,13 +55,13 @@ cond_next: ; preds = %cond_true, %bb4 %b16 = bitcast [68 x i8]* %b to i8* ; [#uses=1] - %tmp17 = getelementptr [6 x i8]* @str2, i32 0, i32 0 ; [#uses=1] - %tmp18 = call i8* @strstr( i8* %b16, i8* %tmp17 ) ; [#uses=1] + %tmp17 = getelementptr [6 x i8]* @str2, i64 0, i64 0 ; [#uses=1] + %tmp18 = call i8* @strstr( i8* %b16, i8* %tmp17 ) readonly ; [#uses=1] store i8* %tmp18, i8** %p %tmp19 = load i8** %p ; [#uses=1] - %ttmp6 = icmp ne i8* %tmp19, null ; :3 [#uses=1] - %ttmp9 = zext i1 %ttmp6 to i8 ; :4 [#uses=1] - %ttmp4 = icmp ne i8 %ttmp9, 0 ; :5 [#uses=1] + %ttmp6 = icmp ne i8* %tmp19, null ; [#uses=1] + %ttmp9 = zext i1 %ttmp6 to i8 ; [#uses=1] + %ttmp4 = icmp ne i8 %ttmp9, 0 ; [#uses=1] br i1 %ttmp4, label %cond_true20, label %cond_next28 cond_true20: ; preds = %cond_next @@ -78,8 +77,8 @@ cond_next28: ; preds = %cond_true20, %cond_next %b29 = bitcast [68 x i8]* %b to i8* ; [#uses=1] - %tmp30 = getelementptr [3 x i8]* @str3, i32 0, i32 0 ; [#uses=1] - %tmp31 = call i32 @strcspn( i8* %b29, i8* %tmp30 ) ; [#uses=1] + %tmp30 = getelementptr [3 x i8]* @str3, i64 0, i64 0 ; [#uses=1] + %tmp31 = call i32 @strcspn( i8* %b29, i8* %tmp30 ) readonly ; [#uses=1] %tmp32 = load i32* %c ; [#uses=1] %tmp33 = add i32 %tmp31, %tmp32 ; [#uses=1] store i32 %tmp33, i32* %c @@ -90,9 +89,9 @@ bb36: ; preds = %cond_next28, %bb %tmp37 = load i32* %i ; [#uses=1] - %ttmp3= icmp sle i32 %tmp37, 249 ; :6 [#uses=1] - %ttmp12 = zext i1 %ttmp3 to i8 ; :7 [#uses=1] - %ttmp1 = icmp ne i8 %ttmp12, 0 ; :8 [#uses=1] + %ttmp3 = icmp sle i32 %tmp37, 249 ; [#uses=1] + %ttmp12 = zext i1 %ttmp3 to i8 ; [#uses=1] + %ttmp1 = icmp ne i8 %ttmp12, 0 ; [#uses=1] br i1 %ttmp1, label %bb4, label %bb38 bb38: ; preds = %bb36 @@ -104,9 +103,9 @@ bb41: ; preds = %bb38, %entry %tmp42 = load i32* %j ; [#uses=1] %tmp43 = load i32* %count_addr ; [#uses=1] - %ttmp2 = icmp slt i32 %tmp42, %tmp43 ; :9 [#uses=1] - %ttmp11 = zext i1 %ttmp2 to i8 ; :10 [#uses=1] - %ttmp5 = icmp ne i8 %ttmp11, 0 ; :11 [#uses=1] + %ttmp2 = icmp slt i32 %tmp42, %tmp43 ; [#uses=1] + %ttmp11 = zext i1 %ttmp2 to i8 ; [#uses=1] + %ttmp5 = icmp ne i8 %ttmp11, 0 ; [#uses=1] br i1 %ttmp5, label %bb, label %bb44 bb44: ; preds = %bb41 @@ -123,6 +122,6 @@ declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) -declare i8* @strstr(i8*, i8*) +declare i8* @strstr(i8*, i8*) readonly -declare i32 @strcspn(i8*, i8*) +declare i32 @strcspn(i8*, i8*) readonly From sabre at nondot.org Fri Nov 23 16:19:35 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:19:35 -0000 Subject: [llvm-commits] [llvm] r44291 - /llvm/trunk/docs/tutorial/LangImpl6.html Message-ID: <200711232219.lANMJZN7027567@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:19:33 2007 New Revision: 44291 URL: http://llvm.org/viewvc/llvm-project?rev=44291&view=rev Log: !< is >=, not >. Thanks to Max Hailperin for pointing this out! Modified: llvm/trunk/docs/tutorial/LangImpl6.html Modified: llvm/trunk/docs/tutorial/LangImpl6.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl6.html?rev=44291&r1=44290&r2=44291&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl6.html (original) +++ llvm/trunk/docs/tutorial/LangImpl6.html Fri Nov 23 16:19:33 2007 @@ -97,7 +97,7 @@ # Define > with the same precedence as <. def binary> 10 (LHS RHS) - !(LHS < RHS); # alternatively, could just use "RHS < LHS" + RHS < LHS; # Binary "logical or", (note that it does not "short circuit") def binary| 5 (LHS RHS) @@ -532,7 +532,7 @@ # Define > with the same precedence as >. def binary> 10 (LHS RHS) - !(LHS < RHS); + RHS < LHS; # Binary logical or, which does not short circuit. def binary| 5 (LHS RHS) From sabre at nondot.org Fri Nov 23 16:34:59 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:34:59 -0000 Subject: [llvm-commits] [llvm] r44292 - /llvm/trunk/lib/Analysis/ConstantFolding.cpp Message-ID: <200711232234.lANMYx1U028172@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:34:59 2007 New Revision: 44292 URL: http://llvm.org/viewvc/llvm-project?rev=44292&view=rev Log: splice some lines together, no functionality change. Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=44292&r1=44291&r2=44292&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Fri Nov 23 16:34:59 2007 @@ -516,18 +516,14 @@ break; } } else if (ConstantInt *Op = dyn_cast(Operands[0])) { - if (Len > 11 && !memcmp(Str, "llvm.bswap", 10)) { + if (Len > 11 && !memcmp(Str, "llvm.bswap", 10)) return ConstantInt::get(Op->getValue().byteSwap()); - } else if (Len > 11 && !memcmp(Str, "llvm.ctpop", 10)) { - uint64_t ctpop = Op->getValue().countPopulation(); - return ConstantInt::get(Ty, ctpop); - } else if (Len > 10 && !memcmp(Str, "llvm.cttz", 9)) { - uint64_t cttz = Op->getValue().countTrailingZeros(); - return ConstantInt::get(Ty, cttz); - } else if (Len > 10 && !memcmp(Str, "llvm.ctlz", 9)) { - uint64_t ctlz = Op->getValue().countLeadingZeros(); - return ConstantInt::get(Ty, ctlz); - } + else if (Len > 11 && !memcmp(Str, "llvm.ctpop", 10)) + return ConstantInt::get(Ty, Op->getValue().countPopulation()); + else if (Len > 10 && !memcmp(Str, "llvm.cttz", 9)) + return ConstantInt::get(Ty, Op->getValue().countTrailingZeros()); + else if (Len > 10 && !memcmp(Str, "llvm.ctlz", 9)) + return ConstantInt::get(Ty, Op->getValue().countLeadingZeros()); } } else if (NumOperands == 2) { if (ConstantFP *Op1 = dyn_cast(Operands[0])) { From sabre at nondot.org Fri Nov 23 16:35:18 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:35:18 -0000 Subject: [llvm-commits] [llvm] r44293 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200711232235.lANMZIAf028193@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:35:18 2007 New Revision: 44293 URL: http://llvm.org/viewvc/llvm-project?rev=44293&view=rev Log: add a comment. Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44293&r1=44292&r2=44293&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Nov 23 16:35:18 2007 @@ -2660,7 +2660,7 @@ if (ConstantInt *RHS = dyn_cast(I->getOperand(1))) { // X & 0xFFF0 is known to be a multiple of 16. uint32_t Zeros = RHS->getValue().countTrailingZeros(); - if (Zeros != V->getType()->getPrimitiveSizeInBits()) + if (Zeros != V->getType()->getPrimitiveSizeInBits())// don't shift by "32" return ConstantExpr::getShl(Result, ConstantInt::get(Result->getType(), Zeros)); } From sabre at nondot.org Fri Nov 23 16:36:25 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:36:25 -0000 Subject: [llvm-commits] [llvm] r44294 - /llvm/trunk/lib/Support/APInt.cpp Message-ID: <200711232236.lANMaPqk028276@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:36:25 2007 New Revision: 44294 URL: http://llvm.org/viewvc/llvm-project?rev=44294&view=rev Log: Fix APInt::countTrailingZeros to return BitWidth if the input is zero instead of returning some random large number. Modified: llvm/trunk/lib/Support/APInt.cpp Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=44294&r1=44293&r2=44294&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Fri Nov 23 16:36:25 2007 @@ -782,14 +782,14 @@ uint32_t APInt::countTrailingZeros() const { if (isSingleWord()) - return CountTrailingZeros_64(VAL); + return std::min(CountTrailingZeros_64(VAL), BitWidth); uint32_t Count = 0; uint32_t i = 0; for (; i < getNumWords() && pVal[i] == 0; ++i) Count += APINT_BITS_PER_WORD; if (i < getNumWords()) Count += CountTrailingZeros_64(pVal[i]); - return Count; + return std::min(Count, BitWidth); } uint32_t APInt::countPopulation() const { From sabre at nondot.org Fri Nov 23 16:36:49 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:36:49 -0000 Subject: [llvm-commits] [llvm] r44295 - /llvm/trunk/lib/Analysis/ScalarEvolution.cpp Message-ID: <200711232236.lANManPR028298@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:36:49 2007 New Revision: 44295 URL: http://llvm.org/viewvc/llvm-project?rev=44295&view=rev Log: simplify some code. Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44295&r1=44294&r2=44295&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Fri Nov 23 16:36:49 2007 @@ -1416,11 +1416,7 @@ /// it returns 2. If S is guaranteed to be 0, it returns the bitwidth of S. static uint32_t GetMinTrailingZeros(SCEVHandle S) { if (SCEVConstant *C = dyn_cast(S)) - // APInt::countTrailingZeros() returns the number of trailing zeros in its - // internal representation, which length may be greater than the represented - // value bitwidth. This is why we use a min operation here. - return std::min(C->getValue()->getValue().countTrailingZeros(), - C->getBitWidth()); + return C->getValue()->getValue().countTrailingZeros(); if (SCEVTruncateExpr *T = dyn_cast(S)) return std::min(GetMinTrailingZeros(T->getOperand()), T->getBitWidth()); From sabre at nondot.org Fri Nov 23 16:42:31 2007 From: sabre at nondot.org (Chris Lattner) Date: Fri, 23 Nov 2007 22:42:31 -0000 Subject: [llvm-commits] [llvm] r44296 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Support/APInt.cpp test/Transforms/ConstProp/2007-11-23-cttz.ll Message-ID: <200711232242.lANMgVOk028511@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 16:42:31 2007 New Revision: 44296 URL: http://llvm.org/viewvc/llvm-project?rev=44296&view=rev Log: Fix PR1816, by correcting the broken definition of APInt::countTrailingZeros. Added: llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll Modified: llvm/trunk/include/llvm/ADT/APInt.h llvm/trunk/lib/Support/APInt.cpp Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=44296&r1=44295&r2=44296&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Fri Nov 23 16:42:31 2007 @@ -896,10 +896,9 @@ /// countLeadingZeros - This function is an APInt version of the /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number /// of zeros from the most significant bit to the first one bit. - /// @returns getNumWords() * APINT_BITS_PER_WORD if the value is zero. + /// @returns BitWidth if the value is zero. /// @returns the number of zeros from the most significant bit to the first /// one bits. - /// @brief Count the number of leading one bits. uint32_t countLeadingZeros() const; /// countLeadingOnes - This function counts the number of contiguous 1 bits @@ -911,8 +910,8 @@ /// countTrailingZeros - This function is an APInt version of the /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts - /// the number of zeros from the least significant bit to the first one bit. - /// @returns getNumWords() * APINT_BITS_PER_WORD if the value is zero. + /// the number of zeros from the least significant bit to the first set bit. + /// @returns BitWidth if the value is zero. /// @returns the number of zeros from the least significant bit to the first /// one bit. /// @brief Count the number of trailing zero bits. Modified: llvm/trunk/lib/Support/APInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APInt.cpp?rev=44296&r1=44295&r2=44296&view=diff ============================================================================== --- llvm/trunk/lib/Support/APInt.cpp (original) +++ llvm/trunk/lib/Support/APInt.cpp Fri Nov 23 16:42:31 2007 @@ -745,7 +745,7 @@ uint32_t remainder = BitWidth % APINT_BITS_PER_WORD; if (remainder) Count -= APINT_BITS_PER_WORD - remainder; - return Count; + return std::min(Count, BitWidth); } static uint32_t countLeadingOnes_64(uint64_t V, uint32_t skip) { Added: llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll?rev=44296&view=auto ============================================================================== --- llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll (added) +++ llvm/trunk/test/Transforms/ConstProp/2007-11-23-cttz.ll Fri Nov 23 16:42:31 2007 @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | opt -constprop | llvm-dis | grep {ret i13 13} +; PR1816 +declare i13 @llvm.cttz.i13(i13) + +define i13 @test() { + %X = call i13 @llvm.cttz.i13(i13 0) + ret i13 %X +} From sabre at nondot.org Fri Nov 23 23:39:30 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 05:39:30 -0000 Subject: [llvm-commits] [llvm] r44298 - /llvm/trunk/test/CodeGen/X86/rdtsc.ll Message-ID: <200711240539.lAO5dU68013496@zion.cs.uiuc.edu> Author: lattner Date: Fri Nov 23 23:39:29 2007 New Revision: 44298 URL: http://llvm.org/viewvc/llvm-project?rev=44298&view=rev Log: upgrade this test Modified: llvm/trunk/test/CodeGen/X86/rdtsc.ll Modified: llvm/trunk/test/CodeGen/X86/rdtsc.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/rdtsc.ll?rev=44298&r1=44297&r2=44298&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/rdtsc.ll (original) +++ llvm/trunk/test/CodeGen/X86/rdtsc.ll Fri Nov 23 23:39:29 2007 @@ -1,10 +1,8 @@ -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86 | grep rdtsc -; RUN: llvm-upgrade < %s | llvm-as | llc -march=x86-64 | grep rdtsc +; RUN: llvm-as < %s | llc -march=x86 | grep rdtsc +; RUN: llvm-as < %s | llc -march=x86-64 | grep rdtsc +declare i64 @llvm.readcyclecounter() -declare ulong %llvm.readcyclecounter() - -ulong %foo() { -%tmp.1 = call ulong %llvm.readcyclecounter () -ret ulong %tmp.1 +define i64 @foo() { + %tmp.1 = call i64 @llvm.readcyclecounter( ) ; [#uses=1] + ret i64 %tmp.1 } - From sabre at nondot.org Sat Nov 24 00:13:34 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 06:13:34 -0000 Subject: [llvm-commits] [llvm] r44299 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200711240613.lAO6DYZI014900@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 00:13:33 2007 New Revision: 44299 URL: http://llvm.org/viewvc/llvm-project?rev=44299&view=rev Log: add a note Modified: llvm/trunk/lib/Target/X86/README.txt Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=44299&r1=44298&r2=44299&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sat Nov 24 00:13:33 2007 @@ -1511,3 +1511,24 @@ cmpl $262144, %eax //===---------------------------------------------------------------------===// + +define i64 @test(double %X) { + %Y = fptosi double %X to i64 + ret i64 %Y +} + +compiles to: + +_test: + subl $20, %esp + movsd 24(%esp), %xmm0 + movsd %xmm0, 8(%esp) + fldl 8(%esp) + fisttpll (%esp) + movl 4(%esp), %edx + movl (%esp), %eax + addl $20, %esp + #FP_REG_KILL + ret + +This should just fldl directly from the input stack slot. From sabre at nondot.org Sat Nov 24 01:07:02 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 07:07:02 -0000 Subject: [llvm-commits] [llvm] r44300 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h Message-ID: <200711240707.lAO772rd017178@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 01:07:01 2007 New Revision: 44300 URL: http://llvm.org/viewvc/llvm-project?rev=44300&view=rev Log: Several changes: 1) Change the interface to TargetLowering::ExpandOperationResult to take and return entire NODES that need a result expanded, not just the value. This allows us to handle things like READCYCLECOUNTER, which returns two values. 2) Implement (extremely limited) support in LegalizeDAG::ExpandOp for MERGE_VALUES. 3) Reimplement custom lowering in LegalizeDAGTypes in terms of the new ExpandOperationResult. This makes the result simpler and fully general. 4) Implement (fully general) expand support for MERGE_VALUES in LegalizeDAGTypes. 5) Implement ExpandOperationResult support for ARM f64->i64 bitconvert and ARM i64 shifts, allowing them to work with LegalizeDAGTypes. 6) Implement ExpandOperationResult support for X86 READCYCLECOUNTER and FP_TO_SINT, allowing them to work with LegalizeDAGTypes. LegalizeDAGTypes now passes several more X86 codegen tests when enabled and when type legalization in LegalizeDAG is ifdef'd out. Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sat Nov 24 01:07:01 2007 @@ -910,12 +910,16 @@ /// ExpandOperationResult - This callback is invoked for operations that are /// unsupported by the target, which are registered to use 'custom' lowering, - /// and whose result type needs to be expanded. + /// and whose result type needs to be expanded. This must return a node whose + /// results precisely match the results of the input node. This typically + /// involves a MERGE_VALUES node and/or BUILD_PAIR. /// /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation of this aborts. - virtual std::pair - ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { + assert(0 && "ExpandOperationResult not implemented for this target!"); + return 0; + } /// IsEligibleForTailCallOptimization - Check whether the call is eligible for /// tail call optimization. Targets which want to do tail call optimization Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Nov 24 01:07:01 2007 @@ -5187,10 +5187,21 @@ // Otherwise, try a larger type. } - // Okay, we found the operation and type to use. Truncate the result of the - // extended FP_TO_*INT operation to the desired size. - return DAG.getNode(ISD::TRUNCATE, DestVT, - DAG.getNode(OpToUse, NewOutTy, LegalOp)); + + // Okay, we found the operation and type to use. + SDOperand Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp); + + // If the operation produces an invalid type, it must be custom lowered. Use + // the target lowering hooks to expand it. Just keep the low part of the + // expanded operation, we know that we're truncating anyway. + if (getTypeAction(NewOutTy) == Expand) { + Operation = SDOperand(TLI.ExpandOperationResult(Operation.Val, DAG), 0); + assert(Operation.Val && "Didn't return anything"); + } + + // Truncate the result of the extended FP_TO_*INT operation to the desired + // size. + return DAG.getNode(ISD::TRUNCATE, DestVT, Operation); } /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. @@ -5388,6 +5399,16 @@ Lo = Node->getOperand(0); Hi = Node->getOperand(1); break; + + case ISD::MERGE_VALUES: + // FIXME: For now only expand i64,chain = MERGE_VALUES (x, y) + assert(Op.ResNo == 0 && Node->getNumValues() == 2 && + Op.getValue(1).getValueType() == MVT::Other && + "unhandled MERGE_VALUES"); + ExpandOp(Op.getOperand(0), Lo, Hi); + // Remember that we legalized the chain. + AddLegalizedOperand(Op.getValue(1), LegalizeOp(Op.getOperand(1))); + break; case ISD::SIGN_EXTEND_INREG: ExpandOp(Node->getOperand(0), Lo, Hi); @@ -5652,16 +5673,17 @@ break; } - case ISD::READCYCLECOUNTER: + case ISD::READCYCLECOUNTER: { assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == TargetLowering::Custom && "Must custom expand ReadCycleCounter"); - Lo = TLI.LowerOperation(Op, DAG); - assert(Lo.Val && "Node must be custom expanded!"); - Hi = Lo.getValue(1); + SDOperand Tmp = TLI.LowerOperation(Op, DAG); + assert(Tmp.Val && "Node must be custom expanded!"); + ExpandOp(Tmp.getValue(0), Lo, Hi); AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain. - LegalizeOp(Lo.getValue(2))); + LegalizeOp(Tmp.getValue(1))); break; + } // These operators cannot be expanded directly, emit them as calls to // library functions. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Sat Nov 24 01:07:01 2007 @@ -115,7 +115,8 @@ private: void MarkNewNodes(SDNode *N); - void ReplaceLegalValueWith(SDOperand From, SDOperand To); + void ReplaceValueWith(SDOperand From, SDOperand To); + void ReplaceNodeWith(SDNode *From, SDNode *To); void RemapNode(SDOperand &N); @@ -167,6 +168,7 @@ void ExpandResult_UNDEF (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandResult_Constant (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi); + void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi); @@ -391,10 +393,10 @@ Worklist.push_back(N); } -/// ReplaceLegalValueWith - The specified value with a legal type was legalized -/// to the specified other value. If they are different, update the DAG and -/// NodeIDs replacing any uses of From to use To instead. -void DAGTypeLegalizer::ReplaceLegalValueWith(SDOperand From, SDOperand To) { +/// ReplaceValueWith - The specified value was legalized to the specified other +/// value. If they are different, update the DAG and NodeIDs replacing any uses +/// of From to use To instead. +void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) { if (From == To) return; // If expansion produced new nodes, make sure they are properly marked. @@ -410,8 +412,8 @@ ReplacedNodes[From] = To; // Since we just made an unstructured update to the DAG, which could wreak - // general havoc on anything that once used N and now uses Res, walk all users - // of the result, updating their flags. + // general havoc on anything that once used From and now uses To, walk all + // users of the result, updating their flags. for (SDNode::use_iterator I = To.Val->use_begin(), E = To.Val->use_end(); I != E; ++I) { SDNode *User = *I; @@ -425,14 +427,51 @@ } } +/// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to' +/// node's results. The from and to node must define identical result types. +void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) { + if (From == To) return; + assert(From->getNumValues() == To->getNumValues() && + "Node results don't match"); + + // If expansion produced new nodes, make sure they are properly marked. + if (To->getNodeId() == NewNode) + MarkNewNodes(To); + + // Anything that used the old node should now use the new one. Note that this + // can potentially cause recursive merging. + DAG.ReplaceAllUsesWith(From, To); + + // The old node may still be present in ExpandedNodes or PromotedNodes. + // Inform them about the replacement. + for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) { + assert(From->getValueType(i) == To->getValueType(i) && + "Node results don't match"); + ReplacedNodes[SDOperand(From, i)] = SDOperand(To, i); + } + + // Since we just made an unstructured update to the DAG, which could wreak + // general havoc on anything that once used From and now uses To, walk all + // users of the result, updating their flags. + for (SDNode::use_iterator I = To->use_begin(), E = To->use_end();I != E; ++I){ + SDNode *User = *I; + // If the node isn't already processed or in the worklist, mark it as new, + // then use MarkNewNodes to recompute its ID. + int NodeId = User->getNodeId(); + if (NodeId != ReadyToProcess && NodeId != Processed) { + User->setNodeId(NewNode); + MarkNewNodes(User); + } + } +} + + /// RemapNode - If the specified value was already legalized to another value, /// replace it by that value. void DAGTypeLegalizer::RemapNode(SDOperand &N) { - DenseMap::iterator I = ReplacedNodes.find(N); - if (I != ReplacedNodes.end()) { - RemapNode(I->second); + for (DenseMap::iterator I = ReplacedNodes.find(N); + I != ReplacedNodes.end(); I = ReplacedNodes.find(N)) N = I->second; - } } void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) { @@ -712,7 +751,7 @@ // Legalized the chain result - switch anything that used the old chain to // use the new one. - ReplaceLegalValueWith(SDOperand(N, 1), Res.getValue(1)); + ReplaceValueWith(SDOperand(N, 1), Res.getValue(1)); return Res; } @@ -798,15 +837,14 @@ SDOperand Lo, Hi; Lo = Hi = SDOperand(); - // If this is a single-result node, see if the target wants to custom expand - // it. - if (N->getNumValues() == 1 && - TLI.getOperationAction(N->getOpcode(), - N->getValueType(0)) == TargetLowering::Custom) { + // See if the target wants to custom expand this node. + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - std::pair P = TLI.ExpandOperationResult(N, DAG); - if (P.first.Val) { - SetExpandedOp(SDOperand(N, ResNo), P.first, P.second); + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + // Everything that once used N now uses P. P had better not require + // custom expansion. + ReplaceNodeWith(N, P); return; } } @@ -817,12 +855,13 @@ cerr << "ExpandResult #" << ResNo << ": "; N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to expand this operator!"); + assert(0 && "Do not know how to expand the result of this operator!"); abort(); case ISD::UNDEF: ExpandResult_UNDEF(N, Lo, Hi); break; case ISD::Constant: ExpandResult_Constant(N, Lo, Hi); break; case ISD::BUILD_PAIR: ExpandResult_BUILD_PAIR(N, Lo, Hi); break; + case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break; case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break; case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break; case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break; @@ -846,7 +885,6 @@ case ISD::SHL: case ISD::SRA: case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break; - } // If Lo/Hi is null, the sub-method took care of registering results etc. @@ -875,6 +913,27 @@ Hi = N->getOperand(1); } +void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + // A MERGE_VALUES node can produce any number of values. We know that the + // first illegal one needs to be expanded into Lo/Hi. + unsigned i; + + // The string of legal results gets turns into the input operands, which have + // the same type. + for (i = 0; isTypeLegal(N->getValueType(i)); ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); + + // The first illegal result must be the one that needs to be expanded. + GetExpandedOp(N->getOperand(i), Lo, Hi); + + // Legalize the rest of the results into the input operands whether they are + // legal or not. + unsigned e = N->getNumValues(); + for (++i; i != e; ++i) + ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i))); +} + void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); @@ -1096,7 +1155,7 @@ // Legalized the chain result - switch anything that used the old chain to // use the new one. - ReplaceLegalValueWith(SDOperand(N, 1), Ch); + ReplaceValueWith(SDOperand(N, 1), Ch); } void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N, @@ -1184,7 +1243,7 @@ // Legalized the flag result - switch anything that used the old flag to // use the new one. - ReplaceLegalValueWith(SDOperand(N, 1), Hi.getValue(1)); + ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); } void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N, @@ -1203,7 +1262,7 @@ // Legalized the flag result - switch anything that used the old flag to // use the new one. - ReplaceLegalValueWith(SDOperand(N, 1), Hi.getValue(1)); + ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1)); } void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N, @@ -1537,7 +1596,7 @@ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && "Invalid operand expansion"); - ReplaceLegalValueWith(SDOperand(N, 0), Res); + ReplaceValueWith(SDOperand(N, 0), Res); return false; } @@ -1759,7 +1818,7 @@ assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && "Invalid operand expansion"); - ReplaceLegalValueWith(SDOperand(N, 0), Res); + ReplaceValueWith(SDOperand(N, 0), Res); return false; } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Sat Nov 24 01:07:01 2007 @@ -1921,7 +1921,7 @@ if (Cases.size()>=2) // Must recompute end() each iteration because it may be // invalidated by erase if we hold on to it - for (CaseItr I=Cases.begin(), J=next(Cases.begin()); J!=Cases.end(); ) { + for (CaseItr I=Cases.begin(), J=++(Cases.begin()); J!=Cases.end(); ) { int64_t nextValue = cast(J->Low)->getSExtValue(); int64_t currentValue = cast(I->High)->getSExtValue(); MachineBasicBlock* nextBB = J->BB; @@ -4144,14 +4144,6 @@ return SDOperand(); } -std::pair -TargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { - assert(0 && "ExpandOperation not implemented for this target!"); - abort(); - return std::pair(); -} - - SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG) { assert(0 && "CustomPromoteOperation not implemented for this target!"); Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Sat Nov 24 01:07:01 2007 @@ -949,10 +949,8 @@ vRegs[NumGPRs+1] = VReg; SDOperand ArgValue2 = DAG.getCopyFromReg(Root, VReg, MVT::i32); - if (ObjectVT == MVT::i64) - ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2); - else - ArgValue = DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2); + assert(ObjectVT != MVT::i64 && "i64 should already be lowered"); + ArgValue = DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2); } NumGPRs += ObjGPRs; @@ -966,12 +964,9 @@ if (ObjGPRs == 0) ArgValue = DAG.getLoad(ObjectVT, Root, FIN, NULL, 0); else { - SDOperand ArgValue2 = - DAG.getLoad(MVT::i32, Root, FIN, NULL, 0); - if (ObjectVT == MVT::i64) - ArgValue= DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgValue, ArgValue2); - else - ArgValue= DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2); + SDOperand ArgValue2 = DAG.getLoad(MVT::i32, Root, FIN, NULL, 0); + assert(ObjectVT != MVT::i64 && "i64 should already be lowered"); + ArgValue = DAG.getNode(ARMISD::FMDRR, MVT::f64, ArgValue, ArgValue2); } } else { // Don't emit a dead load. @@ -1256,51 +1251,6 @@ return DAG.getNode(ARMISD::CNEG, VT, AbsVal, AbsVal, ARMCC, CCR, Cmp); } -static SDOperand LowerBIT_CONVERT(SDOperand Op, SelectionDAG &DAG) { - // Turn f64->i64 into FMRRD. - assert(Op.getValueType() == MVT::i64 && - Op.getOperand(0).getValueType() == MVT::f64); - - Op = Op.getOperand(0); - SDOperand Cvt = DAG.getNode(ARMISD::FMRRD, DAG.getVTList(MVT::i32, MVT::i32), - &Op, 1); - - // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)); -} - -static SDOperand LowerSRx(SDOperand Op, SelectionDAG &DAG, - const ARMSubtarget *ST) { - assert(Op.getValueType() == MVT::i64 && - (Op.getOpcode() == ISD::SRL || Op.getOpcode() == ISD::SRA) && - "Unknown shift to lower!"); - - // We only lower SRA, SRL of 1 here, all others use generic lowering. - if (!isa(Op.getOperand(1)) || - cast(Op.getOperand(1))->getValue() != 1) - return SDOperand(); - - // If we are in thumb mode, we don't have RRX. - if (ST->isThumb()) return SDOperand(); - - // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. - SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(0, MVT::i32)); - SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0), - DAG.getConstant(1, MVT::i32)); - - // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and - // captures the result into a carry flag. - unsigned Opc = Op.getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; - Hi = DAG.getNode(Opc, DAG.getVTList(MVT::i32, MVT::Flag), &Hi, 1); - - // The low part is an ARMISD::RRX operand, which shifts the carry in. - Lo = DAG.getNode(ARMISD::RRX, MVT::i32, Lo, Hi.getValue(1)); - - // Merge the pieces into a single i64 value. - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); -} - SDOperand ARMTargetLowering::LowerMEMCPYInline(SDOperand Chain, SDOperand Dest, SDOperand Source, @@ -1396,6 +1346,51 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i); } +static SDNode *ExpandBIT_CONVERT(SDNode *N, SelectionDAG &DAG) { + // Turn f64->i64 into FMRRD. + assert(N->getValueType(0) == MVT::i64 && + N->getOperand(0).getValueType() == MVT::f64); + + SDOperand Op = N->getOperand(0); + SDOperand Cvt = DAG.getNode(ARMISD::FMRRD, DAG.getVTList(MVT::i32, MVT::i32), + &Op, 1); + + // Merge the pieces into a single i64 value. + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Cvt, Cvt.getValue(1)).Val; +} + +static SDNode *ExpandSRx(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *ST) { + assert(N->getValueType(0) == MVT::i64 && + (N->getOpcode() == ISD::SRL || N->getOpcode() == ISD::SRA) && + "Unknown shift to lower!"); + + // We only lower SRA, SRL of 1 here, all others use generic lowering. + if (!isa(N->getOperand(1)) || + cast(N->getOperand(1))->getValue() != 1) + return 0; + + // If we are in thumb mode, we don't have RRX. + if (ST->isThumb()) return 0; + + // Okay, we have a 64-bit SRA or SRL of 1. Lower this to an RRX expr. + SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(0), + DAG.getConstant(0, MVT::i32)); + SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, N->getOperand(0), + DAG.getConstant(1, MVT::i32)); + + // First, build a SRA_FLAG/SRL_FLAG op, which shifts the top part by one and + // captures the result into a carry flag. + unsigned Opc = N->getOpcode() == ISD::SRL ? ARMISD::SRL_FLAG:ARMISD::SRA_FLAG; + Hi = DAG.getNode(Opc, DAG.getVTList(MVT::i32, MVT::Flag), &Hi, 1); + + // The low part is an ARMISD::RRX operand, which shifts the carry in. + Lo = DAG.getNode(ARMISD::RRX, MVT::i32, Lo, Hi.getValue(1)); + + // Merge the pieces into a single i64 value. + return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi).Val; +} + + SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: assert(0 && "Don't know how to custom lower this!"); abort(); @@ -1415,20 +1410,35 @@ case ISD::FP_TO_SINT: case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); - case ISD::BIT_CONVERT: return LowerBIT_CONVERT(Op, DAG); - case ISD::SRL: - case ISD::SRA: return LowerSRx(Op, DAG, Subtarget); - case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG); + case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::MEMCPY: return LowerMEMCPY(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); + + + // FIXME: Remove these when LegalizeDAGTypes lands. + case ISD::BIT_CONVERT: return SDOperand(ExpandBIT_CONVERT(Op.Val, DAG), 0); + case ISD::SRL: + case ISD::SRA: return SDOperand(ExpandSRx(Op.Val, DAG,Subtarget),0); } return SDOperand(); } + +/// ExpandOperationResult - Provide custom lowering hooks for expanding +/// operations. +SDNode *ARMTargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { + switch (N->getOpcode()) { + default: assert(0 && "Don't know how to custom expand this!"); abort(); + case ISD::BIT_CONVERT: return ExpandBIT_CONVERT(N, DAG); + case ISD::SRL: + case ISD::SRA: return ExpandSRx(N, DAG, Subtarget); + } +} + + //===----------------------------------------------------------------------===// // ARM Scheduler Hooks //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Sat Nov 24 01:07:01 2007 @@ -76,6 +76,8 @@ explicit ARMTargetLowering(TargetMachine &TM); virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + virtual const char *getTargetNodeName(unsigned Opcode) const; virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Nov 24 01:07:01 2007 @@ -1258,7 +1258,7 @@ SDOperand AlignNode = DAG.getConstant(Align, MVT::i32); SDOperand SizeNode = DAG.getConstant(Size, MVT::i32); - SDOperand AlwaysInline = DAG.getConstant(1, MVT::i1); + SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32); return DAG.getMemcpy(Chain, PtrOff, Arg, SizeNode, AlignNode, AlwaysInline); @@ -3918,22 +3918,22 @@ return Result; } -SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) { +std::pair X86TargetLowering:: +FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) { assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 && "Unknown FP_TO_SINT to lower!"); - SDOperand Result; // These are really Legal. if (Op.getValueType() == MVT::i32 && X86ScalarSSEf32 && Op.getOperand(0).getValueType() == MVT::f32) - return Result; + return std::make_pair(SDOperand(), SDOperand()); if (Op.getValueType() == MVT::i32 && X86ScalarSSEf64 && Op.getOperand(0).getValueType() == MVT::f64) - return Result; + return std::make_pair(SDOperand(), SDOperand()); if (Subtarget->is64Bit() && Op.getValueType() == MVT::i64 && Op.getOperand(0).getValueType() != MVT::f80) - return Result; + return std::make_pair(SDOperand(), SDOperand()); // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary // stack slot. @@ -3943,10 +3943,10 @@ SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy()); unsigned Opc; switch (Op.getValueType()) { - default: assert(0 && "Invalid FP_TO_SINT to lower!"); - case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; - case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; - case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; + default: assert(0 && "Invalid FP_TO_SINT to lower!"); + case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break; + case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break; + case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break; } SDOperand Chain = DAG.getEntryNode(); @@ -3969,20 +3969,33 @@ SDOperand Ops[] = { Chain, Value, StackSlot }; SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops, 3); - // Load the result. If this is an i64 load on an x86-32 host, expand the - // load. - if (Op.getValueType() != MVT::i64 || Subtarget->is64Bit()) - return DAG.getLoad(Op.getValueType(), FIST, StackSlot, NULL, 0); - - SDOperand Lo = DAG.getLoad(MVT::i32, FIST, StackSlot, NULL, 0); - StackSlot = DAG.getNode(ISD::ADD, StackSlot.getValueType(), StackSlot, - DAG.getConstant(StackSlot.getValueType(), 4)); - SDOperand Hi = DAG.getLoad(MVT::i32, FIST, StackSlot, NULL, 0); - + return std::make_pair(FIST, StackSlot); +} + +SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) { + assert((Op.getValueType() != MVT::i64 || Subtarget->is64Bit()) && + "This FP_TO_SINT must be expanded!"); + + std::pair Vals = FP_TO_SINTHelper(Op, DAG); + SDOperand FIST = Vals.first, StackSlot = Vals.second; + if (FIST.Val == 0) return SDOperand(); - return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); + // Load the result. + return DAG.getLoad(Op.getValueType(), FIST, StackSlot, NULL, 0); } +SDNode *X86TargetLowering::ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG) { + std::pair Vals = FP_TO_SINTHelper(SDOperand(N, 0), DAG); + SDOperand FIST = Vals.first, StackSlot = Vals.second; + if (FIST.Val == 0) return 0; + + // Return an i64 load from the stack slot. + SDOperand Res = DAG.getLoad(MVT::i64, FIST, StackSlot, NULL, 0); + + // Use a MERGE_VALUES node to drop the chain result value. + return DAG.getNode(ISD::MERGE_VALUES, MVT::i64, Res).Val; +} + SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) { MVT::ValueType VT = Op.getValueType(); MVT::ValueType EltVT = VT; @@ -4587,32 +4600,36 @@ return Chain; } -SDOperand -X86TargetLowering::LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG) { +/// Expand the result of: i64,outchain = READCYCLECOUNTER inchain +SDNode *X86TargetLowering::ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG){ SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag); - SDOperand TheOp = Op.getOperand(0); - SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheOp, 1); + SDOperand TheChain = N->getOperand(0); + SDOperand rd = DAG.getNode(X86ISD::RDTSC_DAG, Tys, &TheChain, 1); if (Subtarget->is64Bit()) { - SDOperand Copy1 = - DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); - SDOperand Copy2 = DAG.getCopyFromReg(Copy1.getValue(1), X86::RDX, - MVT::i64, Copy1.getValue(2)); - SDOperand Tmp = DAG.getNode(ISD::SHL, MVT::i64, Copy2, + SDOperand rax = DAG.getCopyFromReg(rd, X86::RAX, MVT::i64, rd.getValue(1)); + SDOperand rdx = DAG.getCopyFromReg(rax.getValue(1), X86::RDX, + MVT::i64, rax.getValue(2)); + SDOperand Tmp = DAG.getNode(ISD::SHL, MVT::i64, rdx, DAG.getConstant(32, MVT::i8)); SDOperand Ops[] = { - DAG.getNode(ISD::OR, MVT::i64, Copy1, Tmp), Copy2.getValue(1) + DAG.getNode(ISD::OR, MVT::i64, rax, Tmp), rdx.getValue(1) }; Tys = DAG.getVTList(MVT::i64, MVT::Other); - return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2); + return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2).Val; } - SDOperand Copy1 = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); - SDOperand Copy2 = DAG.getCopyFromReg(Copy1.getValue(1), X86::EDX, - MVT::i32, Copy1.getValue(2)); - SDOperand Ops[] = { Copy1, Copy2, Copy2.getValue(1) }; - Tys = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other); - return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 3); + SDOperand eax = DAG.getCopyFromReg(rd, X86::EAX, MVT::i32, rd.getValue(1)); + SDOperand edx = DAG.getCopyFromReg(eax.getValue(1), X86::EDX, + MVT::i32, eax.getValue(2)); + // Use a buildpair to merge the two 32-bit values into a 64-bit one. + SDOperand Ops[] = { eax, edx }; + Ops[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Ops, 2); + + // Use a MERGE_VALUES to return the value and chain. + Ops[1] = edx.getValue(1); + Tys = DAG.getVTList(MVT::i64, MVT::Other); + return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2).Val; } SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) { @@ -5032,7 +5049,6 @@ case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::MEMSET: return LowerMEMSET(Op, DAG); case ISD::MEMCPY: return LowerMEMCPY(Op, DAG); - case ISD::READCYCLECOUNTER: return LowerREADCYCLCECOUNTER(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::VACOPY: return LowerVACOPY(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); @@ -5044,8 +5060,21 @@ case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG); case ISD::FLT_ROUNDS: return LowerFLT_ROUNDS(Op, DAG); + + + // FIXME: REMOVE THIS WHEN LegalizeDAGTypes lands. + case ISD::READCYCLECOUNTER: + return SDOperand(ExpandREADCYCLECOUNTER(Op.Val, DAG), 0); + } +} + +/// ExpandOperation - Provide custom lowering hooks for expanding operations. +SDNode *X86TargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { + switch (N->getOpcode()) { + default: assert(0 && "Should not custom lower this!"); + case ISD::FP_TO_SINT: return ExpandFP_TO_SINT(N, DAG); + case ISD::READCYCLECOUNTER: return ExpandREADCYCLECOUNTER(N, DAG); } - return SDOperand(); } const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=44300&r1=44299&r2=44300&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Sat Nov 24 01:07:01 2007 @@ -321,6 +321,12 @@ /// virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); + /// ExpandOperation - Custom lower the specified operation, splitting the + /// value into two pieces. + /// + virtual SDNode *ExpandOperationResult(SDNode *N, SelectionDAG &DAG); + + virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, @@ -444,6 +450,9 @@ SDOperand LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC); + std::pair FP_TO_SINTHelper(SDOperand Op, + SelectionDAG &DAG); + SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG); SDOperand LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG); SDOperand LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG); @@ -471,7 +480,6 @@ SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerDYNAMIC_STACKALLOC(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); - SDOperand LowerREADCYCLCECOUNTER(SDOperand Op, SelectionDAG &DAG); SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG); SDOperand LowerVACOPY(SDOperand Op, SelectionDAG &DAG); SDOperand LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG); @@ -481,6 +489,8 @@ SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG); SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG); + SDNode *ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG); + SDNode *ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG); }; } From baldrick at free.fr Sat Nov 24 02:55:43 2007 From: baldrick at free.fr (Duncan Sands) Date: Sat, 24 Nov 2007 09:55:43 +0100 Subject: [llvm-commits] [llvm] r44300 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h In-Reply-To: <200711240707.lAO772rd017178@zion.cs.uiuc.edu> References: <200711240707.lAO772rd017178@zion.cs.uiuc.edu> Message-ID: <200711240955.44277.baldrick@free.fr> Hi Chris, > /// RemapNode - If the specified value was already legalized to another value, > /// replace it by that value. > void DAGTypeLegalizer::RemapNode(SDOperand &N) { > - DenseMap::iterator I = ReplacedNodes.find(N); > - if (I != ReplacedNodes.end()) { > - RemapNode(I->second); > + for (DenseMap::iterator I = ReplacedNodes.find(N); > + I != ReplacedNodes.end(); I = ReplacedNodes.find(N)) > N = I->second; > - } > } in the original version this updated the map too (or at least it was supposed to). For example, suppose we remap N and the map contained: N -> A A -> B B -> C then afterwards we would get N = C, but also the map would be modified to: N -> C A -> C B -> C This was supposed to speed up later lookups. > + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { > + // Everything that once used N now uses P. P had better not require > + // custom expansion. How about an assertion that it doesn't require custom expansion? Ciao, Duncan. From sabre at nondot.org Sat Nov 24 12:11:43 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 18:11:43 -0000 Subject: [llvm-commits] [llvm] r44301 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200711241811.lAOIBh2f028092@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 12:11:42 2007 New Revision: 44301 URL: http://llvm.org/viewvc/llvm-project?rev=44301&view=rev Log: Implement support for custom legalization in DAGTypeLegalizer::ExpandOperand. Improve a comment. Unbreak Duncan's carefully written path compression where I didn't realize what was happening! Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=44301&r1=44300&r2=44301&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Sat Nov 24 12:11:42 2007 @@ -469,9 +469,13 @@ /// RemapNode - If the specified value was already legalized to another value, /// replace it by that value. void DAGTypeLegalizer::RemapNode(SDOperand &N) { - for (DenseMap::iterator I = ReplacedNodes.find(N); - I != ReplacedNodes.end(); I = ReplacedNodes.find(N)) + DenseMap::iterator I = ReplacedNodes.find(N); + if (I != ReplacedNodes.end()) { + // Use path compression to speed up future lookups if values get multiply + // replaced with other values. + RemapNode(I->second); N = I->second; + } } void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) { @@ -842,8 +846,8 @@ TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { - // Everything that once used N now uses P. P had better not require - // custom expansion. + // Everything that once used N now uses P. We are guaranteed that the + // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); return; } @@ -1774,32 +1778,41 @@ /// need promotion or expansion as well as the specified one. bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res; - switch (N->getOpcode()) { - default: -#ifndef NDEBUG - cerr << "ExpandOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; -#endif - assert(0 && "Do not know how to expand this operator's operand!"); - abort(); - - case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break; - case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break; - - case ISD::SINT_TO_FP: - Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::UINT_TO_FP: - Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); - break; - case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break; - case ISD::SETCC: Res = ExpandOperand_SETCC(N); break; + SDOperand Res(0, 0); + + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == + TargetLowering::Custom) + Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + + if (Res.Val == 0) { + switch (N->getOpcode()) { + default: + #ifndef NDEBUG + cerr << "ExpandOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; + #endif + assert(0 && "Do not know how to expand this operator's operand!"); + abort(); + + case ISD::TRUNCATE: Res = ExpandOperand_TRUNCATE(N); break; + case ISD::BIT_CONVERT: Res = ExpandOperand_BIT_CONVERT(N); break; - case ISD::STORE: Res = ExpandOperand_STORE(cast(N), OpNo); break; - case ISD::MEMSET: - case ISD::MEMCPY: - case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; + case ISD::SINT_TO_FP: + Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0)); + break; + case ISD::UINT_TO_FP: + Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); + break; + case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break; + case ISD::SETCC: Res = ExpandOperand_SETCC(N); break; + + case ISD::STORE: + Res = ExpandOperand_STORE(cast(N), OpNo); + break; + case ISD::MEMSET: + case ISD::MEMCPY: + case ISD::MEMMOVE: Res = HandleMemIntrinsic(N); break; + } } // If the result is null, the sub-method took care of registering results etc. From clattner at apple.com Sat Nov 24 12:12:38 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 24 Nov 2007 10:12:38 -0800 Subject: [llvm-commits] [llvm] r44300 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h In-Reply-To: <200711240955.44277.baldrick@free.fr> References: <200711240707.lAO772rd017178@zion.cs.uiuc.edu> <200711240955.44277.baldrick@free.fr> Message-ID: On Nov 24, 2007, at 12:55 AM, Duncan Sands wrote: > Hi Chris, > >> /// RemapNode - If the specified value was already legalized to >> another value, >> /// replace it by that value. >> void DAGTypeLegalizer::RemapNode(SDOperand &N) { >> - DenseMap::iterator I = >> ReplacedNodes.find(N); >> - if (I != ReplacedNodes.end()) { >> - RemapNode(I->second); >> + for (DenseMap::iterator I = >> ReplacedNodes.find(N); >> + I != ReplacedNodes.end(); I = ReplacedNodes.find(N)) >> N = I->second; >> - } >> } > > in the original version this updated the map too (or at least it was > supposed > to). For example, suppose we remap N and the map contained: > N -> A > A -> B > B -> C > then afterwards we would get N = C, but also the map would be > modified to: > N -> C > A -> C > B -> C > This was supposed to speed up later lookups. Urg, I completely missed that. Restored, sorry! >> + if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { >> + // Everything that once used N now uses P. P had better not >> require >> + // custom expansion. > > How about an assertion that it doesn't require custom expansion? I don't know what I was thinking with that comment, I updated it to better describe the constraints. Thanks for the review Duncan! -Chris From clattner at apple.com Sat Nov 24 13:17:35 2007 From: clattner at apple.com (Chris Lattner) Date: Sat, 24 Nov 2007 11:17:35 -0800 Subject: [llvm-commits] jit failures due to attributes changes Message-ID: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> I think all of my breakage is resolved, however, the attribuets changes introduced a number of jit regressions. The problem is that "exit" is now getting declared as: declare void @exit(i32) noreturn nounwind This is a problem for lli.cpp, because it does this: Constant *Exit = Mod->getOrInsertFunction("exit", Type::VoidTy, Type::Int32Ty, NULL); ... if (Function *ExitF = dyn_cast(Exit)) { ... } else { std::cerr << "ERROR: exit defined with wrong prototype!\n"; abort(); The problem here is that getOrInsertFunction is returning a bitcast of the exit function (with the type above) to a void(int)* type. I think that getOrInsertFunction should just return the function (not a bitcast) if the function type other than the attributes are the same. -Chris From sabre at nondot.org Sat Nov 24 13:12:15 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 19:12:15 -0000 Subject: [llvm-commits] [llvm] r44304 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200711241912.lAOJCGSp031869@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 13:12:15 2007 New Revision: 44304 URL: http://llvm.org/viewvc/llvm-project?rev=44304&view=rev Log: Implement expand support for MERGE_VALUEs that only produces one result. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=44304&r1=44303&r2=44304&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sat Nov 24 13:12:15 2007 @@ -5401,6 +5401,10 @@ break; case ISD::MERGE_VALUES: + if (Node->getNumValues() == 1) { + ExpandOp(Op.getOperand(0), Lo, Hi); + break; + } // FIXME: For now only expand i64,chain = MERGE_VALUES (x, y) assert(Op.ResNo == 0 && Node->getNumValues() == 2 && Op.getValue(1).getValueType() == MVT::Other && From sabre at nondot.org Sat Nov 24 12:37:21 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 18:37:21 -0000 Subject: [llvm-commits] [llvm] r44302 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <200711241837.lAOIbLuP029872@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 12:37:20 2007 New Revision: 44302 URL: http://llvm.org/viewvc/llvm-project?rev=44302&view=rev Log: remove bogus assertion that broke CodeGen/Generic/cast-fp.ll on x86 among others. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44302&r1=44301&r2=44302&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Nov 24 12:37:20 2007 @@ -3973,9 +3973,6 @@ } SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) { - assert((Op.getValueType() != MVT::i64 || Subtarget->is64Bit()) && - "This FP_TO_SINT must be expanded!"); - std::pair Vals = FP_TO_SINTHelper(Op, DAG); SDOperand FIST = Vals.first, StackSlot = Vals.second; if (FIST.Val == 0) return SDOperand(); From sabre at nondot.org Sat Nov 24 13:02:07 2007 From: sabre at nondot.org (Chris Lattner) Date: Sat, 24 Nov 2007 19:02:07 -0000 Subject: [llvm-commits] [llvm] r44303 - /llvm/trunk/lib/Target/TargetSelectionDAG.td Message-ID: <200711241902.lAOJ27jT031322@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 13:02:07 2007 New Revision: 44303 URL: http://llvm.org/viewvc/llvm-project?rev=44303&view=rev Log: add a immAllZerosV_bc pattern fragment for consistency with others. Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td Modified: llvm/trunk/lib/Target/TargetSelectionDAG.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetSelectionDAG.td?rev=44303&r1=44302&r2=44303&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetSelectionDAG.td (original) +++ llvm/trunk/lib/Target/TargetSelectionDAG.td Sat Nov 24 13:02:07 2007 @@ -405,15 +405,18 @@ def immAllOnesV: PatLeaf<(build_vector), [{ return ISD::isBuildVectorAllOnes(N); }]>; +def immAllOnesV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllOnes(N); +}]>; def immAllZerosV: PatLeaf<(build_vector), [{ return ISD::isBuildVectorAllZeros(N); }]>; - -def immAllOnesV_bc: PatLeaf<(bitconvert), [{ - return ISD::isBuildVectorAllOnes(N); +def immAllZerosV_bc: PatLeaf<(bitconvert), [{ + return ISD::isBuildVectorAllZeros(N); }]>; + // Other helper fragments. def not : PatFrag<(ops node:$in), (xor node:$in, immAllOnes)>; def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; From nicholas at mxc.ca Sat Nov 24 17:35:12 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Sat, 24 Nov 2007 15:35:12 -0800 Subject: [llvm-commits] recent kimwitu++ failure Message-ID: <4748B530.2060300@mxc.ca> MultiSource/Applications/kimwitu++ fails to link with this error: llvm-ld: error: Cannot link file 'Output/rk.bc': Appending variables with different element types need to be linked! This appears to be fall-out from the attribute changes. Could someone please take a look at this? Thanks, Nick Lewycky From sabre at nondot.org Sat Nov 24 18:24:50 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 25 Nov 2007 00:24:50 -0000 Subject: [llvm-commits] [llvm] r44310 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrMMX.td lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/vec_zero_cse.ll Message-ID: <200711250024.lAP0OopO021141@zion.cs.uiuc.edu> Author: lattner Date: Sat Nov 24 18:24:49 2007 New Revision: 44310 URL: http://llvm.org/viewvc/llvm-project?rev=44310&view=rev Log: Fix a long standing deficiency in the X86 backend: we would sometimes emit "zero" and "all one" vectors multiple times, for example: _test2: pcmpeqd %mm0, %mm0 movq %mm0, _M1 pcmpeqd %mm0, %mm0 movq %mm0, _M2 ret instead of: _test2: pcmpeqd %mm0, %mm0 movq %mm0, _M1 movq %mm0, _M2 ret This patch fixes this by always arranging for zero/one vectors to be defined as v4i32 or v2i32 (SSE/MMX) instead of letting them be any random type. This ensures they get trivially CSE'd on the dag. This fix is also important for LegalizeDAGTypes, as it gets unhappy when the x86 backend wants BUILD_VECTOR(i64 0) to be legal even when 'i64' isn't legal. This patch makes the following changes: 1) X86TargetLowering::LowerBUILD_VECTOR now lowers 0/1 vectors into their canonical types. 2) The now-dead patterns are removed from the SSE/MMX .td files. 3) All the patterns in the .td file that referred to immAllOnesV or immAllZerosV in the wrong form now use *_bc to match them with a bitcast wrapped around them. 4) X86DAGToDAGISel::SelectScalarSSELoad is generalized to handle bitcast'd zero vectors, which simplifies the code actually. 5) getShuffleVectorZeroOrUndef is updated to generate a shuffle that is legal, instead of generating one that is illegal and expecting a later legalize pass to clean it up. 6) isZeroShuffle is generalized to handle bitcast of zeros. 7) several other minor tweaks. This patch is definite goodness, but has the potential to cause random code quality regressions. Please be on the lookout for these and let me know if they happen. Added: llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrMMX.td llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=44310&r1=44309&r2=44310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Sat Nov 24 18:24:49 2007 @@ -842,20 +842,15 @@ // Also handle the case where we explicitly require zeros in the top // elements. This is a vector shuffle from the zero vector. if (N.getOpcode() == ISD::VECTOR_SHUFFLE && N.Val->hasOneUse() && - N.getOperand(0).getOpcode() == ISD::BUILD_VECTOR && + // Check to see if the top elements are all zeros (or bitcast of zeros). + ISD::isBuildVectorAllZeros(N.getOperand(0).Val) && N.getOperand(1).getOpcode() == ISD::SCALAR_TO_VECTOR && N.getOperand(1).Val->hasOneUse() && ISD::isNON_EXTLoad(N.getOperand(1).getOperand(0).Val) && N.getOperand(1).getOperand(0).hasOneUse()) { - // Check to see if the BUILD_VECTOR is building a zero vector. - SDOperand BV = N.getOperand(0); - for (unsigned i = 0, e = BV.getNumOperands(); i != e; ++i) - if (!isZeroNode(BV.getOperand(i)) && - BV.getOperand(i).getOpcode() != ISD::UNDEF) - return false; // Not a zero/undef vector. // Check to see if the shuffle mask is 4/L/L/L or 2/L, where L is something // from the LHS. - unsigned VecWidth = BV.getNumOperands(); + unsigned VecWidth=MVT::getVectorNumElements(N.getOperand(0).getValueType()); SDOperand ShufMask = N.getOperand(2); assert(ShufMask.getOpcode() == ISD::BUILD_VECTOR && "Invalid shuf mask!"); if (ConstantSDNode *C = dyn_cast(ShufMask.getOperand(0))) { Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=44310&r1=44309&r2=44310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sat Nov 24 18:24:49 2007 @@ -2728,7 +2728,7 @@ return true; } -/// CommuteVectorShuffle - Swap vector_shuffle operandsas well as +/// CommuteVectorShuffle - Swap vector_shuffle operands as well as /// values in ther permute mask. static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1, SDOperand &V2, SDOperand &Mask, @@ -2867,23 +2867,24 @@ unsigned NumElems = Mask.getNumOperands(); for (unsigned i = 0; i != NumElems; ++i) { SDOperand Arg = Mask.getOperand(i); - if (Arg.getOpcode() != ISD::UNDEF) { - unsigned Idx = cast(Arg)->getValue(); - if (Idx < NumElems) { - unsigned Opc = V1.Val->getOpcode(); - if (Opc == ISD::UNDEF) - continue; - if (Opc != ISD::BUILD_VECTOR || - !isZeroNode(V1.Val->getOperand(Idx))) - return false; - } else if (Idx >= NumElems) { - unsigned Opc = V2.Val->getOpcode(); - if (Opc == ISD::UNDEF) - continue; - if (Opc != ISD::BUILD_VECTOR || - !isZeroNode(V2.Val->getOperand(Idx - NumElems))) - return false; - } + if (Arg.getOpcode() == ISD::UNDEF) + continue; + + unsigned Idx = cast(Arg)->getValue(); + if (Idx < NumElems) { + unsigned Opc = V1.Val->getOpcode(); + if (Opc == ISD::UNDEF || ISD::isBuildVectorAllZeros(V1.Val)) + continue; + if (Opc != ISD::BUILD_VECTOR || + !isZeroNode(V1.Val->getOperand(Idx))) + return false; + } else if (Idx >= NumElems) { + unsigned Opc = V2.Val->getOpcode(); + if (Opc == ISD::UNDEF || ISD::isBuildVectorAllZeros(V2.Val)) + continue; + if (Opc != ISD::BUILD_VECTOR || + !isZeroNode(V2.Val->getOperand(Idx - NumElems))) + return false; } } return true; @@ -2893,14 +2894,35 @@ /// static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) { assert(MVT::isVector(VT) && "Expected a vector type"); - unsigned NumElems = MVT::getVectorNumElements(VT); - MVT::ValueType EVT = MVT::getVectorElementType(VT); - bool isFP = MVT::isFloatingPoint(EVT); - SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT); - SmallVector ZeroVec(NumElems, Zero); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size()); + + // Always build zero vectors as <4 x i32> or <2 x i32> bitcasted to their dest + // type. This ensures they get CSE'd. + SDOperand Cst = DAG.getTargetConstant(0, MVT::i32); + SDOperand Vec; + if (MVT::getSizeInBits(VT) == 64) // MMX + Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i32, Cst, Cst); + else // SSE + Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst, Cst, Cst, Cst); + return DAG.getNode(ISD::BIT_CONVERT, VT, Vec); +} + +/// getOnesVector - Returns a vector of specified type with all bits set. +/// +static SDOperand getOnesVector(MVT::ValueType VT, SelectionDAG &DAG) { + assert(MVT::isVector(VT) && "Expected a vector type"); + + // Always build ones vectors as <4 x i32> or <2 x i32> bitcasted to their dest + // type. This ensures they get CSE'd. + SDOperand Cst = DAG.getTargetConstant(~0U, MVT::i32); + SDOperand Vec; + if (MVT::getSizeInBits(VT) == 64) // MMX + Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i32, Cst, Cst); + else // SSE + Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst, Cst, Cst, Cst); + return DAG.getNode(ISD::BIT_CONVERT, VT, Vec); } + /// NormalizeMask - V2 is a splat, modify the mask (if needed) so all elements /// that point to V2 points to its first element. static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) { @@ -2981,24 +3003,28 @@ } V1 = DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, V1); - MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4); - Mask = getZeroVector(MaskVT, DAG); + Mask = getZeroVector(MVT::v4i32, DAG); SDOperand Shuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v4i32, V1, DAG.getNode(ISD::UNDEF, MVT::v4i32), Mask); return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle); } /// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified -/// vector of zero or undef vector. +/// vector of zero or undef vector. This produces a shuffle where the low +/// element of V2 is swizzled into the zero/undef vector, landing at element +/// Idx. This produces a shuffle mask like 4,1,2,3 (idx=0) or 0,1,2,4 (idx=3). static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT, unsigned NumElems, unsigned Idx, bool isZero, SelectionDAG &DAG) { SDOperand V1 = isZero ? getZeroVector(VT, DAG) : DAG.getNode(ISD::UNDEF, VT); MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems); MVT::ValueType EVT = MVT::getVectorElementType(MaskVT); - SDOperand Zero = DAG.getConstant(0, EVT); - SmallVector MaskVec(NumElems, Zero); - MaskVec[Idx] = DAG.getConstant(NumElems, EVT); + SmallVector MaskVec; + for (unsigned i = 0; i != NumElems; ++i) + if (i == Idx) // If this is the insertion idx, put the low elt of V2 here. + MaskVec.push_back(DAG.getConstant(NumElems, EVT)); + else + MaskVec.push_back(DAG.getConstant(i, EVT)); SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size()); return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask); @@ -3078,13 +3104,18 @@ SDOperand X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) { - // All zero's are handled with pxor. - if (ISD::isBuildVectorAllZeros(Op.Val)) - return Op; + // All zero's are handled with pxor, all one's are handled with pcmpeqd. + if (ISD::isBuildVectorAllZeros(Op.Val) || ISD::isBuildVectorAllOnes(Op.Val)) { + // Canonicalize this to either <4 x i32> or <2 x i32> (SSE vs MMX) to + // 1) ensure the zero vectors are CSE'd, and 2) ensure that i64 scalars are + // eliminated on x86-32 hosts. + if (Op.getValueType() == MVT::v4i32 || Op.getValueType() == MVT::v2i32) + return Op; - // All one's are handled with pcmpeqd. - if (ISD::isBuildVectorAllOnes(Op.Val)) - return Op; + if (ISD::isBuildVectorAllOnes(Op.Val)) + return getOnesVector(Op.getValueType(), DAG); + return getZeroVector(Op.getValueType(), DAG); + } MVT::ValueType VT = Op.getValueType(); MVT::ValueType EVT = MVT::getVectorElementType(VT); @@ -3113,12 +3144,8 @@ } if (NumNonZero == 0) { - if (NumZero == 0) - // All undef vector. Return an UNDEF. - return DAG.getNode(ISD::UNDEF, VT); - else - // A mix of zero and undef. Return a zero vector. - return getZeroVector(VT, DAG); + // All undef vector. Return an UNDEF. All zero vectors were handled above. + return DAG.getNode(ISD::UNDEF, VT); } // Splat is obviously ok. Let legalizer expand it to a shuffle. @@ -3299,8 +3326,12 @@ return CommuteVectorShuffle(Op, V1, V2, PermMask, DAG); bool Commuted = false; + // FIXME: This should also accept a bitcast of a splat? Be careful, not + // 1,1,1,1 -> v8i16 though. V1IsSplat = isSplatVector(V1.Val); V2IsSplat = isSplatVector(V2.Val); + + // Canonicalize the splat or undef, if present, to be on the RHS. if ((V1IsSplat || V1IsUndef) && !(V2IsSplat || V2IsUndef)) { Op = CommuteVectorShuffle(Op, V1, V2, PermMask, DAG); std::swap(V1IsSplat, V2IsSplat); Modified: llvm/trunk/lib/Target/X86/X86InstrMMX.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrMMX.td?rev=44310&r1=44309&r2=44310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrMMX.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrMMX.td Sat Nov 24 18:24:49 2007 @@ -486,14 +486,13 @@ //===----------------------------------------------------------------------===// // Alias instructions that map zero vector to pxor. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. let isReMaterializable = 1 in { def MMX_V_SET0 : MMXI<0xEF, MRMInitReg, (outs VR64:$dst), (ins), "pxor\t$dst, $dst", - [(set VR64:$dst, (v1i64 immAllZerosV))]>; + [(set VR64:$dst, (v2i32 immAllZerosV))]>; def MMX_V_SETALLONES : MMXI<0x76, MRMInitReg, (outs VR64:$dst), (ins), "pcmpeqd\t$dst, $dst", - [(set VR64:$dst, (v1i64 immAllOnesV))]>; + [(set VR64:$dst, (v2i32 immAllOnesV))]>; } //===----------------------------------------------------------------------===// @@ -510,18 +509,6 @@ def : Pat<(store (v1i64 VR64:$src), addr:$dst), (MMX_MOVQ64mr addr:$dst, VR64:$src)>; -// 64-bit vector all zero's. -def : Pat<(v8i8 immAllZerosV), (MMX_V_SET0)>; -def : Pat<(v4i16 immAllZerosV), (MMX_V_SET0)>; -def : Pat<(v2i32 immAllZerosV), (MMX_V_SET0)>; -def : Pat<(v1i64 immAllZerosV), (MMX_V_SET0)>; - -// 64-bit vector all one's. -def : Pat<(v8i8 immAllOnesV), (MMX_V_SETALLONES)>; -def : Pat<(v4i16 immAllOnesV), (MMX_V_SETALLONES)>; -def : Pat<(v2i32 immAllOnesV), (MMX_V_SETALLONES)>; -def : Pat<(v1i64 immAllOnesV), (MMX_V_SETALLONES)>; - // Bit convert. def : Pat<(v8i8 (bitconvert (v1i64 VR64:$src))), (v8i8 VR64:$src)>; def : Pat<(v8i8 (bitconvert (v2i32 VR64:$src))), (v8i8 VR64:$src)>; @@ -551,10 +538,10 @@ // Move scalar to XMM zero-extended // movd to XMM register zero-extends let AddedComplexity = 15 in { - def : Pat<(v8i8 (vector_shuffle immAllZerosV, + def : Pat<(v8i8 (vector_shuffle immAllZerosV_bc, (v8i8 (MMX_X86s2vec GR32:$src)), MMX_MOVL_shuffle_mask)), (MMX_MOVZDI2PDIrr GR32:$src)>; - def : Pat<(v4i16 (vector_shuffle immAllZerosV, + def : Pat<(v4i16 (vector_shuffle immAllZerosV_bc, (v4i16 (MMX_X86s2vec GR32:$src)), MMX_MOVL_shuffle_mask)), (MMX_MOVZDI2PDIrr GR32:$src)>; def : Pat<(v2i32 (vector_shuffle immAllZerosV, @@ -606,19 +593,19 @@ def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v2i32 immAllOnesV))), VR64:$src2)), (MMX_PANDNrr VR64:$src1, VR64:$src2)>; -def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v4i16 immAllOnesV))), +def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v4i16 immAllOnesV_bc))), VR64:$src2)), (MMX_PANDNrr VR64:$src1, VR64:$src2)>; -def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v8i8 immAllOnesV))), +def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v8i8 immAllOnesV_bc))), VR64:$src2)), (MMX_PANDNrr VR64:$src1, VR64:$src2)>; def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v2i32 immAllOnesV))), (load addr:$src2))), (MMX_PANDNrm VR64:$src1, addr:$src2)>; -def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v4i16 immAllOnesV))), +def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v4i16 immAllOnesV_bc))), (load addr:$src2))), (MMX_PANDNrm VR64:$src1, addr:$src2)>; -def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v8i8 immAllOnesV))), +def : Pat<(v1i64 (and (xor VR64:$src1, (bc_v1i64 (v8i8 immAllOnesV_bc))), (load addr:$src2))), (MMX_PANDNrm VR64:$src1, addr:$src2)>; Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=44310&r1=44309&r2=44310&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Sat Nov 24 18:24:49 2007 @@ -939,11 +939,10 @@ "stmxcsr\t$dst", [(int_x86_sse_stmxcsr addr:$dst)]>; // Alias instructions that map zero vector to pxor / xorp* for sse. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. let isReMaterializable = 1 in def V_SET0 : PSI<0x57, MRMInitReg, (outs VR128:$dst), (ins), "xorps\t$dst, $dst", - [(set VR128:$dst, (v4f32 immAllZerosV))]>; + [(set VR128:$dst, (v4i32 immAllZerosV))]>; // FR32 to 128-bit vector conversion. def MOVSS2PSrr : SSI<0x10, MRMSrcReg, (outs VR128:$dst), (ins FR32:$src), @@ -991,7 +990,7 @@ let AddedComplexity = 20 in def MOVZSS2PSrm : SSI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f32mem:$src), "movss\t{$src, $dst|$dst, $src}", - [(set VR128:$dst, (v4f32 (vector_shuffle immAllZerosV, + [(set VR128:$dst, (v4f32 (vector_shuffle immAllZerosV_bc, (v4f32 (scalar_to_vector (loadf32 addr:$src))), MOVL_shuffle_mask)))]>; @@ -2119,11 +2118,10 @@ // Alias instructions that map zero vector to pxor / xorp* for sse. -// FIXME: remove when we can teach regalloc that xor reg, reg is ok. let isReMaterializable = 1 in def V_SETALLONES : PDI<0x76, MRMInitReg, (outs VR128:$dst), (ins), "pcmpeqd\t$dst, $dst", - [(set VR128:$dst, (v2f64 immAllOnesV))]>; + [(set VR128:$dst, (v4i32 immAllOnesV))]>; // FR64 to 128-bit vector conversion. def MOVSD2PDrr : SDI<0x10, MRMSrcReg, (outs VR128:$dst), (ins FR64:$src), @@ -2220,7 +2218,7 @@ def MOVZSD2PDrm : SDI<0x10, MRMSrcMem, (outs VR128:$dst), (ins f64mem:$src), "movsd\t{$src, $dst|$dst, $src}", [(set VR128:$dst, - (v2f64 (vector_shuffle immAllZerosV, + (v2f64 (vector_shuffle immAllZerosV_bc, (v2f64 (scalar_to_vector (loadf64 addr:$src))), MOVL_shuffle_mask)))]>; @@ -2692,21 +2690,6 @@ def : Pat<(v4i32 (undef)), (IMPLICIT_DEF_VR128)>, Requires<[HasSSE2]>; def : Pat<(v2i64 (undef)), (IMPLICIT_DEF_VR128)>, Requires<[HasSSE2]>; -// 128-bit vector all zero's. -def : Pat<(v16i8 immAllZerosV), (V_SET0)>, Requires<[HasSSE2]>; -def : Pat<(v8i16 immAllZerosV), (V_SET0)>, Requires<[HasSSE2]>; -def : Pat<(v4i32 immAllZerosV), (V_SET0)>, Requires<[HasSSE2]>; -def : Pat<(v2i64 immAllZerosV), (V_SET0)>, Requires<[HasSSE2]>; -def : Pat<(v2f64 immAllZerosV), (V_SET0)>, Requires<[HasSSE2]>; - -// 128-bit vector all one's. -def : Pat<(v16i8 immAllOnesV), (V_SETALLONES)>, Requires<[HasSSE2]>; -def : Pat<(v8i16 immAllOnesV), (V_SETALLONES)>, Requires<[HasSSE2]>; -def : Pat<(v4i32 immAllOnesV), (V_SETALLONES)>, Requires<[HasSSE2]>; -def : Pat<(v2i64 immAllOnesV), (V_SETALLONES)>, Requires<[HasSSE2]>; -def : Pat<(v4f32 immAllOnesV), (V_SETALLONES)>, Requires<[HasSSE1]>; - - // Scalar to v8i16 / v16i8. The source may be a GR32, but only the lower 8 or // 16-bits matter. def : Pat<(v8i16 (X86s2vec GR32:$src)), (MOVDI2PDIrr GR32:$src)>, @@ -2751,17 +2734,17 @@ // Move scalar to XMM zero-extended // movd to XMM register zero-extends let AddedComplexity = 15 in { -def : Pat<(v8i16 (vector_shuffle immAllZerosV, +def : Pat<(v8i16 (vector_shuffle immAllZerosV_bc, (v8i16 (X86s2vec GR32:$src)), MOVL_shuffle_mask)), (MOVZDI2PDIrr GR32:$src)>, Requires<[HasSSE2]>; -def : Pat<(v16i8 (vector_shuffle immAllZerosV, +def : Pat<(v16i8 (vector_shuffle immAllZerosV_bc, (v16i8 (X86s2vec GR32:$src)), MOVL_shuffle_mask)), (MOVZDI2PDIrr GR32:$src)>, Requires<[HasSSE2]>; // Zeroing a VR128 then do a MOVS{S|D} to the lower bits. -def : Pat<(v2f64 (vector_shuffle immAllZerosV, +def : Pat<(v2f64 (vector_shuffle immAllZerosV_bc, (v2f64 (scalar_to_vector FR64:$src)), MOVL_shuffle_mask)), (MOVLSD2PDrr (V_SET0), FR64:$src)>, Requires<[HasSSE2]>; -def : Pat<(v4f32 (vector_shuffle immAllZerosV, +def : Pat<(v4f32 (vector_shuffle immAllZerosV_bc, (v4f32 (scalar_to_vector FR32:$src)), MOVL_shuffle_mask)), (MOVLSS2PSrr (V_SET0), FR32:$src)>, Requires<[HasSSE2]>; } @@ -2911,7 +2894,7 @@ // Set lowest element and zero upper elements. let AddedComplexity = 20 in -def : Pat<(bc_v2i64 (vector_shuffle immAllZerosV, +def : Pat<(bc_v2i64 (vector_shuffle immAllZerosV_bc, (v2f64 (scalar_to_vector (loadf64 addr:$src))), MOVL_shuffle_mask)), (MOVZQI2PQIrm addr:$src)>, Requires<[HasSSE2]>; Added: llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll?rev=44310&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll (added) +++ llvm/trunk/test/CodeGen/X86/vec_zero_cse.ll Sat Nov 24 18:24:49 2007 @@ -0,0 +1,35 @@ +; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep pxor | count 1 +; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep xorps | count 1 +; RUN: llvm-as < %s | llc -relocation-model=static -mcpu=yonah | grep pcmpeqd | count 2 + + at M1 = external global <1 x i64> + at M2 = external global <2 x i32> + + at S1 = external global <2 x i64> + at S2 = external global <4 x i32> + +define void @test() { + store <1 x i64> zeroinitializer, <1 x i64>* @M1 + store <2 x i32> zeroinitializer, <2 x i32>* @M2 + ret void +} + +define void @test2() { + store <1 x i64> < i64 -1 >, <1 x i64>* @M1 + store <2 x i32> < i32 -1, i32 -1 >, <2 x i32>* @M2 + ret void +} + +define void @test3() { + store <2 x i64> zeroinitializer, <2 x i64>* @S1 + store <4 x i32> zeroinitializer, <4 x i32>* @S2 + ret void +} + +define void @test4() { + store <2 x i64> < i64 -1, i64 -1>, <2 x i64>* @S1 + store <4 x i32> < i32 -1, i32 -1, i32 -1, i32 -1 >, <4 x i32>* @S2 + ret void +} + + From rspencer at reidspencer.com Sun Nov 25 01:05:07 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Sun, 25 Nov 2007 07:05:07 -0000 Subject: [llvm-commits] [llvm] r44313 - /llvm/trunk/utils/TableGen/ Message-ID: <200711250705.lAP757Z0018521@zion.cs.uiuc.edu> Author: reid Date: Sun Nov 25 01:05:05 2007 New Revision: 44313 URL: http://llvm.org/viewvc/llvm-project?rev=44313&view=rev Log: Don't ignore files that are no longer in use. Modified: llvm/trunk/utils/TableGen/ (props changed) Propchange: llvm/trunk/utils/TableGen/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Sun Nov 25 01:05:05 2007 @@ -1,7 +1,3 @@ Debug Release Release-Asserts -FileParser.output -FileLexer.cpp -FileParser.cpp -FileParser.h From rspencer at reidspencer.com Sun Nov 25 01:34:34 2007 From: rspencer at reidspencer.com (Reid Spencer) Date: Sun, 25 Nov 2007 07:34:34 -0000 Subject: [llvm-commits] [support] r44314 - in /support/trunk: ./ include/llvm/ADT/ include/llvm/Config/ include/llvm/Support/ Message-ID: <200711250734.lAP7YYqJ020160@zion.cs.uiuc.edu> Author: reid Date: Sun Nov 25 01:34:31 2007 New Revision: 44314 URL: http://llvm.org/viewvc/llvm-project?rev=44314&view=rev Log: Add svn:ignore properties appropriately. Modified: support/trunk/ (props changed) support/trunk/include/llvm/ADT/ (props changed) support/trunk/include/llvm/Config/ (props changed) support/trunk/include/llvm/Support/ (props changed) Propchange: support/trunk/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Nov 25 01:34:31 2007 @@ -0,0 +1,9 @@ +Makefile.config +config.log +config.cache +Debug +configure.out +config.status +mklib +Makefile.common +autom4te.cache Propchange: support/trunk/include/llvm/ADT/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Nov 25 01:34:31 2007 @@ -0,0 +1,3 @@ +hash_map +hash_set +iterator Propchange: support/trunk/include/llvm/Config/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Nov 25 01:34:31 2007 @@ -0,0 +1 @@ +config.h Propchange: support/trunk/include/llvm/Support/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Sun Nov 25 01:34:31 2007 @@ -0,0 +1 @@ +DataTypes.h From baldrick at free.fr Sun Nov 25 04:13:03 2007 From: baldrick at free.fr (Duncan Sands) Date: Sun, 25 Nov 2007 11:13:03 +0100 Subject: [llvm-commits] jit failures due to attributes changes In-Reply-To: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> References: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> Message-ID: <200711251113.03561.baldrick@free.fr> Hi Chris, > The problem here is that getOrInsertFunction is returning a bitcast of > the exit function (with the type above) to a void(int)* type. > > I think that getOrInsertFunction should just return the function (not > a bitcast) if the function type other than the attributes are the same. I think it would be wrong to ignore attributes altogether, since some attributes really change the function (by changing the calling convention for example). My plan is to have some helpers for determining when the differences between two sets of attributes are harmless. Ciao, Duncan. From baldrick at free.fr Sun Nov 25 06:48:08 2007 From: baldrick at free.fr (Duncan Sands) Date: Sun, 25 Nov 2007 13:48:08 +0100 Subject: [llvm-commits] jit failures due to attributes changes In-Reply-To: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> References: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> Message-ID: <200711251348.11270.baldrick@free.fr> Hi Chris, > I think that getOrInsertFunction should just return the function (not > a bitcast) if the function type other than the attributes are the same. once PR1146 is done, what should happen here? Suppose the new function and the old differ in some essential attribute (eg: byval). It won't be possible to bitcast the old function to the new function anymore because the attributes will no longer be part of the type... Ciao, Duncan. From baldrick at free.fr Sun Nov 25 08:10:57 2007 From: baldrick at free.fr (Duncan Sands) Date: Sun, 25 Nov 2007 14:10:57 -0000 Subject: [llvm-commits] [llvm] r44315 - in /llvm/trunk: include/llvm/ParameterAttributes.h lib/Transforms/Scalar/InstructionCombining.cpp lib/VMCore/Function.cpp lib/VMCore/Verifier.cpp test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll Message-ID: <200711251410.lAPEAvx9008956@zion.cs.uiuc.edu> Author: baldrick Date: Sun Nov 25 08:10:56 2007 New Revision: 44315 URL: http://llvm.org/viewvc/llvm-project?rev=44315&view=rev Log: Fix PR1816. If a bitcast of a function only exists because of a trivial difference in function attributes, allow calls to it to be converted to direct calls. Based on a patch by T?r?k Edwin. While there, move the various lists of mutually incompatible parameters etc out of the verifier and into ParameterAttributes.h. Added: llvm/trunk/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll Modified: llvm/trunk/include/llvm/ParameterAttributes.h llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/lib/VMCore/Function.cpp llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/include/llvm/ParameterAttributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ParameterAttributes.h?rev=44315&r1=44314&r2=44315&view=diff ============================================================================== --- llvm/trunk/include/llvm/ParameterAttributes.h (original) +++ llvm/trunk/include/llvm/ParameterAttributes.h Sun Nov 25 08:10:56 2007 @@ -43,6 +43,34 @@ ReadOnly = 1 << 10 ///< Function only reads from memory }; +/// These attributes can safely be dropped from a function or a function call: +/// doing so may reduce the number of optimizations performed, but it will not +/// change a correct program into an incorrect one. +/// @brief Attributes that do not change the calling convention. +const uint16_t Informative = NoReturn | NoUnwind | NoAlias | + ReadNone | ReadOnly; + +/// The following attribute sets are used by the verifier: + +/// @brief Attributes that only apply to function parameters. +const uint16_t ParameterOnly = ByVal | InReg | Nest | StructRet; + +/// @brief Attributes that only apply to function return values. +const uint16_t ReturnOnly = NoReturn | NoUnwind | ReadNone | ReadOnly; + +/// @brief Attributes that only apply to integers. +const uint16_t IntegerTypeOnly = SExt | ZExt; + +/// @brief Attributes that only apply to pointers. +const uint16_t PointerTypeOnly = ByVal | Nest | NoAlias | StructRet; + +/// @brief Attributes that are mutually incompatible. +const uint16_t MutuallyIncompatible[3] = { + ByVal | InReg | Nest | StructRet, + ZExt | SExt, + ReadNone | ReadOnly +}; + } /// This is just a pair of values to associate a set of parameter attributes @@ -110,6 +138,11 @@ /// @brief Get a ParamAttrsList instance. static ParamAttrsList *get(const ParamAttrsVector &attrVec); + /// Returns whether each of the specified lists of attributes can be safely + /// replaced with the other in a function or a function call. + /// @brief Whether one attribute list can safely replace the other. + static bool areCompatible(const ParamAttrsList *A, const ParamAttrsList *B); + /// @} /// @name Accessors /// @{ Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44315&r1=44314&r2=44315&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 25 08:10:56 2007 @@ -7990,11 +7990,12 @@ const FunctionType *ActualFT = cast(cast(CE->getType())->getElementType()); - // If the parameter attributes don't match up, don't do the xform. We don't - // want to lose an sret attribute or something. - if (FT->getParamAttrs() != ActualFT->getParamAttrs()) + // If the parameter attributes are not compatible, don't do the xform. We + // don't want to lose an sret attribute or something. + if (!ParamAttrsList::areCompatible(FT->getParamAttrs(), + ActualFT->getParamAttrs())) return false; - + // Check to see if we are changing the return type... if (OldRetTy != FT->getReturnType()) { if (Callee->isDeclaration() && !Caller->use_empty() && Modified: llvm/trunk/lib/VMCore/Function.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Function.cpp?rev=44315&r1=44314&r2=44315&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Function.cpp (original) +++ llvm/trunk/lib/VMCore/Function.cpp Sun Nov 25 08:10:56 2007 @@ -86,7 +86,6 @@ return ParamAttr::None; } - std::string ParamAttrsList::getParamAttrsText(uint16_t Attrs) { std::string Result; @@ -115,6 +114,50 @@ return Result; } +/// onlyInformative - Returns whether only informative attributes are set. +static inline bool onlyInformative(uint16_t attrs) { + return !(attrs & ~ParamAttr::Informative); +} + +bool +ParamAttrsList::areCompatible(const ParamAttrsList *A, const ParamAttrsList *B){ + if (A == B) + return true; + unsigned ASize = A ? A->size() : 0; + unsigned BSize = B ? B->size() : 0; + unsigned AIndex = 0; + unsigned BIndex = 0; + + while (AIndex < ASize && BIndex < BSize) { + uint16_t AIdx = A->getParamIndex(AIndex); + uint16_t BIdx = B->getParamIndex(BIndex); + uint16_t AAttrs = A->getParamAttrsAtIndex(AIndex); + uint16_t BAttrs = B->getParamAttrsAtIndex(AIndex); + + if (AIdx < BIdx) { + if (!onlyInformative(AAttrs)) + return false; + ++AIndex; + } else if (BIdx < AIdx) { + if (!onlyInformative(BAttrs)) + return false; + ++BIndex; + } else { + if (!onlyInformative(AAttrs ^ BAttrs)) + return false; + ++AIndex; + ++BIndex; + } + } + for (; AIndex < ASize; ++AIndex) + if (!onlyInformative(A->getParamAttrsAtIndex(AIndex))) + return false; + for (; BIndex < BSize; ++BIndex) + if (!onlyInformative(B->getParamAttrsAtIndex(AIndex))) + return false; + return true; +} + void ParamAttrsList::Profile(FoldingSetNodeID &ID) const { for (unsigned i = 0; i < attrs.size(); ++i) { Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=44315&r1=44314&r2=44315&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sun Nov 25 08:10:56 2007 @@ -393,30 +393,6 @@ Assert1(!FT->isStructReturn() || FT->getReturnType() == Type::VoidTy, "Invalid struct-return function!", &F); - const uint16_t ReturnIncompatible = - ParamAttr::ByVal | ParamAttr::InReg | - ParamAttr::Nest | ParamAttr::StructRet; - - const uint16_t ParameterIncompatible = - ParamAttr::NoReturn | ParamAttr::NoUnwind | - ParamAttr::ReadNone | ParamAttr::ReadOnly; - - const uint16_t MutuallyIncompatible[3] = { - ParamAttr::ByVal | ParamAttr::InReg | - ParamAttr::Nest | ParamAttr::StructRet, - - ParamAttr::ZExt | ParamAttr::SExt, - - ParamAttr::ReadNone | ParamAttr::ReadOnly - }; - - const uint16_t IntegerTypeOnly = - ParamAttr::SExt | ParamAttr::ZExt; - - const uint16_t PointerTypeOnly = - ParamAttr::ByVal | ParamAttr::Nest | - ParamAttr::NoAlias | ParamAttr::StructRet; - bool SawSRet = false; if (const ParamAttrsList *Attrs = FT->getParamAttrs()) { @@ -426,28 +402,29 @@ uint16_t Attr = Attrs->getParamAttrs(Idx); if (!Idx) { - uint16_t RetI = Attr & ReturnIncompatible; + uint16_t RetI = Attr & ParamAttr::ParameterOnly; Assert1(!RetI, "Attribute " + Attrs->getParamAttrsText(RetI) + "should not apply to functions!", &F); } else { - uint16_t ParmI = Attr & ParameterIncompatible; + uint16_t ParmI = Attr & ParamAttr::ReturnOnly; Assert1(!ParmI, "Attribute " + Attrs->getParamAttrsText(ParmI) + "should only be applied to function!", &F); } - for (unsigned i = 0; i < array_lengthof(MutuallyIncompatible); ++i) { - uint16_t MutI = Attr & MutuallyIncompatible[i]; + for (unsigned i = 0; + i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { + uint16_t MutI = Attr & ParamAttr::MutuallyIncompatible[i]; Assert1(!(MutI & (MutI - 1)), "Attributes " + Attrs->getParamAttrsText(MutI) + "are incompatible!", &F); } - uint16_t IType = Attr & IntegerTypeOnly; + uint16_t IType = Attr & ParamAttr::IntegerTypeOnly; Assert1(!IType || FT->getParamType(Idx-1)->isInteger(), "Attribute " + Attrs->getParamAttrsText(IType) + "should only apply to Integer type!", &F); - uint16_t PType = Attr & PointerTypeOnly; + uint16_t PType = Attr & ParamAttr::PointerTypeOnly; Assert1(!PType || isa(FT->getParamType(Idx-1)), "Attribute " + Attrs->getParamAttrsText(PType) + "should only apply to Pointer type!", &F); Added: llvm/trunk/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll?rev=44315&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2007-11-25-CompatibleAttributes.ll Sun Nov 25 08:10:56 2007 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep bitcast +; PR1716 + + at .str = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +define i32 @main(i32 %argc, i8** %argv) { +entry: + %tmp32 = tail call i32 (i8* noalias , ...) nounwind * bitcast (i32 (i8*, ...) nounwind * @printf to i32 (i8* noalias , ...) nounwind *)( i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0) noalias , i32 0 ) nounwind ; [#uses=0] + ret i32 undef +} + +declare i32 @printf(i8*, ...) nounwind From clattner at apple.com Sun Nov 25 11:28:34 2007 From: clattner at apple.com (Chris Lattner) Date: Sun, 25 Nov 2007 09:28:34 -0800 Subject: [llvm-commits] jit failures due to attributes changes In-Reply-To: <200711251348.11270.baldrick@free.fr> References: <858C155F-5A85-4A3A-8870-7E931CC99AD6@apple.com> <200711251348.11270.baldrick@free.fr> Message-ID: <8000159D-081C-476D-9E28-9FCCA6198F1E@apple.com> On Nov 25, 2007, at 4:48 AM, Duncan Sands wrote: >> I think that getOrInsertFunction should just return the function (not >> a bitcast) if the function type other than the attributes are the >> same. > > once PR1146 is done, what should happen here? Suppose the new > function > and the old differ in some essential attribute (eg: byval). It won't > be possible to bitcast the old function to the new function anymore > because the attributes will no longer be part of the type... I think everything will be fine. Consider what happens today: If you use getOrInsertFunction(..) then make a call to it, one of two things happen: 1. the callee doesn't exist or does and matches your expectation. Everything is cool. 2. The callee exists and doesn't match your expectation (e.g. takes too many, two few, or wrong arguments). In this case, we return a bitcast of the function so that the callee can create the call without aborting, but the generated code is quite likely to not work right. I think that mismatched/unexpected attributes are just another case of #2. In practice however, getOrInsertFunction is only used for very simple "c" functions, so I don't think that byval etc will come up very often. -Chris From asl at math.spbu.ru Sun Nov 25 12:41:39 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 25 Nov 2007 18:41:39 -0000 Subject: [llvm-commits] [llvm] r44317 - /llvm/trunk/include/llvm/Analysis/LoopInfo.h Message-ID: <200711251841.lAPIfdLn026424@zion.cs.uiuc.edu> Author: asl Date: Sun Nov 25 12:41:39 2007 New Revision: 44317 URL: http://llvm.org/viewvc/llvm-project?rev=44317&view=rev Log: Remove a leak. Destroy LoopInfoBase object. releaseMemory() is actually called in its dtor. Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LoopInfo.h?rev=44317&r1=44316&r2=44317&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Sun Nov 25 12:41:39 2007 @@ -834,7 +834,7 @@ LI = new LoopInfoBase(); } - ~LoopInfo() { LI->releaseMemory(); } + ~LoopInfo() { delete LI; } /// iterator/begin/end - The interface to the top-level loops in the current /// function. From sabre at nondot.org Sun Nov 25 15:27:54 2007 From: sabre at nondot.org (Chris Lattner) Date: Sun, 25 Nov 2007 21:27:54 -0000 Subject: [llvm-commits] [llvm] r44318 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/select.ll Message-ID: <200711252127.lAPLRsgw003623@zion.cs.uiuc.edu> Author: lattner Date: Sun Nov 25 15:27:53 2007 New Revision: 44318 URL: http://llvm.org/viewvc/llvm-project?rev=44318&view=rev Log: Implement PR1822 Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp llvm/trunk/test/Transforms/InstCombine/select.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=44318&r1=44317&r2=44318&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Nov 25 15:27:53 2007 @@ -7326,6 +7326,13 @@ return BinaryOperator::createOr(NotCond, TrueVal); } } + + // select a, b, a -> a&b + // select a, a, b -> a|b + if (CondVal == TrueVal) + return BinaryOperator::createOr(CondVal, FalseVal); + else if (CondVal == FalseVal) + return BinaryOperator::createAnd(CondVal, TrueVal); } // Selecting between two integer constants? Modified: llvm/trunk/test/Transforms/InstCombine/select.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=44318&r1=44317&r2=44318&view=diff ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/select.ll (original) +++ llvm/trunk/test/Transforms/InstCombine/select.ll Sun Nov 25 15:27:53 2007 @@ -1,8 +1,7 @@ ; This test makes sure that these instructions are properly eliminated. +; PR1822 -; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | \ -; RUN: not grep select -; END. +; RUN: llvm-upgrade < %s | llvm-as | opt -instcombine | llvm-dis | not grep select implementation @@ -180,3 +179,12 @@ ret short %retval } +bool %test23(bool %a, bool %b) { + %c = select bool %a, bool %b, bool %a + ret bool %c +} + +bool %test24(bool %a, bool %b) { + %c = select bool %a, bool %a, bool %b + ret bool %c +} From nicholas at mxc.ca Sun Nov 25 16:41:32 2007 From: nicholas at mxc.ca (Nick Lewycky) Date: Sun, 25 Nov 2007 22:41:32 -0000 Subject: [llvm-commits] [llvm] r44319 - in /llvm/trunk: include/llvm/Analysis/ScalarEvolution.h include/llvm/Analysis/ScalarEvolutionExpander.h include/llvm/Analysis/ScalarEvolutionExpressions.h lib/Analysis/ScalarEvolution.cpp lib/Analysis/ScalarEvolutionExpander.cpp test/Analysis/ScalarEvolution/do-loop.ll test/Analysis/ScalarEvolution/smax.ll test/Transforms/IndVarsSimplify/loop_evaluate_2.ll Message-ID: <200711252241.lAPMfXBk008446@zion.cs.uiuc.edu> Author: nicholas Date: Sun Nov 25 16:41:31 2007 New Revision: 44319 URL: http://llvm.org/viewvc/llvm-project?rev=44319&view=rev Log: Add new SCEV, SCEVSMax. This allows LLVM to analyze do-while loops. Added: llvm/trunk/test/Analysis/ScalarEvolution/do-loop.ll llvm/trunk/test/Analysis/ScalarEvolution/smax.ll Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h llvm/trunk/lib/Analysis/ScalarEvolution.cpp llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp llvm/trunk/test/Transforms/IndVarsSimplify/loop_evaluate_2.ll Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Sun Nov 25 16:41:31 2007 @@ -235,6 +235,8 @@ std::vector NewOp(Operands); return getAddRecExpr(NewOp, L); } + SCEVHandle getSMaxExpr(const SCEVHandle &LHS, const SCEVHandle &RHS); + SCEVHandle getSMaxExpr(std::vector Operands); SCEVHandle getUnknown(Value *V); /// getNegativeSCEV - Return the SCEV object corresponding to -V. Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Sun Nov 25 16:41:31 2007 @@ -134,6 +134,8 @@ Value *visitAddRecExpr(SCEVAddRecExpr *S); + Value *visitSMaxExpr(SCEVSMaxExpr *S); + Value *visitUnknown(SCEVUnknown *S) { return S->getValue(); } Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Sun Nov 25 16:41:31 2007 @@ -25,7 +25,7 @@ // These should be ordered in terms of increasing complexity to make the // folders simpler. scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr, - scSDivExpr, scAddRecExpr, scUnknown, scCouldNotCompute + scSDivExpr, scAddRecExpr, scSMaxExpr, scUnknown, scCouldNotCompute }; //===--------------------------------------------------------------------===// @@ -274,7 +274,8 @@ static inline bool classof(const SCEVCommutativeExpr *S) { return true; } static inline bool classof(const SCEV *S) { return S->getSCEVType() == scAddExpr || - S->getSCEVType() == scMulExpr; + S->getSCEVType() == scMulExpr || + S->getSCEVType() == scSMaxExpr; } }; @@ -459,6 +460,28 @@ } }; + + //===--------------------------------------------------------------------===// + /// SCEVSMaxExpr - This class represents a signed maximum selection. + /// + class SCEVSMaxExpr : public SCEVCommutativeExpr { + friend class ScalarEvolution; + + explicit SCEVSMaxExpr(const std::vector &ops) + : SCEVCommutativeExpr(scSMaxExpr, ops) { + } + + public: + virtual const char *getOperationStr() const { return " smax "; } + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SCEVSMaxExpr *S) { return true; } + static inline bool classof(const SCEV *S) { + return S->getSCEVType() == scSMaxExpr; + } + }; + + //===--------------------------------------------------------------------===// /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV /// value, and only represent it as it's LLVM Value. This is the "bottom" @@ -521,6 +544,8 @@ return ((SC*)this)->visitSDivExpr((SCEVSDivExpr*)S); case scAddRecExpr: return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S); + case scSMaxExpr: + return ((SC*)this)->visitSMaxExpr((SCEVSMaxExpr*)S); case scUnknown: return ((SC*)this)->visitUnknown((SCEVUnknown*)S); case scCouldNotCompute: Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Sun Nov 25 16:41:31 2007 @@ -318,6 +318,8 @@ return SE.getAddExpr(NewOps); else if (isa(this)) return SE.getMulExpr(NewOps); + else if (isa(this)) + return SE.getSMaxExpr(NewOps); else assert(0 && "Unknown commutative expr!"); } @@ -1095,6 +1097,93 @@ return Result; } +SCEVHandle ScalarEvolution::getSMaxExpr(const SCEVHandle &LHS, + const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return getSMaxExpr(Ops); +} + +SCEVHandle ScalarEvolution::getSMaxExpr(std::vector Ops) { + assert(!Ops.empty() && "Cannot get empty smax!"); + if (Ops.size() == 1) return Ops[0]; + + // Sort by complexity, this groups all similar expression types together. + GroupByComplexity(Ops); + + // If there are any constants, fold them together. + unsigned Idx = 0; + if (SCEVConstant *LHSC = dyn_cast(Ops[0])) { + ++Idx; + assert(Idx < Ops.size()); + while (SCEVConstant *RHSC = dyn_cast(Ops[Idx])) { + // We found two constants, fold them together! + Constant *Fold = ConstantInt::get( + APIntOps::smax(LHSC->getValue()->getValue(), + RHSC->getValue()->getValue())); + if (ConstantInt *CI = dyn_cast(Fold)) { + Ops[0] = getConstant(CI); + Ops.erase(Ops.begin()+1); // Erase the folded element + if (Ops.size() == 1) return Ops[0]; + LHSC = cast(Ops[0]); + } else { + // If we couldn't fold the expression, move to the next constant. Note + // that this is impossible to happen in practice because we always + // constant fold constant ints to constant ints. + ++Idx; + } + } + + // If we are left with a constant -inf, strip it off. + if (cast(Ops[0])->getValue()->isMinValue(true)) { + Ops.erase(Ops.begin()); + --Idx; + } + } + + if (Ops.size() == 1) return Ops[0]; + + // Find the first SMax + while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scSMaxExpr) + ++Idx; + + // Check to see if one of the operands is an SMax. If so, expand its operands + // onto our operand list, and recurse to simplify. + if (Idx < Ops.size()) { + bool DeletedSMax = false; + while (SCEVSMaxExpr *SMax = dyn_cast(Ops[Idx])) { + Ops.insert(Ops.end(), SMax->op_begin(), SMax->op_end()); + Ops.erase(Ops.begin()+Idx); + DeletedSMax = true; + } + + if (DeletedSMax) + return getSMaxExpr(Ops); + } + + // Okay, check to see if the same value occurs in the operand list twice. If + // so, delete one. Since we sorted the list, these values are required to + // be adjacent. + for (unsigned i = 0, e = Ops.size()-1; i != e; ++i) + if (Ops[i] == Ops[i+1]) { // X smax Y smax Y --> X smax Y + Ops.erase(Ops.begin()+i, Ops.begin()+i+1); + --i; --e; + } + + if (Ops.size() == 1) return Ops[0]; + + assert(!Ops.empty() && "Reduced smax down to nothing!"); + + // Okay, it looks like we really DO need an add expr. Check to see if we + // already have one, otherwise create a new one. + std::vector SCEVOps(Ops.begin(), Ops.end()); + SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scSMaxExpr, + SCEVOps)]; + if (Result == 0) Result = new SCEVSMaxExpr(Ops); + return Result; +} + SCEVHandle ScalarEvolution::getUnknown(Value *V) { if (ConstantInt *CI = dyn_cast(V)) return getConstant(CI); @@ -1458,6 +1547,14 @@ return MinOpRes; } + if (SCEVSMaxExpr *M = dyn_cast(S)) { + // The result is the min of all operands results. + uint32_t MinOpRes = GetMinTrailingZeros(M->getOperand(0)); + for (unsigned i = 1, e = M->getNumOperands(); MinOpRes && i != e; ++i) + MinOpRes = std::min(MinOpRes, GetMinTrailingZeros(M->getOperand(i))); + return MinOpRes; + } + // SCEVSDivExpr, SCEVUnknown return 0; } @@ -1537,6 +1634,25 @@ case Instruction::PHI: return createNodeForPHI(cast(I)); + case Instruction::Select: + // This could be an SCEVSMax that was lowered earlier. Try to recover it. + if (ICmpInst *ICI = dyn_cast(I->getOperand(0))) { + Value *LHS = ICI->getOperand(0); + Value *RHS = ICI->getOperand(1); + switch (ICI->getPredicate()) { + case ICmpInst::ICMP_SLT: + case ICmpInst::ICMP_SLE: + std::swap(LHS, RHS); + // fall through + case ICmpInst::ICMP_SGT: + case ICmpInst::ICMP_SGE: + if (LHS == I->getOperand(1) && RHS == I->getOperand(2)) + return SE.getSMaxExpr(getSCEV(LHS), getSCEV(RHS)); + default: + break; + } + } + default: // We cannot analyze this expression. break; } @@ -2125,8 +2241,11 @@ } if (isa(Comm)) return SE.getAddExpr(NewOps); - assert(isa(Comm) && "Only know about add and mul!"); - return SE.getMulExpr(NewOps); + if (isa(Comm)) + return SE.getMulExpr(NewOps); + if (isa(Comm)) + return SE.getSMaxExpr(NewOps); + assert(0 && "Unknown commutative SCEV type!"); } } // If we got here, all operands are loop invariant. @@ -2343,90 +2462,21 @@ return UnknownValue; if (AddRec->isAffine()) { + // The number of iterations for "{n,+,1} < m", is m-n. However, we don't + // know that m is >= n on input to the loop. If it is, the condition + // returns true zero times. To handle both cases, we return SMAX(0, m-n). + // FORNOW: We only support unit strides. - SCEVHandle Zero = SE.getIntegerSCEV(0, RHS->getType()); SCEVHandle One = SE.getIntegerSCEV(1, RHS->getType()); if (AddRec->getOperand(1) != One) return UnknownValue; - // The number of iterations for "{n,+,1} < m", is m-n. However, we don't - // know that m is >= n on input to the loop. If it is, the condition return - // true zero times. What we really should return, for full generality, is - // SMAX(0, m-n). Since we cannot check this, we will instead check for a - // canonical loop form: most do-loops will have a check that dominates the - // loop, that only enters the loop if (n-1)= n. - - // Search for the check. - BasicBlock *Preheader = L->getLoopPreheader(); - BasicBlock *PreheaderDest = L->getHeader(); - if (Preheader == 0) return UnknownValue; - - BranchInst *LoopEntryPredicate = - dyn_cast(Preheader->getTerminator()); - if (!LoopEntryPredicate) return UnknownValue; - - // This might be a critical edge broken out. If the loop preheader ends in - // an unconditional branch to the loop, check to see if the preheader has a - // single predecessor, and if so, look for its terminator. - while (LoopEntryPredicate->isUnconditional()) { - PreheaderDest = Preheader; - Preheader = Preheader->getSinglePredecessor(); - if (!Preheader) return UnknownValue; // Multiple preds. - - LoopEntryPredicate = - dyn_cast(Preheader->getTerminator()); - if (!LoopEntryPredicate) return UnknownValue; - } - - // Now that we found a conditional branch that dominates the loop, check to - // see if it is the comparison we are looking for. - if (ICmpInst *ICI = dyn_cast(LoopEntryPredicate->getCondition())){ - Value *PreCondLHS = ICI->getOperand(0); - Value *PreCondRHS = ICI->getOperand(1); - ICmpInst::Predicate Cond; - if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest) - Cond = ICI->getPredicate(); - else - Cond = ICI->getInversePredicate(); - - switch (Cond) { - case ICmpInst::ICMP_UGT: - if (isSigned) return UnknownValue; - std::swap(PreCondLHS, PreCondRHS); - Cond = ICmpInst::ICMP_ULT; - break; - case ICmpInst::ICMP_SGT: - if (!isSigned) return UnknownValue; - std::swap(PreCondLHS, PreCondRHS); - Cond = ICmpInst::ICMP_SLT; - break; - case ICmpInst::ICMP_ULT: - if (isSigned) return UnknownValue; - break; - case ICmpInst::ICMP_SLT: - if (!isSigned) return UnknownValue; - break; - default: - return UnknownValue; - } - - if (PreCondLHS->getType()->isInteger()) { - if (RHS != getSCEV(PreCondRHS)) - return UnknownValue; // Not a comparison against 'm'. + SCEVHandle Iters = SE.getMinusSCEV(RHS, AddRec->getOperand(0)); - if (SE.getMinusSCEV(AddRec->getOperand(0), One) - != getSCEV(PreCondLHS)) - return UnknownValue; // Not a comparison against 'n-1'. - } - else return UnknownValue; - - // cerr << "Computed Loop Trip Count as: " - // << // *SE.getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n"; - return SE.getMinusSCEV(RHS, AddRec->getOperand(0)); - } - else - return UnknownValue; + if (isSigned) + return SE.getSMaxExpr(SE.getIntegerSCEV(0, RHS->getType()), Iters); + else + return Iters; } return UnknownValue; Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Sun Nov 25 16:41:31 2007 @@ -208,6 +208,16 @@ return expand(V); } +Value *SCEVExpander::visitSMaxExpr(SCEVSMaxExpr *S) { + Value *LHS = expand(S->getOperand(0)); + for (unsigned i = 1; i < S->getNumOperands(); ++i) { + Value *RHS = expand(S->getOperand(i)); + Value *ICmp = new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, "tmp", InsertPt); + LHS = new SelectInst(ICmp, LHS, RHS, "smax", InsertPt); + } + return LHS; +} + Value *SCEVExpander::expand(SCEV *S) { // Check to see if we already expanded this. std::map::iterator I = InsertedExpressions.find(S); Added: llvm/trunk/test/Analysis/ScalarEvolution/do-loop.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/do-loop.ll?rev=44319&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/do-loop.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/do-loop.ll Sun Nov 25 16:41:31 2007 @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution | grep smax +; PR1614 + +define i32 @f(i32 %x, i32 %y) { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=2] + %x_addr.0 = add i32 %indvar, %x ; [#uses=1] + %tmp2 = add i32 %x_addr.0, 1 ; [#uses=2] + %tmp5 = icmp slt i32 %tmp2, %y ; [#uses=1] + %indvar.next = add i32 %indvar, 1 ; [#uses=1] + br i1 %tmp5, label %bb, label %bb7 + +bb7: ; preds = %bb + ret i32 %tmp2 +} Added: llvm/trunk/test/Analysis/ScalarEvolution/smax.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ScalarEvolution/smax.ll?rev=44319&view=auto ============================================================================== --- llvm/trunk/test/Analysis/ScalarEvolution/smax.ll (added) +++ llvm/trunk/test/Analysis/ScalarEvolution/smax.ll Sun Nov 25 16:41:31 2007 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -analyze -scalar-evolution | grep smax | count 2 +; RUN: llvm-as < %s | opt -analyze -scalar-evolution | grep \ +; RUN: "%. smax %. smax %." +; PR1614 + +define i32 @x(i32 %a, i32 %b, i32 %c) { + %A = icmp sgt i32 %a, %b + %B = select i1 %A, i32 %a, i32 %b + %C = icmp sle i32 %c, %B + %D = select i1 %C, i32 %B, i32 %c + ret i32 %D +} Modified: llvm/trunk/test/Transforms/IndVarsSimplify/loop_evaluate_2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarsSimplify/loop_evaluate_2.ll?rev=44319&r1=44318&r2=44319&view=diff ============================================================================== --- llvm/trunk/test/Transforms/IndVarsSimplify/loop_evaluate_2.ll (original) +++ llvm/trunk/test/Transforms/IndVarsSimplify/loop_evaluate_2.ll Sun Nov 25 16:41:31 2007 @@ -1,5 +1,5 @@ -; RUN: llvm-as < %s | opt -indvars -adce -simplifycfg | llvm-dis | grep select -; RUN: llvm-as < %s | opt -indvars -adce -simplifycfg | llvm-dis | not grep br +; RUN: llvm-as < %s | opt -indvars -adce -simplifycfg | opt \ +; RUN: -analyze -loops | not grep "^Loop Containing" ; PR1179 define i32 @ltst(i32 %x) { From asl at math.spbu.ru Sun Nov 25 17:52:03 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 25 Nov 2007 23:52:03 -0000 Subject: [llvm-commits] [llvm] r44320 - in /llvm/trunk: include/llvm/Analysis/AliasSetTracker.h lib/Transforms/Scalar/LICM.cpp Message-ID: <200711252352.lAPNq3Nk012906@zion.cs.uiuc.edu> Author: asl Date: Sun Nov 25 17:52:02 2007 New Revision: 44320 URL: http://llvm.org/viewvc/llvm-project?rev=44320&view=rev Log: Remove another leak. Due to some reason AliasSetTracker didn't had any dtor... Modified: llvm/trunk/include/llvm/Analysis/AliasSetTracker.h llvm/trunk/lib/Transforms/Scalar/LICM.cpp Modified: llvm/trunk/include/llvm/Analysis/AliasSetTracker.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasSetTracker.h?rev=44320&r1=44319&r2=44320&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/AliasSetTracker.h (original) +++ llvm/trunk/include/llvm/Analysis/AliasSetTracker.h Sun Nov 25 17:52:02 2007 @@ -263,6 +263,7 @@ /// the specified alias analysis object to disambiguate load and store /// addresses. explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {} + ~AliasSetTracker() { clear(); } /// add methods - These methods are used to add different types of /// instructions to the alias sets. Adding a new instruction can result in Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=44320&r1=44319&r2=44320&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Sun Nov 25 17:52:02 2007 @@ -84,6 +84,11 @@ } bool doFinalization() { + // Free the values stored in the map + for (std::map::iterator + I = LoopToAliasMap.begin(), E = LoopToAliasMap.end(); I != E; ++I) + delete I->second; + LoopToAliasMap.clear(); return false; } From resistor at mac.com Sun Nov 25 20:26:36 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 26 Nov 2007 02:26:36 -0000 Subject: [llvm-commits] [llvm] r44323 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp lib/Transforms/Scalar/GVN.cpp test/Analysis/BasicAA/pure-const-dce.ll Message-ID: <200711260226.lAQ2QarY023713@zion.cs.uiuc.edu> Author: resistor Date: Sun Nov 25 20:26:36 2007 New Revision: 44323 URL: http://llvm.org/viewvc/llvm-project?rev=44323&view=rev Log: Allow GVN to eliminate read-only function calls when it can detect that they are redundant. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp llvm/trunk/lib/Transforms/Scalar/GVN.cpp llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=44323&r1=44322&r2=44323&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Nov 25 20:26:36 2007 @@ -79,9 +79,6 @@ if (StoreInst* S = dyn_cast(QI)) { pointer = S->getPointerOperand(); pointerSize = TD.getTypeStoreSize(S->getOperand(0)->getType()); - } else if (LoadInst* L = dyn_cast(QI)) { - pointer = L->getPointerOperand(); - pointerSize = TD.getTypeStoreSize(L->getType()); } else if (AllocationInst* AI = dyn_cast(QI)) { pointer = AI; if (ConstantInt* C = dyn_cast(AI->getArraySize())) @@ -98,7 +95,11 @@ // FreeInsts erase the entire structure pointerSize = ~0UL; } else if (CallSite::get(QI).getInstruction() != 0) { - if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) { + AliasAnalysis::ModRefBehavior result = + AA.getModRefBehavior(cast(QI)->getCalledFunction(), + CallSite::get(QI)); + if (result != AliasAnalysis::DoesNotAccessMemory && + result != AliasAnalysis::OnlyReadsMemory) { if (!start && !block) { depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true))); Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=44323&r1=44322&r2=44323&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Sun Nov 25 20:26:36 2007 @@ -476,7 +476,8 @@ if (CallInst* C = dyn_cast(V)) { if (C->getCalledFunction() && - AA->doesNotAccessMemory(C->getCalledFunction())) { + (AA->doesNotAccessMemory(C->getCalledFunction()) || + AA->onlyReadsMemory(C->getCalledFunction()))) { Expression e = create_expression(C); DenseMap::iterator EI = expressionNumbering.find(e); @@ -1038,6 +1039,22 @@ } else if (currAvail.test(num)) { Value* repl = find_leader(currAvail, num); + if (CallInst* CI = dyn_cast(I)) { + AliasAnalysis& AA = getAnalysis(); + if (CI->getCalledFunction() && + !AA.doesNotAccessMemory(CI->getCalledFunction())) { + MemoryDependenceAnalysis& MD = getAnalysis(); + if (MD.getDependency(CI) != MD.getDependency(cast(repl))) { + // There must be an intervening may-alias store, so nothing from + // this point on will be able to be replaced with the preceding call + currAvail.erase(repl); + currAvail.insert(I); + + return false; + } + } + } + VN.erase(I); I->replaceAllUsesWith(repl); toErase.push_back(I); Modified: llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll?rev=44323&r1=44322&r2=44323&view=diff ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll (original) +++ llvm/trunk/test/Analysis/BasicAA/pure-const-dce.ll Sun Nov 25 20:26:36 2007 @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestConst | count 2 -; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure | not count 2 +; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestPure | count 3 ; RUN: llvm-as < %s | opt -basicaa -gvn | llvm-dis | grep TestNone | count 4 @g = global i32 0 ; [#uses=1] From resistor at mac.com Sun Nov 25 21:27:39 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 26 Nov 2007 03:27:39 -0000 Subject: [llvm-commits] [llvm] r44324 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Message-ID: <200711260327.lAQ3RdVc029239@zion.cs.uiuc.edu> Author: resistor Date: Sun Nov 25 21:27:38 2007 New Revision: 44324 URL: http://llvm.org/viewvc/llvm-project?rev=44324&view=rev Log: Fix a silly bug that Nicholas noticed. Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=44324&r1=44323&r2=44324&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sun Nov 25 21:27:38 2007 @@ -94,7 +94,8 @@ // FreeInsts erase the entire structure pointerSize = ~0UL; - } else if (CallSite::get(QI).getInstruction() != 0) { + } else if (CallSite::get(QI).getInstruction() != 0 && + cast(QI)->getCalledFunction()) { AliasAnalysis::ModRefBehavior result = AA.getModRefBehavior(cast(QI)->getCalledFunction(), CallSite::get(QI));