From isanbard at gmail.com Mon Oct 22 00:10:06 2007 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 22 Oct 2007 05:10:06 -0000 Subject: [llvm-commits] [llvm] r43216 - /llvm/trunk/docs/LangRef.html Message-ID: <200710220510.l9M5A6Sk001918@zion.cs.uiuc.edu> Author: void Date: Mon Oct 22 00:10:05 2007 New Revision: 43216 URL: http://llvm.org/viewvc/llvm-project?rev=43216&view=rev Log: Put correct link in example Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=43216&r1=43215&r2=43216&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Oct 22 00:10:05 2007 @@ -2788,9 +2788,8 @@ at the location specified by the '<pointer>' operand.

Example:
  %ptr = alloca i32                               ; yields {i32*}:ptr
-  store i32 3, i32* %ptr                          ; yields {void}
-  %val = load i32* %ptr                           ; yields {i32}:val = i32 3
+  store i32 3, i32* %ptr                          ; yields {void}
+  %val = load i32* %ptr                           ; yields {i32}:val = i32 3
 
From resistor at mac.com Mon Oct 22 01:29:31 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 22 Oct 2007 06:29:31 -0000 Subject: [llvm-commits] [llvm] r43217 - /llvm/trunk/docs/tutorial/JITTutorial1.html Message-ID: <200710220629.l9M6TVkl006218@zion.cs.uiuc.edu> Author: resistor Date: Mon Oct 22 01:29:31 2007 New Revision: 43217 URL: http://llvm.org/viewvc/llvm-project?rev=43217&view=rev Log: Fix some code to make it actually work. Modified: llvm/trunk/docs/tutorial/JITTutorial1.html Modified: llvm/trunk/docs/tutorial/JITTutorial1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial1.html?rev=43217&r1=43216&r2=43217&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial1.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial1.html Mon Oct 22 01:29:31 2007 @@ -90,11 +90,12 @@
-  Constant* c->getOrInsertFunction("mul_add",
-  /*ret type*/                     IntegerType::get(32),
-  /*args*/                         IntegerType::get(32),
-                                   IntegerType::get(32),
-                                   IntegerType::get(32));
+  Constant* c = mod->getOrInsertFunction("mul_add",
+  /*ret type*/                           IntegerType::get(32),
+  /*args*/                               IntegerType::get(32),
+                                         IntegerType::get(32),
+                                         IntegerType::get(32),
+  /*varargs terminated with null*/       NULL);
   
   Function* mul_add = cast<Function>(c);
   mul_add->setCallingConv(CallingConv::C);
@@ -140,6 +141,8 @@
                                     tmp, z, "tmp2");
 
   builder.CreateRet(tmp2);
+  
+  return mod;
 }
 
From sabre at nondot.org Mon Oct 22 01:34:16 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 22 Oct 2007 06:34:16 -0000 Subject: [llvm-commits] [llvm] r43218 - in /llvm/trunk/docs/tutorial: LangImpl1.html LangImpl2.html index.html Message-ID: <200710220634.l9M6YGo6006511@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 01:34:15 2007 New Revision: 43218 URL: http://llvm.org/viewvc/llvm-project?rev=43218&view=rev Log: Check in part 2: parser and ast. Added: llvm/trunk/docs/tutorial/LangImpl2.html Modified: llvm/trunk/docs/tutorial/LangImpl1.html llvm/trunk/docs/tutorial/index.html Modified: llvm/trunk/docs/tutorial/LangImpl1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl1.html?rev=43218&r1=43217&r2=43218&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl1.html (original) +++ llvm/trunk/docs/tutorial/LangImpl1.html Mon Oct 22 01:34:15 2007 @@ -56,7 +56,7 @@
 # Compute the x'th fibonacci number.
 def fib(x)
-  if x < 3 then
+  if x < 3 then
     1
   else
     fib(x-1)+fib(x-2)
@@ -241,8 +241,8 @@
 
 

With this, we have the complete lexer for the basic Kaleidoscope language. Next we'll build a simple parser that uses this to -build an Abstract Syntax Tree. If you prefer, you can jump to the main tutorial index page. +build an Abstract Syntax Tree. When we have that, we'll include a driver +so that you can use the lexer and parser together.

Added: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43218&view=auto ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (added) +++ llvm/trunk/docs/tutorial/LangImpl2.html Mon Oct 22 01:34:15 2007 @@ -0,0 +1,1177 @@ + + + + + Kaleidoscope: Implementing a Parser and AST + + + + + + + +
Kaleidoscope: Implementing a Parser and AST
+ +
+

Written by Chris Lattner

+
+ + +
Part 2 Introduction
+ + +
+ +

Welcome to part 2 of the "Implementing a language with +LLVM" tutorial. This chapter shows you how to use the Lexer built in Chapter 1 to build a full parser for +our Kaleidoscope language and build an Abstract Syntax +Tree (AST).

+ +

The parser we will build uses a combination of Recursive Descent +Parsing and Operator-Precedence +Parsing to parse the Kaleidoscope language (the later for binary expression +and the former for everything else). Before we get to parsing though, lets talk +about the output of the parser: the Abstract Syntax Tree.

+ +
+ + +
The Abstract Syntax Tree (AST)
+ + +
+ +

The AST for a program captures its behavior in a way that it is easy for +later stages of the compiler (e.g. code generation) to interpret. We basically +want one object for each construct in the language, and the AST should closely +model the language. In Kaleidoscope, we have expressions, a prototype, and a +function object. We'll start with expressions first:

+ +
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+  virtual ~ExprAST() {}
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+  double Val;
+public:
+  NumberExprAST(double val) : Val(val) {}
+};
+
+
+ +

The code above shows the definition of the base ExprAST class and one +subclass which we use for numeric literals. The important thing about this is +that the NumberExprAST class captures the numeric value of the literal in the +class, so that later phases of the compiler can know what it is.

+ +

Right now we only create the AST, so there are no useful accessor methods on +them. It would be very easy to add a virtual method to pretty print the code, +for example. Here are the other expression AST node definitions that we'll use +in the basic form of the Kaleidoscope language. +

+ +
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+  std::string Name;
+public:
+  VariableExprAST(const std::string &name) : Name(name) {}
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+  char Op;
+  ExprAST *LHS, *RHS;
+public:
+  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 
+    : Op(op), LHS(lhs), RHS(rhs) {}
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+  std::string Callee;
+  std::vector<ExprAST*> Args;
+public:
+  CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
+    : Callee(callee), Args(args) {}
+};
+
+
+ +

This is all (intentially) rather straight-forward: variables capture the +variable name, binary operators capture their opcode (e.g. '+'), and calls +capture a function name and list of argument expressions. One thing that is +nice about our AST is that it captures the language features without talking +about the syntax of the language. Note that there is no discussion about +precedence of binary operators, lexical structure etc.

+ +

For our basic language, these are all of the expression nodes we'll define. +because it doesn't have conditional control flow, it isn't turing complete: +we'll fix that in a later installment. The two things we need next are a way +to talk about the interface to a function, and a way to talk about functions +themselves:

+ +
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its argument names as well as if it is an operator.
+class PrototypeAST {
+  std::string Name;
+  std::vector<std::string> Args;
+public:
+  PrototypeAST(const std::string &name, const std::vector<std::string> &args)
+    : Name(name), Args(args) {}
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+  PrototypeAST *Proto;
+  ExprAST *Body;
+public:
+  FunctionAST(PrototypeAST *proto, ExprAST *body)
+    : Proto(proto), Body(body) {}
+};
+
+
+ +

In Kaleidoscope, functions are typed with just a count of their arguments. +Since all values are double precision floating point, this fact doesn't need to +be captured anywhere. In a more aggressive and realistic language, the +"ExprAST" class would probably have a type field.

+ +

With this scaffolding, we can now talk about parsing expressions and function +bodies in Kaleidoscope.

+ +
+ + +
Parser Basics
+ + +
+ +

Now that we have an AST to build, we need to define the parser code to build +it. The idea here is that we want to parse something like "x+y" (which is +returned as three tokens by the lexer) into an AST that could be generated with +calls like this:

+ +
+
+  ExprAST *X = new VariableExprAST("x");
+  ExprAST *Y = new VariableExprAST("y");
+  ExprAST *Result = new BinaryExprAST('+', X, Y);
+
+
+ +

In order to do this, we'll start by defining some basic helper routines:

+ +
+
+/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
+/// token the parser it looking at.  getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() {
+  return CurTok = gettok();
+}
+
+
+ +

+This implements a simple token buffer around the lexer. This allows +us to look one token ahead at what the lexer is returning. Every function in +our lexer will assume that CurTok is the current token that needs to be +parsed.

+ +

Again, we define +these with global variables: it would be better design to wrap the entire parser +in a class and use instance variables for these. +

+ +
+
+
+/// Error* - These are little helper functions for error handling.
+ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
+PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
+FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
+
+
+ +

+The Error routines are simple helper routines that our parser will use +to handle errors. The error recovery in our parser will not be the best and +are not particular user-friendly, but it will be enough for our tutorial. These +routines make it easier to handle errors in routines that have various return +types: they always return null.

+ +

With these basic helper functions implemented, we can implement the first +piece of our grammar: we'll start with numeric literals.

+ +
+ + +
Basic Expression + Parsing
+ + +
+ +

We start with numeric literals, because they are the simplest to process. +For each production in our grammar, we'll define a function which parses that +production. For numeric literals, we have: +

+ +
+
+/// numberexpr ::= number
+static ExprAST *ParseNumberExpr() {
+  ExprAST *Result = new NumberExprAST(NumVal);
+  getNextToken(); // consume the number
+  return Result;
+}
+
+
+ +

This routine is very simple: it expects to be called when the current token +is a tok_number token. It takes the current number value, creates +a NumberExprAST node, advances the lexer to the next token, then +returns.

+ +

There are some interesting aspects of this. The most important one is that +this routine eats all of the tokens that correspond to the production, and +returns the lexer buffer with the next token (which is not part of the grammar +production) ready to go. This is a fairly standard way to go for recursive +descent parsers. For a better example, the parenthesis operator is defined like +this:

+ +
+
+/// parenexpr ::= '(' expression ')'
+static ExprAST *ParseParenExpr() {
+  getNextToken();  // eat (.
+  ExprAST *V = ParseExpression();
+  if (!V) return 0;
+  
+  if (CurTok != ')')
+    return Error("expected ')'");
+  getNextToken();  // eat ).
+  return V;
+}
+
+
+ +

This function illustrates a number of interesting things about the parser: +1) it shows how we use the Error routines. When called, this function expects +that the current token is a '(' token, but after parsing the subexpression, it +is possible that there is not a ')' waiting. For example, if the user types in +"(4 x" instead of "(4)", the parser should emit an error. Because errors can +occur, the parser needs a way to indicate that they happened: in our parser, we +return null on an error.

+ +

Another interesting aspect of this function is that it uses recursion by +calling ParseExpression (we will soon see that ParseExpression can call +ParseParenExpr). This is powerful because it allows us to handle +recursive grammars, and keeps each production very simple. Note that +parenthesis do not cause construction of AST nodes themselves. While we could +do this, the most important role of parens are to guide the parser and provide +grouping. Once the parser constructs the AST, parens are not needed.

+ +

The next simple production is for handling variable references and function +calls:

+ +
+
+/// identifierexpr
+///   ::= identifer
+///   ::= identifer '(' expression* ')'
+static ExprAST *ParseIdentifierExpr() {
+  std::string IdName = IdentifierStr;
+  
+  getNextToken();  // eat identifer.
+  
+  if (CurTok != '(') // Simple variable ref.
+    return new VariableExprAST(IdName);
+  
+  // Call.
+  getNextToken();  // eat (
+  std::vector<ExprAST*> Args;
+  while (1) {
+    ExprAST *Arg = ParseExpression();
+    if (!Arg) return 0;
+    Args.push_back(Arg);
+    
+    if (CurTok == ')') break;
+    
+    if (CurTok != ',')
+      return Error("Expected ')'");
+    getNextToken();
+  }
+
+  // Eat the ')'.
+  getNextToken();
+  
+  return new CallExprAST(IdName, Args);
+}
+
+
+ +

This routine follows the same style as the other routines (it expects to be +called if the current token is a tok_identifier token). It also has +recursion and error handling. One interesting aspect of this is that it uses +look-ahead to determine if the current identifier is a stand alone +variable reference or if it is a function call expression. It handles this by +checking to see if the token after the identifier is a '(' token, and constructs +either a VariableExprAST or CallExprAST node as appropriate. +

+ +

Now that we have all of our simple expression parsing logic in place, we can +define a helper function to wrap them up in a class. We call this class of +expressions "primary" expressions, for reasons that will become more clear +later. In order to parse a primary expression, we need to determine what sort +of expression it is:

+ +
+
+/// primary
+///   ::= identifierexpr
+///   ::= numberexpr
+///   ::= parenexpr
+static ExprAST *ParsePrimary() {
+  switch (CurTok) {
+  default: return Error("unknown token when expecting an expression");
+  case tok_identifier: return ParseIdentifierExpr();
+  case tok_number:     return ParseNumberExpr();
+  case '(':            return ParseParenExpr();
+  }
+}
+
+
+ +

Now that you see the definition of this function, it makes it more obvious +why we can assume the state of CurTok in the various functions. This uses +look-ahead to determine which sort of expression is being inspected, and parses +it with a function call.

+ +

Now that basic expressions are handled, we need to handle binary expressions, +which are a bit more complex.

+ +
+ + +
Binary Expression + Parsing
+ + +
+ +

Binary expressions are significantly harder to parse because they are often +ambiguous. For example, when given the string "x+y*z", the parser can choose +to parse it as either "(x+y)*z" or "x+(y*z)". With common definitions from +mathematics, we expect the later parse, because "*" (multiplication) has +higher precedence than "+" (addition).

+ +

There are many ways to handle this, but an elegant and efficient way is to +use Operator-Precedence +Parsing. This parsing technique uses the precedence of binary operators to +guide recursion. To start with, we need a table of precedences:

+ +
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+  if (!isascii(CurTok))
+    return -1;
+    
+  // Make sure it's a declared binop.
+  int TokPrec = BinopPrecedence[CurTok];
+  if (TokPrec <= 0) return -1;
+  return TokPrec;
+}
+
+int main() {
+  // Install standard binary operators.
+  // 1 is lowest precedence.
+  BinopPrecedence['<'] = 10;
+  BinopPrecedence['+'] = 20;
+  BinopPrecedence['-'] = 20;
+  BinopPrecedence['*'] = 40;  // highest.
+  ...
+}
+
+
+ +

For the basic form of Kaleidoscope, we will only support 4 binary operators +(this can obviously be extended by you, the reader). The +GetTokPrecedence function returns the precedence for the current token, +or -1 if the token is not a binary operator. Having a map makes it easy to add +new operators and makes it clear that the algorithm doesn't depend on the +specific operators involved, but it would be easy enough to eliminate the map +and do the comparisons in the GetTokPrecedence function.

+ +

With the helper above defined, we can now start parsing binary expressions. +The basic idea of operator precedence parsing is to break down an expression +with potentially ambiguous binary operators into pieces. Consider for example +the expression "a+b+(c+d)*e*f+g". Operator precedence parsing considers this +as a stream of primary expressions separated by binary operators. As such, +it will first parse the leading primary expression "a", then it will see the +pairs [+, b] [+, (c+d)] [*, e] [*, f] and [+, g]. Note that because parentheses +are primary expressions that the binary expression parser doesn't need to worry +about nested subexpressions like (c+d) at all. +

+ +

+To start, an expression is a primary expression potentially followed by a +sequence of [binop,primaryexpr] pairs:

+ +
+
+/// expression
+///   ::= primary binoprhs
+///
+static ExprAST *ParseExpression() {
+  ExprAST *LHS = ParsePrimary();
+  if (!LHS) return 0;
+  
+  return ParseBinOpRHS(0, LHS);
+}
+
+
+ +

ParseBinOpRHS is the function that parses the sequence of pairs for +us. It takes a precedence and a pointer to an expression for the part parsed +so far. Note that "x" is a perfectly valid expression: As such, "binoprhs" is +allowed to be empty, in which case it returns the expression that is passed into +it. In our example above, the code passes the expression for "a" into +ParseBinOpRHS and the current token is "+".

+ +

The precedence value passed into ParseBinOpRHS indicates the +minimal operator precedence that the function is allowed to eat. For +example, if the current pair stream is [+, x] and ParseBinOpRHS is +passed in a precedence of 40, it will not consume any tokens (because the +precedence of '+' is only 20). With this in mind, ParseBinOpRHS starts +with:

+ +
+
+/// binoprhs
+///   ::= ('+' primary)*
+static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+  // If this is a binop, find its precedence.
+  while (1) {
+    int TokPrec = GetTokPrecedence();
+    
+    // If this is a binop that binds at least as tightly as the current binop,
+    // consume it, otherwise we are done.
+    if (TokPrec < ExprPrec)
+      return LHS;
+
+
+ +

This code gets the precedence of the current token and checks to see if if is +too low. Because we defined invalid tokens to have a precedence of -1, this +check implicitly knows that the pair-stream ends when the token stream runs out +of binary operators. If this check succeeds, we know that the token is a binary +operator and that it will be included in this expression:

+ +
+
+    // Okay, we know this is a binop.
+    int BinOp = CurTok;
+    getNextToken();  // eat binop
+    
+    // Parse the primary expression after the binary operator.
+    ExprAST *RHS = ParsePrimary();
+    if (!RHS) return 0;
+
+
+ +

As such, this code eats (and remembers) the binary operator and then parses +the following primary expression. This builds up the whole pair, the first of +which is [+, b] for the running example.

+ +

Now that we parsed the left-hand side of an expression and one pair of the +RHS sequence, we have to decide which way the expression associates. In +particular, we could have "(a+b) binop unparsed" or "a + (b binop unparsed)". +To determine this, we look ahead at "binop" to determine its precedence and +compare it to BinOp's precedence (which is '+' in this case):

+ +
+
+    // If BinOp binds less tightly with RHS than the operator after RHS, let
+    // the pending operator take RHS as its LHS.
+    int NextPrec = GetTokPrecedence();
+    if (TokPrec < NextPrec) {
+
+
+ +

If the precedence of the binop to the right of "RHS" is lower or equal to the +precedence of our current operator, then we know that the parentheses associate +as "(a+b) binop ...". In our example, since the next operator is "+" and so is +our current one, we know that they have the same precedence. In this case we'll +create the AST node for "a+b", and then continue parsing:

+ +
+
+      ... if body omitted ...
+    }
+    
+    // Merge LHS/RHS.
+    LHS = new BinaryExprAST(BinOp, LHS, RHS);
+  }  // loop around to the top of the while loop.
+}
+
+
+ +

In our example above, this will turn "a+b+" into "(a+b)" and execute the next +iteration of the loop, with "+" as the current token. The code above will eat +and remember it and parse "(c+d)" as the primary expression, which makes the +current pair be [+, (c+d)]. It will then enter the 'if' above with "*" as the +binop to the right of the primary. In this case, the precedence of "*" is +higher than the precedence of "+" so the if condition will be entered.

+ +

The critical question left here is "how can the if condition parse the right +hand side in full"? In particular, to build the AST correctly for our example, +it needs to get all of "(c+d)*e*f" as the RHS expression variable. The code to +do this is surprisingly simple (code from the above two blocks duplicated for +context):

+ +
+
+    // If BinOp binds less tightly with RHS than the operator after RHS, let
+    // the pending operator take RHS as its LHS.
+    int NextPrec = GetTokPrecedence();
+    if (TokPrec < NextPrec) {
+      RHS = ParseBinOpRHS(TokPrec+1, RHS);
+      if (RHS == 0) return 0;
+    }
+    // Merge LHS/RHS.
+    LHS = new BinaryExprAST(BinOp, LHS, RHS);
+  }  // loop around to the top of the while loop.
+}
+
+
+ +

At this point, we know that the binary operator to the RHS of our primary +has higher precedence than the binop we are currently parsing. As such, we know +that any sequence of pairs whose operators are all higher precedence than "+" +should be parsed together and returned as "RHS". To do this, we recursively +invoke the ParseBinOpRHS function specifying "TokPrec+1" as the minimum +precedence required for it to continue. In our example above, this will cause +it to return the AST node for "(c+d)*e*f" as RHS, which is then set as the RHS +of the '+' expression.

+ +

Finally, on the next iteration of the while loop, the "+g" piece is parsed. +and added to the AST. With this little bit of code (14 non-trivial lines), we +correctly handle fully general binary expression parsing in a very elegant way. +

+ +

This wraps up handling of expressions. At this point, we can point the +parser at an arbitrary token stream and build an expression from them, stopping +at the first token that is not part of the expression. Next up we need to +handle function definitions etc.

+ +
+ + +
Parsing the Rest
+ + +
+ +

+The first basic thing missing is that of function prototypes. In Kaleidoscope, +these are used both for 'extern' function declarations as well as function body +definitions. The code to do this is straight-forward and not very interesting +(once you've survived expressions): +

+ +
+
+/// prototype
+///   ::= id '(' id* ')'
+static PrototypeAST *ParsePrototype() {
+  if (CurTok != tok_identifier)
+    return ErrorP("Expected function name in prototype");
+
+  std::string FnName = IdentifierStr;
+  getNextToken();
+  
+  if (CurTok != '(')
+    return ErrorP("Expected '(' in prototype");
+  
+  std::vector<std::string> ArgNames;
+  while (getNextToken() == tok_identifier)
+    ArgNames.push_back(IdentifierStr);
+  if (CurTok != ')')
+    return ErrorP("Expected ')' in prototype");
+  
+  // success.
+  getNextToken();  // eat ')'.
+  
+  return new PrototypeAST(FnName, ArgNames);
+}
+
+
+ +

Given this, a function definition is very simple, just a prototype plus +and expression to implement the body:

+ +
+
+/// definition ::= 'def' prototype expression
+static FunctionAST *ParseDefinition() {
+  getNextToken();  // eat def.
+  PrototypeAST *Proto = ParsePrototype();
+  if (Proto == 0) return 0;
+
+  if (ExprAST *E = ParseExpression())
+    return new FunctionAST(Proto, E);
+  return 0;
+}
+
+
+ +

In addition, we support 'extern' to declare functions like 'sin' and 'cos' as +well as to support forward declaration of user functions. 'externs' are just +prototypes with no body:

+ +
+
+/// external ::= 'extern' prototype
+static PrototypeAST *ParseExtern() {
+  getNextToken();  // eat extern.
+  return ParsePrototype();
+}
+
+
+ +

Finally, we'll also let the user type in arbitrary top-level expressions and +evaluate them on the fly. We will handle this by defining anonymous nullary +(zero argument) functions for them:

+ +
+
+/// toplevelexpr ::= expression
+static FunctionAST *ParseTopLevelExpr() {
+  if (ExprAST *E = ParseExpression()) {
+    // Make an anonymous proto.
+    PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
+    return new FunctionAST(Proto, E);
+  }
+  return 0;
+}
+
+
+ +

Now that we have all the pieces, lets build a little driver that will let us +actually execute this code we've built!

+ +
+ + +
The Driver
+ + +
+ +

The driver for this simply invokes all of the parsing pieces with a top-level +dispatch loop. There isn't much interesting here, so I'll just include the +top-level loop. See below for full code in the "Top-Level +Parsing" section.

+ +
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+  while (1) {
+    fprintf(stderr, "ready> ");
+    switch (CurTok) {
+    case tok_eof:    return;
+    case ';':        getNextToken(); break;  // ignore top level semicolons.
+    case tok_def:    HandleDefinition(); break;
+    case tok_extern: HandleExtern(); break;
+    default:         HandleTopLevelExpression(); break;
+    }
+  }
+}
+
+
+ +

The most interesting part of this is that we ignore top-level semi colons. +Why is this do you ask? The basic reason is that if you type "4 + 5" at the +command line, the parser doesn't know that that is the end of what you will +type. For example, on the next line you could type "def foo..." in which case +4+5 is the end of a top-level expression. Alternatively you could type "* 6", +which would continue the expression. Having top-level semicolons allows you to +type "4+5;" and the parser will know you are done.

+ +
+ + +
Conclusions and the Full Code
+ + +
+ +

With just under 400 lines of commented code, we fully defined our minimal +language, including a lexer, parser and AST builder. With this done, the +executable will validate code and tell us if it is gramatically invalid. For +example, here is a sample interaction:

+ +
+
+$ ./a.out 
+ready> def foo(x y) x+foo(y, 4.0);
+ready> Parsed an function definition.
+ready> def foo(x y) x+y y;
+ready> Parsed an function definition.
+ready> Parsed a top-level expr
+ready> def foo(x y) x+y );
+ready> Parsed an function definition.
+ready> Error: unknown token when expecting an expression
+ready> extern sin(a);
+ready> Parsed an extern
+ready> ^D
+$ 
+
+
+ +

+Here is the full code. Note that it is fully self-contained: you don't even +need LLVM for this. In the next installment, we +will describe how to generate LLVM IR from the AST.

+ +
+
+// To build this:
+//  g++ -g toy.cpp 
+//  ./a.out 
+
+#include <cstdio>
+#include <string>
+#include <
+#include <vector>
+
+//===----------------------------------------------------------------------===//
+// Lexer
+//===----------------------------------------------------------------------===//
+
+// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
+// of these for known things.
+enum Token {
+  tok_eof = -1,
+
+  // commands
+  tok_def = -2, tok_extern = -3,
+
+  // primary
+  tok_identifier = -4, tok_number = -5,
+};
+
+static std::string IdentifierStr;  // Filled in if tok_identifier
+static double NumVal;              // Filled in if tok_number
+
+/// gettok - Return the next token from standard input.
+static int gettok() {
+  static int LastChar = ' ';
+
+  // Skip any whitespace.
+  while (isspace(LastChar))
+    LastChar = getchar();
+
+  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
+    IdentifierStr = LastChar;
+    while (isalnum((LastChar = getchar())))
+      IdentifierStr += LastChar;
+
+    if (IdentifierStr == "def") return tok_def;
+    if (IdentifierStr == "extern") return tok_extern;
+    return tok_identifier;
+  }
+
+  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
+    std::string NumStr;
+    do {
+      NumStr += LastChar;
+      LastChar = getchar();
+    } while (isdigit(LastChar) || LastChar == '.');
+
+    NumVal = strtod(NumStr.c_str(), 0);
+    return tok_number;
+  }
+
+  if (LastChar == '#') {
+    // Comment until end of line.
+    do LastChar = getchar();
+    while (LastChar != EOF && LastChar != '\n' & LastChar != '\r');
+    
+    if (LastChar != EOF)
+      return gettok();
+  }
+  
+  // Check for end of file.  Don't eat the EOF.
+  if (LastChar == EOF)
+    return tok_eof;
+
+  // Otherwise, just return the character as its ascii value.
+  int ThisChar = LastChar;
+  LastChar = getchar();
+  return ThisChar;
+}
+
+//===----------------------------------------------------------------------===//
+// Abstract Syntax Tree (aka Parse Tree)
+//===----------------------------------------------------------------------===//
+
+/// ExprAST - Base class for all expression nodes.
+class ExprAST {
+public:
+  virtual ~ExprAST() {}
+};
+
+/// NumberExprAST - Expression class for numeric literals like "1.0".
+class NumberExprAST : public ExprAST {
+  double Val;
+public:
+  NumberExprAST(double val) : Val(val) {}
+};
+
+/// VariableExprAST - Expression class for referencing a variable, like "a".
+class VariableExprAST : public ExprAST {
+  std::string Name;
+public:
+  VariableExprAST(const std::string &name) : Name(name) {}
+};
+
+/// BinaryExprAST - Expression class for a binary operator.
+class BinaryExprAST : public ExprAST {
+  char Op;
+  ExprAST *LHS, *RHS;
+public:
+  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 
+    : Op(op), LHS(lhs), RHS(rhs) {}
+};
+
+/// CallExprAST - Expression class for function calls.
+class CallExprAST : public ExprAST {
+  std::string Callee;
+  std::vector<ExprAST*> Args;
+public:
+  CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
+    : Callee(callee), Args(args) {}
+};
+
+/// PrototypeAST - This class represents the "prototype" for a function,
+/// which captures its argument names as well as if it is an operator.
+class PrototypeAST {
+  std::string Name;
+  std::vector< Args;
+public:
+  PrototypeAST(const std::string &name, const std::vector<std::string> &args)
+    : Name(name), Args(args) {}
+  
+};
+
+/// FunctionAST - This class represents a function definition itself.
+class FunctionAST {
+  PrototypeAST *Proto;
+  ExprAST *Body;
+public:
+  FunctionAST(PrototypeAST *proto, ExprAST *body)
+    : Proto(proto), Body(body) {}
+  
+};
+
+//===----------------------------------------------------------------------===//
+// Parser
+//===----------------------------------------------------------------------===//
+
+/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
+/// token the parser it looking at.  getNextToken reads another token from the
+/// lexer and updates CurTok with its results.
+static int CurTok;
+static int getNextToken() {
+  return CurTok = gettok();
+}
+
+/// BinopPrecedence - This holds the precedence for each binary operator that is
+/// defined.
+static std::map<char, int> BinopPrecedence;
+
+/// GetTokPrecedence - Get the precedence of the pending binary operator token.
+static int GetTokPrecedence() {
+  if (!isascii(CurTok))
+    return -1;
+  
+  // Make sure it's a declared binop.
+  int TokPrec = BinopPrecedence[CurTok];
+  if (TokPrec <= 0) return -1;
+  return TokPrec;
+}
+
+/// Error* - These are little helper functions for error handling.
+ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
+PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
+FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
+
+static ExprAST *ParseExpression();
+
+/// identifierexpr
+///   ::= identifer
+///   ::= identifer '(' expression* ')'
+static ExprAST *ParseIdentifierExpr() {
+  std::string IdName = IdentifierStr;
+  
+  getNextToken();  // eat identifer.
+  
+  if (CurTok != '(') // Simple variable ref.
+    return new VariableExprAST(IdName);
+  
+  // Call.
+  getNextToken();  // eat (
+  std::vector<ExprAST*> Args;
+  while (1) {
+    ExprAST *Arg = ParseExpression();
+    if (!Arg) return 0;
+    Args.push_back(Arg);
+    
+    if (CurTok == ')') break;
+    
+    if (CurTok != ',')
+      return Error("Expected ')'");
+    getNextToken();
+  }
+
+  // Eat the ')'.
+  getNextToken();
+  
+  return new CallExprAST(IdName, Args);
+}
+
+/// numberexpr ::= number
+static ExprAST *ParseNumberExpr() {
+  ExprAST *Result = new NumberExprAST(NumVal);
+  getNextToken(); // consume the number
+  return Result;
+}
+
+/// parenexpr ::= '(' expression ')'
+static ExprAST *ParseParenExpr() {
+  getNextToken();  // eat (.
+  ExprAST *V = ParseExpression();
+  if (!V) return 0;
+  
+  if (CurTok != ')')
+    return Error("expected ')'");
+  getNextToken();  // eat ).
+  return V;
+}
+
+/// primary
+///   ::= identifierexpr
+///   ::= numberexpr
+///   ::= parenexpr
+static ExprAST *ParsePrimary() {
+  switch (CurTok) {
+  default: return Error("unknown token when expecting an expression");
+  case tok_identifier: return ParseIdentifierExpr();
+  case tok_number:     return ParseNumberExpr();
+  case '(':            return ParseParenExpr();
+  }
+}
+
+/// binoprhs
+///   ::= ('+' primary)*
+static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
+  // If this is a binop, find its precedence.
+  while (1) {
+    int TokPrec = GetTokPrecedence();
+    
+    // If this is a binop that binds at least as tightly as the current binop,
+    // consume it, otherwise we are done.
+    if (TokPrec < ExprPrec)
+      return LHS;
+    
+    // Okay, we know this is a binop.
+    int BinOp = CurTok;
+    getNextToken();  // eat binop
+    
+    // Parse the primary expression after the binary operator.
+    ExprAST *RHS = ParsePrimary();
+    if (!RHS) return 0;
+    
+    // If BinOp binds less tightly with RHS than the operator after RHS, let
+    // the pending operator take RHS as its LHS.
+    int NextPrec = GetTokPrecedence();
+    if (TokPrec < NextPrec) {
+      RHS = ParseBinOpRHS(TokPrec+1, RHS);
+      if (RHS == 0) return 0;
+    }
+    
+    // Merge LHS/RHS.
+    LHS = new BinaryExprAST(BinOp, LHS, RHS);
+  }
+}
+
+/// expression
+///   ::= primary binoprhs
+///
+static ExprAST *ParseExpression() {
+  ExprAST *LHS = ParsePrimary();
+  if (!LHS) return 0;
+  
+  return ParseBinOpRHS(0, LHS);
+}
+
+/// prototype
+///   ::= id '(' id* ')'
+static PrototypeAST *ParsePrototype() {
+  if (CurTok != tok_identifier)
+    return ErrorP("Expected function name in prototype");
+
+  std::string FnName = IdentifierStr;
+  getNextToken();
+  
+  if (CurTok != '(')
+    return ErrorP("Expected '(' in prototype");
+  
+  std::vector<std::string> ArgNames;
+  while (getNextToken() == tok_identifier)
+    ArgNames.push_back(IdentifierStr);
+  if (CurTok != ')')
+    return ErrorP("Expected ')' in prototype");
+  
+  // success.
+  getNextToken();  // eat ')'.
+  
+  return new PrototypeAST(FnName, ArgNames);
+}
+
+/// definition ::= 'def' prototype expression
+static FunctionAST *ParseDefinition() {
+  getNextToken();  // eat def.
+  PrototypeAST *Proto = ParsePrototype();
+  if (Proto == 0) return 0;
+
+  if (ExprAST *E = ParseExpression())
+    return new FunctionAST(Proto, E);
+  return 0;
+}
+
+/// toplevelexpr ::= expression
+static FunctionAST *ParseTopLevelExpr() {
+  if (ExprAST *E = ParseExpression()) {
+    // Make an anonymous proto.
+    PrototypeAST *Proto = new PrototypeAST("", std::vector<());
+    return new FunctionAST(Proto, E);
+  }
+  return 0;
+}
+
+/// external ::= 'extern' prototype
+static PrototypeAST *ParseExtern() {
+  getNextToken();  // eat extern.
+  return ParsePrototype();
+}
+
+//===----------------------------------------------------------------------===//
+// Top-Level parsing
+//===----------------------------------------------------------------------===//
+
+static void HandleDefinition() {
+  if (FunctionAST *F = ParseDefinition()) {
+    fprintf(stderr, "Parsed a function definition.\n");
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+static void HandleExtern() {
+  if (PrototypeAST *P = ParseExtern()) {
+    fprintf(stderr, "Parsed an extern\n");
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+static void HandleTopLevelExpression() {
+  // Evaluate a top level expression into an anonymous function.
+  if (FunctionAST *F = ParseTopLevelExpr()) {
+    fprintf(stderr, "Parsed a top-level expr\n");
+  } else {
+    // Skip token for error recovery.
+    getNextToken();
+  }
+}
+
+/// top ::= definition | external | expression | ';'
+static void MainLoop() {
+  while (1) {
+    fprintf(stderr, "ready> ");
+    switch (CurTok) {
+    case tok_eof:    return;
+    case ';':        getNextToken(); break;  // ignore top level semicolons.
+    case tok_def:    HandleDefinition(); break;
+    case tok_extern: HandleExtern(); break;
+    default:         HandleTopLevelExpression(); break;
+    }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Main driver code.
+//===----------------------------------------------------------------------===//
+
+int main() {
+  // Install standard binary operators.
+  // 1 is lowest precedence.
+  BinopPrecedence['<'] = 10;
+  BinopPrecedence['+'] = 20;
+  BinopPrecedence['-'] = 20;
+  BinopPrecedence['*'] = 40;  // highest.
+
+  // Prime the first token.
+  fprintf(stderr, "ready> ");
+  getNextToken();
+
+  MainLoop();
+  return 0;
+}
+
+
+
+ + +
+
+ Valid CSS! + Valid HTML 4.01! + + Chris Lattner
+ The LLVM Compiler Infrastructure
+ Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ +
+ + Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43218&r1=43217&r2=43218&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Mon Oct 22 01:34:15 2007 @@ -28,7 +28,7 @@
  • Implementing a language with LLVM: Kaleidoscope
    1. The basic language, with its lexer
    2. -
    3. Implementing a Parser and AST
    4. +
    5. Implementing a Parser and AST
    6. Implementing code generation to LLVM IR
    7. Adding JIT codegen support
    8. Extending the language: if/then/else
    9. From resistor at mac.com Mon Oct 22 01:35:08 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 22 Oct 2007 06:35:08 -0000 Subject: [llvm-commits] [llvm] r43219 - in /llvm/trunk/docs/tutorial: JITTutorial1.html Tutorial1.tar.bz2 Tutorial1.zip Message-ID: <200710220635.l9M6Z8OK006558@zion.cs.uiuc.edu> Author: resistor Date: Mon Oct 22 01:35:07 2007 New Revision: 43219 URL: http://llvm.org/viewvc/llvm-project?rev=43219&view=rev Log: Add downloadable code samples. Added: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 (with props) llvm/trunk/docs/tutorial/Tutorial1.zip (with props) Modified: llvm/trunk/docs/tutorial/JITTutorial1.html Modified: llvm/trunk/docs/tutorial/JITTutorial1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial1.html?rev=43219&r1=43218&r2=43219&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial1.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial1.html Mon Oct 22 01:35:07 2007 @@ -19,6 +19,18 @@

      Written by Owen Anderson

      + + + + +
      +All the code in this example can be downloaded at Tutorial1.tar.bz2 or Tutorial1.zip. +
      + + + + +

      For starters, lets consider a relatively straightforward function that takes three integer parameters and returns an arithmetic combination of them. This is nice and simple, especially since it involves no control flow:

      Added: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.tar.bz2?rev=43219&view=auto ============================================================================== Binary file - no diff available. Propchange: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: llvm/trunk/docs/tutorial/Tutorial1.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.zip?rev=43219&view=auto ============================================================================== Binary file - no diff available. Propchange: llvm/trunk/docs/tutorial/Tutorial1.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream From resistor at mac.com Mon Oct 22 01:48:29 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 22 Oct 2007 06:48:29 -0000 Subject: [llvm-commits] [llvm] r43220 - /llvm/trunk/docs/tutorial/LangImpl2.html Message-ID: <200710220648.l9M6mT3D007251@zion.cs.uiuc.edu> Author: resistor Date: Mon Oct 22 01:48:28 2007 New Revision: 43220 URL: http://llvm.org/viewvc/llvm-project?rev=43220&view=rev Log: Fix a few typos I noticed. Modified: llvm/trunk/docs/tutorial/LangImpl2.html Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43220&r1=43219&r2=43220&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Mon Oct 22 01:48:28 2007 @@ -118,7 +118,7 @@ precedence of binary operators, lexical structure etc.

      For our basic language, these are all of the expression nodes we'll define. -because it doesn't have conditional control flow, it isn't turing complete: +Because it doesn't have conditional control flow, it isn't Turing-complete; we'll fix that in a later installment. The two things we need next are a way to talk about the interface to a function, and a way to talk about functions themselves:

      @@ -195,9 +195,7 @@ our lexer will assume that CurTok is the current token that needs to be parsed.

      -

      Again, we define -these with global variables: it would be better design to wrap the entire parser -in a class and use instance variables for these. +

      Again, we define these with global variables; it would be better design to wrap the entire parser in a class and use instance variables for these.

      @@ -282,7 +280,7 @@ return null on an error.

      Another interesting aspect of this function is that it uses recursion by -calling ParseExpression (we will soon see that ParseExpression can call +calling ParseExpression (we will soon see that ParseExpression can call ParseParenExpr). This is powerful because it allows us to handle recursive grammars, and keeps each production very simple. Note that parenthesis do not cause construction of AST nodes themselves. While we could @@ -716,7 +714,7 @@

      The most interesting part of this is that we ignore top-level semi colons. -Why is this do you ask? The basic reason is that if you type "4 + 5" at the +Why is this, you ask? The basic reason is that if you type "4 + 5" at the command line, the parser doesn't know that that is the end of what you will type. For example, on the next line you could type "def foo..." in which case 4+5 is the end of a top-level expression. Alternatively you could type "* 6", From sabre at nondot.org Mon Oct 22 02:01:42 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 22 Oct 2007 07:01:42 -0000 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html Message-ID: <200710220701.l9M71h3d008003@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 02:01:42 2007 New Revision: 43221 URL: http://llvm.org/viewvc/llvm-project?rev=43221&view=rev Log: start of chapter 3 Added: llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/index.html Added: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43221&view=auto ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (added) +++ llvm/trunk/docs/tutorial/LangImpl3.html Mon Oct 22 02:01:42 2007 @@ -0,0 +1,787 @@ + + + + + Kaleidoscope: Implementing code generation to LLVM IR + + + + + + + +

      Kaleidoscope: Code generation to LLVM IR
      + +
      +

      Written by Chris Lattner

      +
      + + + + + +
      + +

      Welcome to part 3 of the "Implementing a language with +LLVM" tutorial. This chapter shows you how to transform the Abstract Syntax Tree built in Chapter 2 into LLVM IR. +This will teach you a little bit about how LLVM does things, as well as +demonstrate how easy it is to use. It's much more work to build a lexer and +parser than it is to generate LLVM IR code. +

      + +
      + + + + + +
      + +

      +In order to generate LLVM IR, we want some simple setup to get started. First, +we define virtual codegen methods in each AST class:

      + +
      +
      +/// ExprAST - Base class for all expression nodes.
      +class ExprAST {
      +public:
      +  virtual ~ExprAST() {}
      +  virtual Value *Codegen() = 0;
      +};
      +
      +/// NumberExprAST - Expression class for numeric literals like "1.0".
      +class NumberExprAST : public ExprAST {
      +  double Val;
      +public:
      +  NumberExprAST(double val) : Val(val) {}
      +  virtual Value *Codegen();
      +};
      +...
      +
      +
      + +

      "Value" is the class used to represent a "register" in LLVM. The Codegen() +method says to emit IR for that AST node and all things it depends on. The +second thing we want is an "Error" method like we used for parser, which will +be used to report errors found during code generation (for example, use of an +undeclared parameter):

      + +
      +
      +Value *ErrorV(const char *Str) { Error(Str); return 0; }
      +
      +static Module *TheModule;
      +static LLVMBuilder Builder;
      +static std::map<std::string, Value*> NamedValues;
      +
      +
      + +

      The static variables will be used during code generation. TheModule +is the LLVM construct that contains all of the functions and global variables in +a chunk of code. In many ways, it is the top-level structure that the LLVM IR +uses to contain code.

      + +

      The Builder object is a helper object that makes it easy to generate +LLVM instructions. The Builder keeps track of the current place to +insert instructions and has methods to create new instructions.

      + +

      The NamedValues map keeps track of which values are defined in the +current scope and what their LLVM representation is. In this form of +Kaleidoscope, the only things that can be referenced are function parameters. +As such, function parameters will be in this map when generating code for their +function body.

      + +

      +With these basics in place, we can start talking about how to generate code for +each expression. Note that this assumes that the Builder has been set +up to generate code into something. For now, we'll assume that this +has already been done, and we'll just use it to emit code. +

      + +
      + + + + + +
      + +

      Generating LLVM code for expression nodes is very straight-forward: less +than 45 lines of commented code for all four of our expression nodes. First, +we'll do numeric literals:

      + +
      +
      +Value *NumberExprAST::Codegen() {
      +  return ConstantFP::get(Type::DoubleTy, APFloat(Val));
      +}
      +
      +
      + +

      In the LLVM IR, numeric constants are represented with the ConstantFP class, +which holds the numeric value in an APFloat internally (APFloat has the +capability of holding floating point constants of arbitrary precision). This +code basically just creates and returns a ConstantFP. Note that in the LLVM IR +that constants are all uniqued together and shared. For this reason, the API +uses "the foo::get(...)" idiom instead of a "create" method or "new foo".

      + +
      +
      +Value *VariableExprAST::Codegen() {
      +  // Look this variable up in the function.
      +  Value *V = NamedValues[Name];
      +  return V ? V : ErrorV("Unknown variable name");
      +}
      +
      +
      + +

      References to variables is also quite simple here. In our system, we assume +that the variable has already been emited somewhere and its value is available. +In practice, the only values in the NamedValues map will be arguments. This +code simply checks to see that the specified name is in the map (if not, an +unknown variable is being referenced) and returns the value for it.

      + +
      +
      +Value *BinaryExprAST::Codegen() {
      +  Value *L = LHS->Codegen();
      +  Value *R = RHS->Codegen();
      +  if (L == 0 || R == 0) return 0;
      +  
      +  switch (Op) {
      +  case '+': return Builder.CreateAdd(L, R, "addtmp");
      +  case '-': return Builder.CreateSub(L, R, "subtmp");
      +  case '*': return Builder.CreateMul(L, R, "multmp");
      +  case '<':
      +    L = Builder.CreateFCmpULT(L, R, "multmp");
      +    // Convert bool 0/1 to double 0.0 or 1.0
      +    return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
      +  default: return ErrorV("invalid binary operator");
      +  }
      +}
      +
      +
      + + + +
      +
      +Value *CallExprAST::Codegen() {
      +  // Look up the name in the global module table.
      +  Function *CalleeF = TheModule->getFunction(Callee);
      +  if (CalleeF == 0)
      +    return ErrorV("Unknown function referenced");
      +  
      +  // If argument mismatch error.
      +  if (CalleeF->arg_size() != Args.size())
      +    return ErrorV("Incorrect # arguments passed");
      +
      +  std::vector<Value*> ArgsV;
      +  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
      +    ArgsV.push_back(Args[i]->Codegen());
      +    if (ArgsV.back() == 0) return 0;
      +  }
      +  
      +  return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
      +}
      +
      +
      + +

      more todo

      + +
      + + + + + +
      + +
      +
      +// To build this:
      +//  g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
      +//                `llvm-config --libs core` -I ~/llvm/include/
      +//  ./a.out 
      +// See example below.
      +
      +#include "llvm/DerivedTypes.h"
      +#include "llvm/Module.h"
      +#include "llvm/Support/LLVMBuilder.h"
      +#include <cstdio>
      +#include <string>
      +#include <map>
      +#include <vector>
      +using namespace llvm;
      +
      +//===----------------------------------------------------------------------===//
      +// Lexer
      +//===----------------------------------------------------------------------===//
      +
      +// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
      +// of these for known things.
      +enum Token {
      +  tok_eof = -1,
      +
      +  // commands
      +  tok_def = -2, tok_extern = -3,
      +
      +  // primary
      +  tok_identifier = -4, tok_number = -5,
      +};
      +
      +static std::string IdentifierStr;  // Filled in if tok_identifier
      +static double NumVal;              // Filled in if tok_number
      +
      +/// gettok - Return the next token from standard input.
      +static int gettok() {
      +  static int LastChar = ' ';
      +
      +  // Skip any whitespace.
      +  while (isspace(LastChar))
      +    LastChar = getchar();
      +
      +  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
      +    IdentifierStr = LastChar;
      +    while (isalnum((LastChar = getchar())))
      +      IdentifierStr += LastChar;
      +
      +    if (IdentifierStr == "def") return tok_def;
      +    if (IdentifierStr == "extern") return tok_extern;
      +    return tok_identifier;
      +  }
      +
      +  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
      +    std::string NumStr;
      +    do {
      +      NumStr += LastChar;
      +      LastChar = getchar();
      +    } while (isdigit(LastChar) || LastChar == '.');
      +
      +    NumVal = strtod(NumStr.c_str(), 0);
      +    return tok_number;
      +  }
      +
      +  if (LastChar == '#') {
      +    // Comment until end of line.
      +    do LastChar = getchar();
      +    while (LastChar != EOF && LastChar != '\n' & LastChar != '\r');
      +    
      +    if (LastChar != EOF)
      +      return gettok();
      +  }
      +  
      +  // Check for end of file.  Don't eat the EOF.
      +  if (LastChar == EOF)
      +    return tok_eof;
      +
      +  // Otherwise, just return the character as its ascii value.
      +  int ThisChar = LastChar;
      +  LastChar = getchar();
      +  return ThisChar;
      +}
      +
      +//===----------------------------------------------------------------------===//
      +// Abstract Syntax Tree (aka Parse Tree)
      +//===----------------------------------------------------------------------===//
      +
      +/// ExprAST - Base class for all expression nodes.
      +class ExprAST {
      +public:
      +  virtual ~ExprAST() {}
      +  virtual Value *Codegen() = 0;
      +};
      +
      +/// NumberExprAST - Expression class for numeric literals like "1.0".
      +class NumberExprAST : public ExprAST {
      +  double Val;
      +public:
      +  NumberExprAST(double val) : Val(val) {}
      +  virtual Value *Codegen();
      +};
      +
      +/// VariableExprAST - Expression class for referencing a variable, like "a".
      +class VariableExprAST : public ExprAST {
      +  std::string Name;
      +public:
      +  VariableExprAST(const std::string &name) : Name(name) {}
      +  virtual Value *Codegen();
      +};
      +
      +/// BinaryExprAST - Expression class for a binary operator.
      +class BinaryExprAST : public ExprAST {
      +  char Op;
      +  ExprAST *LHS, *RHS;
      +public:
      +  BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) 
      +    : Op(op), LHS(lhs), RHS(rhs) {}
      +  virtual Value *Codegen();
      +};
      +
      +/// CallExprAST - Expression class for function calls.
      +class CallExprAST : public ExprAST {
      +  std::string Callee;
      +  std::vector<ExprAST*> Args;
      +public:
      +  CallExprAST(const std::string &callee, std::vector<ExprAST*> &args)
      +    : Callee(callee), Args(args) {}
      +  virtual Value *Codegen();
      +};
      +
      +/// PrototypeAST - This class represents the "prototype" for a function,
      +/// which captures its argument names as well as if it is an operator.
      +class PrototypeAST {
      +  std::string Name;
      +  std::vector<std::string> Args;
      +public:
      +  PrototypeAST(const std::string &name, const std::vector<std::string> &args)
      +    : Name(name), Args(args) {}
      +  
      +  Function *Codegen();
      +};
      +
      +/// FunctionAST - This class represents a function definition itself.
      +class FunctionAST {
      +  PrototypeAST *Proto;
      +  ExprAST *Body;
      +public:
      +  FunctionAST(PrototypeAST *proto, ExprAST *body)
      +    : Proto(proto), Body(body) {}
      +  
      +  Function *Codegen();
      +};
      +
      +//===----------------------------------------------------------------------===//
      +// Parser
      +//===----------------------------------------------------------------------===//
      +
      +/// CurTok/getNextToken - Provide a simple token buffer.  CurTok is the current
      +/// token the parser it looking at.  getNextToken reads another token from the
      +/// lexer and updates CurTok with its results.
      +static int CurTok;
      +static int getNextToken() {
      +  return CurTok = gettok();
      +}
      +
      +/// BinopPrecedence - This holds the precedence for each binary operator that is
      +/// defined.
      +static std::map<char, int> BinopPrecedence;
      +
      +/// GetTokPrecedence - Get the precedence of the pending binary operator token.
      +static int GetTokPrecedence() {
      +  if (!isascii(CurTok))
      +    return -1;
      +  
      +  // Make sure it's a declared binop.
      +  int TokPrec = BinopPrecedence[CurTok];
      +  if (TokPrec <= 0) return -1;
      +  return TokPrec;
      +}
      +
      +/// Error* - These are little helper functions for error handling.
      +ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;}
      +PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; }
      +FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; }
      +
      +static ExprAST *ParseExpression();
      +
      +/// identifierexpr
      +///   ::= identifer
      +///   ::= identifer '(' expression* ')'
      +static ExprAST *ParseIdentifierExpr() {
      +  std::string IdName = IdentifierStr;
      +  
      +  getNextToken();  // eat identifer.
      +  
      +  if (CurTok != '(') // Simple variable ref.
      +    return new VariableExprAST(IdName);
      +  
      +  // Call.
      +  getNextToken();  // eat (
      +  std::vector<ExprAST*> Args;
      +  while (1) {
      +    ExprAST *Arg = ParseExpression();
      +    if (!Arg) return 0;
      +    Args.push_back(Arg);
      +    
      +    if (CurTok == ')') break;
      +    
      +    if (CurTok != ',')
      +      return Error("Expected ')'");
      +    getNextToken();
      +  }
      +
      +  // Eat the ')'.
      +  getNextToken();
      +  
      +  return new CallExprAST(IdName, Args);
      +}
      +
      +/// numberexpr ::= number
      +static ExprAST *ParseNumberExpr() {
      +  ExprAST *Result = new NumberExprAST(NumVal);
      +  getNextToken(); // consume the number
      +  return Result;
      +}
      +
      +/// parenexpr ::= '(' expression ')'
      +static ExprAST *ParseParenExpr() {
      +  getNextToken();  // eat (.
      +  ExprAST *V = ParseExpression();
      +  if (!V) return 0;
      +  
      +  if (CurTok != ')')
      +    return Error("expected ')'");
      +  getNextToken();  // eat ).
      +  return V;
      +}
      +
      +/// primary
      +///   ::= identifierexpr
      +///   ::= numberexpr
      +///   ::= parenexpr
      +static ExprAST *ParsePrimary() {
      +  switch (CurTok) {
      +  default: return Error("unknown token when expecting an expression");
      +  case tok_identifier: return ParseIdentifierExpr();
      +  case tok_number:     return ParseNumberExpr();
      +  case '(':            return ParseParenExpr();
      +  }
      +}
      +
      +/// binoprhs
      +///   ::= ('+' primary)*
      +static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) {
      +  // If this is a binop, find its precedence.
      +  while (1) {
      +    int TokPrec = GetTokPrecedence();
      +    
      +    // If this is a binop that binds at least as tightly as the current binop,
      +    // consume it, otherwise we are done.
      +    if (TokPrec < ExprPrec)
      +      return LHS;
      +    
      +    // Okay, we know this is a binop.
      +    int BinOp = CurTok;
      +    getNextToken();  // eat binop
      +    
      +    // Parse the primary expression after the binary operator.
      +    ExprAST *RHS = ParsePrimary();
      +    if (!RHS) return 0;
      +    
      +    // If BinOp binds less tightly with RHS than the operator after RHS, let
      +    // the pending operator take RHS as its LHS.
      +    int NextPrec = GetTokPrecedence();
      +    if (TokPrec < NextPrec) {
      +      RHS = ParseBinOpRHS(TokPrec+1, RHS);
      +      if (RHS == 0) return 0;
      +    }
      +    
      +    // Merge LHS/RHS.
      +    LHS = new BinaryExprAST(BinOp, LHS, RHS);
      +  }
      +}
      +
      +/// expression
      +///   ::= primary binoprhs
      +///
      +static ExprAST *ParseExpression() {
      +  ExprAST *LHS = ParsePrimary();
      +  if (!LHS) return 0;
      +  
      +  return ParseBinOpRHS(0, LHS);
      +}
      +
      +/// prototype
      +///   ::= id '(' id* ')'
      +static PrototypeAST *ParsePrototype() {
      +  if (CurTok != tok_identifier)
      +    return ErrorP("Expected function name in prototype");
      +
      +  std::string FnName = IdentifierStr;
      +  getNextToken();
      +  
      +  if (CurTok != '(')
      +    return ErrorP("Expected '(' in prototype");
      +  
      +  std::vector<std::string> ArgNames;
      +  while (getNextToken() == tok_identifier)
      +    ArgNames.push_back(IdentifierStr);
      +  if (CurTok != ')')
      +    return ErrorP("Expected ')' in prototype");
      +  
      +  // success.
      +  getNextToken();  // eat ')'.
      +  
      +  return new PrototypeAST(FnName, ArgNames);
      +}
      +
      +/// definition ::= 'def' prototype expression
      +static FunctionAST *ParseDefinition() {
      +  getNextToken();  // eat def.
      +  PrototypeAST *Proto = ParsePrototype();
      +  if (Proto == 0) return 0;
      +
      +  if (ExprAST *E = ParseExpression())
      +    return new FunctionAST(Proto, E);
      +  return 0;
      +}
      +
      +/// toplevelexpr ::= expression
      +static FunctionAST *ParseTopLevelExpr() {
      +  if (ExprAST *E = ParseExpression()) {
      +    // Make an anonymous proto.
      +    PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
      +    return new FunctionAST(Proto, E);
      +  }
      +  return 0;
      +}
      +
      +/// external ::= 'extern' prototype
      +static PrototypeAST *ParseExtern() {
      +  getNextToken();  // eat extern.
      +  return ParsePrototype();
      +}
      +
      +//===----------------------------------------------------------------------===//
      +// Code Generation
      +//===----------------------------------------------------------------------===//
      +
      +static Module *TheModule;
      +static LLVMBuilder Builder;
      +static std::map<std::string, Value*> NamedValues;
      +
      +Value *ErrorV(const char *Str) { Error(Str); return 0; }
      +
      +Value *NumberExprAST::Codegen() {
      +  return ConstantFP::get(Type::DoubleTy, APFloat(Val));
      +}
      +
      +Value *VariableExprAST::Codegen() {
      +  // Look this variable up in the function.
      +  Value *V = NamedValues[Name];
      +  return V ? V : ErrorV("Unknown variable name");
      +}
      +
      +Value *BinaryExprAST::Codegen() {
      +  Value *L = LHS->Codegen();
      +  Value *R = RHS->Codegen();
      +  if (L == 0 || R == 0) return 0;
      +  
      +  switch (Op) {
      +  case '+': return Builder.CreateAdd(L, R, "addtmp");
      +  case '-': return Builder.CreateSub(L, R, "subtmp");
      +  case '*': return Builder.CreateMul(L, R, "multmp");
      +  case '<':
      +    L = Builder.CreateFCmpULT(L, R, "multmp");
      +    // Convert bool 0/1 to double 0.0 or 1.0
      +    return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp");
      +  default: return ErrorV("invalid binary operator");
      +  }
      +}
      +
      +Value *CallExprAST::Codegen() {
      +  // Look up the name in the global module table.
      +  Function *CalleeF = TheModule->getFunction(Callee);
      +  if (CalleeF == 0)
      +    return ErrorV("Unknown function referenced");
      +  
      +  // If argument mismatch error.
      +  if (CalleeF->arg_size() != Args.size())
      +    return ErrorV("Incorrect # arguments passed");
      +
      +  std::vector<Value*> ArgsV;
      +  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
      +    ArgsV.push_back(Args[i]->Codegen());
      +    if (ArgsV.back() == 0) return 0;
      +  }
      +  
      +  return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp");
      +}
      +
      +Function *PrototypeAST::Codegen() {
      +  // Make the function type:  double(double,double) etc.
      +  FunctionType *FT = 
      +    FunctionType::get(Type::DoubleTy, std::vector<const Type*>(Args.size(),
      +                                                               Type::DoubleTy),
      +                      false);
      +  
      +  Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
      +  
      +  // If F conflicted, there was already something named 'Name'.  If it has a
      +  // body, don't allow redefinition or reextern.
      +  if (F->getName() != Name) {
      +    // Delete the one we just made and get the existing one.
      +    F->eraseFromParent();
      +    F = TheModule->getFunction(Name);
      +    
      +    // If F already has a body, reject this.
      +    if (!F->empty()) {
      +      ErrorF("redefinition of function");
      +      return 0;
      +    }
      +    
      +    // If F took a different number of args, reject.
      +    if (F->arg_size() != Args.size()) {
      +      ErrorF("redefinition of function with different # args");
      +      return 0;
      +    }
      +  }
      +  
      +  // Set names for all arguments.
      +  unsigned Idx = 0;
      +  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
      +       ++AI, ++Idx) {
      +    AI->setName(Args[Idx]);
      +    
      +    // Add arguments to variable symbol table.
      +    NamedValues[Args[Idx]] = AI;
      +  }
      +  
      +  return F;
      +}
      +
      +Function *FunctionAST::Codegen() {
      +  NamedValues.clear();
      +  
      +  Function *TheFunction = Proto->Codegen();
      +  if (TheFunction == 0)
      +    return 0;
      +  
      +  // Create a new basic block to start insertion into.
      +  Builder.SetInsertPoint(new BasicBlock("entry", TheFunction));
      +  
      +  if (Value *RetVal = Body->Codegen()) {
      +    // Finish off the function.
      +    Builder.CreateRet(RetVal);
      +    return TheFunction;
      +  }
      +  
      +  // Error reading body, remove function.
      +  TheFunction->eraseFromParent();
      +  return 0;
      +}
      +
      +//===----------------------------------------------------------------------===//
      +// Top-Level parsing and JIT Driver
      +//===----------------------------------------------------------------------===//
      +
      +static void HandleDefinition() {
      +  if (FunctionAST *F = ParseDefinition()) {
      +    if (Function *LF = F->Codegen()) {
      +      fprintf(stderr, "Read function definition:");
      +      LF->dump();
      +    }
      +  } else {
      +    // Skip token for error recovery.
      +    getNextToken();
      +  }
      +}
      +
      +static void HandleExtern() {
      +  if (PrototypeAST *P = ParseExtern()) {
      +    if (Function *F = P->Codegen()) {
      +      fprintf(stderr, "Read extern: ");
      +      F->dump();
      +    }
      +  } else {
      +    // Skip token for error recovery.
      +    getNextToken();
      +  }
      +}
      +
      +static void HandleTopLevelExpression() {
      +  // Evaluate a top level expression into an anonymous function.
      +  if (FunctionAST *F = ParseTopLevelExpr()) {
      +    if (Function *LF = F->Codegen()) {
      +      fprintf(stderr, "Read top-level expression:");
      +      LF->dump();
      +    }
      +  } else {
      +    // Skip token for error recovery.
      +    getNextToken();
      +  }
      +}
      +
      +/// top ::= definition | external | expression | ';'
      +static void MainLoop() {
      +  while (1) {
      +    fprintf(stderr, "ready> ");
      +    switch (CurTok) {
      +    case tok_eof:    return;
      +    case ';':        getNextToken(); break;  // ignore top level semicolons.
      +    case tok_def:    HandleDefinition(); break;
      +    case tok_extern: HandleExtern(); break;
      +    default:         HandleTopLevelExpression(); break;
      +    }
      +  }
      +}
      +
      +
      +
      +//===----------------------------------------------------------------------===//
      +// "Library" functions that can be "extern'd" from user code.
      +//===----------------------------------------------------------------------===//
      +
      +/// putchard - putchar that takes a double and returns 0.
      +extern "C" 
      +double putchard(double X) {
      +  putchar((char)X);
      +  return 0;
      +}
      +
      +//===----------------------------------------------------------------------===//
      +// Main driver code.
      +//===----------------------------------------------------------------------===//
      +
      +int main() {
      +  TheModule = new Module("my cool jit");
      +
      +  // Install standard binary operators.
      +  // 1 is lowest precedence.
      +  BinopPrecedence['<'] = 10;
      +  BinopPrecedence['+'] = 20;
      +  BinopPrecedence['-'] = 20;
      +  BinopPrecedence['*'] = 40;  // highest.
      +
      +  // Prime the first token.
      +  fprintf(stderr, "ready> ");
      +  getNextToken();
      +
      +  MainLoop();
      +  TheModule->dump();
      +  return 0;
      +}
      +
      +/* Examples:
      +
      +def fib(x)
      +  if (x < 3) then
      +    1
      +  else
      +    fib(x-1)+fib(x-2);
      +
      +fib(10);
      +
      +*/
      +
      +
      +
      + + +
      +
      + Valid CSS! + Valid HTML 4.01! + + Chris Lattner
      + The LLVM Compiler Infrastructure
      + Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ +
      + + Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43221&r1=43220&r2=43221&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Mon Oct 22 02:01:42 2007 @@ -29,7 +29,7 @@
      1. The basic language, with its lexer
      2. Implementing a Parser and AST
      3. -
      4. Implementing code generation to LLVM IR
      5. +
      6. Implementing code generation to LLVM IR
      7. Adding JIT codegen support
      8. Extending the language: if/then/else
      9. Extending the language: operator overloading
      10. From clattner at apple.com Mon Oct 22 11:35:47 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 22 Oct 2007 09:35:47 -0700 Subject: [llvm-commits] [llvm] r43191 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp test/CFrontend/2007-10-15-VoidPtr.c test/Transforms/BranchFolding/ test/Transforms/BranchFolding/2007-10-19-InlineAsmDirectives.ll In-Reply-To: <5821B330-4E5F-451E-A751-9318E2AA1728@apple.com> References: <200710192109.l9JL9uN2008645@zion.cs.uiuc.edu> <200710201053.59713.baldrick@free.fr> <5821B330-4E5F-451E-A751-9318E2AA1728@apple.com> Message-ID: <785D1020-A93A-4605-A152-B6D768AB26A9@apple.com> On Oct 20, 2007, at 11:49 AM, Dale Johannesen wrote: > On Oct 20, 2007, at 10:29 AM, Chris Lattner wrote: >> This is just a really ugly compatibility hack. Apparently GCC >> doesn't do cross jumping of inline asm statements as much as we do, >> and we've hit a significant body of code that depends on this not >> happening. >> >> The code in question is clearly broken, but at this point, I think >> it's important for LLVM to be "bug compatible" with GCC if it doesn't >> cost much. In this case, we only lose tail merging of inline asm >> statements, which impacts code size but not performance. > > Bill's change is not clearly the wrong thing. People using asm's are > generally trying to do something they can't do more > straightforwardly; they know what code they want the compiler to > produce, and regard writing asm's as an exercise in coercing the > compiler into producing it. (They should be writing in assembler > IMO, but gcc decided years ago to support asm, and we're all stuck > with it now.) Before moving to llvm, I was maintaining gcc for some > time; I never had anybody complain their asm's were not optimized > enough, and I got many complaints that asm's were optimized too much. I'm sympathetic to that viewpoint, but it can't be made to work. In this particular case, the user is using pairs of asms and expecting them to come out in the .s file in the same order as they wrote. There is no way the compiler can reasonably guarantee this to work: it would prevent all block reordering and control flow optimizations etc. Turning off tail merging happens to fix the cases that are failing, but it's just a band-aid, not a solution. -Chris From sabre at nondot.org Mon Oct 22 11:44:32 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 22 Oct 2007 16:44:32 -0000 Subject: [llvm-commits] [llvm] r43222 - /llvm/trunk/docs/tutorial/LangImpl2.html Message-ID: <200710221644.l9MGiWBY016176@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 11:44:31 2007 New Revision: 43222 URL: http://llvm.org/viewvc/llvm-project?rev=43222&view=rev Log: fit in 80 cols :) Modified: llvm/trunk/docs/tutorial/LangImpl2.html Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43222&r1=43221&r2=43222&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Mon Oct 22 11:44:31 2007 @@ -195,7 +195,8 @@ our lexer will assume that CurTok is the current token that needs to be parsed.

        -

        Again, we define these with global variables; it would be better design to wrap the entire parser in a class and use instance variables for these. +

        Again, we define these with global variables; it would be better design to +wrap the entire parser in a class and use instance variables for these.

        From clattner at apple.com Mon Oct 22 11:45:24 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 22 Oct 2007 09:45:24 -0700 Subject: [llvm-commits] [llvm] r43171 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp In-Reply-To: <200710211934.13010.baldrick@free.fr> References: <200710190446.l9J4kkXp018139@zion.cs.uiuc.edu> <200710191031.52183.baldrick@free.fr> <28072F1F-0B36-41E5-BE95-1F80A196B132@apple.com> <200710211934.13010.baldrick@free.fr> Message-ID: On Oct 21, 2007, at 10:34 AM, Duncan Sands wrote: > Hi Chris, > >> Assuming an expansion from i64 to 2x i32, the code above will work >> for sextinreg amounts between 1 and 32. For greater amounts, the top >> part should get a sextinreg, and the bottom part should or togther >> the top and bottom shifted parts, similar to a expanded shift. > > not sure why you need to do something complicated for the bottom > part. Consider > sextinreg from i63 to i64. The operand expands to 2 x i32: Lo and > Hi. It seems > to me that nothing needs to be done to Lo, while Hi needs to > undergo an sextinreg > from i31 to i32. Ah, you're right! -Chris From dalej at apple.com Mon Oct 22 13:06:39 2007 From: dalej at apple.com (Dale Johannesen) Date: Mon, 22 Oct 2007 11:06:39 -0700 Subject: [llvm-commits] [llvm] r43191 - in /llvm/trunk: lib/CodeGen/BranchFolding.cpp test/CFrontend/2007-10-15-VoidPtr.c test/Transforms/BranchFolding/ test/Transforms/BranchFolding/2007-10-19-InlineAsmDirectives.ll In-Reply-To: <785D1020-A93A-4605-A152-B6D768AB26A9@apple.com> References: <200710192109.l9JL9uN2008645@zion.cs.uiuc.edu> <200710201053.59713.baldrick@free.fr> <5821B330-4E5F-451E-A751-9318E2AA1728@apple.com> <785D1020-A93A-4605-A152-B6D768AB26A9@apple.com> Message-ID: On Oct 22, 2007, at 9:35 AM, Chris Lattner wrote: > On Oct 20, 2007, at 11:49 AM, Dale Johannesen wrote: >> On Oct 20, 2007, at 10:29 AM, Chris Lattner wrote: >>> This is just a really ugly compatibility hack. Apparently GCC >>> doesn't do cross jumping of inline asm statements as much as we do, >>> and we've hit a significant body of code that depends on this not >>> happening. >>> >>> The code in question is clearly broken, but at this point, I think >>> it's important for LLVM to be "bug compatible" with GCC if it >>> doesn't >>> cost much. In this case, we only lose tail merging of inline asm >>> statements, which impacts code size but not performance. >> >> Bill's change is not clearly the wrong thing. People using asm's are >> generally trying to do something they can't do more >> straightforwardly; they know what code they want the compiler to >> produce, and regard writing asm's as an exercise in coercing the >> compiler into producing it. (They should be writing in assembler >> IMO, but gcc decided years ago to support asm, and we're all stuck >> with it now.) Before moving to llvm, I was maintaining gcc for some >> time; I never had anybody complain their asm's were not optimized >> enough, and I got many complaints that asm's were optimized too much. > > I'm sympathetic to that viewpoint, but it can't be made to work. > > In this particular case, the user is using pairs of asms and > expecting them to come out in the .s file in the same order as they > wrote. There is no way the compiler can reasonably guarantee this to > work: it would prevent all block reordering and control flow > optimizations etc. Yeah, turning all that off is a bit much. (I did, however, get the question "how do I prevent the compiler from rearranging my code" more than once from the asm users. The current answer is "you don't", but this is something that certain people want.) From baldrick at free.fr Mon Oct 22 13:26:21 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 22 Oct 2007 18:26:21 -0000 Subject: [llvm-commits] [llvm] r43223 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710221826.l9MIQLAj021352@zion.cs.uiuc.edu> Author: baldrick Date: Mon Oct 22 13:26:21 2007 New Revision: 43223 URL: http://llvm.org/viewvc/llvm-project?rev=43223&view=rev Log: Fix up the logic for result expanding the various extension operations so they work right for integers with funky bit-widths. For example, consider extending i48 to i64 on a 32 bit machine. The i64 result is expanded to 2 x i32. We know that the i48 operand will be promoted to i64, then also expanded to 2 x i32. If we had the expanded promoted operand to hand, then expanding the result would be trivial. Unfortunately at this stage we can only get hold of the promoted operand. So instead we kind of hand-expand, doing explicit shifting and truncating to get the top and bottom halves of the i64 operand into 2 x i32, which are then used to expand the result. This is harmless, because when the promoted operand is finally expanded all this bit fiddling turns into trivial operations which are eliminated either by the expansion code itself or the DAG combiner. 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=43223&r1=43222&r2=43223&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 22 13:26:21 2007 @@ -133,7 +133,8 @@ // Common routines. SDOperand CreateStackStoreLoad(SDOperand Op, MVT::ValueType DestVT); SDOperand HandleMemIntrinsic(SDNode *N); - + void SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi); + // Result Promotion. void PromoteResult(SDNode *N, unsigned ResNo); SDOperand PromoteResult_UNDEF(SDNode *N); @@ -498,6 +499,20 @@ return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6); } +/// SplitOp - Return the lower and upper halves of Op's bits in a value type +/// half the size of Op's. +void DAGTypeLegalizer::SplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { + unsigned NVTBits = MVT::getSizeInBits(Op.getValueType())/2; + assert(MVT::getSizeInBits(Op.getValueType()) == 2*NVTBits && + "Cannot split odd sized integer type"); + MVT::ValueType NVT = MVT::getIntegerType(NVTBits); + Lo = DAG.getNode(ISD::TRUNCATE, NVT, Op); + Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, + DAG.getConstant(NVTBits, TLI.getShiftAmountTy())); + Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi); +} + + //===----------------------------------------------------------------------===// // Result Promotion //===----------------------------------------------------------------------===// @@ -805,33 +820,77 @@ Hi = N->getOperand(1); } -void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, +void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - // The low part is any extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, N->getOperand(0)); - Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is any extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op); + Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + } } void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - // The low part is zero extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); - Hi = DAG.getConstant(0, NVT); // The high part is just a zero. + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is zero extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); + Hi = DAG.getConstant(0, NVT); // The high part is just a zero. + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + unsigned ExcessBits = + MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); + Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerType(ExcessBits)); + } } void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - // The low part is sign extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); - - // The high part is obtained by SRA'ing all but one of the bits of low part. - unsigned LoSize = MVT::getSizeInBits(NVT); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + SDOperand Op = N->getOperand(0); + if (MVT::getSizeInBits(Op.getValueType()) <= MVT::getSizeInBits(NVT)) { + // The low part is sign extension of the input (which degenerates to a copy). + Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); + // The high part is obtained by SRA'ing all but one of the bits of low part. + unsigned LoSize = MVT::getSizeInBits(NVT); + Hi = DAG.getNode(ISD::SRA, NVT, Lo, + DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + } else { + // For example, extension of an i48 to an i64. The operand type necessarily + // promotes to the result type, so will end up being expanded too. + assert(getTypeAction(Op.getValueType()) == Promote && + "Don't know how to expand this result!"); + SDOperand Res = GetPromotedOp(Op); + assert(Res.getValueType() == N->getValueType(0) && + "Operand over promoted?"); + // Split the promoted operand. This will simplify when it is expanded. + SplitOp(Res, Lo, Hi); + unsigned ExcessBits = + MVT::getSizeInBits(Op.getValueType()) - MVT::getSizeInBits(NVT); + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + DAG.getValueType(MVT::getIntegerType(ExcessBits))); + } } void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N, @@ -844,18 +903,27 @@ void DAGTypeLegalizer:: ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { GetExpandedOp(N->getOperand(0), Lo, Hi); - - // sext_inreg the low part if needed. - Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, - N->getOperand(1)); - - // The high part gets the sign extension from the lo-part. This handles - // things like sextinreg V:i64 from i8. - Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, - DAG.getConstant(MVT::getSizeInBits(Hi.getValueType())-1, - TLI.getShiftAmountTy())); -} + MVT::ValueType EVT = N->getOperand(1).getValueType(); + if (MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(Lo.getValueType())) { + // sext_inreg the low part if needed. + Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, + N->getOperand(1)); + + // The high part gets the sign extension from the lo-part. This handles + // things like sextinreg V:i64 from i8. + Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, + DAG.getConstant(MVT::getSizeInBits(Hi.getValueType())-1, + TLI.getShiftAmountTy())); + } else { + // For example, extension of an i48 to an i64. Leave the low part alone, + // sext_inreg the high part. + unsigned ExcessBits = + MVT::getSizeInBits(EVT) - MVT::getSizeInBits(Lo.getValueType()); + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + DAG.getValueType(MVT::getIntegerType(ExcessBits))); + } +} void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi) { From djg at cray.com Mon Oct 22 13:31:59 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 22 Oct 2007 18:31:59 -0000 Subject: [llvm-commits] [llvm] r43224 - 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 lib/Transforms/Scalar/IndVarSimplify.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200710221831.l9MIVxcm021599@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 22 13:31:58 2007 New Revision: 43224 URL: http://llvm.org/viewvc/llvm-project?rev=43224&view=rev Log: Move the SCEV object factors from being static members of the individual SCEV subclasses to being non-static member functions of the ScalarEvolution class. 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/lib/Transforms/Scalar/IndVarSimplify.cpp llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolution.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolution.h?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolution.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolution.h Mon Oct 22 13:31:58 2007 @@ -27,12 +27,15 @@ #include namespace llvm { + class APInt; + class ConstantInt; class Instruction; class Type; class ConstantRange; class Loop; class LoopInfo; class SCEVHandle; + class ScalarEvolution; /// SCEV - This class represent an analyzed expression in the program. These /// are reference counted opaque objects that the client is not allowed to @@ -56,16 +59,6 @@ public: explicit SCEV(unsigned SCEVTy) : SCEVType(SCEVTy), RefCount(0) {} - /// getNegativeSCEV - Return the SCEV object corresponding to -V. - /// - static SCEVHandle getNegativeSCEV(const SCEVHandle &V); - - /// getMinusSCEV - Return LHS-RHS. - /// - static SCEVHandle getMinusSCEV(const SCEVHandle &LHS, - const SCEVHandle &RHS); - - unsigned getSCEVType() const { return SCEVType; } /// getValueRange - Return the tightest constant bounds that this value is @@ -97,7 +90,8 @@ /// returns itself. virtual SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const = 0; + const SCEVHandle &Conc, + ScalarEvolution &SE) const = 0; /// print - Print out the internal representation of this scalar to the /// specified stream. This should really only be used for debugging @@ -131,7 +125,8 @@ void print(std::ostream *OS) const { if (OS) print(*OS); } virtual SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SCEVCouldNotCompute *S) { return true; } @@ -204,6 +199,58 @@ /// specified expression. SCEVHandle getSCEV(Value *V) const; + SCEVHandle getConstant(ConstantInt *V); + SCEVHandle getConstant(const APInt& Val); + SCEVHandle getTruncateExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getSignExtendExpr(const SCEVHandle &Op, const Type *Ty); + SCEVHandle getAddExpr(std::vector &Ops); + SCEVHandle getAddExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return getAddExpr(Ops); + } + SCEVHandle getAddExpr(const SCEVHandle &Op0, const SCEVHandle &Op1, + const SCEVHandle &Op2) { + std::vector Ops; + Ops.push_back(Op0); + Ops.push_back(Op1); + Ops.push_back(Op2); + return getAddExpr(Ops); + } + SCEVHandle getMulExpr(std::vector &Ops); + SCEVHandle getMulExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { + std::vector Ops; + Ops.push_back(LHS); + Ops.push_back(RHS); + return getMulExpr(Ops); + } + SCEVHandle getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS); + SCEVHandle getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step, + const Loop *L); + SCEVHandle getAddRecExpr(std::vector &Operands, + const Loop *L); + SCEVHandle getAddRecExpr(const std::vector &Operands, + const Loop *L) { + std::vector NewOp(Operands); + return getAddRecExpr(NewOp, L); + } + SCEVHandle getUnknown(Value *V); + + /// getNegativeSCEV - Return the SCEV object corresponding to -V. + /// + SCEVHandle getNegativeSCEV(const SCEVHandle &V); + + /// getMinusSCEV - Return LHS-RHS. + /// + SCEVHandle getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS); + + /// getIntegerSCEV - Given an integer or FP type, create a constant for the + /// specified signed integer value and return a SCEV for the constant. + SCEVHandle getIntegerSCEV(int Val, const Type *Ty); + /// hasSCEV - Return true if the SCEV for this value has already been /// computed. bool hasSCEV(Value *V) const; Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpander.h Mon Oct 22 13:31:58 2007 @@ -61,8 +61,8 @@ /// starts at zero and steps by one on each iteration. Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty){ assert(Ty->isInteger() && "Can only insert integer induction variables!"); - SCEVHandle H = SCEVAddRecExpr::get(SCEVUnknown::getIntegerSCEV(0, Ty), - SCEVUnknown::getIntegerSCEV(1, Ty), L); + SCEVHandle H = SE.getAddRecExpr(SE.getIntegerSCEV(0, Ty), + SE.getIntegerSCEV(1, Ty), L); return expand(H); } Modified: llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h (original) +++ llvm/trunk/include/llvm/Analysis/ScalarEvolutionExpressions.h Mon Oct 22 13:31:58 2007 @@ -32,16 +32,13 @@ /// SCEVConstant - This class represents a constant integer value. /// class SCEVConstant : public SCEV { + friend class ScalarEvolution; + ConstantInt *V; explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {} virtual ~SCEVConstant(); public: - /// get method - This just gets and returns a new SCEVConstant object. - /// - static SCEVHandle get(ConstantInt *V); - static SCEVHandle get(const APInt& Val); - ConstantInt *getValue() const { return V; } /// getValueRange - Return the tightest constant bounds that this value is @@ -59,7 +56,8 @@ virtual const Type *getType() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { return this; } @@ -78,15 +76,13 @@ /// to a smaller integer value. /// class SCEVTruncateExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVTruncateExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVTruncateExpr(); public: - /// get method - This just gets and returns a new SCEVTruncate object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -99,11 +95,12 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getTruncateExpr(H, Ty); } /// getValueRange - Return the tightest constant bounds that this value is @@ -125,15 +122,13 @@ /// integer value to a larger integer value. /// class SCEVZeroExtendExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVZeroExtendExpr(); public: - /// get method - This just gets and returns a new SCEVZeroExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -150,11 +145,12 @@ virtual ConstantRange getValueRange() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getZeroExtendExpr(H, Ty); } virtual void print(std::ostream &OS) const; @@ -172,15 +168,13 @@ /// integer value to a larger integer value. /// class SCEVSignExtendExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle Op; const Type *Ty; SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty); virtual ~SCEVSignExtendExpr(); public: - /// get method - This just gets and returns a new SCEVSignExtend object - /// - static SCEVHandle get(const SCEVHandle &Op, const Type *Ty); - const SCEVHandle &getOperand() const { return Op; } virtual const Type *getType() const { return Ty; } @@ -197,11 +191,12 @@ virtual ConstantRange getValueRange() const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H == Op) return this; - return get(H, Ty); + return SE.getSignExtendExpr(H, Ty); } virtual void print(std::ostream &OS) const; @@ -220,6 +215,8 @@ /// operators. /// class SCEVCommutativeExpr : public SCEV { + friend class ScalarEvolution; + std::vector Operands; protected: @@ -264,7 +261,8 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; virtual const char *getOperationStr() const = 0; @@ -285,29 +283,13 @@ /// SCEVAddExpr - This node represents an addition of some number of SCEVs. /// class SCEVAddExpr : public SCEVCommutativeExpr { + friend class ScalarEvolution; + SCEVAddExpr(const std::vector &ops) : SCEVCommutativeExpr(scAddExpr, ops) { } public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - - static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1, - const SCEVHandle &Op2) { - std::vector Ops; - Ops.push_back(Op0); - Ops.push_back(Op1); - Ops.push_back(Op2); - return get(Ops); - } - virtual const char *getOperationStr() const { return " + "; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -321,20 +303,13 @@ /// SCEVMulExpr - This node represents multiplication of some number of SCEVs. /// class SCEVMulExpr : public SCEVCommutativeExpr { + friend class ScalarEvolution; + SCEVMulExpr(const std::vector &ops) : SCEVCommutativeExpr(scMulExpr, ops) { } public: - static SCEVHandle get(std::vector &Ops); - - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) { - std::vector Ops; - Ops.push_back(LHS); - Ops.push_back(RHS); - return get(Ops); - } - virtual const char *getOperationStr() const { return " * "; } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -349,16 +324,14 @@ /// SCEVSDivExpr - This class represents a binary signed division operation. /// class SCEVSDivExpr : public SCEV { + friend class ScalarEvolution; + SCEVHandle LHS, RHS; SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs) : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {} virtual ~SCEVSDivExpr(); public: - /// get method - This just gets and returns a new SCEVSDiv object. - /// - static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS); - const SCEVHandle &getLHS() const { return LHS; } const SCEVHandle &getRHS() const { return RHS; } @@ -372,13 +345,14 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { - SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc); - SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc); + const SCEVHandle &Conc, + ScalarEvolution &SE) const { + SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); + SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (L == LHS && R == RHS) return this; else - return get(L, R); + return SE.getSDivExpr(L, R); } @@ -402,6 +376,8 @@ /// All operands of an AddRec are required to be loop invariant. /// class SCEVAddRecExpr : public SCEV { + friend class ScalarEvolution; + std::vector Operands; const Loop *L; @@ -413,16 +389,6 @@ } ~SCEVAddRecExpr(); public: - static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step, - const Loop *); - static SCEVHandle get(std::vector &Operands, - const Loop *); - static SCEVHandle get(const std::vector &Operands, - const Loop *L) { - std::vector NewOp(Operands); - return get(NewOp, L); - } - typedef std::vector::const_iterator op_iterator; op_iterator op_begin() const { return Operands.begin(); } op_iterator op_end() const { return Operands.end(); } @@ -436,10 +402,10 @@ /// getStepRecurrence - This method constructs and returns the recurrence /// indicating how much this expression steps by. If this is a polynomial /// of degree N, it returns a chrec of degree N-1. - SCEVHandle getStepRecurrence() const { + SCEVHandle getStepRecurrence(ScalarEvolution &SE) const { if (getNumOperands() == 2) return getOperand(1); - return SCEVAddRecExpr::get(std::vector(op_begin()+1,op_end()), - getLoop()); + return SE.getAddRecExpr(std::vector(op_begin()+1,op_end()), + getLoop()); } virtual bool hasComputableLoopEvolution(const Loop *QL) const { @@ -468,7 +434,7 @@ /// evaluateAtIteration - Return the value of this chain of recurrences at /// the specified iteration number. - SCEVHandle evaluateAtIteration(SCEVHandle It) const; + SCEVHandle evaluateAtIteration(SCEVHandle It, ScalarEvolution &SE) const; /// getNumIterationsInRange - Return the number of iterations of this loop /// that produce values in the specified constant range. Another way of @@ -476,10 +442,12 @@ /// value is not in the condition, thus computing the exit count. If the /// iteration count can't be computed, an instance of SCEVCouldNotCompute is /// returned. - SCEVHandle getNumIterationsInRange(ConstantRange Range) const; + SCEVHandle getNumIterationsInRange(ConstantRange Range, + ScalarEvolution &SE) const; SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const; + const SCEVHandle &Conc, + ScalarEvolution &SE) const; virtual void print(std::ostream &OS) const; void print(std::ostream *OS) const { if (OS) print(*OS); } @@ -497,20 +465,14 @@ /// value for the analysis. /// class SCEVUnknown : public SCEV { + friend class ScalarEvolution; + Value *V; SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {} protected: ~SCEVUnknown(); public: - /// get method - For SCEVUnknown, this just gets and returns a new - /// SCEVUnknown. - static SCEVHandle get(Value *V); - - /// getIntegerSCEV - Given an integer or FP type, create a constant for the - /// specified signed integer value and return a SCEV for the constant. - static SCEVHandle getIntegerSCEV(int Val, const Type *Ty); - Value *getValue() const { return V; } virtual bool isLoopInvariant(const Loop *L) const; @@ -519,7 +481,8 @@ } SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { if (&*Sym == this) return Conc; return this; } Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Mon Oct 22 13:31:58 2007 @@ -154,7 +154,8 @@ SCEVHandle SCEVCouldNotCompute:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { return this; } @@ -177,14 +178,14 @@ SCEVConstants->erase(V); } -SCEVHandle SCEVConstant::get(ConstantInt *V) { +SCEVHandle ScalarEvolution::getConstant(ConstantInt *V) { SCEVConstant *&R = (*SCEVConstants)[V]; if (R == 0) R = new SCEVConstant(V); return R; } -SCEVHandle SCEVConstant::get(const APInt& Val) { - return get(ConstantInt::get(Val)); +SCEVHandle ScalarEvolution::getConstant(const APInt& Val) { + return getConstant(ConstantInt::get(Val)); } ConstantRange SCEVConstant::getValueRange() const { @@ -298,9 +299,11 @@ SCEVHandle SCEVCommutativeExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc); + SCEVHandle H = + getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H != getOperand(i)) { std::vector NewOps; NewOps.reserve(getNumOperands()); @@ -309,12 +312,12 @@ NewOps.push_back(H); for (++i; i != e; ++i) NewOps.push_back(getOperand(i)-> - replaceSymbolicValuesWithConcrete(Sym, Conc)); + replaceSymbolicValuesWithConcrete(Sym, Conc, SE)); if (isa(this)) - return SCEVAddExpr::get(NewOps); + return SE.getAddExpr(NewOps); else if (isa(this)) - return SCEVMulExpr::get(NewOps); + return SE.getMulExpr(NewOps); else assert(0 && "Unknown commutative expr!"); } @@ -355,9 +358,11 @@ SCEVHandle SCEVAddRecExpr:: replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym, - const SCEVHandle &Conc) const { + const SCEVHandle &Conc, + ScalarEvolution &SE) const { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc); + SCEVHandle H = + getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc, SE); if (H != getOperand(i)) { std::vector NewOps; NewOps.reserve(getNumOperands()); @@ -366,9 +371,9 @@ NewOps.push_back(H); for (++i; i != e; ++i) NewOps.push_back(getOperand(i)-> - replaceSymbolicValuesWithConcrete(Sym, Conc)); + replaceSymbolicValuesWithConcrete(Sym, Conc, SE)); - return get(NewOps, L); + return SE.getAddRecExpr(NewOps, L); } } return this; @@ -480,7 +485,7 @@ /// getIntegerSCEV - Given an integer or FP type, create a constant for the /// specified signed integer value and return a SCEV for the constant. -SCEVHandle SCEVUnknown::getIntegerSCEV(int Val, const Type *Ty) { +SCEVHandle ScalarEvolution::getIntegerSCEV(int Val, const Type *Ty) { Constant *C; if (Val == 0) C = Constant::getNullValue(Ty); @@ -489,42 +494,45 @@ APFloat::IEEEdouble, Val)); else C = ConstantInt::get(Ty, Val); - return SCEVUnknown::get(C); + return getUnknown(C); } /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the /// input value to the specified type. If the type must be extended, it is zero /// extended. -static SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty) { +static SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty, + ScalarEvolution &SE) { const Type *SrcTy = V->getType(); assert(SrcTy->isInteger() && Ty->isInteger() && "Cannot truncate or zero extend with non-integer arguments!"); if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits()) return V; // No conversion if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()) - return SCEVTruncateExpr::get(V, Ty); - return SCEVZeroExtendExpr::get(V, Ty); + return SE.getTruncateExpr(V, Ty); + return SE.getZeroExtendExpr(V, Ty); } /// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V /// -SCEVHandle SCEV::getNegativeSCEV(const SCEVHandle &V) { +SCEVHandle ScalarEvolution::getNegativeSCEV(const SCEVHandle &V) { if (SCEVConstant *VC = dyn_cast(V)) - return SCEVUnknown::get(ConstantExpr::getNeg(VC->getValue())); + return getUnknown(ConstantExpr::getNeg(VC->getValue())); - return SCEVMulExpr::get(V, SCEVUnknown::getIntegerSCEV(-1, V->getType())); + return getMulExpr(V, getIntegerSCEV(-1, V->getType())); } /// getMinusSCEV - Return a SCEV corresponding to LHS - RHS. /// -SCEVHandle SCEV::getMinusSCEV(const SCEVHandle &LHS, const SCEVHandle &RHS) { +SCEVHandle ScalarEvolution::getMinusSCEV(const SCEVHandle &LHS, + const SCEVHandle &RHS) { // X - Y --> X + -Y - return SCEVAddExpr::get(LHS, SCEV::getNegativeSCEV(RHS)); + return getAddExpr(LHS, getNegativeSCEV(RHS)); } /// PartialFact - Compute V!/(V-NumSteps)! -static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps) { +static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps, + ScalarEvolution &SE) { // Handle this case efficiently, it is common to have constant iteration // counts while computing loop exit values. if (SCEVConstant *SC = dyn_cast(V)) { @@ -532,17 +540,17 @@ APInt Result(Val.getBitWidth(), 1); for (; NumSteps; --NumSteps) Result *= Val-(NumSteps-1); - return SCEVConstant::get(Result); + return SE.getConstant(Result); } const Type *Ty = V->getType(); if (NumSteps == 0) - return SCEVUnknown::getIntegerSCEV(1, Ty); + return SE.getIntegerSCEV(1, Ty); SCEVHandle Result = V; for (unsigned i = 1; i != NumSteps; ++i) - Result = SCEVMulExpr::get(Result, SCEV::getMinusSCEV(V, - SCEVUnknown::getIntegerSCEV(i, Ty))); + Result = SE.getMulExpr(Result, SE.getMinusSCEV(V, + SE.getIntegerSCEV(i, Ty))); return Result; } @@ -557,16 +565,17 @@ /// FIXME/VERIFY: I don't trust that this is correct in the face of overflow. /// Is the binomial equation safe using modular arithmetic?? /// -SCEVHandle SCEVAddRecExpr::evaluateAtIteration(SCEVHandle It) const { +SCEVHandle SCEVAddRecExpr::evaluateAtIteration(SCEVHandle It, + ScalarEvolution &SE) const { SCEVHandle Result = getStart(); int Divisor = 1; const Type *Ty = It->getType(); for (unsigned i = 1, e = getNumOperands(); i != e; ++i) { - SCEVHandle BC = PartialFact(It, i); + SCEVHandle BC = PartialFact(It, i, SE); Divisor *= i; - SCEVHandle Val = SCEVSDivExpr::get(SCEVMulExpr::get(BC, getOperand(i)), - SCEVUnknown::getIntegerSCEV(Divisor,Ty)); - Result = SCEVAddExpr::get(Result, Val); + SCEVHandle Val = SE.getSDivExpr(SE.getMulExpr(BC, getOperand(i)), + SE.getIntegerSCEV(Divisor,Ty)); + Result = SE.getAddExpr(Result, Val); } return Result; } @@ -576,9 +585,9 @@ // SCEV Expression folder implementations //===----------------------------------------------------------------------===// -SCEVHandle SCEVTruncateExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getTruncateExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getTrunc(SC->getValue(), Ty)); // If the input value is a chrec scev made out of constants, truncate @@ -588,11 +597,11 @@ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) // FIXME: This should allow truncation of other expression types! if (isa(AddRec->getOperand(i))) - Operands.push_back(get(AddRec->getOperand(i), Ty)); + Operands.push_back(getTruncateExpr(AddRec->getOperand(i), Ty)); else break; if (Operands.size() == AddRec->getNumOperands()) - return SCEVAddRecExpr::get(Operands, AddRec->getLoop()); + return getAddRecExpr(Operands, AddRec->getLoop()); } SCEVTruncateExpr *&Result = (*SCEVTruncates)[std::make_pair(Op, Ty)]; @@ -600,9 +609,9 @@ return Result; } -SCEVHandle SCEVZeroExtendExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getZeroExtendExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getZExt(SC->getValue(), Ty)); // FIXME: If the input value is a chrec scev, and we can prove that the value @@ -615,9 +624,9 @@ return Result; } -SCEVHandle SCEVSignExtendExpr::get(const SCEVHandle &Op, const Type *Ty) { +SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, const Type *Ty) { if (SCEVConstant *SC = dyn_cast(Op)) - return SCEVUnknown::get( + return getUnknown( ConstantExpr::getSExt(SC->getValue(), Ty)); // FIXME: If the input value is a chrec scev, and we can prove that the value @@ -631,7 +640,7 @@ } // get - Get a canonical add expression, or something simpler if possible. -SCEVHandle SCEVAddExpr::get(std::vector &Ops) { +SCEVHandle ScalarEvolution::getAddExpr(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty add!"); if (Ops.size() == 1) return Ops[0]; @@ -648,7 +657,7 @@ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() + RHSC->getValue()->getValue()); if (ConstantInt *CI = dyn_cast(Fold)) { - Ops[0] = SCEVConstant::get(CI); + Ops[0] = getConstant(CI); Ops.erase(Ops.begin()+1); // Erase the folded element if (Ops.size() == 1) return Ops[0]; LHSC = cast(Ops[0]); @@ -677,13 +686,13 @@ if (Ops[i] == Ops[i+1]) { // X + Y + Y --> X + Y*2 // Found a match, merge the two values into a multiply, and add any // remaining values to the result. - SCEVHandle Two = SCEVUnknown::getIntegerSCEV(2, Ty); - SCEVHandle Mul = SCEVMulExpr::get(Ops[i], Two); + SCEVHandle Two = getIntegerSCEV(2, Ty); + SCEVHandle Mul = getMulExpr(Ops[i], Two); if (Ops.size() == 2) return Mul; Ops.erase(Ops.begin()+i, Ops.begin()+i+2); Ops.push_back(Mul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Now we know the first non-constant operand. Skip past any cast SCEVs. @@ -705,7 +714,7 @@ // and they are not necessarily sorted. Recurse to resort and resimplify // any operands we just aquired. if (DeletedAdd) - return get(Ops); + return getAddExpr(Ops); } // Skip over the add expression until we get to a multiply. @@ -728,11 +737,11 @@ // Y*Z term. std::vector MulOps(Mul->op_begin(), Mul->op_end()); MulOps.erase(MulOps.begin()+MulOp); - InnerMul = SCEVMulExpr::get(MulOps); + InnerMul = getMulExpr(MulOps); } - SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, Ty); - SCEVHandle AddOne = SCEVAddExpr::get(InnerMul, One); - SCEVHandle OuterMul = SCEVMulExpr::get(AddOne, Ops[AddOp]); + SCEVHandle One = getIntegerSCEV(1, Ty); + SCEVHandle AddOne = getAddExpr(InnerMul, One); + SCEVHandle OuterMul = getMulExpr(AddOne, Ops[AddOp]); if (Ops.size() == 2) return OuterMul; if (AddOp < Idx) { Ops.erase(Ops.begin()+AddOp); @@ -742,7 +751,7 @@ Ops.erase(Ops.begin()+AddOp-1); } Ops.push_back(OuterMul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Check this multiply against other multiplies being added together. @@ -760,22 +769,22 @@ if (Mul->getNumOperands() != 2) { std::vector MulOps(Mul->op_begin(), Mul->op_end()); MulOps.erase(MulOps.begin()+MulOp); - InnerMul1 = SCEVMulExpr::get(MulOps); + InnerMul1 = getMulExpr(MulOps); } SCEVHandle InnerMul2 = OtherMul->getOperand(OMulOp == 0); if (OtherMul->getNumOperands() != 2) { std::vector MulOps(OtherMul->op_begin(), OtherMul->op_end()); MulOps.erase(MulOps.begin()+OMulOp); - InnerMul2 = SCEVMulExpr::get(MulOps); + InnerMul2 = getMulExpr(MulOps); } - SCEVHandle InnerMulSum = SCEVAddExpr::get(InnerMul1,InnerMul2); - SCEVHandle OuterMul = SCEVMulExpr::get(MulOpSCEV, InnerMulSum); + SCEVHandle InnerMulSum = getAddExpr(InnerMul1,InnerMul2); + SCEVHandle OuterMul = getMulExpr(MulOpSCEV, InnerMulSum); if (Ops.size() == 2) return OuterMul; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherMulIdx-1); Ops.push_back(OuterMul); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } } } @@ -806,9 +815,9 @@ LIOps.push_back(AddRec->getStart()); std::vector AddRecOps(AddRec->op_begin(), AddRec->op_end()); - AddRecOps[0] = SCEVAddExpr::get(LIOps); + AddRecOps[0] = getAddExpr(LIOps); - SCEVHandle NewRec = SCEVAddRecExpr::get(AddRecOps, AddRec->getLoop()); + SCEVHandle NewRec = getAddRecExpr(AddRecOps, AddRec->getLoop()); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -818,7 +827,7 @@ Ops[i] = NewRec; break; } - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } // Okay, if there weren't any loop invariants to be folded, check to see if @@ -837,16 +846,16 @@ OtherAddRec->op_end()); break; } - NewOps[i] = SCEVAddExpr::get(NewOps[i], OtherAddRec->getOperand(i)); + NewOps[i] = getAddExpr(NewOps[i], OtherAddRec->getOperand(i)); } - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop()); + SCEVHandle NewAddRec = getAddRecExpr(NewOps, AddRec->getLoop()); if (Ops.size() == 2) return NewAddRec; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherIdx-1); Ops.push_back(NewAddRec); - return SCEVAddExpr::get(Ops); + return getAddExpr(Ops); } } @@ -864,7 +873,7 @@ } -SCEVHandle SCEVMulExpr::get(std::vector &Ops) { +SCEVHandle ScalarEvolution::getMulExpr(std::vector &Ops) { assert(!Ops.empty() && "Cannot get empty mul!"); // Sort by complexity, this groups all similar expression types together. @@ -879,8 +888,8 @@ if (SCEVAddExpr *Add = dyn_cast(Ops[1])) if (Add->getNumOperands() == 2 && isa(Add->getOperand(0))) - return SCEVAddExpr::get(SCEVMulExpr::get(LHSC, Add->getOperand(0)), - SCEVMulExpr::get(LHSC, Add->getOperand(1))); + return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), + getMulExpr(LHSC, Add->getOperand(1))); ++Idx; @@ -889,7 +898,7 @@ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() * RHSC->getValue()->getValue()); if (ConstantInt *CI = dyn_cast(Fold)) { - Ops[0] = SCEVConstant::get(CI); + Ops[0] = getConstant(CI); Ops.erase(Ops.begin()+1); // Erase the folded element if (Ops.size() == 1) return Ops[0]; LHSC = cast(Ops[0]); @@ -933,7 +942,7 @@ // and they are not necessarily sorted. Recurse to resort and resimplify // any operands we just aquired. if (DeletedMul) - return get(Ops); + return getMulExpr(Ops); } // If there are any add recurrences in the operands list, see if any other @@ -963,16 +972,16 @@ if (LIOps.size() == 1) { SCEV *Scale = LIOps[0]; for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) - NewOps.push_back(SCEVMulExpr::get(Scale, AddRec->getOperand(i))); + NewOps.push_back(getMulExpr(Scale, AddRec->getOperand(i))); } else { for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) { std::vector MulOps(LIOps); MulOps.push_back(AddRec->getOperand(i)); - NewOps.push_back(SCEVMulExpr::get(MulOps)); + NewOps.push_back(getMulExpr(MulOps)); } } - SCEVHandle NewRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop()); + SCEVHandle NewRec = getAddRecExpr(NewOps, AddRec->getLoop()); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -983,7 +992,7 @@ Ops[i] = NewRec; break; } - return SCEVMulExpr::get(Ops); + return getMulExpr(Ops); } // Okay, if there weren't any loop invariants to be folded, check to see if @@ -996,21 +1005,21 @@ if (AddRec->getLoop() == OtherAddRec->getLoop()) { // F * G --> {A,+,B} * {C,+,D} --> {A*C,+,F*D + G*B + B*D} SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; - SCEVHandle NewStart = SCEVMulExpr::get(F->getStart(), + SCEVHandle NewStart = getMulExpr(F->getStart(), G->getStart()); - SCEVHandle B = F->getStepRecurrence(); - SCEVHandle D = G->getStepRecurrence(); - SCEVHandle NewStep = SCEVAddExpr::get(SCEVMulExpr::get(F, D), - SCEVMulExpr::get(G, B), - SCEVMulExpr::get(B, D)); - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewStart, NewStep, - F->getLoop()); + SCEVHandle B = F->getStepRecurrence(*this); + SCEVHandle D = G->getStepRecurrence(*this); + SCEVHandle NewStep = getAddExpr(getMulExpr(F, D), + getMulExpr(G, B), + getMulExpr(B, D)); + SCEVHandle NewAddRec = getAddRecExpr(NewStart, NewStep, + F->getLoop()); if (Ops.size() == 2) return NewAddRec; Ops.erase(Ops.begin()+Idx); Ops.erase(Ops.begin()+OtherIdx-1); Ops.push_back(NewAddRec); - return SCEVMulExpr::get(Ops); + return getMulExpr(Ops); } } @@ -1028,17 +1037,17 @@ return Result; } -SCEVHandle SCEVSDivExpr::get(const SCEVHandle &LHS, const SCEVHandle &RHS) { +SCEVHandle ScalarEvolution::getSDivExpr(const SCEVHandle &LHS, const SCEVHandle &RHS) { if (SCEVConstant *RHSC = dyn_cast(RHS)) { if (RHSC->getValue()->equalsInt(1)) return LHS; // X sdiv 1 --> x if (RHSC->getValue()->isAllOnesValue()) - return SCEV::getNegativeSCEV(LHS); // X sdiv -1 --> -x + return getNegativeSCEV(LHS); // X sdiv -1 --> -x if (SCEVConstant *LHSC = dyn_cast(LHS)) { Constant *LHSCV = LHSC->getValue(); Constant *RHSCV = RHSC->getValue(); - return SCEVUnknown::get(ConstantExpr::getSDiv(LHSCV, RHSCV)); + return getUnknown(ConstantExpr::getSDiv(LHSCV, RHSCV)); } } @@ -1052,7 +1061,7 @@ /// SCEVAddRecExpr::get - Get a add recurrence expression for the /// specified loop. Simplify the expression as much as possible. -SCEVHandle SCEVAddRecExpr::get(const SCEVHandle &Start, +SCEVHandle ScalarEvolution::getAddRecExpr(const SCEVHandle &Start, const SCEVHandle &Step, const Loop *L) { std::vector Operands; Operands.push_back(Start); @@ -1060,23 +1069,23 @@ if (StepChrec->getLoop() == L) { Operands.insert(Operands.end(), StepChrec->op_begin(), StepChrec->op_end()); - return get(Operands, L); + return getAddRecExpr(Operands, L); } Operands.push_back(Step); - return get(Operands, L); + return getAddRecExpr(Operands, L); } /// SCEVAddRecExpr::get - Get a add recurrence expression for the /// specified loop. Simplify the expression as much as possible. -SCEVHandle SCEVAddRecExpr::get(std::vector &Operands, +SCEVHandle ScalarEvolution::getAddRecExpr(std::vector &Operands, const Loop *L) { if (Operands.size() == 1) return Operands[0]; if (SCEVConstant *StepC = dyn_cast(Operands.back())) if (StepC->getValue()->isZero()) { Operands.pop_back(); - return get(Operands, L); // { X,+,0 } --> X + return getAddRecExpr(Operands, L); // { X,+,0 } --> X } SCEVAddRecExpr *&Result = @@ -1086,9 +1095,9 @@ return Result; } -SCEVHandle SCEVUnknown::get(Value *V) { +SCEVHandle ScalarEvolution::getUnknown(Value *V) { if (ConstantInt *CI = dyn_cast(V)) - return SCEVConstant::get(CI); + return getConstant(CI); SCEVUnknown *&Result = (*SCEVUnknowns)[V]; if (Result == 0) Result = new SCEVUnknown(V); return Result; @@ -1104,6 +1113,9 @@ /// namespace { struct VISIBILITY_HIDDEN ScalarEvolutionsImpl { + /// SE - A reference to the public ScalarEvolution object. + ScalarEvolution &SE; + /// F - The function we are analyzing. /// Function &F; @@ -1132,8 +1144,8 @@ std::map ConstantEvolutionLoopExitValue; public: - ScalarEvolutionsImpl(Function &f, LoopInfo &li) - : F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} + ScalarEvolutionsImpl(ScalarEvolution &se, Function &f, LoopInfo &li) + : SE(se), F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {} /// getSCEV - Return an existing SCEV if it exists, otherwise analyze the /// expression and create a new one. @@ -1289,7 +1301,7 @@ if (SI == Scalars.end()) return; SCEVHandle NV = - SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal); + SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal, SE); if (NV == SI->second) return; // No change. SI->second = NV; // Update the scalars map! @@ -1314,7 +1326,7 @@ unsigned BackEdge = IncomingEdge^1; // While we are analyzing this PHI node, handle its value symbolically. - SCEVHandle SymbolicName = SCEVUnknown::get(PN); + SCEVHandle SymbolicName = SE.getUnknown(PN); assert(Scalars.find(PN) == Scalars.end() && "PHI node already processed?"); Scalars.insert(std::make_pair(PN, SymbolicName)); @@ -1345,7 +1357,7 @@ for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i) if (i != FoundIndex) Ops.push_back(Add->getOperand(i)); - SCEVHandle Accum = SCEVAddExpr::get(Ops); + SCEVHandle Accum = SE.getAddExpr(Ops); // This is not a valid addrec if the step amount is varying each // loop iteration, but is not itself an addrec in this loop. @@ -1353,7 +1365,7 @@ (isa(Accum) && cast(Accum)->getLoop() == L)) { SCEVHandle StartVal = getSCEV(PN->getIncomingValue(IncomingEdge)); - SCEVHandle PHISCEV = SCEVAddRecExpr::get(StartVal, Accum, L); + SCEVHandle PHISCEV = SE.getAddRecExpr(StartVal, Accum, L); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and update all of the @@ -1375,10 +1387,10 @@ // If StartVal = j.start - j.stride, we can use StartVal as the // initial step of the addrec evolution. - if (StartVal == SCEV::getMinusSCEV(AddRec->getOperand(0), - AddRec->getOperand(1))) { + if (StartVal == SE.getMinusSCEV(AddRec->getOperand(0), + AddRec->getOperand(1))) { SCEVHandle PHISCEV = - SCEVAddRecExpr::get(StartVal, AddRec->getOperand(1), L); + SE.getAddRecExpr(StartVal, AddRec->getOperand(1), L); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and update all of the @@ -1395,7 +1407,7 @@ } // If it's not a loop phi, we can't handle it yet. - return SCEVUnknown::get(PN); + return SE.getUnknown(PN); } /// GetConstantFactor - Determine the largest constant factor that S has. For @@ -1464,19 +1476,19 @@ if (Instruction *I = dyn_cast(V)) { switch (I->getOpcode()) { case Instruction::Add: - return SCEVAddExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getAddExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); case Instruction::Mul: - return SCEVMulExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getMulExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); case Instruction::SDiv: - return SCEVSDivExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getSDivExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); break; case Instruction::Sub: - return SCEV::getMinusSCEV(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + 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 @@ -1488,8 +1500,8 @@ "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 +. - return SCEVAddExpr::get(LHS, - getSCEV(I->getOperand(1))); + return SE.getAddExpr(LHS, + getSCEV(I->getOperand(1))); } } break; @@ -1498,8 +1510,8 @@ // Instcombine turns add of signbit into xor as a strength reduction step. if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { if (CI->getValue().isSignBit()) - return SCEVAddExpr::get(getSCEV(I->getOperand(0)), - getSCEV(I->getOperand(1))); + return SE.getAddExpr(getSCEV(I->getOperand(0)), + getSCEV(I->getOperand(1))); } break; @@ -1509,18 +1521,18 @@ uint32_t BitWidth = cast(V->getType())->getBitWidth(); Constant *X = ConstantInt::get( APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth))); - return SCEVMulExpr::get(getSCEV(I->getOperand(0)), getSCEV(X)); + return SE.getMulExpr(getSCEV(I->getOperand(0)), getSCEV(X)); } break; case Instruction::Trunc: - return SCEVTruncateExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getTruncateExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::ZExt: - return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getZeroExtendExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::SExt: - return SCEVSignExtendExpr::get(getSCEV(I->getOperand(0)), I->getType()); + return SE.getSignExtendExpr(getSCEV(I->getOperand(0)), I->getType()); case Instruction::BitCast: // BitCasts are no-op casts so we just eliminate the cast. @@ -1537,7 +1549,7 @@ } } - return SCEVUnknown::get(V); + return SE.getUnknown(V); } @@ -1673,7 +1685,7 @@ ConstantRange CompRange( ICmpInst::makeConstantRange(Cond, CompVal->getValue())); - SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange); + SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange, SE); if (!isa(Ret)) return Ret; } } @@ -1681,13 +1693,13 @@ switch (Cond) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) - SCEVHandle TC = HowFarToZero(SCEV::getMinusSCEV(LHS, RHS), L); + SCEVHandle TC = HowFarToZero(SE.getMinusSCEV(LHS, RHS), L); if (!isa(TC)) return TC; break; } case ICmpInst::ICMP_EQ: { // Convert to: while (X-Y == 0) // while (X == Y) - SCEVHandle TC = HowFarToNonZero(SCEV::getMinusSCEV(LHS, RHS), L); + SCEVHandle TC = HowFarToNonZero(SE.getMinusSCEV(LHS, RHS), L); if (!isa(TC)) return TC; break; } @@ -1697,8 +1709,8 @@ break; } case ICmpInst::ICMP_SGT: { - SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS), - SCEV::getNegativeSCEV(RHS), L, true); + SCEVHandle TC = HowManyLessThans(SE.getNegativeSCEV(LHS), + SE.getNegativeSCEV(RHS), L, true); if (!isa(TC)) return TC; break; } @@ -1708,8 +1720,8 @@ break; } case ICmpInst::ICMP_UGT: { - SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS), - SCEV::getNegativeSCEV(RHS), L, false); + SCEVHandle TC = HowManyLessThans(SE.getNegativeSCEV(LHS), + SE.getNegativeSCEV(RHS), L, false); if (!isa(TC)) return TC; break; } @@ -1729,9 +1741,10 @@ } static ConstantInt * -EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C) { - SCEVHandle InVal = SCEVConstant::get(C); - SCEVHandle Val = AddRec->evaluateAtIteration(InVal); +EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C, + ScalarEvolution &SE) { + SCEVHandle InVal = SE.getConstant(C); + SCEVHandle Val = AddRec->evaluateAtIteration(InVal, SE); assert(isa(Val) && "Evaluation of SCEV at constant didn't fold correctly?"); return cast(Val)->getValue(); @@ -1823,7 +1836,7 @@ for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) { ConstantInt *ItCst = ConstantInt::get(IdxExpr->getType(), IterationNum); - ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst); + ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst, SE); // Form the GEP offset. Indexes[VarIdxNum] = Val; @@ -1841,7 +1854,7 @@ << "***\n"; #endif ++NumArrayLenItCounts; - return SCEVConstant::get(ItCst); // Found terminating iteration! + return SE.getConstant(ItCst); // Found terminating iteration! } } return UnknownValue; @@ -2012,7 +2025,7 @@ if (CondVal->getValue() == uint64_t(ExitWhen)) { ConstantEvolutionLoopExitValue[PN] = PHIVal; ++NumBruteForceTripCountsComputed; - return SCEVConstant::get(ConstantInt::get(Type::Int32Ty, IterationNum)); + return SE.getConstant(ConstantInt::get(Type::Int32Ty, IterationNum)); } // Compute the value of the PHI node for the next iteration. @@ -2053,7 +2066,7 @@ Constant *RV = getConstantEvolutionLoopExitValue(PN, ICC->getValue()->getValue(), LI); - if (RV) return SCEVUnknown::get(RV); + if (RV) return SE.getUnknown(RV); } } @@ -2087,7 +2100,7 @@ } } Constant *C =ConstantFoldInstOperands(I, &Operands[0], Operands.size()); - return SCEVUnknown::get(C); + return SE.getUnknown(C); } } @@ -2113,9 +2126,9 @@ NewOps.push_back(OpAtScope); } if (isa(Comm)) - return SCEVAddExpr::get(NewOps); + return SE.getAddExpr(NewOps); assert(isa(Comm) && "Only know about add and mul!"); - return SCEVMulExpr::get(NewOps); + return SE.getMulExpr(NewOps); } } // If we got here, all operands are loop invariant. @@ -2129,7 +2142,7 @@ if (RHS == UnknownValue) return RHS; if (LHS == Div->getLHS() && RHS == Div->getRHS()) return Div; // must be loop invariant - return SCEVSDivExpr::get(LHS, RHS); + return SE.getSDivExpr(LHS, RHS); } // If this is a loop recurrence for a loop that does not contain L, then we @@ -2141,17 +2154,17 @@ SCEVHandle IterationCount = getIterationCount(AddRec->getLoop()); if (IterationCount == UnknownValue) return UnknownValue; IterationCount = getTruncateOrZeroExtend(IterationCount, - AddRec->getType()); + AddRec->getType(), SE); // If the value is affine, simplify the expression evaluation to just // Start + Step*IterationCount. if (AddRec->isAffine()) - return SCEVAddExpr::get(AddRec->getStart(), - SCEVMulExpr::get(IterationCount, - AddRec->getOperand(1))); + return SE.getAddExpr(AddRec->getStart(), + SE.getMulExpr(IterationCount, + AddRec->getOperand(1))); // Otherwise, evaluate it the hard way. - return AddRec->evaluateAtIteration(IterationCount); + return AddRec->evaluateAtIteration(IterationCount, SE); } return UnknownValue; } @@ -2166,7 +2179,7 @@ /// might be the same) or two SCEVCouldNotCompute objects. /// static std::pair -SolveQuadraticEquation(const SCEVAddRecExpr *AddRec) { +SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!"); SCEVConstant *LC = dyn_cast(AddRec->getOperand(0)); SCEVConstant *MC = dyn_cast(AddRec->getOperand(1)); @@ -2212,8 +2225,8 @@ ConstantInt *Solution1 = ConstantInt::get((NegB + SqrtVal).sdiv(TwoA)); ConstantInt *Solution2 = ConstantInt::get((NegB - SqrtVal).sdiv(TwoA)); - return std::make_pair(SCEVConstant::get(Solution1), - SCEVConstant::get(Solution2)); + return std::make_pair(SE.getConstant(Solution1), + SE.getConstant(Solution2)); } // end APIntOps namespace } @@ -2248,7 +2261,7 @@ // FIXME: We should add DivExpr and RemExpr operations to our AST. if (SCEVConstant *StepC = dyn_cast(Step)) { if (StepC->getValue()->equalsInt(1)) // N % 1 == 0 - return SCEV::getNegativeSCEV(Start); // 0 - Start/1 == -Start + return SE.getNegativeSCEV(Start); // 0 - Start/1 == -Start if (StepC->getValue()->isAllOnesValue()) // N % -1 == 0 return Start; // 0 - Start/-1 == Start @@ -2259,14 +2272,14 @@ Constant *Rem = ConstantExpr::getSRem(StartNegC, StepC->getValue()); if (Rem->isNullValue()) { Constant *Result =ConstantExpr::getSDiv(StartNegC,StepC->getValue()); - return SCEVUnknown::get(Result); + return SE.getUnknown(Result); } } } } else if (AddRec->isQuadratic() && AddRec->getType()->isInteger()) { // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of // the quadratic equation to solve it. - std::pair Roots = SolveQuadraticEquation(AddRec); + std::pair Roots = SolveQuadraticEquation(AddRec, SE); SCEVConstant *R1 = dyn_cast(Roots.first); SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { @@ -2284,7 +2297,7 @@ // We can only use this value if the chrec ends up with an exact zero // value at this index. When solving for "X*X != 5", for example, we // should not accept a root of 2. - SCEVHandle Val = AddRec->evaluateAtIteration(R1); + SCEVHandle Val = AddRec->evaluateAtIteration(R1, SE); if (SCEVConstant *EvalVal = dyn_cast(Val)) if (EvalVal->getValue()->isZero()) return R1; // We found a quadratic root! @@ -2333,16 +2346,17 @@ if (AddRec->isAffine()) { // FORNOW: We only support unit strides. - SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, RHS->getType()); + 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 + // 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. @@ -2403,15 +2417,15 @@ if (RHS != getSCEV(PreCondRHS)) return UnknownValue; // Not a comparison against 'm'. - if (SCEV::getMinusSCEV(AddRec->getOperand(0), One) + 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: " - // << // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n"; - return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)); + // << // *SE.getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n"; + return SE.getMinusSCEV(RHS, AddRec->getOperand(0)); } else return UnknownValue; @@ -2425,7 +2439,8 @@ /// this is that it returns the first iteration number where the value is not in /// the condition, thus computing the exit count. If the iteration count can't /// be computed, an instance of SCEVCouldNotCompute is returned. -SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const { +SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range, + ScalarEvolution &SE) const { if (Range.isFullSet()) // Infinite loop. return new SCEVCouldNotCompute(); @@ -2433,11 +2448,11 @@ if (SCEVConstant *SC = dyn_cast(getStart())) if (!SC->getValue()->isZero()) { std::vector Operands(op_begin(), op_end()); - Operands[0] = SCEVUnknown::getIntegerSCEV(0, SC->getType()); - SCEVHandle Shifted = SCEVAddRecExpr::get(Operands, getLoop()); + Operands[0] = SE.getIntegerSCEV(0, SC->getType()); + SCEVHandle Shifted = SE.getAddRecExpr(Operands, getLoop()); if (SCEVAddRecExpr *ShiftedAddRec = dyn_cast(Shifted)) return ShiftedAddRec->getNumIterationsInRange( - Range.subtract(SC->getValue()->getValue())); + Range.subtract(SC->getValue()->getValue()), SE); // This is strange and shouldn't happen. return new SCEVCouldNotCompute(); } @@ -2455,7 +2470,7 @@ // First check to see if the range contains zero. If not, the first // iteration exits. if (!Range.contains(APInt(getBitWidth(),0))) - return SCEVConstant::get(ConstantInt::get(getType(),0)); + return SE.getConstant(ConstantInt::get(getType(),0)); if (isAffine()) { // If this is an affine expression then we have this situation: @@ -2476,28 +2491,28 @@ // Evaluate at the exit value. If we really did fall out of the valid // range, then we computed our trip count, otherwise wrap around or other // things must have happened. - ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue); + ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue, SE); if (Range.contains(Val->getValue())) return new SCEVCouldNotCompute(); // Something strange happened // Ensure that the previous value is in the range. This is a sanity check. assert(Range.contains( EvaluateConstantChrecAtConstant(this, - ConstantInt::get(ExitVal - One))->getValue()) && + ConstantInt::get(ExitVal - One), SE)->getValue()) && "Linear scev computation is off in a bad way!"); - return SCEVConstant::get(ExitValue); + return SE.getConstant(ExitValue); } else if (isQuadratic()) { // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of the // quadratic equation to solve it. To do this, we must frame our problem in // terms of figuring out when zero is crossed, instead of when // Range.getUpper() is crossed. std::vector NewOps(op_begin(), op_end()); - NewOps[0] = SCEV::getNegativeSCEV(SCEVConstant::get(Range.getUpper())); - SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, getLoop()); + NewOps[0] = SE.getNegativeSCEV(SE.getConstant(Range.getUpper())); + SCEVHandle NewAddRec = SE.getAddRecExpr(NewOps, getLoop()); // Next, solve the constructed addrec std::pair Roots = - SolveQuadraticEquation(cast(NewAddRec)); + SolveQuadraticEquation(cast(NewAddRec), SE); SCEVConstant *R1 = dyn_cast(Roots.first); SCEVConstant *R2 = dyn_cast(Roots.second); if (R1) { @@ -2512,21 +2527,22 @@ // not be in the range, but the previous one should be. When solving // for "X*X < 5", for example, we should not return a root of 2. ConstantInt *R1Val = EvaluateConstantChrecAtConstant(this, - R1->getValue()); + R1->getValue(), + SE); if (Range.contains(R1Val->getValue())) { // The next iteration must be out of the range... ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()+1); - R1Val = EvaluateConstantChrecAtConstant(this, NextVal); + R1Val = EvaluateConstantChrecAtConstant(this, NextVal, SE); if (!Range.contains(R1Val->getValue())) - return SCEVConstant::get(NextVal); + return SE.getConstant(NextVal); return new SCEVCouldNotCompute(); // Something strange happened } // If R1 was not in the range, then it is a good return value. Make // sure that R1-1 WAS in the range though, just in case. ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()-1); - R1Val = EvaluateConstantChrecAtConstant(this, NextVal); + R1Val = EvaluateConstantChrecAtConstant(this, NextVal, SE); if (Range.contains(R1Val->getValue())) return R1; return new SCEVCouldNotCompute(); // Something strange happened @@ -2543,13 +2559,13 @@ ConstantInt *EndVal = TestVal; // Stop when we wrap around. do { ++NumBruteForceEvaluations; - SCEVHandle Val = evaluateAtIteration(SCEVConstant::get(TestVal)); + SCEVHandle Val = evaluateAtIteration(SE.getConstant(TestVal), SE); if (!isa(Val)) // This shouldn't happen. return new SCEVCouldNotCompute(); // Check to see if we found the value! if (!Range.contains(cast(Val)->getValue()->getValue())) - return SCEVConstant::get(TestVal); + return SE.getConstant(TestVal); // Increment to test the next index. TestVal = ConstantInt::get(TestVal->getValue()+1); @@ -2565,7 +2581,7 @@ //===----------------------------------------------------------------------===// bool ScalarEvolution::runOnFunction(Function &F) { - Impl = new ScalarEvolutionsImpl(F, getAnalysis()); + Impl = new ScalarEvolutionsImpl(*this, F, getAnalysis()); return false; } Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original) +++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Mon Oct 22 13:31:58 2007 @@ -128,8 +128,8 @@ !cast(S->getStart())->getValue()->isZero()) { Value *Start = expand(S->getStart()); std::vector NewOps(S->op_begin(), S->op_end()); - NewOps[0] = SCEVUnknown::getIntegerSCEV(0, Ty); - Value *Rest = expand(SCEVAddRecExpr::get(NewOps, L)); + NewOps[0] = SE.getIntegerSCEV(0, Ty); + Value *Rest = expand(SE.getAddRecExpr(NewOps, L)); // FIXME: look for an existing add to use. return InsertBinop(Instruction::Add, Rest, Start, InsertPt); @@ -137,7 +137,7 @@ // {0,+,1} --> Insert a canonical induction variable into the loop! if (S->getNumOperands() == 2 && - S->getOperand(1) == SCEVUnknown::getIntegerSCEV(1, Ty)) { + S->getOperand(1) == SE.getIntegerSCEV(1, Ty)) { // Create and insert the PHI node for the induction variable in the // specified loop. BasicBlock *Header = L->getHeader(); @@ -200,9 +200,9 @@ // folders, then expandCodeFor the closed form. This allows the folders to // simplify the expression without having to build a bunch of special code // into this folder. - SCEVHandle IH = SCEVUnknown::get(I); // Get I as a "symbolic" SCEV. + SCEVHandle IH = SE.getUnknown(I); // Get I as a "symbolic" SCEV. - SCEVHandle V = S->evaluateAtIteration(IH); + SCEVHandle V = S->evaluateAtIteration(IH, SE); //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n"; return expand(V); Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Mon Oct 22 13:31:58 2007 @@ -268,7 +268,7 @@ // backedge actually branches to the loop header. This is one less than the // number of times the loop executes, so add one to it. ConstantInt *OneC = ConstantInt::get(IterationCount->getType(), 1); - TripCount = SCEVAddExpr::get(IterationCount, SCEVConstant::get(OneC)); + TripCount = SE->getAddExpr(IterationCount, SE->getConstant(OneC)); IndVar = L->getCanonicalInductionVariableIncrement(); } else { // We have to use the preincremented value... @@ -524,9 +524,9 @@ if (!isa(IterationCount)) { if (IterationCount->getType()->getPrimitiveSizeInBits() < LargestType->getPrimitiveSizeInBits()) - IterationCount = SCEVZeroExtendExpr::get(IterationCount, LargestType); + IterationCount = SE->getZeroExtendExpr(IterationCount, LargestType); else if (IterationCount->getType() != LargestType) - IterationCount = SCEVTruncateExpr::get(IterationCount, LargestType); + IterationCount = SE->getTruncateExpr(IterationCount, LargestType); if (Instruction *DI = LinearFunctionTestReplace(L, IterationCount,Rewriter)) DeadInsts.insert(DI); } Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43224&r1=43223&r2=43224&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Oct 22 13:31:58 2007 @@ -90,9 +90,6 @@ PHINode *PHI; Value *IncV; - IVExpr() - : Stride(SCEVUnknown::getIntegerSCEV(0, Type::Int32Ty)), - Base (SCEVUnknown::getIntegerSCEV(0, Type::Int32Ty)) {} IVExpr(const SCEVHandle &stride, const SCEVHandle &base, PHINode *phi, Value *incv) : Stride(stride), Base(base), PHI(phi), IncV(incv) {} @@ -261,7 +258,7 @@ // Build up the base expression. Insert an LLVM cast of the pointer to // uintptr_t first. - SCEVHandle GEPVal = SCEVUnknown::get( + SCEVHandle GEPVal = SE->getUnknown( getCastedVersionOf(Instruction::PtrToInt, GEP->getOperand(0))); gep_type_iterator GTI = gep_type_begin(GEP); @@ -274,8 +271,8 @@ const StructLayout *SL = TD->getStructLayout(STy); unsigned Idx = cast(GEP->getOperand(i))->getZExtValue(); uint64_t Offset = SL->getElementOffset(Idx); - GEPVal = SCEVAddExpr::get(GEPVal, - SCEVUnknown::getIntegerSCEV(Offset, UIntPtrTy)); + GEPVal = SE->getAddExpr(GEPVal, + SE->getIntegerSCEV(Offset, UIntPtrTy)); } else { unsigned GEPOpiBits = GEP->getOperand(i)->getType()->getPrimitiveSizeInBits(); @@ -288,10 +285,10 @@ uint64_t TypeSize = TD->getABITypeSize(GTI.getIndexedType()); if (TypeSize != 1) - Idx = SCEVMulExpr::get(Idx, - SCEVConstant::get(ConstantInt::get(UIntPtrTy, - TypeSize))); - GEPVal = SCEVAddExpr::get(GEPVal, Idx); + Idx = SE->getMulExpr(Idx, + SE->getConstant(ConstantInt::get(UIntPtrTy, + TypeSize))); + GEPVal = SE->getAddExpr(GEPVal, Idx); } } @@ -304,7 +301,8 @@ /// is. The stride must be a loop invariant expression, but the start may be /// a mix of loop invariant and loop variant expressions. static bool getSCEVStartAndStride(const SCEVHandle &SH, Loop *L, - SCEVHandle &Start, SCEVHandle &Stride) { + SCEVHandle &Start, SCEVHandle &Stride, + ScalarEvolution *SE) { SCEVHandle TheAddRec = Start; // Initialize to zero. // If the outer level is an AddExpr, the operands are all start values except @@ -314,11 +312,11 @@ if (SCEVAddRecExpr *AddRec = dyn_cast(AE->getOperand(i))) { if (AddRec->getLoop() == L) - TheAddRec = SCEVAddExpr::get(AddRec, TheAddRec); + TheAddRec = SE->getAddExpr(AddRec, TheAddRec); else return false; // Nested IV of some sort? } else { - Start = SCEVAddExpr::get(Start, AE->getOperand(i)); + Start = SE->getAddExpr(Start, AE->getOperand(i)); } } else if (isa(SH)) { @@ -333,7 +331,7 @@ // FIXME: Generalize to non-affine IV's. if (!AddRec->isAffine()) return false; - Start = SCEVAddExpr::get(Start, AddRec->getOperand(0)); + Start = SE->getAddExpr(Start, AddRec->getOperand(0)); if (!isa(AddRec->getOperand(1))) DOUT << "[" << L->getHeader()->getName() @@ -414,9 +412,9 @@ if (isa(ISE)) return false; // Get the start and stride for this expression. - SCEVHandle Start = SCEVUnknown::getIntegerSCEV(0, ISE->getType()); + SCEVHandle Start = SE->getIntegerSCEV(0, ISE->getType()); SCEVHandle Stride = Start; - if (!getSCEVStartAndStride(ISE, L, Start, Stride)) + if (!getSCEVStartAndStride(ISE, L, Start, Stride, SE)) return false; // Non-reducible symbolic expression, bail out. std::vector IUsers; @@ -458,7 +456,7 @@ if (IVUseShouldUsePostIncValue(User, I, L, DT, this)) { // The value used will be incremented by the stride more than we are // expecting, so subtract this off. - SCEVHandle NewStart = SCEV::getMinusSCEV(Start, Stride); + SCEVHandle NewStart = SE->getMinusSCEV(Start, Stride); StrideUses.addUser(NewStart, User, I); StrideUses.Users.back().isUseOfPostIncrementedValue = true; DOUT << " USING POSTINC SCEV, START=" << *NewStart<< "\n"; @@ -474,6 +472,9 @@ /// BasedUser - For a particular base value, keep information about how we've /// partitioned the expression so far. struct BasedUser { + /// SE - The current ScalarEvolution object. + ScalarEvolution *SE; + /// Base - The Base value for the PHI node that needs to be inserted for /// this use. As the use is processed, information gets moved from this /// field to the Imm field (below). BasedUser values are sorted by this @@ -503,10 +504,10 @@ // the loop. bool isUseOfPostIncrementedValue; - BasedUser(IVStrideUse &IVSU) - : Base(IVSU.Offset), Inst(IVSU.User), + BasedUser(IVStrideUse &IVSU, ScalarEvolution *se) + : SE(se), Base(IVSU.Offset), Inst(IVSU.User), OperandValToReplace(IVSU.OperandValToReplace), - Imm(SCEVUnknown::getIntegerSCEV(0, Base->getType())), EmittedBase(0), + Imm(SE->getIntegerSCEV(0, Base->getType())), EmittedBase(0), isUseOfPostIncrementedValue(IVSU.isUseOfPostIncrementedValue) {} // Once we rewrite the code to insert the new IVs we want, update the @@ -565,7 +566,7 @@ IP = Rewriter.getInsertionPoint(); // Always emit the immediate (if non-zero) into the same block as the user. - SCEVHandle NewValSCEV = SCEVAddExpr::get(SCEVUnknown::get(Base), Imm); + SCEVHandle NewValSCEV = SE->getAddExpr(SE->getUnknown(Base), Imm); return Rewriter.expandCodeFor(NewValSCEV, IP); } @@ -703,7 +704,7 @@ /// MoveLoopVariantsToImediateField - Move any subexpressions from Val that are /// loop varying to the Imm operand. static void MoveLoopVariantsToImediateField(SCEVHandle &Val, SCEVHandle &Imm, - Loop *L) { + Loop *L, ScalarEvolution *SE) { if (Val->isLoopInvariant(L)) return; // Nothing to do. if (SCEVAddExpr *SAE = dyn_cast(Val)) { @@ -714,27 +715,27 @@ if (!SAE->getOperand(i)->isLoopInvariant(L)) { // If this is a loop-variant expression, it must stay in the immediate // field of the expression. - Imm = SCEVAddExpr::get(Imm, SAE->getOperand(i)); + Imm = SE->getAddExpr(Imm, SAE->getOperand(i)); } else { NewOps.push_back(SAE->getOperand(i)); } if (NewOps.empty()) - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Val = SE->getIntegerSCEV(0, Val->getType()); else - Val = SCEVAddExpr::get(NewOps); + Val = SE->getAddExpr(NewOps); } else if (SCEVAddRecExpr *SARE = dyn_cast(Val)) { // Try to pull immediates out of the start value of nested addrec's. SCEVHandle Start = SARE->getStart(); - MoveLoopVariantsToImediateField(Start, Imm, L); + MoveLoopVariantsToImediateField(Start, Imm, L, SE); std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Start; - Val = SCEVAddRecExpr::get(Ops, SARE->getLoop()); + Val = SE->getAddRecExpr(Ops, SARE->getLoop()); } else { // Otherwise, all of Val is variant, move the whole thing over. - Imm = SCEVAddExpr::get(Imm, Val); - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Imm = SE->getAddExpr(Imm, Val); + Val = SE->getIntegerSCEV(0, Val->getType()); } } @@ -745,7 +746,8 @@ static void MoveImmediateValues(const TargetLowering *TLI, Instruction *User, SCEVHandle &Val, SCEVHandle &Imm, - bool isAddress, Loop *L) { + bool isAddress, Loop *L, + ScalarEvolution *SE) { const Type *UseTy = User->getType(); if (StoreInst *SI = dyn_cast(User)) UseTy = SI->getOperand(0)->getType(); @@ -756,31 +758,31 @@ for (unsigned i = 0; i != SAE->getNumOperands(); ++i) { SCEVHandle NewOp = SAE->getOperand(i); - MoveImmediateValues(TLI, User, NewOp, Imm, isAddress, L); + MoveImmediateValues(TLI, User, NewOp, Imm, isAddress, L, SE); if (!NewOp->isLoopInvariant(L)) { // If this is a loop-variant expression, it must stay in the immediate // field of the expression. - Imm = SCEVAddExpr::get(Imm, NewOp); + Imm = SE->getAddExpr(Imm, NewOp); } else { NewOps.push_back(NewOp); } } if (NewOps.empty()) - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Val = SE->getIntegerSCEV(0, Val->getType()); else - Val = SCEVAddExpr::get(NewOps); + Val = SE->getAddExpr(NewOps); return; } else if (SCEVAddRecExpr *SARE = dyn_cast(Val)) { // Try to pull immediates out of the start value of nested addrec's. SCEVHandle Start = SARE->getStart(); - MoveImmediateValues(TLI, User, Start, Imm, isAddress, L); + MoveImmediateValues(TLI, User, Start, Imm, isAddress, L, SE); if (Start != SARE->getStart()) { std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Start; - Val = SCEVAddRecExpr::get(Ops, SARE->getLoop()); + Val = SE->getAddRecExpr(Ops, SARE->getLoop()); } return; } else if (SCEVMulExpr *SME = dyn_cast(Val)) { @@ -788,22 +790,22 @@ if (isAddress && isTargetConstant(SME->getOperand(0), UseTy, TLI) && SME->getNumOperands() == 2 && SME->isLoopInvariant(L)) { - SCEVHandle SubImm = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + SCEVHandle SubImm = SE->getIntegerSCEV(0, Val->getType()); SCEVHandle NewOp = SME->getOperand(1); - MoveImmediateValues(TLI, User, NewOp, SubImm, isAddress, L); + MoveImmediateValues(TLI, User, NewOp, SubImm, isAddress, L, SE); // If we extracted something out of the subexpressions, see if we can // simplify this! if (NewOp != SME->getOperand(1)) { // Scale SubImm up by "8". If the result is a target constant, we are // good. - SubImm = SCEVMulExpr::get(SubImm, SME->getOperand(0)); + SubImm = SE->getMulExpr(SubImm, SME->getOperand(0)); if (isTargetConstant(SubImm, UseTy, TLI)) { // Accumulate the immediate. - Imm = SCEVAddExpr::get(Imm, SubImm); + Imm = SE->getAddExpr(Imm, SubImm); // Update what is left of 'Val'. - Val = SCEVMulExpr::get(SME->getOperand(0), NewOp); + Val = SE->getMulExpr(SME->getOperand(0), NewOp); return; } } @@ -814,8 +816,8 @@ // expression. if ((isAddress && isTargetConstant(Val, UseTy, TLI)) || !Val->isLoopInvariant(L)) { - Imm = SCEVAddExpr::get(Imm, Val); - Val = SCEVUnknown::getIntegerSCEV(0, Val->getType()); + Imm = SE->getAddExpr(Imm, Val); + Val = SE->getIntegerSCEV(0, Val->getType()); return; } @@ -827,22 +829,23 @@ /// added together. This is used to reassociate common addition subexprs /// together for maximal sharing when rewriting bases. static void SeparateSubExprs(std::vector &SubExprs, - SCEVHandle Expr) { + SCEVHandle Expr, + ScalarEvolution *SE) { if (SCEVAddExpr *AE = dyn_cast(Expr)) { for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j) - SeparateSubExprs(SubExprs, AE->getOperand(j)); + SeparateSubExprs(SubExprs, AE->getOperand(j), SE); } else if (SCEVAddRecExpr *SARE = dyn_cast(Expr)) { - SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Expr->getType()); + SCEVHandle Zero = SE->getIntegerSCEV(0, Expr->getType()); if (SARE->getOperand(0) == Zero) { SubExprs.push_back(Expr); } else { // Compute the addrec with zero as its base. std::vector Ops(SARE->op_begin(), SARE->op_end()); Ops[0] = Zero; // Start with zero base. - SubExprs.push_back(SCEVAddRecExpr::get(Ops, SARE->getLoop())); + SubExprs.push_back(SE->getAddRecExpr(Ops, SARE->getLoop())); - SeparateSubExprs(SubExprs, SARE->getOperand(0)); + SeparateSubExprs(SubExprs, SARE->getOperand(0), SE); } } else if (!isa(Expr) || !cast(Expr)->getValue()->isZero()) { @@ -857,11 +860,12 @@ /// removed, accumulated, and returned. This looks for things like (a+b+c) and /// (a+c+d) -> (a+c). The common expression is *removed* from the Bases. static SCEVHandle -RemoveCommonExpressionsFromUseBases(std::vector &Uses) { +RemoveCommonExpressionsFromUseBases(std::vector &Uses, + ScalarEvolution *SE) { unsigned NumUses = Uses.size(); // Only one use? Use its base, regardless of what it is! - SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Uses[0].Base->getType()); + SCEVHandle Zero = SE->getIntegerSCEV(0, Uses[0].Base->getType()); SCEVHandle Result = Zero; if (NumUses == 1) { std::swap(Result, Uses[0].Base); @@ -883,7 +887,7 @@ if (Uses[i].Base == Zero) return Zero; // Split the expression into subexprs. - SeparateSubExprs(SubExprs, Uses[i].Base); + SeparateSubExprs(SubExprs, Uses[i].Base, SE); // Add one to SubExpressionUseCounts for each subexpr present. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) if (++SubExpressionUseCounts[SubExprs[j]] == 1) @@ -898,7 +902,7 @@ SubExpressionUseCounts.find(UniqueSubExprs[i]); assert(I != SubExpressionUseCounts.end() && "Entry not found?"); if (I->second == NumUses) { // Found CSE! - Result = SCEVAddExpr::get(Result, I->first); + Result = SE->getAddExpr(Result, I->first); } else { // Remove non-cse's from SubExpressionUseCounts. SubExpressionUseCounts.erase(I); @@ -911,7 +915,7 @@ // Otherwise, remove all of the CSE's we found from each of the base values. for (unsigned i = 0; i != NumUses; ++i) { // Split the expression into subexprs. - SeparateSubExprs(SubExprs, Uses[i].Base); + SeparateSubExprs(SubExprs, Uses[i].Base, SE); // Remove any common subexpressions. for (unsigned j = 0, e = SubExprs.size(); j != e; ++j) @@ -924,7 +928,7 @@ if (SubExprs.empty()) Uses[i].Base = Zero; else - Uses[i].Base = SCEVAddExpr::get(SubExprs); + Uses[i].Base = SE->getAddExpr(SubExprs); SubExprs.clear(); } @@ -1037,13 +1041,13 @@ std::vector UsersToProcess; UsersToProcess.reserve(Uses.Users.size()); for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) { - UsersToProcess.push_back(Uses.Users[i]); + UsersToProcess.push_back(BasedUser(Uses.Users[i], SE)); // Move any loop invariant operands from the offset field to the immediate // field of the use, so that we don't try to use something before it is // computed. MoveLoopVariantsToImediateField(UsersToProcess.back().Base, - UsersToProcess.back().Imm, L); + UsersToProcess.back().Imm, L, SE); assert(UsersToProcess.back().Base->isLoopInvariant(L) && "Base value is not loop invariant!"); } @@ -1056,7 +1060,7 @@ // "A+B"), emit it to the preheader, then remove the expression from the // UsersToProcess base values. SCEVHandle CommonExprs = - RemoveCommonExpressionsFromUseBases(UsersToProcess); + RemoveCommonExpressionsFromUseBases(UsersToProcess, SE); // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm @@ -1067,10 +1071,10 @@ // value of the IV. Do not put anything in the base, make sure it's all in // the immediate field to allow as much factoring as possible. if (!L->contains(UsersToProcess[i].Inst->getParent())) { - UsersToProcess[i].Imm = SCEVAddExpr::get(UsersToProcess[i].Imm, - UsersToProcess[i].Base); + UsersToProcess[i].Imm = SE->getAddExpr(UsersToProcess[i].Imm, + UsersToProcess[i].Base); UsersToProcess[i].Base = - SCEVUnknown::getIntegerSCEV(0, UsersToProcess[i].Base->getType()); + SE->getIntegerSCEV(0, UsersToProcess[i].Base->getType()); } else { // Addressing modes can be folded into loads and stores. Be careful that @@ -1088,7 +1092,7 @@ } MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base, - UsersToProcess[i].Imm, isAddress, L); + UsersToProcess[i].Imm, isAddress, L, SE); } } @@ -1098,7 +1102,9 @@ // instruction after this substition, including the immediate field, if any. PHINode *NewPHI = NULL; Value *IncV = NULL; - IVExpr ReuseIV; + IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty), + SE->getIntegerSCEV(0, Type::Int32Ty), + 0, 0); unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV, CommonExprs->getType(), UsersToProcess); @@ -1143,7 +1149,7 @@ bool isNegative = isNonConstantNegative(Stride); SCEVHandle IncAmount = Stride; if (isNegative) - IncAmount = SCEV::getNegativeSCEV(Stride); + IncAmount = SE->getNegativeSCEV(Stride); // Insert the stride into the preheader. Value *StrideV = PreheaderRewriter.expandCodeFor(IncAmount, PreInsertPt); @@ -1151,10 +1157,10 @@ // Emit the increment of the base value before the terminator of the loop // latch block, and add it to the Phi node. - SCEVHandle IncExp = SCEVUnknown::get(StrideV); + SCEVHandle IncExp = SE->getUnknown(StrideV); if (isNegative) - IncExp = SCEV::getNegativeSCEV(IncExp); - IncExp = SCEVAddExpr::get(SCEVUnknown::get(NewPHI), IncExp); + IncExp = SE->getNegativeSCEV(IncExp); + IncExp = SE->getAddExpr(SE->getUnknown(NewPHI), IncExp); IncV = Rewriter.expandCodeFor(IncExp, LatchBlock->getTerminator()); IncV->setName(NewPHI->getName()+".inc"); @@ -1168,7 +1174,7 @@ Constant *C = dyn_cast(CommonBaseV); if (!C || (!C->isNullValue() && - !isTargetConstant(SCEVUnknown::get(CommonBaseV), ReplacedTy, TLI))) + !isTargetConstant(SE->getUnknown(CommonBaseV), ReplacedTy, TLI))) // We want the common base emitted into the preheader! This is just // using cast as a copy so BitCast (no-op cast) is appropriate CommonBaseV = new BitCastInst(CommonBaseV, CommonBaseV->getType(), @@ -1257,7 +1263,7 @@ RewriteOp = SCEVExpander::InsertCastOfTo(opcode, RewriteOp, ReplacedTy); } - SCEVHandle RewriteExpr = SCEVUnknown::get(RewriteOp); + SCEVHandle RewriteExpr = SE->getUnknown(RewriteOp); // Clear the SCEVExpander's expression map so that we are guaranteed // to have the code emitted where we expect it. @@ -1267,8 +1273,8 @@ // factor take advantage of addressing mode scale component. if (RewriteFactor != 0) { RewriteExpr = - SCEVMulExpr::get(SCEVUnknown::getIntegerSCEV(RewriteFactor, - RewriteExpr->getType()), + SE->getMulExpr(SE->getIntegerSCEV(RewriteFactor, + RewriteExpr->getType()), RewriteExpr); // The common base is emitted in the loop preheader. But since we @@ -1276,15 +1282,15 @@ // Add it to the expression used to rewrite the uses. if (!isa(CommonBaseV) || !cast(CommonBaseV)->isZero()) - RewriteExpr = SCEVAddExpr::get(RewriteExpr, - SCEVUnknown::get(CommonBaseV)); + RewriteExpr = SE->getAddExpr(RewriteExpr, + SE->getUnknown(CommonBaseV)); } // Now that we know what we need to do, insert code before User for the // immediate and any loop-variant expressions. if (!isa(BaseV) || !cast(BaseV)->isZero()) // Add BaseV to the PHI value if needed. - RewriteExpr = SCEVAddExpr::get(RewriteExpr, SCEVUnknown::get(BaseV)); + RewriteExpr = SE->getAddExpr(RewriteExpr, SE->getUnknown(BaseV)); User.RewriteInstructionToUseNewBase(RewriteExpr, Rewriter, L, this); @@ -1380,7 +1386,7 @@ // If we get to here, we know that we can transform the setcc instruction to // use the post-incremented version of the IV, allowing us to coalesce the // live ranges for the IV correctly. - CondUse->Offset = SCEV::getMinusSCEV(CondUse->Offset, *CondStride); + CondUse->Offset = SE->getMinusSCEV(CondUse->Offset, *CondStride); CondUse->isUseOfPostIncrementedValue = true; } From baldrick at free.fr Mon Oct 22 14:00:05 2007 From: baldrick at free.fr (Duncan Sands) Date: Mon, 22 Oct 2007 19:00:05 -0000 Subject: [llvm-commits] [llvm] r43225 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710221900.l9MJ05fI022929@zion.cs.uiuc.edu> Author: baldrick Date: Mon Oct 22 14:00:05 2007 New Revision: 43225 URL: http://llvm.org/viewvc/llvm-project?rev=43225&view=rev Log: Support for expanding extending loads of integers with funky bit-widths. 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=43225&r1=43224&r2=43225&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Mon Oct 22 14:00:05 2007 @@ -935,17 +935,19 @@ int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); - + + assert(!(MVT::getSizeInBits(NVT) & 7) && "Expanded type not byte sized!"); + if (ExtType == ISD::NON_EXTLOAD) { Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, isVolatile, Alignment); // Increment the pointer to the other half. - unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8; + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, isVolatile, std::max(Alignment, IncrementSize)); - + // Build a factor node to remember that this load is independent of the // other one. Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), @@ -954,19 +956,15 @@ // Handle endianness of the load. if (!TLI.isLittleEndian()) std::swap(Lo, Hi); - } else { + } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) { MVT::ValueType EVT = N->getLoadedVT(); - - if (EVT == NVT) - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), - SVOffset, isVolatile, Alignment); - else - Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), - SVOffset, EVT, isVolatile, - Alignment); + + Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, + isVolatile, Alignment); + // Remember the chain. Ch = Lo.getValue(1); - + if (ExtType == ISD::SEXTLOAD) { // The high part is obtained by SRA'ing all but one of the bits of the // lo part. @@ -981,13 +979,70 @@ // The high part is undefined. Hi = DAG.getNode(ISD::UNDEF, NVT); } + } else if (TLI.isLittleEndian()) { + // Little-endian - low bits are at low addresses. + Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + isVolatile, Alignment); + + unsigned ExcessBits = + MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT); + MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits); + + // Increment the pointer to the other half. + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, NEVT, + isVolatile, std::max(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + } else { + // Big-endian - high bits are at low addresses. Favor aligned loads at + // the cost of some bit-fiddling. + MVT::ValueType EVT = N->getLoadedVT(); + unsigned EBytes = (MVT::getSizeInBits(EVT) + 7)/8; + unsigned IncrementSize = MVT::getSizeInBits(NVT)/8; + unsigned ExcessBits = (EBytes - IncrementSize)*8; + + // Load both the high bits and maybe some of the low bits. + Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + MVT::getIntegerType(MVT::getSizeInBits(EVT)-ExcessBits), + isVolatile, Alignment); + + // Increment the pointer to the other half. + Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + getIntPtrConstant(IncrementSize)); + // Load the rest of the low bits. + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), + SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), + isVolatile, std::max(Alignment, IncrementSize)); + + // Build a factor node to remember that this load is independent of the + // other one. + Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Hi.getValue(1)); + + if (ExcessBits < MVT::getSizeInBits(NVT)) { + // Transfer low bits from the bottom of Hi to the top of Lo. + Lo = DAG.getNode(ISD::OR, NVT, Lo, + DAG.getNode(ISD::SHL, NVT, Hi, + DAG.getConstant(ExcessBits, + TLI.getShiftAmountTy()))); + // Move high bits to the right position in Hi. + Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi, + DAG.getConstant(MVT::getSizeInBits(NVT) - ExcessBits, + TLI.getShiftAmountTy())); + } } - + // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceLegalValueWith(SDOperand(N, 1), Ch); -} - +} void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N, SDOperand &Lo, SDOperand &Hi) { From sabre at nondot.org Mon Oct 22 14:41:46 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 22 Oct 2007 19:41:46 -0000 Subject: [llvm-commits] [llvm] r43226 - /llvm/trunk/tools/llvmc/llvmc.cpp Message-ID: <200710221941.l9MJfkwO024915@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 14:41:46 2007 New Revision: 43226 URL: http://llvm.org/viewvc/llvm-project?rev=43226&view=rev Log: add a 'don't use me' marker. Modified: llvm/trunk/tools/llvmc/llvmc.cpp Modified: llvm/trunk/tools/llvmc/llvmc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvmc/llvmc.cpp?rev=43226&r1=43225&r2=43226&view=diff ============================================================================== --- llvm/trunk/tools/llvmc/llvmc.cpp (original) +++ llvm/trunk/tools/llvmc/llvmc.cpp Mon Oct 22 14:41:46 2007 @@ -253,6 +253,9 @@ // Make sure we print stack trace if we get bad signals sys::PrintStackTraceOnErrorSignal(); + std::cout << "NOTE: llvmc is highly experimental and mostly useless right " + "now.\nPlease use llvm-gcc directly instead.\n\n"; + try { // Parse the command line options From evan.cheng at apple.com Mon Oct 22 14:42:28 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 22 Oct 2007 19:42:28 -0000 Subject: [llvm-commits] [llvm] r43227 - /llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Message-ID: <200710221942.l9MJgSek024961@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 22 14:42:28 2007 New Revision: 43227 URL: http://llvm.org/viewvc/llvm-project?rev=43227&view=rev Log: Add missing paratheses. Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=43227&r1=43226&r2=43227&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Mon Oct 22 14:42:28 2007 @@ -618,7 +618,7 @@ // Unallocatable register dead, ignore. continue; } else { - assert(!PhysRegsUsed[PhysReg] || PhysRegsUsed[PhysReg] == -1 && + assert((!PhysRegsUsed[PhysReg] || PhysRegsUsed[PhysReg] == -1) && "Silently clearing a virtual register?"); } From evan.cheng at apple.com Mon Oct 22 14:46:19 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 22 Oct 2007 19:46:19 -0000 Subject: [llvm-commits] [llvm] r43228 - in /llvm/trunk: lib/Target/PowerPC/PPCISelLowering.cpp test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll Message-ID: <200710221946.l9MJkJII025122@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 22 14:46:19 2007 New Revision: 43228 URL: http://llvm.org/viewvc/llvm-project?rev=43228&view=rev Log: Use ptr type in the immediate field of a BxA instruction so we don't end up selecting 32-bit call instruction for ppc64. Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=43228&r1=43227&r2=43228&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Oct 22 14:46:19 2007 @@ -1537,7 +1537,8 @@ (Addr << 6 >> 6) != Addr) return 0; // Top 6 bits have to be sext of immediate. - return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val; + return DAG.getConstant((int)C->getValue() >> 2, + DAG.getTargetLoweringInfo().getPointerTy()).Val; } Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll?rev=43228&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert.ll Mon Oct 22 14:46:19 2007 @@ -0,0 +1,27 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -regalloc=local -relocation-model=pic + + %struct.NSError = type opaque + %struct.NSManagedObjectContext = type opaque + %struct.NSPersistentStoreCoordinator = type opaque + %struct.NSString = type opaque + %struct.NSURL = type opaque + %struct._message_ref_t = type { %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*, %struct.objc_selector* } + %struct.objc_object = type { } + %struct.objc_selector = type opaque +@"\01L_OBJC_MESSAGE_REF_2" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=1] +@"\01L_OBJC_MESSAGE_REF_6" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=1] + at NSXMLStoreType = external constant %struct.NSString* ; <%struct.NSString**> [#uses=1] +@"\01L_OBJC_MESSAGE_REF_5" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=2] +@"\01L_OBJC_MESSAGE_REF_4" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=1] + +define %struct.NSManagedObjectContext* @"+[ListGenerator(Private) managedObjectContextWithModelURL:storeURL:]"(%struct.objc_object* %self, %struct._message_ref_t* %_cmd, %struct.NSURL* %modelURL, %struct.NSURL* %storeURL) { +entry: + %storeCoordinator = alloca %struct.NSPersistentStoreCoordinator* ; <%struct.NSPersistentStoreCoordinator**> [#uses=0] + %tmp29 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* null( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_2" ) ; <%struct.objc_object*> [#uses=0] + %tmp34 = load %struct.NSString** @NSXMLStoreType, align 8 ; <%struct.NSString*> [#uses=1] + %tmp37 = load %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)** getelementptr (%struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_5", i32 0, i32 0), align 8 ; <%struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*> [#uses=1] + %tmp42 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* null( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_4", i32 1 ) ; <%struct.objc_object*> [#uses=1] + %tmp45 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* %tmp37( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_5", %struct.objc_object* %tmp42, %struct.NSString* null ) ; <%struct.objc_object*> [#uses=1] + %tmp48 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* null( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_6", %struct.NSString* %tmp34, i8* null, %struct.NSURL* null, %struct.objc_object* %tmp45, %struct.NSError** null ) ; <%struct.objc_object*> [#uses=0] + unreachable +} From criswell at uiuc.edu Mon Oct 22 14:57:26 2007 From: criswell at uiuc.edu (John Criswell) Date: Mon, 22 Oct 2007 19:57:26 -0000 Subject: [llvm-commits] [poolalloc] r43229 - /poolalloc/branches/SVA/lib/DSA/Local.cpp Message-ID: <200710221957.l9MJvQmp025589@zion.cs.uiuc.edu> Author: criswell Date: Mon Oct 22 14:57:26 2007 New Revision: 43229 URL: http://llvm.org/viewvc/llvm-project?rev=43229&view=rev Log: Make DSA compile correctly in kernel and non-kernel mode. Modified: poolalloc/branches/SVA/lib/DSA/Local.cpp Modified: poolalloc/branches/SVA/lib/DSA/Local.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/branches/SVA/lib/DSA/Local.cpp?rev=43229&r1=43228&r2=43229&view=diff ============================================================================== --- poolalloc/branches/SVA/lib/DSA/Local.cpp (original) +++ poolalloc/branches/SVA/lib/DSA/Local.cpp Mon Oct 22 14:57:26 2007 @@ -1490,8 +1490,8 @@ N->setModifiedMarker()->setReadMarker(); return true; #endif - } #endif + } return false; } @@ -1553,12 +1553,14 @@ } } +#ifdef LLVA_KERNEL if (isSyscall6) { assert (isa(CS.getArgument(0)) && "llva_syscall6 called with non-const argument"); ConstantInt * C = dyn_cast(CS.getArgument(0)); Callee = syscalls[C->getSExtValue()]; assert (Callee && "llva_syscall: No target for system call vector"); } +#endif // Set up the return value... DSNodeHandle RetVal; From djg at cray.com Mon Oct 22 15:22:25 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 22 Oct 2007 20:22:25 -0000 Subject: [llvm-commits] [llvm] r43230 - in /llvm/trunk: lib/Target/X86/X86ISelDAGToDAG.cpp test/CodeGen/X86/fold-mul-lohi.ll Message-ID: <200710222022.l9MKMPet026663@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 22 15:22:24 2007 New Revision: 43230 URL: http://llvm.org/viewvc/llvm-project?rev=43230&view=rev Log: Fix the folding of multiplication into addresses on x86, which was broken by the recent {U,S}MUL_LOHI changes. Added: llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=43230&r1=43229&r2=43230&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Mon Oct 22 15:22:24 2007 @@ -681,6 +681,11 @@ } break; + case ISD::SMUL_LOHI: + case ISD::UMUL_LOHI: + // A mul_lohi where we need the low part can be folded as a plain multiply. + if (N.ResNo != 0) break; + // FALL THROUGH case ISD::MUL: // X*[3,5,9] -> X+X*[2,4,8] if (!Available && Added: llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll?rev=43230&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll (added) +++ llvm/trunk/test/CodeGen/X86/fold-mul-lohi.ll Mon Oct 22 15:22:24 2007 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep lea +; RUN: llvm-as < %s | llc -march=x86-64 | not grep lea + + at B = external global [1000 x i8], align 32 + at A = external global [1000 x i8], align 32 + at P = external global [1000 x i8], align 32 + +define void @foo(i32 %m) { +entry: + %tmp1 = icmp sgt i32 %m, 0 + br i1 %tmp1, label %bb, label %return + +bb: + %i.019.0 = phi i32 [ %indvar.next, %bb ], [ 0, %entry ] + %tmp2 = getelementptr [1000 x i8]* @B, i32 0, i32 %i.019.0 + %tmp3 = load i8* %tmp2, align 4 + %tmp4 = mul i8 %tmp3, 2 + %tmp5 = getelementptr [1000 x i8]* @A, i32 0, i32 %i.019.0 + store i8 %tmp4, i8* %tmp5, align 4 + %tmp8 = mul i32 %i.019.0, 9 + %tmp10 = getelementptr [1000 x i8]* @P, i32 0, i32 %tmp8 + store i8 17, i8* %tmp10, align 4 + %indvar.next = add i32 %i.019.0, 1 + %exitcond = icmp eq i32 %indvar.next, %m + br i1 %exitcond, label %return, label %bb + +return: + ret void +} + From djg at cray.com Mon Oct 22 15:40:42 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 22 Oct 2007 20:40:42 -0000 Subject: [llvm-commits] [llvm] r43231 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/2007-08-10-LEA16Use32.ll test/CodeGen/X86/stride-nine-with-base-reg.ll test/CodeGen/X86/stride-reuse.ll Message-ID: <200710222040.l9MKegSC027675@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 22 15:40:42 2007 New Revision: 43231 URL: http://llvm.org/viewvc/llvm-project?rev=43231&view=rev Log: Strength reduction improvements. - Avoid attempting stride-reuse in the case that there are users that aren't addresses. In that case, there will be places where the multiplications won't be folded away, so it's better to try to strength-reduce them. - Several SSE intrinsics have operands that strength-reduction can treat as addresses. The previous item makes this more visible, as any non-address use of an IV can inhibit stride-reuse. - Make ValidStride aware of whether there's likely to be a base register in the address computation. This prevents it from thinking that things like stride 9 are valid on x86 when the base register is already occupied. Also, XFAIL the 2007-08-10-LEA16Use32.ll test; the new logic to avoid stride-reuse elimintes the LEA in the loop, so the test is no longer testing what it was intended to test. Added: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll llvm/trunk/test/CodeGen/X86/stride-reuse.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp llvm/trunk/test/CodeGen/X86/2007-08-10-LEA16Use32.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43231&r1=43230&r2=43231&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Oct 22 15:40:42 2007 @@ -175,10 +175,12 @@ bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, const SCEVHandle *&CondStride); - unsigned CheckForIVReuse(const SCEVHandle&, IVExpr&, const Type*, + unsigned CheckForIVReuse(bool, const SCEVHandle&, + IVExpr&, const Type*, const std::vector& UsersToProcess); - bool ValidStride(int64_t, const std::vector& UsersToProcess); + bool ValidStride(bool, int64_t, + const std::vector& UsersToProcess); void StrengthReduceStridedIVUsers(const SCEVHandle &Stride, IVUsersOfOneStride &Uses, @@ -937,8 +939,8 @@ /// isZero - returns true if the scalar evolution expression is zero. /// -static bool isZero(SCEVHandle &V) { - if (SCEVConstant *SC = dyn_cast(V)) +static bool isZero(const SCEVHandle &V) { + if (const SCEVConstant *SC = dyn_cast(V)) return SC->getValue()->isZero(); return false; } @@ -946,7 +948,8 @@ /// ValidStride - Check whether the given Scale is valid for all loads and /// stores in UsersToProcess. /// -bool LoopStrengthReduce::ValidStride(int64_t Scale, +bool LoopStrengthReduce::ValidStride(bool HasBaseReg, + int64_t Scale, const std::vector& UsersToProcess) { for (unsigned i=0, e = UsersToProcess.size(); i!=e; ++i) { // If this is a load or other access, pass the type of the access in. @@ -959,6 +962,7 @@ TargetLowering::AddrMode AM; if (SCEVConstant *SC = dyn_cast(UsersToProcess[i].Imm)) AM.BaseOffs = SC->getValue()->getSExtValue(); + AM.HasBaseReg = HasBaseReg || !isZero(UsersToProcess[i].Base); AM.Scale = Scale; // If load[imm+r*scale] is illegal, bail out. @@ -970,9 +974,11 @@ /// CheckForIVReuse - Returns the multiple if the stride is the multiple /// of a previous stride and it is a legal value for the target addressing -/// mode scale component. This allows the users of this stride to be rewritten -/// as prev iv * factor. It returns 0 if no reuse is possible. -unsigned LoopStrengthReduce::CheckForIVReuse(const SCEVHandle &Stride, +/// mode scale component and optional base reg. This allows the users of +/// this stride to be rewritten as prev iv * factor. It returns 0 if no +/// reuse is possible. +unsigned LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg, + const SCEVHandle &Stride, IVExpr &IV, const Type *Ty, const std::vector& UsersToProcess) { if (!TLI) return 0; @@ -992,7 +998,7 @@ // stores; if it can be used for some and not others, we might as well use // the original stride everywhere, since we have to create the IV for it // anyway. - if (ValidStride(Scale, UsersToProcess)) + if (ValidStride(HasBaseReg, Scale, UsersToProcess)) for (std::vector::iterator II = SI->second.IVs.begin(), IE = SI->second.IVs.end(); II != IE; ++II) // FIXME: Only handle base == 0 for now. @@ -1061,7 +1067,18 @@ // UsersToProcess base values. SCEVHandle CommonExprs = RemoveCommonExpressionsFromUseBases(UsersToProcess, SE); - + + // If we managed to find some expressions in common, we'll need to carry + // their value in a register and add it in for each use. This will take up + // a register operand, which potentially restricts what stride values are + // valid. + bool HaveCommonExprs = !isZero(CommonExprs); + + // Keep track if every use in UsersToProcess is an address. If they all are, + // we may be able to rewrite the entire collection of them in terms of a + // smaller-stride IV. + bool AllUsesAreAddresses = true; + // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm // fields of the BasedUsers. We do this so that it increases the commonality @@ -1085,29 +1102,53 @@ isAddress = true; } else if (IntrinsicInst *II = dyn_cast(UsersToProcess[i].Inst)) { - // Addressing modes can also be folded into prefetches. - if (II->getIntrinsicID() == Intrinsic::prefetch && - II->getOperand(1) == UsersToProcess[i].OperandValToReplace) - isAddress = true; + // Addressing modes can also be folded into prefetches and a variety + // of intrinsics. + switch (II->getIntrinsicID()) { + default: break; + case Intrinsic::prefetch: + case Intrinsic::x86_sse2_loadu_dq: + case Intrinsic::x86_sse2_loadu_pd: + case Intrinsic::x86_sse_loadu_ps: + case Intrinsic::x86_sse_storeu_ps: + case Intrinsic::x86_sse2_storeu_pd: + case Intrinsic::x86_sse2_storeu_dq: + case Intrinsic::x86_sse2_storel_dq: + if (II->getOperand(1) == UsersToProcess[i].OperandValToReplace) + isAddress = true; + break; + case Intrinsic::x86_sse2_loadh_pd: + case Intrinsic::x86_sse2_loadl_pd: + if (II->getOperand(2) == UsersToProcess[i].OperandValToReplace) + isAddress = true; + break; + } } + + // If this use isn't an address, then not all uses are addresses. + if (!isAddress) + AllUsesAreAddresses = false; MoveImmediateValues(TLI, UsersToProcess[i].Inst, UsersToProcess[i].Base, UsersToProcess[i].Imm, isAddress, L, SE); } } - // Check if it is possible to reuse a IV with stride that is factor of this - // stride. And the multiple is a number that can be encoded in the scale - // field of the target addressing mode. And we will have a valid - // instruction after this substition, including the immediate field, if any. + // If all uses are addresses, check if it is possible to reuse an IV with a + // stride that is a factor of this stride. And that the multiple is a number + // that can be encoded in the scale field of the target addressing mode. And + // that we will have a valid instruction after this substition, including the + // immediate field, if any. PHINode *NewPHI = NULL; Value *IncV = NULL; IVExpr ReuseIV(SE->getIntegerSCEV(0, Type::Int32Ty), SE->getIntegerSCEV(0, Type::Int32Ty), 0, 0); - unsigned RewriteFactor = CheckForIVReuse(Stride, ReuseIV, - CommonExprs->getType(), - UsersToProcess); + unsigned RewriteFactor = 0; + if (AllUsesAreAddresses) + RewriteFactor = CheckForIVReuse(HaveCommonExprs, Stride, ReuseIV, + CommonExprs->getType(), + UsersToProcess); if (RewriteFactor != 0) { DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride << " and BASE " << *ReuseIV.Base << " :\n"; Modified: llvm/trunk/test/CodeGen/X86/2007-08-10-LEA16Use32.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-08-10-LEA16Use32.ll?rev=43231&r1=43230&r2=43231&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-08-10-LEA16Use32.ll (original) +++ llvm/trunk/test/CodeGen/X86/2007-08-10-LEA16Use32.ll Mon Oct 22 15:40:42 2007 @@ -1,4 +1,8 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep {leal} +; XFAIL: * +; This test is XFAIL'd because strength-reduction was improved to +; avoid emitting the lea, so it longer tests whether the 16-bit +; lea is avoided. @X = global i16 0 ; [#uses=1] @Y = global i16 0 ; [#uses=1] Added: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll?rev=43231&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll (added) +++ llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Mon Oct 22 15:40:42 2007 @@ -0,0 +1,34 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep lea | count 1 +; RUN: llvm-as < %s | llc -march=x86-64 | not grep lea + +; For x86 there's an lea above the loop. In both cases, there shouldn't +; be any lea instructions inside the loop. + + at B = external global [1000 x i8], align 32 + at A = external global [1000 x i8], align 32 + at P = external global [1000 x i8], align 32 + +define void @foo(i32 %m, i32 %p) { +entry: + %tmp1 = icmp sgt i32 %m, 0 + br i1 %tmp1, label %bb, label %return + +bb: + %i.019.0 = phi i32 [ %indvar.next, %bb ], [ 0, %entry ] + %tmp2 = getelementptr [1000 x i8]* @B, i32 0, i32 %i.019.0 + %tmp3 = load i8* %tmp2, align 4 + %tmp4 = mul i8 %tmp3, 2 + %tmp5 = getelementptr [1000 x i8]* @A, i32 0, i32 %i.019.0 + store i8 %tmp4, i8* %tmp5, align 4 + %tmp8 = mul i32 %i.019.0, 9 + %tmp0 = add i32 %tmp8, %p + %tmp10 = getelementptr [1000 x i8]* @P, i32 0, i32 %tmp0 + store i8 17, i8* %tmp10, align 4 + %indvar.next = add i32 %i.019.0, 1 + %exitcond = icmp eq i32 %indvar.next, %m + br i1 %exitcond, label %return, label %bb + +return: + ret void +} + Added: llvm/trunk/test/CodeGen/X86/stride-reuse.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-reuse.ll?rev=43231&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-reuse.ll (added) +++ llvm/trunk/test/CodeGen/X86/stride-reuse.ll Mon Oct 22 15:40:42 2007 @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep lea +; RUN: llvm-as < %s | llc -march=x86-64 | not grep lea + + at B = external global [1000 x float], align 32 + at A = external global [1000 x float], align 32 + at P = external global [1000 x i32], align 32 + +define void @foo(i32 %m) { +entry: + %tmp1 = icmp sgt i32 %m, 0 + br i1 %tmp1, label %bb, label %return + +bb: + %i.019.0 = phi i32 [ %indvar.next, %bb ], [ 0, %entry ] + %tmp2 = getelementptr [1000 x float]* @B, i32 0, i32 %i.019.0 + %tmp3 = load float* %tmp2, align 4 + %tmp4 = mul float %tmp3, 2.000000e+00 + %tmp5 = getelementptr [1000 x float]* @A, i32 0, i32 %i.019.0 + store float %tmp4, float* %tmp5, align 4 + %tmp8 = shl i32 %i.019.0, 1 + %tmp9 = add i32 %tmp8, 64 + %tmp10 = getelementptr [1000 x i32]* @P, i32 0, i32 %i.019.0 + store i32 %tmp9, i32* %tmp10, align 4 + %indvar.next = add i32 %i.019.0, 1 + %exitcond = icmp eq i32 %indvar.next, %m + br i1 %exitcond, label %return, label %bb + +return: + ret void +} From djg at cray.com Mon Oct 22 15:44:10 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 22 Oct 2007 20:44:10 -0000 Subject: [llvm-commits] [llvm] r43232 - /llvm/trunk/lib/VMCore/ConstantFold.h Message-ID: <200710222044.l9MKiAgg027994@zion.cs.uiuc.edu> Author: djg Date: Mon Oct 22 15:44:10 2007 New Revision: 43232 URL: http://llvm.org/viewvc/llvm-project?rev=43232&view=rev Log: The #include isn't needed in this header. Modified: llvm/trunk/lib/VMCore/ConstantFold.h Modified: llvm/trunk/lib/VMCore/ConstantFold.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.h?rev=43232&r1=43231&r2=43232&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.h (original) +++ llvm/trunk/lib/VMCore/ConstantFold.h Mon Oct 22 15:44:10 2007 @@ -19,8 +19,6 @@ #ifndef CONSTANTFOLDING_H #define CONSTANTFOLDING_H -#include - namespace llvm { class Value; class Constant; @@ -48,7 +46,6 @@ Constant *ConstantFoldCompareInstruction(unsigned short predicate, const Constant *C1, const Constant *C2); - Constant *ConstantFoldGetElementPtr(const Constant *C, Constant* const *Idxs, unsigned NumIdx); } // End llvm namespace From evan.cheng at apple.com Mon Oct 22 16:31:06 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 22 Oct 2007 14:31:06 -0700 Subject: [llvm-commits] [llvm] r43176 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h In-Reply-To: <200710191435.l9JEZIAM018674@zion.cs.uiuc.edu> References: <200710191435.l9JEZIAM018674@zion.cs.uiuc.edu> Message-ID: <90524216-7D9B-4B62-9FFF-E5669A37DEF9@apple.com> Hi Rafael, There a couple of problems with this patch. 1. This breaks a number of tests for me: llc-beta /MultiSource/Applications/JM/ldecod/ldecod llc /MultiSource/Applications/JM/ldecod/ldecod llc /External/SPEC/CINT2000/254.gap/254.gap llc /MultiSource/Benchmarks/MiBench/office-ispell/office-ispell llc-beta /MultiSource/Benchmarks/MiBench/office-ispell/office-ispell llc-beta /External/SPEC/CINT2000/254.gap/254.gap LowerMEMCPYInline() is asserting when the memcpy is 4-byte aligned but the size isn't multiple of 4. I'm going to remove the assertion and issue byte / word loads / stores to handle the trailing bytes. Please let me know if that's undesirable. 2. The stores are unnecessarily serialized. Each of them should use the load tokenfactor as input chain. All the chains produced by the stores should then be fed into a new tokenfactor. I'll fix this. Thanks, Evan On Oct 19, 2007, at 7:35 AM, Rafael Espindola wrote: > Author: rafael > Date: Fri Oct 19 09:35:17 2007 > New Revision: 43176 > > URL: http://llvm.org/viewvc/llvm-project?rev=43176&view=rev > Log: > split LowerMEMCPY into LowerMEMCPYCall and LowerMEMCPYInline in the > ARM backend. > > Modified: > llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > llvm/trunk/lib/Target/ARM/ARMISelLowering.h > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=43176&r1=43175&r2=43176&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Oct 19 > 09:35:17 2007 > @@ -1288,40 +1288,73 @@ > } > > SDOperand ARMTargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG > &DAG) { > - SDOperand Chain = Op.getOperand(0); > - SDOperand Dest = Op.getOperand(1); > - SDOperand Src = Op.getOperand(2); > - SDOperand Count = Op.getOperand(3); > - unsigned Align = > - (unsigned)cast(Op.getOperand(4))->getValue(); > + SDOperand ChainOp = Op.getOperand(0); > + SDOperand DestOp = Op.getOperand(1); > + SDOperand SourceOp = Op.getOperand(2); > + SDOperand CountOp = Op.getOperand(3); > + SDOperand AlignOp = Op.getOperand(4); > + SDOperand AlwaysInlineOp = Op.getOperand(5); > + > + bool AlwaysInline = (bool)cast(AlwaysInlineOp)- > >getValue(); > + unsigned Align = (unsigned)cast(AlignOp)- > >getValue(); > if (Align == 0) Align = 1; > > - ConstantSDNode *I = dyn_cast(Count); > - // Just call memcpy if: > - // not 4-byte aligned > - // size is unknown > - // size is >= the threshold. > - if ((Align & 3) != 0 || > - !I || > - I->getValue() >= 64 || > - (I->getValue() & 3) != 0) { > - MVT::ValueType IntPtr = getPointerTy(); > - TargetLowering::ArgListTy Args; > - TargetLowering::ArgListEntry Entry; > - Entry.Ty = getTargetData()->getIntPtrType(); > - Entry.Node = Op.getOperand(1); Args.push_back(Entry); > - Entry.Node = Op.getOperand(2); Args.push_back(Entry); > - Entry.Node = Op.getOperand(3); Args.push_back(Entry); > - std::pair CallResult = > + // If size is unknown, call memcpy. > + ConstantSDNode *I = dyn_cast(CountOp); > + if (!I) { > + assert(!AlwaysInline && "Cannot inline copy of unknown size"); > + return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); > + } > + unsigned Size = I->getValue(); > + > + if (AlwaysInline) > + return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, > Align, DAG); > + > + // The libc version is likely to be faster for the following > cases. It can > + // use the address value and run time information about the CPU. > + // With glibc 2.6.1 on a core 2, coping an array of 100M longs > was 30% faster > + > + // If not DWORD aligned, call memcpy. > + if ((Align & 3) != 0) > + return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); > + > + // If size is more than the threshold, call memcpy. > + // if (Size > Subtarget->getMinRepStrSizeThreshold()) > + if (Size >= 64) > + return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); > + > + return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, > DAG); > +} > + > +SDOperand ARMTargetLowering::LowerMEMCPYCall(SDOperand Chain, > + SDOperand Dest, > + SDOperand Source, > + SDOperand Count, > + SelectionDAG &DAG) { > + MVT::ValueType IntPtr = getPointerTy(); > + TargetLowering::ArgListTy Args; > + TargetLowering::ArgListEntry Entry; > + Entry.Ty = getTargetData()->getIntPtrType(); > + Entry.Node = Dest; Args.push_back(Entry); > + Entry.Node = Source; Args.push_back(Entry); > + Entry.Node = Count; Args.push_back(Entry); > + std::pair CallResult = > LowerCallTo(Chain, Type::VoidTy, false, false, CallingConv::C, > false, > DAG.getExternalSymbol("memcpy", IntPtr), Args, DAG); > - return CallResult.second; > - } > + return CallResult.second; > +} > + > +SDOperand ARMTargetLowering::LowerMEMCPYInline(SDOperand Chain, > + SDOperand Dest, > + SDOperand Source, > + unsigned Size, > + unsigned Align, > + SelectionDAG &DAG) { > > - // Otherwise do repeated 4-byte loads and stores. To be improved. > - assert((I->getValue() & 3) == 0); > + // Do repeated 4-byte loads and stores. To be improved. > + assert((Size& 3) == 0); > assert((Align & 3) == 0); > - unsigned NumMemOps = I->getValue() >> 2; > + unsigned NumMemOps = Size >> 2; > unsigned EmittedNumMemOps = 0; > unsigned SrcOff = 0, DstOff = 0; > MVT::ValueType VT = MVT::i32; > @@ -1337,7 +1370,7 @@ > unsigned i; > for (i=0; i ++) { > Loads[i] = DAG.getLoad(VT, Chain, > - DAG.getNode(ISD::ADD, VT, Src, > + DAG.getNode(ISD::ADD, VT, Source, > DAG.getConstant(SrcOff, VT)), > NULL, 0); > LoadChains[i] = Loads[i].getValue(1); > > Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=43176&r1=43175&r2=43176&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) > +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Oct 19 09:35:17 > 2007 > @@ -135,6 +135,14 @@ > SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); > SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG); > SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG); > + SDOperand LowerMEMCPYCall(SDOperand Chain, SDOperand Dest, > + SDOperand Source, SDOperand Count, > + SelectionDAG &DAG); > + SDOperand LowerMEMCPYInline(SDOperand Chain, SDOperand Dest, > + SDOperand Source, unsigned Size, > + unsigned Align, SelectionDAG &DAG); > + > + > }; > } > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From djg at cray.com Mon Oct 22 17:05:07 2007 From: djg at cray.com (Dan Gohman) Date: Mon, 22 Oct 2007 17:05:07 -0500 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html Message-ID: <20071022220507.GC22306@village.us.cray.com> > "Value" is the class used to represent a "register" in LLVM. The Codegen() method says to emit IR for that AST It would be good to mention that the "registers" here cannot be reassigned, as the word "register" might seem to imply. I don't know much you want to say about SSA at this point in the tutorial, or if you want to go into using entry-block Allocas and mem2reg to avoid having to compute SSA in a front-end here, but it's something that should be mentioned somewhere. > NumberExprAST(double val) : Val(val) {} > VariableExprAST(const std::string &name) : Name(name) {} These miss explicit keywords. > case '+': return Builder.CreateAdd(L, R, "addtmp"); > case '-': return Builder.CreateSub(L, R, "subtmp"); > case '*': return Builder.CreateMul(L, R, "multmp"); You might mention that the names "addtmp" and so on are automatically make unique by LLVM in case there's more than one add in the program, for example. Dan -- Dan Gohman, Cray Inc. From evan.cheng at apple.com Mon Oct 22 17:11:30 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Mon, 22 Oct 2007 22:11:30 -0000 Subject: [llvm-commits] [llvm] r43234 - in /llvm/trunk: lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/ARMISelLowering.h lib/Target/ARM/README-Thumb.txt test/CodeGen/ARM/memcpy-inline.ll Message-ID: <200710222211.l9MMBUk2032292@zion.cs.uiuc.edu> Author: evancheng Date: Mon Oct 22 17:11:27 2007 New Revision: 43234 URL: http://llvm.org/viewvc/llvm-project?rev=43234&view=rev Log: Fix memcpy lowering when addresses are 4-byte aligned but size is not multiple of 4. Added: llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.h llvm/trunk/lib/Target/ARM/README-Thumb.txt Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=43234&r1=43233&r2=43234&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Oct 22 17:11:27 2007 @@ -1287,7 +1287,8 @@ return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); } -SDOperand ARMTargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG) { +SDOperand ARMTargetLowering::LowerMEMCPY(SDOperand Op, SelectionDAG &DAG, + const ARMSubtarget *ST) { SDOperand ChainOp = Op.getOperand(0); SDOperand DestOp = Op.getOperand(1); SDOperand SourceOp = Op.getOperand(2); @@ -1305,25 +1306,18 @@ assert(!AlwaysInline && "Cannot inline copy of unknown size"); return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); } - unsigned Size = I->getValue(); - - if (AlwaysInline) - return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG); - // The libc version is likely to be faster for the following cases. It can + // If not DWORD aligned or if size is more than threshold, then call memcpy. + // The libc version is likely to be faster for the these cases. It can // use the address value and run time information about the CPU. // With glibc 2.6.1 on a core 2, coping an array of 100M longs was 30% faster - - // If not DWORD aligned, call memcpy. - if ((Align & 3) != 0) - return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); - - // If size is more than the threshold, call memcpy. - // if (Size > Subtarget->getMinRepStrSizeThreshold()) - if (Size >= 64) - return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); - - return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG); + // FIXME: For now, we don't lower memcpy's to loads / stores for Thumb. Change + // this once Thumb ldmia / stmia support is added. + unsigned Size = I->getValue(); + if (AlwaysInline || + (!ST->isThumb() && Size < 64 && (Align & 3) == 0)) + return LowerMEMCPYInline(ChainOp, DestOp, SourceOp, Size, Align, DAG); + return LowerMEMCPYCall(ChainOp, DestOp, SourceOp, CountOp, DAG); } SDOperand ARMTargetLowering::LowerMEMCPYCall(SDOperand Chain, @@ -1350,46 +1344,93 @@ unsigned Size, unsigned Align, SelectionDAG &DAG) { - - // Do repeated 4-byte loads and stores. To be improved. - assert((Size& 3) == 0); - assert((Align & 3) == 0); + // Do repeated 4-byte loads and stores. To be improved. + assert((Align & 3) == 0 && "Expected 4-byte aligned addresses!"); + unsigned BytesLeft = Size & 3; unsigned NumMemOps = Size >> 2; unsigned EmittedNumMemOps = 0; unsigned SrcOff = 0, DstOff = 0; MVT::ValueType VT = MVT::i32; unsigned VTSize = 4; + unsigned i = 0; const unsigned MAX_LOADS_IN_LDM = 6; - SDOperand LoadChains[MAX_LOADS_IN_LDM]; + SDOperand TFOps[MAX_LOADS_IN_LDM]; SDOperand Loads[MAX_LOADS_IN_LDM]; - // Emit up to 4 loads, then a TokenFactor barrier, then the same - // number of stores. The loads and stores will get combined into + // Emit up to MAX_LOADS_IN_LDM loads, then a TokenFactor barrier, then the + // same number of stores. The loads and stores will get combined into // ldm/stm later on. - while(EmittedNumMemOps < NumMemOps) { - unsigned i; - for (i=0; i= 2) { + VT = MVT::i16; + VTSize = 2; + } else { + VT = MVT::i8; + VTSize = 1; + } + + Loads[i] = DAG.getLoad(VT, Chain, + DAG.getNode(ISD::ADD, MVT::i32, Source, + DAG.getConstant(SrcOff, MVT::i32)), + NULL, 0); + TFOps[i] = Loads[i].getValue(1); + ++i; + SrcOff += VTSize; + BytesLeft -= VTSize; + } + Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i); + + i = 0; + BytesLeft = BytesLeftSave; + while (BytesLeft) { + if (BytesLeft >= 2) { + VT = MVT::i16; + VTSize = 2; + } else { + VT = MVT::i8; + VTSize = 1; + } + + TFOps[i] = DAG.getStore(Chain, Loads[i], + DAG.getNode(ISD::ADD, MVT::i32, Dest, + DAG.getConstant(DstOff, MVT::i32)), + NULL, 0); + ++i; + DstOff += VTSize; + BytesLeft -= VTSize; + } + return DAG.getNode(ISD::TokenFactor, MVT::Other, &TFOps[0], i); } SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -1419,7 +1460,7 @@ 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::MEMCPY: return LowerMEMCPY(Op, DAG, Subtarget); } return SDOperand(); } Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=43234&r1=43233&r2=43234&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Mon Oct 22 17:11:27 2007 @@ -130,11 +130,12 @@ SDOperand LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG); SDOperand LowerToTLSExecModels(GlobalAddressSDNode *GA, - SelectionDAG &DAG); + SelectionDAG &DAG); SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG); - SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerMEMCPY(SDOperand Op, SelectionDAG &DAG, + const ARMSubtarget *ST); SDOperand LowerMEMCPYCall(SDOperand Chain, SDOperand Dest, SDOperand Source, SDOperand Count, SelectionDAG &DAG); Modified: llvm/trunk/lib/Target/ARM/README-Thumb.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/README-Thumb.txt?rev=43234&r1=43233&r2=43234&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/README-Thumb.txt (original) +++ llvm/trunk/lib/Target/ARM/README-Thumb.txt Mon Oct 22 17:11:27 2007 @@ -221,3 +221,7 @@ Make register allocator / spiller smarter so we can re-materialize "mov r, imm", etc. Almost all Thumb instructions clobber condition code. + +//===---------------------------------------------------------------------===// + +Add ldmia, stmia support. Added: llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll?rev=43234&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll (added) +++ llvm/trunk/test/CodeGen/ARM/memcpy-inline.ll Mon Oct 22 17:11:27 2007 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldmia +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldrb +; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep ldrh + + %struct.x = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8 } + at src = external global %struct.x + at dst = external global %struct.x + +define i32 @t() { +entry: + call void @llvm.memcpy.i32( i8* getelementptr (%struct.x* @dst, i32 0, i32 0), i8* getelementptr (%struct.x* @src, i32 0, i32 0), i32 11, i32 8 ) + ret i32 0 +} + +declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) From resistor at mac.com Mon Oct 22 19:02:48 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 22 Oct 2007 19:02:48 -0500 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html Message-ID: <8ABBD4C2-17FD-4335-886C-F6A52C21F63A@mac.com> Dan, I'm planning to cover both of those points in the "Basic Topics" sections of the tutorial. --Owen -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/4856dd20/attachment.bin From owen at apple.com Mon Oct 22 18:11:24 2007 From: owen at apple.com (Owen Anderson) Date: Mon, 22 Oct 2007 18:11:24 -0500 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html Message-ID: Dan, I'm planning to cover both of those points in the "Basic Topics" sections of the tutorial. --Owen -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/5690c2b5/attachment.bin From owen at apple.com Mon Oct 22 18:11:24 2007 From: owen at apple.com (Owen Anderson) Date: Mon, 22 Oct 2007 18:11:24 -0500 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html Message-ID: Dan, I'm planning to cover both of those points in the "Basic Topics" sections of the tutorial. --Owen -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2555 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/5690c2b5/attachment-0001.bin From nlewycky at google.com Mon Oct 22 22:55:28 2007 From: nlewycky at google.com (Nicholas Lewycky) Date: Mon, 22 Oct 2007 20:55:28 -0700 Subject: [llvm-commits] makeinfo versions for llvm-gcc Message-ID: Hi, There's a problem with the makeinfo test in llvm-gcc where it checks for a makeinfo version >= 4.4. It treats 4.10 as less than 4.4 The attached patch should be applied to both llvm-gcc4.0 and 4.2. Thanks, Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/6dd8b20c/attachment.html From nlewycky at google.com Mon Oct 22 22:56:13 2007 From: nlewycky at google.com (Nicholas Lewycky) Date: Mon, 22 Oct 2007 20:56:13 -0700 Subject: [llvm-commits] makeinfo versions for llvm-gcc Message-ID: and this time with the attachment! Hi, There's a problem with the makeinfo test in llvm-gcc where it checks for a makeinfo version >= 4.4. It treats 4.10 as less than 4.4 The attached patch should be applied to both llvm-gcc4.0 and 4.2. Thanks, Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/7b59802f/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: makeinfo.patch Type: text/x-patch Size: 561 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071022/7b59802f/attachment.bin From clattner at apple.com Mon Oct 22 23:29:04 2007 From: clattner at apple.com (Chris Lattner) Date: Mon, 22 Oct 2007 21:29:04 -0700 Subject: [llvm-commits] [llvm] r43221 - in /llvm/trunk/docs/tutorial: LangImpl3.html index.html In-Reply-To: <20071022220507.GC22306@village.us.cray.com> References: <20071022220507.GC22306@village.us.cray.com> Message-ID: On Oct 22, 2007, at 3:05 PM, Dan Gohman wrote: >> "Value" is the class used to represent a "register" in LLVM. The >> Codegen() method says to emit IR for that AST > > It would be good to mention that the "registers" here cannot be > reassigned, > as the word "register" might seem to imply. Good idea. > I don't know much you want to say about SSA at this point in the > tutorial, > or if you want to go into using entry-block Allocas and mem2reg to > avoid > having to compute SSA in a front-end here, but it's something that > should > be mentioned somewhere. I plan to unveil it slowly: in the if/then/else chapter, I'll talk about phi nodes. In the "mutable variables" chapter, I'll talk about the alloca trick. >> NumberExprAST(double val) : Val(val) {} > >> VariableExprAST(const std::string &name) : Name(name) {} > > These miss explicit keywords. *grumble* explicit should be the default *grumble* :) >> case '+': return Builder.CreateAdd(L, R, "addtmp"); >> case '-': return Builder.CreateSub(L, R, "subtmp"); >> case '*': return Builder.CreateMul(L, R, "multmp"); > > You might mention that the names "addtmp" and so on are automatically > make unique by LLVM in case there's more than one add in the program, > for example. will do! -Chris From sabre at nondot.org Mon Oct 22 23:51:30 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 04:51:30 -0000 Subject: [llvm-commits] [llvm] r43238 - /llvm/trunk/docs/tutorial/LangImpl3.html Message-ID: <200710230451.l9N4pUiZ019001@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 23:51:30 2007 New Revision: 43238 URL: http://llvm.org/viewvc/llvm-project?rev=43238&view=rev Log: Finish up expr codegen. Modified: llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43238&r1=43237&r2=43238&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Mon Oct 22 23:51:30 2007 @@ -132,12 +132,13 @@
  • -

    In the LLVM IR, numeric constants are represented with the ConstantFP class, -which holds the numeric value in an APFloat internally (APFloat has the -capability of holding floating point constants of arbitrary precision). This -code basically just creates and returns a ConstantFP. Note that in the LLVM IR +

    In the LLVM IR, numeric constants are represented with the +ConstantFP class, which holds the numeric value in an APFloat +internally (APFloat has the capability of holding floating point +constants of Arbitrary Precision). This code basically just +creates and returns a ConstantFP. Note that in the LLVM IR that constants are all uniqued together and shared. For this reason, the API -uses "the foo::get(...)" idiom instead of a "create" method or "new foo".

    +uses "the foo::get(..)" idiom instead of "new foo(..)" or "foo::create(..).

    @@ -149,9 +150,10 @@
     
    -

    References to variables is also quite simple here. In our system, we assume -that the variable has already been emited somewhere and its value is available. -In practice, the only values in the NamedValues map will be arguments. This +

    References to variables is also quite simple here. In the simple version +of Kaleidoscope, we assume that the variable has already been emited somewhere +and its value is available. In practice, the only values that can be in the +NamedValues map are function arguments. This code simply checks to see that the specified name is in the map (if not, an unknown variable is being referenced) and returns the value for it.

    @@ -176,7 +178,38 @@ - +

    Binary operators start to get more interesting. The basic idea here is that +we recursively emit code for the left-hand side of the expression, then the +right-hand side, then we compute the result of the binary expression. In this +code, we do a simple switch on the opcode to create the right LLVM instruction. +

    + +

    In this example, the LLVM builder class is starting to show its value. +Because it knows where to insert the newly created instruction, you just have to +specificy what instruction to create (e.g. with CreateAdd), which +operands to use (L and R here) and optionally provide a name +for the generated instruction. One nice thing about LLVM is that the name is +just a hint: if there are multiple additions in a single function, the first +will be named "addtmp" and the second will be "autorenamed" by adding a suffix, +giving it a name like "addtmp42". Local value names for instructions are purely +optional, but it makes it much easier to read the IR dumps.

    + +

    LLVM instructions are constrained to +have very strict type properties: for example, the Left and Right operators of +an add instruction have to have the same +type, and that the result of the add matches the operands. Because all values +in Kaleidoscope are doubles, this makes for very simple code for add, sub and +mul.

    + +

    On the other hand, LLVM specifies that the fcmp instruction always returns an 'i1' value +(a one bit integer). However, Kaleidoscope wants the value to be a 0.0 or 1.0 +value. In order to get these semantics, we combine the fcmp instruction with +a uitofp instruction. This instruction +converts its input integer into a floating point value by treating the input +as an unsigned value. In contrast, if we used the sitofp instruction, the Kaleidoscope '<' +operator would return 0.0 and -1.0, depending on the input value.

    @@ -201,7 +234,24 @@
     
    -

    more todo

    +

    Code generation for function calls is quite straight-forward with LLVM. The +code above first looks the name of the function up in the LLVM Module's symbol +table. Recall that the LLVM Module is the container that holds all of the +functions we are JIT'ing. By giving each function the same name as what the +user specifies, we can use the LLVM symbol table to resolve function names for +us.

    + +

    Once we have the function to call, we recursively codegen each argument that +is to be passed in, and create an LLVM call +instruction. Note that LLVM uses the native C calling conventions by +default, allowing these calls to call into standard library functions like +"sin" and "cos" with no additional effort.

    + +

    This wraps up our handling of the four basic expressions that we have so far +in Kaleidoscope. Feel free to go in and add some more. For example, by +browsing the LLVM language reference you'll find +several other interesting instructions that are really easy to plug into our +basic framework.

    From sabre at nondot.org Mon Oct 22 23:27:45 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 04:27:45 -0000 Subject: [llvm-commits] [llvm] r43237 - in /llvm/trunk/docs/tutorial: LangImpl2.html LangImpl3.html Message-ID: <200710230427.l9N4RkmV018163@zion.cs.uiuc.edu> Author: lattner Date: Mon Oct 22 23:27:44 2007 New Revision: 43237 URL: http://llvm.org/viewvc/llvm-project?rev=43237&view=rev Log: several improvements suggested by Dan, thanks! Modified: llvm/trunk/docs/tutorial/LangImpl2.html llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43237&r1=43236&r2=43237&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Mon Oct 22 23:27:44 2007 @@ -65,7 +65,7 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} + explicit NumberExprAST(double val) : Val(val) {} }; @@ -87,7 +87,7 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} + explicit VariableExprAST(const std::string &name) : Name(name) {} }; /// BinaryExprAST - Expression class for a binary operator. @@ -850,14 +850,14 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} + explicit NumberExprAST(double val) : Val(val) {} }; /// VariableExprAST - Expression class for referencing a variable, like "a". class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} + explicit VariableExprAST(const std::string &name) : Name(name) {} }; /// BinaryExprAST - Expression class for a binary operator. Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43237&r1=43236&r2=43237&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Mon Oct 22 23:27:44 2007 @@ -56,15 +56,26 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} + explicit NumberExprAST(double val) : Val(val) {} virtual Value *Codegen(); }; ... -

    "Value" is the class used to represent a "register" in LLVM. The Codegen() -method says to emit IR for that AST node and all things it depends on. The +

    The Codegen() method says to emit IR for that AST node and all things it +depends on, and they all return an LLVM Value object. +"Value" is the class used to represent a "Static Single +Assignment (SSA) register" or "SSA value" in LLVM. The most distinct aspect +of SSA values is that their value is computed as the related instruction +executes, and it does not get a new value until (and if) the instruction +re-executes. In order words, there is no way to "change" an SSA value. For +more information, please read up on Static Single +Assignment - the concepts are really quite natural once you grok them.

    + +

    The second thing we want is an "Error" method like we used for parser, which will be used to report errors found during code generation (for example, use of an undeclared parameter):

    @@ -299,7 +310,7 @@ class NumberExprAST : public ExprAST { double Val; public: - NumberExprAST(double val) : Val(val) {} + explicit NumberExprAST(double val) : Val(val) {} virtual Value *Codegen(); }; @@ -307,7 +318,7 @@ class VariableExprAST : public ExprAST { std::string Name; public: - VariableExprAST(const std::string &name) : Name(name) {} + explicit VariableExprAST(const std::string &name) : Name(name) {} virtual Value *Codegen(); }; From sabre at nondot.org Tue Oct 23 00:43:01 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 05:43:01 -0000 Subject: [llvm-commits] [llvm] r43239 - /llvm/trunk/docs/tutorial/LangImpl2.html Message-ID: <200710230543.l9N5h1vd021070@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 00:43:01 2007 New Revision: 43239 URL: http://llvm.org/viewvc/llvm-project?rev=43239&view=rev Log: Fix up a broken #include, move code to its own section, add conclusions. Modified: llvm/trunk/docs/tutorial/LangImpl2.html Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43239&r1=43238&r2=43239&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Tue Oct 23 00:43:01 2007 @@ -753,20 +753,40 @@ +

    There is a lot of room for extension here. You can define new AST nodes, +extend the language in many ways, etc. In the next +installment, we will describe how to generate LLVM IR from the AST.

    + + + + +
    Full Code Listing
    + + +
    +

    -Here is the full code. Note that it is fully self-contained: you don't even -need LLVM for this. In the next installment, we -will describe how to generate LLVM IR from the AST.

    +Here is the complete code listing for this and the previous chapter. +Note that it is fully self-contained: you don't need LLVM or any external +libraries at all for this (other than the C and C++ standard libraries of +course). To build this, just compile with:

    -// To build this:
    -//  g++ -g toy.cpp 
    -//  ./a.out 
    +   # Compile
    +   g++ -g toy.cpp 
    +   # Run
    +   ./a.out 
    +
    +
    +

    Here is the code:

    + +
    +
     #include <cstdio>
     #include <string>
    -#include <
    +#include <map>
     #include <vector>
     
     //===----------------------------------------------------------------------===//
    
    
    
    
    From resistor at mac.com  Tue Oct 23 01:02:15 2007
    From: resistor at mac.com (Owen Anderson)
    Date: Tue, 23 Oct 2007 06:02:15 -0000
    Subject: [llvm-commits] [llvm] r43240 - /llvm/trunk/docs/tutorial/index.html
    Message-ID: <200710230602.l9N62FKO021898@zion.cs.uiuc.edu>
    
    Author: resistor
    Date: Tue Oct 23 01:02:14 2007
    New Revision: 43240
    
    URL: http://llvm.org/viewvc/llvm-project?rev=43240&view=rev
    Log:
    Reorder the optimization and bitcode tutorials.
    
    Modified:
        llvm/trunk/docs/tutorial/index.html
    
    Modified: llvm/trunk/docs/tutorial/index.html
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43240&r1=43239&r2=43240&view=diff
    
    ==============================================================================
    --- llvm/trunk/docs/tutorial/index.html (original)
    +++ llvm/trunk/docs/tutorial/index.html Tue Oct 23 01:02:14 2007
    @@ -20,8 +20,8 @@
         
    1. A First Function
    2. A More Complicated Function
    3. -
    4. Reading and Writing Bitcode
    5. -
    6. Running Optimizations
    7. +
    8. Running Optimizations
    9. +
    10. Reading and Writing Bitcode
    11. Invoking the JIT
    From resistor at mac.com Tue Oct 23 01:03:24 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 06:03:24 -0000 Subject: [llvm-commits] [llvm] r43241 - in /llvm/trunk/docs/tutorial: JITTutorial2-1.png JITTutorial2.html index.html Message-ID: <200710230603.l9N63O9o021947@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 01:03:24 2007 New Revision: 43241 URL: http://llvm.org/viewvc/llvm-project?rev=43241&view=rev Log: Add the second of the "basic topics" tutorials. Added: llvm/trunk/docs/tutorial/JITTutorial2-1.png (with props) llvm/trunk/docs/tutorial/JITTutorial2.html Modified: llvm/trunk/docs/tutorial/index.html Added: llvm/trunk/docs/tutorial/JITTutorial2-1.png URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2-1.png?rev=43241&view=auto ============================================================================== Binary file - no diff available. Propchange: llvm/trunk/docs/tutorial/JITTutorial2-1.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: llvm/trunk/docs/tutorial/JITTutorial2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=43241&view=auto ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (added) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Tue Oct 23 01:03:24 2007 @@ -0,0 +1,186 @@ + + + + + LLVM Tutorial 2: A More Complicated Function + + + + + + + + +
    LLVM Tutorial 2: A More Complicated Function
    + +
    +

    Written by Owen Anderson

    +
    + + + + + +
    +All the code in this example can be downloaded at Tutorial2.tar.bz2 or Tutorial2.zip. +
    + + + + + +
    + +

    Now that we understand the basics of creating functions in LLVM, let's move on to a more complicated example: something with control flow. As an example, let's consider Euclid's Greatest Common Denominator (GCD) algorithm:

    + +
    +
    +unsigned gcd(unsigned x, unsigned y) {
    +  if(x == y) {
    +    return x;
    +  } else if(x < y) {
    +    return gcd(x, y - x);
    +  } else {
    +    return gcd(x - y, y);
    +  }
    +}
    +
    +
    + +

    With this example, we'll learn how to create functions with multiple blocks and control flow, and how to make function calls within your LLVM code. For starters, consider the diagram below.

    + +
    GCD CFG
    + +

    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 the have the same prototype as our mul_add function.

    + +
    +
    +#include <llvm/Module.h>
    +#include <llvm/Function.h>
    +#include <llvm/PassManager.h>
    +#include <llvm/Analysis/Verifier.h>
    +#include <llvm/Assembly/PrintModulePass.h>
    +#include <llvm/Support/LLVMBuilder.h>
    +
    +using namespace llvm;
    +
    +Module* makeLLVMModule();
    +
    +int main(int argc, char**argv) {
    +  Module* Mod = makeLLVMModule();
    +  
    +  verifyModule(*Mod, PrintMessageAction);
    +  
    +  PassManager PM;
    +  PM.add(new PrintModulePass(&llvm::cout));
    +  PM.run(*Mod);
    +  
    +  return 0;
    +}
    +
    +Module* makeLLVMModule() {
    +  Module* mod = new Module("tut2");
    +  
    +  Constant* c = mod->getOrInsertFunction("gcd",
    +                                         IntegerType::get(32),
    +                                         IntegerType::get(32),
    +                                         IntegerType::get(32),
    +                                         NULL);
    +  Function* gcd = cast(c);
    +  
    +  Function::arg_iterator args = gcd->arg_begin();
    +  Value* x = args++;
    +  x->setName("x");
    +  Value* y = args++;
    +  y->setName("y");
    +
    +
    + +

    Here, however, is where our code begins to diverge from the first tutorial. Because gcd has control flow, it is composed of multiple blocks interconnected by branching (br) instructions. For those familiar with assembly language, a block is similar to a labeled set of instructions. For those not familiar with assembly language, a block is basically a set of instructions that can be branched to and is executed linearly until the block is terminated by one of a small number of control flow instructions, such as br or ret.

    + +

    Blocks corresponds to the nodes in the diagram we looked at in the beginning of this tutorial. From the diagram, we can see that this function contains five blocks, so we'll go ahead and create them. Note that, in this code sample, we're making use of LLVM's automatic name uniquing, since we're giving two blocks the same name.

    + +
    +
    +  BasicBlock* entry = new BasicBlock("entry", gcd);
    +  BasicBlock* ret = new BasicBlock("return", gcd);
    +  BasicBlock* cond_false = new BasicBlock("cond_false", gcd);
    +  BasicBlock* cond_true = new BasicBlock("cond_true", gcd);
    +  BasicBlock* cond_false_2 = new BasicBlock("cond_false", gcd);
    +
    +
    + +

    Now, we're ready to begin generate code! We'll start with the entry block. This block corresponds to the top-level if-statement in the original C code, so we need to compare x == y To achieve this, we perform an explicity comparison using ICmpEQ. ICmpEQ stands for an integer comparison for equality and returns a 1-bit integer result. This 1-bit result is then used as the input to a conditional branch, with ret as the true and cond_false as the false case.

    + +
    +
    +  LLVMBuilder builder(entry);
    +  Value* xEqualsY = builder.CreateICmpEQ(x, y, "tmp");
    +  builder.CreateCondBr(xEqualsY, ret, cond_false);
    +
    +
    + +

    Our next block, ret, is pretty simple: it just returns the value of x. Recall that this block is only reached if x == y, so this is the correct behavior. Notice that, instead of creating a new LLVMBuilder for each block, we can use SetInsertPoint to retarget our existing one. This saves on construction and memory allocation costs.

    + +
    +
    +  builder.SetInsertPoint(ret);
    +  builder.CreateRet(x);
    +
    +
    + +

    cond_false is a more interesting block: we now know that x != y, so we must branch again to determine which of x and y is larger. This is achieved using the ICmpULT instruction, which stands for integer comparison for unsigned less-than. In LLVM, integer types do not carry sign; a 32-bit integer pseudo-register can interpreted as signed or unsigned without casting. Whether a signed or unsigned interpretation is desired is specified in the instruction. This is why several instructions in the LLVM IR, such as integer less-than, include a specifier for signed or unsigned.

    + +

    Also, note that we're again making use of LLVM's automatic name uniquing, this time at a register level. We've deliberately chosen to name every instruction "tmp", to illustrate that LLVM will give them all unique names without getting confused.

    + +
    +
    +  builder.SetInsertPoint(cond_false);
    +  Value* xLessThanY = builder.CreateICmpULT(x, y, "tmp");
    +  builder.CreateCondBr(xLessThanY, cond_true, cond_false_2);
    +
    +
    + +

    Our last two blocks are quite similar; they're both recursive calls to gcd with different parameters. To create a call instruction, we have to create a vector (or any other container with InputInterators) to hold the arguments. We then pass in the beginning and ending iterators for this vector.

    + +
    +
    +  builder.SetInsertPoint(cond_true);
    +  Value* yMinusX = builder.CreateSub(y, x, "tmp");
    +  std::vector args1;
    +  args1.push_back(x);
    +  args1.push_back(yMinusX);
    +  Value* recur_1 = builder.CreateCall(gcd, args1.begin(), args1.end(), "tmp");
    +  builder.CreateRet(recur_1);
    +  
    +  builder.SetInsertPoint(cond_false_2);
    +  Value* xMinusY = builder.CreateSub(x, y, "tmp");
    +  std::vector args2;
    +  args2.push_back(xMinusY);
    +  args2.push_back(y);
    +  Value* recur_2 = builder.CreateCall(gcd, args2.begin(), args2.end(), "tmp");
    +  builder.CreateRet(recur_2);
    +  
    +  return mod;
    +}
    +
    +
    + +

    And that's it! You can compile your code and execute your code in the same way as before, by executing:

    + +
    +
    +# c++ -g tut2.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    +                  `llvm-config --libs core` -o tut2
    +# ./tut2
    +
    +
    + +
    + + + \ No newline at end of file Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43241&r1=43240&r2=43241&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Tue Oct 23 01:03:24 2007 @@ -19,7 +19,7 @@
  • Simple JIT Tutorials
    1. A First Function
    2. -
    3. A More Complicated Function
    4. +
    5. A More Complicated Function
    6. Running Optimizations
    7. Reading and Writing Bitcode
    8. Invoking the JIT
    9. From resistor at mac.com Tue Oct 23 01:05:39 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 06:05:39 -0000 Subject: [llvm-commits] [llvm] r43242 - in /llvm/trunk/docs/tutorial: JITTutorial2.html Tutorial2.tar.bz2 Tutorial2.zip Message-ID: <200710230605.l9N65dSk022039@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 01:05:37 2007 New Revision: 43242 URL: http://llvm.org/viewvc/llvm-project?rev=43242&view=rev Log: Add downloadable code sample for tutorial 2. Added: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 (with props) llvm/trunk/docs/tutorial/Tutorial2.zip (with props) 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=43242&r1=43241&r2=43242&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Tue Oct 23 01:05:37 2007 @@ -24,7 +24,7 @@
      -All the code in this example can be downloaded at Tutorial2.tar.bz2 or Tutorial2.zip. +All the code in this example can be downloaded at Tutorial2.tar.bz2 or Tutorial2.zip.
      Added: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.tar.bz2?rev=43242&view=auto ============================================================================== Binary file - no diff available. Propchange: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: llvm/trunk/docs/tutorial/Tutorial2.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.zip?rev=43242&view=auto ============================================================================== Binary file - no diff available. Propchange: llvm/trunk/docs/tutorial/Tutorial2.zip ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream From resistor at mac.com Tue Oct 23 01:17:39 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 06:17:39 -0000 Subject: [llvm-commits] [llvm] r43243 - /llvm/trunk/docs/tutorial/index.html Message-ID: <200710230617.l9N6HdH2022434@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 01:17:39 2007 New Revision: 43243 URL: http://llvm.org/viewvc/llvm-project?rev=43243&view=rev Log: Add a link to the "writing an optimization" tutorial. Modified: llvm/trunk/docs/tutorial/index.html Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43243&r1=43242&r2=43243&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Tue Oct 23 01:17:39 2007 @@ -36,6 +36,10 @@
    10. Extending the language: mutable variables
    11. Thoughts and ideas for extensions
  • +
  • Advanced Topics +
      +
    1. Writing an Optimization for LLVM
    2. +
  • From resistor at mac.com Tue Oct 23 01:22:22 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 06:22:22 -0000 Subject: [llvm-commits] [llvm] r43244 - /llvm/trunk/docs/tutorial/JITTutorial2.html Message-ID: <200710230622.l9N6MMmB022663@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 01:22:21 2007 New Revision: 43244 URL: http://llvm.org/viewvc/llvm-project?rev=43244&view=rev Log: Now with valid HTML 4.01! 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=43244&r1=43243&r2=43244&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Tue Oct 23 01:22:21 2007 @@ -51,9 +51,9 @@

    With this example, we'll learn how to create functions with multiple blocks and control flow, and how to make function calls within your LLVM code. For starters, consider the diagram below.

    -
    GCD CFG
    +
    GCD CFG
    -

    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 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 the have the same prototype as our mul_add function.

    @@ -76,27 +76,27 @@ verifyModule(*Mod, PrintMessageAction); PassManager PM; - PM.add(new PrintModulePass(&llvm::cout)); + PM.add(new PrintModulePass(&llvm::cout)); PM.run(*Mod); return 0; } Module* makeLLVMModule() { - Module* mod = new Module("tut2"); + Module* mod = new Module("tut2"); - Constant* c = mod->getOrInsertFunction("gcd", + Constant* c = mod->getOrInsertFunction("gcd", IntegerType::get(32), IntegerType::get(32), IntegerType::get(32), NULL); - Function* gcd = cast(c); + Function* gcd = cast<Function>(c); - Function::arg_iterator args = gcd->arg_begin(); + Function::arg_iterator args = gcd->arg_begin(); Value* x = args++; - x->setName("x"); + x->setName("x"); Value* y = args++; - y->setName("y"); + y->setName("y");
    @@ -106,11 +106,11 @@
    -  BasicBlock* entry = new BasicBlock("entry", gcd);
    -  BasicBlock* ret = new BasicBlock("return", gcd);
    -  BasicBlock* cond_false = new BasicBlock("cond_false", gcd);
    -  BasicBlock* cond_true = new BasicBlock("cond_true", gcd);
    -  BasicBlock* cond_false_2 = new BasicBlock("cond_false", gcd);
    +  BasicBlock* entry = new BasicBlock("entry", gcd);
    +  BasicBlock* ret = new BasicBlock("return", gcd);
    +  BasicBlock* cond_false = new BasicBlock("cond_false", gcd);
    +  BasicBlock* cond_true = new BasicBlock("cond_true", gcd);
    +  BasicBlock* cond_false_2 = new BasicBlock("cond_false", gcd);
     
    @@ -119,7 +119,7 @@
       LLVMBuilder builder(entry);
    -  Value* xEqualsY = builder.CreateICmpEQ(x, y, "tmp");
    +  Value* xEqualsY = builder.CreateICmpEQ(x, y, "tmp");
       builder.CreateCondBr(xEqualsY, ret, cond_false);
     
    @@ -140,7 +140,7 @@
       builder.SetInsertPoint(cond_false);
    -  Value* xLessThanY = builder.CreateICmpULT(x, y, "tmp");
    +  Value* xLessThanY = builder.CreateICmpULT(x, y, "tmp");
       builder.CreateCondBr(xLessThanY, cond_true, cond_false_2);
     
    @@ -150,19 +150,19 @@
       builder.SetInsertPoint(cond_true);
    -  Value* yMinusX = builder.CreateSub(y, x, "tmp");
    -  std::vector args1;
    +  Value* yMinusX = builder.CreateSub(y, x, "tmp");
    +  std::vector<Value*> args1;
       args1.push_back(x);
       args1.push_back(yMinusX);
    -  Value* recur_1 = builder.CreateCall(gcd, args1.begin(), args1.end(), "tmp");
    +  Value* recur_1 = builder.CreateCall(gcd, args1.begin(), args1.end(), "tmp");
       builder.CreateRet(recur_1);
       
       builder.SetInsertPoint(cond_false_2);
    -  Value* xMinusY = builder.CreateSub(x, y, "tmp");
    -  std::vector args2;
    +  Value* xMinusY = builder.CreateSub(x, y, "tmp");
    +  std::vector<Value*> args2;
       args2.push_back(xMinusY);
       args2.push_back(y);
    -  Value* recur_2 = builder.CreateCall(gcd, args2.begin(), args2.end(), "tmp");
    +  Value* recur_2 = builder.CreateCall(gcd, args2.begin(), args2.end(), "tmp");
       builder.CreateRet(recur_2);
       
       return mod;
    
    
    
    
    From sabre at nondot.org  Tue Oct 23 01:23:57 2007
    From: sabre at nondot.org (Chris Lattner)
    Date: Tue, 23 Oct 2007 06:23:57 -0000
    Subject: [llvm-commits] [llvm] r43245 - in /llvm/trunk/docs/tutorial:
    	LangImpl2.html LangImpl3.html
    Message-ID: <200710230623.l9N6Nv2p022730@zion.cs.uiuc.edu>
    
    Author: lattner
    Date: Tue Oct 23 01:23:57 2007
    New Revision: 43245
    
    URL: http://llvm.org/viewvc/llvm-project?rev=43245&view=rev
    Log:
    complete the codegen chapter
    
    Modified:
        llvm/trunk/docs/tutorial/LangImpl2.html
        llvm/trunk/docs/tutorial/LangImpl3.html
    
    Modified: llvm/trunk/docs/tutorial/LangImpl2.html
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43245&r1=43244&r2=43245&view=diff
    
    ==============================================================================
    --- llvm/trunk/docs/tutorial/LangImpl2.html (original)
    +++ llvm/trunk/docs/tutorial/LangImpl2.html Tue Oct 23 01:23:57 2007
    @@ -738,17 +738,17 @@
     
     $ ./a.out 
    -ready> def foo(x y) x+foo(y, 4.0);
    -ready> Parsed an function definition.
    -ready> def foo(x y) x+y y;
    -ready> Parsed an function definition.
    -ready> Parsed a top-level expr
    -ready> def foo(x y) x+y );
    -ready> Parsed an function definition.
    -ready> Error: unknown token when expecting an expression
    -ready> extern sin(a);
    -ready> Parsed an extern
    -ready> ^D
    +ready> def foo(x y) x+foo(y, 4.0);
    +ready> Parsed an function definition.
    +ready> def foo(x y) x+y y;
    +ready> Parsed an function definition.
    +ready> Parsed a top-level expr
    +ready> def foo(x y) x+y );
    +ready> Parsed an function definition.
    +ready> Error: unknown token when expecting an expression
    +ready> extern sin(a);
    +ready> Parsed an extern
    +ready> ^D
     $ 
     
    Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43245&r1=43244&r2=43245&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Tue Oct 23 01:23:57 2007 @@ -256,17 +256,372 @@
    -
    Conclusions and the Full Code
    +
    Function Code Generation
    +

    Code generation for prototypes and functions has to handle a number of +details, which make their code less beautiful and elegant than expression code +generation, but they illustrate some important points. First, lets talk about +code generation for prototypes: this is used both for function bodies as well +as external function declarations. The code starts with:

    + +
    +
    +Function *PrototypeAST::Codegen() {
    +  // Make the function type:  double(double,double) etc.
    +  std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy);
    +  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
    +  
    +  Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
    +
    +
    + +

    This code packs a lot of power into a few lines. The first step is to create +the FunctionType that should be used for a given Prototype. Since all +function arguments in Kaleidoscope are of type double, the first line creates +a vector of "N" LLVM Double types. It then uses the FunctionType::get +method to create a function type that takes "N" doubles as arguments, returns +one double as a result, and that is not vararg (the false parameter indicates +this). Note that Types in LLVM are uniqued just like Constants are, so you +don't "new" a type, you "get" it.

    + +

    The final line above actually creates the function that the prototype will +correspond to. This indicates which type, linkage, and name to use, and which +module to insert into. "external linkage" +means that the function may be defined outside the current module and/or that it +is callable by functions outside the module. The Name passed in is the name the +user specified: since "TheModule" is specified, this name is registered +in "TheModule"s symbol table, which is used by the function call code +above.

    + +
    +
    +  // If F conflicted, there was already something named 'Name'.  If it has a
    +  // body, don't allow redefinition or reextern.
    +  if (F->getName() != Name) {
    +    // Delete the one we just made and get the existing one.
    +    F->eraseFromParent();
    +    F = TheModule->getFunction(Name);
    +
    +
    + +

    The Module symbol table works just like the Function symbol table when it +comes to name conflicts: if a new function is created with a name was previously +added to the symbol table, it will get implicitly renamed when added to the +Module. The code above exploits this fact to tell if there was a previous +definition of this function.

    + +

    In Kaleidoscope, I choose to allow redefinitions of functions in two cases: +first, we want to allow 'extern'ing a function more than once, so long as the +prototypes for the externs match (since all arguments have the same type, we +just have to check that the number of arguments match). Second, we want to +allow 'extern'ing a function and then definining a body for it. This is useful +when defining mutually recursive functions.

    + +

    In order to implement this, the code above first checks to see if there is +a collision on the name of the function. If so, it deletes the function we just +created (by calling eraseFromParent) and then calling +getFunction to get the existing function with the specified name. Note +that many APIs in LLVM have "erase" forms and "remove" forms. The "remove" form +unlinks the object from its parent (e.g. a Function from a Module) and returns +it. The "erase" form unlinks the object and then deletes it.

    + +
    +
    +    // If F already has a body, reject this.
    +    if (!F->empty()) {
    +      ErrorF("redefinition of function");
    +      return 0;
    +    }
    +    
    +    // If F took a different number of args, reject.
    +    if (F->arg_size() != Args.size()) {
    +      ErrorF("redefinition of function with different # args");
    +      return 0;
    +    }
    +  }
    +
    +
    + +

    In order to verify the logic above, we first check to see if the preexisting +function is "empty". In this case, empty means that it has no basic blocks in +it, which means it has no body. If it has no body, this means its a forward +declaration. Since we don't allow anything after a full definition of the +function, the code rejects this case. If the previous reference to a function +was an 'extern', we simply verify that the number of arguments for that +definition and this one match up. If not, we emit an error.

    + +
    +
    +  // Set names for all arguments.
    +  unsigned Idx = 0;
    +  for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size();
    +       ++AI, ++Idx) {
    +    AI->setName(Args[Idx]);
    +    
    +    // Add arguments to variable symbol table.
    +    NamedValues[Args[Idx]] = AI;
    +  }
    +  return F;
    +}
    +
    +
    + +

    The last bit of code for prototypes loops over all of the arguments in the +function, setting the name of the LLVM Argument objects to match and registering +the arguments in the NamedValues map for future use by the +VariableExprAST AST node. Once this is set up, it returns the Function +object to the caller. Note that we don't check for conflicting +argument names here (e.g. "extern foo(a b a)"). Doing so would be very +straight-forward.

    + +
    +
    +Function *FunctionAST::Codegen() {
    +  NamedValues.clear();
    +  
    +  Function *TheFunction = Proto->Codegen();
    +  if (TheFunction == 0)
    +    return 0;
    +
    +
    + +

    Code generation for function definitions starts out simply enough: first we +codegen the prototype and verify that it is ok. We also clear out the +NamedValues map to make sure that there isn't anything in it from the +last function we compiled.

    + +
    +
    +  // Create a new basic block to start insertion into.
    +  BasicBlock *BB = new BasicBlock("entry", TheFunction);
    +  Builder.SetInsertPoint(BB);
    +  
    +  if (Value *RetVal = Body->Codegen()) {
    +    // Finish off the function.
    +    Builder.CreateRet(RetVal);
    +    return TheFunction;
    +  }
    +
    +
    + +

    Now we get to the point where the Builder is set up. The first +line creates a new basic +block (named "entry"), which is inserted into TheFunction. The +second line then tells the builder that new instructions should be inserted into +the end of the new basic block. Basic blocks in LLVM are an important part +of functions that define the Control Flow Graph. +Since we don't have any control flow, our functions will only contain one +block so far. We'll fix this in a future installment :).

    + +

    Once the insertion point is set up, we call the CodeGen() method for +the root expression of the function. If no error happens, this emits code to +compute the expression into the entry block and returns the value that was +computed. Assuming no error, we then create an LLVM ret instruction. This completes the function, +which is then returned.

    + +
    +
    +  // Error reading body, remove function.
    +  TheFunction->eraseFromParent();
    +  return 0;
    +}
    +
    +
    + +

    The only piece left here is handling of the error case. For simplicity, we +simply handle this by deleting the function we produced with the +eraseFromParent method. This allows the user to redefine a function +that they incorrectly typed in before: if we didn't delete it, it would live in +the symbol table, with a body, preventing future redefinition.

    + +

    This code does have a bug though. Since the PrototypeAST::Codegen +can return a previously defined forward declaration, this can actually delete +a forward declaration. There are a number of ways to fix this bug, see what you +can come up with! Here is a testcase:

    + +
    +
    +extern foo(a b);     # ok, defines foo.
    +def foo(a b) c;      # error, 'c' is invalid.
    +def bar() foo(1, 2); # error, unknown function "foo"
    +
    +
    + +
    + + +
    Driver Changes and +Closing Thoughts
    + + +
    + +

    +For now, code generation to LLVM doesn't really get us much, except that we can +look at the pretty IR calls. The sample code inserts calls to Codegen into the +"HandleDefinition", "HandleExtern" etc functions, and then +dumps out the LLVM IR. This gives a nice way to look at the LLVM IR for simple +functions. For example: +

    + +
    +
    +ready> 4+5;
    +ready> Read top-level expression:
    +define double @""() {
    +entry:
    +        %addtmp = add double 4.000000e+00, 5.000000e+00
    +        ret double %addtmp
    +}
    +
    +
    + +

    Note how the parser turns the top-level expression into anonymous functions +for us. This will be handy when we add JIT support in the next chapter. Also +note that the code is very literally transcribed, no optimizations are being +performed. We will add optimizations explicitly in the next chapter.

    + +
    +
    +ready> def foo(a b) a*a + 2*a*b + b*b;
    +ready> Read function definition:
    +define double @foo(double %a, double %b) {
    +entry:
    +        %multmp = mul double %a, %a
    +        %multmp1 = mul double 2.000000e+00, %a
    +        %multmp2 = mul double %multmp1, %b
    +        %addtmp = add double %multmp, %multmp2
    +        %multmp3 = mul double %b, %b
    +        %addtmp4 = add double %addtmp, %multmp3
    +        ret double %addtmp4
    +}
    +
    +
    + +

    This shows some simple arithmetic. Notice the striking similarity to the +LLVM builder calls that we use to create the instructions.

    + +
    +
    +ready> def bar(a) foo(a, 4.0) + bar(31337);
    +ready> Read function definition:
    +define double @bar(double %a) {
    +entry:
    +        %calltmp = call double @foo( double %a, double 4.000000e+00 )
    +        %calltmp1 = call double @bar( double 3.133700e+04 )
    +        %addtmp = add double %calltmp, %calltmp1
    +        ret double %addtmp
    +}
    +
    +
    + +

    This shows some function calls. Note that the runtime of this function might +be fairly high. In the future we'll add conditional control flow to make +recursion actually be useful :).

    + +
    +
    +ready> extern cos(x);
    +ready> Read extern: 
    +declare double @cos(double)
    +
    +ready> cos(1.234);
    +ready> Read top-level expression:
    +define double @""() {
    +entry:
    +        %calltmp = call double @cos( double 1.234000e+00 )              ;  [#uses=1]
    +        ret double %calltmp
    +}
    +
    +
    + +

    This shows an extern for the libm "cos" function, and a call to it.

    + + +
    +
    +ready> ^D
    +; ModuleID = 'my cool jit'
    +
    +define double @""() {
    +entry:
    +        %addtmp = add double 4.000000e+00, 5.000000e+00
    +        ret double %addtmp
    +}
    +
    +define double @foo(double %a, double %b) {
    +entry:
    +        %multmp = mul double %a, %a
    +        %multmp1 = mul double 2.000000e+00, %a
    +        %multmp2 = mul double %multmp1, %b
    +        %addtmp = add double %multmp, %multmp2
    +        %multmp3 = mul double %b, %b
    +        %addtmp4 = add double %addtmp, %multmp3
    +        ret double %addtmp4
    +}
    +
    +define double @bar(double %a) {
    +entry:
    +        %calltmp = call double @foo( double %a, double 4.000000e+00 )
    +        %calltmp1 = call double @bar( double 3.133700e+04 )
    +        %addtmp = add double %calltmp, %calltmp1
    +        ret double %addtmp
    +}
    +
    +declare double @cos(double)
    +
    +define double @""() {
    +entry:
    +        %calltmp = call double @cos( double 1.234000e+00 )
    +        ret double %calltmp
    +}
    +
    +
    + +

    When you quit the current demo, it dumps out the IR for the entire module +generated. Here you can see the big picture with all the functions referencing +each other.

    + +

    This wraps up this chapter of the Kaleidoscope tutorial. Up next we'll +describe how to add JIT codegen and optimizer +support to this so we can actually start running code!

    + +
    + + + +
    Full Code Listing
    + + +
    + +

    +Here is the complete code listing for our running example, enhanced with the +LLVM code generator. Because this uses the LLVM libraries, we need to link +them in. To do this, we use the llvm-config tool to inform +our makefile/command line about which options to use:

    + +
    +
    +   # Compile
    +   g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    +                  `llvm-config --libs core` -I ~/llvm/include/ -o toy
    +   # Run
    +   ./toy
    +
    +
    + +

    Here is the code:

    +
     // To build this:
    -//  g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    -//                `llvm-config --libs core` -I ~/llvm/include/
    -//  ./a.out 
     // See example below.
     
     #include "llvm/DerivedTypes.h"
    @@ -665,10 +1020,8 @@
     
     Function *PrototypeAST::Codegen() {
       // Make the function type:  double(double,double) etc.
    -  FunctionType *FT = 
    -    FunctionType::get(Type::DoubleTy, std::vector<const Type*>(Args.size(),
    -                                                               Type::DoubleTy),
    -                      false);
    +  std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy);
    +  FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false);
       
       Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule);
       
    @@ -713,7 +1066,8 @@
         return 0;
       
       // Create a new basic block to start insertion into.
    -  Builder.SetInsertPoint(new BasicBlock("entry", TheFunction));
    +  BasicBlock *BB = new BasicBlock("entry", TheFunction);
    +  Builder.SetInsertPoint(BB);
       
       if (Value *RetVal = Body->Codegen()) {
         // Finish off the function.
    @@ -816,18 +1170,6 @@
       TheModule->dump();
       return 0;
     }
    -
    -/* Examples:
    -
    -def fib(x)
    -  if (x < 3) then
    -    1
    -  else
    -    fib(x-1)+fib(x-2);
    -
    -fib(10);
    -
    -*/
     
    From sabre at nondot.org Tue Oct 23 01:27:55 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 06:27:55 -0000 Subject: [llvm-commits] [llvm] r43246 - in /llvm/trunk/docs/tutorial: LangImpl4.html index.html Message-ID: <200710230627.l9N6Rtrl022859@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 01:27:55 2007 New Revision: 43246 URL: http://llvm.org/viewvc/llvm-project?rev=43246&view=rev Log: add a skeleton for part 4 Added: llvm/trunk/docs/tutorial/LangImpl4.html Modified: llvm/trunk/docs/tutorial/index.html Added: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=43246&view=auto ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (added) +++ llvm/trunk/docs/tutorial/LangImpl4.html Tue Oct 23 01:27:55 2007 @@ -0,0 +1,78 @@ + + + + + Kaleidoscope: Adding JIT and Optimizer Support + + + + + + + +
    Kaleidoscope: Adding JIT and Optimizer Support
    + +
    +

    Written by Chris Lattner

    +
    + + +
    Part 4 Introduction
    + + +
    + +

    Welcome to part 4 of the "Implementing a language with +LLVM" tutorial.

    + +
    + + +
    Code Generation setup
    + + +
    + +

    +In order to generate LLVM IR, we want some simple setup to get started. First, +we define virtual codegen methods in each AST class:

    + +
    +
    +/// ExprAST - Base class for all expression nodes.
    +class ExprAST {
    +public:
    +  virtual ~ExprAST() {}
    +  virtual Value *Codegen() = 0;
    +};
    +
    +/// NumberExprAST - Expression class for numeric literals like "1.0".
    +class NumberExprAST : public ExprAST {
    +  double Val;
    +public:
    +  explicit NumberExprAST(double val) : Val(val) {}
    +  virtual Value *Codegen();
    +};
    +...
    +
    +
    + + + +
    + + +
    +
    + Valid CSS! + Valid HTML 4.01! + + Chris Lattner
    + The LLVM Compiler Infrastructure
    + Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ +
    + + Modified: llvm/trunk/docs/tutorial/index.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/index.html?rev=43246&r1=43245&r2=43246&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/index.html (original) +++ llvm/trunk/docs/tutorial/index.html Tue Oct 23 01:27:55 2007 @@ -29,8 +29,8 @@
    1. The basic language, with its lexer
    2. Implementing a Parser and AST
    3. -
    4. Implementing code generation to LLVM IR
    5. -
    6. Adding JIT codegen support
    7. +
    8. Implementing Code Generation to LLVM IR
    9. +
    10. Adding JIT and Optimizer Support
    11. Extending the language: if/then/else
    12. Extending the language: operator overloading
    13. Extending the language: mutable variables
    14. @@ -38,7 +38,8 @@
  • Advanced Topics
      -
    1. Writing an Optimization for LLVM
    2. +
    3. Writing + an Optimization for LLVM
  • From sabre at nondot.org Tue Oct 23 01:30:50 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 06:30:50 -0000 Subject: [llvm-commits] [llvm] r43247 - in /llvm/trunk/docs/tutorial: LangImpl1.html LangImpl2.html LangImpl3.html LangImpl4.html Message-ID: <200710230630.l9N6Uo3U022961@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 01:30:50 2007 New Revision: 43247 URL: http://llvm.org/viewvc/llvm-project?rev=43247&view=rev Log: Fix validation problems, which were somewhat ironically in the "valid html" button code :) Modified: llvm/trunk/docs/tutorial/LangImpl1.html llvm/trunk/docs/tutorial/LangImpl2.html llvm/trunk/docs/tutorial/LangImpl3.html llvm/trunk/docs/tutorial/LangImpl4.html Modified: llvm/trunk/docs/tutorial/LangImpl1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl1.html?rev=43247&r1=43246&r2=43247&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl1.html (original) +++ llvm/trunk/docs/tutorial/LangImpl1.html Tue Oct 23 01:30:50 2007 @@ -253,7 +253,7 @@ Valid CSS! Valid HTML 4.01! + src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> Chris Lattner
    The LLVM Compiler Infrastructure
    Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43247&r1=43246&r2=43247&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Tue Oct 23 01:30:50 2007 @@ -1186,7 +1186,7 @@ Valid CSS! Valid HTML 4.01! + src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> Chris Lattner
    The LLVM Compiler Infrastructure
    Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43247&r1=43246&r2=43247&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Tue Oct 23 01:30:50 2007 @@ -534,7 +534,7 @@ ready> Read top-level expression: define double @""() { entry: - %calltmp = call double @cos( double 1.234000e+00 ) ; [#uses=1] + %calltmp = call double @cos( double 1.234000e+00 ) ret double %calltmp } @@ -1180,7 +1180,7 @@ Valid CSS! Valid HTML 4.01! + src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> Chris Lattner
    The LLVM Compiler Infrastructure
    Modified: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=43247&r1=43246&r2=43247&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (original) +++ llvm/trunk/docs/tutorial/LangImpl4.html Tue Oct 23 01:30:50 2007 @@ -68,7 +68,7 @@ Valid CSS! Valid HTML 4.01! + src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"> Chris Lattner
    The LLVM Compiler Infrastructure
    From evan.cheng at apple.com Tue Oct 23 01:42:43 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 06:42:43 -0000 Subject: [llvm-commits] [llvm] r43248 - in /llvm/trunk: lib/Target/PowerPC/PPCISelDAGToDAG.cpp lib/Target/PowerPC/PPCInstr64Bit.td lib/Target/PowerPC/PPCInstrInfo.td test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll Message-ID: <200710230642.l9N6ghBC023439@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 23 01:42:42 2007 New Revision: 43248 URL: http://llvm.org/viewvc/llvm-project?rev=43248&view=rev Log: Temporary solution: added a different set of BCTRL_Macho / BCTRL_ELF with right callee-saved defs set for ppc64. Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=43248&r1=43247&r2=43248&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Tue Oct 23 01:42:42 2007 @@ -42,11 +42,13 @@ class VISIBILITY_HIDDEN PPCDAGToDAGISel : public SelectionDAGISel { PPCTargetMachine &TM; PPCTargetLowering PPCLowering; + const PPCSubtarget &PPCSubTarget; unsigned GlobalBaseReg; public: PPCDAGToDAGISel(PPCTargetMachine &tm) : SelectionDAGISel(PPCLowering), TM(tm), - PPCLowering(*TM.getTargetLowering()) {} + PPCLowering(*TM.getTargetLowering()), + PPCSubTarget(*TM.getSubtargetImpl()) {} virtual bool runOnFunction(Function &Fn) { // Make sure we re-emit a set of the global base reg if necessary @@ -736,7 +738,7 @@ CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), CR7Reg, CCReg, InFlag).getValue(1); - if (TLI.getTargetMachine().getSubtarget().isGigaProcessor()) + if (PPCSubTarget.isGigaProcessor()) IntCR = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg), 0); else @@ -859,7 +861,7 @@ SDOperand InFlag = N->getOperand(1); AddToISelQueue(InFlag); // Use MFOCRF if supported. - if (TLI.getTargetMachine().getSubtarget().isGigaProcessor()) + if (PPCSubTarget.isGigaProcessor()) return CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, N->getOperand(0), InFlag); else Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=43248&r1=43247&r2=43248&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Tue Oct 23 01:42:42 2007 @@ -81,10 +81,13 @@ def BL8_Macho : IForm<18, 0, 1, (outs), (ins calltarget:$func, variable_ops), "bl $func", BrB, []>; // See Pat patterns below. - def BLA8_Macho : IForm<18, 1, 1, (outs), (ins aaddr:$func, variable_ops), "bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>; + def BCTRL8_Macho : XLForm_2_ext<19, 528, 20, 0, 1, + (outs), (ins variable_ops), + "bctrl", BrB, + [(PPCbctrl_Macho)]>, Requires<[In64BitMode]>; } // ELF 64 ABI Calls = Macho ABI Calls @@ -99,11 +102,14 @@ // Convenient aliases for call instructions def BL8_ELF : IForm<18, 0, 1, (outs), (ins calltarget:$func, variable_ops), - "bl $func", BrB, []>; // See Pat patterns below. - + "bl $func", BrB, []>; // See Pat patterns below. def BLA8_ELF : IForm<18, 1, 1, (outs), (ins aaddr:$func, variable_ops), "bla $func", BrB, [(PPCcall_ELF (i64 imm:$func))]>; + def BCTRL8_ELF : XLForm_2_ext<19, 528, 20, 0, 1, + (outs), (ins variable_ops), + "bctrl", BrB, + [(PPCbctrl_ELF)]>, Requires<[In64BitMode]>; } Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=43248&r1=43247&r2=43248&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original) +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Tue Oct 23 01:42:42 2007 @@ -304,6 +304,8 @@ //===----------------------------------------------------------------------===// // PowerPC Instruction Predicate Definitions. def FPContractions : Predicate<"!NoExcessFPPrecision">; +def In32BitMode : Predicate<"!PPCSubTarget.isPPC64()">; +def In64BitMode : Predicate<"PPCSubTarget.isPPC64()">; //===----------------------------------------------------------------------===// @@ -409,7 +411,7 @@ def BCTRL_Macho : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins variable_ops), "bctrl", BrB, - [(PPCbctrl_Macho)]>; + [(PPCbctrl_Macho)]>, Requires<[In32BitMode]>; } // ELF ABI Calls. @@ -431,7 +433,7 @@ def BCTRL_ELF : XLForm_2_ext<19, 528, 20, 0, 1, (outs), (ins variable_ops), "bctrl", BrB, - [(PPCbctrl_ELF)]>; + [(PPCbctrl_ELF)]>, Requires<[In32BitMode]>; } // DCB* instructions. Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll?rev=43248&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-21-LocalRegAllocAssert2.ll Tue Oct 23 01:42:42 2007 @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -regalloc=local -relocation-model=pic + + %struct.NSError = type opaque + %struct.NSManagedObjectContext = type opaque + %struct.NSString = type opaque + %struct.NSURL = type opaque + %struct._message_ref_t = type { %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*, %struct.objc_selector* } + %struct.objc_object = type { } + %struct.objc_selector = type opaque +@"\01L_OBJC_MESSAGE_REF_2" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=2] +@"\01L_OBJC_MESSAGE_REF_6" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=2] + at NSXMLStoreType = external constant %struct.NSString* ; <%struct.NSString**> [#uses=1] +@"\01L_OBJC_MESSAGE_REF_4" = external global %struct._message_ref_t ; <%struct._message_ref_t*> [#uses=2] + +define %struct.NSManagedObjectContext* @"+[ListGenerator(Private) managedObjectContextWithModelURL:storeURL:]"(%struct.objc_object* %self, %struct._message_ref_t* %_cmd, %struct.NSURL* %modelURL, %struct.NSURL* %storeURL) { +entry: + %tmp27 = load %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)** getelementptr (%struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_2", i32 0, i32 0), align 8 ; <%struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*> [#uses=1] + %tmp29 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* %tmp27( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_2" ) ; <%struct.objc_object*> [#uses=0] + %tmp33 = load %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)** getelementptr (%struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_6", i32 0, i32 0), align 8 ; <%struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*> [#uses=1] + %tmp34 = load %struct.NSString** @NSXMLStoreType, align 8 ; <%struct.NSString*> [#uses=1] + %tmp40 = load %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)** getelementptr (%struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_4", i32 0, i32 0), align 8 ; <%struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)*> [#uses=1] + %tmp42 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* %tmp40( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_4", i32 1 ) ; <%struct.objc_object*> [#uses=0] + %tmp48 = call %struct.objc_object* (%struct.objc_object*, %struct._message_ref_t*, ...)* %tmp33( %struct.objc_object* null, %struct._message_ref_t* @"\01L_OBJC_MESSAGE_REF_6", %struct.NSString* %tmp34, i8* null, %struct.NSURL* null, %struct.objc_object* null, %struct.NSError** null ) ; <%struct.objc_object*> [#uses=0] + unreachable +} From evan.cheng at apple.com Tue Oct 23 01:51:51 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 06:51:51 -0000 Subject: [llvm-commits] [llvm] r43249 - in /llvm/trunk: include/llvm/Target/MRegisterInfo.h lib/CodeGen/LowerSubregs.cpp Message-ID: <200710230651.l9N6ppKT023806@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 23 01:51:50 2007 New Revision: 43249 URL: http://llvm.org/viewvc/llvm-project?rev=43249&view=rev Log: isSubRegOf() is a dup of isSubRegister. Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h llvm/trunk/lib/CodeGen/LowerSubregs.cpp Modified: llvm/trunk/include/llvm/Target/MRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/MRegisterInfo.h?rev=43249&r1=43248&r2=43249&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/MRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/MRegisterInfo.h Tue Oct 23 01:51:50 2007 @@ -375,17 +375,6 @@ return get(RegNo).SuperRegs; } - /// isSubRegOf - Predicate which returns true if RegA is a sub-register of - /// RegB. Returns false otherwise. - /// - bool isSubRegOf(unsigned RegA, unsigned RegB) const { - const TargetRegisterDesc &RD = (*this)[RegA]; - for (const unsigned *reg = RD.SuperRegs; *reg != 0; ++reg) - if (*reg == RegB) - return true; - return false; - } - /// getName - Return the symbolic target specific name for the specified /// physical register. const char *getName(unsigned RegNo) const { Modified: llvm/trunk/lib/CodeGen/LowerSubregs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LowerSubregs.cpp?rev=43249&r1=43248&r2=43249&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LowerSubregs.cpp (original) +++ llvm/trunk/lib/CodeGen/LowerSubregs.cpp Tue Oct 23 01:51:50 2007 @@ -146,7 +146,7 @@ // of the destination, we copy the subreg into the source // However, this is only safe if the insert instruction is the kill // of the source register - bool revCopyOrder = MRI.isSubRegOf(InsReg, DstReg); + bool revCopyOrder = MRI.isSubRegister(DstReg, InsReg); if (revCopyOrder && InsReg != DstSubReg) { if (MI->getOperand(1).isKill()) { DstSubReg = MRI.getSubReg(SrcReg, SubIdx); From espindola at google.com Tue Oct 23 08:36:08 2007 From: espindola at google.com (Rafael Espindola) Date: Tue, 23 Oct 2007 14:36:08 +0100 Subject: [llvm-commits] [llvm] r43176 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h In-Reply-To: <90524216-7D9B-4B62-9FFF-E5669A37DEF9@apple.com> References: <200710191435.l9JEZIAM018674@zion.cs.uiuc.edu> <90524216-7D9B-4B62-9FFF-E5669A37DEF9@apple.com> Message-ID: <38a0d8450710230636q2ebde484t465366a0db6f1b7b@mail.gmail.com> On 22/10/2007, Evan Cheng wrote: > Hi Rafael, > > There a couple of problems with this patch. > > 1. This breaks a number of tests for me: > llc-beta /MultiSource/Applications/JM/ldecod/ldecod > llc /MultiSource/Applications/JM/ldecod/ldecod > llc /External/SPEC/CINT2000/254.gap/254.gap > llc /MultiSource/Benchmarks/MiBench/office-ispell/office-ispell > llc-beta /MultiSource/Benchmarks/MiBench/office-ispell/office-ispell > llc-beta /External/SPEC/CINT2000/254.gap/254.gap Sorry about that. I don't have an arm board with me. I will try to set up a qemu chroot this Friday to better test on ARM. > LowerMEMCPYInline() is asserting when the memcpy is 4-byte aligned but > the size isn't multiple of 4. I'm going to remove the assertion and > issue byte / word loads / stores to handle the trailing bytes. Please > let me know if that's undesirable. I now notice that the original code had a "I->getValue() & 3" then call memcpy. You can just add a if (Size & 3) LowerMEMCPYCall(...) This will return to the previous behavior. Making the inline version handle other sizes is also fine. What I am trying to do is factor a bit of the memcpy expansion code among the various backends since I will need it on all of them to implement "byval" arguments. > 2. The stores are unnecessarily serialized. Each of them should use > the load tokenfactor as input chain. All the chains produced by the > stores should then be fed into a new tokenfactor. I'll fix this. The code that generates the inline expansion is the same as before. Just on a different function. Any improvement is welcome :-) > Thanks, > > Evan Sorry for the problem..., -- Rafael Avila de Espindola Google Ireland Ltd. Gordon House Barrow Street Dublin 4 Ireland Registered in Dublin, Ireland Registration Number: 368047 From gabor at mac.com Tue Oct 23 10:57:11 2007 From: gabor at mac.com (Gabor Greif) Date: Tue, 23 Oct 2007 17:57:11 +0200 Subject: [llvm-commits] link error on SPARC b/c of missing lib Message-ID: <471E19D7.50602@mac.com> Hi! Here is a quick patch to get test/Feature/llvm2cpp.ll to pass on SPARC. the addition of -lmalloc should not harm on other platforms, right? Cheers, Gabor PS: This knocks down the SPARC failures to # of expected passes 2006 # of unexpected failures 4 # of expected failures 9 Of the 4 unexpecteds I have 3 because of OCaml (old compiler) and 1 because of PR http://llvm.org/bugs/show_bug.cgi?id=1557 -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: llvm2cpp.ll.diff Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071023/4e985d00/attachment.pl From alenhar2 at cs.uiuc.edu Tue Oct 23 11:09:00 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Tue, 23 Oct 2007 16:09:00 -0000 Subject: [llvm-commits] [poolalloc] r43250 - /poolalloc/trunk/autoconf/configure.ac Message-ID: <200710231609.l9NG90ok024673@zion.cs.uiuc.edu> Author: alenhar2 Date: Tue Oct 23 11:08:59 2007 New Revision: 43250 URL: http://llvm.org/viewvc/llvm-project?rev=43250&view=rev Log: fix LLVMSRC, thanks Torvald Riegel Modified: poolalloc/trunk/autoconf/configure.ac Modified: poolalloc/trunk/autoconf/configure.ac URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/autoconf/configure.ac?rev=43250&r1=43249&r2=43250&view=diff ============================================================================== --- poolalloc/trunk/autoconf/configure.ac (original) +++ poolalloc/trunk/autoconf/configure.ac Tue Oct 23 11:08:59 2007 @@ -7,14 +7,14 @@ LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`" LLVM_OBJ_ROOT="`(cd ../..; pwd)`" -dnl Tell autoconf that the auxilliary files are actually located in -dnl the LLVM autoconf directory, not here. -AC_CONFIG_AUX_DIR($LLVM_SRC_ROOT/autoconf) - dnl Tell autoconf that this is an LLVM project being configured dnl This provides the --with-llvmsrc and --with-llvmobj options LLVM_CONFIG_PROJECT($LLVM_SRC_ROOT,$LLVM_OBJ_ROOT) +dnl Tell autoconf that the auxilliary files are actually located in +dnl the LLVM autoconf directory, not here. +AC_CONFIG_AUX_DIR($LLVM_SRC/autoconf) + dnl Verify that the source directory is valid AC_CONFIG_SRCDIR(["Makefile.common.in"]) From gordonhenriksen at mac.com Tue Oct 23 11:34:14 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Tue, 23 Oct 2007 12:34:14 -0400 Subject: [llvm-commits] link error on SPARC b/c of missing lib In-Reply-To: <471E19D7.50602@mac.com> References: <471E19D7.50602@mac.com> Message-ID: <59C0FDD5-D44B-4DA4-B2AE-A53D32DD95BC@mac.com> On Oct 23, 2007, at 11:57, Gabor Greif wrote: > Here is a quick patch to get > > test/Feature/llvm2cpp.ll > > to pass on SPARC. > > the addition of -lmalloc should not harm on other platforms, right? Pretty sure it will bugger them, actually. This should probably use llvm-config --libs. ? Gordon -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20071023/b1a696b5/attachment.html From sabre at nondot.org Tue Oct 23 12:56:04 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 17:56:04 -0000 Subject: [llvm-commits] [llvm] r43251 - /llvm/trunk/test/Feature/llvm2cpp.ll Message-ID: <200710231756.l9NHu4VC030546@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 12:56:04 2007 New Revision: 43251 URL: http://llvm.org/viewvc/llvm-project?rev=43251&view=rev Log: llvm/test programs should not be execution programs. This will hopefully fix Gabor's Sparc problem. Modified: llvm/trunk/test/Feature/llvm2cpp.ll Modified: llvm/trunk/test/Feature/llvm2cpp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/llvm2cpp.ll?rev=43251&r1=43250&r2=43251&view=diff ============================================================================== --- llvm/trunk/test/Feature/llvm2cpp.ll (original) +++ llvm/trunk/test/Feature/llvm2cpp.ll Tue Oct 23 12:56:04 2007 @@ -1,8 +1,5 @@ ; RUN: llvm-as < %s | llvm-dis > %t1.ll -; RUN: llvm-as < %s | llvm2cpp -gen-program -o %t2.cpp - -f -; RUN: %link -o %t2.exe %t2.cpp -lLLVMCore -lLLVMSupport -lLLVMSystem -lstdc++ -; RUN: ./%t2.exe > %t2.ll -; RUN: diff %t1.ll %t2.ll +; RUN: llvm-as < %s | llvm2cpp -gen-program -o - @X = global i32 4, align 16 ; [#uses=0] From sabre at nondot.org Tue Oct 23 13:07:23 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 18:07:23 -0000 Subject: [llvm-commits] [llvm] r43252 - /llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m Message-ID: <200710231807.l9NI7NKn031096@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 13:07:23 2007 New Revision: 43252 URL: http://llvm.org/viewvc/llvm-project?rev=43252&view=rev Log: new testcase Added: llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m Added: llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m?rev=43252&view=auto ============================================================================== --- llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m (added) +++ llvm/trunk/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m Tue Oct 23 13:07:23 2007 @@ -0,0 +1,9 @@ +// RUN: %llvmgcc -x objective-c -c %s -o /dev/null -fobjc-gc +// rdar://5541393 + +typedef unsigned int NSUInteger; +__attribute__((objc_gc(strong))) float *_scores; + +void foo(int i, float f) { + _scores[i] = f; +} From sabre at nondot.org Tue Oct 23 13:08:07 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 18:08:07 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43253 - /llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Message-ID: <200710231808.l9NI87xB031149@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 13:08:05 2007 New Revision: 43253 URL: http://llvm.org/viewvc/llvm-project?rev=43253&view=rev Log: Fix test/FrontendObjC/2007-10-23-GC-WriteBarrier.m, a bug where objc write barriers were emitted for non pointer values due to our ARRAY_REF hack. Modified: llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.0/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/objc/objc-act.c?rev=43253&r1=43252&r2=43253&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.0/trunk/gcc/objc/objc-act.c Tue Oct 23 13:08:05 2007 @@ -6914,6 +6914,9 @@ return NULL_TREE; /* APPLE LOCAL end ObjC GC */ + /* LLVM LOCAL 5541393 */ + if (TREE_CODE(TREE_TYPE(lhs)) != POINTER_TYPE) return NULL_TREE; + /* APPLE LOCAL begin ObjC GC */ /* At this point, we are committed to using one of the write-barriers, unless the user is attempting to perform pointer arithmetic. */ From sabre at nondot.org Tue Oct 23 13:10:37 2007 From: sabre at nondot.org (Chris Lattner) Date: Tue, 23 Oct 2007 18:10:37 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43254 - /llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Message-ID: <200710231810.l9NIAbLd031260@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 13:10:37 2007 New Revision: 43254 URL: http://llvm.org/viewvc/llvm-project?rev=43254&view=rev Log: Fix test/FrontendObjC/2007-10-23-GC-WriteBarrier.m, a bug where objc write barriers were emitted for non pointer values due to our ARRAY_REF hack. Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Modified: llvm-gcc-4.2/trunk/gcc/objc/objc-act.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/objc/objc-act.c?rev=43254&r1=43253&r2=43254&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/objc/objc-act.c (original) +++ llvm-gcc-4.2/trunk/gcc/objc/objc-act.c Tue Oct 23 13:10:37 2007 @@ -6882,6 +6882,9 @@ return NULL_TREE; /* APPLE LOCAL end radar 4426814 */ + /* LLVM LOCAL 5541393 */ + if (TREE_CODE(TREE_TYPE(lhs)) != POINTER_TYPE) return NULL_TREE; + /* APPLE LOCAL begin ObjC GC */ /* Use the strong-cast write barrier as a last resort. */ if (warn_assign_intercept) From clattner at apple.com Tue Oct 23 14:43:43 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 12:43:43 -0700 Subject: [llvm-commits] [llvm] r43176 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h In-Reply-To: <38a0d8450710230636q2ebde484t465366a0db6f1b7b@mail.gmail.com> References: <200710191435.l9JEZIAM018674@zion.cs.uiuc.edu> <90524216-7D9B-4B62-9FFF-E5669A37DEF9@apple.com> <38a0d8450710230636q2ebde484t465366a0db6f1b7b@mail.gmail.com> Message-ID: On Oct 23, 2007, at 6:36 AM, Rafael Espindola wrote: > What I am trying to do is factor a bit of the memcpy expansion code > among the various backends since I will need it on all of them to > implement "byval" arguments. > >> 2. The stores are unnecessarily serialized. Each of them should use >> the load tokenfactor as input chain. All the chains produced by the >> stores should then be fed into a new tokenfactor. I'll fix this. > > The code that generates the inline expansion is the same as before. > Just on a different function. Any improvement is welcome :-) Hey Rafael, I just asked Bill to look into merging these memcpy lowering implementations. Have you already started on this, or should Bill look into it? -Chris From evan.cheng at apple.com Tue Oct 23 15:14:41 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 20:14:41 -0000 Subject: [llvm-commits] [llvm] r43256 - /llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Message-ID: <200710232014.l9NKEfWo005834@zion.cs.uiuc.edu> Author: evancheng Date: Tue Oct 23 15:14:40 2007 New Revision: 43256 URL: http://llvm.org/viewvc/llvm-project?rev=43256&view=rev Log: It's possible to commute instrctions with more than 3 operands. Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Modified: llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp?rev=43256&r1=43255&r2=43256&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp (original) +++ llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp Tue Oct 23 15:14:40 2007 @@ -143,7 +143,7 @@ // so, swap the B and C operands. This makes the live ranges of A // and C joinable. // FIXME: This code also works for A := B op C instructions. - if ((TID->Flags & M_COMMUTABLE) && mi->getNumOperands() == 3) { + if ((TID->Flags & M_COMMUTABLE) && mi->getNumOperands() >= 3) { assert(mi->getOperand(3-si).isRegister() && "Not a proper commutative instruction!"); unsigned regC = mi->getOperand(3-si).getReg(); From resistor at mac.com Tue Oct 23 15:58:41 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 20:58:41 -0000 Subject: [llvm-commits] [llvm] r43259 - in /llvm/trunk: include/llvm/Analysis/PostDominators.h lib/Analysis/PostDominators.cpp lib/VMCore/Dominators.cpp Message-ID: <200710232058.l9NKwfBR007886@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 15:58:37 2007 New Revision: 43259 URL: http://llvm.org/viewvc/llvm-project?rev=43259&view=rev Log: Make DomTree and PostDomTree thin wrappers around DomTreeBase, rather than inheriting from it. Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h llvm/trunk/lib/Analysis/PostDominators.cpp llvm/trunk/lib/VMCore/Dominators.cpp Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PostDominators.h?rev=43259&r1=43258&r2=43259&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PostDominators.h (original) +++ llvm/trunk/include/llvm/Analysis/PostDominators.h Tue Oct 23 15:58:37 2007 @@ -21,17 +21,39 @@ /// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to /// compute the a post-dominator tree. /// -struct PostDominatorTree : public DominatorTreeBase { +struct PostDominatorTree : public FunctionPass { static char ID; // Pass identification, replacement for typeid + DominatorTreeBase* DT; - PostDominatorTree() : - DominatorTreeBase((intptr_t)&ID, true) {} + PostDominatorTree() : FunctionPass((intptr_t)&ID) { + DT = new DominatorTreeBase(intptr_t(&ID), true); + } virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + + inline const std::vector &getRoots() const { + return DT->getRoots(); + } + + inline DomTreeNode *getRootNode() const { + return DT->getRootNode(); + } + + inline DomTreeNode *operator[](BasicBlock *BB) const { + return DT->getNode(BB); + } + + inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const { + return DT->properlyDominates(A, B); + } + + inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const { + return DT->properlyDominates(A, B); + } }; Modified: llvm/trunk/lib/Analysis/PostDominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PostDominators.cpp?rev=43259&r1=43258&r2=43259&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PostDominators.cpp (original) +++ llvm/trunk/lib/Analysis/PostDominators.cpp Tue Oct 23 15:58:37 2007 @@ -29,25 +29,7 @@ F("postdomtree", "Post-Dominator Tree Construction", true); bool PostDominatorTree::runOnFunction(Function &F) { - reset(); // Reset from the last time we were run... - - // Initialize the roots list - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { - TerminatorInst *Insn = I->getTerminator(); - if (Insn->getNumSuccessors() == 0) { - // Unreachable block is not a root node. - if (!isa(Insn)) - Roots.push_back(I); - } - - // Prepopulate maps so that we don't get iterator invalidation issues later. - IDoms[I] = 0; - DomTreeNodes[I] = 0; - } - - Vertex.push_back(0); - - Calculate, GraphTraits > >(*this, F); + DT->recalculate(F); return false; } Modified: llvm/trunk/lib/VMCore/Dominators.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Dominators.cpp?rev=43259&r1=43258&r2=43259&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Dominators.cpp (original) +++ llvm/trunk/lib/VMCore/Dominators.cpp Tue Oct 23 15:58:37 2007 @@ -57,17 +57,7 @@ E("domtree", "Dominator Tree Construction", true); bool DominatorTree::runOnFunction(Function &F) { - reset(); // Reset from the last time we were run... - - // Initialize roots - Roots.push_back(&F.getEntryBlock()); - IDoms[&F.getEntryBlock()] = 0; - DomTreeNodes[&F.getEntryBlock()] = 0; - Vertex.push_back(0); - - Calculate >(*this, F); - - updateDFSNumbers(); + DT->recalculate(F); return false; } From resistor at mac.com Tue Oct 23 16:04:39 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 21:04:39 -0000 Subject: [llvm-commits] [llvm] r43260 - /llvm/trunk/include/llvm/Analysis/Dominators.h Message-ID: <200710232104.l9NL4dMr008152@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 16:04:37 2007 New Revision: 43260 URL: http://llvm.org/viewvc/llvm-project?rev=43260&view=rev Log: Unbreak the build. Forgot to commit this file. Modified: llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43260&r1=43259&r2=43260&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Tue Oct 23 16:04:37 2007 @@ -22,20 +22,22 @@ #define LLVM_ANALYSIS_DOMINATORS_H #include "llvm/Pass.h" +#include "llvm/BasicBlock.h" +#include "llvm/Function.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Assembly/Writer.h" +#include "llvm/Support/CFG.h" #include "llvm/Support/Compiler.h" #include #include namespace llvm { -template struct GraphTraits; - //===----------------------------------------------------------------------===// /// DominatorBase - Base class that other, more interesting dominator analyses /// inherit from. @@ -161,8 +163,8 @@ /// template -void Split(DominatorTreeBase& DT, - typename GraphT::NodeType* NewBB); +void Calculate(DominatorTreeBase& DT, + Function& F); template class DominatorTreeBase : public DominatorBase { @@ -295,6 +297,9 @@ : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {} ~DominatorTreeBase() { reset(); } + // FIXME: Should remove this + virtual bool runOnFunction(Function &F) { return false; } + virtual void releaseMemory() { reset(); } /// getNode - return the (Post)DominatorTree node for the specified basic @@ -305,10 +310,6 @@ return I != DomTreeNodes.end() ? I->second : 0; } - inline DomTreeNodeBase *operator[](NodeT *BB) const { - return getNode(BB); - } - /// getRootNode - This returns the entry node for the CFG of the function. If /// this tree represents the post-dominance relations for a function, however, /// this root may be a node with the block == NULL. This is the case when @@ -381,6 +382,11 @@ return dominates(getNode(A), getNode(B)); } + + NodeT *getRoot() const { + assert(this->Roots.size() == 1 && "Should always have entry node!"); + return this->Roots[0]; + } /// findNearestCommonDominator - Find nearest common dominator basic block /// for basic block A and B. If there is no such block then return NULL. @@ -428,30 +434,6 @@ return NULL; } - // dominates - Return true if A dominates B. This performs the - // special checks necessary if A and B are in the same basic block. - bool dominates(Instruction *A, Instruction *B) { - NodeT *BBA = A->getParent(), *BBB = B->getParent(); - if (BBA != BBB) return this->dominates(BBA, BBB); - - // It is not possible to determine dominance between two PHI nodes - // based on their ordering. - if (isa(A) && isa(B)) - return false; - - // Loop through the basic block until we find A or B. - typename NodeT::iterator I = BBA->begin(); - for (; &*I != A && &*I != B; ++I) /*empty*/; - - if(!this->IsPostDominators) { - // A dominates B if it is found first in the basic block. - return &*I == A; - } else { - // A post-dominates B if B is found first in the basic block. - return &*I == B; - } - } - //===--------------------------------------------------------------------===// // API to update (Post)DominatorTree information based on modifications to // the CFG... @@ -517,9 +499,9 @@ /// tree to reflect this change. void splitBlock(NodeT* NewBB) { if (this->IsPostDominators) - Split, GraphTraits > >(*this, NewBB); + this->Split, GraphTraits > >(*this, NewBB); else - Split >(*this, NewBB); + this->Split >(*this, NewBB); } /// print - Convert to human readable form @@ -624,6 +606,44 @@ typename DenseMap::const_iterator I = IDoms.find(BB); return I != IDoms.end() ? I->second : 0; } + +public: + /// recalculate - compute a dominator tree for the given function + void recalculate(Function& F) { + if (!this->IsPostDominators) { + reset(); + + // Initialize roots + this->Roots.push_back(&F.getEntryBlock()); + this->IDoms[&F.getEntryBlock()] = 0; + this->DomTreeNodes[&F.getEntryBlock()] = 0; + this->Vertex.push_back(0); + + Calculate >(*this, F); + + updateDFSNumbers(); + } else { + reset(); // Reset from the last time we were run... + + // Initialize the roots list + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { + TerminatorInst *Insn = I->getTerminator(); + if (Insn->getNumSuccessors() == 0) { + // Unreachable block is not a root node. + if (!isa(Insn)) + this->Roots.push_back(I); + } + + // Prepopulate maps so that we don't get iterator invalidation issues later. + this->IDoms[I] = 0; + this->DomTreeNodes[I] = 0; + } + + this->Vertex.push_back(0); + + Calculate, GraphTraits > >(*this, F); + } + } }; EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase); @@ -632,14 +652,34 @@ /// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to /// compute a normal dominator tree. /// -class DominatorTree : public DominatorTreeBase { +class DominatorTree : public FunctionPass { public: static char ID; // Pass ID, replacement for typeid - DominatorTree() : DominatorTreeBase(intptr_t(&ID), false) {} + DominatorTreeBase* DT; - BasicBlock *getRoot() const { - assert(Roots.size() == 1 && "Should always have entry node!"); - return Roots[0]; + DominatorTree() : FunctionPass(intptr_t(&ID)) { + DT = new DominatorTreeBase(intptr_t(&ID), false); + } + + ~DominatorTree() { + DT->releaseMemory(); + delete DT; + } + + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + inline const std::vector &getRoots() const { + return DT->getRoots(); + } + + inline BasicBlock *getRoot() const { + return DT->getRoot(); + } + + inline DomTreeNode *getRootNode() const { + return DT->getRootNode(); } virtual bool runOnFunction(Function &F); @@ -647,6 +687,103 @@ virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } + + inline bool dominates(DomTreeNode* A, DomTreeNode* B) const { + return DT->dominates(A, B); + } + + inline bool dominates(BasicBlock* A, BasicBlock* B) const { + return DT->dominates(A, B); + } + + // dominates - Return true if A dominates B. This performs the + // special checks necessary if A and B are in the same basic block. + bool dominates(Instruction *A, Instruction *B) const { + BasicBlock *BBA = A->getParent(), *BBB = B->getParent(); + if (BBA != BBB) return DT->dominates(BBA, BBB); + + // It is not possible to determine dominance between two PHI nodes + // based on their ordering. + if (isa(A) && isa(B)) + return false; + + // Loop through the basic block until we find A or B. + BasicBlock::iterator I = BBA->begin(); + for (; &*I != A && &*I != B; ++I) /*empty*/; + + //if(!DT.IsPostDominators) { + // A dominates B if it is found first in the basic block. + return &*I == A; + //} else { + // // A post-dominates B if B is found first in the basic block. + // return &*I == B; + //} + } + + inline bool properlyDominates(const DomTreeNode* A, DomTreeNode* B) const { + return DT->properlyDominates(A, B); + } + + inline bool properlyDominates(BasicBlock* A, BasicBlock* B) const { + return DT->properlyDominates(A, B); + } + + /// findNearestCommonDominator - Find nearest common dominator basic block + /// for basic block A and B. If there is no such block then return NULL. + inline BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B) { + return DT->findNearestCommonDominator(A, B); + } + + inline DomTreeNode *operator[](BasicBlock *BB) const { + return DT->getNode(BB); + } + + /// getNode - return the (Post)DominatorTree node for the specified basic + /// block. This is the same as using operator[] on this class. + /// + inline DomTreeNode *getNode(BasicBlock *BB) const { + return DT->getNode(BB); + } + + /// addNewBlock - Add a new node to the dominator tree information. This + /// creates a new node as a child of DomBB dominator node,linking it into + /// the children list of the immediate dominator. + inline DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) { + return DT->addNewBlock(BB, DomBB); + } + + /// changeImmediateDominator - This method is used to update the dominator + /// tree information when a node's immediate dominator changes. + /// + inline void changeImmediateDominator(BasicBlock *N, BasicBlock* NewIDom) { + DT->changeImmediateDominator(N, NewIDom); + } + + inline void changeImmediateDominator(DomTreeNode *N, DomTreeNode* NewIDom) { + DT->changeImmediateDominator(N, NewIDom); + } + + /// eraseNode - Removes a node from the dominator tree. Block must not + /// domiante any other blocks. Removes node from its immediate dominator's + /// children list. Deletes dominator node associated with basic block BB. + inline void eraseNode(BasicBlock *BB) { + DT->eraseNode(BB); + } + + /// splitBlock - BB is split and now it has one successor. Update dominator + /// tree to reflect this change. + inline void splitBlock(BasicBlock* NewBB) { + DT->splitBlock(NewBB); + } + + + virtual void releaseMemory() { + DT->releaseMemory(); + } + + virtual void print(std::ostream &OS, const Module* M= 0) const { + DT->print(OS, M); + } }; //===------------------------------------- From kremenek at apple.com Tue Oct 23 16:29:33 2007 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 23 Oct 2007 21:29:33 -0000 Subject: [llvm-commits] [llvm] r43261 - in /llvm/trunk: include/llvm/Bitcode/Serialization.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp Message-ID: <200710232129.l9NLTXWd009517@zion.cs.uiuc.edu> Author: kremenek Date: Tue Oct 23 16:29:33 2007 New Revision: 43261 URL: http://llvm.org/viewvc/llvm-project?rev=43261&view=rev Log: Added preliminary implementation of generic object serialization to bitcode. Added: llvm/trunk/include/llvm/Bitcode/Serialization.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Added: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43261&view=auto ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (added) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Tue Oct 23 16:29:33 2007 @@ -0,0 +1,115 @@ + //=- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for generic object serialization to +// LLVM bitcode. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_SERIALIZE +#define LLVM_BITCODE_SERIALIZE + +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/ADT/SmallVector.h" +#include + +namespace llvm { + +template struct SerializeTrait; + +class Serializer { + BitstreamWriter& Stream; + SmallVector Record; + bool inBlock; +public: + Serializer(BitstreamWriter& stream, unsigned BlockID = 0); + ~Serializer(); + + template + inline void Emit(const T& X) { SerializeTrait::Serialize(*this,X); } + + void EmitInt(unsigned X, unsigned bits); + void EmitCString(const char* cstr); + + void Flush() { if (inRecord()) EmitRecord(); } + +private: + void EmitRecord(); + inline bool inRecord() { return Record.size() > 0; } +}; + + +class Deserializer { + BitstreamReader& Stream; + SmallVector Record; + unsigned RecIdx; +public: + Deserializer(BitstreamReader& stream); + ~Deserializer(); + + template + inline void Read(T& X) { SerializeTrait::Deserialize(*this,X); } + + template + inline T* Materialize() { + T* X = SerializeTrait::Instantiate(); + Read(*X); + return X; + } + + uint64_t ReadInt(unsigned bits = 32); + bool ReadBool() { return ReadInt(1); } + + char* ReadCString(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); + void ReadCString(std::vector& buff, bool isNullTerm=false); + +private: + void ReadRecord(); + + inline bool inRecord() { + if (Record.size() > 0) { + if (RecIdx >= Record.size()) { + RecIdx = 0; + Record.clear(); + return false; + } + else return true; + } + else return false; + } +}; + + +template +struct SerializeIntTrait { + static inline void Serialize(Serializer& S, uintty X) { + S.EmitInt(X,Bits); + } + + static inline void Deserialize(Deserializer& S, uintty& X) { + X = (uintty) S.ReadInt(Bits); + } +}; + + +template <> struct SerializeTrait + : public SerializeIntTrait {}; + +template <> struct SerializeTrait + : public SerializeIntTrait {}; + +template <> struct SerializeTrait + : public SerializeIntTrait {}; + +template <> struct SerializeTrait + : public SerializeIntTrait {}; + +} // end namespace llvm +#endif Added: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43261&view=auto ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (added) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Tue Oct 23 16:29:33 2007 @@ -0,0 +1,83 @@ +//==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the internal methods used for object serialization. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/Serialization.h" + +using namespace llvm; + +Deserializer::Deserializer(BitstreamReader& stream) + : Stream(stream), RecIdx(0) { +} + +Deserializer::~Deserializer() { + assert (RecIdx >= Record.size() && + "Still scanning bitcode record when deserialization completed."); +} + +void Deserializer::ReadRecord() { + // FIXME: Check if we haven't run off the edge of the stream. + // FIXME: Handle abbreviations. + unsigned Code = Stream.ReadCode(); + // FIXME: Check for the correct code. + assert (Record.size() == 0); + + Stream.ReadRecord(Code,Record); + + assert (Record.size() > 0); +} + +uint64_t Deserializer::ReadInt(unsigned Bits) { + // FIXME: Any error recovery/handling with incomplete or bad files? + if (!inRecord()) + ReadRecord(); + + // FIXME: check for loss of precision in read (compare to Bits) + return Record[RecIdx++]; +} + +char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) { + if (cstr == NULL) + MaxLen = 0; // Zero this just in case someone does something funny. + + unsigned len = ReadInt(32); + + // FIXME: perform dynamic checking of lengths? + assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen); + + if (!cstr) + cstr = new char[len + (isNullTerm ? 1 : 0)]; + + assert (cstr != NULL); + + for (unsigned i = 0; i < len; ++i) + cstr[i] = ReadInt(8); + + if (isNullTerm) + cstr[len+1] = '\0'; + + return cstr; +} + +void Deserializer::ReadCString(std::vector& buff, bool isNullTerm) { + buff.clear(); + + unsigned len = ReadInt(32); + + buff.reserve(len); + + for (unsigned i = 0; i < len; ++i) + buff.push_back(ReadInt(8)); + + if (isNullTerm) + buff.push_back('\0'); +} Added: llvm/trunk/lib/Bitcode/Writer/Serialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/Serialize.cpp?rev=43261&view=auto ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (added) +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Tue Oct 23 16:29:33 2007 @@ -0,0 +1,52 @@ +//==- Serialize.cpp - Generic Object Serialization to Bitcode ----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the internal methods used for object serialization. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/Serialization.h" + +using namespace llvm; + +Serializer::Serializer(BitstreamWriter& stream, unsigned BlockID) + : Stream(stream), inBlock(BlockID >= 8) { + + if (inBlock) Stream.EnterSubblock(8,3); +} + +Serializer::~Serializer() { + if (inRecord()) + EmitRecord(); + + if (inBlock) + Stream.ExitBlock(); + + Stream.FlushToWord(); +} + +void Serializer::EmitRecord() { + assert(Record.size() > 0 && "Cannot emit empty record."); + Stream.EmitRecord(8,Record); + Record.clear(); +} + +void Serializer::EmitInt(unsigned X, unsigned bits) { + Record.push_back(X); +} + +void Serializer::EmitCString(const char* cstr) { + unsigned l = strlen(cstr); + Record.push_back(l); + + for (unsigned i = 0; i < l; i++) + Record.push_back(cstr[i]); + + EmitRecord(); +} From isanbard at gmail.com Tue Oct 23 16:30:25 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 21:30:25 -0000 Subject: [llvm-commits] [llvm] r43262 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200710232130.l9NLUPpD009581@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 16:30:25 2007 New Revision: 43262 URL: http://llvm.org/viewvc/llvm-project?rev=43262&view=rev Log: Lowering a memcpy to the stack is killing PPC. The ARM and X86 backends already have their own custom memcpy lowering code. This code needs to be factored out into a target-independent lowering method with hooks to the backend. In the meantime, just call memcpy if we're trying to copy onto a stack. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43262&r1=43261&r2=43262&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 23 16:30:25 2007 @@ -4302,6 +4302,10 @@ break; } case ISD::MEMCPY: { + // FIXME: Disabling memcpy lowering for copying onto the stack. + if (Op1.getOpcode() == ISD::FrameIndex) + break; + if (MeetsMaxMemopRequirement(MemOps, TLI.getMaxStoresPerMemcpy(), Size->getValue(), Align, TLI)) { unsigned NumMemOps = MemOps.size(); From resistor at mac.com Tue Oct 23 16:42:49 2007 From: resistor at mac.com (Owen Anderson) Date: Tue, 23 Oct 2007 21:42:49 -0000 Subject: [llvm-commits] [llvm] r43263 - in /llvm/trunk/include/llvm/Analysis: Dominators.h PostDominators.h Message-ID: <200710232142.l9NLgn2i010212@zion.cs.uiuc.edu> Author: resistor Date: Tue Oct 23 16:42:49 2007 New Revision: 43263 URL: http://llvm.org/viewvc/llvm-project?rev=43263&view=rev Log: Make DomTreeBase not a FunctionPass. Modified: llvm/trunk/include/llvm/Analysis/Dominators.h llvm/trunk/include/llvm/Analysis/PostDominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43263&r1=43262&r2=43263&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Tue Oct 23 16:42:49 2007 @@ -43,12 +43,12 @@ /// inherit from. /// template -class DominatorBase : public FunctionPass { +class DominatorBase { protected: std::vector Roots; const bool IsPostDominators; - inline DominatorBase(intptr_t ID, bool isPostDom) : - FunctionPass(ID), Roots(), IsPostDominators(isPostDom) {} + inline DominatorBase(bool isPostDom) : + Roots(), IsPostDominators(isPostDom) {} public: /// getRoots - Return the root blocks of the current CFG. This may include @@ -293,9 +293,9 @@ } public: - DominatorTreeBase(intptr_t ID, bool isPostDom) - : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {} - ~DominatorTreeBase() { reset(); } + DominatorTreeBase(bool isPostDom) + : DominatorBase(isPostDom), DFSInfoValid(false), SlowQueries(0) {} + virtual ~DominatorTreeBase() { reset(); } // FIXME: Should remove this virtual bool runOnFunction(Function &F) { return false; } @@ -658,7 +658,7 @@ DominatorTreeBase* DT; DominatorTree() : FunctionPass(intptr_t(&ID)) { - DT = new DominatorTreeBase(intptr_t(&ID), false); + DT = new DominatorTreeBase(false); } ~DominatorTree() { @@ -817,15 +817,28 @@ /// DominanceFrontierBase - Common base class for computing forward and inverse /// dominance frontiers for a function. /// -class DominanceFrontierBase : public DominatorBase { +class DominanceFrontierBase : public FunctionPass { public: typedef std::set DomSetType; // Dom set for a bb typedef std::map DomSetMapType; // Dom set map protected: DomSetMapType Frontiers; + std::vector Roots; + const bool IsPostDominators; + public: DominanceFrontierBase(intptr_t ID, bool isPostDom) - : DominatorBase(ID, isPostDom) {} + : FunctionPass(ID), IsPostDominators(isPostDom) {} + + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + inline const std::vector &getRoots() const { return Roots; } + + /// isPostDominator - Returns true if analysis based of postdoms + /// + bool isPostDominator() const { return IsPostDominators; } virtual void releaseMemory() { Frontiers.clear(); } Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/PostDominators.h?rev=43263&r1=43262&r2=43263&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/PostDominators.h (original) +++ llvm/trunk/include/llvm/Analysis/PostDominators.h Tue Oct 23 16:42:49 2007 @@ -26,7 +26,7 @@ DominatorTreeBase* DT; PostDominatorTree() : FunctionPass((intptr_t)&ID) { - DT = new DominatorTreeBase(intptr_t(&ID), true); + DT = new DominatorTreeBase(true); } virtual bool runOnFunction(Function &F); From evan.cheng at apple.com Tue Oct 23 17:00:12 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 15:00:12 -0700 Subject: [llvm-commits] [llvm] r43262 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp In-Reply-To: <200710232130.l9NLUPpD009581@zion.cs.uiuc.edu> References: <200710232130.l9NLUPpD009581@zion.cs.uiuc.edu> Message-ID: <1DF5E1D0-0B13-47D2-BC5A-0B69D455FFBA@apple.com> Hi Bill, This disables too much. Even as a first step you should only disable this when it may be possible to generate a unaligned load / store. Also please add comments to describe what can go wrong when the destination is a stack object. Also, is it possible the same issue can arise when the source is a frameindex? Evan On Oct 23, 2007, at 2:30 PM, Bill Wendling wrote: > Author: void > Date: Tue Oct 23 16:30:25 2007 > New Revision: 43262 > > URL: http://llvm.org/viewvc/llvm-project?rev=43262&view=rev > Log: > Lowering a memcpy to the stack is killing PPC. The ARM and X86 > backends already > have their own custom memcpy lowering code. This code needs to be > factored out > into a target-independent lowering method with hooks to the backend. > In the > meantime, just call memcpy if we're trying to copy onto a stack. > > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43262&r1=43261&r2=43262&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct > 23 16:30:25 2007 > @@ -4302,6 +4302,10 @@ > break; > } > case ISD::MEMCPY: { > + // FIXME: Disabling memcpy lowering for copying onto the stack. > + if (Op1.getOpcode() == ISD::FrameIndex) > + break; > + > if (MeetsMaxMemopRequirement(MemOps, > TLI.getMaxStoresPerMemcpy(), > Size->getValue(), Align, TLI)) { > unsigned NumMemOps = MemOps.size(); > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Tue Oct 23 17:04:26 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 22:04:26 -0000 Subject: [llvm-commits] [llvm] r43264 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200710232204.l9NM4QxK011684@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 17:04:26 2007 New Revision: 43264 URL: http://llvm.org/viewvc/llvm-project?rev=43264&view=rev Log: This broke lots. Reverting. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43264&r1=43263&r2=43264&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 23 17:04:26 2007 @@ -4302,10 +4302,6 @@ break; } case ISD::MEMCPY: { - // FIXME: Disabling memcpy lowering for copying onto the stack. - if (Op1.getOpcode() == ISD::FrameIndex) - break; - if (MeetsMaxMemopRequirement(MemOps, TLI.getMaxStoresPerMemcpy(), Size->getValue(), Align, TLI)) { unsigned NumMemOps = MemOps.size(); From kremenek at apple.com Tue Oct 23 17:17:03 2007 From: kremenek at apple.com (Ted Kremenek) Date: Tue, 23 Oct 2007 22:17:03 -0000 Subject: [llvm-commits] [llvm] r43265 - /llvm/trunk/include/llvm/Bitcode/Serialization.h Message-ID: <200710232217.l9NMH32E012511@zion.cs.uiuc.edu> Author: kremenek Date: Tue Oct 23 17:17:03 2007 New Revision: 43265 URL: http://llvm.org/viewvc/llvm-project?rev=43265&view=rev Log: Added "ReadEnum" and "WriteEnum" to serialization classes. Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43265&r1=43264&r2=43265&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Tue Oct 23 17:17:03 2007 @@ -35,7 +35,12 @@ template inline void Emit(const T& X) { SerializeTrait::Serialize(*this,X); } - void EmitInt(unsigned X, unsigned bits); + void EmitInt(unsigned X, unsigned bits); + + // FIXME: Substitute a better implementation which calculates the minimum + // number of bits needed to serialize the enum. + void EmitEnum(unsigned X, unsigned MinVal, unsigned MaxVal) { EmitInt(X,32); } + void EmitCString(const char* cstr); void Flush() { if (inRecord()) EmitRecord(); } @@ -55,7 +60,7 @@ ~Deserializer(); template - inline void Read(T& X) { SerializeTrait::Deserialize(*this,X); } + inline T& Read(T& X) { SerializeTrait::Deserialize(*this,X); return X; } template inline T* Materialize() { @@ -67,6 +72,13 @@ uint64_t ReadInt(unsigned bits = 32); bool ReadBool() { return ReadInt(1); } + // FIXME: Substitute a better implementation which calculates the minimum + // number of bits needed to serialize the enum. + template + EnumT ReadEnum(unsigned MinVal, unsigned MaxVal) { + return static_cast(ReadInt(32)); + } + char* ReadCString(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); void ReadCString(std::vector& buff, bool isNullTerm=false); @@ -97,7 +109,6 @@ X = (uintty) S.ReadInt(Bits); } }; - template <> struct SerializeTrait : public SerializeIntTrait {}; @@ -111,5 +122,7 @@ template <> struct SerializeTrait : public SerializeIntTrait {}; + + } // end namespace llvm #endif From dalej at apple.com Tue Oct 23 18:20:21 2007 From: dalej at apple.com (Dale Johannesen) Date: Tue, 23 Oct 2007 23:20:21 -0000 Subject: [llvm-commits] [llvm] r43267 - /llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Message-ID: <200710232320.l9NNKMYN015566@zion.cs.uiuc.edu> Author: johannes Date: Tue Oct 23 18:20:14 2007 New Revision: 43267 URL: http://llvm.org/viewvc/llvm-project?rev=43267&view=rev Log: Disable a couple more things for ppcf128. Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=43267&r1=43266&r2=43267&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Tue Oct 23 18:20:14 2007 @@ -3143,7 +3143,8 @@ // Turn (sint_to_fp (fp_to_sint X)) -> fctidz/fcfid without load/stores. // We allow the src/dst to be either f32/f64, but the intermediate // type must be i64. - if (N->getOperand(0).getValueType() == MVT::i64) { + if (N->getOperand(0).getValueType() == MVT::i64 && + N->getOperand(0).getOperand(0).getValueType() != MVT::ppcf128) { SDOperand Val = N->getOperand(0).getOperand(0); if (Val.getValueType() == MVT::f32) { Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); @@ -3170,7 +3171,8 @@ // Turn STORE (FP_TO_SINT F) -> STFIWX(FCTIWZ(F)). if (TM.getSubtarget().hasSTFIWX() && N->getOperand(1).getOpcode() == ISD::FP_TO_SINT && - N->getOperand(1).getValueType() == MVT::i32) { + N->getOperand(1).getValueType() == MVT::i32 && + N->getOperand(1).getOperand(0).getValueType() != MVT::ppcf128) { SDOperand Val = N->getOperand(1).getOperand(0); if (Val.getValueType() == MVT::f32) { Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); From isanbard at gmail.com Tue Oct 23 18:32:42 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 23:32:42 -0000 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Message-ID: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 18:32:40 2007 New Revision: 43270 URL: http://llvm.org/viewvc/llvm-project?rev=43270&view=rev Log: If there's an unaligned memcpy to/from the stack, don't lower it. Just call the memcpy library function instead. Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43270&r1=43269&r2=43270&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 23 18:32:40 2007 @@ -4329,6 +4329,19 @@ } } + // Check to see if there is an unaligned memcpy from/onto the stack. If + // so, then ignore it for the present. + if (Op1.getOpcode() == ISD::FrameIndex || + Op2.getOpcode() == ISD::FrameIndex) { + unsigned TotalSize = 0; + + for (unsigned i = 0; i < NumMemOps; i++) + TotalSize += MVT::getSizeInBits(MemOps[i]) / 8; + + if (TotalSize % Align != 0) + break; + } + for (unsigned i = 0; i < NumMemOps; i++) { MVT::ValueType VT = MemOps[i]; unsigned VTSize = MVT::getSizeInBits(VT) / 8; Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll?rev=43270&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll (added) +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Tue Oct 23 18:32:40 2007 @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -o - | grep memcpy + + at C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> [#uses=1] + +define void @Bork() { +entry: + %Qux = alloca [33 x i8] ; <[33 x i8]*> [#uses=1] + %Qux1 = bitcast [33 x i8]* %Qux to i8* ; [#uses=1] + call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) + ret void +} + +declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) From isanbard at gmail.com Tue Oct 23 18:36:57 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 23:36:57 -0000 Subject: [llvm-commits] [llvm] r43271 - /llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Message-ID: <200710232336.l9NNavKJ016278@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 18:36:57 2007 New Revision: 43271 URL: http://llvm.org/viewvc/llvm-project?rev=43271&view=rev Log: Fix comment and use the "Size" variable that's already provided. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43271&r1=43270&r2=43271&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Oct 23 18:36:57 2007 @@ -4329,18 +4329,13 @@ } } - // Check to see if there is an unaligned memcpy from/onto the stack. If - // so, then ignore it for the present. + // The lowered load/store instructions from/to the stack frame can be + // unaligned depending on whether it's accessed off sp or fp. If this is + // the case, then just use the memcpy library call. if (Op1.getOpcode() == ISD::FrameIndex || - Op2.getOpcode() == ISD::FrameIndex) { - unsigned TotalSize = 0; - - for (unsigned i = 0; i < NumMemOps; i++) - TotalSize += MVT::getSizeInBits(MemOps[i]) / 8; - - if (TotalSize % Align != 0) + Op2.getOpcode() == ISD::FrameIndex) + if (Size->getValue() % Align != 0) break; - } for (unsigned i = 0; i < NumMemOps; i++) { MVT::ValueType VT = MemOps[i]; From isanbard at gmail.com Tue Oct 23 18:45:13 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 23:45:13 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43272 - /llvm-gcc-4.0/tags/llvm-gcc-1200-19/ Message-ID: <200710232345.l9NNjDUp016626@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 18:45:12 2007 New Revision: 43272 URL: http://llvm.org/viewvc/llvm-project?rev=43272&view=rev Log: Creating llvm-gcc-1200-19 branch Added: llvm-gcc-4.0/tags/llvm-gcc-1200-19/ - copied from r43271, llvm-gcc-4.0/trunk/ From isanbard at gmail.com Tue Oct 23 18:45:18 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 23:45:18 -0000 Subject: [llvm-commits] [llvm] r43273 - /llvm/tags/Apple/llvm-1200-19/ Message-ID: <200710232345.l9NNjIhE016640@zion.cs.uiuc.edu> Author: void Date: Tue Oct 23 18:45:18 2007 New Revision: 43273 URL: http://llvm.org/viewvc/llvm-project?rev=43273&view=rev Log: Creating llvm-1200-19 branch Added: llvm/tags/Apple/llvm-1200-19/ - copied from r43272, llvm/trunk/ From clattner at apple.com Tue Oct 23 18:47:33 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 16:47:33 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> Message-ID: > URL: http://llvm.org/viewvc/llvm-project?rev=43270&view=rev > Log: > If there's an unaligned memcpy to/from the stack, don't lower it. > Just call the > memcpy library function instead. Hey Bill, There is nothing specific about the stack here, please just make it depend on whether the alignment of the src/dest pointers are sufficient. -Chris > Added: > llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll > Modified: > llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > > Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ > SelectionDAG/SelectionDAGISel.cpp? > rev=43270&r1=43269&r2=43270&view=diff > > ====================================================================== > ======== > --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp > (original) > +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue > Oct 23 18:32:40 2007 > @@ -4329,6 +4329,19 @@ > } > } > > + // Check to see if there is an unaligned memcpy from/onto > the stack. If > + // so, then ignore it for the present. > + if (Op1.getOpcode() == ISD::FrameIndex || > + Op2.getOpcode() == ISD::FrameIndex) { > + unsigned TotalSize = 0; > + > + for (unsigned i = 0; i < NumMemOps; i++) > + TotalSize += MVT::getSizeInBits(MemOps[i]) / 8; > + > + if (TotalSize % Align != 0) > + break; > + } > + > for (unsigned i = 0; i < NumMemOps; i++) { > MVT::ValueType VT = MemOps[i]; > unsigned VTSize = MVT::getSizeInBits(VT) / 8; > > Added: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ > PowerPC/2007-10-23-UnalignedMemcpy.ll?rev=43270&view=auto > > ====================================================================== > ======== > --- llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll > (added) > +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll > Tue Oct 23 18:32:40 2007 > @@ -0,0 +1,13 @@ > +; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -o - | > grep memcpy > + > + at C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> > [#uses=1] > + > +define void @Bork() { > +entry: > + %Qux = alloca [33 x i8] ; <[33 x i8]*> [#uses=1] > + %Qux1 = bitcast [33 x i8]* %Qux to i8* ; > [#uses=1] > + call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr > ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) > + ret void > +} > + > +declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Tue Oct 23 18:50:32 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 16:50:32 -0700 Subject: [llvm-commits] [llvm] r43259 - in /llvm/trunk: include/llvm/Analysis/PostDominators.h lib/Analysis/PostDominators.cpp lib/VMCore/Dominators.cpp In-Reply-To: <200710232058.l9NKwfBR007886@zion.cs.uiuc.edu> References: <200710232058.l9NKwfBR007886@zion.cs.uiuc.edu> Message-ID: On Oct 23, 2007, at 1:58 PM, Owen Anderson wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=43259&view=rev > Log: > Make DomTree and PostDomTree thin wrappers around DomTreeBase, > rather than inheriting from it. Very nice! > @@ -21,17 +21,39 @@ > /// PostDominatorTree Class - Concrete subclass of DominatorTree > that is used to > /// compute the a post-dominator tree. > /// > -struct PostDominatorTree : public DominatorTreeBase { > +struct PostDominatorTree : public FunctionPass { > static char ID; // Pass identification, replacement for typeid > + DominatorTreeBase* DT; Is there any reason to new/delete the DT pointer? Why not just have DomTreeBase be embedded by-value? -Chris From hartmut.kaiser at gmail.com Tue Oct 23 18:57:01 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Tue, 23 Oct 2007 23:57:01 -0000 Subject: [llvm-commits] [llvm] r43275 - /llvm/trunk/win32/Bitcode/Bitcode.vcproj Message-ID: <200710232357.l9NNv2H0017254@zion.cs.uiuc.edu> Author: hkaiser Date: Tue Oct 23 18:57:01 2007 New Revision: 43275 URL: http://llvm.org/viewvc/llvm-project?rev=43275&view=rev Log: Updated VC++ build system Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Bitcode/Bitcode.vcproj?rev=43275&r1=43274&r2=43275&view=diff ============================================================================== --- llvm/trunk/win32/Bitcode/Bitcode.vcproj (original) +++ llvm/trunk/win32/Bitcode/Bitcode.vcproj Tue Oct 23 18:57:01 2007 @@ -161,10 +161,6 @@ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > - - @@ -176,6 +172,10 @@ RelativePath="..\..\lib\Bitcode\Reader\BitcodeReader.h" > + + + + + + From hartmut.kaiser at gmail.com Tue Oct 23 19:06:31 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Wed, 24 Oct 2007 00:06:31 -0000 Subject: [llvm-commits] [llvm] r43276 - in /llvm/trunk/include/llvm/Bitcode: BitstreamReader.h Serialization.h Message-ID: <200710240006.l9O06Vfo017602@zion.cs.uiuc.edu> Author: hkaiser Date: Tue Oct 23 19:06:31 2007 New Revision: 43276 URL: http://llvm.org/viewvc/llvm-project?rev=43276&view=rev Log: Silenced a VC++ warning. Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h llvm/trunk/include/llvm/Bitcode/Serialization.h Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=43276&r1=43275&r2=43276&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Oct 23 19:06:31 2007 @@ -385,7 +385,7 @@ BitCodeAbbrev *Abbv = new BitCodeAbbrev(); unsigned NumOpInfo = ReadVBR(5); for (unsigned i = 0; i != NumOpInfo; ++i) { - bool IsLiteral = Read(1); + bool IsLiteral = Read(1) ? true : false; if (IsLiteral) { Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); continue; Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43276&r1=43275&r2=43276&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Tue Oct 23 19:06:31 2007 @@ -70,7 +70,7 @@ } uint64_t ReadInt(unsigned bits = 32); - bool ReadBool() { return ReadInt(1); } + bool ReadBool() { return ReadInt(1) ? true : false; } // FIXME: Substitute a better implementation which calculates the minimum // number of bits needed to serialize the enum. From isanbard at gmail.com Tue Oct 23 19:11:30 2007 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 23 Oct 2007 17:11:30 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> Message-ID: <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> On 10/23/07, Chris Lattner wrote: > > URL: http://llvm.org/viewvc/llvm-project?rev=43270&view=rev > > Log: > > If there's an unaligned memcpy to/from the stack, don't lower it. > > Just call the > > memcpy library function instead. > > Hey Bill, > > There is nothing specific about the stack here, please just make it > depend on whether the alignment of the src/dest pointers are sufficient. > Are you certain? When Evan and I looked at it, it seemed like it was mostly having problems with the stack pointer and alignment. If it wasn't aligned for PPC, then it would barf. I'm that's not the case, then this would be the patch, right? if (Size % Align != 0) break; -bw From hartmut.kaiser at gmail.com Tue Oct 23 19:13:42 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Wed, 24 Oct 2007 00:13:42 -0000 Subject: [llvm-commits] [llvm] r43279 - /llvm/trunk/win32/clang.sln Message-ID: <200710240013.l9O0Dgkv017942@zion.cs.uiuc.edu> Author: hkaiser Date: Tue Oct 23 19:13:40 2007 New Revision: 43279 URL: http://llvm.org/viewvc/llvm-project?rev=43279&view=rev Log: Added VC++ solution file allowing to build clang. Added: llvm/trunk/win32/clang.sln (with props) Added: llvm/trunk/win32/clang.sln URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/clang.sln?rev=43279&view=auto ============================================================================== --- llvm/trunk/win32/clang.sln (added) +++ llvm/trunk/win32/clang.sln Tue Oct 23 19:13:40 2007 @@ -0,0 +1,740 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "support", "Support\Support.vcproj", "{28AA9146-3482-4F41-9CC6-407B1D258508}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TableGen", "TableGen\TableGen.vcproj", "{339C2249-26B6-4172-B484-85653029AF57}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}") = "Fibonacci", "Fibonacci\Fibonacci.vcproj", "{48FB551D-E37E-42EC-BC97-FF7219774867}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodeGen", "CodeGen\CodeGen.vcproj", "{08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Analysis", "Analysis\Analysis.vcproj", "{0622E827-8464-489D-8B1C-B0B496F35C08}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lli", "lli\lli.vcproj", "{FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "llvm-ar", "llvm-ar\llvm-ar.vcproj", "{0FF2B75C-49C1-4B49-A44A-531C93000296}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {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}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Archive", "Archive\Archive.vcproj", "{F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {19514E48-456C-4B9D-8637-F2285476461E} = {19514E48-456C-4B9D-8637-F2285476461E} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LLVM", "LLVM", "{455BCF47-13B6-451E-8321-8ED9C4866BAA}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Clang", "Clang", "{DAC2AB11-F09C-454B-86FD-9BDBBA25827F}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangLex", "..\tools\clang\win32\clangLex\clangLex.vcproj", "{030F6909-B2FA-4E53-BEA7-9A559CFC2F73}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangParse", "..\tools\clang\win32\clangParse\clangParse.vcproj", "{05DF3074-11AF-491A-B078-83BD2EDC31F6}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangAST", "..\tools\clang\win32\clangAST\clangAST.vcproj", "{5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangSema", "..\tools\clang\win32\clangSema\clangSema.vcproj", "{4727E8B7-AA99-41C9-AB09-A8A862595DB7}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangCodeGen", "..\tools\clang\win32\clangCodeGen\clangCodeGen.vcproj", "{4CEC5897-D957-47E7-A6AE-2021D4F44A8F}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangDriver", "..\tools\clang\win32\clangDriver\clangDriver.vcproj", "{7E7DA455-C276-4B93-8D02-8F7E2F629BAF}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection + ProjectSection(ProjectDependencies) = postProject + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73} = {030F6909-B2FA-4E53-BEA7-9A559CFC2F73} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0} = {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD} = {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} + {4727E8B7-AA99-41C9-AB09-A8A862595DB7} = {4727E8B7-AA99-41C9-AB09-A8A862595DB7} + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F} = {4CEC5897-D957-47E7-A6AE-2021D4F44A8F} + {298B4876-6EF1-4E80-85D7-72F80693BBEB} = {298B4876-6EF1-4E80-85D7-72F80693BBEB} + {05DF3074-11AF-491A-B078-83BD2EDC31F6} = {05DF3074-11AF-491A-B078-83BD2EDC31F6} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {28AA9146-3482-4F41-9CC6-407B1D258508} + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D} = {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangBasic", "..\tools\clang\win32\clangBasic\clangBasic.vcproj", "{298B4876-6EF1-4E80-85D7-72F80693BBEB}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangAnalysis", "..\tools\clang\win32\clangAnalysis\clangAnalysis.vcproj", "{6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "clangRewrite", "..\tools\clang\win32\clangRewrite\clangRewrite.vcproj", "{F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}" + ProjectSection(WebsiteProperties) = preProject + Debug.AspNetCompiler.Debug = "True" + Release.AspNetCompiler.Debug = "False" + EndProjectSection +EndProject +Global + GlobalSection(DPCodeReviewSolutionGUID) = preSolution + DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Configure|Win32 = Configure|Win32 + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + 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}.Debug|Win32.ActiveCfg = Debug|Win32 + {28AA9146-3482-4F41-9CC6-407B1D258508}.Debug|Win32.Build.0 = Debug|Win32 + {28AA9146-3482-4F41-9CC6-407B1D258508}.Release|Win32.ActiveCfg = Release|Win32 + {28AA9146-3482-4F41-9CC6-407B1D258508}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {339C2249-26B6-4172-B484-85653029AF57}.Debug|Win32.Build.0 = Debug|Win32 + {339C2249-26B6-4172-B484-85653029AF57}.Release|Win32.ActiveCfg = Release|Win32 + {339C2249-26B6-4172-B484-85653029AF57}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {48FB551D-E37E-42EC-BC97-FF7219774867}.Debug|Win32.Build.0 = Debug|Win32 + {48FB551D-E37E-42EC-BC97-FF7219774867}.Release|Win32.ActiveCfg = Release|Win32 + {48FB551D-E37E-42EC-BC97-FF7219774867}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {76295AE8-A083-460E-9F80-6F2B8923264A}.Debug|Win32.Build.0 = Debug|Win32 + {76295AE8-A083-460E-9F80-6F2B8923264A}.Release|Win32.ActiveCfg = Release|Win32 + {76295AE8-A083-460E-9F80-6F2B8923264A}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Debug|Win32.Build.0 = Debug|Win32 + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|Win32.ActiveCfg = Release|Win32 + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Debug|Win32.Build.0 = Debug|Win32 + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|Win32.ActiveCfg = Release|Win32 + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Debug|Win32.Build.0 = Debug|Win32 + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|Win32.ActiveCfg = Release|Win32 + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Debug|Win32.Build.0 = Debug|Win32 + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|Win32.ActiveCfg = Release|Win32 + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {0622E827-8464-489D-8B1C-B0B496F35C08}.Debug|Win32.Build.0 = Debug|Win32 + {0622E827-8464-489D-8B1C-B0B496F35C08}.Release|Win32.ActiveCfg = Release|Win32 + {0622E827-8464-489D-8B1C-B0B496F35C08}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {144EEBF6-8C9B-4473-B715-2C821666AF6C}.Debug|Win32.Build.0 = Debug|Win32 + {144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|Win32.ActiveCfg = Release|Win32 + {144EEBF6-8C9B-4473-B715-2C821666AF6C}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {C59374C1-9FC0-4147-B836-327DFDC52D99}.Debug|Win32.Build.0 = Debug|Win32 + {C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|Win32.ActiveCfg = Release|Win32 + {C59374C1-9FC0-4147-B836-327DFDC52D99}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Configure|Win32 + {19514E48-456C-4B9D-8637-F2285476461E}.Debug|Win32.Build.0 = Configure|Win32 + {19514E48-456C-4B9D-8637-F2285476461E}.Release|Win32.ActiveCfg = Configure|Win32 + {19514E48-456C-4B9D-8637-F2285476461E}.Release|Win32.Build.0 = Configure|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Debug|Win32.Build.0 = Debug|Win32 + {FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|Win32.ActiveCfg = Release|Win32 + {FB6FFD68-C1E4-4DCF-AB02-36D205D5263E}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Debug|Win32.Build.0 = Debug|Win32 + {ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|Win32.ActiveCfg = Release|Win32 + {ADE86BDC-B04C-43DF-B9BB-90492C7B14AC}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {B13476BC-30AB-4EA0-BC1E-212C0A459405}.Debug|Win32.Build.0 = Debug|Win32 + {B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|Win32.ActiveCfg = Release|Win32 + {B13476BC-30AB-4EA0-BC1E-212C0A459405}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Debug|Win32.Build.0 = Debug|Win32 + {4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|Win32.ActiveCfg = Release|Win32 + {4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {3DC216F5-1DDD-478A-84F8-C124E5C31982}.Debug|Win32.Build.0 = Debug|Win32 + {3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|Win32.ActiveCfg = Release|Win32 + {3DC216F5-1DDD-478A-84F8-C124E5C31982}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {0FF2B75C-49C1-4B49-A44A-531C93000296}.Debug|Win32.Build.0 = Debug|Win32 + {0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|Win32.ActiveCfg = Release|Win32 + {0FF2B75C-49C1-4B49-A44A-531C93000296}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Debug|Win32.Build.0 = Debug|Win32 + {BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|Win32.ActiveCfg = Release|Win32 + {BB16C7EE-B4ED-4714-B5ED-B775C62A6612}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {5E249789-49E1-4600-B12B-8AD2BB6439B2}.Debug|Win32.Build.0 = Debug|Win32 + {5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|Win32.ActiveCfg = Release|Win32 + {5E249789-49E1-4600-B12B-8AD2BB6439B2}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {342CF48F-760A-4040-A9A1-7D75AA2471CE}.Debug|Win32.Build.0 = Debug|Win32 + {342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|Win32.ActiveCfg = Release|Win32 + {342CF48F-760A-4040-A9A1-7D75AA2471CE}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {057777CD-DED5-46DF-BF9A-6B76DE212549}.Debug|Win32.Build.0 = Debug|Win32 + {057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|Win32.ActiveCfg = Release|Win32 + {057777CD-DED5-46DF-BF9A-6B76DE212549}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Debug|Win32.Build.0 = Debug|Win32 + {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|Win32.ActiveCfg = Release|Win32 + {006D8B41-C3C7-4448-85E1-AF8907E591E5}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Debug|Win32.Build.0 = Debug|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|Win32.ActiveCfg = Release|Win32 + {E0B1E329-BE3E-456D-B372-5F397BE42C84}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Debug|Win32.Build.0 = Debug|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|Win32.ActiveCfg = Release|Win32 + {64D8AA46-88DB-41F4-B837-053AE02406B8}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Debug|Win32.Build.0 = Debug|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|Win32.ActiveCfg = Release|Win32 + {5FF862CE-80A0-4B48-A80B-68AE325A0432}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Debug|Win32.Build.0 = Debug|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|Win32.ActiveCfg = Release|Win32 + {ACBE81D9-64B1-4133-823A-807A4E60B454}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Debug|Win32.Build.0 = Debug|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|Win32.ActiveCfg = Release|Win32 + {57249192-8E29-4D85-8B7A-FEFF1760B1DA}.Release|Win32.Build.0 = Release|Win32 + {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}.Debug|Win32.ActiveCfg = Debug|Win32 + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62}.Debug|Win32.Build.0 = Debug|Win32 + {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-CD8F4A5F8D61}.Configure|Win32.ActiveCfg = Release|Win32 + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Configure|Win32.Build.0 = 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}.Release|Win32.ActiveCfg = Release|Win32 + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61}.Release|Win32.Build.0 = Release|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Configure|Win32.ActiveCfg = Release|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Configure|Win32.Build.0 = Release|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Debug|Win32.ActiveCfg = Debug|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Debug|Win32.Build.0 = Debug|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Release|Win32.ActiveCfg = Release|Win32 + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73}.Release|Win32.Build.0 = Release|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Configure|Win32.ActiveCfg = Release|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Configure|Win32.Build.0 = Release|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Debug|Win32.Build.0 = Debug|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Release|Win32.ActiveCfg = Release|Win32 + {05DF3074-11AF-491A-B078-83BD2EDC31F6}.Release|Win32.Build.0 = Release|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Configure|Win32.ActiveCfg = Release|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Configure|Win32.Build.0 = Release|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Debug|Win32.ActiveCfg = Debug|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Debug|Win32.Build.0 = Debug|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Release|Win32.ActiveCfg = Release|Win32 + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD}.Release|Win32.Build.0 = Release|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Configure|Win32.ActiveCfg = Release|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Configure|Win32.Build.0 = Release|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Debug|Win32.ActiveCfg = Debug|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Debug|Win32.Build.0 = Debug|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Release|Win32.ActiveCfg = Release|Win32 + {4727E8B7-AA99-41C9-AB09-A8A862595DB7}.Release|Win32.Build.0 = Release|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Configure|Win32.ActiveCfg = Release|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Configure|Win32.Build.0 = Release|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Debug|Win32.ActiveCfg = Debug|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Debug|Win32.Build.0 = Debug|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Release|Win32.ActiveCfg = Release|Win32 + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F}.Release|Win32.Build.0 = Release|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Configure|Win32.ActiveCfg = Release|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Configure|Win32.Build.0 = Release|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Debug|Win32.Build.0 = Debug|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Release|Win32.ActiveCfg = Release|Win32 + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF}.Release|Win32.Build.0 = Release|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Configure|Win32.ActiveCfg = Release|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Configure|Win32.Build.0 = Release|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Debug|Win32.Build.0 = Debug|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Release|Win32.ActiveCfg = Release|Win32 + {298B4876-6EF1-4E80-85D7-72F80693BBEB}.Release|Win32.Build.0 = Release|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Configure|Win32.ActiveCfg = Release|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Configure|Win32.Build.0 = Release|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Debug|Win32.ActiveCfg = Debug|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Debug|Win32.Build.0 = Debug|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Release|Win32.ActiveCfg = Release|Win32 + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0}.Release|Win32.Build.0 = Release|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Configure|Win32.ActiveCfg = Release|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Configure|Win32.Build.0 = Release|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Debug|Win32.ActiveCfg = Debug|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Debug|Win32.Build.0 = Debug|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Release|Win32.ActiveCfg = Release|Win32 + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {339C2249-26B6-4172-B484-85653029AF57} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {48FB551D-E37E-42EC-BC97-FF7219774867} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {76295AE8-A083-460E-9F80-6F2B8923264A} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {45CD78D7-C5D9-47FE-AD12-F3251EEDAFFB} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {059FBAB8-C76D-48A0-AA75-3C57BD3EAFE4} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {08CEB1BB-C2A4-4587-B9A9-AEDB8FB44897} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {0F8407F3-FA23-4CF1-83A9-DCBE0B361489} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {0622E827-8464-489D-8B1C-B0B496F35C08} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {144EEBF6-8C9B-4473-B715-2C821666AF6C} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {C59374C1-9FC0-4147-B836-327DFDC52D99} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {19514E48-456C-4B9D-8637-F2285476461E} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {FB6FFD68-C1E4-4DCF-AB02-36D205D5263E} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {ADE86BDC-B04C-43DF-B9BB-90492C7B14AC} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {B13476BC-30AB-4EA0-BC1E-212C0A459405} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {4FBC40A5-E626-4A6C-A9D3-FAE5C28D30CC} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {3DC216F5-1DDD-478A-84F8-C124E5C31982} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {0FF2B75C-49C1-4B49-A44A-531C93000296} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {BB16C7EE-B4ED-4714-B5ED-B775C62A6612} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {5E249789-49E1-4600-B12B-8AD2BB6439B2} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {342CF48F-760A-4040-A9A1-7D75AA2471CE} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {057777CD-DED5-46DF-BF9A-6B76DE212549} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {006D8B41-C3C7-4448-85E1-AF8907E591E5} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {E0B1E329-BE3E-456D-B372-5F397BE42C84} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {64D8AA46-88DB-41F4-B837-053AE02406B8} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {5FF862CE-80A0-4B48-A80B-68AE325A0432} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {ACBE81D9-64B1-4133-823A-807A4E60B454} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {57249192-8E29-4D85-8B7A-FEFF1760B1DA} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D62} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {F1EFF064-8869-4DFF-8E1A-CD8F4A5F8D61} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {28AA9146-3482-4F41-9CC6-407B1D258508} = {455BCF47-13B6-451E-8321-8ED9C4866BAA} + {030F6909-B2FA-4E53-BEA7-9A559CFC2F73} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {05DF3074-11AF-491A-B078-83BD2EDC31F6} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {5125C3DB-FBD6-4BF8-8D8B-CE51D6E93BCD} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {4727E8B7-AA99-41C9-AB09-A8A862595DB7} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {4CEC5897-D957-47E7-A6AE-2021D4F44A8F} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {7E7DA455-C276-4B93-8D02-8F7E2F629BAF} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {298B4876-6EF1-4E80-85D7-72F80693BBEB} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {6C98551A-4C36-4E74-8419-4D3EEEC9D8E0} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + {F9FBDDA2-9EE1-473C-A456-BE20B7B2439D} = {DAC2AB11-F09C-454B-86FD-9BDBBA25827F} + EndGlobalSection +EndGlobal Propchange: llvm/trunk/win32/clang.sln ------------------------------------------------------------------------------ svn:eol-style = CRLF Propchange: llvm/trunk/win32/clang.sln ------------------------------------------------------------------------------ svn:mime-type = text/xml From clattner at apple.com Tue Oct 23 19:47:17 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 17:47:17 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> Message-ID: <6E094317-B03F-419A-81FA-A9434F122141@apple.com> On Oct 23, 2007, at 5:11 PM, Bill Wendling wrote: > On 10/23/07, Chris Lattner wrote: >>> URL: http://llvm.org/viewvc/llvm-project?rev=43270&view=rev >>> Log: >>> If there's an unaligned memcpy to/from the stack, don't lower it. >>> Just call the >>> memcpy library function instead. >> >> Hey Bill, >> >> There is nothing specific about the stack here, please just make it >> depend on whether the alignment of the src/dest pointers are >> sufficient. >> > Are you certain? When Evan and I looked at it, it seemed like it was > mostly having problems with the stack pointer and alignment. If it > wasn't aligned for PPC, then it would barf. In this testcase yes. > I'm that's not the case, then this would be the patch, right? > > if (Size % Align != 0) > break; I haven't looked at the code, but the size of the memcpy has nothing to do with it. This is strictly a problem because memcpy lowering is making 8-byte stores to a pointer that is not 8-byte aligned. This is independent of the size that is ultimately copied. Evan, thoughts? -Chris From evan.cheng at apple.com Tue Oct 23 20:00:03 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 18:00:03 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> Message-ID: Now that I think about it some more. The bug Bill and I looked at appears to be just a PPC prologue / epilogue lowering bug. It doesn't seem to be rounding up the size of the stack correctly. Suppose the size of source frame object is 5, this can be lowered into a pair of 4 byte load / store and a pair of 1 byte load / store: fi#0 : size 5, align 4 v1 = load i32 [fi#0], 0 store v1 v2 = load i8 [fi#0], 4 store v2 If fi#0 offset 0 is accessed off sp, then all is well, If it's accessed off fp, then the 32-bit load is unaligned. The problem is probably as simple as rounding up the size of the stack to be multiple of 4 and adjust the fp index accordingly. Evan On Oct 23, 2007, at 5:11 PM, Bill Wendling wrote: > On 10/23/07, Chris Lattner wrote: >>> URL: http://llvm.org/viewvc/llvm-project?rev=43270&view=rev >>> Log: >>> If there's an unaligned memcpy to/from the stack, don't lower it. >>> Just call the >>> memcpy library function instead. >> >> Hey Bill, >> >> There is nothing specific about the stack here, please just make it >> depend on whether the alignment of the src/dest pointers are >> sufficient. >> > Are you certain? When Evan and I looked at it, it seemed like it was > mostly having problems with the stack pointer and alignment. If it > wasn't aligned for PPC, then it would barf. > > I'm that's not the case, then this would be the patch, right? > > if (Size % Align != 0) > break; > > -bw > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From clattner at apple.com Tue Oct 23 20:18:52 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 18:18:52 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> Message-ID: <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> On Oct 23, 2007, at 6:00 PM, Evan Cheng wrote: > Now that I think about it some more. The bug Bill and I looked at > appears to be just a PPC prologue / epilogue lowering bug. It doesn't > seem to be rounding up the size of the stack correctly. > > Suppose the size of source frame object is 5, this can be lowered into > a pair of 4 byte load / store and a pair of 1 byte load / store: > > fi#0 : size 5, align 4 > > v1 = load i32 [fi#0], 0 > store v1 > v2 = load i8 [fi#0], 4 > store v2 > > If fi#0 offset 0 is accessed off sp, then all is well, If it's > accessed off fp, then the 32-bit load is unaligned. The problem is > probably as simple as rounding up the size of the stack to be multiple > of 4 and adjust the fp index accordingly. The frame lowering stuff is right. The PPC backend is using the redzone, so the stack pointer doesn't need to move. This is just accessing 33 bytes below the stack pointer, which isn't aligned. Again, in this specific case you could force the frame object to be aligned or something, but that wouldn't help the case when some random unaligned pointer is memcpy'd. -Chris From sabre at nondot.org Tue Oct 23 23:35:55 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 04:35:55 -0000 Subject: [llvm-commits] [llvm] r43286 - /llvm/trunk/tools/llvm-config/llvm-config.in.in Message-ID: <200710240435.l9O4ZtpO029341@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 23:35:54 2007 New Revision: 43286 URL: http://llvm.org/viewvc/llvm-project?rev=43286&view=rev Log: Fix PR1739. Modified: llvm/trunk/tools/llvm-config/llvm-config.in.in Modified: llvm/trunk/tools/llvm-config/llvm-config.in.in URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-config/llvm-config.in.in?rev=43286&r1=43285&r2=43286&view=diff ============================================================================== --- llvm/trunk/tools/llvm-config/llvm-config.in.in (original) +++ llvm/trunk/tools/llvm-config/llvm-config.in.in Tue Oct 23 23:35:54 2007 @@ -64,14 +64,20 @@ # Convert the current executable name into its directory (e.g. "."). my ($RUN_DIR) = ($0 =~ /^(.*)\/.*$/); +# Find the unix pwd program: we don't want to use the bash builtin, as it does +# not look through symlinks etc. +my $PWD = `which pwd`; +chomp($PWD); +$PWD = "pwd" if (!-e $PWD); + # Turn the directory into an absolute directory on the file system, also pop up # from "bin" into the build or prefix dir. -my $ABS_RUN_DIR = `cd $RUN_DIR/..; pwd`; +my $ABS_RUN_DIR = `cd $RUN_DIR/..; $PWD`; chomp($ABS_RUN_DIR); # Compute the absolute object directory build, e.g. "foo/llvm/Debug". my $ABS_OBJ_ROOT = "$LLVM_OBJ_ROOT/$LLVM_BUILDMODE"; -$ABS_OBJ_ROOT = `cd $ABS_OBJ_ROOT; pwd` if (-d $ABS_OBJ_ROOT); +$ABS_OBJ_ROOT = `cd $ABS_OBJ_ROOT; $PWD` if (-d $ABS_OBJ_ROOT); chomp($ABS_OBJ_ROOT); my $INCLUDEDIR = "$ABS_RUN_DIR/include"; @@ -136,9 +142,9 @@ } elsif ($arg eq "--build-mode") { $has_opt = 1; print "$LLVM_BUILDMODE\n"; } elsif ($arg eq "--obj-root") { - $has_opt = 1; print `cd $LLVM_OBJ_ROOT/; pwd`; + $has_opt = 1; print `cd $LLVM_OBJ_ROOT/; $PWD`; } elsif ($arg eq "--src-root") { - $has_opt = 1; print `cd $LLVM_SRC_ROOT/; pwd`; + $has_opt = 1; print `cd $LLVM_SRC_ROOT/; $PWD`; } else { usage(); } From sabre at nondot.org Tue Oct 23 23:37:24 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 04:37:24 -0000 Subject: [llvm-commits] [llvm] r43287 - /llvm/trunk/docs/tutorial/LangImpl3.html Message-ID: <200710240437.l9O4bODI029418@zion.cs.uiuc.edu> Author: lattner Date: Tue Oct 23 23:37:23 2007 New Revision: 43287 URL: http://llvm.org/viewvc/llvm-project?rev=43287&view=rev Log: Fix instructions now that PR1739 is fixed. Modified: llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43287&r1=43286&r2=43287&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Tue Oct 23 23:37:23 2007 @@ -611,7 +611,7 @@
        # Compile
        g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    -                  `llvm-config --libs core` -I ~/llvm/include/ -o toy
    +                  `llvm-config --libs core` -o toy
        # Run
        ./toy
     
    From clattner at apple.com Wed Oct 24 00:05:27 2007 From: clattner at apple.com (Chris Lattner) Date: Tue, 23 Oct 2007 22:05:27 -0700 Subject: [llvm-commits] [llvm] r43261 - in /llvm/trunk: include/llvm/Bitcode/Serialization.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp In-Reply-To: <200710232129.l9NLTXWd009517@zion.cs.uiuc.edu> References: <200710232129.l9NLTXWd009517@zion.cs.uiuc.edu> Message-ID: > URL: http://llvm.org/viewvc/llvm-project?rev=43261&view=rev > Log: > Added preliminary implementation of generic object serialization to > bitcode. > > ====================================================================== > ======== > --- llvm/trunk/include/llvm/Bitcode/Serialization.h (added) > +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Tue Oct 23 > 16:29:33 2007 > @@ -0,0 +1,115 @@ > + //=- Serialization.h - Generic Object Serialization to Bitcode --- > *- C++ -*-=// A critical flaw is revealed! you have an extra space at the start of the line. :) > +#ifndef LLVM_BITCODE_SERIALIZE > +#define LLVM_BITCODE_SERIALIZE > + > +#include "llvm/Bitcode/BitstreamWriter.h" > +#include "llvm/Bitcode/BitstreamReader.h" Would it make sense to split this function up into a Serializer.h and Deserializer.h that only brings on one of these each respectively? Then Serialization.h would have the stuff that is truly common. This would also match the structure of your .cpp files. > +#include "llvm/ADT/SmallVector.h" > +#include > + > +namespace llvm { > + > +template struct SerializeTrait; > + > +class Serializer { This needs a nice big doxygen comment above it explaining what it is. > + BitstreamWriter& Stream; > + SmallVector Record; > + bool inBlock; > +public: > + Serializer(BitstreamWriter& stream, unsigned BlockID = 0); > + ~Serializer(); > + > + template > + inline void Emit(const T& X) { SerializeTrait::Serialize > (*this,X); } > + > + void EmitInt(unsigned X, unsigned bits); > + void EmitCString(const char* cstr); > + > + void Flush() { if (inRecord()) EmitRecord(); } > + > +private: > + void EmitRecord(); > + inline bool inRecord() { return Record.size() > 0; } > +}; > + > + > +class Deserializer { Likewise, needs a comment. > > +template > +struct SerializeIntTrait { > + static inline void Serialize(Serializer& S, uintty X) { > + S.EmitInt(X,Bits); > + } > + > + static inline void Deserialize(Deserializer& S, uintty& X) { > + X = (uintty) S.ReadInt(Bits); > + } > +}; Ok. > +template <> struct SerializeTrait > + : public SerializeIntTrait {}; > + > +template <> struct SerializeTrait > + : public SerializeIntTrait {}; > + > +template <> struct SerializeTrait > + : public SerializeIntTrait {}; > + > +template <> struct SerializeTrait > + : public SerializeIntTrait {}; This won't work: the sizes of these types aren't guaranteed to be what you claim them to be. You could use: > +template <> struct SerializeTrait > + : public SerializeIntTrait {}; though. More significantly, I don't think you need a size in bits at all. Just allow the default vbr encoding to work for now, we can worry about optimizing them later, no? > ====================================================================== > ======== > --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (added) > +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Tue Oct 23 16:29:33 > 2007 > @@ -0,0 +1,52 @@ > + > +Serializer::Serializer(BitstreamWriter& stream, unsigned BlockID) > + : Stream(stream), inBlock(BlockID >= 8) { > + > + if (inBlock) Stream.EnterSubblock(8,3); This is obviously very early, but what is the magic number 8 here? > +void Serializer::EmitRecord() { > + assert(Record.size() > 0 && "Cannot emit empty record."); > + Stream.EmitRecord(8,Record); and here? -Chris From sabre at nondot.org Wed Oct 24 00:09:49 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 05:09:49 -0000 Subject: [llvm-commits] [llvm] r43288 - /llvm/trunk/docs/tutorial/LangImpl3.html Message-ID: <200710240509.l9O59nLO030593@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 00:09:48 2007 New Revision: 43288 URL: http://llvm.org/viewvc/llvm-project?rev=43288&view=rev Log: further simplify run options, thanks to gordonh for pointing this out Modified: llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43288&r1=43287&r2=43288&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Wed Oct 24 00:09:48 2007 @@ -610,8 +610,7 @@
        # Compile
    -   g++ -g toy.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    -                  `llvm-config --libs core` -o toy
    +   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
        # Run
        ./toy
     
    From sabre at nondot.org Wed Oct 24 00:38:08 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 05:38:08 -0000 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll Message-ID: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 00:38:08 2007 New Revision: 43289 URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev Log: Implement a couple of foldings for ordered and unordered comparisons, implementing cases related to PR1738. Added: llvm/trunk/test/Transforms/InstCombine/and2.ll llvm/trunk/test/Transforms/InstCombine/or2.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=43289&r1=43288&r2=43289&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Oct 24 00:38:08 2007 @@ -3628,6 +3628,24 @@ } } + // (fcmp ord x, c) & (fcmp ord y, c) -> (fcmp ord x, y) + if (FCmpInst *LHS = dyn_cast(I.getOperand(0))) { + if (FCmpInst *RHS = dyn_cast(I.getOperand(1))) { + if (LHS->getPredicate() == FCmpInst::FCMP_ORD && + RHS->getPredicate() == FCmpInst::FCMP_ORD) + if (ConstantFP *LHSC = dyn_cast(LHS->getOperand(1))) + if (ConstantFP *RHSC = dyn_cast(RHS->getOperand(1))) { + // If either of the constants are nans, then the whole thing returns + // false. + if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN || + RHSC->getValueAPF().getCategory() == APFloat::fcNaN) + return ReplaceInstUsesWith(I, ConstantInt::getFalse()); + return new FCmpInst(FCmpInst::FCMP_ORD, LHS->getOperand(0), + RHS->getOperand(0)); + } + } + } + return Changed ? &I : 0; } @@ -4074,7 +4092,7 @@ } // fold (or (cast A), (cast B)) -> (cast (or A, B)) - if (CastInst *Op0C = dyn_cast(Op0)) + if (CastInst *Op0C = dyn_cast(Op0)) { if (CastInst *Op1C = dyn_cast(Op1)) if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ? const Type *SrcTy = Op0C->getOperand(0)->getType(); @@ -4091,7 +4109,29 @@ return CastInst::create(Op0C->getOpcode(), NewOp, I.getType()); } } - + } + + + // (fcmp uno x, c) | (fcmp uno y, c) -> (fcmp uno x, y) + if (FCmpInst *LHS = dyn_cast(I.getOperand(0))) { + if (FCmpInst *RHS = dyn_cast(I.getOperand(1))) { + if (LHS->getPredicate() == FCmpInst::FCMP_UNO && + RHS->getPredicate() == FCmpInst::FCMP_UNO) + if (ConstantFP *LHSC = dyn_cast(LHS->getOperand(1))) + if (ConstantFP *RHSC = dyn_cast(RHS->getOperand(1))) { + // If either of the constants are nans, then the whole thing returns + // true. + if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN || + RHSC->getValueAPF().getCategory() == APFloat::fcNaN) + return ReplaceInstUsesWith(I, ConstantInt::getTrue()); + + // Otherwise, no need to compare the two constants, compare the + // rest. + return new FCmpInst(FCmpInst::FCMP_UNO, LHS->getOperand(0), + RHS->getOperand(0)); + } + } + } return Changed ? &I : 0; } @@ -4341,7 +4381,7 @@ return R; // fold (xor (cast A), (cast B)) -> (cast (xor A, B)) - if (CastInst *Op0C = dyn_cast(Op0)) + if (CastInst *Op0C = dyn_cast(Op0)) { if (CastInst *Op1C = dyn_cast(Op1)) if (Op0C->getOpcode() == Op1C->getOpcode()) { // same cast kind? const Type *SrcTy = Op0C->getOperand(0)->getType(); @@ -4358,7 +4398,7 @@ return CastInst::create(Op0C->getOpcode(), NewOp, I.getType()); } } - + } return Changed ? &I : 0; } Added: llvm/trunk/test/Transforms/InstCombine/and2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and2.ll?rev=43289&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/and2.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/and2.ll Wed Oct 24 00:38:08 2007 @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep and + + +; PR1738 +define i1 @test1(double %X, double %Y) { + %tmp9 = fcmp ord double %X, 0.000000e+00 + %tmp13 = fcmp ord double %Y, 0.000000e+00 + %bothcond = and i1 %tmp13, %tmp9 + ret i1 %bothcond +} + + Added: llvm/trunk/test/Transforms/InstCombine/or2.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/or2.ll?rev=43289&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/or2.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/or2.ll Wed Oct 24 00:38:08 2007 @@ -0,0 +1,12 @@ +; This test makes sure that these instructions are properly eliminated. +; +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep -v xor | not grep {or } + +; PR1738 +define i1 @test1(double %X, double %Y) { + %tmp9 = fcmp uno double %X, 0.000000e+00 ; [#uses=1] + %tmp13 = fcmp uno double %Y, 0.000000e+00 ; [#uses=1] + %bothcond = or i1 %tmp13, %tmp9 ; [#uses=1] + ret i1 %bothcond +} + From sabre at nondot.org Wed Oct 24 01:25:10 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 06:25:10 -0000 Subject: [llvm-commits] [llvm] r43290 - /llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Message-ID: <200710240625.l9O6PAGB001608@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 01:25:09 2007 New Revision: 43290 URL: http://llvm.org/viewvc/llvm-project?rev=43290&view=rev Log: switch some calls to SelectionDAG::getTargetNode to use the one that takes an operand list instead of explicit operands. There is one left though, the more interesting one :) Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Modified: llvm/trunk/utils/TableGen/DAGISelEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/DAGISelEmitter.cpp?rev=43290&r1=43289&r2=43290&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/DAGISelEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/DAGISelEmitter.cpp Wed Oct 24 01:25:09 2007 @@ -3718,8 +3718,9 @@ << " unsigned C = cast(N1)->getValue();\n" << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" << " AddToISelQueue(Chain);\n" + << " SDOperand Ops[] = { Tmp, Chain };\n" << " return CurDAG->getTargetNode(TargetInstrInfo::LABEL,\n" - << " MVT::Other, Tmp, Chain);\n" + << " MVT::Other, Ops, 2);\n" << "}\n\n"; OS << "SDNode *Select_EXTRACT_SUBREG(const SDOperand &N) {\n" @@ -3728,8 +3729,9 @@ << " unsigned C = cast(N1)->getValue();\n" << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" << " AddToISelQueue(N0);\n" + << " SDOperand Ops[] = { N0, Tmp };\n" << " return CurDAG->getTargetNode(TargetInstrInfo::EXTRACT_SUBREG,\n" - << " N.getValueType(), N0, Tmp);\n" + << " N.getValueType(), Ops, 2);\n" << "}\n\n"; OS << "SDNode *Select_INSERT_SUBREG(const SDOperand &N) {\n" @@ -3739,13 +3741,14 @@ << " unsigned C = cast(N2)->getValue();\n" << " SDOperand Tmp = CurDAG->getTargetConstant(C, MVT::i32);\n" << " AddToISelQueue(N1);\n" + << " SDOperand Ops[] = { N0, N1, Tmp };\n" << " if (N0.getOpcode() == ISD::UNDEF) {\n" << " return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n" - << " N.getValueType(), N1, Tmp);\n" + << " N.getValueType(), Ops+1, 2);\n" << " } else {\n" << " AddToISelQueue(N0);\n" << " return CurDAG->getTargetNode(TargetInstrInfo::INSERT_SUBREG,\n" - << " N.getValueType(), N0, N1, Tmp);\n" + << " N.getValueType(), Ops, 3);\n" << " }\n" << "}\n\n"; From evan.cheng at apple.com Wed Oct 24 01:29:21 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 23 Oct 2007 23:29:21 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> Message-ID: <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> On Oct 23, 2007, at 6:18 PM, Chris Lattner wrote: > > On Oct 23, 2007, at 6:00 PM, Evan Cheng wrote: > >> Now that I think about it some more. The bug Bill and I looked at >> appears to be just a PPC prologue / epilogue lowering bug. It doesn't >> seem to be rounding up the size of the stack correctly. >> >> Suppose the size of source frame object is 5, this can be lowered >> into >> a pair of 4 byte load / store and a pair of 1 byte load / store: >> >> fi#0 : size 5, align 4 >> >> v1 = load i32 [fi#0], 0 >> store v1 >> v2 = load i8 [fi#0], 4 >> store v2 >> >> If fi#0 offset 0 is accessed off sp, then all is well, If it's >> accessed off fp, then the 32-bit load is unaligned. The problem is >> probably as simple as rounding up the size of the stack to be >> multiple >> of 4 and adjust the fp index accordingly. > > The frame lowering stuff is right. The PPC backend is using the > redzone, so the stack pointer doesn't need to move. This is just > accessing 33 bytes below the stack pointer, which isn't aligned. > Again, in this specific case you could force the frame object to be > aligned or something, but that wouldn't help the case when some > random unaligned pointer is memcpy'd. It's not memcpy'ing unaligned pointer. The lowering code does check that. If my memory is right, in this case, the frame object itself is aligned on 4-byte boundary. The memcpy size is 33, that is lowered into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads from r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it must be r1 is mis-aligned. Bill, please post the assembly code. Thanks. Evan > > -Chris > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed Oct 24 02:03:52 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 24 Oct 2007 00:03:52 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> Message-ID: <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> On Oct 23, 2007, at 11:29 PM, Evan Cheng wrote: > On Oct 23, 2007, at 6:18 PM, Chris Lattner wrote: >> On Oct 23, 2007, at 6:00 PM, Evan Cheng wrote: >>> Now that I think about it some more. The bug Bill and I looked at >>> appears to be just a PPC prologue / epilogue lowering bug. It >>> doesn't >>> seem to be rounding up the size of the stack correctly. >>> >>> Suppose the size of source frame object is 5, this can be lowered >>> into >>> a pair of 4 byte load / store and a pair of 1 byte load / store: >>> >>> fi#0 : size 5, align 4 >>> >>> v1 = load i32 [fi#0], 0 >>> store v1 >>> v2 = load i8 [fi#0], 4 >>> store v2 >>> >>> If fi#0 offset 0 is accessed off sp, then all is well, If it's >>> accessed off fp, then the 32-bit load is unaligned. The problem is >>> probably as simple as rounding up the size of the stack to be >>> multiple >>> of 4 and adjust the fp index accordingly. >> >> The frame lowering stuff is right. The PPC backend is using the >> redzone, so the stack pointer doesn't need to move. This is just >> accessing 33 bytes below the stack pointer, which isn't aligned. >> Again, in this specific case you could force the frame object to be >> aligned or something, but that wouldn't help the case when some >> random unaligned pointer is memcpy'd. > > It's not memcpy'ing unaligned pointer. The lowering code does check > that. > > If my memory is right, in this case, the frame object itself is > aligned on 4-byte boundary. The memcpy size is 33, that is lowered > into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / > store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads from > r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it > must be r1 is mis-aligned. > > Bill, please post the assembly code. Thanks. > Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). (gdb) call MF.dump() # Machine code for Bork(): : size is 33 bytes, alignment is 1 byte, at location [SP-33] entry: 0x1203860, LLVM BB @0x1201480, ID#0: %r2 = LIS8 %r2 = LD , %r2 %r3 = LBZ 32, %r2 %r4 = LD 0, %r2 STB %r3, 32, %r3 = LD 2, %r2 %r5 = LD 4, %r2 %r2 = LD 6, %r2 STD %r4, 0, STD %r3, 2, STD %r5, 4, STD %r2, 6, BLR 20, %cr0 # End machine code for Bork(). The second time through (while processing the "STD %r4, 0, "), the "STB" is now "STB %r3, -1, %r1" and the Offset is -33. -bw From espindola at google.com Wed Oct 24 02:22:05 2007 From: espindola at google.com (Rafael Espindola) Date: Wed, 24 Oct 2007 08:22:05 +0100 Subject: [llvm-commits] [llvm] r43176 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h In-Reply-To: References: <200710191435.l9JEZIAM018674@zion.cs.uiuc.edu> <90524216-7D9B-4B62-9FFF-E5669A37DEF9@apple.com> <38a0d8450710230636q2ebde484t465366a0db6f1b7b@mail.gmail.com> Message-ID: <38a0d8450710240022n63a7162bq339cde5892fe888d@mail.gmail.com> > Hey Rafael, > > I just asked Bill to look into merging these memcpy lowering > implementations. Have you already started on this, or should Bill > look into it? > I have started, but I could use some help :-) The items I have in mind: 1) make the arm inline version work on thumb 2) add a Subtarget->getMinRepStrSizeThreshold to ARM (maybe with a more generic name) 3) make the high level memcpy lowering identical on ARM and X86 4) move it to a common place. 5) move the code that lowers to a call to a common place. 6) implement a generic inline version that works on every arch (just a bunch of load/store). I should have 2 implemented on Friday. If someone could implement 1 it would be great :-) Cheers, -- Rafael Avila de Espindola Google Ireland Ltd. Gordon House Barrow Street Dublin 4 Ireland Registered in Dublin, Ireland Registration Number: 368047 From neil at daikokuya.co.uk Wed Oct 24 09:42:05 2007 From: neil at daikokuya.co.uk (Neil Booth) Date: Wed, 24 Oct 2007 23:42:05 +0900 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll In-Reply-To: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> References: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> Message-ID: <20071024144205.GB20440@daikokuya.co.uk> Chris Lattner wrote:- > Author: lattner > Date: Wed Oct 24 00:38:08 2007 > New Revision: 43289 > > URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev > Log: > Implement a couple of foldings for ordered and unordered comparisons, > implementing cases related to PR1738. Is there a reason you're not using APFloat's comparison operation? Neil. From resistor at mac.com Wed Oct 24 11:04:09 2007 From: resistor at mac.com (Owen Anderson) Date: Wed, 24 Oct 2007 16:04:09 -0000 Subject: [llvm-commits] [llvm] r43291 - in /llvm/trunk/docs/tutorial: Tutorial1.tar.bz2 Tutorial1.zip Message-ID: <200710241604.l9OG49D5008833@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 24 11:04:08 2007 New Revision: 43291 URL: http://llvm.org/viewvc/llvm-project?rev=43291&view=rev Log: Update Makefile to use simpler llvm-config parameters. Modified: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 llvm/trunk/docs/tutorial/Tutorial1.zip Modified: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.tar.bz2?rev=43291&r1=43290&r2=43291&view=diff ============================================================================== Binary files - no diff available. Modified: llvm/trunk/docs/tutorial/Tutorial1.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.zip?rev=43291&r1=43290&r2=43291&view=diff ============================================================================== Binary files - no diff available. From clattner at apple.com Wed Oct 24 11:06:06 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 24 Oct 2007 09:06:06 -0700 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll In-Reply-To: <20071024144205.GB20440@daikokuya.co.uk> References: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> <20071024144205.GB20440@daikokuya.co.uk> Message-ID: On Oct 24, 2007, at 7:42 AM, Neil Booth wrote: > Chris Lattner wrote:- > >> Author: lattner >> Date: Wed Oct 24 00:38:08 2007 >> New Revision: 43289 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev >> Log: >> Implement a couple of foldings for ordered and unordered comparisons, >> implementing cases related to PR1738. > > Is there a reason you're not using APFloat's comparison operation? Which one? I just need to know if single apfloats are nan, I'm not comparing the constant values themselves. -Chris From resistor at mac.com Wed Oct 24 11:06:42 2007 From: resistor at mac.com (Owen Anderson) Date: Wed, 24 Oct 2007 16:06:42 -0000 Subject: [llvm-commits] [llvm] r43292 - in /llvm/trunk/docs/tutorial: Tutorial2.tar.bz2 Tutorial2.zip Message-ID: <200710241606.l9OG6gkB009037@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 24 11:06:42 2007 New Revision: 43292 URL: http://llvm.org/viewvc/llvm-project?rev=43292&view=rev Log: Update Makefile to use simpler llvm-config parameters. Modified: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 llvm/trunk/docs/tutorial/Tutorial2.zip Modified: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.tar.bz2?rev=43292&r1=43291&r2=43292&view=diff ============================================================================== Binary files - no diff available. Modified: llvm/trunk/docs/tutorial/Tutorial2.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.zip?rev=43292&r1=43291&r2=43292&view=diff ============================================================================== Binary files - no diff available. From dalej at apple.com Wed Oct 24 11:24:26 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 09:24:26 -0700 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll In-Reply-To: References: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> <20071024144205.GB20440@daikokuya.co.uk> Message-ID: <489FB4D5-D399-4EDC-A773-1D77525D069B@apple.com> On Oct 24, 2007, at 9:06 AM, Chris Lattner wrote: > > On Oct 24, 2007, at 7:42 AM, Neil Booth wrote: > >> Chris Lattner wrote:- >> >>> Author: lattner >>> Date: Wed Oct 24 00:38:08 2007 >>> New Revision: 43289 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev >>> Log: >>> Implement a couple of foldings for ordered and unordered >>> comparisons, >>> implementing cases related to PR1738. >> >> Is there a reason you're not using APFloat's comparison operation? > > Which one? I just need to know if single apfloats are nan, I'm not > comparing the constant values themselves. getCategory()==fcNaN I suppose we could add an isNan function, but this doesn't seem like a very common operation. From dalej at apple.com Wed Oct 24 11:25:46 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 09:25:46 -0700 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll In-Reply-To: <489FB4D5-D399-4EDC-A773-1D77525D069B@apple.com> References: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> <20071024144205.GB20440@daikokuya.co.uk> <489FB4D5-D399-4EDC-A773-1D77525D069B@apple.com> Message-ID: On Oct 24, 2007, at 9:24 AM, Dale Johannesen wrote: > > On Oct 24, 2007, at 9:06 AM, Chris Lattner wrote: > >> >> On Oct 24, 2007, at 7:42 AM, Neil Booth wrote: >> >>> Chris Lattner wrote:- >>> >>>> Author: lattner >>>> Date: Wed Oct 24 00:38:08 2007 >>>> New Revision: 43289 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev >>>> Log: >>>> Implement a couple of foldings for ordered and unordered >>>> comparisons, >>>> implementing cases related to PR1738. >>> >>> Is there a reason you're not using APFloat's comparison operation? >> >> Which one? I just need to know if single apfloats are nan, I'm not >> comparing the constant values themselves. > > getCategory()==fcNaN Ahem, now that I've gotten around to looking at your code, I see you did that. Never mind. That looks like the best way to me given the existing interface. > I suppose we could add an isNan function, but this doesn't seem > like a very common operation. From lattner at apple.com Wed Oct 24 11:28:47 2007 From: lattner at apple.com (Tanya Lattner) Date: Wed, 24 Oct 2007 09:28:47 -0700 Subject: [llvm-commits] [llvm] r43292 - in /llvm/trunk/docs/tutorial: Tutorial2.tar.bz2 Tutorial2.zip In-Reply-To: <200710241606.l9OG6gkB009037@zion.cs.uiuc.edu> References: <200710241606.l9OG6gkB009037@zion.cs.uiuc.edu> Message-ID: <52F57381-39AE-4A5F-8B75-92E1BC9E2ECD@apple.com> Why are we adding zip files to the repository? -Tanya On Oct 24, 2007, at 9:06 AM, Owen Anderson wrote: > Author: resistor > Date: Wed Oct 24 11:06:42 2007 > New Revision: 43292 > > URL: http://llvm.org/viewvc/llvm-project?rev=43292&view=rev > Log: > Update Makefile to use simpler llvm-config parameters. > > Modified: > llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 > llvm/trunk/docs/tutorial/Tutorial2.zip > > Modified: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/ > Tutorial2.tar.bz2?rev=43292&r1=43291&r2=43292&view=diff > > ====================================================================== > ======== > Binary files - no diff available. > > Modified: llvm/trunk/docs/tutorial/Tutorial2.zip > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/ > Tutorial2.zip?rev=43292&r1=43291&r2=43292&view=diff > > ====================================================================== > ======== > Binary files - no diff available. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Wed Oct 24 11:38:24 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 16:38:24 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43293 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200710241638.l9OGcOdO011409@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 11:38:24 2007 New Revision: 43293 URL: http://llvm.org/viewvc/llvm-project?rev=43293&view=rev Log: Honor signedness of constant when converting ptr+-constant to getelementptr. gcc.c-torture/execute/20010329-1.c 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=43293&r1=43292&r2=43293&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Wed Oct 24 11:38:24 2007 @@ -3351,8 +3351,8 @@ TREE_CODE(TREE_OPERAND(exp, 1)) == INTEGER_CST) { int64_t Offset = getINTEGER_CSTVal(TREE_OPERAND(exp, 1)); - // If POINTER_SIZE is 32-bits, sign extend the offset. - if (POINTER_SIZE == 32) + // If POINTER_SIZE is 32-bits and the offset is signed, sign extend the offset. + if (POINTER_SIZE == 32 && !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1)))) Offset = (Offset << 32) >> 32; // Figure out how large the element pointed to is. From dalej at apple.com Wed Oct 24 11:40:18 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 16:40:18 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43294 - /llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Message-ID: <200710241640.l9OGeIsD011521@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 11:40:18 2007 New Revision: 43294 URL: http://llvm.org/viewvc/llvm-project?rev=43294&view=rev Log: Mark the sret bit correctly for functions defined with empty parameter list (treated as "K&R" style internally, although it's equally valid and semantically identical in ANSI for definitions.) gcc.c-torture/execute/20020920-1.c 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=43294&r1=43293&r2=43294&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Wed Oct 24 11:40:18 2007 @@ -947,6 +947,12 @@ ABIConverter.HandleReturnType(ReturnType); + // If this is a struct-return function, the dest loc is passed in as a + // pointer. Mark that pointer as structret. + ParamAttrsVector Attrs; + if (ABIConverter.isStructReturn()) + Attrs.push_back(ParamAttrsWithIndex::get(ArgTys.size(), + ParamAttr::StructRet)); if (static_chain) // Pass the static chain as the first parameter. ABIConverter.HandleArgument(TREE_TYPE(static_chain)); @@ -954,7 +960,11 @@ for (; Args && TREE_TYPE(Args) != void_type_node; Args = TREE_CHAIN(Args)) ABIConverter.HandleArgument(TREE_TYPE(Args)); - return GetFunctionType(RetTy, ArgTys, false, 0); + ParamAttrsList *PAL = 0; + if (!Attrs.empty()) + PAL = ParamAttrsList::get(Attrs); + + return GetFunctionType(RetTy, ArgTys, false, PAL); } const FunctionType *TypeConverter::ConvertFunctionType(tree type, From kremenek at apple.com Wed Oct 24 11:40:12 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 24 Oct 2007 09:40:12 -0700 Subject: [llvm-commits] [llvm] r43261 - in /llvm/trunk: include/llvm/Bitcode/Serialization.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp In-Reply-To: References: <200710232129.l9NLTXWd009517@zion.cs.uiuc.edu> Message-ID: <743D05C1-7F23-42E5-A29C-1EC03DB8A96D@apple.com> On Oct 23, 2007, at 10:05 PM, Chris Lattner wrote: >> Would it make sense to split this function up into a Serializer.h and > Deserializer.h that only brings on one of these each respectively? > Then Serialization.h would have the stuff that is truly common. > This would also match the structure of your .cpp files. Make sense. >> +#include "llvm/ADT/SmallVector.h" >> +#include >> + >> +namespace llvm { >> + >> +template struct SerializeTrait; >> + >> +class Serializer { > > This needs a nice big doxygen comment above it explaining what it is. Documentation, who needs that? There aren't really any comments there, and you want doxygen comments! >> +template <> struct SerializeTrait >> + : public SerializeIntTrait {}; >> + >> +template <> struct SerializeTrait >> + : public SerializeIntTrait {}; >> + >> +template <> struct SerializeTrait >> + : public SerializeIntTrait {}; >> + >> +template <> struct SerializeTrait >> + : public SerializeIntTrait {}; > > This won't work: the sizes of these types aren't guaranteed to be > what you claim them to be. You could use: > >> +template <> struct SerializeTrait >> + : public SerializeIntTrait {}; > > though. Right. > More significantly, I don't think you need a size in bits at all. > Just allow the default vbr encoding to work for now, we can worry > about optimizing them later, no? These sizes are currently ignored. I was thinking of using them as clues for abbreviations, etc. I can simplify it until I know what the real optimization will be. >> = >> ===================================================================== >> ======== >> --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (added) >> +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Tue Oct 23 16:29:33 >> 2007 >> @@ -0,0 +1,52 @@ >> + >> +Serializer::Serializer(BitstreamWriter& stream, unsigned BlockID) >> + : Stream(stream), inBlock(BlockID >= 8) { >> + >> + if (inBlock) Stream.EnterSubblock(8,3); > > This is obviously very early, but what is the magic number 8 here? > > >> +void Serializer::EmitRecord() { >> + assert(Record.size() > 0 && "Cannot emit empty record."); >> + Stream.EmitRecord(8,Record); > > and here? No particular reason for 8, other than the custom codes start at 8 (which I know doesn't apply to block ids or records). I just picked 8 so that it wouldn't conflict with anything I knew of. Clearly this must be changed eventually. The bigger question is what will record IDs be used for? I can envision uses for the block IDs (just sections in the file), but what about the records? From dalej at apple.com Wed Oct 24 12:06:02 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 17:06:02 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43297 - /llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Message-ID: <200710241706.l9OH62bH013646@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 12:06:02 2007 New Revision: 43297 URL: http://llvm.org/viewvc/llvm-project?rev=43297&view=rev Log: Mark the sret bit correctly for functions defined with empty parameter list (treated as "K&R" style internally, although it's equally valid and semantically identical in ANSI for definitions.) gcc.c-torture/execute/20020920-1.c 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=43297&r1=43296&r2=43297&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-types.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-types.cpp Wed Oct 24 12:06:02 2007 @@ -971,6 +971,12 @@ ABIConverter.HandleReturnType(ReturnType); + // If this is a struct-return function, the dest loc is passed in as a + // pointer. Mark that pointer as structret. + ParamAttrsVector Attrs; + if (ABIConverter.isStructReturn()) + Attrs.push_back(ParamAttrsWithIndex::get(ArgTys.size(), + ParamAttr::StructRet)); if (static_chain) // Pass the static chain as the first parameter. ABIConverter.HandleArgument(TREE_TYPE(static_chain)); @@ -978,7 +984,11 @@ for (; Args && TREE_TYPE(Args) != void_type_node; Args = TREE_CHAIN(Args)) ABIConverter.HandleArgument(TREE_TYPE(Args)); - return GetFunctionType(RetTy, ArgTys, false, 0); + ParamAttrsList *PAL = 0; + if (!Attrs.empty()) + PAL = ParamAttrsList::get(Attrs); + + return GetFunctionType(RetTy, ArgTys, false, PAL); } const FunctionType *TypeConverter::ConvertFunctionType(tree type, From dalej at apple.com Wed Oct 24 12:06:19 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 17:06:19 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43298 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200710241706.l9OH6J4Q013666@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 12:06:19 2007 New Revision: 43298 URL: http://llvm.org/viewvc/llvm-project?rev=43298&view=rev Log: Honor signedness of constant when converting ptr+-constant to getelementptr. gcc.c-torture/execute/20010329-1.c 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=43298&r1=43297&r2=43298&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Oct 24 12:06:19 2007 @@ -2872,8 +2872,8 @@ TREE_CODE(TREE_OPERAND(exp, 1)) == INTEGER_CST) { int64_t Offset = getINTEGER_CSTVal(TREE_OPERAND(exp, 1)); - // If POINTER_SIZE is 32-bits, sign extend the offset. - if (POINTER_SIZE == 32) + // If POINTER_SIZE is 32-bits and the offset is signed, sign extend the offset. + if (POINTER_SIZE == 32 && !TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 1)))) Offset = (Offset << 32) >> 32; // Figure out how large the element pointed to is. From scottm at aero.org Wed Oct 24 13:15:44 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 24 Oct 2007 18:15:44 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43302 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200710241815.l9OIFiw3018157@zion.cs.uiuc.edu> Author: pingbak Date: Wed Oct 24 13:15:43 2007 New Revision: 43302 URL: http://llvm.org/viewvc/llvm-project?rev=43302&view=rev Log: "::entry" should be "::Entry". Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=43302&r1=43301&r2=43302&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Oct 24 13:15:43 2007 @@ -163,7 +163,7 @@ // Create the TargetMachine we will be generating code with. // FIXME: Figure out how to select the target and pass down subtarget info. std::string Err; - const TargetMachineRegistry::entry *TME = + const TargetMachineRegistry::Entry *TME = TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, Err); if (!TME) { cerr << "Did not get a target machine!\n"; From scottm at aero.org Wed Oct 24 13:42:58 2007 From: scottm at aero.org (Scott Michel) Date: Wed, 24 Oct 2007 18:42:58 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43303 - /llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Message-ID: <200710241842.l9OIgwck019676@zion.cs.uiuc.edu> Author: pingbak Date: Wed Oct 24 13:42:58 2007 New Revision: 43303 URL: http://llvm.org/viewvc/llvm-project?rev=43303&view=rev Log: Revert the change. Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Modified: llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp?rev=43303&r1=43302&r2=43303&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-backend.cpp Wed Oct 24 13:42:58 2007 @@ -163,7 +163,7 @@ // Create the TargetMachine we will be generating code with. // FIXME: Figure out how to select the target and pass down subtarget info. std::string Err; - const TargetMachineRegistry::Entry *TME = + const TargetMachineRegistry::entry *TME = TargetMachineRegistry::getClosestStaticTargetForModule(*TheModule, Err); if (!TME) { cerr << "Did not get a target machine!\n"; From sabre at nondot.org Wed Oct 24 13:54:28 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 18:54:28 -0000 Subject: [llvm-commits] [llvm] r43304 - /llvm/trunk/include/llvm/ADT/APFloat.h Message-ID: <200710241854.l9OIsSmC020383@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 13:54:28 2007 New Revision: 43304 URL: http://llvm.org/viewvc/llvm-project?rev=43304&view=rev Log: add a nice predicate to check to see if nan Modified: llvm/trunk/include/llvm/ADT/APFloat.h Modified: llvm/trunk/include/llvm/ADT/APFloat.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APFloat.h?rev=43304&r1=43303&r2=43304&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APFloat.h (original) +++ llvm/trunk/include/llvm/ADT/APFloat.h Wed Oct 24 13:54:28 2007 @@ -232,6 +232,7 @@ const fltSemantics &getSemantics() const { return *semantics; } bool isZero() const { return category == fcZero; } bool isNonZero() const { return category != fcZero; } + bool isNaN() const { return category == fcNaN; } bool isNegative() const { return sign; } bool isPosZero() const { return isZero() && !isNegative(); } bool isNegZero() const { return isZero() && isNegative(); } From sabre at nondot.org Wed Oct 24 13:54:45 2007 From: sabre at nondot.org (Chris Lattner) Date: Wed, 24 Oct 2007 18:54:45 -0000 Subject: [llvm-commits] [llvm] r43305 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Message-ID: <200710241854.l9OIskga020415@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 13:54:45 2007 New Revision: 43305 URL: http://llvm.org/viewvc/llvm-project?rev=43305&view=rev Log: simplify some code by using the new isNaN predicate 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=43305&r1=43304&r2=43305&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Wed Oct 24 13:54:45 2007 @@ -3637,8 +3637,7 @@ if (ConstantFP *RHSC = dyn_cast(RHS->getOperand(1))) { // If either of the constants are nans, then the whole thing returns // false. - if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN || - RHSC->getValueAPF().getCategory() == APFloat::fcNaN) + if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN()) return ReplaceInstUsesWith(I, ConstantInt::getFalse()); return new FCmpInst(FCmpInst::FCMP_ORD, LHS->getOperand(0), RHS->getOperand(0)); @@ -4121,8 +4120,7 @@ if (ConstantFP *RHSC = dyn_cast(RHS->getOperand(1))) { // If either of the constants are nans, then the whole thing returns // true. - if (LHSC->getValueAPF().getCategory() == APFloat::fcNaN || - RHSC->getValueAPF().getCategory() == APFloat::fcNaN) + if (LHSC->getValueAPF().isNaN() || RHSC->getValueAPF().isNaN()) return ReplaceInstUsesWith(I, ConstantInt::getTrue()); // Otherwise, no need to compare the two constants, compare the From clattner at apple.com Wed Oct 24 13:55:15 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 24 Oct 2007 11:55:15 -0700 Subject: [llvm-commits] [llvm] r43289 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/and2.ll test/Transforms/InstCombine/or2.ll In-Reply-To: <489FB4D5-D399-4EDC-A773-1D77525D069B@apple.com> References: <200710240538.l9O5c8QK032013@zion.cs.uiuc.edu> <20071024144205.GB20440@daikokuya.co.uk> <489FB4D5-D399-4EDC-A773-1D77525D069B@apple.com> Message-ID: <764F4B99-DAFF-4A2A-A685-9B01178BFD57@apple.com> On Oct 24, 2007, at 9:24 AM, Dale Johannesen wrote: > > On Oct 24, 2007, at 9:06 AM, Chris Lattner wrote: > >> >> On Oct 24, 2007, at 7:42 AM, Neil Booth wrote: >> >>> Chris Lattner wrote:- >>> >>>> Author: lattner >>>> Date: Wed Oct 24 00:38:08 2007 >>>> New Revision: 43289 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=43289&view=rev >>>> Log: >>>> Implement a couple of foldings for ordered and unordered >>>> comparisons, >>>> implementing cases related to PR1738. >>> >>> Is there a reason you're not using APFloat's comparison operation? >> >> Which one? I just need to know if single apfloats are nan, I'm not >> comparing the constant values themselves. > > getCategory()==fcNaN > I suppose we could add an isNan function, but this doesn't seem like > a very common operation. Yeah, having isNaN() would be much nicer, and it doesn't cost much. I added it and updated the code, thanks! -Chris From kremenek at apple.com Wed Oct 24 14:06:40 2007 From: kremenek at apple.com (Ted Kremenek) Date: Wed, 24 Oct 2007 19:06:40 -0000 Subject: [llvm-commits] [llvm] r43307 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h include/llvm/Bitcode/Serialization.h include/llvm/Bitcode/Serialize.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp Message-ID: <200710241906.l9OJ6eKh021334@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 24 14:06:40 2007 New Revision: 43307 URL: http://llvm.org/viewvc/llvm-project?rev=43307&view=rev Log: Split Serialization.h into separate headers: Serialize.h and Deserialize.h Serialization.h now includes trait speciailizations for unsigned long, etc. Added: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/include/llvm/Bitcode/Serialize.h Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Added: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43307&view=auto ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (added) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Wed Oct 24 14:06:40 2007 @@ -0,0 +1,74 @@ +//=- Deserialize.h - Generic Object Deserialization from Bitcode --*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for generic object deserialization from +// LLVM bitcode. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_SERIALIZE_INPUT +#define LLVM_BITCODE_SERIALIZE_INPUT + +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitcode/Serialization.h" +#include + +namespace llvm { + +class Deserializer { + BitstreamReader& Stream; + SmallVector Record; + unsigned RecIdx; +public: + Deserializer(BitstreamReader& stream); + ~Deserializer(); + + template + inline T& Read(T& X) { + SerializeTrait::Read(*this,X); + return X; + } + + template + inline T* Materialize() { + return SerializeTrait::Materialize(*this); + } + + uint64_t ReadInt(); + bool ReadBool() { return ReadInt() ? true : false; } + + // FIXME: Substitute a better implementation which calculates the minimum + // number of bits needed to serialize the enum. + template + EnumT ReadEnum(unsigned MinVal, unsigned MaxVal) { + return static_cast(ReadInt(32)); + } + + char* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); + void ReadCStr(std::vector& buff, bool isNullTerm=false); + +private: + void ReadRecord(); + + inline bool inRecord() { + if (Record.size() > 0) { + if (RecIdx >= Record.size()) { + RecIdx = 0; + Record.clear(); + return false; + } + else return true; + } + else return false; + } +}; + +} // end namespace llvm + +#endif Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43307&r1=43306&r2=43307&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Wed Oct 24 14:06:40 2007 @@ -1,4 +1,4 @@ - //=- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// +//==- Serialization.h - Generic Object Serialization to Bitcode ---*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -15,114 +15,26 @@ #ifndef LLVM_BITCODE_SERIALIZE #define LLVM_BITCODE_SERIALIZE -#include "llvm/Bitcode/BitstreamWriter.h" -#include "llvm/Bitcode/BitstreamReader.h" -#include "llvm/ADT/SmallVector.h" -#include - namespace llvm { +class Serializer; +class Deserializer; template struct SerializeTrait; -class Serializer { - BitstreamWriter& Stream; - SmallVector Record; - bool inBlock; -public: - Serializer(BitstreamWriter& stream, unsigned BlockID = 0); - ~Serializer(); - - template - inline void Emit(const T& X) { SerializeTrait::Serialize(*this,X); } - - void EmitInt(unsigned X, unsigned bits); - - // FIXME: Substitute a better implementation which calculates the minimum - // number of bits needed to serialize the enum. - void EmitEnum(unsigned X, unsigned MinVal, unsigned MaxVal) { EmitInt(X,32); } - - void EmitCString(const char* cstr); - - void Flush() { if (inRecord()) EmitRecord(); } - -private: - void EmitRecord(); - inline bool inRecord() { return Record.size() > 0; } -}; - - -class Deserializer { - BitstreamReader& Stream; - SmallVector Record; - unsigned RecIdx; -public: - Deserializer(BitstreamReader& stream); - ~Deserializer(); - - template - inline T& Read(T& X) { SerializeTrait::Deserialize(*this,X); return X; } - - template - inline T* Materialize() { - T* X = SerializeTrait::Instantiate(); - Read(*X); - return X; - } - - uint64_t ReadInt(unsigned bits = 32); - bool ReadBool() { return ReadInt(1) ? true : false; } - - // FIXME: Substitute a better implementation which calculates the minimum - // number of bits needed to serialize the enum. - template - EnumT ReadEnum(unsigned MinVal, unsigned MaxVal) { - return static_cast(ReadInt(32)); - } - - char* ReadCString(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); - void ReadCString(std::vector& buff, bool isNullTerm=false); - -private: - void ReadRecord(); - - inline bool inRecord() { - if (Record.size() > 0) { - if (RecIdx >= Record.size()) { - RecIdx = 0; - Record.clear(); - return false; - } - else return true; - } - else return false; - } -}; - - -template -struct SerializeIntTrait { - static inline void Serialize(Serializer& S, uintty X) { - S.EmitInt(X,Bits); - } - - static inline void Deserialize(Deserializer& S, uintty& X) { - X = (uintty) S.ReadInt(Bits); - } -}; - -template <> struct SerializeTrait - : public SerializeIntTrait {}; +#define SERIALIZE_INT_TRAIT(TYPE)\ +template <> struct SerializeTrait {\ + static void Emit(Serializer& S, TYPE X);\ + static void Read(Deserializer& S, TYPE& X); }; + +SERIALIZE_INT_TRAIT(bool) +SERIALIZE_INT_TRAIT(unsigned char) +SERIALIZE_INT_TRAIT(unsigned short) +SERIALIZE_INT_TRAIT(unsigned int) +SERIALIZE_INT_TRAIT(unsigned long) +SERIALIZE_INT_TRAIT(unsigned long long) -template <> struct SerializeTrait - : public SerializeIntTrait {}; - -template <> struct SerializeTrait - : public SerializeIntTrait {}; - -template <> struct SerializeTrait - : public SerializeIntTrait {}; - - +#undef SERIALIZE_INT_TRAIT } // end namespace llvm + #endif Added: llvm/trunk/include/llvm/Bitcode/Serialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialize.h?rev=43307&view=auto ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialize.h (added) +++ llvm/trunk/include/llvm/Bitcode/Serialize.h Wed Oct 24 14:06:40 2007 @@ -0,0 +1,48 @@ +//==- Serialize.h - Generic Object Serialization to Bitcode -------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface for generic object serialization to +// LLVM bitcode. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_SERIALIZE_OUTPUT +#define LLVM_BITCODE_SERIALIZE_OUTPUT + +#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +class Serializer { + BitstreamWriter& Stream; + SmallVector Record; + bool inBlock; +public: + Serializer(BitstreamWriter& stream, unsigned BlockID = 0); + ~Serializer(); + + template + inline void Emit(const T& X) { SerializeTrait::Emit(*this,X); } + + void EmitInt(unsigned X); + void EmitBool(bool X) { EmitInt(X); } + void EmitCStr(const char* beg, const char* end); + void EmitCStr(const char* cstr); + + void Flush() { if (inRecord()) EmitRecord(); } + +private: + void EmitRecord(); + inline bool inRecord() { return Record.size() > 0; } +}; + +} // end namespace llvm +#endif Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43307&r1=43306&r2=43307&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Wed Oct 24 14:06:40 2007 @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/Deserialize.h" using namespace llvm; @@ -27,31 +27,29 @@ void Deserializer::ReadRecord() { // FIXME: Check if we haven't run off the edge of the stream. // FIXME: Handle abbreviations. - unsigned Code = Stream.ReadCode(); + // FIXME: Check for the correct code. - assert (Record.size() == 0); - - Stream.ReadRecord(Code,Record); - + unsigned Code = Stream.ReadCode(); + + assert (Record.size() == 0); + Stream.ReadRecord(Code,Record); assert (Record.size() > 0); } -uint64_t Deserializer::ReadInt(unsigned Bits) { +uint64_t Deserializer::ReadInt() { // FIXME: Any error recovery/handling with incomplete or bad files? if (!inRecord()) ReadRecord(); - // FIXME: check for loss of precision in read (compare to Bits) return Record[RecIdx++]; } -char* Deserializer::ReadCString(char* cstr, unsigned MaxLen, bool isNullTerm) { +char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) { if (cstr == NULL) MaxLen = 0; // Zero this just in case someone does something funny. - unsigned len = ReadInt(32); + unsigned len = ReadInt(); - // FIXME: perform dynamic checking of lengths? assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen); if (!cstr) @@ -60,7 +58,7 @@ assert (cstr != NULL); for (unsigned i = 0; i < len; ++i) - cstr[i] = ReadInt(8); + cstr[i] = (char) ReadInt(); if (isNullTerm) cstr[len+1] = '\0'; @@ -68,16 +66,27 @@ return cstr; } -void Deserializer::ReadCString(std::vector& buff, bool isNullTerm) { - buff.clear(); +void Deserializer::ReadCStr(std::vector& buff, bool isNullTerm) { + unsigned len = ReadInt(); - unsigned len = ReadInt(32); - + buff.clear(); buff.reserve(len); for (unsigned i = 0; i < len; ++i) - buff.push_back(ReadInt(8)); + buff.push_back((char) ReadInt()); if (isNullTerm) buff.push_back('\0'); } + + +#define INT_READ(TYPE)\ +void SerializeTrait::Read(Deserializer& D, TYPE& X) {\ + X = (TYPE) D.ReadInt(); } + +INT_READ(bool) +INT_READ(unsigned char) +INT_READ(unsigned short) +INT_READ(unsigned int) +INT_READ(unsigned long) +INT_READ(unsigned long long) Modified: llvm/trunk/lib/Bitcode/Writer/Serialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/Serialize.cpp?rev=43307&r1=43306&r2=43307&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Wed Oct 24 14:06:40 2007 @@ -11,7 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Bitcode/Serialization.h" +#include "llvm/Bitcode/Serialize.h" +#include "string.h" using namespace llvm; @@ -37,16 +38,31 @@ Record.clear(); } -void Serializer::EmitInt(unsigned X, unsigned bits) { +void Serializer::EmitInt(unsigned X) { Record.push_back(X); } -void Serializer::EmitCString(const char* cstr) { - unsigned l = strlen(cstr); - Record.push_back(l); +void Serializer::EmitCStr(const char* s, const char* end) { + Record.push_back(end - s); - for (unsigned i = 0; i < l; i++) - Record.push_back(cstr[i]); + while(s != end) { + Record.push_back(*s); + ++s; + } EmitRecord(); } + +void Serializer::EmitCStr(const char* s) { + EmitCStr(s,s+strlen(s)); +} + +#define INT_EMIT(TYPE)\ +void SerializeTrait::Emit(Serializer&S, TYPE X) { S.EmitInt(X); } + +INT_EMIT(bool) +INT_EMIT(unsigned char) +INT_EMIT(unsigned short) +INT_EMIT(unsigned int) +INT_EMIT(unsigned long) +INT_EMIT(unsigned long long) From dalej at apple.com Wed Oct 24 15:14:51 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 20:14:51 -0000 Subject: [llvm-commits] [llvm] r43309 - /llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp Message-ID: <200710242014.l9OKEpLl025820@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 15:14:50 2007 New Revision: 43309 URL: http://llvm.org/viewvc/llvm-project?rev=43309&view=rev Log: Fix off by 1 bug in printf->puts lowering. Modified: llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp Modified: llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp?rev=43309&r1=43308&r2=43309&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/SimplifyLibCalls.cpp Wed Oct 24 15:14:50 2007 @@ -1211,8 +1211,10 @@ new CallInst(SLC.get_puts(), GV, "", CI); if (CI->use_empty()) return ReplaceCallWith(CI, 0); + // The return value from printf includes the \n we just removed, so +1. return ReplaceCallWith(CI, - ConstantInt::get(CI->getType(), FormatStr.size())); + ConstantInt::get(CI->getType(), + FormatStr.size()+1)); } From dalej at apple.com Wed Oct 24 15:58:14 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 20:58:14 -0000 Subject: [llvm-commits] [llvm] r43312 - /llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Message-ID: <200710242058.l9OKwE4W028967@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 15:58:14 2007 New Revision: 43312 URL: http://llvm.org/viewvc/llvm-project?rev=43312&view=rev Log: This was failing on Darwin, which defaults to PIC; no lea was generated. I think this follows the intent. Modified: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Modified: llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll?rev=43312&r1=43311&r2=43312&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll (original) +++ llvm/trunk/test/CodeGen/X86/stride-nine-with-base-reg.ll Wed Oct 24 15:58:14 2007 @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep lea | count 1 +; RUN: llvm-as < %s | llc -march=x86 -relocation-model=static | grep lea | count 1 ; RUN: llvm-as < %s | llc -march=x86-64 | not grep lea ; For x86 there's an lea above the loop. In both cases, there shouldn't From evan.cheng at apple.com Wed Oct 24 17:11:31 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 Oct 2007 15:11:31 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> Message-ID: On Oct 24, 2007, at 12:03 AM, Bill Wendling wrote: > On Oct 23, 2007, at 11:29 PM, Evan Cheng wrote: >> On Oct 23, 2007, at 6:18 PM, Chris Lattner wrote: >>> On Oct 23, 2007, at 6:00 PM, Evan Cheng wrote: >>>> Now that I think about it some more. The bug Bill and I looked at >>>> appears to be just a PPC prologue / epilogue lowering bug. It >>>> doesn't >>>> seem to be rounding up the size of the stack correctly. >>>> >>>> Suppose the size of source frame object is 5, this can be lowered >>>> into >>>> a pair of 4 byte load / store and a pair of 1 byte load / store: >>>> >>>> fi#0 : size 5, align 4 >>>> >>>> v1 = load i32 [fi#0], 0 >>>> store v1 >>>> v2 = load i8 [fi#0], 4 >>>> store v2 >>>> >>>> If fi#0 offset 0 is accessed off sp, then all is well, If it's >>>> accessed off fp, then the 32-bit load is unaligned. The problem is >>>> probably as simple as rounding up the size of the stack to be >>>> multiple >>>> of 4 and adjust the fp index accordingly. >>> >>> The frame lowering stuff is right. The PPC backend is using the >>> redzone, so the stack pointer doesn't need to move. This is just >>> accessing 33 bytes below the stack pointer, which isn't aligned. >>> Again, in this specific case you could force the frame object to be >>> aligned or something, but that wouldn't help the case when some >>> random unaligned pointer is memcpy'd. >> >> It's not memcpy'ing unaligned pointer. The lowering code does check >> that. >> >> If my memory is right, in this case, the frame object itself is >> aligned on 4-byte boundary. The memcpy size is 33, that is lowered >> into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / >> store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads from >> r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it >> must be r1 is mis-aligned. >> >> Bill, please post the assembly code. Thanks. >> > Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). > > (gdb) call MF.dump() > # Machine code for Bork(): > : size is 33 bytes, alignment is 1 byte, at location [SP-33] Ok, then the problem is just this stack object is misaligned? I thought the source specified this alloca should be 4-byte aligned? Evan > > entry: 0x1203860, LLVM BB @0x1201480, ID#0: > %r2 = LIS8 > %r2 = LD , %r2 > %r3 = LBZ 32, %r2 > %r4 = LD 0, %r2 > STB %r3, 32, > %r3 = LD 2, %r2 > %r5 = LD 4, %r2 > %r2 = LD 6, %r2 > STD %r4, 0, > STD %r3, 2, > STD %r5, 4, > STD %r2, 6, > BLR 20, %cr0 > > # End machine code for Bork(). > > The second time through (while processing the "STD %r4, 0, > "), the "STB" is now "STB %r3, -1, %r1" and the Offset is > -33. > > -bw > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dalej at apple.com Wed Oct 24 17:26:08 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 22:26:08 -0000 Subject: [llvm-commits] [llvm] r43314 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Message-ID: <200710242226.l9OMQ8Iv001814@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 17:26:08 2007 New Revision: 43314 URL: http://llvm.org/viewvc/llvm-project?rev=43314&view=rev Log: Another expansion for i64 multiply, suitable for PPC. 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=43314&r1=43313&r2=43314&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Oct 24 17:26:08 2007 @@ -5930,6 +5930,15 @@ Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); break; } + if (HasMULHU) { + Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + break; + } } // If nothing else, we can make a libcall. From clattner at apple.com Wed Oct 24 19:04:01 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 24 Oct 2007 17:04:01 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r43294 - /llvm-gcc-4.0/trunk/gcc/llvm-types.cpp In-Reply-To: <200710241640.l9OGeIsD011521@zion.cs.uiuc.edu> References: <200710241640.l9OGeIsD011521@zion.cs.uiuc.edu> Message-ID: <62962642-8AE2-449C-84D3-15532F539E8C@apple.com> On Oct 24, 2007, at 9:40 AM, Dale Johannesen wrote: > Author: johannes > URL: http://llvm.org/viewvc/llvm-project?rev=43294&view=rev > Log: > Mark the sret bit correctly for functions defined > with empty parameter list (treated as "K&R" style > internally, although it's equally valid and > semantically identical in ANSI for definitions.) > gcc.c-torture/execute/20020920-1.c Nifty! Does this fix http://llvm.org/bugs/show_bug.cgi?id=1397 ? Can you please add a testcase to llvm/test/CFrontend that checks for this? Thanks Dale, -Chris > > 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=43294&r1=43293&r2=43294&view=diff > > ====================================================================== > ======== > --- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original) > +++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Wed Oct 24 11:40:18 2007 > @@ -947,6 +947,12 @@ > > ABIConverter.HandleReturnType(ReturnType); > > + // If this is a struct-return function, the dest loc is passed > in as a > + // pointer. Mark that pointer as structret. > + ParamAttrsVector Attrs; > + if (ABIConverter.isStructReturn()) > + Attrs.push_back(ParamAttrsWithIndex::get(ArgTys.size(), > + ParamAttr::StructRet)); > if (static_chain) > // Pass the static chain as the first parameter. > ABIConverter.HandleArgument(TREE_TYPE(static_chain)); > @@ -954,7 +960,11 @@ > for (; Args && TREE_TYPE(Args) != void_type_node; Args = > TREE_CHAIN(Args)) > ABIConverter.HandleArgument(TREE_TYPE(Args)); > > - return GetFunctionType(RetTy, ArgTys, false, 0); > + ParamAttrsList *PAL = 0; > + if (!Attrs.empty()) > + PAL = ParamAttrsList::get(Attrs); > + > + return GetFunctionType(RetTy, ArgTys, false, PAL); > } > > const FunctionType *TypeConverter::ConvertFunctionType(tree type, > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From kremenek at apple.com Wed Oct 24 19:10:21 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 25 Oct 2007 00:10:21 -0000 Subject: [llvm-commits] [llvm] r43319 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h include/llvm/Bitcode/Serialization.h include/llvm/Bitcode/Serialize.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp Message-ID: <200710250010.l9P0ALgL008200@zion.cs.uiuc.edu> Author: kremenek Date: Wed Oct 24 19:10:21 2007 New Revision: 43319 URL: http://llvm.org/viewvc/llvm-project?rev=43319&view=rev Log: Implemented prototype serialization of pointers, including support for backpatching. Added Deserialize::ReadVal. Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/include/llvm/Bitcode/Serialization.h llvm/trunk/include/llvm/Bitcode/Serialize.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43319&r1=43318&r2=43319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Wed Oct 24 19:10:21 2007 @@ -17,6 +17,9 @@ #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/Serialization.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" #include namespace llvm { @@ -25,10 +28,42 @@ BitstreamReader& Stream; SmallVector Record; unsigned RecIdx; + BumpPtrAllocator Allocator; + + struct PtrIdInfo { + static inline unsigned getEmptyKey() { return ~((unsigned) 0x0); } + static inline unsigned getTombstoneKey() { return getEmptyKey()-1; } + static inline unsigned getHashValue(unsigned X) { return X; } + static inline bool isEqual(unsigned X, unsigned Y) { return X == Y; } + static inline bool isPod() { return true; } + }; + + struct BPatchNode { + BPatchNode* const Next; + void*& PtrRef; + BPatchNode(BPatchNode* n, void*& pref) : Next(n), PtrRef(pref) {} + }; + + struct BPatchEntry { + BPatchNode* Head; + void* Ptr; + BPatchEntry() : Head(NULL), Ptr(NULL) {} + static inline bool isPod() { return true; } + }; + + typedef llvm::DenseMap MapTy; + + MapTy BPatchMap; + public: Deserializer(BitstreamReader& stream); ~Deserializer(); - + + uint64_t ReadInt(); + bool ReadBool() { + return ReadInt() ? true : false; + } + template inline T& Read(T& X) { SerializeTrait::Read(*this,X); @@ -36,39 +71,36 @@ } template + inline T ReadVal() { + return SerializeTrait::ReadVal(*this); + } + + template inline T* Materialize() { return SerializeTrait::Materialize(*this); } - - uint64_t ReadInt(); - bool ReadBool() { return ReadInt() ? true : false; } - - // FIXME: Substitute a better implementation which calculates the minimum - // number of bits needed to serialize the enum. - template - EnumT ReadEnum(unsigned MinVal, unsigned MaxVal) { - return static_cast(ReadInt(32)); - } char* ReadCStr(char* cstr = NULL, unsigned MaxLen=0, bool isNullTerm=true); void ReadCStr(std::vector& buff, bool isNullTerm=false); + + template + inline T* ReadOwnedPtr() { + unsigned PtrId = ReadInt(); + T* x = SerializeTrait::Materialize(*this); + RegisterPtr(PtrId,x); + return x; + } + void ReadPtr(void*& PtrRef); + void RegisterPtr(unsigned PtrId, void* Ptr); + + + void BackpatchPointers(); private: - void ReadRecord(); - - inline bool inRecord() { - if (Record.size() > 0) { - if (RecIdx >= Record.size()) { - RecIdx = 0; - Record.clear(); - return false; - } - else return true; - } - else return false; - } + void ReadRecord(); + bool inRecord(); }; - + } // end namespace llvm #endif Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43319&r1=43318&r2=43319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Wed Oct 24 19:10:21 2007 @@ -24,14 +24,14 @@ #define SERIALIZE_INT_TRAIT(TYPE)\ template <> struct SerializeTrait {\ static void Emit(Serializer& S, TYPE X);\ - static void Read(Deserializer& S, TYPE& X); }; + static void Read(Deserializer& S, TYPE& X);\ + static TYPE ReadVal(Deserializer& S); }; SERIALIZE_INT_TRAIT(bool) SERIALIZE_INT_TRAIT(unsigned char) SERIALIZE_INT_TRAIT(unsigned short) SERIALIZE_INT_TRAIT(unsigned int) SERIALIZE_INT_TRAIT(unsigned long) -SERIALIZE_INT_TRAIT(unsigned long long) #undef SERIALIZE_INT_TRAIT Modified: llvm/trunk/include/llvm/Bitcode/Serialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialize.h?rev=43319&r1=43318&r2=43319&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialize.h Wed Oct 24 19:10:21 2007 @@ -18,6 +18,7 @@ #include "llvm/Bitcode/Serialization.h" #include "llvm/Bitcode/BitstreamWriter.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/DenseMap.h" namespace llvm { @@ -25,6 +26,10 @@ BitstreamWriter& Stream; SmallVector Record; bool inBlock; + + typedef DenseMap MapTy; + MapTy PtrMap; + public: Serializer(BitstreamWriter& stream, unsigned BlockID = 0); ~Serializer(); @@ -35,13 +40,22 @@ void EmitInt(unsigned X); void EmitBool(bool X) { EmitInt(X); } void EmitCStr(const char* beg, const char* end); - void EmitCStr(const char* cstr); + void EmitCStr(const char* cstr); + + void EmitPtr(void* ptr) { EmitInt(getPtrId(ptr)); } + + template + void EmitOwnedPtr(T* ptr) { + EmitPtr(ptr); + SerializeTrait::Emit(*this,*ptr); + } void Flush() { if (inRecord()) EmitRecord(); } private: void EmitRecord(); - inline bool inRecord() { return Record.size() > 0; } + inline bool inRecord() { return Record.size() > 0; } + unsigned getPtrId(void* ptr); }; } // end namespace llvm Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43319&r1=43318&r2=43319&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Wed Oct 24 19:10:21 2007 @@ -22,6 +22,21 @@ Deserializer::~Deserializer() { assert (RecIdx >= Record.size() && "Still scanning bitcode record when deserialization completed."); + + BackpatchPointers(); +} + + +bool Deserializer::inRecord() { + if (Record.size() > 0) { + if (RecIdx >= Record.size()) { + RecIdx = 0; + Record.clear(); + return false; + } + else return true; + } + else return false; } void Deserializer::ReadRecord() { @@ -79,14 +94,49 @@ buff.push_back('\0'); } +void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) { + BPatchEntry& E = BPatchMap[PtrId]; + assert (E.Ptr == NULL && "Pointer already registered."); + E.Ptr = Ptr; +} + +void Deserializer::ReadPtr(void*& PtrRef) { + unsigned PtrId = ReadInt(); + + BPatchEntry& E = BPatchMap[PtrId]; + + if (E.Ptr == NULL) { + // Register backpatch. + void* P = Allocator.Allocate(); + E.Head = new (P) BPatchNode(E.Head,PtrRef); + } + else + PtrRef = E.Ptr; +} + +void Deserializer::BackpatchPointers() { + for (MapTy::iterator I=BPatchMap.begin(),E=BPatchMap.end(); I!=E; ++I) { + + BPatchEntry& E = I->second; + assert (E.Ptr && "No pointer found for backpatch."); + + for (BPatchNode* N = E.Head; N != NULL; N = N->Next) + N->PtrRef = E.Ptr; + + E.Head = NULL; + } + + Allocator.Reset(); +} #define INT_READ(TYPE)\ void SerializeTrait::Read(Deserializer& D, TYPE& X) {\ - X = (TYPE) D.ReadInt(); } + X = (TYPE) D.ReadInt(); }\ +TYPE SerializeTrait::ReadVal(Deserializer& D) {\ + return (TYPE) D.ReadInt(); } INT_READ(bool) INT_READ(unsigned char) INT_READ(unsigned short) INT_READ(unsigned int) INT_READ(unsigned long) -INT_READ(unsigned long long) Modified: llvm/trunk/lib/Bitcode/Writer/Serialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/Serialize.cpp?rev=43319&r1=43318&r2=43319&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Wed Oct 24 19:10:21 2007 @@ -57,6 +57,17 @@ EmitCStr(s,s+strlen(s)); } +unsigned Serializer::getPtrId(void* ptr) { + MapTy::iterator I = PtrMap.find(ptr); + + if (I == PtrMap.end()) { + unsigned id = PtrMap.size(); + PtrMap[ptr] = id; + return id; + } + else return I->second; +} + #define INT_EMIT(TYPE)\ void SerializeTrait::Emit(Serializer&S, TYPE X) { S.EmitInt(X); } @@ -65,4 +76,3 @@ INT_EMIT(unsigned short) INT_EMIT(unsigned int) INT_EMIT(unsigned long) -INT_EMIT(unsigned long long) From clattner at apple.com Wed Oct 24 19:09:34 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 24 Oct 2007 17:09:34 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> Message-ID: >>> If my memory is right, in this case, the frame object itself is >>> aligned on 4-byte boundary. The memcpy size is 33, that is lowered >>> into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / >>> store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads from >>> r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it >>> must be r1 is mis-aligned. >>> >>> Bill, please post the assembly code. Thanks. >>> >> Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). >> >> (gdb) call MF.dump() >> # Machine code for Bork(): >> : size is 33 bytes, alignment is 1 byte, at location >> [SP-33] > > Ok, then the problem is just this stack object is misaligned? I > thought the source specified this alloca should be 4-byte aligned? I discussed this with Bill today. The problem is that we have: llvm.memcpy(p, q, 8, 1/*alignment) this gets turned into an 8-byte load and an 8-byte store, but the alignment (of 1) from the memcpy isn't put onto the load or store, so the legalizer thinks they are properly aligned. There is a separate issue of "maybe we should align this thing", but it is a performance, not correctness, issue. -Chris From clattner at apple.com Wed Oct 24 19:11:13 2007 From: clattner at apple.com (Chris Lattner) Date: Wed, 24 Oct 2007 17:11:13 -0700 Subject: [llvm-commits] [llvm] r43261 - in /llvm/trunk: include/llvm/Bitcode/Serialization.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp In-Reply-To: <743D05C1-7F23-42E5-A29C-1EC03DB8A96D@apple.com> References: <200710232129.l9NLTXWd009517@zion.cs.uiuc.edu> <743D05C1-7F23-42E5-A29C-1EC03DB8A96D@apple.com> Message-ID: <63924215-380E-4A76-993C-67891005C995@apple.com> On Oct 24, 2007, at 9:40 AM, Ted Kremenek wrote: > No particular reason for 8, other than the custom codes start at 8 > (which I know doesn't apply to block ids or records). I just > picked 8 so that it wouldn't conflict with anything I knew of. > Clearly this must be changed eventually. > > The bigger question is what will record IDs be used for? I can > envision uses for the block IDs (just sections in the file), but > what about the records? I think the serializer api should define a set of IDs that it wants to use, which will probably be completely independent from the application using the serializer. -Chris From isanbard at gmail.com Wed Oct 24 19:12:45 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 24 Oct 2007 17:12:45 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> Message-ID: <16e5fdf90710241712s20c738b0jb2a802efc2ab439c@mail.gmail.com> The alloca doesn't have an alignment requirement: @C.0.1173 = external constant [33 x i8] define void @Bork() { entry: %Qux = alloca [33 x i8] %Qux1 = bitcast [33 x i8]* %Qux to i8* call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) ret void } declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) I tried adding an alignment to the Store & Load SDNodes that were created. Passing in the "Align" variable (which is set to 8) doesn't work. If I pass in "1", it works (but isn't good). -bw On 10/24/07, Evan Cheng wrote: > > Ok, then the problem is just this stack object is misaligned? I > thought the source specified this alloca should be 4-byte aligned? > > Evan > > > > > entry: 0x1203860, LLVM BB @0x1201480, ID#0: > > %r2 = LIS8 > > %r2 = LD , %r2 > > %r3 = LBZ 32, %r2 > > %r4 = LD 0, %r2 > > STB %r3, 32, > > %r3 = LD 2, %r2 > > %r5 = LD 4, %r2 > > %r2 = LD 6, %r2 > > STD %r4, 0, > > STD %r3, 2, > > STD %r5, 4, > > STD %r2, 6, > > BLR 20, %cr0 > > > > # End machine code for Bork(). > > > > The second time through (while processing the "STD %r4, 0, > > "), the "STB" is now "STB %r3, -1, %r1" and the Offset is > > -33. > > > > -bw > > > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From evan.cheng at apple.com Wed Oct 24 19:13:55 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 24 Oct 2007 17:13:55 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> Message-ID: <245A3AC2-763A-4CBC-A915-4AB044BB39AB@apple.com> On Oct 24, 2007, at 5:09 PM, Chris Lattner wrote: >>>> If my memory is right, in this case, the frame object itself is >>>> aligned on 4-byte boundary. The memcpy size is 33, that is lowered >>>> into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / >>>> store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads >>>> from >>>> r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it >>>> must be r1 is mis-aligned. >>>> >>>> Bill, please post the assembly code. Thanks. >>>> >>> Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). >>> >>> (gdb) call MF.dump() >>> # Machine code for Bork(): >>> : size is 33 bytes, alignment is 1 byte, at location >>> [SP-33] >> >> Ok, then the problem is just this stack object is misaligned? I >> thought the source specified this alloca should be 4-byte aligned? > > I discussed this with Bill today. The problem is that we have: > > llvm.memcpy(p, q, 8, 1/*alignment) > > this gets turned into an 8-byte load and an 8-byte store, but the > alignment (of 1) from the memcpy isn't put onto the load or store, so > the legalizer thinks they are properly aligned. Ok, this makes sense. I'd thought the memcpy alignment was 4. Evan > > There is a separate issue of "maybe we should align this thing", but > it is a performance, not correctness, issue. > > -Chris > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at mac.com Wed Oct 24 19:16:57 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 00:16:57 -0000 Subject: [llvm-commits] [llvm] r43321 - in /llvm/trunk/include/llvm/Analysis: DominatorInternals.h Dominators.h Message-ID: <200710250016.l9P0Gvvv008599@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 24 19:16:57 2007 New Revision: 43321 URL: http://llvm.org/viewvc/llvm-project?rev=43321&view=rev Log: Make it possible for DomTreeBase to be constructed from MachineFunction's as well as just Function's. Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/DominatorInternals.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DominatorInternals.h?rev=43321&r1=43320&r2=43321&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DominatorInternals.h (original) +++ llvm/trunk/include/llvm/Analysis/DominatorInternals.h Wed Oct 24 19:16:57 2007 @@ -216,8 +216,11 @@ #endif } -template -void Calculate(DominatorTreeBase& DT, Function& F) { +template +void Calculate(DominatorTreeBase::NodeType>& DT, + FuncT& F) { + typedef GraphTraits GraphT; + // Step #1: Number blocks in depth-first order and initialize variables used // in later stages of the algorithm. unsigned N = 0; Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43321&r1=43320&r2=43321&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Wed Oct 24 19:16:57 2007 @@ -162,9 +162,9 @@ /// DominatorTree - Calculate the immediate dominator tree for a function. /// -template -void Calculate(DominatorTreeBase& DT, - Function& F); +template +void Calculate(DominatorTreeBase::NodeType>& DT, + FuncT& F); template class DominatorTreeBase : public DominatorBase { @@ -545,9 +545,9 @@ typename GraphT::NodeType* V, unsigned N); - template - friend void Calculate(DominatorTreeBase& DT, - Function& F); + template + friend void Calculate(DominatorTreeBase::NodeType>& DT, + FuncT& F); /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking /// dominator tree in dfs order. @@ -609,7 +609,8 @@ public: /// recalculate - compute a dominator tree for the given function - void recalculate(Function& F) { + template + void recalculate(FT& F) { if (!this->IsPostDominators) { reset(); @@ -619,7 +620,7 @@ this->DomTreeNodes[&F.getEntryBlock()] = 0; this->Vertex.push_back(0); - Calculate >(*this, F); + Calculate(*this, F); updateDFSNumbers(); } else { @@ -641,7 +642,7 @@ this->Vertex.push_back(0); - Calculate, GraphTraits > >(*this, F); + Calculate >(*this, F); } } }; From dalej at apple.com Wed Oct 24 19:18:31 2007 From: dalej at apple.com (Dale Johannesen) Date: Wed, 24 Oct 2007 17:18:31 -0700 Subject: [llvm-commits] [llvm-gcc-4.0] r43294 - /llvm-gcc-4.0/trunk/gcc/llvm-types.cpp In-Reply-To: <62962642-8AE2-449C-84D3-15532F539E8C@apple.com> References: <200710241640.l9OGeIsD011521@zion.cs.uiuc.edu> <62962642-8AE2-449C-84D3-15532F539E8C@apple.com> Message-ID: <18862558-81A2-429F-BF0E-232CBCDF49D7@apple.com> On Oct 24, 2007, at 5:04 PM, Chris Lattner wrote: > On Oct 24, 2007, at 9:40 AM, Dale Johannesen wrote: > >> Author: johannes >> URL: http://llvm.org/viewvc/llvm-project?rev=43294&view=rev >> Log: >> Mark the sret bit correctly for functions defined >> with empty parameter list (treated as "K&R" style >> internally, although it's equally valid and >> semantically identical in ANSI for definitions.) >> gcc.c-torture/execute/20020920-1.c > > Nifty! Does this fix http://llvm.org/bugs/show_bug.cgi?id=1397 ? Yes. At least the originally reported problem, the bug seems to have metastasized a bit. > Can you please add a testcase to llvm/test/CFrontend that checks for > this? OK. Although I think the pointer to the gcc testsuite should be sufficient, really. > Thanks Dale, > > -Chris > >> >> 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=43294&r1=43293&r2=43294&view=diff >> >> ===================================================================== >> = >> ======== >> --- llvm-gcc-4.0/trunk/gcc/llvm-types.cpp (original) >> +++ llvm-gcc-4.0/trunk/gcc/llvm-types.cpp Wed Oct 24 11:40:18 2007 >> @@ -947,6 +947,12 @@ >> >> ABIConverter.HandleReturnType(ReturnType); >> >> + // If this is a struct-return function, the dest loc is passed >> in as a >> + // pointer. Mark that pointer as structret. >> + ParamAttrsVector Attrs; >> + if (ABIConverter.isStructReturn()) >> + Attrs.push_back(ParamAttrsWithIndex::get(ArgTys.size(), >> + ParamAttr::StructRet)); >> if (static_chain) >> // Pass the static chain as the first parameter. >> ABIConverter.HandleArgument(TREE_TYPE(static_chain)); >> @@ -954,7 +960,11 @@ >> for (; Args && TREE_TYPE(Args) != void_type_node; Args = >> TREE_CHAIN(Args)) >> ABIConverter.HandleArgument(TREE_TYPE(Args)); >> >> - return GetFunctionType(RetTy, ArgTys, false, 0); >> + ParamAttrsList *PAL = 0; >> + if (!Attrs.empty()) >> + PAL = ParamAttrsList::get(Attrs); >> + >> + return GetFunctionType(RetTy, ArgTys, false, PAL); >> } >> >> const FunctionType *TypeConverter::ConvertFunctionType(tree type, >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Wed Oct 24 19:34:46 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 24 Oct 2007 17:34:46 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> Message-ID: <16e5fdf90710241734x749d4265n7cc9f3d8927a5a32@mail.gmail.com> On 10/24/07, Chris Lattner wrote: > >> Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). > >> > >> (gdb) call MF.dump() > >> # Machine code for Bork(): > >> : size is 33 bytes, alignment is 1 byte, at location > >> [SP-33] > > > > Ok, then the problem is just this stack object is misaligned? I > > thought the source specified this alloca should be 4-byte aligned? > > I discussed this with Bill today. The problem is that we have: > > llvm.memcpy(p, q, 8, 1/*alignment) > > this gets turned into an 8-byte load and an 8-byte store, but the > alignment (of 1) from the memcpy isn't put onto the load or store, so > the legalizer thinks they are properly aligned. > Hold on. Here's what we have in the bitcode: call void @llvm.memcpy.i64(p, q, 33, 8) So the alignment is 8 here. But from the function above, the frame's alignment is 1... -bw From isanbard at gmail.com Wed Oct 24 19:47:10 2007 From: isanbard at gmail.com (Bill Wendling) Date: Wed, 24 Oct 2007 17:47:10 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <245A3AC2-763A-4CBC-A915-4AB044BB39AB@apple.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> <245A3AC2-763A-4CBC-A915-4AB044BB39AB@apple.com> Message-ID: <16e5fdf90710241747s4425fdd1s786cc4e9b51d4f0f@mail.gmail.com> On 10/24/07, Evan Cheng wrote: > > On Oct 24, 2007, at 5:09 PM, Chris Lattner wrote: > > >>>> If my memory is right, in this case, the frame object itself is > >>>> aligned on 4-byte boundary. The memcpy size is 33, that is lowered > >>>> into 4 pairs of 8-byte load / store and 1 pair of 1 byte load / > >>>> store. It's issuing a 1-byte load from r1+32 and 4 8-byte loads > >>>> from > >>>> r1+8, r1+16, r1+24. It's faulting on one of the 8-byte load so it > >>>> must be r1 is mis-aligned. > >>>> > >>>> Bill, please post the assembly code. Thanks. > >>>> > >>> Here's what it's doing in PPCRegisterInfo::eliminateFrameIndex(). > >>> > >>> (gdb) call MF.dump() > >>> # Machine code for Bork(): > >>> : size is 33 bytes, alignment is 1 byte, at location > >>> [SP-33] > >> > >> Ok, then the problem is just this stack object is misaligned? I > >> thought the source specified this alloca should be 4-byte aligned? > > > > I discussed this with Bill today. The problem is that we have: > > > > llvm.memcpy(p, q, 8, 1/*alignment) > > > > this gets turned into an 8-byte load and an 8-byte store, but the > > alignment (of 1) from the memcpy isn't put onto the load or store, so > > the legalizer thinks they are properly aligned. > > Ok, this makes sense. I'd thought the memcpy alignment was 4. > Um...so...since the Align that I get is 8 from the memcpy, how do I get the alignment of the src/dst pointers? -bw From dalej at apple.com Wed Oct 24 19:50:15 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 25 Oct 2007 00:50:15 -0000 Subject: [llvm-commits] [llvm] r43323 - /llvm/trunk/test/CFrontend/sret2.c Message-ID: <200710250050.l9P0oFGj010869@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 19:50:14 2007 New Revision: 43323 URL: http://llvm.org/viewvc/llvm-project?rev=43323&view=rev Log: Testcase for PR 1397. Added: llvm/trunk/test/CFrontend/sret2.c Added: llvm/trunk/test/CFrontend/sret2.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/sret2.c?rev=43323&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/sret2.c (added) +++ llvm/trunk/test/CFrontend/sret2.c Wed Oct 24 19:50:14 2007 @@ -0,0 +1,9 @@ +// RUN: %llvmgcc %s -S -emit-llvm -O0 -o - | grep sret | count 2 + +struct abc { + int a; + int b; + int c; +}; + +struct abc foo2(){} From dalej at apple.com Wed Oct 24 19:52:04 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 25 Oct 2007 00:52:04 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43324 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200710250052.l9P0q4Vl011001@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 19:52:03 2007 New Revision: 43324 URL: http://llvm.org/viewvc/llvm-project?rev=43324&view=rev Log: Handle the case where the struct return output area and one of the input parameters overlap. This is not optimal. gcc.c-torture/execute/20010124-1.c 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=43324&r1=43323&r2=43324&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Wed Oct 24 19:52:03 2007 @@ -3020,7 +3020,7 @@ Emit(TREE_OPERAND(exp, 1), LV.Ptr); EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); - } else if (!isVolatile) { + } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) { Emit(TREE_OPERAND(exp, 1), LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we @@ -3029,6 +3029,10 @@ // it gets the volatile memory access right. It would be better if the // destloc pointer of 'Emit' had a flag that indicated it should be // volatile. + // We do this for stores into RESULT_DECL because it is possible for that + // memory area to overlap with the object being stored into it; see + // gcc.c-torture/execute/20010124-1.c. + Value *Tmp = CreateTemporary(ConvertType(TREE_TYPE(TREE_OPERAND(exp,1)))); Emit(TREE_OPERAND(exp, 1), Tmp); EmitAggregateCopy(LV.Ptr, Tmp, TREE_TYPE(TREE_OPERAND(exp,1)), From dalej at apple.com Wed Oct 24 20:16:43 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 25 Oct 2007 01:16:43 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43325 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200710250116.l9P1GhW7012500@zion.cs.uiuc.edu> Author: johannes Date: Wed Oct 24 20:16:42 2007 New Revision: 43325 URL: http://llvm.org/viewvc/llvm-project?rev=43325&view=rev Log: Handle the case where the struct return output area and one of the input parameters overlap. This is not optimal. gcc.c-torture/execute/20010124-1.c 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=43325&r1=43324&r2=43325&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Wed Oct 24 20:16:42 2007 @@ -2540,7 +2540,7 @@ Emit(TREE_OPERAND(exp, 1), LV.Ptr); EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); - } else if (!isVolatile) { + } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) { Emit(TREE_OPERAND(exp, 1), LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we @@ -2549,6 +2549,10 @@ // it gets the volatile memory access right. It would be better if the // destloc pointer of 'Emit' had a flag that indicated it should be // volatile. + // We do this for stores into RESULT_DECL because it is possible for that + // memory area to overlap with the object being stored into it; see + // gcc.c-torture/execute/20010124-1.c. + Value *Tmp = CreateTemporary(ConvertType(TREE_TYPE(TREE_OPERAND(exp,1)))); Emit(TREE_OPERAND(exp, 1), Tmp); EmitAggregateCopy(LV.Ptr, Tmp, TREE_TYPE(TREE_OPERAND(exp,1)), From resistor at mac.com Wed Oct 24 21:36:18 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 02:36:18 -0000 Subject: [llvm-commits] [llvm] r43326 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll Message-ID: <200710250236.l9P2aIOT016062@zion.cs.uiuc.edu> Author: resistor Date: Wed Oct 24 21:36:18 2007 New Revision: 43326 URL: http://llvm.org/viewvc/llvm-project?rev=43326&view=rev Log: Fix for PR1741. Added: llvm/trunk/test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.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=43326&r1=43325&r2=43326&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Oct 24 21:36:18 2007 @@ -339,8 +339,9 @@ // Otherwise, nothing is known... } else if (O1 != O2) { - // If they are two different objects, we know that we have no alias... - return NoAlias; + if (!isa(O1)) + // If they are two different objects, we know that we have no alias... + return NoAlias; } // If they are the same object, they we can look at the indexes. If they Added: llvm/trunk/test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll?rev=43326&view=auto ============================================================================== --- llvm/trunk/test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll (added) +++ llvm/trunk/test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll Wed Oct 24 21:36:18 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -basicaa -gvn -dce | llvm-dis | grep tmp7 + + %struct.A = type { i32 } + %struct.B = type { %struct.A } + at a = global %struct.B zeroinitializer ; <%struct.B*> [#uses=2] + +define i32 @_Z3fooP1A(%struct.A* %b) { +entry: + store i32 1, i32* getelementptr (%struct.B* @a, i32 0, i32 0, i32 0), align 8 + %tmp4 = getelementptr %struct.A* %b, i32 0, i32 0 ; [#uses=1] + store i32 0, i32* %tmp4, align 4 + %tmp7 = load i32* getelementptr (%struct.B* @a, i32 0, i32 0, i32 0), align 8 ; [#uses=1] + ret i32 %tmp7 +} From sabre at nondot.org Wed Oct 24 23:30:37 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 25 Oct 2007 04:30:37 -0000 Subject: [llvm-commits] [llvm] r43327 - /llvm/trunk/docs/tutorial/LangImpl3.html Message-ID: <200710250430.l9P4UbMR021505@zion.cs.uiuc.edu> Author: lattner Date: Wed Oct 24 23:30:35 2007 New Revision: 43327 URL: http://llvm.org/viewvc/llvm-project?rev=43327&view=rev Log: Run the verifier on generated code. Modified: llvm/trunk/docs/tutorial/LangImpl3.html Modified: llvm/trunk/docs/tutorial/LangImpl3.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl3.html?rev=43327&r1=43326&r2=43327&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl3.html (original) +++ llvm/trunk/docs/tutorial/LangImpl3.html Wed Oct 24 23:30:35 2007 @@ -400,10 +400,6 @@ Builder.SetInsertPoint(BB); if (Value *RetVal = Body->Codegen()) { - // Finish off the function. - Builder.CreateRet(RetVal); - return TheFunction; - }
    @@ -417,12 +413,29 @@ Since we don't have any control flow, our functions will only contain one block so far. We'll fix this in a future installment :).

    +
    +
    +  if (Value *RetVal = Body->Codegen()) {
    +    // Finish off the function.
    +    Builder.CreateRet(RetVal);
    +    
    +    // Validate the generated code, checking for consistency.
    +    verifyFunction(*TheFunction);
    +    return TheFunction;
    +  }
    +
    +
    +

    Once the insertion point is set up, we call the CodeGen() method for the root expression of the function. If no error happens, this emits code to compute the expression into the entry block and returns the value that was computed. Assuming no error, we then create an LLVM ret instruction. This completes the function, -which is then returned.

    +href="../LangRef.html#i_ret">ret instruction, which completes the function. +Once the function is built, we call the verifyFunction function, which +is provided by LLVM. This function does a variety of consistency checks on the +generated code, to determine if our compiler is doing everything right. Using +this is important: it can catch a lot of bugs. Once the function is finished +and validated, we return it.

    @@ -625,6 +638,7 @@
     
     #include "llvm/DerivedTypes.h"
     #include "llvm/Module.h"
    +#include "llvm/Analysis/Verifier.h"
     #include "llvm/Support/LLVMBuilder.h"
     #include <cstdio>
     #include <string>
    @@ -1071,6 +1085,9 @@
       if (Value *RetVal = Body->Codegen()) {
         // Finish off the function.
         Builder.CreateRet(RetVal);
    +    
    +    // Validate the generated code, checking for consistency.
    +    verifyFunction(*TheFunction);
         return TheFunction;
       }
       
    
    
    
    
    From sabre at nondot.org  Thu Oct 25 00:19:24 2007
    From: sabre at nondot.org (Chris Lattner)
    Date: Thu, 25 Oct 2007 05:19:24 -0000
    Subject: [llvm-commits] [llvm] r43328 -
    	/llvm/trunk/include/llvm/PassManager.h
    Message-ID: <200710250519.l9P5JPiU023626@zion.cs.uiuc.edu>
    
    Author: lattner
    Date: Thu Oct 25 00:19:24 2007
    New Revision: 43328
    
    URL: http://llvm.org/viewvc/llvm-project?rev=43328&view=rev
    Log:
    remove unimplemented ctor, add some comments.
    
    Modified:
        llvm/trunk/include/llvm/PassManager.h
    
    Modified: llvm/trunk/include/llvm/PassManager.h
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassManager.h?rev=43328&r1=43327&r2=43328&view=diff
    
    ==============================================================================
    --- llvm/trunk/include/llvm/PassManager.h (original)
    +++ llvm/trunk/include/llvm/PassManager.h Thu Oct 25 00:19:24 2007
    @@ -31,7 +31,6 @@
     
     /// PassManager manages ModulePassManagers
     class PassManager {
    -
     public:
     
       PassManager();
    @@ -52,14 +51,14 @@
       /// PassManagerImpl_New is the actual class. PassManager is just the 
       /// wraper to publish simple pass manager interface
       PassManagerImpl *PM;
    -
     };
     
     /// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
     class FunctionPassManager {
     public:
    +  /// FunctionPassManager ctor - This initializes the pass manager.  It needs,
    +  /// but does not take ownership of, the specified module provider.
       explicit FunctionPassManager(ModuleProvider *P);
    -  FunctionPassManager();
       ~FunctionPassManager();
      
       /// add - Add a pass to the queue of passes to run.  This passes
    @@ -82,8 +81,8 @@
       /// doFinalization - Run all of the finalizers for the function passes.
       ///
       bool doFinalization();
    +
     private:
    -  
       FunctionPassManagerImpl *FPM;
       ModuleProvider *MP;
     };
    
    
    
    
    From sabre at nondot.org  Thu Oct 25 01:23:37 2007
    From: sabre at nondot.org (Chris Lattner)
    Date: Thu, 25 Oct 2007 06:23:37 -0000
    Subject: [llvm-commits] [llvm] r43329 -
    	/llvm/trunk/docs/tutorial/LangImpl4.html
    Message-ID: <200710250623.l9P6Nblb026317@zion.cs.uiuc.edu>
    
    Author: lattner
    Date: Thu Oct 25 01:23:36 2007
    New Revision: 43329
    
    URL: http://llvm.org/viewvc/llvm-project?rev=43329&view=rev
    Log:
    Add chapter 4, feedback appreciated.
    
    Modified:
        llvm/trunk/docs/tutorial/LangImpl4.html
    
    Modified: llvm/trunk/docs/tutorial/LangImpl4.html
    URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=43329&r1=43328&r2=43329&view=diff
    
    ==============================================================================
    --- llvm/trunk/docs/tutorial/LangImpl4.html (original)
    +++ llvm/trunk/docs/tutorial/LangImpl4.html Thu Oct 25 01:23:36 2007
    @@ -24,22 +24,544 @@
     

    Welcome to part 4 of the "Implementing a language with -LLVM" tutorial.

    +LLVM" tutorial. Parts 1-3 described the implementation of a simple language +and included support for generating LLVM IR. This chapter describes two new +techniques: adding optimizer support to your language, and adding JIT compiler +support. This shows how to get nice efficient code for your language.

    - +

    -In order to generate LLVM IR, we want some simple setup to get started. First, -we define virtual codegen methods in each AST class:

    +Our demonstration for Chapter 3 is elegant and easy to extend. Unfortunately, +it does not produce wonderful code. For example, when compiling simple code, +we don't get obvious optimizations:

    +ready> def test(x) 1+2+x;
    +Read function definition:
    +define double @test(double %x) {
    +entry:
    +        %addtmp = add double 1.000000e+00, 2.000000e+00
    +        %addtmp1 = add double %addtmp, %x
    +        ret double %addtmp1
    +}
    +
    +
    + +

    This code is a very very literal transcription of the AST built by parsing +our code, and as such, lacks optimizations like constant folding (we'd like to +get "add x, 3.0" in the example above) as well as other more important +optimizations. Constant folding in particular is a very common and very +important optimization: so much so that many language implementors implement +constant folding support in their AST representation.

    + +

    With LLVM, you don't need to. Since all calls to build LLVM IR go through +the LLVM builder, it would be nice if the builder itself checked to see if there +was a constant folding opportunity when you call it. If so, it could just do +the constant fold and return the constant instead of creating an instruction. +This is exactly what the LLVMFoldingBuilder class does. Lets make one +change: + +

    +
    +static LLVMFoldingBuilder Builder;
    +
    +
    + +

    All we did was switch from LLVMBuilder to +LLVMFoldingBuilder. Though we change no other code, now all of our +instructions are implicitly constant folded without us having to do anything +about it. For example, our example above now compiles to:

    + +
    +
    +ready> def test(x) 1+2+x;
    +Read function definition:
    +define double @test(double %x) {
    +entry:
    +        %addtmp = add double 3.000000e+00, %x
    +        ret double %addtmp
    +}
    +
    +
    + +

    Well, that was easy. :) In practice, we recommend always using +LLVMConstantBuilder when generating code like this. It has no +"syntactic overhead" for its use (you don't have to uglify your compiler with +constant checks everywhere) and it can dramatically reduce the amount of +LLVM IR that is generated in some cases (particular for languages with a macro +preprocessor or that use a lot of constants).

    + +

    On the other hand, the LLVMFoldingBuilder is limited by the fact +that it does all of its analysis inline with the code as it is built. If you +take a slightly more complex example:

    + +
    +
    +ready> def test(x) (1+2+x)*(x+(1+2));
    +ready> Read function definition:
    +define double @test(double %x) {
    +entry:
    +        %addtmp = add double 3.000000e+00, %x
    +        %addtmp1 = add double %x, 3.000000e+00
    +        %multmp = mul double %addtmp, %addtmp1
    +        ret double %multmp
    +}
    +
    +
    + +

    In this case, the LHS and RHS of the multiplication are the same value. We'd +really like to see this generate "tmp = x+3; result = tmp*tmp;" instead +of computing "x*3" twice.

    + +

    Unfortunately, no amount of local analysis will be able to detect and correct +this. This requires two transformations: reassociation of expressions (to +make the add's lexically identical) and Common Subexpression Elimination (CSE) +to delete the redundant add instruction. Fortunately, LLVM provides a broad +range of optimizations that you can use, in the form of "passes".

    + +
    + + + + + +
    + +

    LLVM provides many optimization passes which do many different sorts of +things and have different tradeoffs. Unlike other systems, LLVM doesn't hold +to the mistaken notion that one set of optimizations is right for all languages +and for all situations. LLVM allows a compiler implementor to make complete +decisions about what optimizations to use, in which order, and in what +situation.

    + +

    As a concrete example, LLVM supports both "whole module" passes, which look +across as large of body of code as they can (often a whole file, but if run +at link time, this can be a substantial portion of the whole program). It also +supports and includes "per-function" passes which just operate on a single +function at a time, without looking at other functions. For more information +on passes and how the get run, see the How +to Write a Pass document.

    + +

    For Kaleidoscope, we are currently generating functions on the fly, one at +a time, as the user types them in. We aren't shooting for the ultimate +optimization experience in this setting, but we also want to catch the easy and +quick stuff where possible. As such, we will choose to run a few per-function +optimizations as the user types the function in. If we wanted to make a "static +Kaleidoscope compiler", we would use exactly the code we have now, except that +we would defer running the optimizer until the entire file has been parsed.

    + +

    In order to get per-function optimizations going, we need to set up a +FunctionPassManager to hold and +organize the LLVM optimizations that we want to run. Once we have that, we can +add a set of optimizations to run. The code looks like this:

    + +
    +
    +    ExistingModuleProvider OurModuleProvider(TheModule);
    +    FunctionPassManager OurFPM(&OurModuleProvider);
    +      
    +    // Set up the optimizer pipeline.  Start with registering info about how the
    +    // target lays out data structures.
    +    OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData()));
    +    // Do simple "peephole" optimizations and bit-twiddling optzns.
    +    OurFPM.add(createInstructionCombiningPass());
    +    // Reassociate expressions.
    +    OurFPM.add(createReassociatePass());
    +    // Eliminate Common SubExpressions.
    +    OurFPM.add(createGVNPass());
    +    // Simplify the control flow graph (deleting unreachable blocks, etc).
    +    OurFPM.add(createCFGSimplificationPass());
    +
    +    // Set the global so the code gen can use this.
    +    TheFPM = &OurFPM;
    +
    +    // Run the main "interpreter loop" now.
    +    MainLoop();
    +
    +
    + +

    This code defines two objects, a ExistingModuleProvider and a +FunctionPassManager. The former is basically a wrapper around our +Module that the PassManager requires. It provides certain flexibility +that we're not going to take advantage of here, so I won't dive into what it is +all about.

    + +

    The meat of the matter is the definition of the "OurFPM". It +requires a pointer to the Module (through the ModuleProvider) +to construct itself. Once it is set up, we use a series of "add" calls to add +a bunch of LLVM passes. The first pass is basically boilerplate, it adds a pass +so that later optimizations know how the data structures in the program are +layed out. The "TheExecutionEngine" variable is related to the JIT, +which we will get to in the next section.

    + +

    In this case, we choose to add 4 optimization passes. The passes we chose +here are a pretty standard set of "cleanup" optimizations that are useful for +a wide variety of code. I won't delve into what they do, but believe that they +are a good starting place.

    + +

    Once the passmanager, is set up, we need to make use of it. We do this by +running it after our newly created function is constructed (in +FunctionAST::Codegen), but before it is returned to the client:

    + +
    +
    +  if (Value *RetVal = Body->Codegen()) {
    +    // Finish off the function.
    +    Builder.CreateRet(RetVal);
    +
    +    // Validate the generated code, checking for consistency.
    +    verifyFunction(*TheFunction);
    +
    +    // Optimize the function.
    +    TheFPM->run(*TheFunction);
    +    
    +    return TheFunction;
    +  }
    +
    +
    + +

    As you can see, this is pretty straight-forward. The +FunctionPassManager optimizes and updates the LLVM Function* in place, +improving (hopefully) its body. With this in place, we can try our test above +again:

    + +
    +
    +ready> def test(x) (1+2+x)*(x+(1+2));
    +ready> Read function definition:
    +define double @test(double %x) {
    +entry:
    +        %addtmp = add double %x, 3.000000e+00
    +        %multmp = mul double %addtmp, %addtmp
    +        ret double %multmp
    +}
    +
    +
    + +

    As expected, we now get our nicely optimized code, saving a floating point +add from the program.

    + +

    LLVM provides a wide variety of optimizations that can be used in certain +circumstances. Unfortunately we don't have a good centralized description of +what every pass does, but you can check out the ones that llvm-gcc or +llvm-ld run to get started. The "opt" tool allows you to +experiment with passes from the command line, so you can see if they do +anything.

    + +

    Now that we have reasonable code coming out of our front-end, lets talk about +executing it!

    + +
    + + + + + +
    + +

    Once the code is available in LLVM IR form a wide variety of tools can be +applied to it. For example, you can run optimizations on it (as we did above), +you can dump it out in textual or binary forms, you can compile the code to an +assembly file (.s) for some target, or you can JIT compile it. The nice thing +about the LLVM IR representation is that it is the common currency between many +different parts of the compiler. +

    + +

    In this chapter, we'll add JIT compiler support to our interpreter. The +basic idea that we want for Kaleidoscope is to have the user enter function +bodies as they do now, but immediately evaluate the top-level expressions they +type in. For example, if they type in "1 + 2;", we should evaluate and print +out 3. If they define a function, they should be able to call it from the +command line.

    + +

    In order to do this, we first declare and initialize the JIT. This is done +by adding a global variable and a call in main:

    + +
    +
    +static ExecutionEngine *TheExecutionEngine;
    +...
    +int main() {
    +  ..
    +  // Create the JIT.
    +  TheExecutionEngine = ExecutionEngine::create(TheModule);
    +  ..
    +}
    +
    +
    + +

    This creates an abstract "Execution Engine" which can be either a JIT +compiler or the LLVM interpreter. LLVM will automatically pick a JIT compiler +for you if one is available for your platform, otherwise it will fall back to +the interpreter.

    + +

    Once the ExecutionEngine is created, the JIT is ready to be used. +There are a variety of APIs that are useful, but the most simple one is the +"getPointerToFunction(F)" method. This method JIT compiles the +specified LLVM Function and returns a function pointer to the generated machine +code. In our case, this means that we can change the code that parses a +top-level expression to look like this:

    + +
    +
    +static void HandleTopLevelExpression() {
    +  // Evaluate a top level expression into an anonymous function.
    +  if (FunctionAST *F = ParseTopLevelExpr()) {
    +    if (Function *LF = F->Codegen()) {
    +      LF->dump();  // Dump the function for exposition purposes.
    +    
    +      // JIT the function, returning a function pointer.
    +      void *FPtr = TheExecutionEngine->getPointerToFunction(LF);
    +      
    +      // Cast it to the right type (takes no arguments, returns a double) so we
    +      // can call it as a native function.
    +      double (*FP)() = (double (*)())FPtr;
    +      fprintf(stderr, "Evaluated to %f\n", FP());
    +    }
    +
    +
    + +

    Recall that we compile top-level expressions into a self-contained LLVM +function that takes no arguments and returns the computed double. Because the +LLVM JIT compiler matches the native platform ABI, this means that you can just +cast the result pointer to a function pointer of that type and call it directly. +As such, there is no difference between JIT compiled code and native machine +code that is statically linked into your application.

    + +

    With just these two changes, lets see how Kaleidoscope works now!

    + +
    +
    +ready> 4+5;
    +define double @""() {
    +entry:
    +        ret double 9.000000e+00
    +}
    +
    +Evaluated to 9.000000
    +
    +
    + +

    Well this looks like it is basically working. The dump of the function +shows the "no argument function that always returns double" that we synthesize +for each top level expression that is typed it. This demonstrates very basic +functionality, but can we do more?

    + +
    +
    +ready> def testfunc(x y) x + y*2;  
    +Read function definition:
    +define double @testfunc(double %x, double %y) {
    +entry:
    +        %multmp = mul double %y, 2.000000e+00
    +        %addtmp = add double %multmp, %x
    +        ret double %addtmp
    +}
    +
    +ready> testfunc(4, 10);
    +define double @""() {
    +entry:
    +        %calltmp = call double @testfunc( double 4.000000e+00, double 1.000000e+01 )
    +        ret double %calltmp
    +}
    +
    +Evaluated to 24.000000
    +
    +
    + +

    This illustrates that we can now call user code, but it is a bit subtle what +is going on here. Note that we only invoke the JIT on the anonymous functions +that calls testfunc, but we never invoked it on testfunc +itself.

    + +

    What actually happened here is that the anonymous function is +JIT'd when requested. When the Kaleidoscope app calls through the function +pointer that is returned, the anonymous function starts executing. It ends up +making the call for the "testfunc" function, and ends up in a stub that invokes +the JIT, lazily, on testfunc. Once the JIT finishes lazily compiling testfunc, +it returns and the code reexecutes the call.

    + +

    In summary, the JIT will lazily JIT code on the fly as it is needed. The +JIT provides a number of other more advanced interfaces for things like freeing +allocated machine code, rejit'ing functions to update them, etc. However, even +with this simple code, we get some surprisingly powerful capabilities - check +this out (I removed the dump of the anonymous functions, you should get the idea +by now :) :

    + +
    +
    +ready> extern sin(x);
    +Read extern: 
    +declare double @sin(double)
    +
    +ready> extern cos(x);
    +Read extern: 
    +declare double @cos(double)
    +
    +ready> sin(1.0);
    +Evaluated to 0.841471
    +ready> def foo(x) sin(x)*sin(x) + cos(x)*cos(x);
    +Read function definition:
    +define double @foo(double %x) {
    +entry:
    +        %calltmp = call double @sin( double %x )
    +        %multmp = mul double %calltmp, %calltmp
    +        %calltmp2 = call double @cos( double %x )
    +        %multmp4 = mul double %calltmp2, %calltmp2
    +        %addtmp = add double %multmp, %multmp4
    +        ret double %addtmp
    +}
    +
    +ready> foo(4.0);
    +Evaluated to 1.000000
    +
    +
    + +

    Whoa, how does the JIT know about sin and cos? The answer is simple: in this +example, the JIT started execution of a function and got to a function call. It +realized that the function was not yet JIT compiled and invoked the standard set +of routines to resolve the function. In this case, there is no body defined +for the function, so the JIT ended up calling "dlsym("sin")" on itself. +Since "sin" is defined within the JIT's address space, it simply +patches up calls in the module to call the libm version of sin +directly.

    + +

    The LLVM JIT provides a number of interfaces (look in the +ExecutionEngine.h file) for controlling how unknown functions get +resolved. It allows you to establish explicit mappings between IR objects and +addresses (useful for LLVM global variables that you want to map to static +tables, for example), allows you to dynamically decide on the fly based on the +function name, and even allows you to have the JIT abort itself if any lazy +compilation is attempted.

    + +

    This completes the JIT and optimizer chapter of the Kaleidoscope tutorial. At +this point, we can compile a non-Turing-complete programming language, optimize +and JIT compile it in a user-driven way. Next up we'll look into extending the language with control flow constructs, +tackling some interesting LLVM IR issues along the way.

    + +
    + + + + + +
    + +

    +Here is the complete code listing for our running example, enhanced with the +LLVM JIT and optimizer. To build this example, use: +

    + +
    +
    +   # Compile
    +   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    +   # Run
    +   ./toy
    +
    +
    + +

    Here is the code:

    + +
    +
    +#include "llvm/DerivedTypes.h"
    +#include "llvm/ExecutionEngine/ExecutionEngine.h"
    +#include "llvm/Module.h"
    +#include "llvm/ModuleProvider.h"
    +#include "llvm/PassManager.h"
    +#include "llvm/Analysis/Verifier.h"
    +#include "llvm/Target/TargetData.h"
    +#include "llvm/Transforms/Scalar.h"
    +#include "llvm/Support/LLVMBuilder.h"
    +#include <cstdio>
    +#include <string>
    +#include <map>
    +#include <vector>
    +using namespace llvm;
    +
    +//===----------------------------------------------------------------------===//
    +// Lexer
    +//===----------------------------------------------------------------------===//
    +
    +// The lexer returns tokens [0-255] if it is an unknown character, otherwise one
    +// of these for known things.
    +enum Token {
    +  tok_eof = -1,
    +
    +  // commands
    +  tok_def = -2, tok_extern = -3,
    +
    +  // primary
    +  tok_identifier = -4, tok_number = -5,
    +};
    +
    +static std::string IdentifierStr;  // Filled in if tok_identifier
    +static double NumVal;              // Filled in if tok_number
    +
    +/// gettok - Return the next token from standard input.
    +static int gettok() {
    +  static int LastChar = ' ';
    +
    +  // Skip any whitespace.
    +  while (isspace(LastChar))
    +    LastChar = getchar();
    +
    +  if (isalpha(LastChar)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
    +    IdentifierStr = LastChar;
    +    while (isalnum((LastChar = getchar())))
    +      IdentifierStr += LastChar;
    +
    +    if (IdentifierStr == "def") return tok_def;
    +    if (IdentifierStr == "extern") return tok_extern;
    +    return tok_identifier;
    +  }
    +
    +  if (isdigit(LastChar) || LastChar == '.') {   // Number: [0-9.]+
    +    std::string NumStr;
    +    do {
    +      NumStr += LastChar;
    +      LastChar = getchar();
    +    } while (isdigit(LastChar) || LastChar == '.');
    +
    +    NumVal = strtod(NumStr.c_str(), 0);
    +    return tok_number;
    +  }
    +
    +  if (LastChar == '#') {
    +    // Comment until end of line.
    +    do LastChar = getchar();
    +    while (LastChar != EOF && LastChar != '\n' & LastChar != '\r');
    +    
    +    if (LastChar != EOF)
    +      return gettok();
    +  }
    +  
    +  // Check for end of file.  Don't eat the EOF.
    +  if (LastChar == EOF)
    +    return tok_eof;
    +
    +  // Otherwise, just return the character as its ascii value.
    +  int ThisChar = LastChar;
    +  LastChar = getchar();
    +  return ThisChar;
    +}
    +
    +//===----------------------------------------------------------------------===//
    +// Abstract Syntax Tree (aka Parse Tree)
    +//===----------------------------------------------------------------------===//
    +
     /// ExprAST - Base class for all expression nodes.
     class ExprAST {
     public:
    @@ -51,14 +573,508 @@
     class NumberExprAST : public ExprAST {
       double Val;
     public:
    -  explicit NumberExprAST(double val) : Val(val) {}
    +  NumberExprAST(double val) : Val(val) {}
       virtual Value *Codegen();
     };
    -...
    -
    -
    +/// VariableExprAST - Expression class for referencing a variable, like "a". +class VariableExprAST : public ExprAST { + std::string Name; +public: + VariableExprAST(const std::string &name) : Name(name) {} + virtual Value *Codegen(); +}; +/// BinaryExprAST - Expression class for a binary operator. +class BinaryExprAST : public ExprAST { + char Op; + ExprAST *LHS, *RHS; +public: + BinaryExprAST(char op, ExprAST *lhs, ExprAST *rhs) + : Op(op), LHS(lhs), RHS(rhs) {} + virtual Value *Codegen(); +}; + +/// CallExprAST - Expression class for function calls. +class CallExprAST : public ExprAST { + std::string Callee; + std::vector<ExprAST*> Args; +public: + CallExprAST(const std::string &callee, std::vector<ExprAST*> &args) + : Callee(callee), Args(args) {} + virtual Value *Codegen(); +}; + +/// PrototypeAST - This class represents the "prototype" for a function, +/// which captures its argument names as well as if it is an operator. +class PrototypeAST { + std::string Name; + std::vector<std::string> Args; +public: + PrototypeAST(const std::string &name, const std::vector<std::string> &args) + : Name(name), Args(args) {} + + Function *Codegen(); +}; + +/// FunctionAST - This class represents a function definition itself. +class FunctionAST { + PrototypeAST *Proto; + ExprAST *Body; +public: + FunctionAST(PrototypeAST *proto, ExprAST *body) + : Proto(proto), Body(body) {} + + Function *Codegen(); +}; + +//===----------------------------------------------------------------------===// +// Parser +//===----------------------------------------------------------------------===// + +/// CurTok/getNextToken - Provide a simple token buffer. CurTok is the current +/// token the parser it looking at. getNextToken reads another token from the +/// lexer and updates CurTok with its results. +static int CurTok; +static int getNextToken() { + return CurTok = gettok(); +} + +/// BinopPrecedence - This holds the precedence for each binary operator that is +/// defined. +static std::map<char, int> BinopPrecedence; + +/// GetTokPrecedence - Get the precedence of the pending binary operator token. +static int GetTokPrecedence() { + if (!isascii(CurTok)) + return -1; + + // Make sure it's a declared binop. + int TokPrec = BinopPrecedence[CurTok]; + if (TokPrec <= 0) return -1; + return TokPrec; +} + +/// Error* - These are little helper functions for error handling. +ExprAST *Error(const char *Str) { fprintf(stderr, "Error: %s\n", Str);return 0;} +PrototypeAST *ErrorP(const char *Str) { Error(Str); return 0; } +FunctionAST *ErrorF(const char *Str) { Error(Str); return 0; } + +static ExprAST *ParseExpression(); + +/// identifierexpr +/// ::= identifer +/// ::= identifer '(' expression* ')' +static ExprAST *ParseIdentifierExpr() { + std::string IdName = IdentifierStr; + + getNextToken(); // eat identifer. + + if (CurTok != '(') // Simple variable ref. + return new VariableExprAST(IdName); + + // Call. + getNextToken(); // eat ( + std::vector<ExprAST*> Args; + while (1) { + ExprAST *Arg = ParseExpression(); + if (!Arg) return 0; + Args.push_back(Arg); + + if (CurTok == ')') break; + + if (CurTok != ',') + return Error("Expected ')'"); + getNextToken(); + } + + // Eat the ')'. + getNextToken(); + + return new CallExprAST(IdName, Args); +} + +/// numberexpr ::= number +static ExprAST *ParseNumberExpr() { + ExprAST *Result = new NumberExprAST(NumVal); + getNextToken(); // consume the number + return Result; +} + +/// parenexpr ::= '(' expression ')' +static ExprAST *ParseParenExpr() { + getNextToken(); // eat (. + ExprAST *V = ParseExpression(); + if (!V) return 0; + + if (CurTok != ')') + return Error("expected ')'"); + getNextToken(); // eat ). + return V; +} + +/// primary +/// ::= identifierexpr +/// ::= numberexpr +/// ::= parenexpr +static ExprAST *ParsePrimary() { + switch (CurTok) { + default: return Error("unknown token when expecting an expression"); + case tok_identifier: return ParseIdentifierExpr(); + case tok_number: return ParseNumberExpr(); + case '(': return ParseParenExpr(); + } +} + +/// binoprhs +/// ::= ('+' primary)* +static ExprAST *ParseBinOpRHS(int ExprPrec, ExprAST *LHS) { + // If this is a binop, find its precedence. + while (1) { + int TokPrec = GetTokPrecedence(); + + // If this is a binop that binds at least as tightly as the current binop, + // consume it, otherwise we are done. + if (TokPrec < ExprPrec) + return LHS; + + // Okay, we know this is a binop. + int BinOp = CurTok; + getNextToken(); // eat binop + + // Parse the primary expression after the binary operator. + ExprAST *RHS = ParsePrimary(); + if (!RHS) return 0; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + int NextPrec = GetTokPrecedence(); + if (TokPrec < NextPrec) { + RHS = ParseBinOpRHS(TokPrec+1, RHS); + if (RHS == 0) return 0; + } + + // Merge LHS/RHS. + LHS = new BinaryExprAST(BinOp, LHS, RHS); + } +} + +/// expression +/// ::= primary binoprhs +/// +static ExprAST *ParseExpression() { + ExprAST *LHS = ParsePrimary(); + if (!LHS) return 0; + + return ParseBinOpRHS(0, LHS); +} + +/// prototype +/// ::= id '(' id* ')' +static PrototypeAST *ParsePrototype() { + if (CurTok != tok_identifier) + return ErrorP("Expected function name in prototype"); + + std::string FnName = IdentifierStr; + getNextToken(); + + if (CurTok != '(') + return ErrorP("Expected '(' in prototype"); + + std::vector<std::string> ArgNames; + while (getNextToken() == tok_identifier) + ArgNames.push_back(IdentifierStr); + if (CurTok != ')') + return ErrorP("Expected ')' in prototype"); + + // success. + getNextToken(); // eat ')'. + + return new PrototypeAST(FnName, ArgNames); +} + +/// definition ::= 'def' prototype expression +static FunctionAST *ParseDefinition() { + getNextToken(); // eat def. + PrototypeAST *Proto = ParsePrototype(); + if (Proto == 0) return 0; + + if (ExprAST *E = ParseExpression()) + return new FunctionAST(Proto, E); + return 0; +} + +/// toplevelexpr ::= expression +static FunctionAST *ParseTopLevelExpr() { + if (ExprAST *E = ParseExpression()) { + // Make an anonymous proto. + PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>()); + return new FunctionAST(Proto, E); + } + return 0; +} + +/// external ::= 'extern' prototype +static PrototypeAST *ParseExtern() { + getNextToken(); // eat extern. + return ParsePrototype(); +} + +//===----------------------------------------------------------------------===// +// Code Generation +//===----------------------------------------------------------------------===// + +static Module *TheModule; +static LLVMFoldingBuilder Builder; +static std::map<std::string, Value*> NamedValues; +static FunctionPassManager *TheFPM; + +Value *ErrorV(const char *Str) { Error(Str); return 0; } + +Value *NumberExprAST::Codegen() { + return ConstantFP::get(Type::DoubleTy, APFloat(Val)); +} + +Value *VariableExprAST::Codegen() { + // Look this variable up in the function. + Value *V = NamedValues[Name]; + return V ? V : ErrorV("Unknown variable name"); +} + +Value *BinaryExprAST::Codegen() { + Value *L = LHS->Codegen(); + Value *R = RHS->Codegen(); + if (L == 0 || R == 0) return 0; + + switch (Op) { + case '+': return Builder.CreateAdd(L, R, "addtmp"); + case '-': return Builder.CreateSub(L, R, "subtmp"); + case '*': return Builder.CreateMul(L, R, "multmp"); + case '<': + L = Builder.CreateFCmpULT(L, R, "multmp"); + // Convert bool 0/1 to double 0.0 or 1.0 + return Builder.CreateUIToFP(L, Type::DoubleTy, "booltmp"); + default: return ErrorV("invalid binary operator"); + } +} + +Value *CallExprAST::Codegen() { + // Look up the name in the global module table. + Function *CalleeF = TheModule->getFunction(Callee); + if (CalleeF == 0) + return ErrorV("Unknown function referenced"); + + // If argument mismatch error. + if (CalleeF->arg_size() != Args.size()) + return ErrorV("Incorrect # arguments passed"); + + std::vector<Value*> ArgsV; + for (unsigned i = 0, e = Args.size(); i != e; ++i) { + ArgsV.push_back(Args[i]->Codegen()); + if (ArgsV.back() == 0) return 0; + } + + return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); +} + +Function *PrototypeAST::Codegen() { + // Make the function type: double(double,double) etc. + std::vector<const Type*> Doubles(Args.size(), Type::DoubleTy); + FunctionType *FT = FunctionType::get(Type::DoubleTy, Doubles, false); + + Function *F = new Function(FT, Function::ExternalLinkage, Name, TheModule); + + // If F conflicted, there was already something named 'Name'. If it has a + // body, don't allow redefinition or reextern. + if (F->getName() != Name) { + // Delete the one we just made and get the existing one. + F->eraseFromParent(); + F = TheModule->getFunction(Name); + + // If F already has a body, reject this. + if (!F->empty()) { + ErrorF("redefinition of function"); + return 0; + } + + // If F took a different number of args, reject. + if (F->arg_size() != Args.size()) { + ErrorF("redefinition of function with different # args"); + return 0; + } + } + + // Set names for all arguments. + unsigned Idx = 0; + for (Function::arg_iterator AI = F->arg_begin(); Idx != Args.size(); + ++AI, ++Idx) { + AI->setName(Args[Idx]); + + // Add arguments to variable symbol table. + NamedValues[Args[Idx]] = AI; + } + + return F; +} + +Function *FunctionAST::Codegen() { + NamedValues.clear(); + + Function *TheFunction = Proto->Codegen(); + if (TheFunction == 0) + return 0; + + // Create a new basic block to start insertion into. + BasicBlock *BB = new BasicBlock("entry", TheFunction); + Builder.SetInsertPoint(BB); + + if (Value *RetVal = Body->Codegen()) { + // Finish off the function. + Builder.CreateRet(RetVal); + + // Validate the generated code, checking for consistency. + verifyFunction(*TheFunction); + + // Optimize the function. + TheFPM->run(*TheFunction); + + return TheFunction; + } + + // Error reading body, remove function. + TheFunction->eraseFromParent(); + return 0; +} + +//===----------------------------------------------------------------------===// +// Top-Level parsing and JIT Driver +//===----------------------------------------------------------------------===// + +static ExecutionEngine *TheExecutionEngine; + +static void HandleDefinition() { + if (FunctionAST *F = ParseDefinition()) { + if (Function *LF = F->Codegen()) { + fprintf(stderr, "Read function definition:"); + LF->dump(); + } + } else { + // Skip token for error recovery. + getNextToken(); + } +} + +static void HandleExtern() { + if (PrototypeAST *P = ParseExtern()) { + if (Function *F = P->Codegen()) { + fprintf(stderr, "Read extern: "); + F->dump(); + } + } else { + // Skip token for error recovery. + getNextToken(); + } +} + +static void HandleTopLevelExpression() { + // Evaluate a top level expression into an anonymous function. + if (FunctionAST *F = ParseTopLevelExpr()) { + if (Function *LF = F->Codegen()) { + // JIT the function, returning a function pointer. + void *FPtr = TheExecutionEngine->getPointerToFunction(LF); + + // Cast it to the right type (takes no arguments, returns a double) so we + // can call it as a native function. + double (*FP)() = (double (*)())FPtr; + fprintf(stderr, "Evaluated to %f\n", FP()); + } + } else { + // Skip token for error recovery. + getNextToken(); + } +} + +/// top ::= definition | external | expression | ';' +static void MainLoop() { + while (1) { + fprintf(stderr, "ready> "); + switch (CurTok) { + case tok_eof: return; + case ';': getNextToken(); break; // ignore top level semicolons. + case tok_def: HandleDefinition(); break; + case tok_extern: HandleExtern(); break; + default: HandleTopLevelExpression(); break; + } + } +} + + + +//===----------------------------------------------------------------------===// +// "Library" functions that can be "extern'd" from user code. +//===----------------------------------------------------------------------===// + +/// putchard - putchar that takes a double and returns 0. +extern "C" +double putchard(double X) { + putchar((char)X); + return 0; +} + +//===----------------------------------------------------------------------===// +// Main driver code. +//===----------------------------------------------------------------------===// + +int main() { + // Install standard binary operators. + // 1 is lowest precedence. + BinopPrecedence['<'] = 10; + BinopPrecedence['+'] = 20; + BinopPrecedence['-'] = 20; + BinopPrecedence['*'] = 40; // highest. + + // Prime the first token. + fprintf(stderr, "ready> "); + getNextToken(); + + // Make the module, which holds all the code. + TheModule = new Module("my cool jit"); + + // Create the JIT. + TheExecutionEngine = ExecutionEngine::create(TheModule); + + { + ExistingModuleProvider OurModuleProvider(TheModule); + FunctionPassManager OurFPM(&OurModuleProvider); + + // Set up the optimizer pipeline. Start with registering info about how the + // target lays out data structures. + OurFPM.add(new TargetData(*TheExecutionEngine->getTargetData())); + // Do simple "peephole" optimizations and bit-twiddling optzns. + OurFPM.add(createInstructionCombiningPass()); + // Reassociate expressions. + OurFPM.add(createReassociatePass()); + // Eliminate Common SubExpressions. + OurFPM.add(createGVNPass()); + // Simplify the control flow graph (deleting unreachable blocks, etc). + OurFPM.add(createCFGSimplificationPass()); + + // Set the global so the code gen can use this. + TheFPM = &OurFPM; + + // Run the main "interpreter loop" now. + MainLoop(); + + TheFPM = 0; + } // Free module provider and pass manager. + + + // Print out all of the generated code. + TheModule->dump(); + return 0; +} +
    +
    From resistor at mac.com Thu Oct 25 01:41:23 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 06:41:23 -0000 Subject: [llvm-commits] [llvm] r43330 - in /llvm/trunk/docs/tutorial: JITTutorial1.html JITTutorial2.html Tutorial1.tar.bz2 Tutorial1.zip Tutorial2.tar.bz2 Tutorial2.zip Message-ID: <200710250641.l9P6fNaX026956@zion.cs.uiuc.edu> Author: resistor Date: Thu Oct 25 01:41:23 2007 New Revision: 43330 URL: http://llvm.org/viewvc/llvm-project?rev=43330&view=rev Log: Don't bother providing code samples. Maintaining zip files in the repository is a pain. Removed: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 llvm/trunk/docs/tutorial/Tutorial1.zip llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 llvm/trunk/docs/tutorial/Tutorial2.zip Modified: llvm/trunk/docs/tutorial/JITTutorial1.html llvm/trunk/docs/tutorial/JITTutorial2.html Modified: llvm/trunk/docs/tutorial/JITTutorial1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial1.html?rev=43330&r1=43329&r2=43330&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial1.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial1.html Thu Oct 25 01:41:23 2007 @@ -20,14 +20,6 @@ -
    Code Samples
    - - -
    -All the code in this example can be downloaded at Tutorial1.tar.bz2 or Tutorial1.zip. -
    - -
    A First Function
    Modified: llvm/trunk/docs/tutorial/JITTutorial2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=43330&r1=43329&r2=43330&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Thu Oct 25 01:41:23 2007 @@ -20,14 +20,6 @@ -
    Code Samples
    - - -
    -All the code in this example can be downloaded at Tutorial2.tar.bz2 or Tutorial2.zip. -
    - -
    A First Function
    Removed: llvm/trunk/docs/tutorial/Tutorial1.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.tar.bz2?rev=43329&view=auto ============================================================================== Binary file - no diff available. Removed: llvm/trunk/docs/tutorial/Tutorial1.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial1.zip?rev=43329&view=auto ============================================================================== Binary file - no diff available. Removed: llvm/trunk/docs/tutorial/Tutorial2.tar.bz2 URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.tar.bz2?rev=43329&view=auto ============================================================================== Binary file - no diff available. Removed: llvm/trunk/docs/tutorial/Tutorial2.zip URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/Tutorial2.zip?rev=43329&view=auto ============================================================================== Binary file - no diff available. From resistor at mac.com Thu Oct 25 01:45:01 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 06:45:01 -0000 Subject: [llvm-commits] [llvm] r43331 - in /llvm/trunk/docs/tutorial: JITTutorial1.html JITTutorial2.html Message-ID: <200710250645.l9P6j1ud027135@zion.cs.uiuc.edu> Author: resistor Date: Thu Oct 25 01:45:01 2007 New Revision: 43331 URL: http://llvm.org/viewvc/llvm-project?rev=43331&view=rev Log: Add proper footers. Modified: llvm/trunk/docs/tutorial/JITTutorial1.html llvm/trunk/docs/tutorial/JITTutorial2.html Modified: llvm/trunk/docs/tutorial/JITTutorial1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial1.html?rev=43331&r1=43330&r2=43331&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial1.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial1.html Thu Oct 25 01:45:01 2007 @@ -159,5 +159,18 @@ + +
    +
    + Valid CSS! + Valid HTML 4.01! + + Owen Anderson
    + The LLVM Compiler Infrastructure
    + Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ +
    + \ No newline at end of file Modified: llvm/trunk/docs/tutorial/JITTutorial2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=43331&r1=43330&r2=43331&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Thu Oct 25 01:45:01 2007 @@ -174,5 +174,18 @@ + +
    +
    + Valid CSS! + Valid HTML 4.01! + + Owen Anderson
    + The LLVM Compiler Infrastructure
    + Last modified: $Date: 2007-10-17 11:05:13 -0700 (Wed, 17 Oct 2007) $ +
    + \ No newline at end of file From resistor at mac.com Thu Oct 25 01:49:31 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 06:49:31 -0000 Subject: [llvm-commits] [llvm] r43332 - in /llvm/trunk/docs/tutorial: JITTutorial1.html JITTutorial2.html Message-ID: <200710250649.l9P6nV1q027439@zion.cs.uiuc.edu> Author: resistor Date: Thu Oct 25 01:49:29 2007 New Revision: 43332 URL: http://llvm.org/viewvc/llvm-project?rev=43332&view=rev Log: More tutorial cleanups. Modified: llvm/trunk/docs/tutorial/JITTutorial1.html llvm/trunk/docs/tutorial/JITTutorial2.html Modified: llvm/trunk/docs/tutorial/JITTutorial1.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial1.html?rev=43332&r1=43331&r2=43332&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial1.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial1.html Thu Oct 25 01:49:29 2007 @@ -50,7 +50,18 @@

    If you're unsure what the above code says, skim through the LLVM Language Reference Manual and convince yourself that the above LLVM IR is actually equivalent to the original function. Once you???re satisfied with that, let???s move on to actually generating it programmatically!

    -

    ... STUFF ABOUT HEADERS ...

    +

    Of course, before we can start, we need to #include the appropriate LLVM header files:

    + +
    +
    +#include <llvm/Module.h>
    +#include <llvm/Function.h>
    +#include <llvm/PassManager.h>
    +#include <llvm/Analysis/Verifier.h>
    +#include <llvm/Assembly/PrintModulePass.h>
    +#include <llvm/Support/LLVMBuilder.h>
    +
    +

    Now, let???s get started on our real program. Here???s what our basic main() will look like:

    @@ -153,9 +164,16 @@

    The final step in creating our function is to create the instructions that make it up. Our mul_add function is composed of just three instructions: a multiply, an add, and a return. LLVMBuilder gives us a simple interface for constructing these instructions and appending them to the ???entry??? block. Each of the calls to LLVMBuilder returns a Value* that represents the value yielded by the instruction. You???ll also notice that, above, x, y, and z are also Value*???s, so it???s clear that instructions operate on Value*???s.

    -

    And that???s it! Now you can compile and run your code, and get a wonder textual print out of the LLVM IR we saw at the beginning.

    +

    And that???s it! Now you can compile and run your code, and get a wonderful textual print out of the LLVM IR we saw at the beginning. To compile, use the following commandline as a guide:

    + +
    +
    +# c++ -g tut2.cpp `llvm-config --cppflags --ldflags --libs core` -o tut2
    +# ./tut2
    +
    +
    -

    ... SECTION ABOUT USING llvm-config TO GET THE NECESSARY COMPILER FLAGS TO COMPILE YOUR CODE ...

    +

    The llvm-config utility is used to obtain the necessary GCC-compatible compiler flags for linking with LLVM. For this example, we only need the 'core' library. We'll use others once we start adding optimizers and the JIT engine.

    Modified: llvm/trunk/docs/tutorial/JITTutorial2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/JITTutorial2.html?rev=43332&r1=43331&r2=43332&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/JITTutorial2.html (original) +++ llvm/trunk/docs/tutorial/JITTutorial2.html Thu Oct 25 01:49:29 2007 @@ -166,8 +166,7 @@
    -# c++ -g tut2.cpp `llvm-config --cppflags` `llvm-config --ldflags` \
    -                  `llvm-config --libs core` -o tut2
    +# c++ -g tut2.cpp `llvm-config --cppflags --ldflags --libs core` -o tut2
     # ./tut2
     
    From resistor at mac.com Thu Oct 25 01:50:30 2007 From: resistor at mac.com (Owen Anderson) Date: Thu, 25 Oct 2007 06:50:30 -0000 Subject: [llvm-commits] [llvm] r43333 - /llvm/trunk/docs/tutorial/LangImpl4.html Message-ID: <200710250650.l9P6oU68027482@zion.cs.uiuc.edu> Author: resistor Date: Thu Oct 25 01:50:30 2007 New Revision: 43333 URL: http://llvm.org/viewvc/llvm-project?rev=43333&view=rev Log: Fix an obvious typo. Modified: llvm/trunk/docs/tutorial/LangImpl4.html Modified: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=43333&r1=43332&r2=43333&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (original) +++ llvm/trunk/docs/tutorial/LangImpl4.html Thu Oct 25 01:50:30 2007 @@ -94,7 +94,7 @@

    Well, that was easy. :) In practice, we recommend always using -LLVMConstantBuilder when generating code like this. It has no +LLVMFoldingBuilder when generating code like this. It has no "syntactic overhead" for its use (you don't have to uglify your compiler with constant checks everywhere) and it can dramatically reduce the amount of LLVM IR that is generated in some cases (particular for languages with a macro From gordonhenriksen at mac.com Thu Oct 25 03:46:16 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Thu, 25 Oct 2007 08:46:16 -0000 Subject: [llvm-commits] [llvm] r43334 - /llvm/trunk/docs/Passes.html Message-ID: <200710250846.l9P8kIug007057@zion.cs.uiuc.edu> Author: gordon Date: Thu Oct 25 03:46:12 2007 New Revision: 43334 URL: http://llvm.org/viewvc/llvm-project?rev=43334&view=rev Log: Bringing Passes.html structurally up-to-date, and enabling semi-automated maintenance. Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=43334&r1=43333&r2=43334&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Thu Oct 25 03:46:12 2007 @@ -7,6 +7,34 @@ + +

    LLVM's Analysis and Transform Passes
      @@ -26,11 +54,11 @@

      This document serves as a high level summary of the optimization features that LLVM provides. Optimizations are implemented as Passes that traverse some portion of a program to either collect information or transform the program. - THe table below divides the passes that LLVM provides into three categories. + The table below divides the passes that LLVM provides into three categories. Analysis passes compute information that other passes can use or for debugging or program visualization purposes. Transform passes can use (or invalidate) the analysis passes. Transform passes all mutate the program in some way. - Utility passes provides ome utility but don't otherwise fit categorization. + Utility passes provides some utility but don't otherwise fit categorization. For example passes to extract functions to bitcode or write a module to bitcode are neither analysis nor transform passes.

      The table below provides a quick summary of each pass and links to the more @@ -48,26 +76,23 @@ -callgraphPrint a call graph -callsccPrint SCCs of the Call Graph -cfgsccPrint SCCs of each function CFG +-codegenprepareOptimize for code generation -count-aaCount Alias Analysis Query Responses -debug-aaAA use debugger -domfrontierDominance Frontier Construction --domsetDominator Set Construction -domtreeDominator Tree Construction --etforestET Forest Construction -externalfnconstantsPrint external fn callsites passed constants -globalsmodref-aaSimple mod/ref analysis for globals --idomImmediate Dominators Construction +-gvnGlobal Value Numbering -instcountCounts the various types of Instructions -intervalsInterval Partition Construction -load-vnLoad Value Numbering -loopsNatural Loop Construction +-memdepMemory Dependence Analysis -no-aaNo Alias Analysis (always returns 'may' alias) -no-profileNo Profile Information -postdomfrontierPost-Dominance Frontier Construction --postdomsetPost-Dominator Set Construction -postdomtreePost-Dominator Tree Construction --postetforestPost-ET-Forest Construction --postidomImmediate Post-Dominators Construction -printPrint function to stderr -print-alias-setsAlias Set Printer -print-callgraphPrint Call Graph to 'dot' file @@ -85,7 +110,7 @@ -adceAggressive Dead Code Elimination -argpromotionPromote 'by reference' arguments to scalars -block-placementProfile Guided Basic Block Placement --break-crit-edgesBreak Critical Edges in CFG +-break-crit-edgesBreak critical edges in CFG -ceeCorrelated Expression Elimination -condpropConditional Propagation -constmergeMerge Duplicate Global Constants @@ -98,6 +123,7 @@ -gcseGlobal Common Subexpression Elimination -globaldceDead Global Elimination -globaloptGlobal Variable Optimizer +-gvnpreGlobal Value Numbering/Partial Redundancy Elimination -indmemremIndirect Malloc and Free Removal -indvarsCanonicalize Induction Variables -inlineFunction Integration/Inlining @@ -114,24 +140,26 @@ -licmLoop Invariant Code Motion -loop-extractExtract loops into new functions -loop-extract-singleExtract at most one loop into a new function +-loop-index-splitIndex Split Loops -loop-reduceLoop Strength Reduction --loop-unrollUnroll Loops --loop-unswitchUnswitch Loops --loopsimplifyCanonicalize Natural Loops --lower-packedLower Packed Operations +-loop-rotateRotate Loops +-loop-unrollUnroll loops +-loop-unswitchUnswitch loops +-loopsimplifyCanonicalize natural loops +-lower-packedlowers packed operations to operations on smaller packed datatypes -lowerallocsLower allocations from instructions to calls -lowergcLower GC intrinsics, for GCless code generators --lowerinvokeLower Invoke and Unwind --lowerselectLower Selects To Branches +-lowerinvokeLower invoke and unwind, for unwindless code generators +-lowerselectLower select instructions to branches -lowersetjmpLower Set Jump -lowerswitchLower SwitchInst's to branches -mem2regPromote Memory to Register --mergereturnUnify Function Exit Nodes +-mergereturnUnify function exit nodes -predsimplifyPredicate Simplifier -prune-ehRemove unused exception handling info -raiseallocsRaise allocations from calls to instructions --reassociateReassociate Expressions --reg2memDemote Values to Memory +-reassociateReassociate expressions +-reg2memDemote all values to stack slots -scalarreplScalar Replacement of Aggregates -sccpSparse Conditional Constant Propagation -simplify-libcallsSimplify well-known library calls @@ -139,12 +167,16 @@ -stripStrip all symbols from a module -tailcallelimTail Call Elimination -tailduplicateTail Duplication + + UTILITY PASSES OptionNameDirectory --deadarghaX0rDead Argument Hacking (BUGPOINT ONLY) --extract-blocksExtract Basic Blocks From Module (BUGPOINT ONLY) +-deadarghaX0rDead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE) +-extract-blocksExtract Basic Blocks From Module (for bugpoint use) -emitbitcodeBitcode Writer -verifyModule Verifier +-view-cfgView CFG of function +-view-cfg-onlyView CFG of function (with no function bodies) @@ -172,7 +204,7 @@

      - Basic Alias Analysis + Basic Alias Analysis (default AA impl)

      Yet to be written.

      @@ -180,7 +212,7 @@

      Yet to be written.

      @@ -188,7 +220,7 @@

      Yet to be written.

      @@ -196,7 +228,7 @@

      Yet to be written.

      @@ -212,7 +244,7 @@

      Yet to be written.

      @@ -220,7 +252,7 @@

      Yet to be written.

      @@ -228,7 +260,7 @@

      Yet to be written.

      @@ -236,7 +268,7 @@

      Yet to be written.

      @@ -244,7 +276,7 @@

      Yet to be written.

      @@ -260,22 +292,6 @@ -
      -

      Yet to be written.

      -
      - - - -
      -

      Yet to be written.

      -
      - - -
      @@ -292,7 +308,7 @@

      Yet to be written.

      @@ -332,7 +348,7 @@

      Yet to be written.

      @@ -340,7 +356,7 @@

      Yet to be written.

      @@ -348,7 +364,7 @@

      Yet to be written.

      @@ -356,7 +372,7 @@

      Yet to be written.

      @@ -372,22 +388,6 @@ -
      -

      Yet to be written.

      -
      - - - -
      -

      Yet to be written.

      -
      - - -
      @@ -515,7 +515,7 @@

      Yet to be written.

      @@ -564,7 +564,7 @@

      This file implements constant propagation and merging. It looks for @@ -644,6 +644,14 @@

      +
      +

      Yet to be written.

      +
      + + +
      @@ -772,6 +780,14 @@ +
      +

      Yet to be written.

      +
      + + +
      @@ -780,7 +796,7 @@

      Yet to be written.

      @@ -788,7 +804,7 @@

      Yet to be written.

      @@ -796,7 +812,7 @@

      Yet to be written.

      @@ -804,7 +820,15 @@ +
      +

      Yet to be written.

      +
      + + +

      Yet to be written.

      @@ -828,7 +852,7 @@

      Yet to be written.

      @@ -836,7 +860,7 @@

      Yet to be written.

      @@ -868,7 +892,7 @@

      Yet to be written.

      @@ -900,7 +924,7 @@

      Yet to be written.

      @@ -908,7 +932,7 @@

      Yet to be written.

      @@ -978,7 +1002,7 @@

      Yet to be written.

      @@ -986,7 +1010,7 @@

      Yet to be written.

      @@ -1008,6 +1032,22 @@

      Yet to be written.

      + + +
      +

      Yet to be written.

      +
      + + + +
      +

      Yet to be written.

      +
      +
      From gordonhenriksen at mac.com Thu Oct 25 03:58:58 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Thu, 25 Oct 2007 08:58:58 -0000 Subject: [llvm-commits] [llvm] r43335 - /llvm/trunk/docs/Passes.html Message-ID: <200710250859.l9P8x0Hk007631@zion.cs.uiuc.edu> Author: gordon Date: Thu Oct 25 03:58:56 2007 New Revision: 43335 URL: http://llvm.org/viewvc/llvm-project?rev=43335&view=rev Log: Passes.html now 'passes' validation. Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=43335&r1=43334&r2=43335&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Thu Oct 25 03:58:56 2007 @@ -4,6 +4,7 @@ LLVM's Analysis and Transform Passes + @@ -20,7 +21,7 @@ m:^-.*.*$: or next; $order{$1} = sprintf("%03d", 1 + int %order); } -open HELP, "../Release/bin/opt --help|" or die "open: opt --help: $!\n"; +open HELP, "../Release/bin/opt -help|" or die "open: opt -help: $!\n"; while () { m:^ -([^ ]+) +- (.*)$: or next; my $o = $order{$1}; @@ -66,8 +67,8 @@
      - - + + @@ -105,8 +106,8 @@ - - + + @@ -169,8 +170,8 @@ - - + + @@ -529,15 +530,16 @@

      Correlated Expression Elimination propagates information from conditional branches to blocks dominated by destinations of the branch. It propagates information from the condition check itself into the body of the branch, - allowing transformations like these for example: -

      -    if (i == 7)
      -      ... 4*i;  // constant propagation
      -
      -    M = i+1; N = j+1;
      -    if (i == j)
      -      X = M-N;  // = M-M == 0;
      -   

      + allowing transformations like these for example:

      + +
      +if (i == 7)
      +  ... 4*i;  // constant propagation
      +
      +M = i+1; N = j+1;
      +if (i == j)
      +  X = M-N;  // = M-M == 0;
      +

      This is called Correlated Expression Elimination because we eliminate or simplify expressions that are correlated with the direction of a branch. In @@ -569,10 +571,10 @@

      This file implements constant propagation and merging. It looks for instructions involving only constant operands and replaces them with a - constant value instead of an instruction. For example: -

      add i32 1, 2

      - becomes -
      i32 3

      + constant value instead of an instruction. For example:

      +
      add i32 1, 2
      +

      becomes

      +
      i32 3

      NOTE: this pass has a habit of making definitions be dead. It is a good idea to to run a DIE (Dead Instruction Elimination) pass sometime after running this pass.

      From evan.cheng at apple.com Thu Oct 25 04:11:18 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 Oct 2007 09:11:18 -0000 Subject: [llvm-commits] [llvm] r43336 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce3.ll test/CodeGen/X86/loop-strength-reduce4.ll Message-ID: <200710250911.l9P9BJYd008571@zion.cs.uiuc.edu> Author: evancheng Date: Thu Oct 25 04:11:16 2007 New Revision: 43336 URL: http://llvm.org/viewvc/llvm-project?rev=43336&view=rev Log: If a loop termination compare instruction is the only use of its stride, and the compaison is against a constant value, try eliminate the stride by moving the compare instruction to another stride and change its constant operand accordingly. e.g. loop: .. v1 = v1 + 3 v2 = v2 + 1 if (v2 < 10) goto loop => loop: .. v1 = v1 + 3 if (v1 < 30) goto loop Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll llvm/trunk/test/CodeGen/X86/loop-strength-reduce4.ll Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43336&r1=43335&r2=43336&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Oct 25 04:11:16 2007 @@ -39,9 +39,10 @@ #include using namespace llvm; -STATISTIC(NumReduced , "Number of GEPs strength reduced"); -STATISTIC(NumInserted, "Number of PHIs inserted"); -STATISTIC(NumVariable, "Number of PHIs with variable strides"); +STATISTIC(NumReduced , "Number of GEPs strength reduced"); +STATISTIC(NumInserted, "Number of PHIs inserted"); +STATISTIC(NumVariable, "Number of PHIs with variable strides"); +STATISTIC(NumEliminated , "Number of strides eliminated"); namespace { @@ -170,18 +171,17 @@ bool AddUsersIfInteresting(Instruction *I, Loop *L, std::set &Processed); SCEVHandle GetExpressionSCEV(Instruction *E, Loop *L); - + ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond, + IVStrideUse* &CondUse, + const SCEVHandle* &CondStride); void OptimizeIndvars(Loop *L); bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, const SCEVHandle *&CondStride); - unsigned CheckForIVReuse(bool, const SCEVHandle&, IVExpr&, const Type*, const std::vector& UsersToProcess); - bool ValidStride(bool, int64_t, const std::vector& UsersToProcess); - void StrengthReduceStridedIVUsers(const SCEVHandle &Stride, IVUsersOfOneStride &Uses, Loop *L, bool isOnlyStride); @@ -981,8 +981,6 @@ const SCEVHandle &Stride, IVExpr &IV, const Type *Ty, const std::vector& UsersToProcess) { - if (!TLI) return 0; - if (SCEVConstant *SC = dyn_cast(Stride)) { int64_t SInt = SC->getValue()->getSExtValue(); if (SInt == 1) return 0; @@ -1039,6 +1037,10 @@ IVUsersOfOneStride &Uses, Loop *L, bool isOnlyStride) { + // If all the users are moved to another stride, then there is nothing to do. + if (Uses.Users.size() == 0) + return; + // Transform our list of users and offsets to a bit more complex table. In // this new vector, each 'BasedUser' contains 'Base' the base of the // strided accessas well as the old information from Uses. We progressively @@ -1377,6 +1379,154 @@ return false; } +namespace { + // Constant strides come first which in turns are sorted by their absolute + // values. If absolute values are the same, then positive strides comes first. + // e.g. + // 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X + struct StrideCompare { + bool operator()(const SCEVHandle &LHS, const SCEVHandle &RHS) { + SCEVConstant *LHSC = dyn_cast(LHS); + SCEVConstant *RHSC = dyn_cast(RHS); + if (LHSC && RHSC) { + int64_t LV = LHSC->getValue()->getSExtValue(); + int64_t RV = RHSC->getValue()->getSExtValue(); + uint64_t ALV = (LV < 0) ? -LV : LV; + uint64_t ARV = (RV < 0) ? -RV : RV; + if (ALV == ARV) + return LV > RV; + else + return ALV < ARV; + } + return (LHSC && !RHSC); + } + }; +} + +/// ChangeCompareStride - If a loop termination compare instruction is the +/// only use of its stride, and the compaison is against a constant value, +/// try eliminate the stride by moving the compare instruction to another +/// stride and change its constant operand accordingly. e.g. +/// +/// loop: +/// ... +/// v1 = v1 + 3 +/// v2 = v2 + 1 +/// if (v2 < 10) goto loop +/// => +/// loop: +/// ... +/// v1 = v1 + 3 +/// if (v1 < 30) goto loop +ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, + IVStrideUse* &CondUse, + const SCEVHandle* &CondStride) { + if (StrideOrder.size() < 2 || + IVUsesByStride[*CondStride].Users.size() != 1) + return Cond; + // FIXME: loosen this restriction? + if (!isa(CondUse->Offset)) + return Cond; + const SCEVConstant *SC = dyn_cast(*CondStride); + if (!SC) return Cond; + ConstantInt *C = dyn_cast(Cond->getOperand(1)); + if (!C) return Cond; + + ICmpInst::Predicate Predicate = Cond->getPredicate(); + bool isSigned = ICmpInst::isSignedPredicate(Predicate); + int64_t CmpSSInt = SC->getValue()->getSExtValue(); + int64_t CmpVal = C->getValue().getSExtValue(); + uint64_t SignBit = 1ULL << (C->getValue().getBitWidth()-1); + int64_t NewCmpVal = CmpVal; + SCEVHandle *NewStride = NULL; + Value *NewIncV = NULL; + int64_t Scale = 1; + const Type *CmpTy = C->getType(); + const Type *NewCmpTy = NULL; + + // Look for a suitable stride / iv as replacement. + std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare()); + for (unsigned i = 0, e = StrideOrder.size(); i != e; ++i) { + std::map::iterator SI = + IVUsesByStride.find(StrideOrder[i]); + if (!isa(SI->first)) + continue; + int64_t SSInt = cast(SI->first)->getValue()->getSExtValue(); + if (abs(SSInt) < abs(CmpSSInt) && (CmpSSInt % SSInt) == 0) { + Scale = CmpSSInt / SSInt; + NewCmpVal = CmpVal / Scale; + } else if (abs(SSInt) > abs(CmpSSInt) && (SSInt % CmpSSInt) == 0) { + Scale = SSInt / CmpSSInt; + NewCmpVal = CmpVal * Scale; + } else + continue; + + // Watch out for overflow. + if (isSigned && (CmpVal & SignBit) != (NewCmpVal & SignBit)) + NewCmpVal = CmpVal; + if (NewCmpVal != CmpVal) { + // Pick the best iv to use trying to avoid a cast. + NewIncV = NULL; + for (std::vector::iterator UI = SI->second.Users.begin(), + E = SI->second.Users.end(); UI != E; ++UI) { + // if (!isa(UI->Offset)) + // continue; + NewIncV = UI->OperandValToReplace; + if (NewIncV->getType() == CmpTy) + break; + } + if (!NewIncV) { + NewCmpVal = CmpVal; + continue; + } + + // FIXME: allow reuse of iv of a smaller type? + NewCmpTy = NewIncV->getType(); + if (!CmpTy->canLosslesslyBitCastTo(NewCmpTy) && + !(isa(NewCmpTy) && + CmpTy->canLosslesslyBitCastTo(UIntPtrTy))) { + NewCmpVal = CmpVal; + continue; + } + + // If scale is negative, use inverse predicate unless it's testing + // for equality. + if (Scale < 0 && !Cond->isEquality()) + Predicate = ICmpInst::getInversePredicate(Predicate); + + NewStride = &StrideOrder[i]; + break; + } + } + + if (NewCmpVal != CmpVal) { + // Create a new compare instruction using new stride / iv. + ICmpInst *OldCond = Cond; + Value *RHS = ConstantInt::get(C->getType(), NewCmpVal); + // Both sides of a ICmpInst must be of the same type. + if (NewCmpTy != CmpTy) { + if (isa(NewCmpTy) && !isa(CmpTy)) + RHS= SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, RHS, NewCmpTy); + else + RHS = SCEVExpander::InsertCastOfTo(Instruction::BitCast, RHS, NewCmpTy); + } + Cond = new ICmpInst(Predicate, NewIncV, RHS); + Cond->setName(L->getHeader()->getName() + ".termcond"); + OldCond->getParent()->getInstList().insert(OldCond, Cond); + OldCond->replaceAllUsesWith(Cond); + OldCond->eraseFromParent(); + IVUsesByStride[*CondStride].Users.pop_back(); + SCEVHandle NewOffset = SE->getMulExpr(CondUse->Offset, + SE->getConstant(ConstantInt::get(CondUse->Offset->getType(), Scale))); + IVUsesByStride[*NewStride].addUser(NewOffset, Cond, NewIncV); + CondUse = &IVUsesByStride[*NewStride].Users.back(); + CondStride = NewStride; + ++NumEliminated; + } + + return Cond; +} + // OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar // uses in the loop, look to see if we can eliminate some, in favor of using // common indvars for the different uses. @@ -1403,7 +1553,10 @@ if (!FindIVForUser(Cond, CondUse, CondStride)) return; // setcc doesn't use the IV. - + + // If possible, change stride and operands of the compare instruction to + // eliminate one stride. + Cond = ChangeCompareStride(L, Cond, CondUse, CondStride); // It's possible for the setcc instruction to be anywhere in the loop, and // possible for it to have multiple users. If it is not immediately before @@ -1431,30 +1584,6 @@ CondUse->isUseOfPostIncrementedValue = true; } -namespace { - // Constant strides come first which in turns are sorted by their absolute - // values. If absolute values are the same, then positive strides comes first. - // e.g. - // 4, -1, X, 1, 2 ==> 1, -1, 2, 4, X - struct StrideCompare { - bool operator()(const SCEVHandle &LHS, const SCEVHandle &RHS) { - SCEVConstant *LHSC = dyn_cast(LHS); - SCEVConstant *RHSC = dyn_cast(RHS); - if (LHSC && RHSC) { - int64_t LV = LHSC->getValue()->getSExtValue(); - int64_t RV = RHSC->getValue()->getSExtValue(); - uint64_t ALV = (LV < 0) ? -LV : LV; - uint64_t ARV = (RV < 0) ? -RV : RV; - if (ALV == ARV) - return LV > RV; - else - return ALV < ARV; - } - return (LHSC && !RHSC); - } - }; -} - bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager &LPM) { LI = &getAnalysis(); Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll?rev=43336&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll (added) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce3.ll Thu Oct 25 04:11:16 2007 @@ -0,0 +1,37 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep cmp | grep 240 +; RUN: llvm-as < %s | llc -march=x86 | grep inc | count 1 + +define i32 @foo(i32 %A, i32 %B, i32 %C, i32 %D) { +entry: + %tmp2955 = icmp sgt i32 %C, 0 ; [#uses=1] + br i1 %tmp2955, label %bb26.outer.us, label %bb40.split + +bb26.outer.us: ; preds = %bb26.bb32_crit_edge.us, %entry + %i.044.0.ph.us = phi i32 [ 0, %entry ], [ %indvar.next57, %bb26.bb32_crit_edge.us ] ; [#uses=2] + %k.1.ph.us = phi i32 [ 0, %entry ], [ %k.0.us, %bb26.bb32_crit_edge.us ] ; [#uses=1] + %tmp3.us = mul i32 %i.044.0.ph.us, 6 ; [#uses=1] + br label %bb1.us + +bb1.us: ; preds = %bb1.us, %bb26.outer.us + %j.053.us = phi i32 [ 0, %bb26.outer.us ], [ %tmp25.us, %bb1.us ] ; [#uses=2] + %k.154.us = phi i32 [ %k.1.ph.us, %bb26.outer.us ], [ %k.0.us, %bb1.us ] ; [#uses=1] + %tmp5.us = add i32 %tmp3.us, %j.053.us ; [#uses=1] + %tmp7.us = shl i32 %D, %tmp5.us ; [#uses=2] + %tmp9.us = icmp eq i32 %tmp7.us, %B ; [#uses=1] + %tmp910.us = zext i1 %tmp9.us to i32 ; [#uses=1] + %tmp12.us = and i32 %tmp7.us, %A ; [#uses=1] + %tmp19.us = and i32 %tmp12.us, %tmp910.us ; [#uses=1] + %k.0.us = add i32 %tmp19.us, %k.154.us ; [#uses=3] + %tmp25.us = add i32 %j.053.us, 1 ; [#uses=2] + %tmp29.us = icmp slt i32 %tmp25.us, %C ; [#uses=1] + br i1 %tmp29.us, label %bb1.us, label %bb26.bb32_crit_edge.us + +bb26.bb32_crit_edge.us: ; preds = %bb1.us + %indvar.next57 = add i32 %i.044.0.ph.us, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next57, 40 ; [#uses=1] + br i1 %exitcond, label %bb40.split, label %bb26.outer.us + +bb40.split: ; preds = %bb26.bb32_crit_edge.us, %entry + %k.1.lcssa.lcssa.us-lcssa = phi i32 [ %k.0.us, %bb26.bb32_crit_edge.us ], [ 0, %entry ] ; [#uses=1] + ret i32 %k.1.lcssa.lcssa.us-lcssa +} Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce4.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce4.ll?rev=43336&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce4.ll (added) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce4.ll Thu Oct 25 04:11:16 2007 @@ -0,0 +1,49 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep cmp | grep 64 +; RUN: llvm-as < %s | llc -march=x86 | not grep inc + + at state = external global [0 x i32] ; <[0 x i32]*> [#uses=4] + at S = external global [0 x i32] ; <[0 x i32]*> [#uses=4] + +define i32 @foo() { +entry: + br label %bb + +bb: ; preds = %bb, %entry + %indvar = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=2] + %t.063.0 = phi i32 [ 0, %entry ], [ %tmp47, %bb ] ; [#uses=1] + %j.065.0 = shl i32 %indvar, 2 ; [#uses=4] + %tmp3 = getelementptr [0 x i32]* @state, i32 0, i32 %j.065.0 ; [#uses=2] + %tmp4 = load i32* %tmp3, align 4 ; [#uses=1] + %tmp6 = getelementptr [0 x i32]* @S, i32 0, i32 %t.063.0 ; [#uses=1] + %tmp7 = load i32* %tmp6, align 4 ; [#uses=1] + %tmp8 = xor i32 %tmp7, %tmp4 ; [#uses=2] + store i32 %tmp8, i32* %tmp3, align 4 + %tmp1378 = or i32 %j.065.0, 1 ; [#uses=1] + %tmp16 = getelementptr [0 x i32]* @state, i32 0, i32 %tmp1378 ; [#uses=2] + %tmp17 = load i32* %tmp16, align 4 ; [#uses=1] + %tmp19 = getelementptr [0 x i32]* @S, i32 0, i32 %tmp8 ; [#uses=1] + %tmp20 = load i32* %tmp19, align 4 ; [#uses=1] + %tmp21 = xor i32 %tmp20, %tmp17 ; [#uses=2] + store i32 %tmp21, i32* %tmp16, align 4 + %tmp2680 = or i32 %j.065.0, 2 ; [#uses=1] + %tmp29 = getelementptr [0 x i32]* @state, i32 0, i32 %tmp2680 ; [#uses=2] + %tmp30 = load i32* %tmp29, align 4 ; [#uses=1] + %tmp32 = getelementptr [0 x i32]* @S, i32 0, i32 %tmp21 ; [#uses=1] + %tmp33 = load i32* %tmp32, align 4 ; [#uses=1] + %tmp34 = xor i32 %tmp33, %tmp30 ; [#uses=2] + store i32 %tmp34, i32* %tmp29, align 4 + %tmp3982 = or i32 %j.065.0, 3 ; [#uses=1] + %tmp42 = getelementptr [0 x i32]* @state, i32 0, i32 %tmp3982 ; [#uses=2] + %tmp43 = load i32* %tmp42, align 4 ; [#uses=1] + %tmp45 = getelementptr [0 x i32]* @S, i32 0, i32 %tmp34 ; [#uses=1] + %tmp46 = load i32* %tmp45, align 4 ; [#uses=1] + %tmp47 = xor i32 %tmp46, %tmp43 ; [#uses=3] + store i32 %tmp47, i32* %tmp42, align 4 + %indvar.next = add i32 %indvar, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 4 ; [#uses=1] + br i1 %exitcond, label %bb57, label %bb + +bb57: ; preds = %bb + %tmp59 = and i32 %tmp47, 255 ; [#uses=1] + ret i32 %tmp59 +} From gordonhenriksen at mac.com Thu Oct 25 05:18:31 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Thu, 25 Oct 2007 10:18:31 -0000 Subject: [llvm-commits] [llvm] r43337 - /llvm/trunk/docs/Passes.html Message-ID: <200710251018.l9PAIXh2012056@zion.cs.uiuc.edu> Author: gordon Date: Thu Oct 25 05:18:27 2007 New Revision: 43337 URL: http://llvm.org/viewvc/llvm-project?rev=43337&view=rev Log: Fleshing out docs/Passes.html for some analyses. Modified: llvm/trunk/docs/Passes.html Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=43337&r1=43336&r2=43337&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Thu Oct 25 05:18:27 2007 @@ -34,6 +34,10 @@ print @x, @y; EOT +This (real) one-liner can also be helpful when converting comments to HTML: + +perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print "

      \n" if !$on && $_ =~ /\S/; print "

      \n" if $on && $_ =~ /^\s*$/; print " $_\n"; $on = ($_ =~ /\S/); } print "

      \n" if $on' + -->
      LLVM's Analysis and Transform Passes
      @@ -46,7 +50,8 @@
      -

      Written by Reid Spencer

      +

      Written by Reid Spencer + and Gordon Henriksen

      @@ -84,7 +89,6 @@
      - @@ -124,6 +128,7 @@ + @@ -192,7 +197,13 @@ Exhaustive Alias Analysis Precision Evaluator
      -

      Yet to be written.

      +

      This is a simple N^2 alias analysis accuracy evaluator. + Basically, for each function in the program, it simply queries to see how the + alias analysis implementation answers alias queries between each pair of + pointers in the function.

      + +

      This is inspired and adapted from code by: Naveen Neelakantam, Francesco + Spadini, and Wojciech Stryjewski.

      @@ -200,7 +211,67 @@ Andersen's Interprocedural Alias Analysis
      -

      Yet to be written.

      +

      + This is an implementation of Andersen's interprocedural alias + analysis +

      + +

      + In pointer analysis terms, this is a subset-based, flow-insensitive, + field-sensitive, and context-insensitive algorithm pointer algorithm. +

      + +

      + This algorithm is implemented as three stages: +

      + +
        +
      1. Object identification.
      2. +
      3. Inclusion constraint identification.
      4. +
      5. Offline constraint graph optimization.
      6. +
      7. Inclusion constraint solving.
      8. +
      + +

      + The object identification stage identifies all of the memory objects in the + program, which includes globals, heap allocated objects, and stack allocated + objects. +

      + +

      + The inclusion constraint identification stage finds all inclusion constraints + in the program by scanning the program, looking for pointer assignments and + other statements that effect the points-to graph. For a statement like + A = B, this statement is processed to + indicate that A can point to anything that B can point + to. Constraints can handle copies, loads, and stores, and address taking. +

      + +

      + The offline constraint graph optimization portion includes offline variable + substitution algorithms intended to computer pointer and location + equivalences. Pointer equivalences are those pointers that will have the + same points-to sets, and location equivalences are those variables that + always appear together in points-to sets. +

      + +

      + The inclusion constraint solving phase iteratively propagates the inclusion + constraints until a fixed point is reached. This is an O(n??) + algorithm. +

      + +

      + Function constraints are handled as if they were structs with X + fields. Thus, an access to argument X of function Y is + an access to node index getNode(Y) + X. + This representation allows handling of indirect calls without any issues. To + wit, an indirect call Y(a,b) is + equivalent to *(Y + 1) = a, *(Y + 2) = + b. The return node for a function F is always + located at getNode(F) + CallReturnPos. The arguments + start at getNode(F) + CallArgPos. +

      @@ -208,7 +279,11 @@ Basic Alias Analysis (default AA impl)
      -

      Yet to be written.

      +

      + This is the default implementation of the Alias Analysis interface + that simply implements a few identities (two different globals cannot alias, + etc), but otherwise does no analysis. +

      @@ -224,7 +299,12 @@ Basic Value Numbering (default GVN impl)
      -

      Yet to be written.

      +

      + This is the default implementation of the ValueNumbering + interface. It walks the SSA def-use chains to trivially identify + lexically identical expressions. This does not require any ahead of time + analysis, so it is a very fast default implementation. +

      @@ -232,7 +312,11 @@ Print a call graph
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints + the call graph into a .dot graph. This graph can then be processed with the + "dot" tool to convert it to postscript or some other suitable format. +

      @@ -240,7 +324,10 @@ Print SCCs of the Call Graph
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints + the SCCs of the call graph to standard output in a human-readable form. +

      @@ -248,7 +335,10 @@ Print SCCs of each function CFG
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints + the SCCs of each function CFG to standard output in a human-readable form. +

      @@ -256,7 +346,11 @@ Optimize for code generation
      -

      Yet to be written.

      +

      + This pass munges the code in the input function to better prepare it for + SelectionDAG-based code generation. This works around limitations in it's + basic-block-at-a-time approach. It should eventually be removed. +

      @@ -264,7 +358,10 @@ Count Alias Analysis Query Responses
      -

      Yet to be written.

      +

      + A pass which can be used to count how many alias queries + are being made and how the alias analysis implementation being used responds. +

      @@ -272,7 +369,16 @@ AA use debugger
      -

      Yet to be written.

      +

      + This simple pass checks alias analysis users to ensure that if they + create a new value, they do not query AA without informing it of the value. + It acts as a shim over any other AA pass you want. +

      + +

      + Yes keeping track of every value in the program is expensive, but this is + a debugging pass. +

      @@ -280,7 +386,10 @@ Dominance Frontier Construction
      -

      Yet to be written.

      +

      + This pass is a simple dominator construction algorithm for finding forward + dominator frontiers. +

      @@ -288,7 +397,10 @@ Dominator Tree Construction
      -

      Yet to be written.

      +

      + This pass is a simple dominator construction algorithm for finding forward + dominators. +

      @@ -296,7 +408,12 @@ Print external fn callsites passed constants
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints out call sites to + external functions that are called with constant arguments. This can be + useful when looking for standard library functions we should constant fold + or handle in alias analyses. +

      @@ -304,15 +421,12 @@ Simple mod/ref analysis for globals
      -

      Yet to be written.

      -
      - - - -
      -

      Yet to be written.

      +

      + This simple pass provides alias and mod/ref information for global values + that do not have their address taken, and keeps track of whether functions + read or write memory (are "pure"). For this simple (but very common) case, + we can provide pretty accurate and useful information. +

      @@ -320,7 +434,9 @@ Counts the various types of Instructions
      -

      Yet to be written.

      +

      + This pass collects the count of all instructions and reports them +

      @@ -328,7 +444,15 @@ Interval Partition Construction
      -

      Yet to be written.

      +

      + This analysis calculates and represents the interval partition of a function, + or a preexisting interval partition. +

      + +

      + In this way, the interval partition may be used to reduce a flow graph down + to its degenerate single node interval partition (unless it is irreducible). +

      @@ -336,7 +460,21 @@ Load Value Numbering
      -

      Yet to be written.

      +

      + This pass value numbers load and call instructions. To do this, it finds + lexically identical load instructions, and uses alias analysis to determine + which loads are guaranteed to produce the same value. To value number call + instructions, it looks for calls to functions that do not write to memory + which do not have intervening instructions that clobber the memory that is + read from. +

      + +

      + This pass builds off of another value numbering pass to implement value + numbering for non-load and non-call instructions. It uses Alias Analysis so + that it can disambiguate the load instructions. The more powerful these base + analyses are, the more powerful the resultant value numbering will be. +

      @@ -344,7 +482,12 @@ Natural Loop Construction
      -

      Yet to be written.

      +

      + This analysis is used to identify natural loops and determine the loop depth + of various nodes of the CFG. Note that the loops identified may actually be + several natural loops that share the same header node... not just a single + natural loop. +

      @@ -506,6 +649,7 @@ Code Positioning" by Pettis and Hansen, except that it uses basic block counts instead of edge counts. This could be improved in many ways, but is very simple for now.

      +

      Basically we "place" the entry block, then loop over all successors in a DFO, placing the most frequently executed successor until we run out of blocks. Did we mention that this was extremely simplistic? This is @@ -646,10 +790,30 @@

      +
      +

      + This pass performs global value numbering to eliminate fully redundant + instructions. It also performs simple dead load elimination. +

      +
      + + +
      -

      Yet to be written.

      +

      + This pass performs a hybrid of global value numbering and partial redundancy + elimination, known as GVN-PRE. It performs partial redundancy elimination on + values, rather than lexical expressions, allowing a more comprehensive view + the optimization. It replaces redundant values with uses of earlier + occurences of the same value. While this is beneficial in that it eliminates + unneeded computation, it also increases register pressure by creating large + live ranges, and should be used with caution on platforms that are very + sensitive to register pressure. +

      From baldrick at free.fr Thu Oct 25 07:28:15 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 25 Oct 2007 12:28:15 -0000 Subject: [llvm-commits] [llvm] r43338 - /llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Message-ID: <200710251228.l9PCSI45017855@zion.cs.uiuc.edu> Author: baldrick Date: Thu Oct 25 07:28:12 2007 New Revision: 43338 URL: http://llvm.org/viewvc/llvm-project?rev=43338&view=rev Log: Fix comment typos. 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=43338&r1=43337&r2=43338&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original) +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Thu Oct 25 07:28:12 2007 @@ -235,7 +235,7 @@ ADD, SUB, MUL, SDIV, UDIV, SREM, UREM, // SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing - // a signed/unsigned value of type i[2*n], and return the full value as + // a signed/unsigned value of type i[2*N], and return the full value as // two results, each of type iN. SMUL_LOHI, UMUL_LOHI, @@ -319,7 +319,7 @@ INSERT_SUBREG, // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing - // an unsigned/signed value of type i[2*n], then return the top part. + // an unsigned/signed value of type i[2*N], then return the top part. MULHU, MULHS, // Bitwise operators - logical and, logical or, logical xor, shift left, From baldrick at free.fr Thu Oct 25 07:30:52 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 25 Oct 2007 12:30:52 -0000 Subject: [llvm-commits] [llvm] r43339 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710251230.l9PCUqYk017960@zion.cs.uiuc.edu> Author: baldrick Date: Thu Oct 25 07:30:51 2007 New Revision: 43339 URL: http://llvm.org/viewvc/llvm-project?rev=43339&view=rev Log: Correctly extract the ValueType from a VTSDNode. 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=43339&r1=43338&r2=43339&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Thu Oct 25 07:30:51 2007 @@ -903,7 +903,7 @@ void DAGTypeLegalizer:: ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { GetExpandedOp(N->getOperand(0), Lo, Hi); - MVT::ValueType EVT = N->getOperand(1).getValueType(); + MVT::ValueType EVT = cast(N->getOperand(1))->getVT(); if (MVT::getSizeInBits(EVT) <= MVT::getSizeInBits(Lo.getValueType())) { // sext_inreg the low part if needed. From baldrick at free.fr Thu Oct 25 07:32:33 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 25 Oct 2007 12:32:33 -0000 Subject: [llvm-commits] [llvm] r43340 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710251232.l9PCWXek018032@zion.cs.uiuc.edu> Author: baldrick Date: Thu Oct 25 07:32:31 2007 New Revision: 43340 URL: http://llvm.org/viewvc/llvm-project?rev=43340&view=rev Log: Promote SETCC operands. 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=43340&r1=43339&r2=43340&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Thu Oct 25 07:32:31 2007 @@ -190,6 +190,7 @@ SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo); SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo); SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo); + SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo); SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo); void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code); @@ -1456,6 +1457,7 @@ case ISD::SELECT: Res = PromoteOperand_SELECT(N, OpNo); break; case ISD::BRCOND: Res = PromoteOperand_BRCOND(N, OpNo); break; case ISD::BR_CC: Res = PromoteOperand_BR_CC(N, OpNo); break; + case ISD::SETCC: Res = PromoteOperand_SETCC(N, OpNo); break; case ISD::STORE: Res = PromoteOperand_STORE(cast(N), OpNo); break; @@ -1577,6 +1579,17 @@ N->getOperand(1), LHS, RHS, N->getOperand(4)); } +SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) { + assert(OpNo == 0 && "Don't know how to promote this operand"); + + SDOperand LHS = N->getOperand(0); + SDOperand RHS = N->getOperand(1); + PromoteSetCCOperands(LHS, RHS, cast(N->getOperand(2))->get()); + + // The CC (#2) is always legal. + return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2)); +} + /// PromoteSetCCOperands - Promote the operands of a comparison. This code is /// shared among BR_CC, SELECT_CC, and SETCC handlers. void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS, From baldrick at free.fr Thu Oct 25 07:35:53 2007 From: baldrick at free.fr (Duncan Sands) Date: Thu, 25 Oct 2007 12:35:53 -0000 Subject: [llvm-commits] [llvm] r43341 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710251235.l9PCZsDF018161@zion.cs.uiuc.edu> Author: baldrick Date: Thu Oct 25 07:35:51 2007 New Revision: 43341 URL: http://llvm.org/viewvc/llvm-project?rev=43341&view=rev Log: Small formatting changes. Add a sanity check. Use NVT rather than looking it up, since we have it to hand. 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=43341&r1=43340&r2=43341&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Thu Oct 25 07:35:51 2007 @@ -454,7 +454,6 @@ return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0); } - /// HandleMemIntrinsic - This handles memcpy/memset/memmove with invalid /// operands. This promotes or expands the operands as required. SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) { @@ -664,7 +663,6 @@ return DAG.getNode(NewOpc, NVT, Op); } - SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) { assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??"); return DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), N->getOperand(0), @@ -730,6 +728,7 @@ N->getOperand(1), LHS, RHS, N->getOperand(4)); } + //===----------------------------------------------------------------------===// // Result Expansion //===----------------------------------------------------------------------===// @@ -1061,7 +1060,6 @@ Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); } - void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi) { SDOperand LL, LH, RL, RH; @@ -1166,7 +1164,7 @@ SDOperand LL, LH, RL, RH; GetExpandedOp(N->getOperand(0), LL, LH); GetExpandedOp(N->getOperand(1), RL, RH); - unsigned BitSize = MVT::getSizeInBits(RH.getValueType()); + unsigned BitSize = MVT::getSizeInBits(NVT); unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0)); unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1)); @@ -1364,6 +1362,8 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0)); unsigned NVTBits = MVT::getSizeInBits(NVT); + assert(!(NVTBits & (NVTBits - 1)) && + "Expanded integer type size not a power of two!"); uint64_t HighBitMask = NVTBits, KnownZero, KnownOne; DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne); @@ -1425,6 +1425,7 @@ return true; } + //===----------------------------------------------------------------------===// // Operand Promotion //===----------------------------------------------------------------------===// @@ -1530,7 +1531,6 @@ return DAG.UpdateNodeOperands(SDOperand(N, 0), In); } - SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) { assert(OpNo == 0 && "Only know how to promote condition"); SDOperand Cond = GetPromotedOp(N->getOperand(0)); // Promote the condition. @@ -1548,7 +1548,6 @@ N->getOperand(2)); } - SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) { assert(OpNo == 1 && "only know how to promote condition"); SDOperand Cond = GetPromotedOp(N->getOperand(1)); // Promote the condition. @@ -1633,7 +1632,6 @@ return; } } - SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){ SDOperand Ch = N->getChain(), Ptr = N->getBasePtr(); @@ -1799,7 +1797,6 @@ return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); } - SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) { SDOperand Lo, Hi; GetExpandedOp(N->getOperand(0), Lo, Hi); @@ -1936,7 +1933,6 @@ NewRHS = SDOperand(); } - SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) { assert(OpNo == 1 && "Can only expand the stored value so far"); assert(!N->isTruncatingStore() && "Can't expand truncstore!"); @@ -2010,6 +2006,7 @@ return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); } + //===----------------------------------------------------------------------===// // Entry Point //===----------------------------------------------------------------------===// @@ -2022,4 +2019,3 @@ void SelectionDAG::LegalizeTypes() { DAGTypeLegalizer(*this).run(); } - From clattner at apple.com Thu Oct 25 10:23:27 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 25 Oct 2007 08:23:27 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <16e5fdf90710241747s4425fdd1s786cc4e9b51d4f0f@mail.gmail.com> References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <16e5fdf90710231711r297a02bbi143225f22629f018@mail.gmail.com> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> <245A3AC2-763A-4CBC-A915-4AB044BB39AB@apple.com> <16e5fdf90710241747s4425fdd1s786cc4e9b51d4f0f@mail.gmail.com> Message-ID: >>> >>> I discussed this with Bill today. The problem is that we have: >>> >>> llvm.memcpy(p, q, 8, 1/*alignment) >>> >>> this gets turned into an 8-byte load and an 8-byte store, but the >>> alignment (of 1) from the memcpy isn't put onto the load or >>> store, so >>> the legalizer thinks they are properly aligned. >> >> Ok, this makes sense. I'd thought the memcpy alignment was 4. >> > Um...so...since the Align that I get is 8 from the memcpy, how do I > get the alignment of the src/dst pointers? Okay, well then. Bill and I discussed this again. It sounds like there are multibugs here. One issue is that the alignment from the memcpy isn't pushed onto the generated load/stores when lowering the memcpy. However, there is another bug with this specific testcase: @C.0.1173 = external constant [33 x i8] define void @Bork() { entry: %Qux = alloca [33 x i8] %Qux1 = bitcast [33 x i8]* %Qux to i8* call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) ret void } declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) Note that the memcpy has an alignment of 8 specified here, but it is copying out of a global and out of a local alloca that need not be so aligned. This is a bug in the testcase: whatever generated the memcpy is broken, as the alignment is not valid. However, invalid code shouldn't cause llc to abort, so we have to fix *that too*. :) -Chris From kremenek at apple.com Thu Oct 25 11:09:09 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 25 Oct 2007 16:09:09 -0000 Subject: [llvm-commits] [llvm] r43345 - /llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200710251609.l9PG99Pe029332@zion.cs.uiuc.edu> Author: kremenek Date: Thu Oct 25 11:09:09 2007 New Revision: 43345 URL: http://llvm.org/viewvc/llvm-project?rev=43345&view=rev Log: Added Serialization.h, Serialize.h, Deserialize.h, Serialize.cpp, and Deserialize.cpp to the XCode project. Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj?rev=43345&r1=43344&r2=43345&view=diff ============================================================================== --- llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj (original) +++ llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Thu Oct 25 11:09:09 2007 @@ -65,6 +65,11 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 35A9CDED0CD0F6AF008ABC1D /* Deserialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deserialize.h; sourceTree = ""; }; + 35A9CDEE0CD0F6AF008ABC1D /* Serialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialization.h; sourceTree = ""; }; + 35A9CDEF0CD0F6AF008ABC1D /* Serialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialize.h; sourceTree = ""; }; + 35A9CDF00CD0F6D5008ABC1D /* Deserialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Deserialize.cpp; sourceTree = ""; }; + 35A9CDF10CD0F6E1008ABC1D /* Serialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Serialize.cpp; sourceTree = ""; }; 35E98A830CBC2ED300C5CDC1 /* DenseSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DenseSet.h; sourceTree = ""; }; 35E98A840CBC2ED300C5CDC1 /* ImmutableMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableMap.h; sourceTree = ""; }; 35E98A850CBC2ED300C5CDC1 /* ImmutableSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImmutableSet.h; sourceTree = ""; }; @@ -1099,6 +1104,7 @@ 9F68EB050C77AD2C004AA152 /* Reader */ = { isa = PBXGroup; children = ( + 35A9CDF00CD0F6D5008ABC1D /* Deserialize.cpp */, 9F68EB060C77AD2C004AA152 /* BitcodeReader.cpp */, 9F68EB070C77AD2C004AA152 /* BitcodeReader.h */, ); @@ -1113,6 +1119,7 @@ 9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */, 9F68EB250C77AD2C004AA152 /* ValueEnumerator.cpp */, 9F68EB260C77AD2C004AA152 /* ValueEnumerator.h */, + 35A9CDF10CD0F6E1008ABC1D /* Serialize.cpp */, ); path = Writer; sourceTree = ""; @@ -1126,6 +1133,9 @@ 9F7793830C73C54C00551F9C /* BitstreamWriter.h */, 9F7793840C73C54C00551F9C /* LLVMBitCodes.h */, 9F7793850C73C54C00551F9C /* ReaderWriter.h */, + 35A9CDEE0CD0F6AF008ABC1D /* Serialization.h */, + 35A9CDEF0CD0F6AF008ABC1D /* Serialize.h */, + 35A9CDED0CD0F6AF008ABC1D /* Deserialize.h */, ); path = Bitcode; sourceTree = ""; From sabre at nondot.org Thu Oct 25 12:52:39 2007 From: sabre at nondot.org (Chris Lattner) Date: Thu, 25 Oct 2007 17:52:39 -0000 Subject: [llvm-commits] [llvm] r43350 - /llvm/trunk/docs/tutorial/LangImpl4.html Message-ID: <200710251752.l9PHqd4O003412@zion.cs.uiuc.edu> Author: lattner Date: Thu Oct 25 12:52:39 2007 New Revision: 43350 URL: http://llvm.org/viewvc/llvm-project?rev=43350&view=rev Log: some minor edits, link to Passes.html, make one point I forgot about yesterday. Modified: llvm/trunk/docs/tutorial/LangImpl4.html Modified: llvm/trunk/docs/tutorial/LangImpl4.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=43350&r1=43349&r2=43350&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl4.html (original) +++ llvm/trunk/docs/tutorial/LangImpl4.html Thu Oct 25 12:52:39 2007 @@ -252,8 +252,9 @@ add from the program.

      LLVM provides a wide variety of optimizations that can be used in certain -circumstances. Unfortunately we don't have a good centralized description of -what every pass does, but you can check out the ones that llvm-gcc or +circumstances. Some documentation about the various +passes is available, but it isn't very complete. Another good source of +ideas is to look at the passes that llvm-gcc or llvm-ld run to get started. The "opt" tool allows you to experiment with passes from the command line, so you can see if they do anything.

      @@ -410,6 +411,7 @@ ready> sin(1.0); Evaluated to 0.841471 + ready> def foo(x) sin(x)*sin(x) + cos(x)*cos(x); Read function definition: define double @foo(double %x) { @@ -444,6 +446,27 @@ function name, and even allows you to have the JIT abort itself if any lazy compilation is attempted.

      +

      One interesting application of this is that we can now extend the language +by writing arbitrary C++ code to implement operations. For example, if we add: +

      + +
      +
      +/// putchard - putchar that takes a double and returns 0.
      +extern "C" 
      +double putchard(double X) {
      +  putchar((char)X);
      +  return 0;
      +}
      +
      +
      + +

      Now we can produce simple output to the console by using things like: +"extern putchard(x); putchard(120);", which prints a lowercase 'x' on +the console (120 is the ascii code for 'x'). Similar code could be used to +implement file I/O, console input, and many other capabilities in +Kaleidoscope.

      +

      This completes the JIT and optimizer chapter of the Kaleidoscope tutorial. At this point, we can compile a non-Turing-complete programming language, optimize and JIT compile it in a user-driven way. Next up we'll look into Author: lattner Date: Thu Oct 25 13:05:29 2007 New Revision: 43351 URL: http://llvm.org/viewvc/llvm-project?rev=43351&view=rev Log: typo Modified: llvm/trunk/docs/tutorial/LangImpl2.html Modified: llvm/trunk/docs/tutorial/LangImpl2.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl2.html?rev=43351&r1=43350&r2=43351&view=diff ============================================================================== --- llvm/trunk/docs/tutorial/LangImpl2.html (original) +++ llvm/trunk/docs/tutorial/LangImpl2.html Thu Oct 25 13:05:29 2007 @@ -192,7 +192,7 @@

      This implements a simple token buffer around the lexer. This allows us to look one token ahead at what the lexer is returning. Every function in -our lexer will assume that CurTok is the current token that needs to be +our parser will assume that CurTok is the current token that needs to be parsed.

      Again, we define these with global variables; it would be better design to From kremenek at apple.com Thu Oct 25 13:19:29 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 25 Oct 2007 18:19:29 -0000 Subject: [llvm-commits] [llvm] r43352 - in /llvm/trunk/include/llvm/Bitcode: Serialization.h SerializationFwd.h Message-ID: <200710251819.l9PIJT0a004903@zion.cs.uiuc.edu> Author: kremenek Date: Thu Oct 25 13:19:29 2007 New Revision: 43352 URL: http://llvm.org/viewvc/llvm-project?rev=43352&view=rev Log: Created header file to include minimal forward references needed for object serialization. Added: llvm/trunk/include/llvm/Bitcode/SerializationFwd.h Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43352&r1=43351&r2=43352&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Thu Oct 25 13:19:29 2007 @@ -7,19 +7,17 @@ // //===----------------------------------------------------------------------===// // -// This file defines the interface for generic object serialization to -// LLVM bitcode. +// This file defines traits for primitive types used for both object +// serialization and deserialization. // //===----------------------------------------------------------------------===// #ifndef LLVM_BITCODE_SERIALIZE #define LLVM_BITCODE_SERIALIZE -namespace llvm { +#include "llvm/Bitcode/SerializationFwd.h" -class Serializer; -class Deserializer; -template struct SerializeTrait; +namespace llvm { #define SERIALIZE_INT_TRAIT(TYPE)\ template <> struct SerializeTrait {\ Added: llvm/trunk/include/llvm/Bitcode/SerializationFwd.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/SerializationFwd.h?rev=43352&view=auto ============================================================================== --- llvm/trunk/include/llvm/Bitcode/SerializationFwd.h (added) +++ llvm/trunk/include/llvm/Bitcode/SerializationFwd.h Thu Oct 25 13:19:29 2007 @@ -0,0 +1,25 @@ +//==- SerializationFwd.h - Forward references for Serialization ---*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides forward references for bitcode object serialization. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BITCODE_SERIALIZE_FWD +#define LLVM_BITCODE_SERIALIZE_FWD + +namespace llvm { + +class Serializer; +class Deserializer; +template struct SerializeTrait; + +} // end namespace llvm + +#endif From isanbard at gmail.com Thu Oct 25 13:23:46 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 25 Oct 2007 18:23:46 -0000 Subject: [llvm-commits] [llvm] r43353 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp Message-ID: <200710251823.l9PINkSd005059@zion.cs.uiuc.edu> Author: void Date: Thu Oct 25 13:23:45 2007 New Revision: 43353 URL: http://llvm.org/viewvc/llvm-project?rev=43353&view=rev Log: Added comment explaining why we are doing this check. Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=43353&r1=43352&r2=43353&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Thu Oct 25 13:23:45 2007 @@ -272,6 +272,11 @@ while (I1 != MBB1->begin() && I2 != MBB2->begin()) { --I1; --I2; if (!I1->isIdenticalTo(I2) || + // XXX: This check is dubious. It's used to get around a problem where + // people incorrectly expect inline asm directives to remain in the same + // relative order. This is untenable because normal compiler + // optimizations (like this one) may reorder and/or merge these + // directives. I1->getOpcode() == TargetInstrInfo::INLINEASM) { ++I1; ++I2; break; From evan.cheng at apple.com Thu Oct 25 13:38:24 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 Oct 2007 18:38:24 -0000 Subject: [llvm-commits] [llvm] r43356 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200710251838.l9PIcO6g006057@zion.cs.uiuc.edu> Author: evancheng Date: Thu Oct 25 13:38:24 2007 New Revision: 43356 URL: http://llvm.org/viewvc/llvm-project?rev=43356&view=rev Log: Remove code that's commented out. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43356&r1=43355&r2=43356&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Oct 25 13:38:24 2007 @@ -1469,8 +1469,6 @@ NewIncV = NULL; for (std::vector::iterator UI = SI->second.Users.begin(), E = SI->second.Users.end(); UI != E; ++UI) { - // if (!isa(UI->Offset)) - // continue; NewIncV = UI->OperandValToReplace; if (NewIncV->getType() == CmpTy) break; From kremenek at apple.com Thu Oct 25 13:42:52 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 25 Oct 2007 18:42:52 -0000 Subject: [llvm-commits] [llvm] r43357 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h include/llvm/Bitcode/Serialize.h lib/Bitcode/Reader/Deserialize.cpp lib/Bitcode/Writer/Serialize.cpp Message-ID: <200710251842.l9PIgqmm006431@zion.cs.uiuc.edu> Author: kremenek Date: Thu Oct 25 13:42:52 2007 New Revision: 43357 URL: http://llvm.org/viewvc/llvm-project?rev=43357&view=rev Log: Added special treatment of serializing NULL pointers. Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/include/llvm/Bitcode/Serialize.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43357&r1=43356&r2=43357&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Thu Oct 25 13:42:52 2007 @@ -86,6 +86,10 @@ template inline T* ReadOwnedPtr() { unsigned PtrId = ReadInt(); + + if (PtrId == 0) + return NULL; + T* x = SerializeTrait::Materialize(*this); RegisterPtr(PtrId,x); return x; Modified: llvm/trunk/include/llvm/Bitcode/Serialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialize.h?rev=43357&r1=43356&r2=43357&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialize.h Thu Oct 25 13:42:52 2007 @@ -47,7 +47,7 @@ template void EmitOwnedPtr(T* ptr) { EmitPtr(ptr); - SerializeTrait::Emit(*this,*ptr); + if (ptr) SerializeTrait::Emit(*this,*ptr); } void Flush() { if (inRecord()) EmitRecord(); } Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43357&r1=43356&r2=43357&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Thu Oct 25 13:42:52 2007 @@ -103,6 +103,11 @@ void Deserializer::ReadPtr(void*& PtrRef) { unsigned PtrId = ReadInt(); + if (PtrId == 0) { + PtrRef = NULL; + return; + } + BPatchEntry& E = BPatchMap[PtrId]; if (E.Ptr == NULL) { Modified: llvm/trunk/lib/Bitcode/Writer/Serialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/Serialize.cpp?rev=43357&r1=43356&r2=43357&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/Serialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/Serialize.cpp Thu Oct 25 13:42:52 2007 @@ -58,10 +58,13 @@ } unsigned Serializer::getPtrId(void* ptr) { + if (!ptr) + return 0; + MapTy::iterator I = PtrMap.find(ptr); if (I == PtrMap.end()) { - unsigned id = PtrMap.size(); + unsigned id = PtrMap.size()+1; PtrMap[ptr] = id; return id; } From isanbard at gmail.com Thu Oct 25 13:45:14 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 25 Oct 2007 11:45:14 -0700 Subject: [llvm-commits] [llvm] r43270 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: References: <200710232332.l9NNWgTH016108@zion.cs.uiuc.edu> <2EF4AD07-6CE9-4094-B306-9B8489170CB0@apple.com> <3DE51EAD-466A-4227-8406-56669FD8067F@apple.com> <793662AC-96AE-4364-B3EA-40572AF8973C@gmail.com> <245A3AC2-763A-4CBC-A915-4AB044BB39AB@apple.com> <16e5fdf90710241747s4425fdd1s786cc4e9b51d4f0f@mail.gmail.com> Message-ID: <16e5fdf90710251145y46d8418x3f13aa29c65a4470@mail.gmail.com> On 10/25/07, Chris Lattner wrote: > Okay, well then. Bill and I discussed this again. It sounds like > there are multibugs here. One issue is that the alignment from the > memcpy isn't pushed onto the generated load/stores when lowering the > memcpy. > > However, there is another bug with this specific testcase: > > @C.0.1173 = external constant [33 x i8] > > define void @Bork() { > entry: > %Qux = alloca [33 x i8] > %Qux1 = bitcast [33 x i8]* %Qux to i8* > call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* > @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) > ret void > } > > declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) > > > Note that the memcpy has an alignment of 8 specified here, but it is > copying out of a global and out of a local alloca that need not be so > aligned. This is a bug in the testcase: whatever generated the > memcpy is broken, as the alignment is not valid. However, invalid > code shouldn't cause llc to abort, so we have to fix *that too*. :) > The FE is generating the 8-byte align thing. However, it's doing it by checking only one of the pointer's alignment types instead of both. The trick is getting it to check both and take the minimal alignment. And then the other two bugs. :-/ -bw From dalej at apple.com Thu Oct 25 13:47:23 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 25 Oct 2007 18:47:23 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43358 - in /llvm-gcc-4.0/trunk/gcc: c-common.c llvm-convert.cpp Message-ID: <200710251847.l9PIlNnW006790@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 25 13:47:23 2007 New Revision: 43358 URL: http://llvm.org/viewvc/llvm-project?rev=43358&view=rev Log: Fix a couple of warnings to enable bootstrap with --enable-checking. Modified: llvm-gcc-4.0/trunk/gcc/c-common.c llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Modified: llvm-gcc-4.0/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-common.c?rev=43358&r1=43357&r2=43358&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.0/trunk/gcc/c-common.c Thu Oct 25 13:47:23 2007 @@ -7094,9 +7094,12 @@ if (once == 0) { size_t i; + /* Extract this into a variable to prevent compiler warning. */ + unsigned limit = sizeof(db) / sizeof(db[0]) - 1; once = 1; - for (i=0; i < sizeof (db) / sizeof(db[0]) - 1; ++i) - gcc_assert (iasm_op_clobber_comp (&db[i+1], &db[i]) >= 0); + + for (i=0; i < limit; ++i) + gcc_assert (iasm_op_clobber_comp (&db[i+1], &db[i]) >= 0); } #endif 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=43358&r1=43357&r2=43358&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Thu Oct 25 13:47:23 2007 @@ -6304,7 +6304,13 @@ // The lvalue is just the address. return Convert(TREE_OPERAND(exp, 0)); case COMPOUND_LITERAL_EXPR: // FIXME: not gimple - defined by C front-end - return EmitLV(COMPOUND_LITERAL_EXPR_DECL(exp)); + /* This used to read + return EmitLV(COMPOUND_LITERAL_EXPR_DECL(exp)); + but gcc warns about that and there doesn't seem to be any way to stop it + with casts or the like. The following is equivalent with no checking + (since we know TREE_CODE(exp) is COMPOUND_LITERAL_EXPR the checking + doesn't accomplish anything anyway). */ + return EmitLV(DECL_EXPR_DECL (TREE_OPERAND (exp, 0))); } } From evan.cheng at apple.com Thu Oct 25 13:51:27 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 Oct 2007 11:51:27 -0700 Subject: [llvm-commits] [llvm] r43353 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp In-Reply-To: <200710251823.l9PINkSd005059@zion.cs.uiuc.edu> References: <200710251823.l9PINkSd005059@zion.cs.uiuc.edu> Message-ID: Hi Bill, Is the XXX marker used anywhere else in llvm? I think we use FIXME or TODO everywhere else. It's not that important, but it makes sense to be somewhere consistent so we can grep it later. Please also add an entry to README.txt under CodeGen. Evan On Oct 25, 2007, at 11:23 AM, Bill Wendling wrote: > Author: void > Date: Thu Oct 25 13:23:45 2007 > New Revision: 43353 > > URL: http://llvm.org/viewvc/llvm-project?rev=43353&view=rev > Log: > Added comment explaining why we are doing this check. > > Modified: > llvm/trunk/lib/CodeGen/BranchFolding.cpp > > Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=43353&r1=43352&r2=43353&view=diff > > = > = > = > = > = > = > = > = > ====================================================================== > --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) > +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Thu Oct 25 13:23:45 2007 > @@ -272,6 +272,11 @@ > while (I1 != MBB1->begin() && I2 != MBB2->begin()) { > --I1; --I2; > if (!I1->isIdenticalTo(I2) || > + // XXX: This check is dubious. It's used to get around a > problem where > + // people incorrectly expect inline asm directives to > remain in the same > + // relative order. This is untenable because normal compiler > + // optimizations (like this one) may reorder and/or merge > these > + // directives. > I1->getOpcode() == TargetInstrInfo::INLINEASM) { > ++I1; ++I2; > break; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From isanbard at gmail.com Thu Oct 25 14:49:32 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 25 Oct 2007 19:49:32 -0000 Subject: [llvm-commits] [llvm] r43359 - in /llvm/trunk/lib/CodeGen: BranchFolding.cpp README.txt Message-ID: <200710251949.l9PJnWoP011072@zion.cs.uiuc.edu> Author: void Date: Thu Oct 25 14:49:32 2007 New Revision: 43359 URL: http://llvm.org/viewvc/llvm-project?rev=43359&view=rev Log: Changed XXX to FIXME, and added comment to the README file Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/README.txt Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=43359&r1=43358&r2=43359&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Thu Oct 25 14:49:32 2007 @@ -272,7 +272,7 @@ while (I1 != MBB1->begin() && I2 != MBB2->begin()) { --I1; --I2; if (!I1->isIdenticalTo(I2) || - // XXX: This check is dubious. It's used to get around a problem where + // FIXME: This check is dubious. It's used to get around a problem where // people incorrectly expect inline asm directives to remain in the same // relative order. This is untenable because normal compiler // optimizations (like this one) may reorder and/or merge these Modified: llvm/trunk/lib/CodeGen/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/README.txt?rev=43359&r1=43358&r2=43359&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/README.txt (original) +++ llvm/trunk/lib/CodeGen/README.txt Thu Oct 25 14:49:32 2007 @@ -179,3 +179,11 @@ The ocaml frametable structure supports liveness information. It would be good to support it. + +//===---------------------------------------------------------------------===// + +The FIXME in ComputeCommonTailLength in BranchFolding.cpp needs to be +revisited. The check is there to work around a misuse of directives in inline +assembly. + +//===---------------------------------------------------------------------===// From isanbard at gmail.com Thu Oct 25 14:50:20 2007 From: isanbard at gmail.com (Bill Wendling) Date: Thu, 25 Oct 2007 12:50:20 -0700 Subject: [llvm-commits] [llvm] r43353 - /llvm/trunk/lib/CodeGen/BranchFolding.cpp In-Reply-To: References: <200710251823.l9PINkSd005059@zion.cs.uiuc.edu> Message-ID: <16e5fdf90710251250k229f61b4ld43564b790b9b7b@mail.gmail.com> Hi Evan, > Is the XXX marker used anywhere else in llvm? I think we use FIXME or > TODO everywhere else. It's not that important, but it makes sense to > be somewhere consistent so we can grep it later. > I don't think it's used elsewhere. I just changed it to a FIXME and added the README.txt entry too. :-) -bw > Please also add an entry to README.txt under CodeGen. > From dalej at apple.com Thu Oct 25 16:54:43 2007 From: dalej at apple.com (Dale Johannesen) Date: Thu, 25 Oct 2007 21:54:43 -0000 Subject: [llvm-commits] [llvm] r43364 - /llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp Message-ID: <200710252154.l9PLshes017910@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 25 16:54:43 2007 New Revision: 43364 URL: http://llvm.org/viewvc/llvm-project?rev=43364&view=rev Log: Support non-POSIX hosts by removing use of strncasecmp. Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp Modified: llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp?rev=43364&r1=43363&r2=43364&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetAsmInfo.cpp Thu Oct 25 16:54:43 2007 @@ -162,7 +162,14 @@ } /// ARM-specific version of TargetAsmInfo::getInlineAsmLength. -unsigned ARMTargetAsmInfo::getInlineAsmLength(const char *Str) const { +unsigned ARMTargetAsmInfo::getInlineAsmLength(const char *s) const { + // Make a lowercase-folded version of s for counting purposes. + char *q, *s_copy = (char *)malloc(strlen(s) + 1); + strcpy(s_copy, s); + for (q=s_copy; *q; q++) + *q = tolower(*q); + const char *Str = s_copy; + // Count the number of bytes in the asm. bool atInsnStart = true; bool inTextSection = true; @@ -187,65 +194,66 @@ else if (*Str == '.' && Subtarget->isTargetDarwin()) { // Directive. atInsnStart = false; + // Some change the section, but don't generate code. - if (strncasecmp(Str, ".literal4", strlen(".literal4"))==0 || - strncasecmp(Str, ".literal8", strlen(".literal8"))==0 || - strncasecmp(Str, ".const", strlen(".const"))==0 || - strncasecmp(Str, ".constructor", strlen(".constructor"))==0 || - strncasecmp(Str, ".cstring", strlen(".cstring"))==0 || - strncasecmp(Str, ".data", strlen(".data"))==0 || - strncasecmp(Str, ".destructor", strlen(".destructor"))==0 || - strncasecmp(Str, ".fvmlib_init0", strlen(".fvmlib_init0"))==0 || - strncasecmp(Str, ".fvmlib_init1", strlen(".fvmlib_init1"))==0 || - strncasecmp(Str, ".mod_init_func", strlen(".mod_init_func"))==0 || - strncasecmp(Str, ".mod_term_func", strlen(".mod_term_func"))==0 || - strncasecmp(Str, ".picsymbol_stub", strlen(".picsymbol_stub"))==0 || - strncasecmp(Str, ".symbol_stub", strlen(".symbol_stub"))==0 || - strncasecmp(Str, ".static_data", strlen(".static_data"))==0 || - strncasecmp(Str, ".section", strlen(".section"))==0 || - strncasecmp(Str, ".lazy_symbol_pointer", strlen(".lazy_symbol_pointer"))==0 || - strncasecmp(Str, ".non_lazy_symbol_pointer", strlen(".non_lazy_symbol_pointer"))==0 || - strncasecmp(Str, ".dyld", strlen(".dyld"))==0 || - strncasecmp(Str, ".const_data", strlen(".const_data"))==0 || - strncasecmp(Str, ".objc", strlen(".objc"))==0 || //// many directives - strncasecmp(Str, ".static_const", strlen(".static_const"))==0) + if (strncmp(Str, ".literal4", strlen(".literal4"))==0 || + strncmp(Str, ".literal8", strlen(".literal8"))==0 || + strncmp(Str, ".const", strlen(".const"))==0 || + strncmp(Str, ".constructor", strlen(".constructor"))==0 || + strncmp(Str, ".cstring", strlen(".cstring"))==0 || + strncmp(Str, ".data", strlen(".data"))==0 || + strncmp(Str, ".destructor", strlen(".destructor"))==0 || + strncmp(Str, ".fvmlib_init0", strlen(".fvmlib_init0"))==0 || + strncmp(Str, ".fvmlib_init1", strlen(".fvmlib_init1"))==0 || + strncmp(Str, ".mod_init_func", strlen(".mod_init_func"))==0 || + strncmp(Str, ".mod_term_func", strlen(".mod_term_func"))==0 || + strncmp(Str, ".picsymbol_stub", strlen(".picsymbol_stub"))==0 || + strncmp(Str, ".symbol_stub", strlen(".symbol_stub"))==0 || + strncmp(Str, ".static_data", strlen(".static_data"))==0 || + strncmp(Str, ".section", strlen(".section"))==0 || + strncmp(Str, ".lazy_symbol_pointer", strlen(".lazy_symbol_pointer"))==0 || + strncmp(Str, ".non_lazy_symbol_pointer", strlen(".non_lazy_symbol_pointer"))==0 || + strncmp(Str, ".dyld", strlen(".dyld"))==0 || + strncmp(Str, ".const_data", strlen(".const_data"))==0 || + strncmp(Str, ".objc", strlen(".objc"))==0 || //// many directives + strncmp(Str, ".static_const", strlen(".static_const"))==0) inTextSection=false; - else if (strncasecmp(Str, ".text", strlen(".text"))==0) + else if (strncmp(Str, ".text", strlen(".text"))==0) inTextSection = true; // Some can't really be handled without implementing significant pieces // of an assembler. Others require dynamic adjustment of block sizes in // AdjustBBOffsetsAfter; it's a big compile-time speed hit to check every // instruction in there, and none of these are currently used in the kernel. - else if (strncasecmp(Str, ".macro", strlen(".macro"))==0 || - strncasecmp(Str, ".if", strlen(".if"))==0 || - strncasecmp(Str, ".align", strlen(".align"))==0 || - strncasecmp(Str, ".fill", strlen(".fill"))==0 || - strncasecmp(Str, ".space", strlen(".space"))==0 || - strncasecmp(Str, ".zerofill", strlen(".zerofill"))==0 || - strncasecmp(Str, ".p2align", strlen(".p2align"))==0 || - strncasecmp(Str, ".p2alignw", strlen(".p2alignw"))==0 || - strncasecmp(Str, ".p2alignl", strlen(".p2alignl"))==0 || - strncasecmp(Str, ".align32", strlen(".p2align32"))==0 || - strncasecmp(Str, ".include", strlen(".include"))==0) + else if (strncmp(Str, ".macro", strlen(".macro"))==0 || + strncmp(Str, ".if", strlen(".if"))==0 || + strncmp(Str, ".align", strlen(".align"))==0 || + strncmp(Str, ".fill", strlen(".fill"))==0 || + strncmp(Str, ".space", strlen(".space"))==0 || + strncmp(Str, ".zerofill", strlen(".zerofill"))==0 || + strncmp(Str, ".p2align", strlen(".p2align"))==0 || + strncmp(Str, ".p2alignw", strlen(".p2alignw"))==0 || + strncmp(Str, ".p2alignl", strlen(".p2alignl"))==0 || + strncmp(Str, ".align32", strlen(".p2align32"))==0 || + strncmp(Str, ".include", strlen(".include"))==0) cerr << "Directive " << Str << " in asm may lead to invalid offsets for" << " constant pools (the assembler will tell you if this happens).\n"; // Some generate code, but this is only interesting in the text section. else if (inTextSection) { - if (strncasecmp(Str, ".long", strlen(".long"))==0) + if (strncmp(Str, ".long", strlen(".long"))==0) Length += 4*countArguments(Str+strlen(".long")); - else if (strncasecmp(Str, ".short", strlen(".short"))==0) + else if (strncmp(Str, ".short", strlen(".short"))==0) Length += 2*countArguments(Str+strlen(".short")); - else if (strncasecmp(Str, ".byte", strlen(".byte"))==0) + else if (strncmp(Str, ".byte", strlen(".byte"))==0) Length += 1*countArguments(Str+strlen(".byte")); - else if (strncasecmp(Str, ".single", strlen(".single"))==0) + else if (strncmp(Str, ".single", strlen(".single"))==0) Length += 4*countArguments(Str+strlen(".single")); - else if (strncasecmp(Str, ".double", strlen(".double"))==0) + else if (strncmp(Str, ".double", strlen(".double"))==0) Length += 8*countArguments(Str+strlen(".double")); - else if (strncasecmp(Str, ".quad", strlen(".quad"))==0) + else if (strncmp(Str, ".quad", strlen(".quad"))==0) Length += 16*countArguments(Str+strlen(".quad")); - else if (strncasecmp(Str, ".ascii", strlen(".ascii"))==0) + else if (strncmp(Str, ".ascii", strlen(".ascii"))==0) Length += countString(Str+strlen(".ascii")); - else if (strncasecmp(Str, ".asciz", strlen(".asciz"))==0) + else if (strncmp(Str, ".asciz", strlen(".asciz"))==0) Length += countString(Str+strlen(".asciz"))+1; } } else if (inTextSection) { @@ -253,7 +261,7 @@ atInsnStart = false; if (Subtarget->isThumb()) { // BL and BLX are 4 bytes, all others 2. - if (strncasecmp(Str, "blx", strlen("blx"))==0) { + if (strncmp(Str, "blx", strlen("blx"))==0) { const char* p = Str+3; while (*p && isspace(*p)) p++; @@ -261,7 +269,7 @@ Length += 2; // BLX reg else Length += 4; // BLX non-reg - } else if (strncasecmp(Str, "bl", strlen("bl"))==0) + } else if (strncmp(Str, "bl", strlen("bl"))==0) Length += 4; // BL else Length += 2; // Thumb anything else @@ -273,5 +281,6 @@ if (*Str == '\n' || *Str == SeparatorChar) atInsnStart = true; } + free(s_copy); return Length; } From evan.cheng at apple.com Thu Oct 25 17:45:20 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Thu, 25 Oct 2007 22:45:20 -0000 Subject: [llvm-commits] [llvm] r43367 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200710252245.l9PMjLpG021073@zion.cs.uiuc.edu> Author: evancheng Date: Thu Oct 25 17:45:20 2007 New Revision: 43367 URL: http://llvm.org/viewvc/llvm-project?rev=43367&view=rev Log: Do not rewrite compare instruction using iv of a different stride if the new stride may be rewritten using the stride of the compare instruction. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43367&r1=43366&r2=43367&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Oct 25 17:45:20 2007 @@ -177,11 +177,17 @@ void OptimizeIndvars(Loop *L); bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, const SCEVHandle *&CondStride); + bool RequiresTypeConversion(const Type *Ty, const Type *NewTy); unsigned CheckForIVReuse(bool, const SCEVHandle&, IVExpr&, const Type*, const std::vector& UsersToProcess); bool ValidStride(bool, int64_t, const std::vector& UsersToProcess); + SCEVHandle CollectIVUsers(const SCEVHandle &Stride, + IVUsersOfOneStride &Uses, + Loop *L, + bool &AllUsesAreAddresses, + std::vector &UsersToProcess); void StrengthReduceStridedIVUsers(const SCEVHandle &Stride, IVUsersOfOneStride &Uses, Loop *L, bool isOnlyStride); @@ -972,6 +978,19 @@ return true; } +/// RequiresTypeConversion - Returns true if converting Ty to NewTy is not +/// a nop. +bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty, + const Type *NewTy) { + if (Ty == NewTy) + return false; + return (!Ty->canLosslesslyBitCastTo(NewTy) && + !(isa(NewTy) && + Ty->canLosslesslyBitCastTo(UIntPtrTy)) && + !(isa(Ty) && + NewTy->canLosslesslyBitCastTo(UIntPtrTy))); +} + /// CheckForIVReuse - Returns the multiple if the stride is the multiple /// of a previous stride and it is a legal value for the target addressing /// mode scale component and optional base reg. This allows the users of @@ -1001,7 +1020,8 @@ IE = SI->second.IVs.end(); II != IE; ++II) // FIXME: Only handle base == 0 for now. // Only reuse previous IV if it would not require a type conversion. - if (isZero(II->Base) && II->Base->getType() == Ty) { + if (isZero(II->Base) && + !RequiresTypeConversion(II->Base->getType(),Ty)) { IV = *II; return Scale; } @@ -1030,23 +1050,16 @@ return SC->getValue()->getValue().isNegative(); } -/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single -/// stride of IV. All of the users may have different starting values, and this -/// may not be the only stride (we know it is if isOnlyStride is true). -void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, - IVUsersOfOneStride &Uses, - Loop *L, - bool isOnlyStride) { - // If all the users are moved to another stride, then there is nothing to do. - if (Uses.Users.size() == 0) - return; - - // Transform our list of users and offsets to a bit more complex table. In - // this new vector, each 'BasedUser' contains 'Base' the base of the - // strided accessas well as the old information from Uses. We progressively - // move information from the Base field to the Imm field, until we eventually - // have the full access expression to rewrite the use. - std::vector UsersToProcess; +// CollectIVUsers - Transform our list of users and offsets to a bit more +// complex table. In this new vector, each 'BasedUser' contains 'Base' the base +// of the strided accessas well as the old information from Uses. We +// progressively move information from the Base field to the Imm field, until +// we eventually have the full access expression to rewrite the use. +SCEVHandle LoopStrengthReduce::CollectIVUsers(const SCEVHandle &Stride, + IVUsersOfOneStride &Uses, + Loop *L, + bool &AllUsesAreAddresses, + std::vector &UsersToProcess) { UsersToProcess.reserve(Uses.Users.size()); for (unsigned i = 0, e = Uses.Users.size(); i != e; ++i) { UsersToProcess.push_back(BasedUser(Uses.Users[i], SE)); @@ -1070,17 +1083,6 @@ SCEVHandle CommonExprs = RemoveCommonExpressionsFromUseBases(UsersToProcess, SE); - // If we managed to find some expressions in common, we'll need to carry - // their value in a register and add it in for each use. This will take up - // a register operand, which potentially restricts what stride values are - // valid. - bool HaveCommonExprs = !isZero(CommonExprs); - - // Keep track if every use in UsersToProcess is an address. If they all are, - // we may be able to rewrite the entire collection of them in terms of a - // smaller-stride IV. - bool AllUsesAreAddresses = true; - // Next, figure out what we can represent in the immediate fields of // instructions. If we can represent anything there, move it to the imm // fields of the BasedUsers. We do this so that it increases the commonality @@ -1136,6 +1138,40 @@ } } + return CommonExprs; +} + +/// StrengthReduceStridedIVUsers - Strength reduce all of the users of a single +/// stride of IV. All of the users may have different starting values, and this +/// may not be the only stride (we know it is if isOnlyStride is true). +void LoopStrengthReduce::StrengthReduceStridedIVUsers(const SCEVHandle &Stride, + IVUsersOfOneStride &Uses, + Loop *L, + bool isOnlyStride) { + // If all the users are moved to another stride, then there is nothing to do. + if (Uses.Users.size() == 0) + return; + + // Keep track if every use in UsersToProcess is an address. If they all are, + // we may be able to rewrite the entire collection of them in terms of a + // smaller-stride IV. + bool AllUsesAreAddresses = true; + + // Transform our list of users and offsets to a bit more complex table. In + // this new vector, each 'BasedUser' contains 'Base' the base of the + // strided accessas well as the old information from Uses. We progressively + // move information from the Base field to the Imm field, until we eventually + // have the full access expression to rewrite the use. + std::vector UsersToProcess; + SCEVHandle CommonExprs = CollectIVUsers(Stride, Uses, L, AllUsesAreAddresses, + UsersToProcess); + + // If we managed to find some expressions in common, we'll need to carry + // their value in a register and add it in for each use. This will take up + // a register operand, which potentially restricts what stride values are + // valid. + bool HaveCommonExprs = !isZero(CommonExprs); + // If all uses are addresses, check if it is possible to reuse an IV with a // stride that is a factor of this stride. And that the multiple is a number // that can be encoded in the scale field of the target addressing mode. And @@ -1424,9 +1460,6 @@ if (StrideOrder.size() < 2 || IVUsesByStride[*CondStride].Users.size() != 1) return Cond; - // FIXME: loosen this restriction? - if (!isa(CondUse->Offset)) - return Cond; const SCEVConstant *SC = dyn_cast(*CondStride); if (!SC) return Cond; ConstantInt *C = dyn_cast(Cond->getOperand(1)); @@ -1478,11 +1511,22 @@ continue; } - // FIXME: allow reuse of iv of a smaller type? NewCmpTy = NewIncV->getType(); - if (!CmpTy->canLosslesslyBitCastTo(NewCmpTy) && - !(isa(NewCmpTy) && - CmpTy->canLosslesslyBitCastTo(UIntPtrTy))) { + if (RequiresTypeConversion(CmpTy, NewCmpTy)) { + // FIXME: allow reuse of iv of a smaller type? + NewCmpVal = CmpVal; + continue; + } + + bool AllUsesAreAddresses = true; + std::vector UsersToProcess; + SCEVHandle CommonExprs = CollectIVUsers(SI->first, SI->second, L, + AllUsesAreAddresses, + UsersToProcess); + // Avoid rewriting the compare instruction with an iv of new stride + // if it's likely the new stride uses will be rewritten using the + if (AllUsesAreAddresses && + ValidStride(!isZero(CommonExprs), Scale, UsersToProcess)) { NewCmpVal = CmpVal; continue; } From hartmut.kaiser at gmail.com Thu Oct 25 17:56:14 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Thu, 25 Oct 2007 22:56:14 -0000 Subject: [llvm-commits] [llvm] r43368 - /llvm/trunk/win32/Bitcode/Bitcode.vcproj Message-ID: <200710252256.l9PMuEuQ021717@zion.cs.uiuc.edu> Author: hkaiser Date: Thu Oct 25 17:56:13 2007 New Revision: 43368 URL: http://llvm.org/viewvc/llvm-project?rev=43368&view=rev Log: Updated VC++ build system Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj Modified: llvm/trunk/win32/Bitcode/Bitcode.vcproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/win32/Bitcode/Bitcode.vcproj?rev=43368&r1=43367&r2=43368&view=diff ============================================================================== --- llvm/trunk/win32/Bitcode/Bitcode.vcproj (original) +++ llvm/trunk/win32/Bitcode/Bitcode.vcproj Thu Oct 25 17:56:13 2007 @@ -212,6 +212,10 @@ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -224,6 +228,10 @@ > + + @@ -231,6 +239,18 @@ RelativePath="..\..\include\llvm\Bitcode\ReaderWriter.h" > + + + + + + From hartmut.kaiser at gmail.com Thu Oct 25 17:57:48 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Thu, 25 Oct 2007 22:57:48 -0000 Subject: [llvm-commits] [llvm] r43369 - /llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Message-ID: <200710252257.l9PMvmE2021790@zion.cs.uiuc.edu> Author: hkaiser Date: Thu Oct 25 17:57:48 2007 New Revision: 43369 URL: http://llvm.org/viewvc/llvm-project?rev=43369&view=rev Log: Disambiguated variable name to comply with VC++'s archaic variable scoping rules. Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43369&r1=43368&r2=43369&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Thu Oct 25 17:57:48 2007 @@ -122,13 +122,13 @@ void Deserializer::BackpatchPointers() { for (MapTy::iterator I=BPatchMap.begin(),E=BPatchMap.end(); I!=E; ++I) { - BPatchEntry& E = I->second; - assert (E.Ptr && "No pointer found for backpatch."); + BPatchEntry& Entry = I->second; + assert (Entry.Ptr && "No pointer found for backpatch."); - for (BPatchNode* N = E.Head; N != NULL; N = N->Next) - N->PtrRef = E.Ptr; + for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next) + N->PtrRef = Entry.Ptr; - E.Head = NULL; + Entry.Head = NULL; } Allocator.Reset(); From hartmut.kaiser at gmail.com Thu Oct 25 18:15:32 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Thu, 25 Oct 2007 23:15:32 -0000 Subject: [llvm-commits] [llvm] r43372 - /llvm/trunk/lib/Support/APFloat.cpp Message-ID: <200710252315.l9PNFWIk022664@zion.cs.uiuc.edu> Author: hkaiser Date: Thu Oct 25 18:15:31 2007 New Revision: 43372 URL: http://llvm.org/viewvc/llvm-project?rev=43372&view=rev Log: Clarified operator precedence. Silenced VC++ warning. Modified: llvm/trunk/lib/Support/APFloat.cpp Modified: llvm/trunk/lib/Support/APFloat.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/APFloat.cpp?rev=43372&r1=43371&r2=43372&view=diff ============================================================================== --- llvm/trunk/lib/Support/APFloat.cpp (original) +++ llvm/trunk/lib/Support/APFloat.cpp Thu Oct 25 18:15:31 2007 @@ -1230,7 +1230,7 @@ case convolve(fcInfinity, fcInfinity): /* Differently signed infinities can only be validly subtracted. */ - if(sign ^ rhs.sign != subtract) { + if((sign ^ rhs.sign) != subtract) { makeNaN(); return opInvalidOp; } @@ -1252,7 +1252,7 @@ /* Determine if the operation on the absolute values is effectively an addition or subtraction. */ - subtract ^= (sign ^ rhs.sign); + subtract ^= (sign ^ rhs.sign) ? true : false; /* Are we bigger exponent-wise than the RHS? */ bits = exponent - rhs.exponent; From kremenek at apple.com Thu Oct 25 18:40:35 2007 From: kremenek at apple.com (Ted Kremenek) Date: Thu, 25 Oct 2007 23:40:35 -0000 Subject: [llvm-commits] [llvm] r43373 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h lib/Bitcode/Reader/Deserialize.cpp Message-ID: <200710252340.l9PNeZuu023787@zion.cs.uiuc.edu> Author: kremenek Date: Thu Oct 25 18:40:35 2007 New Revision: 43373 URL: http://llvm.org/viewvc/llvm-project?rev=43373&view=rev Log: Updated backpatching during object deserialization to support "smart" pointers that employ unused bits in a pointer to store extra data. Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43373&r1=43372&r2=43373&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Thu Oct 25 18:40:35 2007 @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/DataTypes.h" #include namespace llvm { @@ -40,8 +41,11 @@ struct BPatchNode { BPatchNode* const Next; - void*& PtrRef; - BPatchNode(BPatchNode* n, void*& pref) : Next(n), PtrRef(pref) {} + uintptr_t& PtrRef; + BPatchNode(BPatchNode* n, void*& pref) + : Next(n), PtrRef(reinterpret_cast(pref)) { + PtrRef = 0; + } }; struct BPatchEntry { Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43373&r1=43372&r2=43373&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Thu Oct 25 18:40:35 2007 @@ -126,7 +126,9 @@ assert (Entry.Ptr && "No pointer found for backpatch."); for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next) - N->PtrRef = Entry.Ptr; + // Bitwise-OR in the pointer to support "smart" pointers that use + // unused bits to store extra data. + N->PtrRef |= reinterpret_cast(Entry.Ptr); Entry.Head = NULL; } From hartmut.kaiser at gmail.com Thu Oct 25 18:49:14 2007 From: hartmut.kaiser at gmail.com (Hartmut Kaiser) Date: Thu, 25 Oct 2007 23:49:14 -0000 Subject: [llvm-commits] [llvm] r43374 - /llvm/trunk/lib/Analysis/IPA/Andersens.cpp Message-ID: <200710252349.l9PNnEF3024143@zion.cs.uiuc.edu> Author: hkaiser Date: Thu Oct 25 18:49:14 2007 New Revision: 43374 URL: http://llvm.org/viewvc/llvm-project?rev=43374&view=rev Log: Silenced a VC++ warning. 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=43374&r1=43373&r2=43374&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/IPA/Andersens.cpp (original) +++ llvm/trunk/lib/Analysis/IPA/Andersens.cpp Thu Oct 25 18:49:14 2007 @@ -112,7 +112,7 @@ class VISIBILITY_HIDDEN Andersens : public ModulePass, public AliasAnalysis, private InstVisitor { - class Node; + struct Node; /// Constraint - Objects of this structure are used to represent the various /// constraints identified by the algorithm. The constraints are 'copy', From evan.cheng at apple.com Thu Oct 25 20:56:12 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 Oct 2007 01:56:12 -0000 Subject: [llvm-commits] [llvm] r43375 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/X86/README.txt lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce5.ll Message-ID: <200710260156.l9Q1uCfu028601@zion.cs.uiuc.edu> Author: evancheng Date: Thu Oct 25 20:56:11 2007 New Revision: 43375 URL: http://llvm.org/viewvc/llvm-project?rev=43375&view=rev Log: Loosen up iv reuse to allow reuse of the same stride but a larger type when truncating from the larger type to smaller type is free. e.g. Turns this loop: LBB1_1: # entry.bb_crit_edge xorl %ecx, %ecx xorw %dx, %dx movw %dx, %si LBB1_2: # bb movl L_X$non_lazy_ptr, %edi movw %si, (%edi) movl L_Y$non_lazy_ptr, %edi movw %dx, (%edi) addw $4, %dx incw %si incl %ecx cmpl %eax, %ecx jne LBB1_2 # bb into LBB1_1: # entry.bb_crit_edge xorl %ecx, %ecx xorw %dx, %dx LBB1_2: # bb movl L_X$non_lazy_ptr, %esi movw %cx, (%esi) movl L_Y$non_lazy_ptr, %esi movw %dx, (%esi) addw $4, %dx incl %ecx cmpl %eax, %ecx jne LBB1_2 # bb Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll Modified: llvm/trunk/include/llvm/Target/TargetLowering.h llvm/trunk/lib/Target/X86/README.txt llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/include/llvm/Target/TargetLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=43375&r1=43374&r2=43375&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) +++ llvm/trunk/include/llvm/Target/TargetLowering.h Thu Oct 25 20:56:11 2007 @@ -104,7 +104,7 @@ /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of /// srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } - + /// getSetCCResultTy - Return the ValueType of the result of setcc operations. /// MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; } @@ -994,6 +994,13 @@ /// TODO: Handle pre/postinc as well. virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty) const; + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const { + return false; + } + //===--------------------------------------------------------------------===// // Div utility functions // Modified: llvm/trunk/lib/Target/X86/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=43375&r1=43374&r2=43375&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Thu Oct 25 20:56:11 2007 @@ -339,20 +339,18 @@ for (i = 0; i < N; i++) { X = i; Y = i*4; } } -LBB1_1: #bb.preheader - xorl %ecx, %ecx - xorw %dx, %dx -LBB1_2: #bb - movl L_X$non_lazy_ptr, %esi - movw %dx, (%esi) - movw %dx, %si - shlw $2, %si - movl L_Y$non_lazy_ptr, %edi - movw %si, (%edi) - incl %ecx - incw %dx - cmpl %eax, %ecx - jne LBB1_2 #bb +LBB1_1: # entry.bb_crit_edge + xorl %ecx, %ecx + xorw %dx, %dx +LBB1_2: # bb + movl L_X$non_lazy_ptr, %esi + movw %cx, (%esi) + movl L_Y$non_lazy_ptr, %esi + movw %dx, (%esi) + addw $4, %dx + incl %ecx + cmpl %eax, %ecx + jne LBB1_2 # bb vs. @@ -367,11 +365,7 @@ cmpl %edx, %edi jne L4 -There are 3 issues: - -1. Lack of post regalloc LICM. -2. LSR unable to reused IV for a different type (i16 vs. i32) even though - the cast would be free. +This is due to the lack of post regalloc LICM. //===---------------------------------------------------------------------===// Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=43375&r1=43374&r2=43375&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Oct 25 20:56:11 2007 @@ -5122,6 +5122,13 @@ } +bool X86TargetLowering::isTruncateFree(const Type *Ty1, const Type *Ty2) const { + if (!Ty1->isInteger() || !Ty2->isInteger()) + return false; + return Ty1->getPrimitiveSizeInBits() > Ty2->getPrimitiveSizeInBits(); +} + + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=43375&r1=43374&r2=43375&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Thu Oct 25 20:56:11 2007 @@ -359,6 +359,11 @@ /// by AM is legal for this target, for a load/store of the specified type. virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const; + /// isShuffleMaskLegal - Targets can use this to indicate that they only /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43375&r1=43374&r2=43375&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Oct 25 20:56:11 2007 @@ -178,7 +178,7 @@ bool FindIVForUser(ICmpInst *Cond, IVStrideUse *&CondUse, const SCEVHandle *&CondStride); bool RequiresTypeConversion(const Type *Ty, const Type *NewTy); - unsigned CheckForIVReuse(bool, const SCEVHandle&, + unsigned CheckForIVReuse(bool, bool, const SCEVHandle&, IVExpr&, const Type*, const std::vector& UsersToProcess); bool ValidStride(bool, int64_t, @@ -980,15 +980,17 @@ /// RequiresTypeConversion - Returns true if converting Ty to NewTy is not /// a nop. -bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty, - const Type *NewTy) { - if (Ty == NewTy) +bool LoopStrengthReduce::RequiresTypeConversion(const Type *Ty1, + const Type *Ty2) { + if (Ty1 == Ty2) return false; - return (!Ty->canLosslesslyBitCastTo(NewTy) && - !(isa(NewTy) && - Ty->canLosslesslyBitCastTo(UIntPtrTy)) && - !(isa(Ty) && - NewTy->canLosslesslyBitCastTo(UIntPtrTy))); + if (TLI && TLI->isTruncateFree(Ty1, Ty2)) + return false; + return (!Ty1->canLosslesslyBitCastTo(Ty2) && + !(isa(Ty2) && + Ty1->canLosslesslyBitCastTo(UIntPtrTy)) && + !(isa(Ty1) && + Ty2->canLosslesslyBitCastTo(UIntPtrTy))); } /// CheckForIVReuse - Returns the multiple if the stride is the multiple @@ -997,20 +999,23 @@ /// this stride to be rewritten as prev iv * factor. It returns 0 if no /// reuse is possible. unsigned LoopStrengthReduce::CheckForIVReuse(bool HasBaseReg, + bool AllUsesAreAddresses, const SCEVHandle &Stride, IVExpr &IV, const Type *Ty, const std::vector& UsersToProcess) { if (SCEVConstant *SC = dyn_cast(Stride)) { int64_t SInt = SC->getValue()->getSExtValue(); - if (SInt == 1) return 0; - for (std::map::iterator SI= IVsByStride.begin(), SE = IVsByStride.end(); SI != SE; ++SI) { int64_t SSInt = cast(SI->first)->getValue()->getSExtValue(); - if (SInt != -SSInt && + if (SI->first != Stride && (unsigned(abs(SInt)) < SSInt || (SInt % SSInt) != 0)) continue; int64_t Scale = SInt / SSInt; + // When scale is 1, we don't need to worry about whether the + // multiplication can be folded into the addressing mode. + if (!AllUsesAreAddresses && Scale != 1) + continue; // Check that this stride is valid for all the types used for loads and // stores; if it can be used for some and not others, we might as well use // the original stride everywhere, since we have to create the IV for it @@ -1021,7 +1026,7 @@ // FIXME: Only handle base == 0 for now. // Only reuse previous IV if it would not require a type conversion. if (isZero(II->Base) && - !RequiresTypeConversion(II->Base->getType(),Ty)) { + !RequiresTypeConversion(II->Base->getType(), Ty)) { IV = *II; return Scale; } @@ -1183,10 +1188,9 @@ SE->getIntegerSCEV(0, Type::Int32Ty), 0, 0); unsigned RewriteFactor = 0; - if (AllUsesAreAddresses) - RewriteFactor = CheckForIVReuse(HaveCommonExprs, Stride, ReuseIV, - CommonExprs->getType(), - UsersToProcess); + RewriteFactor = CheckForIVReuse(HaveCommonExprs, AllUsesAreAddresses, + Stride, ReuseIV, CommonExprs->getType(), + UsersToProcess); if (RewriteFactor != 0) { DOUT << "BASED ON IV of STRIDE " << *ReuseIV.Stride << " and BASE " << *ReuseIV.Base << " :\n"; Added: llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll?rev=43375&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll (added) +++ llvm/trunk/test/CodeGen/X86/loop-strength-reduce5.ll Thu Oct 25 20:56:11 2007 @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep inc | count 1 + + at X = weak global i16 0 ; [#uses=1] + at Y = weak global i16 0 ; [#uses=1] + +define void @foo(i32 %N) { +entry: + %tmp1019 = icmp sgt i32 %N, 0 ; [#uses=1] + br i1 %tmp1019, label %bb, label %return + +bb: ; preds = %bb, %entry + %i.014.0 = phi i32 [ 0, %entry ], [ %indvar.next, %bb ] ; [#uses=2] + %tmp1 = trunc i32 %i.014.0 to i16 ; [#uses=2] + volatile store i16 %tmp1, i16* @X, align 2 + %tmp34 = shl i16 %tmp1, 2 ; [#uses=1] + volatile store i16 %tmp34, i16* @Y, align 2 + %indvar.next = add i32 %i.014.0, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, %N ; [#uses=1] + br i1 %exitcond, label %return, label %bb + +return: ; preds = %bb, %entry + ret void +} From dalej at apple.com Thu Oct 25 21:43:15 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 26 Oct 2007 02:43:15 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43376 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200710260243.l9Q2hFqW030276@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 25 21:43:15 2007 New Revision: 43376 URL: http://llvm.org/viewvc/llvm-project?rev=43376&view=rev Log: (inline asm) don't canonicalize single-hard-reg constraints; they're already canonical. gcc.apple/443946.c 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=43376&r1=43375&r2=43376&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Thu Oct 25 21:43:15 2007 @@ -3962,6 +3962,7 @@ if (IsInOut) ++NumInOut, ++NumInputs; + std::string SimplifiedConstraint; // If this output register is pinned to a machine register, use that machine // register instead of the specified constraint. if (TREE_CODE(Operand) == VAR_DECL && DECL_HARD_REGISTER(Operand)) { @@ -3975,14 +3976,14 @@ memcpy(NewConstraint+2, reg_names[RegNum], RegNameLen); NewConstraint[RegNameLen+2] = '}'; NewConstraint[RegNameLen+3] = 0; - Constraint = NewConstraint; + SimplifiedConstraint = NewConstraint; } + } else { + // If we can simplify the constraint into something else, do so now. This + // avoids LLVM having to know about all the (redundant) GCC constraints. + SimplifiedConstraint = CanonicalizeConstraint(Constraint+1); } - // If we can simplify the constraint into something else, do so now. This - // avoids LLVM having to know about all the (redundant) GCC constraints. - std::string SimplifiedConstraint = CanonicalizeConstraint(Constraint+1); - LValue Dest = EmitLV(Operand); const Type *DestValTy = cast(Dest.Ptr->getType())->getElementType(); From gordonhenriksen at mac.com Thu Oct 25 22:03:51 2007 From: gordonhenriksen at mac.com (Gordon Henriksen) Date: Fri, 26 Oct 2007 03:03:51 -0000 Subject: [llvm-commits] [llvm] r43377 - in /llvm/trunk: docs/Passes.html include/llvm/Assembly/PrintModulePass.h lib/Transforms/IPO/ArgumentPromotion.cpp lib/Transforms/Instrumentation/RSProfiling.cpp Message-ID: <200710260303.l9Q33qQY031257@zion.cs.uiuc.edu> Author: gordon Date: Thu Oct 25 22:03:51 2007 New Revision: 43377 URL: http://llvm.org/viewvc/llvm-project?rev=43377&view=rev Log: More fleshing out of docs/Passes.html, plus some typo fixes and improved wording in source files. Modified: llvm/trunk/docs/Passes.html llvm/trunk/include/llvm/Assembly/PrintModulePass.h llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp llvm/trunk/lib/Transforms/Instrumentation/RSProfiling.cpp Modified: llvm/trunk/docs/Passes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/Passes.html?rev=43377&r1=43376&r2=43377&view=diff ============================================================================== --- llvm/trunk/docs/Passes.html (original) +++ llvm/trunk/docs/Passes.html Thu Oct 25 22:03:51 2007 @@ -313,9 +313,8 @@

      - This pass, only available in opt, prints - the call graph into a .dot graph. This graph can then be processed with the - "dot" tool to convert it to postscript or some other suitable format. + This pass, only available in opt, prints the call graph to + standard output in a human-readable form.

      @@ -325,8 +324,8 @@

      - This pass, only available in opt, prints - the SCCs of the call graph to standard output in a human-readable form. + This pass, only available in opt, prints the SCCs of the call + graph to standard output in a human-readable form.

      @@ -336,8 +335,8 @@

      - This pass, only available in opt, prints - the SCCs of each function CFG to standard output in a human-readable form. + This pass, only available in opt, prints the SCCs of each + function CFG to standard output in a human-readable form.

      @@ -495,7 +494,12 @@
      Memory Dependence Analysis
      -

      Yet to be written.

      +

      + An analysis that determines, for a given memory operation, what preceding + memory operations it depends on. It builds on alias analysis information, and + tries to provide a lazy, caching interface to a common kind of alias + information query. +

      @@ -503,7 +507,11 @@ No Alias Analysis (always returns 'may' alias)
      -

      Yet to be written.

      +

      + Always returns "I don't know" for alias queries. NoAA is unlike other alias + analysis implementations, in that it does not chain to a previous analysis. As + such it doesn't follow many of the rules that other alias analyses must. +

      @@ -511,7 +519,10 @@ No Profile Information
      -

      Yet to be written.

      +

      + The default "no profile" implementation of the abstract + ProfileInfo interface. +

      @@ -519,7 +530,10 @@ Post-Dominance Frontier Construction
      -

      Yet to be written.

      +

      + This pass is a simple post-dominator construction algorithm for finding + post-dominator frontiers. +

      @@ -527,7 +541,10 @@ Post-Dominator Tree Construction
      -

      Yet to be written.

      +

      + This pass is a simple post-dominator construction algorithm for finding + post-dominators. +

      @@ -535,7 +552,11 @@ Print function to stderr
      -

      Yet to be written.

      +

      + The PrintFunctionPass class is designed to be pipelined with + other FunctionPasses, and prints out the functions of the module + as they are processed. +

      @@ -551,7 +572,11 @@ Print Call Graph to 'dot' file
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints the call graph into a + .dot graph. This graph can then be processed with the "dot" tool + to convert it to postscript or some other suitable format. +

      @@ -559,7 +584,11 @@ Print CFG of function to 'dot' file
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints the control flow graph + into a .dot graph. This graph can then be processed with the + "dot" tool to convert it to postscript or some other suitable format. +

      @@ -567,7 +596,12 @@ Print CFG of function to 'dot' file (with no function bodies)
      -

      Yet to be written.

      +

      + This pass, only available in opt, prints the control flow graph + into a .dot graph, omitting the function bodies. This graph can + then be processed with the "dot" tool to convert it to postscript or some + other suitable format. +

      @@ -575,7 +609,9 @@ Print module to stderr
      -

      Yet to be written.

      +

      + This pass simply prints out the entire module when it is executed. +

      @@ -583,7 +619,10 @@ Find Used Types
      -

      Yet to be written.

      +

      + This pass is used to seek out all of the types in use by the program. Note + that this analysis explicitly does not include types only used by the symbol + table.

      @@ -591,7 +630,10 @@ Load profile information from llvmprof.out
      -

      Yet to be written.

      +

      + A concrete implementation of profiling information that loads the information + from a profile dump file. +

      @@ -599,7 +641,18 @@ Scalar Evolution Analysis
      -

      Yet to be written.

      +

      + The ScalarEvolution analysis can be used to analyze and + catagorize scalar expressions in loops. It specializes in recognizing general + induction variables, representing them with the abstract and opaque + SCEV class. Given this analysis, trip counts of loops and other + important properties can be obtained. +

      + +

      + This analysis is primarily useful for induction variable substitution and + strength reduction. +

      @@ -607,7 +660,8 @@ Target Data Layout
      -

      Yet to be written.

      +

      Provides other passes access to information on how the size and alignment + required by the the target ABI for various data types.

      @@ -632,7 +686,30 @@ Promote 'by reference' arguments to scalars
      -

      Yet to be written.

      +

      + This pass promotes "by reference" arguments to be "by value" arguments. In + practice, this means looking for internal functions that have pointer + arguments. If it can prove, through the use of alias analysis, that an + argument is *only* loaded, then it can pass the value into the function + instead of the address of the value. This can cause recursive simplification + of code and lead to the elimination of allocas (especially in C++ template + code like the STL). +

      + +

      + This pass also handles aggregate arguments that are passed into a function, + scalarizing them if the elements of the aggregate are only loaded. Note that + it refuses to scalarize aggregates which would require passing in more than + three operands to the function, because passing thousands of operands for a + large array or structure is unprofitable! +

      + +

      + Note that this transformation could also be done for arguments that are only + stored to (returning the value instead), but does not currently. This case + would be best handled when and if LLVM starts supporting multiple return + values from functions. +

      @@ -640,22 +717,11 @@ Profile Guided Basic Block Placement
      -

      This pass implements a very simple profile guided basic block placement - algorithm. The idea is to put frequently executed blocks together at the - start of the function, and hopefully increase the number of fall-through - conditional branches. If there is no profile information for a particular - function, this pass basically orders blocks in depth-first order.

      -

      The algorithm implemented here is basically "Algo1" from "Profile Guided - Code Positioning" by Pettis and Hansen, except that it uses basic block - counts instead of edge counts. This could be improved in many ways, but is - very simple for now.

      - -

      Basically we "place" the entry block, then loop over all successors in a - DFO, placing the most frequently executed successor until we run out of - blocks. Did we mention that this was extremely simplistic? This is - also much slower than it could be. When it becomes important, this pass - will be rewritten to use a better algorithm, and then we can worry about - efficiency.

      +

      This pass is a very simple profile guided basic block placement algorithm. + The idea is to put frequently executed blocks together at the start of the + function and hopefully increase the number of fall-through conditional + branches. If there is no profile information for a particular function, this + pass basically orders blocks in depth-first order.

      @@ -663,7 +729,12 @@ Break critical edges in CFG
      -

      Yet to be written.

      +

      + Break all of the critical edges in the CFG by inserting a dummy basic block. + It may be "required" by passes that cannot deal with critical edges. This + transformation obviously invalidates the CFG, but can update forward dominator + (set, immediate dominators, tree, and frontier) information. +

      @@ -705,7 +776,12 @@ Merge Duplicate Global Constants
      -

      Yet to be written.

      +

      + Merges duplicate global constants together into a single constant that is + shared. This is useful because some passes (ie TraceValues) insert a lot of + string constants into the program, regardless of whether or not an existing + string is available. +

      @@ -729,7 +805,11 @@ Dead Code Elimination
      -

      Yet to be written.

      +

      + Dead code elimination is similar to dead instruction + elimination, but it rechecks instructions that were used by removed + instructions to see if they are newly dead. +

      @@ -737,7 +817,17 @@ Dead Argument Elimination
      -

      Yet to be written.

      +

      + This pass deletes dead arguments from internal functions. Dead argument + elimination removes arguments which are directly dead, as well as arguments + only passed into function calls as dead arguments of other functions. This + pass also deletes dead arguments in a similar way. +

      + +

      + This pass is often useful as a cleanup pass to run after aggressive + interprocedural passes, which add possibly-dead arguments. +

      @@ -745,7 +835,11 @@ Dead Type Elimination
      -

      Yet to be written.

      +

      + This pass is used to cleanup the output of GCC. It eliminate names for types + that are unused in the entire translation unit, using the find used types pass. +

      @@ -753,7 +847,10 @@ Dead Instruction Elimination
      -

      Yet to be written.

      +

      + Dead instruction elimination performs a single pass over the function, + removing instructions that are obviously dead. +

      @@ -761,7 +858,10 @@ Dead Store Elimination
      -

      Yet to be written.

      +

      + A trivial dead store elimination that only considers basic-block local + redundant stores. +

      @@ -769,7 +869,12 @@ Global Common Subexpression Elimination
      -

      Yet to be written.

      +

      + This pass is designed to be a very quick global transformation that + eliminates global common subexpressions from a function. It does this by + using an existing value numbering implementation to identify the common + subexpressions, eliminating them when possible. +

      @@ -777,7 +882,13 @@ Dead Global Elimination
      -

      Yet to be written.

      +

      + This transform is designed to eliminate unreachable internal globals from the + program. It uses an aggressive algorithm, searching out globals that are + known to be alive. After it finds all of the globals which are needed, it + deletes whatever is left over. This allows it to delete recursive chunks of + the program which are unreachable. +

      @@ -785,7 +896,11 @@ Global Variable Optimizer
      -

      Yet to be written.

      +

      + This pass transforms simple global variables that never have their address + taken. If obviously true, it marks read/write globals as constant, deletes + variables only stored to, etc. +

      @@ -821,7 +936,16 @@ Indirect Malloc and Free Removal
      -

      Yet to be written.

      +

      + This pass finds places where memory allocation functions may escape into + indirect land. Some transforms are much easier (aka possible) only if free + or malloc are not called indirectly. +

      + +

      + Thus find places where the address of memory functions are taken and construct + bounce functions with direct calls of those functions. +

      @@ -829,7 +953,50 @@ Canonicalize Induction Variables
      -

      Yet to be written.

      +

      + This transformation analyzes and transforms the induction variables (and + computations derived from them) into simpler forms suitable for subsequent + analysis and transformation. +

      + +

      + This transformation makes the following changes to each loop with an + identifiable induction variable: +

      + +
        +
      1. All loops are transformed to have a single canonical + induction variable which starts at zero and steps by one.
      2. +
      3. The canonical induction variable is guaranteed to be the first PHI node + in the loop header block.
      4. +
      5. Any pointer arithmetic recurrences are raised to use array + subscripts.
      6. +
      + +

      + If the trip count of a loop is computable, this pass also makes the following + changes: +

      + +
        +
      1. The exit condition for the loop is canonicalized to compare the + induction value against the exit value. This turns loops like: +
        for (i = 7; i*i < 1000; ++i)
        + into +
        for (i = 0; i != 25; ++i)
      2. +
      3. Any use outside of the loop of an expression derived from the indvar + is changed to compute the derived value outside of the loop, eliminating + the dependence on the exit value of the induction variable. If the only + purpose of the loop is to compute the exit value of some derived + expression, this transformation will make the loop dead.
      4. +

        + +

        + This transformation should be followed by strength reduction after all of the + desired loop transformations have been performed. Additionally, on targets + where it is profitable, the loop could be transformed to count down to zero + (the "do loop" optimization). +

      @@ -837,7 +1004,9 @@ Function Integration/Inlining
      -

      Yet to be written.

      +

      + Bottom-up inlining of functions into callees. +

      @@ -845,7 +1014,18 @@ Insert instrumentation for block profiling
      -

      Yet to be written.

      +

      + This pass instruments the specified program with counters for basic block + profiling, which counts the number of times each basic block executes. This + is the most basic form of profiling, which can tell which blocks are hot, but + cannot reliably detect hot paths through the CFG. +

      + +

      + Note that this implementation is very na??ve. Control equivalent regions of + the CFG should not require duplicate counters, but it does put duplicate + counters in. +

      @@ -853,7 +1033,17 @@ Insert instrumentation for edge profiling
      -

      Yet to be written.

      +

      + This pass instruments the specified program with counters for edge profiling. + Edge profiling can give a reasonable approximation of the hot paths through a + program, and is used for a wide variety of program transformations. +

      + +

      + Note that this implementation is very na??ve. It inserts a counter for + every edge in the program, instead of using control flow information + to prune the number of counters inserted. +

      @@ -861,7 +1051,10 @@ Insert instrumentation for function profiling
      -

      Yet to be written.

      +

      + This pass instruments the specified program with counters for function + profiling, which counts the number of times each function is called. +

      @@ -869,7 +1062,11 @@ Measure profiling framework overhead
      -

      Yet to be written.

      +

      + The basic profiler that does nothing. It is the default profiler and thus + terminates RSProfiler chains. It is useful for measuring + framework overhead. +

      @@ -877,7 +1074,20 @@ Insert random sampling instrumentation framework
      -

      Yet to be written.

      +

      + The second stage of the random-sampling instrumentation framework, duplicates + all instructions in a function, ignoring the profiling code, then connects the + two versions together at the entry and at backedges. At each connection point + a choice is made as to whether to jump to the profiled code (take a sample) or + execute the unprofiled code. +

      + +

      + After this pass, it is highly recommended to runmem2reg + and adce. instcombine, + load-vn, gdce, and + dse also are good to run afterwards. +

      @@ -885,7 +1095,53 @@ Combine redundant instructions
      -

      Yet to be written.

      +

      + Combine instructions to form fewer, simple + instructions. This pass does not modify the CFG This pass is where algebraic + simplification happens. +

      + +

      + This pass combines things like: +

      + +
      %Y = add i32 %X, 1
      +%Z = add i32 %Y, 1
      + +

      + into: +

      + +
      %Z = add i32 %X, 2
      + +

      + This is a simple worklist driven algorithm. +

      + +

      + This pass guarantees that the following canonicalizations are performed on + the program: +

      + +
        +
      • If a binary operator has a constant operand, it is moved to the right- + hand side.
      • +
      • Bitwise operators with constant operands are always grouped so that + shifts are performed first, then ors, then + ands, then xors.
      • +
      • Compare instructions are converted from <, + >, ???, or ??? to + = or ??? if possible.
      • +
      • All cmp instructions on boolean values are replaced with + logical operations.
      • +
      • add X, X is represented as + mul X, 2 ??? shl X, 1
      • +
      • Multiplies with a constant power-of-two argument are transformed into + shifts.
      • +
      • ??? etc.
      • +
      Modified: llvm/trunk/include/llvm/Assembly/PrintModulePass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Assembly/PrintModulePass.h?rev=43377&r1=43376&r2=43377&view=diff ============================================================================== --- llvm/trunk/include/llvm/Assembly/PrintModulePass.h (original) +++ llvm/trunk/include/llvm/Assembly/PrintModulePass.h Thu Oct 25 22:03:51 2007 @@ -10,7 +10,7 @@ // This file defines two passes to print out a module. The PrintModulePass pass // simply prints out the entire module when it is executed. The // PrintFunctionPass class is designed to be pipelined with other -// FunctionPass's, and prints out the functions of the class as they are +// FunctionPass's, and prints out the functions of the module as they are // processed. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=43377&r1=43376&r2=43377&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Thu Oct 25 22:03:51 2007 @@ -9,22 +9,22 @@ // // This pass promotes "by reference" arguments to be "by value" arguments. In // practice, this means looking for internal functions that have pointer -// arguments. If we can prove, through the use of alias analysis, that an -// argument is *only* loaded, then we can pass the value into the function +// arguments. If it can prove, through the use of alias analysis, that an +// argument is *only* loaded, then it can pass the value into the function // instead of the address of the value. This can cause recursive simplification // of code and lead to the elimination of allocas (especially in C++ template // code like the STL). // // This pass also handles aggregate arguments that are passed into a function, // scalarizing them if the elements of the aggregate are only loaded. Note that -// we refuse to scalarize aggregates which would require passing in more than -// three operands to the function, because we don't want to pass thousands of -// operands for a large array or structure! +// it refuses to scalarize aggregates which would require passing in more than +// three operands to the function, because passing thousands of operands for a +// large array or structure is unprofitable! // // Note that this transformation could also be done for arguments that are only -// stored to (returning the value instead), but we do not currently handle that -// case. This case would be best handled when and if we start supporting -// multiple return values from functions. +// stored to (returning the value instead), but does not currently. This case +// would be best handled when and if LLVM begins supporting multiple return +// values from functions. // //===----------------------------------------------------------------------===// Modified: llvm/trunk/lib/Transforms/Instrumentation/RSProfiling.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/RSProfiling.cpp?rev=43377&r1=43376&r2=43377&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/RSProfiling.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/RSProfiling.cpp Thu Oct 25 22:03:51 2007 @@ -18,7 +18,7 @@ // backedges. At each connection point a choice is made as to whether to jump // to the profiled code (take a sample) or execute the unprofiled code. // -// It is highly recommeneded that after this pass one runs mem2reg and adce +// It is highly recommended that after this pass one runs mem2reg and adce // (instcombine load-vn gdce dse also are good to run afterwards) // // This design is intended to make the profiling passes independent of the RS From clattner at apple.com Thu Oct 25 22:14:34 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 25 Oct 2007 20:14:34 -0700 Subject: [llvm-commits] [llvm] r43375 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/Target/X86/README.txt lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/loop-strength-reduce5.ll In-Reply-To: <200710260156.l9Q1uCfu028601@zion.cs.uiuc.edu> References: <200710260156.l9Q1uCfu028601@zion.cs.uiuc.edu> Message-ID: <461E5B9C-1C07-4E18-B398-4FE1F036B5B7@apple.com> On Oct 25, 2007, at 6:56 PM, Evan Cheng wrote: > Author: evancheng > Date: Thu Oct 25 20:56:11 2007 > New Revision: 43375 > > URL: http://llvm.org/viewvc/llvm-project?rev=43375&view=rev > Log: > Loosen up iv reuse to allow reuse of the same stride but a larger > type when truncating from the larger type to smaller type is free. > e.g. Nice, this is probably a huge win on x86-64. Can you please check to see whether this fixes PR1301? If not, please update it if it helped. Thanks Evan, -Chris From clattner at apple.com Thu Oct 25 22:21:13 2007 From: clattner at apple.com (Chris Lattner) Date: Thu, 25 Oct 2007 20:21:13 -0700 Subject: [llvm-commits] [llvm] r43326 - in /llvm/trunk: lib/Analysis/BasicAliasAnalysis.cpp test/Analysis/BasicAA/2007-10-24-ArgumentsGlobals.ll In-Reply-To: <200710250236.l9P2aIOT016062@zion.cs.uiuc.edu> References: <200710250236.l9P2aIOT016062@zion.cs.uiuc.edu> Message-ID: <3D5C9481-61EC-4175-9B7E-33B8415B2CE9@apple.com> On Oct 24, 2007, at 7:36 PM, Owen Anderson wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=43326&view=rev > Log: > Fix for PR1741. Thanks Owen, this is the proper fix, but it doesn't fix the whole problem: > ====================================================================== > ======== > --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) > +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Wed Oct 24 > 21:36:18 2007 > @@ -339,8 +339,9 @@ > > // Otherwise, nothing is known... > } else if (O1 != O2) { > + if (!isa(O1)) > + // If they are two different objects, we know that we > have no alias... > + return NoAlias; Please change this to: } else if (O1 != O2 && !isa(O1) && !isa(O2)) { return NoAlias; } Thanks for tackling this! -Chris From dalej at apple.com Thu Oct 25 22:29:56 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 26 Oct 2007 03:29:56 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43378 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200710260329.l9Q3TumG032245@zion.cs.uiuc.edu> Author: johannes Date: Thu Oct 25 22:29:56 2007 New Revision: 43378 URL: http://llvm.org/viewvc/llvm-project?rev=43378&view=rev Log: (inline asm) don't canonicalize single-hard-reg constraints; they're already canonical. 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=43378&r1=43377&r2=43378&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Oct 25 22:29:56 2007 @@ -3526,6 +3526,7 @@ if (IsInOut) ++NumInOut, ++NumInputs; + std::string SimplifiedConstraint; // If this output register is pinned to a machine register, use that machine // register instead of the specified constraint. if (TREE_CODE(Operand) == VAR_DECL && DECL_HARD_REGISTER(Operand)) { @@ -3539,14 +3540,14 @@ memcpy(NewConstraint+2, reg_names[RegNum], RegNameLen); NewConstraint[RegNameLen+2] = '}'; NewConstraint[RegNameLen+3] = 0; - Constraint = NewConstraint; + SimplifiedConstraint = NewConstraint; } + } else { + // If we can simplify the constraint into something else, do so now. This + // avoids LLVM having to know about all the (redundant) GCC constraints. + SimplifiedConstraint = CanonicalizeConstraint(Constraint+1); } - // If we can simplify the constraint into something else, do so now. This - // avoids LLVM having to know about all the (redundant) GCC constraints. - std::string SimplifiedConstraint = CanonicalizeConstraint(Constraint+1); - LValue Dest = EmitLV(Operand); const Type *DestValTy = cast(Dest.Ptr->getType())->getElementType(); From resistor at mac.com Thu Oct 25 22:47:14 2007 From: resistor at mac.com (Owen Anderson) Date: Fri, 26 Oct 2007 03:47:14 -0000 Subject: [llvm-commits] [llvm] r43379 - /llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Message-ID: <200710260347.l9Q3lEqD000505@zion.cs.uiuc.edu> Author: resistor Date: Thu Oct 25 22:47:14 2007 New Revision: 43379 URL: http://llvm.org/viewvc/llvm-project?rev=43379&view=rev Log: Make a comment better. 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=43379&r1=43378&r2=43379&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/BasicAliasAnalysis.cpp Thu Oct 25 22:47:14 2007 @@ -338,9 +338,11 @@ return NoAlias; // Otherwise, nothing is known... + } else if (O1 != O2) { if (!isa(O1)) - // If they are two different objects, we know that we have no alias... + // If they are two different objects, and neither is an argument, + // we know that we have no alias... return NoAlias; } From echristo at apple.com Thu Oct 25 23:00:13 2007 From: echristo at apple.com (Eric Christopher) Date: Fri, 26 Oct 2007 04:00:13 -0000 Subject: [llvm-commits] [llvm] r43380 - /llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Message-ID: <200710260400.l9Q40DLW000975@zion.cs.uiuc.edu> Author: echristo Date: Thu Oct 25 23:00:13 2007 New Revision: 43380 URL: http://llvm.org/viewvc/llvm-project?rev=43380&view=rev Log: clo/clz aren't supported on mips I. Keep them around for when we'll want them later (mips32/64). Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=43380&r1=43379&r2=43380&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original) +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Thu Oct 25 23:00:13 2007 @@ -2,7 +2,7 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Bruno Cardoso Lopes and is distributed under the +// This file was developed by Bruno Cardoso Lopes and is distributed under the // University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// @@ -22,31 +22,31 @@ def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain, SDNPOutFlag]>; -// Hi and Lo nodes are created to let easy manipulation of 16-bit when -// handling 32-bit immediates. They are used on MipsISelLowering to +// Hi and Lo nodes are created to let easy manipulation of 16-bit when +// handling 32-bit immediates. They are used on MipsISelLowering to // lower stuff like GlobalAddress, ExternalSymbol, ... on static model // This two nodes have nothing to do with Mips Registers Hi and Lo. def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp, [SDNPOutFlag]>; -def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; +def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; // Necessary to generate glued instructions when loading GlobalAddress // into registers. -def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative, +def MipsAdd : SDNode<"MipsISD::Add", SDTIntBinOp, [SDNPCommutative, SDNPAssociative, SDNPOptInFlag]>; // Used to Load Addresses on PIC code. def MipsLoadAddr: SDNode<"MipsISD::LoadAddr", SDTIntUnaryOp>; -// Return -def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; -def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, +// Return +def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; +def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, SDNPOptInFlag]>; // These are target-independent nodes, but have target-specific formats. def SDT_MipsCallSeq : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; -def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq, +def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq, [SDNPHasChain, SDNPOutFlag]>; -def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq, +def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq, [SDNPHasChain, SDNPOutFlag]>; //===----------------------------------------------------------------------===// @@ -63,7 +63,7 @@ def calltarget : Operand; def uimm16 : Operand; def simm16 : Operand; -def shamt : Operand; +def shamt : Operand; def addrlabel : Operand; // Address operand @@ -87,7 +87,7 @@ def immSExt16 : PatLeaf<(imm), [{ if (N->getValueType(0) == MVT::i32) return (int32_t)N->getValue() == (short)N->getValue(); - else + else return (int64_t)N->getValue() == (short)N->getValue(); }]>; @@ -98,7 +98,7 @@ def immZExt16 : PatLeaf<(imm), [{ if (N->getValueType(0) == MVT::i32) return (uint32_t)N->getValue() == (unsigned short)N->getValue(); - else + else return (uint64_t)N->getValue() == (unsigned short)N->getValue(); }], LO16>; @@ -112,7 +112,7 @@ return N->getValue() == ((N->getValue()) & 0x1f) ; }]>; -// Mips Address Mode! SDNode frameindex could possibily be a match +// Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def addr : ComplexPattern; @@ -121,52 +121,52 @@ //===----------------------------------------------------------------------===// // Arithmetic 3 register operands -let isCommutable = 1 in +let isCommutable = 1 in class ArithR op, bits<6> func, string instr_asm, SDNode OpNode, - InstrItinClass itin>: - FR< op, - func, - (outs CPURegs:$dst), - (ins CPURegs:$b, CPURegs:$c), - !strconcat(instr_asm, " $dst, $b, $c"), + InstrItinClass itin>: + FR< op, + func, + (outs CPURegs:$dst), + (ins CPURegs:$b, CPURegs:$c), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>; -let isCommutable = 1 in -class ArithOverflowR op, bits<6> func, string instr_asm>: - FR< op, - func, - (outs CPURegs:$dst), - (ins CPURegs:$b, CPURegs:$c), - !strconcat(instr_asm, " $dst, $b, $c"), +let isCommutable = 1 in +class ArithOverflowR op, bits<6> func, string instr_asm>: + FR< op, + func, + (outs CPURegs:$dst), + (ins CPURegs:$b, CPURegs:$c), + !strconcat(instr_asm, " $dst, $b, $c"), [], IIAlu>; // Arithmetic 2 register operands let isCommutable = 1 in -class ArithI op, string instr_asm, SDNode OpNode, - Operand Od, PatLeaf imm_type> : - FI< op, - (outs CPURegs:$dst), - (ins CPURegs:$b, Od:$c), - !strconcat(instr_asm, " $dst, $b, $c"), +class ArithI op, string instr_asm, SDNode OpNode, + Operand Od, PatLeaf imm_type> : + FI< op, + (outs CPURegs:$dst), + (ins CPURegs:$b, Od:$c), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>; // Arithmetic Multiply ADD/SUB let rd=0 in -class MArithR func, string instr_asm> : - FR< 0x1c, +class MArithR func, string instr_asm> : + FR< 0x1c, func, - (outs CPURegs:$rs), - (ins CPURegs:$rt), - !strconcat(instr_asm, " $rs, $rt"), + (outs CPURegs:$rs), + (ins CPURegs:$rt), + !strconcat(instr_asm, " $rs, $rt"), [], IIImul>; // Logical class LogicR func, string instr_asm, SDNode OpNode>: - FR< 0x00, - func, - (outs CPURegs:$dst), - (ins CPURegs:$b, CPURegs:$c), - !strconcat(instr_asm, " $dst, $b, $c"), + FR< 0x00, + func, + (outs CPURegs:$dst), + (ins CPURegs:$b, CPURegs:$c), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; class LogicI op, string instr_asm, SDNode OpNode>: @@ -177,29 +177,29 @@ [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))], IIAlu>; class LogicNOR op, bits<6> func, string instr_asm>: - FR< op, - func, - (outs CPURegs:$dst), - (ins CPURegs:$b, CPURegs:$c), - !strconcat(instr_asm, " $dst, $b, $c"), + FR< op, + func, + (outs CPURegs:$dst), + (ins CPURegs:$b, CPURegs:$c), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>; // Shifts let rt = 0 in class LogicR_shift_imm func, string instr_asm, SDNode OpNode>: - FR< 0x00, - func, + FR< 0x00, + func, (outs CPURegs:$dst), (ins CPURegs:$b, shamt:$c), - !strconcat(instr_asm, " $dst, $b, $c"), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>; class LogicR_shift_reg func, string instr_asm, SDNode OpNode>: - FR< 0x00, - func, + FR< 0x00, + func, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c), - !strconcat(instr_asm, " $dst, $b, $c"), + !strconcat(instr_asm, " $dst, $b, $c"), [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; // Load Upper Imediate @@ -210,7 +210,7 @@ !strconcat(instr_asm, " $dst, $imm"), [], IIAlu>; -// Memory Load/Store +// Memory Load/Store let isLoad = 1, hasDelaySlot = 1 in class LoadM op, string instr_asm, PatFrag OpNode>: FI< op, @@ -245,9 +245,9 @@ !strconcat(instr_asm, " $src, $offset"), [(brcond (cond_op CPURegs:$src, 0), bb:$offset)], IIBranch>; -} +} -// SetCC +// SetCC class SetCC_R op, bits<6> func, string instr_asm, PatFrag cond_op>: FR< op, @@ -286,11 +286,11 @@ [], IIBranch>; // Jump and Link (Call) -let isCall=1, hasDelaySlot=1, +let isCall=1, hasDelaySlot=1, // All calls clobber the non-callee saved registers... - Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, + Defs = [AT, V0, V1, A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, K0, K1] in { - class JumpLink op, string instr_asm>: + class JumpLink op, string instr_asm>: FJ< op, (outs), (ins calltarget:$target), @@ -314,36 +314,36 @@ [], IIBranch>; } -// Mul, Div -class MulDiv func, string instr_asm, InstrItinClass itin>: - FR< 0x00, - func, +// Mul, Div +class MulDiv func, string instr_asm, InstrItinClass itin>: + FR< 0x00, + func, (outs), - (ins CPURegs:$a, CPURegs:$b), - !strconcat(instr_asm, " $a, $b"), + (ins CPURegs:$a, CPURegs:$b), + !strconcat(instr_asm, " $a, $b"), [], itin>; -// Move from Hi/Lo +// Move from Hi/Lo class MoveFromTo func, string instr_asm>: - FR< 0x00, - func, - (outs CPURegs:$dst), + FR< 0x00, + func, + (outs CPURegs:$dst), (ins), - !strconcat(instr_asm, " $dst"), + !strconcat(instr_asm, " $dst"), [], IIHiLo>; // Count Leading Ones/Zeros in Word class CountLeading func, string instr_asm>: - FR< 0x1c, - func, - (outs CPURegs:$dst), - (ins CPURegs:$src), - !strconcat(instr_asm, " $dst, $src"), + FR< 0x1c, + func, + (outs CPURegs:$dst), + (ins CPURegs:$src), + !strconcat(instr_asm, " $dst, $src"), [], IIAlu>; -class EffectiveAddress : - FI<0x09, - (outs CPURegs:$dst), +class EffectiveAddress : + FI<0x09, + (outs CPURegs:$dst), (ins mem:$addr), instr_asm, [(set CPURegs:$dst, addr:$addr)], IIAlu>; @@ -366,19 +366,19 @@ "!IMPLICIT_DEF $dst", [(set CPURegs:$dst, (undef))]>; -// When handling PIC code the assembler needs .cpload and .cprestore -// directives. If the real instructions corresponding these directives -// are used, we have the same behavior, but get also a bunch of warnings +// When handling PIC code the assembler needs .cpload and .cprestore +// directives. If the real instructions corresponding these directives +// are used, we have the same behavior, but get also a bunch of warnings // from the assembler. -def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg), +def CPLOAD: PseudoInstMips<(outs), (ins CPURegs:$reg), ".set noreorder\n\t.cpload $reg\n\t.set reorder", []>; -def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc), +def CPRESTORE: PseudoInstMips<(outs), (ins uimm16:$loc), ".cprestore $loc", []>; // Used on PIC code only, it loads the address of label into register reg. The // address is calculated from the global pointer ($gp) and is expanded by the // assembler into two instructions "lw" and "addiu". -def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label), +def LA: PseudoInstMips<(outs CPURegs:$dst), (ins addrlabel:$label), "la $dst, $label", []>; //===----------------------------------------------------------------------===// @@ -414,7 +414,7 @@ def XORi : LogicI<0x0e, "xori", xor>; def NOR : LogicNOR<0x00, 0x27, "nor">; -// Shifts +// Shifts def SLL : LogicR_shift_imm<0x00, "sll", shl>; def SRL : LogicR_shift_imm<0x02, "srl", srl>; def SRA : LogicR_shift_imm<0x03, "sra", sra>; @@ -439,7 +439,7 @@ def BEQ : CBranch<0x04, "beq", seteq>; def BNE : CBranch<0x05, "bne", setne>; -let rt=1 in +let rt=1 in def BGEZ : CBranchZero<0x01, "bgez", setge>; let rt=0 in { @@ -472,30 +472,33 @@ def DIV : MulDiv<0x1a, "div", IIIdiv>; def DIVu : MulDiv<0x1b, "divu", IIIdiv>; -// Move From Hi/Lo +// Move From Hi/Lo def MFHI : MoveFromTo<0x10, "mfhi">; def MFLO : MoveFromTo<0x12, "mflo">; def MTHI : MoveFromTo<0x11, "mthi">; def MTLO : MoveFromTo<0x13, "mtlo">; // Count Leading -def CLO : CountLeading<0x21, "clo">; -def CLZ : CountLeading<0x20, "clz">; +// CLO/CLZ are part of the newer MIPS32(tm) instruction +// set and not older Mips I keep this for future use +// though. +//def CLO : CountLeading<0x21, "clo">; +//def CLZ : CountLeading<0x20, "clz">; // No operation let addr=0 in def NOP : FJ<0, (outs), (ins), "nop", [], IIAlu>; -// Ret instruction - as mips does not have "ret" a +// Ret instruction - as mips does not have "ret" a // jr $ra must be generated. let isReturn=1, isTerminator=1, hasDelaySlot=1, - isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in + isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in { def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target), "jr $target", [(MipsRet CPURegs:$target)], IIBranch>; } -// FrameIndexes are legalized when they are operands from load/store +// FrameIndexes are legalized when they are operands from load/store // instructions. The same not happens for stack address copies, so an // add op with mem ComplexPattern is used and the stack address copy // can be matched. It's similar to Sparc LEA_ADDRi @@ -506,9 +509,9 @@ //===----------------------------------------------------------------------===// // Small immediates -def : Pat<(i32 immSExt16:$in), +def : Pat<(i32 immSExt16:$in), (ADDiu ZERO, imm:$in)>; -def : Pat<(i32 immZExt16:$in), +def : Pat<(i32 immZExt16:$in), (ORi ZERO, imm:$in)>; // Arbitrary immediates @@ -528,17 +531,17 @@ def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>; def : Pat<(MipsAdd CPURegs:$hi, (MipsLo tglobaladdr:$lo)), (ADDiu CPURegs:$hi, tglobaladdr:$lo)>; -def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>; +def : Pat<(MipsLoadAddr tglobaladdr:$in), (LA tglobaladdr:$in)>; -// Mips does not have not, so we increase the operation +// Mips does not have not, so we increase the operation def : Pat<(not CPURegs:$in), (NOR CPURegs:$in, ZERO)>; -// extended load and stores +// extended load and stores def : Pat<(i32 (extloadi1 addr:$src)), (LBu addr:$src)>; def : Pat<(i32 (extloadi8 addr:$src)), (LBu addr:$src)>; def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>; -def : Pat<(truncstorei1 CPURegs:$src, addr:$addr), +def : Pat<(truncstorei1 CPURegs:$src, addr:$addr), (SB CPURegs:$src, addr:$addr)>; /// @@ -585,7 +588,7 @@ (BNE CPURegs:$cond, ZERO, bb:$dst)>; /// -/// setcc patterns, only matched when there +/// setcc patterns, only matched when there /// is no brcond following a setcc operation /// @@ -606,16 +609,15 @@ (XORi (SLTu CPURegs:$lhs, CPURegs:$rhs), 1)>; def : Pat<(setne CPURegs:$lhs, CPURegs:$rhs), - (OR (SLT CPURegs:$lhs, CPURegs:$rhs), + (OR (SLT CPURegs:$lhs, CPURegs:$rhs), (SLT CPURegs:$rhs, CPURegs:$lhs))>; def : Pat<(seteq CPURegs:$lhs, CPURegs:$rhs), - (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs), + (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs), (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>; - + // setcc reg/imm operands def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs), (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>; def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs), (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>; - From asl at math.spbu.ru Fri Oct 26 04:13:24 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Fri, 26 Oct 2007 09:13:24 -0000 Subject: [llvm-commits] [llvm] r43381 - /llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Message-ID: <200710260913.l9Q9DOtJ023132@zion.cs.uiuc.edu> Author: asl Date: Fri Oct 26 04:13:24 2007 New Revision: 43381 URL: http://llvm.org/viewvc/llvm-project?rev=43381&view=rev Log: Fix off-by-one stack offset computations (dwarf information) for callee-saved registers in case, when FP pointer was eliminated. This should fixes misc. random EH-related crahses, when stuff is compiled with -fomit-frame-pointer. Thanks Duncan for nailing this bug! Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp?rev=43381&r1=43380&r2=43381&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86RegisterInfo.cpp Fri Oct 26 04:13:24 2007 @@ -1816,10 +1816,11 @@ MFI->getObjectOffset(CSI[I].getFrameIdx())); // Calculate offsets + int64_t saveAreaOffset = (hasFP(MF) ? 3 : 2)*stackGrowth; for (unsigned I = 0, E = CSI.size(); I!=E; ++I) { int64_t Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); unsigned Reg = CSI[I].getReg(); - Offset = (MaxOffset-Offset+3*stackGrowth); + Offset = (MaxOffset-Offset+saveAreaOffset); MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSSrc(Reg); Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); From evan.cheng at apple.com Fri Oct 26 12:24:47 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 Oct 2007 17:24:47 -0000 Subject: [llvm-commits] [llvm] r43384 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200710261724.l9QHOlXM014281@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 26 12:24:46 2007 New Revision: 43384 URL: http://llvm.org/viewvc/llvm-project?rev=43384&view=rev Log: Fix a crash. Make sure TLI is not null. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43384&r1=43383&r2=43384&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Oct 26 12:24:46 2007 @@ -972,7 +972,7 @@ AM.Scale = Scale; // If load[imm+r*scale] is illegal, bail out. - if (!TLI->isLegalAddressingMode(AM, AccessTy)) + if (TLI && !TLI->isLegalAddressingMode(AM, AccessTy)) return false; } return true; From criswell at uiuc.edu Fri Oct 26 13:31:24 2007 From: criswell at uiuc.edu (John Criswell) Date: Fri, 26 Oct 2007 18:31:24 -0000 Subject: [llvm-commits] [poolalloc] r43388 - /poolalloc/trunk/configure Message-ID: <200710261831.l9QIVORk017891@zion.cs.uiuc.edu> Author: criswell Date: Fri Oct 26 13:31:24 2007 New Revision: 43388 URL: http://llvm.org/viewvc/llvm-project?rev=43388&view=rev Log: Updated configure script for Andrew's latest changes. Modified: poolalloc/trunk/configure Modified: poolalloc/trunk/configure URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/configure?rev=43388&r1=43387&r2=43388&view=diff ============================================================================== --- poolalloc/trunk/configure (original) +++ poolalloc/trunk/configure Fri Oct 26 13:31:24 2007 @@ -1318,32 +1318,6 @@ LLVM_SRC_ROOT="`(cd $srcdir/../..; pwd)`" LLVM_OBJ_ROOT="`(cd ../..; pwd)`" -ac_aux_dir= -for ac_dir in $LLVM_SRC_ROOT/autoconf $srcdir/$LLVM_SRC_ROOT/autoconf; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f $ac_dir/shtool; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $LLVM_SRC_ROOT/autoconf $srcdir/$LLVM_SRC_ROOT/autoconf" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in $LLVM_SRC_ROOT/autoconf $srcdir/$LLVM_SRC_ROOT/autoconf" >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - - # Check whether --with-llvmsrc or --without-llvmsrc was given. if test "${with_llvmsrc+set}" = set; then @@ -1368,6 +1342,32 @@ +ac_aux_dir= +for ac_dir in $LLVM_SRC/autoconf $srcdir/$LLVM_SRC/autoconf; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $LLVM_SRC/autoconf $srcdir/$LLVM_SRC/autoconf" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $LLVM_SRC/autoconf $srcdir/$LLVM_SRC/autoconf" >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + ac_config_files="$ac_config_files Makefile.common" From alenhar2 at cs.uiuc.edu Fri Oct 26 13:31:29 2007 From: alenhar2 at cs.uiuc.edu (Andrew Lenharth) Date: Fri, 26 Oct 2007 18:31:29 -0000 Subject: [llvm-commits] [poolalloc] r43389 - in /poolalloc/trunk/lib: Makefile PoolAllocate/AccessTrace.cpp PoolAllocate/PointerCompress.cpp PoolAllocate/PoolAllocate.cpp PoolAllocate/PoolOptimize.cpp PoolAllocate/TransformFunctionBody.cpp Message-ID: <200710261831.l9QIVTxZ017909@zion.cs.uiuc.edu> Author: alenhar2 Date: Fri Oct 26 13:31:29 2007 New Revision: 43389 URL: http://llvm.org/viewvc/llvm-project?rev=43389&view=rev Log: Poolalloc, now with less bitrot, thanks Torvald Riegel Modified: poolalloc/trunk/lib/Makefile poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp poolalloc/trunk/lib/PoolAllocate/PoolOptimize.cpp poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Modified: poolalloc/trunk/lib/Makefile URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/Makefile?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/Makefile (original) +++ poolalloc/trunk/lib/Makefile Fri Oct 26 13:31:29 2007 @@ -6,6 +6,6 @@ # # List all of the subdirectories that we will compile. # -PARALLEL_DIRS=DSA +PARALLEL_DIRS=DSA PoolAllocate include $(LEVEL)/Makefile.common Modified: poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/AccessTrace.cpp Fri Oct 26 13:31:29 2007 @@ -32,6 +32,8 @@ const Type *VoidPtrTy; public: + PoolAccessTrace() : ModulePass((intptr_t)&ID) {} + bool runOnModule(Module &M); void getAnalysisUsage(AnalysisUsage &AU) const; @@ -39,6 +41,7 @@ const DSGraph &getGraphForFunc(PA::FuncInfo *FI) const { return ECG->getDSGraph(FI->F); } + static char ID; private: void InitializeLibraryFunctions(Module &M); @@ -46,6 +49,7 @@ PA::FuncInfo *FI, DSGraph &DSG); }; + char PoolAccessTrace::ID = 0; RegisterPass X("poolaccesstrace", "Instrument program to print trace of accesses"); } @@ -90,7 +94,8 @@ PD = Constant::getNullValue(VoidPtrTy); // Insert the trace call. - new CallInst(PoolAccessTraceFn, Ptr, PD, "", I); + Value *Opts[2] = {Ptr, PD}; + new CallInst(PoolAccessTraceFn, Opts, Opts + 2, "", I); } bool PoolAccessTrace::runOnModule(Module &M) { Modified: poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PointerCompress.cpp Fri Oct 26 13:31:29 2007 @@ -117,7 +117,9 @@ public: Constant *PoolInitPC, *PoolDestroyPC, *PoolAllocPC; typedef std::map PoolInfoMap; + static char ID; + PointerCompress() : ModulePass((intptr_t)&ID) {} /// NoArgFunctionsCalled - When we are walking the call graph, keep track of /// which functions are called that don't need their prototype to be /// changed. @@ -162,6 +164,7 @@ Function &F, DSGraph &DSG, PA::FuncInfo *FI); }; + char PointerCompress::ID = 0; RegisterPass X("pointercompress", "Compress type-safe data structures"); } @@ -285,7 +288,8 @@ // Get the pool base pointer. Constant *Zero = Constant::getNullValue(Type::Int32Ty); - Value *BasePtrPtr = new GetElementPtrInst(getPoolDesc(), Zero, Zero, + Value *Opts[2] = {Zero, Zero}; + Value *BasePtrPtr = new GetElementPtrInst(getPoolDesc(), Opts, Opts + 2, "poolbaseptrptr", &I); return new LoadInst(BasePtrPtr, "poolbaseptr", &I); } else { @@ -296,7 +300,8 @@ BasicBlock::iterator IP = I.getParent()->getParent()->begin()->begin(); while (isa(IP)) ++IP; Constant *Zero = Constant::getNullValue(Type::Int32Ty); - Value *BasePtrPtr = new GetElementPtrInst(getPoolDesc(), Zero, Zero, + Value *Opts[2] = {Zero, Zero}; + Value *BasePtrPtr = new GetElementPtrInst(getPoolDesc(), Opts, Opts + 2, "poolbaseptrptr", IP); PoolBase = new LoadInst(BasePtrPtr, "poolbaseptr", IP); } @@ -864,7 +869,7 @@ Ops.push_back(ConstantInt::get(Type::Int32Ty, PA::Heuristic::getRecommendedAlignment(PI->getNewType(), TD))); // TODO: Compression could reduce the alignment restriction for the pool! - Value *PB = new CallInst(PtrComp.PoolInitPC, &Ops[0], Ops.size(), "", &CI); + Value *PB = new CallInst(PtrComp.PoolInitPC, Ops.begin(), Ops.end(), "", &CI); if (!DisablePoolBaseASR) { // Load the pool base immediately. PB->setName(CI.getOperand(1)->getName()+".poolbase"); @@ -906,7 +911,8 @@ Size = BinaryOperator::createMul(Size, NewSize, "newbytes", &CI); } - Value *NC = new CallInst(PtrComp.PoolAllocPC, CI.getOperand(1), Size, CI.getName(), &CI); + Value *Opts[2] = {CI.getOperand(1), Size}; + Value *NC = new CallInst(PtrComp.PoolAllocPC, Opts, Opts + 2, CI.getName(), &CI); setTransformedValue(CI, NC); } @@ -1031,7 +1037,7 @@ } Function *Clone = PtrComp.GetExtFunctionClone(Callee, CompressedArgs); - Value *NC = new CallInst(Clone, &Operands[0], Operands.size(), CI.getName(), &CI); + Value *NC = new CallInst(Clone, Operands.begin(), Operands.end(), CI.getName(), &CI); if (NC->getType() != CI.getType()) // Compressing return value? setTransformedValue(CI, NC); else { @@ -1108,7 +1114,7 @@ else Operands.push_back(CI.getOperand(i)); - Value *NC = new CallInst(Clone, &Operands[0], Operands.size(), CI.getName(), &CI); + Value *NC = new CallInst(Clone, Operands.begin(), Operands.end(), CI.getName(), &CI); if (NC->getType() != CI.getType()) // Compressing return value? setTransformedValue(CI, NC); else { Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Fri Oct 26 13:31:29 2007 @@ -546,7 +546,7 @@ Value *ElSize = ConstantInt::get(Type::Int32Ty, RecSize); Value *AlignV = ConstantInt::get(Type::Int32Ty, Align); Value* Opts[3] = {GV, ElSize, AlignV}; - new CallInst(PoolInit, &Opts[0], 3, "", InsertPt); + new CallInst(PoolInit, Opts, Opts + 3, "", InsertPt); ++NumPools; return GV; } @@ -887,7 +887,7 @@ for (unsigned i = 0, e = PoolInitPoints.size(); i != e; ++i) { Value* Opts[3] = {PD, ElSize, Align}; - new CallInst(PoolInit, &Opts[0], 3, "", PoolInitPoints[i]); + new CallInst(PoolInit, Opts, Opts + 3, "", PoolInitPoints[i]); DEBUG(std::cerr << PoolInitPoints[i]->getParent()->getName() << " "); } Modified: poolalloc/trunk/lib/PoolAllocate/PoolOptimize.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolOptimize.cpp?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/PoolOptimize.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/PoolOptimize.cpp Fri Oct 26 13:31:29 2007 @@ -25,9 +25,12 @@ STATISTIC (NumBumpPtr, "Number of bump pointer pools"); struct PoolOptimize : public ModulePass { + static char ID; + PoolOptimize() : ModulePass((intptr_t)&ID) {} bool runOnModule(Module &M); }; + char PoolOptimize::ID = 0; RegisterPass X("pooloptimize", "Optimize a pool allocated program"); } @@ -109,19 +112,22 @@ CallInst *CI = Calls[i]; // poolrealloc(PD, null, X) -> poolalloc(PD, X) if (isa(CI->getOperand(2))) { - Value *New = new CallInst(PoolAlloc, CI->getOperand(1), CI->getOperand(3), + Value* Opts[2] = {CI->getOperand(1), CI->getOperand(3)}; + Value *New = new CallInst(PoolAlloc, Opts, Opts + 2, CI->getName(), CI); CI->replaceAllUsesWith(New); CI->eraseFromParent(); } else if (isa(CI->getOperand(3)) && cast(CI->getOperand(3))->isNullValue()) { // poolrealloc(PD, X, 0) -> poolfree(PD, X) - new CallInst(PoolFree, CI->getOperand(1), CI->getOperand(2), "", CI); + Value* Opts[2] = {CI->getOperand(1), CI->getOperand(2)}; + new CallInst(PoolFree, Opts, Opts + 2, "", CI); CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); CI->eraseFromParent(); } else if (isa(CI->getOperand(1))) { // poolrealloc(null, X, Y) -> realloc(X, Y) - Value *New = new CallInst(Realloc, CI->getOperand(2), CI->getOperand(3), + Value* Opts[2] = {CI->getOperand(2), CI->getOperand(3)}; + Value *New = new CallInst(Realloc, Opts, Opts + 2, CI->getName(), CI); CI->replaceAllUsesWith(New); CI->eraseFromParent(); @@ -148,7 +154,8 @@ CallInst *CI = Calls[i]; // poolmemalign(null, X, Y) -> memalign(X, Y) if (isa(CI->getOperand(1))) { - Value *New = new CallInst(MemAlign, CI->getOperand(2), CI->getOperand(3), CI->getName(), CI); + Value* Opts[2] = {CI->getOperand(2), CI->getOperand(3)}; + Value *New = new CallInst(MemAlign, Opts, Opts + 2, CI->getName(), CI); CI->replaceAllUsesWith(New); CI->eraseFromParent(); } @@ -219,18 +226,18 @@ std::vector Args; if (CI->getCalledFunction() == PoolAlloc) { Args.assign(CI->op_begin()+1, CI->op_end()); - Value *New = new CallInst(PoolAllocBP, &Args[0], Args.size(), CI->getName(), CI); + Value *New = new CallInst(PoolAllocBP, Args.begin(), Args.end(), CI->getName(), CI); CI->replaceAllUsesWith(New); CI->eraseFromParent(); } else if (CI->getCalledFunction() == PoolInit) { Args.assign(CI->op_begin()+1, CI->op_end()); Args.erase(Args.begin()+1); // Drop the size argument. - new CallInst(PoolInitBP, &Args[0], Args.size(), "", CI); + new CallInst(PoolInitBP, Args.begin(), Args.end(), "", CI); CI->eraseFromParent(); } else { assert(CI->getCalledFunction() == PoolDestroy); Args.assign(CI->op_begin()+1, CI->op_end()); - new CallInst(PoolDestroyBP, &Args[0], Args.size(), "", CI); + new CallInst(PoolDestroyBP, Args.begin(), Args.end(), "", CI); CI->eraseFromParent(); } } Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=43389&r1=43388&r2=43389&view=diff ============================================================================== --- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original) +++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Fri Oct 26 13:31:29 2007 @@ -155,7 +155,8 @@ // Insert a call to poolalloc Value *PH = getPoolHandle(I); - Instruction *V = new CallInst(PAInfo.PoolAlloc, PH, Size, Name, I); + Value* Opts[2] = {PH, Size}; + Instruction *V = new CallInst(PAInfo.PoolAlloc, Opts, Opts + 2, Name, I); AddPoolUse(*V, PH, PoolUses); @@ -268,7 +269,8 @@ G.getScalarMap()[Casted] = G.getScalarMap()[Arg]; } - CallInst *FreeI = new CallInst(PAInfo.PoolFree, PH, Casted, "", Where); + Value* Opts[2] = {PH, Casted}; + CallInst *FreeI = new CallInst(PAInfo.PoolFree, Opts, Opts + 2, "", Where); AddPoolUse(*FreeI, PH, PoolFrees); return FreeI; } @@ -329,7 +331,7 @@ // We know that the memory returned by poolalloc is at least 4 byte aligned. Value* Opts[4] = {Ptr, ConstantInt::get(Type::Int8Ty, 0), V2, ConstantInt::get(Type::Int32Ty, 4)}; - new CallInst(MemSet, Opts, 4, "", BBI); + new CallInst(MemSet, Opts, Opts + 4, "", BBI); } @@ -349,7 +351,7 @@ std::string Name = I->getName(); I->setName(""); Value* Opts[3] = {PH, OldPtr, Size}; - Instruction *V = new CallInst(PAInfo.PoolRealloc, Opts, 3, Name, I); + Instruction *V = new CallInst(PAInfo.PoolRealloc, Opts, Opts + 3, Name, I); Instruction *Casted = V; if (V->getType() != I->getType()) Casted = CastInst::createPointerCast(V, I->getType(), V->getName(), I); @@ -417,7 +419,7 @@ std::string Name = I->getName(); I->setName(""); Value* Opts[3] = {PH, Align, Size}; - Instruction *V = new CallInst(PAInfo.PoolMemAlign, Opts, 3, Name, I); + Instruction *V = new CallInst(PAInfo.PoolMemAlign, Opts, Opts + 3, Name, I); Instruction *Casted = V; if (V->getType() != I->getType()) @@ -653,7 +655,7 @@ Value *ElSize = ConstantInt::get(Type::Int32Ty,0); Value *Align = ConstantInt::get(Type::Int32Ty,0); Value* Opts[3] = {ArgVal, ElSize, Align}; - new CallInst(PAInfo.PoolInit, Opts, 3,"", TheCall); + new CallInst(PAInfo.PoolInit, Opts, Opts + 3,"", TheCall); BasicBlock::iterator BBI = TheCall; new CallInst(PAInfo.PoolDestroy, ArgVal, "", ++BBI); } @@ -673,9 +675,9 @@ if (InvokeInst *II = dyn_cast(TheCall)) { NewCall = new InvokeInst(NewCallee, II->getNormalDest(), - II->getUnwindDest(), &Args[0], Args.size(), Name, TheCall); + II->getUnwindDest(), Args.begin(), Args.end(), Name, TheCall); } else { - NewCall = new CallInst(NewCallee, &Args[0], Args.size(), Name, TheCall); + NewCall = new CallInst(NewCallee, Args.begin(), Args.end(), Name, TheCall); } // Add all of the uses of the pool descriptor From dalej at apple.com Fri Oct 26 14:59:04 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 26 Oct 2007 19:59:04 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43392 - in /llvm-gcc-4.0/trunk/gcc: c-common.c config/i386/i386.c Message-ID: <200710261959.l9QJx44Z022755@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 26 14:59:04 2007 New Revision: 43392 URL: http://llvm.org/viewvc/llvm-project?rev=43392&view=rev Log: LLVM does not compute DECL_RTL; remove checks for it in a couple places in inline asm handling. Modified: llvm-gcc-4.0/trunk/gcc/c-common.c llvm-gcc-4.0/trunk/gcc/config/i386/i386.c Modified: llvm-gcc-4.0/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-common.c?rev=43392&r1=43391&r2=43392&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.0/trunk/gcc/c-common.c Fri Oct 26 14:59:04 2007 @@ -7668,7 +7668,11 @@ variable. */ if (TREE_CODE (arg) == VAR_DECL && TREE_STATIC (arg) - && MEM_P (DECL_RTL (arg))) +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL does not get set for LLVM +/* && MEM_P (DECL_RTL (arg))*/ +/* APPLE LOCAL end LLVM */ + ) { /* See assemble_name for details. */ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (arg)); Modified: llvm-gcc-4.0/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/i386/i386.c?rev=43392&r1=43391&r2=43392&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.0/trunk/gcc/config/i386/i386.c Fri Oct 26 14:59:04 2007 @@ -19719,7 +19719,11 @@ } if (TREE_CODE (v) == VAR_DECL && TREE_STATIC (v) - && MEM_P (DECL_RTL (v))) +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL is not set for LLVM */ +/* && MEM_P (DECL_RTL (v))*/ + ) +/* APPLE LOCAL end LLVM */ return true; if ((TREE_CODE (v) == MINUS_EXPR || TREE_CODE (v) == PLUS_EXPR) From dalej at apple.com Fri Oct 26 15:15:55 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 26 Oct 2007 20:15:55 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43393 - /llvm-gcc-4.0/trunk/gcc/c-common.c Message-ID: <200710262015.l9QKFtkk023787@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 26 15:15:55 2007 New Revision: 43393 URL: http://llvm.org/viewvc/llvm-project?rev=43393&view=rev Log: Fix warning and LOCAL comment location. Cosmetic. Modified: llvm-gcc-4.0/trunk/gcc/c-common.c Modified: llvm-gcc-4.0/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/c-common.c?rev=43393&r1=43392&r2=43393&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.0/trunk/gcc/c-common.c Fri Oct 26 15:15:55 2007 @@ -7669,10 +7669,10 @@ if (TREE_CODE (arg) == VAR_DECL && TREE_STATIC (arg) /* APPLE LOCAL begin LLVM */ -/* DECL_RTL does not get set for LLVM +/* DECL_RTL does not get set for LLVM */ /* && MEM_P (DECL_RTL (arg))*/ -/* APPLE LOCAL end LLVM */ ) +/* APPLE LOCAL end LLVM */ { /* See assemble_name for details. */ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (arg)); From isanbard at gmail.com Fri Oct 26 15:20:30 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 20:20:30 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43394 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200710262020.l9QKKUwi024012@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 15:20:29 2007 New Revision: 43394 URL: http://llvm.org/viewvc/llvm-project?rev=43394&view=rev Log: There are situations where the source and destination alignments differ. This can cause havoc with memcpy. In this case, memcpy is using the alignment of the source pointer and assuming that the destination pointer has the same alignment. Fix this by copying the source pointer node and adjusting the alignment to the minimum of the two alignments. 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=43394&r1=43393&r2=43394&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Fri Oct 26 15:20:29 2007 @@ -3020,8 +3020,26 @@ Emit(TREE_OPERAND(exp, 1), LV.Ptr); EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); - } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) { - Emit(TREE_OPERAND(exp, 1), LV.Ptr); + } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0)) != RESULT_DECL) { + // At this point, Alignment is the alignment of the destination + // pointer. It may not match the alignment of the source pointer. So, we + // need to make sure that it's has at least its alignment. + tree new_exp = copy_node(TREE_OPERAND(exp, 1)); + unsigned NewAlignment = expr_align(new_exp) / 8; + Alignment = (Alignment < NewAlignment) ? Alignment : NewAlignment; + TYPE_ALIGN(TREE_TYPE(new_exp)) = Alignment; + + switch (TREE_CODE(new_exp)) { + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + DECL_ALIGN (new_exp) = Alignment * 8; + break; + default: + break; + } + + Emit(new_exp, LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we // emit it into a temporary memory location, then do a volatile copy into From dalej at apple.com Fri Oct 26 15:22:52 2007 From: dalej at apple.com (Dale Johannesen) Date: Fri, 26 Oct 2007 20:22:52 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43395 - in /llvm-gcc-4.2/trunk/gcc: c-common.c config/i386/i386.c Message-ID: <200710262022.l9QKMrPJ024109@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 26 15:22:52 2007 New Revision: 43395 URL: http://llvm.org/viewvc/llvm-project?rev=43395&view=rev Log: Remove checks for DECL_RTL a couple places in inline asm handling; llvm doesn't set that. Modified: llvm-gcc-4.2/trunk/gcc/c-common.c llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Modified: llvm-gcc-4.2/trunk/gcc/c-common.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/c-common.c?rev=43395&r1=43394&r2=43395&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/c-common.c (original) +++ llvm-gcc-4.2/trunk/gcc/c-common.c Fri Oct 26 15:22:52 2007 @@ -7980,7 +7980,11 @@ variable. */ if (TREE_CODE (arg) == VAR_DECL && TREE_STATIC (arg) - && MEM_P (DECL_RTL (arg))) +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL does not get set for LLVM */ +/* && MEM_P (DECL_RTL (arg))*/ + ) +/* APPLE LOCAL end LLVM */ { /* See assemble_name for details. */ const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (arg)); Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=43395&r1=43394&r2=43395&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Fri Oct 26 15:22:52 2007 @@ -20543,7 +20543,11 @@ } if (TREE_CODE (v) == VAR_DECL && TREE_STATIC (v) - && MEM_P (DECL_RTL (v))) +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL is not set for LLVM */ +/* && MEM_P (DECL_RTL (v))*/ + ) +/* APPLE LOCAL end LLVM */ { note_alternative_entry_points (); return true; From kremenek at apple.com Fri Oct 26 15:23:27 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 20:23:27 -0000 Subject: [llvm-commits] [llvm] r43396 - in /llvm/trunk/include/llvm/Bitcode: Deserialize.h Serialization.h Message-ID: <200710262023.l9QKNSgW024139@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 15:23:27 2007 New Revision: 43396 URL: http://llvm.org/viewvc/llvm-project?rev=43396&view=rev Log: Added default implementation of SerializeTrait<> that dispatches to calling member functions of the target type to perform type-specific serialization. Added version of ReadPtr that allows passing references to uintptr_t (useful for smart pointers). Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/include/llvm/Bitcode/Serialization.h Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43396&r1=43395&r2=43396&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Fri Oct 26 15:23:27 2007 @@ -99,7 +99,9 @@ return x; } - void ReadPtr(void*& PtrRef); + void ReadPtr(void*& PtrRef); + void ReadPtr(uintptr_t& PtrRef) { ReadPtr(reinterpret_cast(PtrRef)); } + void RegisterPtr(unsigned PtrId, void* Ptr); Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43396&r1=43395&r2=43396&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Fri Oct 26 15:23:27 2007 @@ -19,6 +19,28 @@ namespace llvm { +/// SerializeTrait - SerializeTrait bridges between the Serializer/Deserializer +/// and the functions that serialize objects of specific types. The default +/// behavior is to call static methods of the class for the object being +/// serialized, but this behavior can be changed by specializing this +/// template. Classes only need to implement the methods corresponding +/// to the serialization scheme they want to support. For example, "Read" +/// and "ReadVal" correspond to different deserialization schemes which make +/// sense for different types; a class need only implement one of them. +/// Serialization and deserialization of pointers are specially handled +/// by the Serializer and Deserializer using the EmitOwnedPtr, etc. methods. +/// To serialize the actual object referred to by a pointer, the class +/// of the object either must implement the methods called by the default +/// behavior of SerializeTrait, or specialize SerializeTrait. This latter +/// is useful when one cannot add methods to an existing class (for example). +template +struct SerializeTrait { + static inline void Emit(Serializer& S, const T& X) { X.Emit(S); } + static inline void Read(Deserializer& D, T& X) { X.Read(D); } + static inline T ReadVal(Deserializer& D) { T::ReadVal(D); } + static inline T* Materialize(Deserializer& D) { T::Materialize(D); } +}; + #define SERIALIZE_INT_TRAIT(TYPE)\ template <> struct SerializeTrait {\ static void Emit(Serializer& S, TYPE X);\ From isanbard at gmail.com Fri Oct 26 15:24:42 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 20:24:42 -0000 Subject: [llvm-commits] [llvm] r43398 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Message-ID: <200710262024.l9QKOg1H024258@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 15:24:42 2007 New Revision: 43398 URL: http://llvm.org/viewvc/llvm-project?rev=43398&view=rev Log: - Remove the hacky code that forces a memcpy. Alignment is taken care of in the FE. - Explicitly pass in the alignment of the load & store. - XFAIL 2007-10-23-UnalignedMemcpy.ll because llc has a bug that crashes on unaligned pointers. Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=43398&r1=43397&r2=43398&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Fri Oct 26 15:24:42 2007 @@ -4329,14 +4329,6 @@ } } - // The lowered load/store instructions from/to the stack frame can be - // unaligned depending on whether it's accessed off sp or fp. If this is - // the case, then just use the memcpy library call. - if (Op1.getOpcode() == ISD::FrameIndex || - Op2.getOpcode() == ISD::FrameIndex) - if (Size->getValue() % Align != 0) - break; - for (unsigned i = 0; i < NumMemOps; i++) { MVT::ValueType VT = MemOps[i]; unsigned VTSize = MVT::getSizeInBits(VT) / 8; @@ -4351,13 +4343,13 @@ I.getOperand(1), DstOff); } else { Value = DAG.getLoad(VT, getRoot(), - getMemBasePlusOffset(Op2, SrcOff, DAG, TLI), - I.getOperand(2), SrcOff); + getMemBasePlusOffset(Op2, SrcOff, DAG, TLI), + I.getOperand(2), SrcOff, false, Align); Chain = Value.getValue(1); Store = DAG.getStore(Chain, Value, getMemBasePlusOffset(Op1, DstOff, DAG, TLI), - I.getOperand(1), DstOff); + I.getOperand(1), DstOff, false, Align); } OutChains.push_back(Store); SrcOff += VTSize; Modified: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll?rev=43398&r1=43397&r2=43398&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Fri Oct 26 15:24:42 2007 @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -o - | grep memcpy +; XFAIL: * @C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> [#uses=1] From isanbard at gmail.com Fri Oct 26 15:27:28 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 20:27:28 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 15:27:28 2007 New Revision: 43399 URL: http://llvm.org/viewvc/llvm-project?rev=43399&view=rev Log: Port of r43394: There are situations where the source and destination alignments differ. This can cause havoc with memcpy. In this case, memcpy is using the alignment of the source pointer and assuming that the destination pointer has the same alignment. Fix this by copying the source pointer node and adjusting the alignment to the minimum of the two alignments. 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=43399&r1=43398&r2=43399&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Oct 26 15:27:28 2007 @@ -2541,7 +2541,25 @@ EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) { - Emit(TREE_OPERAND(exp, 1), LV.Ptr); + // At this point, Alignment is the alignment of the destination + // pointer. It may not match the alignment of the source pointer. So, we + // need to make sure that it's has at least its alignment. + tree new_exp = copy_node(TREE_OPERAND(exp, 1)); + unsigned NewAlignment = expr_align(new_exp) / 8; + Alignment = (Alignment < NewAlignment) ? Alignment : NewAlignment; + TYPE_ALIGN(TREE_TYPE(new_exp)) = Alignment; + + switch (TREE_CODE(new_exp)) { + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + DECL_ALIGN (new_exp) = Alignment * 8; + break; + default: + break; + } + + Emit(new_exp, LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we // emit it into a temporary memory location, then do a volatile copy into From isanbard at gmail.com Fri Oct 26 15:30:58 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 13:30:58 -0700 Subject: [llvm-commits] [llvm] r43398 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll In-Reply-To: <200710262024.l9QKOg1H024258@zion.cs.uiuc.edu> References: <200710262024.l9QKOg1H024258@zion.cs.uiuc.edu> Message-ID: <16e5fdf90710261330i653ec2bcs6503c9fcee17621@mail.gmail.com> On 10/26/07, Bill Wendling wrote: > Author: void > Date: Fri Oct 26 15:24:42 2007 > New Revision: 43398 > > URL: http://llvm.org/viewvc/llvm-project?rev=43398&view=rev > Log: > - XFAIL 2007-10-23-UnalignedMemcpy.ll because llc has a bug that crashes on > unaligned pointers. > Explanation: Chris is looking into the problem with llc crashing on invalid code. That's why I XFAILed this one instead of removing it. -bw From isanbard at gmail.com Fri Oct 26 15:34:39 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 20:34:39 -0000 Subject: [llvm-commits] [llvm] r43400 - /llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Message-ID: <200710262034.l9QKYdN1024702@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 15:34:37 2007 New Revision: 43400 URL: http://llvm.org/viewvc/llvm-project?rev=43400&view=rev Log: On second thought. Remove this as it should never be generated in the first place. Removed: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll Removed: llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll?rev=43399&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll (original) +++ llvm/trunk/test/CodeGen/PowerPC/2007-10-23-UnalignedMemcpy.ll (removed) @@ -1,14 +0,0 @@ -; RUN: llvm-as < %s | llc -mtriple=powerpc64-apple-darwin9 -o - | grep memcpy -; XFAIL: * - - at C.0.1173 = external constant [33 x i8] ; <[33 x i8]*> [#uses=1] - -define void @Bork() { -entry: - %Qux = alloca [33 x i8] ; <[33 x i8]*> [#uses=1] - %Qux1 = bitcast [33 x i8]* %Qux to i8* ; [#uses=1] - call void @llvm.memcpy.i64( i8* %Qux1, i8* getelementptr ([33 x i8]* @C.0.1173, i32 0, i32 0), i64 33, i32 8 ) - ret void -} - -declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) From kremenek at apple.com Fri Oct 26 15:42:45 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 20:42:45 -0000 Subject: [llvm-commits] [llvm] r43401 - /llvm/trunk/include/llvm/ADT/APInt.h Message-ID: <200710262042.l9QKgjhC024995@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 15:42:45 2007 New Revision: 43401 URL: http://llvm.org/viewvc/llvm-project?rev=43401&view=rev Log: Fixed incorrect "path name" in preamble (comment) of header file. Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=43401&r1=43400&r2=43401&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Fri Oct 26 15:42:45 2007 @@ -1,4 +1,4 @@ -//===-- llvm/Support/APInt.h - For Arbitrary Precision Integer -*- C++ -*--===// +//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===// // // The LLVM Compiler Infrastructure // From kremenek at apple.com Fri Oct 26 15:44:03 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 20:44:03 -0000 Subject: [llvm-commits] [llvm] r43402 - /llvm/trunk/include/llvm/ADT/APSInt.h Message-ID: <200710262044.l9QKi3mf025054@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 15:44:02 2007 New Revision: 43402 URL: http://llvm.org/viewvc/llvm-project?rev=43402&view=rev Log: Fixed incorrect "path name" in preamble (comment) of header file. Modified: llvm/trunk/include/llvm/ADT/APSInt.h Modified: llvm/trunk/include/llvm/ADT/APSInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APSInt.h?rev=43402&r1=43401&r2=43402&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APSInt.h (original) +++ llvm/trunk/include/llvm/ADT/APSInt.h Fri Oct 26 15:44:02 2007 @@ -1,4 +1,4 @@ -//===-- llvm/Support/APSInt.h - Arbitrary Precision Signed Int -*- C++ -*--===// +//===-- llvm/ADT/APSInt.h - Arbitrary Precision Signed Int -----*- C++ -*--===// // // The LLVM Compiler Infrastructure // From baldrick at free.fr Fri Oct 26 16:02:06 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 26 Oct 2007 23:02:06 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r43399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> References: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> Message-ID: <200710262302.07224.baldrick@free.fr> Hi Bill, I must say that I don't like this patch at all. Is there no better way? I started to work on something better myself, but unfortunately on my machine (x86-32) the testcase doesn't lead to a memcpy with llvm-gcc-4.2 at all, only a memset. Can you please suggest a testcase that shows the problem with x86-32 linux. Thanks, Duncan. PS: Don't the other two branches of the "if" statement need the same treatment? From isanbard at gmail.com Fri Oct 26 16:15:04 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 14:15:04 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r43399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200710262302.07224.baldrick@free.fr> References: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> <200710262302.07224.baldrick@free.fr> Message-ID: <16e5fdf90710261415s3716e2bew8bec0771a901da7@mail.gmail.com> Hi Duncan, > Hi Bill, I must say that I don't like this patch at all. Is there > no better way? I'm open to suggestions. :-) What part do you object to? I reasoned that we needed to make the memcpy intrinsic have the correct alignment. It is getting its alignment information from the source pointer's alignment, but this could conflict with the destination's alignment. > I started to work on something better myself, but > unfortunately on my machine (x86-32) the testcase doesn't lead to > a memcpy with llvm-gcc-4.2 at all, only a memset. Can you please > suggest a testcase that shows the problem with x86-32 linux. > I've only seen this problem on PPC64. In particular, it's writing this information into the "redzone" because this is a leaf function, and thus the destination may be unaligned. > PS: Don't the other two branches of the "if" statement need the same > treatment? > Possibly...I'll see if I can come up with a testcase for them that fails. -bw From baldrick at free.fr Fri Oct 26 16:31:05 2007 From: baldrick at free.fr (Duncan Sands) Date: Fri, 26 Oct 2007 23:31:05 +0200 Subject: [llvm-commits] [llvm-gcc-4.2] r43399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <16e5fdf90710261415s3716e2bew8bec0771a901da7@mail.gmail.com> References: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> <200710262302.07224.baldrick@free.fr> <16e5fdf90710261415s3716e2bew8bec0771a901da7@mail.gmail.com> Message-ID: <200710262331.05985.baldrick@free.fr> > > Hi Bill, I must say that I don't like this patch at all. Is there > > no better way? > > I'm open to suggestions. :-) What part do you object to? All of it! But let's not go there :) > I've only seen this problem on PPC64. In particular, it's writing this > information into the "redzone" because this is a leaf function, and > thus the destination may be unaligned. Can you please send me the gcc tree dumps, and also what debug_tree gives for the modify_expr. Thanks, Duncan. From kremenek at apple.com Fri Oct 26 16:50:10 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 21:50:10 -0000 Subject: [llvm-commits] [llvm] r43405 - in /llvm/trunk: include/llvm/ADT/APInt.h lib/Bitcode/Reader/DeserializeAPInt.cpp lib/Bitcode/Writer/SerializeAPInt.cpp Message-ID: <200710262150.l9QLoAFk028567@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 16:50:10 2007 New Revision: 43405 URL: http://llvm.org/viewvc/llvm-project?rev=43405&view=rev Log: Added serialization support for APInt. Added: llvm/trunk/lib/Bitcode/Reader/DeserializeAPInt.cpp llvm/trunk/lib/Bitcode/Writer/SerializeAPInt.cpp Modified: llvm/trunk/include/llvm/ADT/APInt.h Modified: llvm/trunk/include/llvm/ADT/APInt.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/APInt.h?rev=43405&r1=43404&r2=43405&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/APInt.h (original) +++ llvm/trunk/include/llvm/ADT/APInt.h Fri Oct 26 16:50:10 2007 @@ -16,6 +16,7 @@ #define LLVM_APINT_H #include "llvm/Support/DataTypes.h" +#include "llvm/Bitcode/SerializationFwd.h" #include #include @@ -203,6 +204,16 @@ /// @brief Destructor. ~APInt(); + + /// Default constructor that creates an uninitialized APInt. This is useful + /// for object deserialization (pair this with the static method Read). + explicit APInt() {} + + /// @brief Used by the Bitcode serializer to emit APInts to Bitcode. + void Emit(Serializer& S) const; + + /// @brief Used by the Bitcode deserializer to deserialize APInts. + void Read(Deserializer& D); /// @} /// @name Value Tests Added: llvm/trunk/lib/Bitcode/Reader/DeserializeAPInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/DeserializeAPInt.cpp?rev=43405&view=auto ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/DeserializeAPInt.cpp (added) +++ llvm/trunk/lib/Bitcode/Reader/DeserializeAPInt.cpp Fri Oct 26 16:50:10 2007 @@ -0,0 +1,33 @@ +//===-- DeserializeAPInt.cpp - Deserialization for APInts ------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements deserialization of APInts. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/APInt.h" +#include "llvm/Bitcode/Deserialize.h" +#include + +using namespace llvm; + +void APInt::Read(Deserializer& D) { + BitWidth = D.ReadInt(); + + if (isSingleWord()) + VAL = D.ReadInt(); + else { + uint32_t NumWords = D.ReadInt(); + assert (NumWords > 1); + pVal = new uint64_t[NumWords]; + assert (pVal && "Allocation in deserialization of APInt failed."); + for (unsigned i = 0; i < NumWords; ++i) + pVal[i] = D.ReadInt(); + } +} Added: llvm/trunk/lib/Bitcode/Writer/SerializeAPInt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/SerializeAPInt.cpp?rev=43405&view=auto ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/SerializeAPInt.cpp (added) +++ llvm/trunk/lib/Bitcode/Writer/SerializeAPInt.cpp Fri Oct 26 16:50:10 2007 @@ -0,0 +1,31 @@ +//===-- SerializeAPInt.cpp - Serialization for APInts ----------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements serialization of APInts. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/APInt.h" +#include "llvm/Bitcode/Serialize.h" +#include + +using namespace llvm; + +void APInt::Emit(Serializer& S) const { + S.EmitInt(BitWidth); + + if (isSingleWord()) + S.EmitInt(VAL); + else { + uint32_t NumWords = getNumWords(); + S.EmitInt(NumWords); + for (unsigned i = 0; i < NumWords; ++i) + S.EmitInt(pVal[i]); + } +} From kremenek at apple.com Fri Oct 26 16:53:37 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 21:53:37 -0000 Subject: [llvm-commits] [llvm] r43406 - /llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Message-ID: <200710262153.l9QLrcsw028713@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 16:53:37 2007 New Revision: 43406 URL: http://llvm.org/viewvc/llvm-project?rev=43406&view=rev Log: Added SerializeAPInt.cpp and DeserializeAPInt.cpp to the XCode project. Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Modified: llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj?rev=43406&r1=43405&r2=43406&view=diff ============================================================================== --- llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj (original) +++ llvm/trunk/Xcode/LLVM.xcodeproj/project.pbxproj Fri Oct 26 16:53:37 2007 @@ -65,6 +65,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 354CF6D10CD299440059AF3E /* DeserializeAPInt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeserializeAPInt.cpp; sourceTree = ""; }; + 354CF6D20CD2994D0059AF3E /* SerializeAPInt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerializeAPInt.cpp; sourceTree = ""; }; 35A9CDED0CD0F6AF008ABC1D /* Deserialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deserialize.h; sourceTree = ""; }; 35A9CDEE0CD0F6AF008ABC1D /* Serialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialization.h; sourceTree = ""; }; 35A9CDEF0CD0F6AF008ABC1D /* Serialize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Serialize.h; sourceTree = ""; }; @@ -1104,6 +1106,7 @@ 9F68EB050C77AD2C004AA152 /* Reader */ = { isa = PBXGroup; children = ( + 354CF6D10CD299440059AF3E /* DeserializeAPInt.cpp */, 35A9CDF00CD0F6D5008ABC1D /* Deserialize.cpp */, 9F68EB060C77AD2C004AA152 /* BitcodeReader.cpp */, 9F68EB070C77AD2C004AA152 /* BitcodeReader.h */, @@ -1114,6 +1117,7 @@ 9F68EB110C77AD2C004AA152 /* Writer */ = { isa = PBXGroup; children = ( + 354CF6D20CD2994D0059AF3E /* SerializeAPInt.cpp */, 9FD3E5920CA012B300E54D15 /* BitWriter.cpp */, 9F68EB120C77AD2C004AA152 /* BitcodeWriter.cpp */, 9F68EB130C77AD2C004AA152 /* BitcodeWriterPass.cpp */, From evan.cheng at apple.com Fri Oct 26 18:08:20 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Fri, 26 Oct 2007 23:08:20 -0000 Subject: [llvm-commits] [llvm] r43408 - /llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Message-ID: <200710262308.l9QN8KAT002137@zion.cs.uiuc.edu> Author: evancheng Date: Fri Oct 26 18:08:19 2007 New Revision: 43408 URL: http://llvm.org/viewvc/llvm-project?rev=43408&view=rev Log: A number of LSR fixes: - ChangeCompareStride only reuse stride that is larger than current stride. It will let the general reuse mechanism to try to reuse a smaller stride. - Watch out for multiplication overflow in ChangeCompareStride. - Replace std::set with SmallPtrSet. Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=43408&r1=43407&r2=43408&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Fri Oct 26 18:08:19 2007 @@ -31,6 +31,7 @@ #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Target/TargetData.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" @@ -135,7 +136,7 @@ /// DeadInsts - Keep track of instructions we may have made dead, so that /// we can remove them after we are done working. - std::set DeadInsts; + SmallPtrSet DeadInsts; /// TLI - Keep a pointer of a TargetLowering to consult for determining /// transformation profitability. @@ -169,7 +170,7 @@ Value *getCastedVersionOf(Instruction::CastOps opcode, Value *V); private: bool AddUsersIfInteresting(Instruction *I, Loop *L, - std::set &Processed); + SmallPtrSet &Processed); SCEVHandle GetExpressionSCEV(Instruction *E, Loop *L); ICmpInst *ChangeCompareStride(Loop *L, ICmpInst *Cond, IVStrideUse* &CondUse, @@ -191,7 +192,7 @@ void StrengthReduceStridedIVUsers(const SCEVHandle &Stride, IVUsersOfOneStride &Uses, Loop *L, bool isOnlyStride); - void DeleteTriviallyDeadInstructions(std::set &Insts); + void DeleteTriviallyDeadInstructions(SmallPtrSet &Insts); }; char LoopStrengthReduce::ID = 0; RegisterPass X("loop-reduce", "Loop Strength Reduction"); @@ -223,10 +224,10 @@ /// specified set are trivially dead, delete them and see if this makes any of /// their operands subsequently dead. void LoopStrengthReduce:: -DeleteTriviallyDeadInstructions(std::set &Insts) { +DeleteTriviallyDeadInstructions(SmallPtrSet &Insts) { while (!Insts.empty()) { Instruction *I = *Insts.begin(); - Insts.erase(Insts.begin()); + Insts.erase(I); if (isInstructionTriviallyDead(I)) { for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (Instruction *U = dyn_cast(I->getOperand(i))) @@ -409,10 +410,10 @@ /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. bool LoopStrengthReduce::AddUsersIfInteresting(Instruction *I, Loop *L, - std::set &Processed) { + SmallPtrSet &Processed) { if (!I->getType()->isInteger() && !isa(I->getType())) return false; // Void and FP expressions cannot be reduced. - if (!Processed.insert(I).second) + if (!Processed.insert(I)) return true; // Instruction already handled. // Get the symbolic expression for this instruction. @@ -1470,16 +1471,16 @@ if (!C) return Cond; ICmpInst::Predicate Predicate = Cond->getPredicate(); - bool isSigned = ICmpInst::isSignedPredicate(Predicate); int64_t CmpSSInt = SC->getValue()->getSExtValue(); int64_t CmpVal = C->getValue().getSExtValue(); - uint64_t SignBit = 1ULL << (C->getValue().getBitWidth()-1); + unsigned BitWidth = C->getValue().getBitWidth(); + uint64_t SignBit = 1ULL << (BitWidth-1); + const Type *CmpTy = C->getType(); + const Type *NewCmpTy = NULL; int64_t NewCmpVal = CmpVal; SCEVHandle *NewStride = NULL; Value *NewIncV = NULL; int64_t Scale = 1; - const Type *CmpTy = C->getType(); - const Type *NewCmpTy = NULL; // Look for a suitable stride / iv as replacement. std::stable_sort(StrideOrder.begin(), StrideOrder.end(), StrideCompare()); @@ -1489,18 +1490,23 @@ if (!isa(SI->first)) continue; int64_t SSInt = cast(SI->first)->getValue()->getSExtValue(); - if (abs(SSInt) < abs(CmpSSInt) && (CmpSSInt % SSInt) == 0) { - Scale = CmpSSInt / SSInt; - NewCmpVal = CmpVal / Scale; - } else if (abs(SSInt) > abs(CmpSSInt) && (SSInt % CmpSSInt) == 0) { - Scale = SSInt / CmpSSInt; - NewCmpVal = CmpVal * Scale; - } else + if (abs(SSInt) <= abs(CmpSSInt) || (SSInt % CmpSSInt) != 0) continue; + Scale = SSInt / CmpSSInt; + NewCmpVal = CmpVal * Scale; + APInt Mul = APInt(BitWidth, NewCmpVal); + // Check for overflow. + if (Mul.getSExtValue() != NewCmpVal) { + NewCmpVal = CmpVal; + continue; + } + // Watch out for overflow. - if (isSigned && (CmpVal & SignBit) != (NewCmpVal & SignBit)) + if (ICmpInst::isSignedPredicate(Predicate) && + (CmpVal & SignBit) != (NewCmpVal & SignBit)) NewCmpVal = CmpVal; + if (NewCmpVal != CmpVal) { // Pick the best iv to use trying to avoid a cast. NewIncV = NULL; @@ -1517,7 +1523,6 @@ NewCmpTy = NewIncV->getType(); if (RequiresTypeConversion(CmpTy, NewCmpTy)) { - // FIXME: allow reuse of iv of a smaller type? NewCmpVal = CmpVal; continue; } @@ -1556,11 +1561,17 @@ else RHS = SCEVExpander::InsertCastOfTo(Instruction::BitCast, RHS, NewCmpTy); } + // Insert new compare instruction. Cond = new ICmpInst(Predicate, NewIncV, RHS); Cond->setName(L->getHeader()->getName() + ".termcond"); OldCond->getParent()->getInstList().insert(OldCond, Cond); + + // Remove the old compare instruction. The old indvar is probably dead too. + DeadInsts.insert(cast(CondUse->OperandValToReplace)); OldCond->replaceAllUsesWith(Cond); + SE->deleteValueFromRecords(OldCond); OldCond->eraseFromParent(); + IVUsesByStride[*CondStride].Users.pop_back(); SCEVHandle NewOffset = SE->getMulExpr(CondUse->Offset, SE->getConstant(ConstantInt::get(CondUse->Offset->getType(), Scale))); @@ -1641,7 +1652,7 @@ // Find all uses of induction variables in this loop, and catagorize // them by stride. Start by finding all of the PHI nodes in the header for // this loop. If they are induction variables, inspect their uses. - std::set Processed; // Don't reprocess instructions. + SmallPtrSet Processed; // Don't reprocess instructions. for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) AddUsersIfInteresting(I, L, Processed); From isanbard at gmail.com Fri Oct 26 18:30:24 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 23:30:24 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43410 - /llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Message-ID: <200710262330.l9QNUOO9003799@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 18:30:22 2007 New Revision: 43410 URL: http://llvm.org/viewvc/llvm-project?rev=43410&view=rev Log: Reverting patch as it doesn't appear that this happens with TOT 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=43410&r1=43409&r2=43410&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.0/trunk/gcc/llvm-convert.cpp Fri Oct 26 18:30:22 2007 @@ -3021,25 +3021,7 @@ EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0)) != RESULT_DECL) { - // At this point, Alignment is the alignment of the destination - // pointer. It may not match the alignment of the source pointer. So, we - // need to make sure that it's has at least its alignment. - tree new_exp = copy_node(TREE_OPERAND(exp, 1)); - unsigned NewAlignment = expr_align(new_exp) / 8; - Alignment = (Alignment < NewAlignment) ? Alignment : NewAlignment; - TYPE_ALIGN(TREE_TYPE(new_exp)) = Alignment; - - switch (TREE_CODE(new_exp)) { - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - DECL_ALIGN (new_exp) = Alignment * 8; - break; - default: - break; - } - - Emit(new_exp, LV.Ptr); + Emit(TREE_OPERAND(exp, 1), LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we // emit it into a temporary memory location, then do a volatile copy into From isanbard at gmail.com Fri Oct 26 18:31:41 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 23:31:41 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43411 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Message-ID: <200710262331.l9QNVfd4003964@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 18:31:40 2007 New Revision: 43411 URL: http://llvm.org/viewvc/llvm-project?rev=43411&view=rev Log: Reverting r43399 because it doesn't appear to happen with TOT anymore 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=43411&r1=43410&r2=43411&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original) +++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Fri Oct 26 18:31:40 2007 @@ -2541,25 +2541,7 @@ EmitAggregateCopy(DestLoc, LV.Ptr, TREE_TYPE(exp), isVolatile, false, Alignment); } else if (!isVolatile && TREE_CODE(TREE_OPERAND(exp, 0))!=RESULT_DECL) { - // At this point, Alignment is the alignment of the destination - // pointer. It may not match the alignment of the source pointer. So, we - // need to make sure that it's has at least its alignment. - tree new_exp = copy_node(TREE_OPERAND(exp, 1)); - unsigned NewAlignment = expr_align(new_exp) / 8; - Alignment = (Alignment < NewAlignment) ? Alignment : NewAlignment; - TYPE_ALIGN(TREE_TYPE(new_exp)) = Alignment; - - switch (TREE_CODE(new_exp)) { - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - DECL_ALIGN (new_exp) = Alignment * 8; - break; - default: - break; - } - - Emit(new_exp, LV.Ptr); + Emit(TREE_OPERAND(exp, 1), LV.Ptr); } else { // Need to do a volatile store into TREE_OPERAND(exp, 1). To do this, we // emit it into a temporary memory location, then do a volatile copy into From isanbard at gmail.com Fri Oct 26 18:34:39 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 16:34:39 -0700 Subject: [llvm-commits] [llvm-gcc-4.2] r43399 - /llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp In-Reply-To: <200710262331.05985.baldrick@free.fr> References: <200710262027.l9QKRSbh024383@zion.cs.uiuc.edu> <200710262302.07224.baldrick@free.fr> <16e5fdf90710261415s3716e2bew8bec0771a901da7@mail.gmail.com> <200710262331.05985.baldrick@free.fr> Message-ID: <16e5fdf90710261634j78b1d2dy25ffafbb71221de3@mail.gmail.com> On 10/26/07, Duncan Sands wrote: > > > Hi Bill, I must say that I don't like this patch at all. Is there > > > no better way? > > > > I'm open to suggestions. :-) What part do you object to? > > All of it! But let's not go there :) > > > I've only seen this problem on PPC64. In particular, it's writing this > > information into the "redzone" because this is a leaf function, and > > thus the destination may be unaligned. > > Can you please send me the gcc tree dumps, and also what debug_tree > gives for the modify_expr. > I'm no longer able to reproduce it with TOT minus my patch. I reverted the patches to llvm-convert.cpp in 4.0 and 4.2. I'm going to add a test to make sure that this continues to work. -bw From isanbard at gmail.com Fri Oct 26 18:43:35 2007 From: isanbard at gmail.com (Bill Wendling) Date: Fri, 26 Oct 2007 23:43:35 -0000 Subject: [llvm-commits] [llvm] r43412 - /llvm/trunk/test/CFrontend/unaligned-memcpy.c Message-ID: <200710262343.l9QNhZF8005075@zion.cs.uiuc.edu> Author: void Date: Fri Oct 26 18:43:35 2007 New Revision: 43412 URL: http://llvm.org/viewvc/llvm-project?rev=43412&view=rev Log: Test to make sure that if we have an unaligned memcpy, it will still compile. Added: llvm/trunk/test/CFrontend/unaligned-memcpy.c Added: llvm/trunk/test/CFrontend/unaligned-memcpy.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CFrontend/unaligned-memcpy.c?rev=43412&view=auto ============================================================================== --- llvm/trunk/test/CFrontend/unaligned-memcpy.c (added) +++ llvm/trunk/test/CFrontend/unaligned-memcpy.c Fri Oct 26 18:43:35 2007 @@ -0,0 +1,5 @@ +// RUN: %llvmgcc %s -S -emit-llvm -o - | llvm-as | llc + +void bork() { + char Qux[33] = {0}; +} From kremenek at apple.com Fri Oct 26 18:44:59 2007 From: kremenek at apple.com (Ted Kremenek) Date: Fri, 26 Oct 2007 23:44:59 -0000 Subject: [llvm-commits] [llvm] r43413 - /llvm/trunk/include/llvm/Bitcode/Serialization.h Message-ID: <200710262344.l9QNixHv005157@zion.cs.uiuc.edu> Author: kremenek Date: Fri Oct 26 18:44:59 2007 New Revision: 43413 URL: http://llvm.org/viewvc/llvm-project?rev=43413&view=rev Log: Fixed bug where default SerializeTrait<>::Materialize would not return the materialized object pointer. Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h Modified: llvm/trunk/include/llvm/Bitcode/Serialization.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Serialization.h?rev=43413&r1=43412&r2=43413&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Serialization.h (original) +++ llvm/trunk/include/llvm/Bitcode/Serialization.h Fri Oct 26 18:44:59 2007 @@ -38,7 +38,7 @@ static inline void Emit(Serializer& S, const T& X) { X.Emit(S); } static inline void Read(Deserializer& D, T& X) { X.Read(D); } static inline T ReadVal(Deserializer& D) { T::ReadVal(D); } - static inline T* Materialize(Deserializer& D) { T::Materialize(D); } + static inline T* Materialize(Deserializer& D) { return T::Materialize(D); } }; #define SERIALIZE_INT_TRAIT(TYPE)\ From dalej at apple.com Fri Oct 26 19:26:49 2007 From: dalej at apple.com (Dale Johannesen) Date: Sat, 27 Oct 2007 00:26:49 -0000 Subject: [llvm-commits] [llvm-gcc-4.0] r43415 - /llvm-gcc-4.0/trunk/gcc/config/i386/i386.c Message-ID: <200710270026.l9R0Qnjq009457@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 26 19:26:49 2007 New Revision: 43415 URL: http://llvm.org/viewvc/llvm-project?rev=43415&view=rev Log: (inline asm) comment out one more place DECL_RTL is referenced Modified: llvm-gcc-4.0/trunk/gcc/config/i386/i386.c Modified: llvm-gcc-4.0/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.0/trunk/gcc/config/i386/i386.c?rev=43415&r1=43414&r2=43415&view=diff ============================================================================== --- llvm-gcc-4.0/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.0/trunk/gcc/config/i386/i386.c Fri Oct 26 19:26:49 2007 @@ -19711,8 +19711,12 @@ v = TREE_OPERAND (v, 0); if (TREE_CODE (v) == VAR_DECL && TREE_STATIC (v) - && MEM_P (DECL_RTL (v))) - return true; +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL is not set for LLVM */ +/* && MEM_P (DECL_RTL (v))*/ + ) +/* APPLE LOCAL end LLVM */ + return true; if (TREE_CODE (v) == LABEL_DECL) return true; return false; From dalej at apple.com Fri Oct 26 19:38:34 2007 From: dalej at apple.com (Dale Johannesen) Date: Sat, 27 Oct 2007 00:38:34 -0000 Subject: [llvm-commits] [llvm-gcc-4.2] r43416 - /llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Message-ID: <200710270038.l9R0cYEx010310@zion.cs.uiuc.edu> Author: johannes Date: Fri Oct 26 19:38:33 2007 New Revision: 43416 URL: http://llvm.org/viewvc/llvm-project?rev=43416&view=rev Log: (inline asm) one more place DECL_RTL is used Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Modified: llvm-gcc-4.2/trunk/gcc/config/i386/i386.c URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/i386/i386.c?rev=43416&r1=43415&r2=43416&view=diff ============================================================================== --- llvm-gcc-4.2/trunk/gcc/config/i386/i386.c (original) +++ llvm-gcc-4.2/trunk/gcc/config/i386/i386.c Fri Oct 26 19:38:33 2007 @@ -20532,7 +20532,11 @@ v = TREE_OPERAND (v, 0); if (TREE_CODE (v) == VAR_DECL && TREE_STATIC (v) - && MEM_P (DECL_RTL (v))) +/* APPLE LOCAL begin LLVM */ +/* DECL_RTL is not set for LLVM */ +/* && MEM_P (DECL_RTL (v))*/ + ) +/* APPLE LOCAL end LLVM */ { note_alternative_entry_points (); return true; From evan.cheng at apple.com Sat Oct 27 23:01:13 2007 From: evan.cheng at apple.com (Evan Cheng) Date: Sun, 28 Oct 2007 04:01:13 -0000 Subject: [llvm-commits] [llvm] r43420 - /llvm/trunk/lib/Target/X86/README.txt Message-ID: <200710280401.l9S41DmV013470@zion.cs.uiuc.edu> Author: evancheng Date: Sat Oct 27 23:01:09 2007 New Revision: 43420 URL: http://llvm.org/viewvc/llvm-project?rev=43420&view=rev Log: New entry. 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=43420&r1=43419&r2=43420&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/README.txt (original) +++ llvm/trunk/lib/Target/X86/README.txt Sat Oct 27 23:01:09 2007 @@ -1429,3 +1429,65 @@ + } + } //===---------------------------------------------------------------------===// + +main () +{ + int i = 0; + unsigned long int z = 0; + + do { + z -= 0x00004000; + i++; + if (i > 0x00040000) + abort (); + } while (z > 0); + exit (0); +} + +gcc compiles this to: + +_main: + subl $28, %esp + xorl %eax, %eax + jmp L2 +L3: + cmpl $262144, %eax + je L10 +L2: + addl $1, %eax + cmpl $262145, %eax + jne L3 + call L_abort$stub +L10: + movl $0, (%esp) + call L_exit$stub + +llvm: + +_main: + subl $12, %esp + movl $1, %eax + movl $16384, %ecx +LBB1_1: # bb + cmpl $262145, %eax + jge LBB1_4 # cond_true +LBB1_2: # cond_next + incl %eax + addl $4294950912, %ecx + cmpl $16384, %ecx + jne LBB1_1 # bb +LBB1_3: # bb11 + xorl %eax, %eax + addl $12, %esp + ret +LBB1_4: # cond_true + call L_abort$stub + +1. LSR should rewrite the first cmp with induction variable %ecx. +2. DAG combiner should fold + leal 1(%eax), %edx + cmpl $262145, %edx + => + cmpl $262144, %eax + +//===---------------------------------------------------------------------===// From baldrick at free.fr Sun Oct 28 07:59:45 2007 From: baldrick at free.fr (Duncan Sands) Date: Sun, 28 Oct 2007 12:59:45 -0000 Subject: [llvm-commits] [llvm] r43421 - in /llvm/trunk: include/llvm/Support/Alignment.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Message-ID: <200710281259.l9SCxkBh003841@zion.cs.uiuc.edu> Author: baldrick Date: Sun Oct 28 07:59:45 2007 New Revision: 43421 URL: http://llvm.org/viewvc/llvm-project?rev=43421&view=rev Log: The guaranteed alignment of ptr+offset is only the minimum of of offset and the alignment of ptr if these are both powers of 2. While the ptr alignment is guaranteed to be a power of 2, there is no reason to think that offset is. For example, if offset is 12 (the size of a long double on x86-32 linux) and the alignment of ptr is 8, then the alignment of ptr+offset will in general be 4, not 8. Introduce a function MinAlign, lifted from gcc, for computing the minimum guaranteed alignment. I've tried to fix up everywhere under lib/CodeGen/SelectionDAG/. I also changed some places that weren't wrong (because both values were a power of 2), as a defensive change against people copying and pasting the code. Hopefully someone who cares about alignment will review the rest of LLVM and fix up the remaining places. Since I'm on x86 I'm not very motivated to do this myself... Added: llvm/trunk/include/llvm/Support/Alignment.h Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Added: llvm/trunk/include/llvm/Support/Alignment.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Alignment.h?rev=43421&view=auto ============================================================================== --- llvm/trunk/include/llvm/Support/Alignment.h (added) +++ llvm/trunk/include/llvm/Support/Alignment.h Sun Oct 28 07:59:45 2007 @@ -0,0 +1,28 @@ +//===----------- Alignment.h - Alignment computation ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Duncan Sands and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities for computing alignments. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ALIGNMENT_H +#define LLVM_SUPPORT_ALIGNMENT_H + +namespace llvm { + +/// MinAlign - A and B are either alignments or offsets. Return the minimum +/// alignment that may be assumed after adding the two together. + +static inline unsigned MinAlign(unsigned A, unsigned B) { + // The largest power of 2 that divides both A and B. + return (A | B) & -(A | B); +} + +} // end namespace llvm +#endif Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=43421&r1=43420&r2=43421&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Oct 28 07:59:45 2007 @@ -37,6 +37,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -1713,15 +1714,18 @@ // read fewer bytes from the same pointer. unsigned PtrOff = (MVT::getSizeInBits(LoadedVT) - MVT::getSizeInBits(EVT)) / 8; + unsigned Alignment = LN0->getAlignment(); SDOperand NewPtr = LN0->getBasePtr(); - if (!TLI.isLittleEndian()) + if (!TLI.isLittleEndian()) { NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, DAG.getConstant(PtrOff, PtrType)); + Alignment = MinAlign(Alignment, PtrOff); + } AddToWorkList(NewPtr.Val); SDOperand Load = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), Alignment); AddToWorkList(N); CombineTo(N0.Val, Load, Load.getValue(1)); return SDOperand(N, 0); // Return N so it doesn't get rechecked! @@ -2879,16 +2883,17 @@ if (!TLI.isLittleEndian()) ShAmt = MVT::getSizeInBits(N0.getValueType()) - ShAmt - EVTBits; uint64_t PtrOff = ShAmt / 8; + unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); SDOperand NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.Val); SDOperand Load = (ExtType == ISD::NON_EXTLOAD) ? DAG.getLoad(VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), - LN0->isVolatile(), LN0->getAlignment()) + LN0->isVolatile(), NewAlign) : DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), LN0->getAlignment()); + LN0->isVolatile(), NewAlign); AddToWorkList(N); if (CombineSRL) { DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1)); @@ -3905,8 +3910,8 @@ // Replace the chain to void dependency. if (LD->getExtensionType() == ISD::NON_EXTLOAD) { ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr, - LD->getSrcValue(), LD->getSrcValueOffset(), - LD->isVolatile(), LD->getAlignment()); + LD->getSrcValue(), LD->getSrcValueOffset(), + LD->isVolatile(), LD->getAlignment()); } else { ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getValueType(0), @@ -3980,7 +3985,7 @@ ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } else if (TLI.isTypeLegal(MVT::i32)) { - // Many FP stores are not make apparent until after legalize, e.g. for + // Many FP stores are not made apparent until after legalize, e.g. for // argument passing. Since this is so common, custom legalize the // 64-bit integer store into two 32-bit stores. uint64_t Val = CFP->getValueAPF().convertToAPInt().getZExtValue(); @@ -3998,8 +4003,7 @@ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, DAG.getConstant(4, Ptr.getValueType())); SVOffset += 4; - if (Alignment > 4) - Alignment = 4; + Alignment = MinAlign(Alignment, 4U); SDOperand St1 = DAG.getStore(Chain, Hi, Ptr, ST->getSrcValue(), SVOffset, isVolatile, Alignment); return DAG.getNode(ISD::TokenFactor, MVT::Other, St0, St1); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=43421&r1=43420&r2=43421&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Sun Oct 28 07:59:45 2007 @@ -23,9 +23,10 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -602,6 +603,7 @@ ST->isVolatile(), Alignment); Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); + Alignment = MinAlign(Alignment, IncrementSize); Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr, ST->getSrcValue(), SVOffset + IncrementSize, NewStoredVT, ST->isVolatile(), Alignment); @@ -660,7 +662,7 @@ DAG.getConstant(IncrementSize, TLI.getPointerTy())); Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } else { Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset, NewLoadedVT,LD->isVolatile(), Alignment); @@ -668,7 +670,7 @@ DAG.getConstant(IncrementSize, TLI.getPointerTy())); Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), - Alignment); + MinAlign(Alignment, IncrementSize)); } // aggregate the two parts @@ -2055,7 +2057,7 @@ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, getIntPtrConstant(4)); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, - isVolatile, std::max(Alignment, 4U)); + isVolatile, MinAlign(Alignment, 4U)); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); break; @@ -2164,8 +2166,7 @@ assert(isTypeLegal(Tmp2.getValueType()) && "Pointers must be legal!"); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); @@ -5429,8 +5430,7 @@ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset, isVolatile, Alignment); @@ -6336,8 +6336,7 @@ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; - if (Alignment > IncrementSize) - Alignment = IncrementSize; + Alignment = MinAlign(Alignment, IncrementSize); Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp?rev=43421&r1=43420&r2=43421&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp Sun Oct 28 07:59:45 2007 @@ -18,6 +18,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Target/TargetLowering.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -946,7 +947,7 @@ Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, getIntPtrConstant(IncrementSize)); Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -994,7 +995,7 @@ getIntPtrConstant(IncrementSize)); Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -1019,7 +1020,7 @@ // Load the rest of the low bits. Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, MVT::getIntegerType(ExcessBits), - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. @@ -2002,7 +2003,7 @@ getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); Hi = DAG.getStore(Chain, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, - isVolatile, std::max(Alignment, IncrementSize)); + isVolatile, MinAlign(Alignment, IncrementSize)); return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); } From kremenek at apple.com Sun Oct 28 16:18:01 2007 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 28 Oct 2007 21:18:01 -0000 Subject: [llvm-commits] [llvm] r43422 - in /llvm/trunk: include/llvm/Bitcode/Deserialize.h lib/Bitcode/Reader/Deserialize.cpp Message-ID: <200710282118.l9SLI1Nd024985@zion.cs.uiuc.edu> Author: kremenek Date: Sun Oct 28 16:17:59 2007 New Revision: 43422 URL: http://llvm.org/viewvc/llvm-project?rev=43422&view=rev Log: Updated backpatching logic during object deserialization to perform eager backpatching instead of waithing until all objects have been deserialized. This allows us to reduce the memory footprint needed for backpatching. Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Modified: llvm/trunk/include/llvm/Bitcode/Deserialize.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/Deserialize.h?rev=43422&r1=43421&r2=43422&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/Deserialize.h (original) +++ llvm/trunk/include/llvm/Bitcode/Deserialize.h Sun Oct 28 16:17:59 2007 @@ -26,11 +26,11 @@ namespace llvm { class Deserializer { - BitstreamReader& Stream; - SmallVector Record; - unsigned RecIdx; - BumpPtrAllocator Allocator; - + + //===----------------------------------------------------------===// + // Internal type definitions. + //===----------------------------------------------------------===// + struct PtrIdInfo { static inline unsigned getEmptyKey() { return ~((unsigned) 0x0); } static inline unsigned getTombstoneKey() { return getEmptyKey()-1; } @@ -39,26 +39,58 @@ static inline bool isPod() { return true; } }; - struct BPatchNode { - BPatchNode* const Next; + struct BPNode { + BPNode* Next; uintptr_t& PtrRef; - BPatchNode(BPatchNode* n, void*& pref) - : Next(n), PtrRef(reinterpret_cast(pref)) { + BPNode(BPNode* n, uintptr_t& pref) + : Next(n), PtrRef(pref) { PtrRef = 0; } }; - struct BPatchEntry { - BPatchNode* Head; - void* Ptr; - BPatchEntry() : Head(NULL), Ptr(NULL) {} + class BPatchEntry { + uintptr_t Ptr; + public: + + BPatchEntry() : Ptr(0x1) {} + + BPatchEntry(void* P) : Ptr(reinterpret_cast(P)) {} + + bool hasFinalPtr() const { return Ptr & 0x1 ? true : false; } + void setFinalPtr(BPNode*& FreeList, void* P); + + BPNode* getBPNode() const { + assert (!hasFinalPtr()); + return reinterpret_cast(Ptr & ~0x1); + } + + void setBPNode(BPNode* N) { + assert (!hasFinalPtr()); + Ptr = reinterpret_cast(N) | 0x1; + } + + uintptr_t getRawPtr() const { return Ptr; } + static inline bool isPod() { return true; } - }; - + }; + typedef llvm::DenseMap MapTy; + //===----------------------------------------------------------===// + // Internal data members. + //===----------------------------------------------------------===// + + BitstreamReader& Stream; + SmallVector Record; + unsigned RecIdx; + BumpPtrAllocator Allocator; + BPNode* FreeList; MapTy BPatchMap; + //===----------------------------------------------------------===// + // Public Interface. + //===----------------------------------------------------------===// + public: Deserializer(BitstreamReader& stream); ~Deserializer(); @@ -99,13 +131,15 @@ return x; } - void ReadPtr(void*& PtrRef); - void ReadPtr(uintptr_t& PtrRef) { ReadPtr(reinterpret_cast(PtrRef)); } + template + void ReadPtr(T*& PtrRef) { ReadUIntPtr(reinterpret_cast(PtrRef));} + + void ReadPtr(uintptr_t& PtrRef) { ReadUIntPtr(PtrRef); } + + void ReadUIntPtr(uintptr_t& PtrRef); void RegisterPtr(unsigned PtrId, void* Ptr); - - void BackpatchPointers(); private: void ReadRecord(); bool inRecord(); Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43422&r1=43421&r2=43422&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Sun Oct 28 16:17:59 2007 @@ -16,14 +16,14 @@ using namespace llvm; Deserializer::Deserializer(BitstreamReader& stream) - : Stream(stream), RecIdx(0) { + : Stream(stream), RecIdx(0), FreeList(NULL) { } Deserializer::~Deserializer() { assert (RecIdx >= Record.size() && "Still scanning bitcode record when deserialization completed."); - BackpatchPointers(); + assert (FreeList == NULL && "Some pointers were not backpatched."); } @@ -96,11 +96,11 @@ void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) { BPatchEntry& E = BPatchMap[PtrId]; - assert (E.Ptr == NULL && "Pointer already registered."); - E.Ptr = Ptr; + assert (E.hasFinalPtr() && "Pointer already registered."); + E.setFinalPtr(FreeList,Ptr); } -void Deserializer::ReadPtr(void*& PtrRef) { +void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) { unsigned PtrId = ReadInt(); if (PtrId == 0) { @@ -110,32 +110,46 @@ BPatchEntry& E = BPatchMap[PtrId]; - if (E.Ptr == NULL) { - // Register backpatch. - void* P = Allocator.Allocate(); - E.Head = new (P) BPatchNode(E.Head,PtrRef); + if (E.hasFinalPtr()) + PtrRef = E.getRawPtr(); + else { + // Register backpatch. Check the freelist for a BPNode. + BPNode* N; + + if (FreeList) { + N = FreeList; + FreeList = FreeList->Next; + } + else // No available BPNode. Allocate one. + N = (BPNode*) Allocator.Allocate(); + + new (N) BPNode(E.getBPNode(),PtrRef); + E.setBPNode(N); } - else - PtrRef = E.Ptr; } -void Deserializer::BackpatchPointers() { - for (MapTy::iterator I=BPatchMap.begin(),E=BPatchMap.end(); I!=E; ++I) { - - BPatchEntry& Entry = I->second; - assert (Entry.Ptr && "No pointer found for backpatch."); - - for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next) - // Bitwise-OR in the pointer to support "smart" pointers that use - // unused bits to store extra data. - N->PtrRef |= reinterpret_cast(Entry.Ptr); - - Entry.Head = NULL; + +void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) { + assert (!hasFinalPtr()); + + // Perform backpatching. + + BPNode* Last = NULL; + + for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) { + Last = N; + N->PtrRef |= reinterpret_cast(P); } - Allocator.Reset(); + if (Last) { + Last->Next = FreeList; + FreeList = getBPNode(); + } + + Ptr = reinterpret_cast(P); } + #define INT_READ(TYPE)\ void SerializeTrait::Read(Deserializer& D, TYPE& X) {\ X = (TYPE) D.ReadInt(); }\ From asl at math.spbu.ru Sun Oct 28 17:50:32 2007 From: asl at math.spbu.ru (Anton Korobeynikov) Date: Sun, 28 Oct 2007 22:50:32 -0000 Subject: [llvm-commits] [llvm] r43424 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200710282250.l9SMoWI9028509@zion.cs.uiuc.edu> Author: asl Date: Sun Oct 28 17:50:32 2007 New Revision: 43424 URL: http://llvm.org/viewvc/llvm-project?rev=43424&view=rev Log: Add 'pedantic' mode to verifier rejecting syntactically valid, but 'bad' due to other reasons code Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=43424&r1=43423&r2=43424&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sun Oct 28 17:50:32 2007 @@ -60,6 +60,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include #include @@ -67,7 +68,10 @@ using namespace llvm; namespace { // Anonymous namespace for class - + cl::opt + Pedantic("pedantic", + cl::desc("Reject code with undefined behaviour")); + struct VISIBILITY_HIDDEN Verifier : public FunctionPass, InstVisitor { static char ID; // Pass ID, replacement for typeid @@ -806,10 +810,17 @@ "Call parameter type does not match function signature!", CI.getOperand(i+1), FTy->getParamType(i), &CI); - if (Function *F = CI.getCalledFunction()) + if (Function *F = CI.getCalledFunction()) { + if (Pedantic) { + // Verify that calling convention of Function and CallInst match + Assert1(F->getCallingConv() == CI.getCallingConv(), + "Call uses different calling convention than function", &CI); + } + if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) visitIntrinsicFunctionCall(ID, CI); - + } + visitInstruction(CI); } From kremenek at apple.com Sun Oct 28 18:38:41 2007 From: kremenek at apple.com (Ted Kremenek) Date: Sun, 28 Oct 2007 23:38:41 -0000 Subject: [llvm-commits] [llvm] r43425 - /llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Message-ID: <200710282338.l9SNcfp3030269@zion.cs.uiuc.edu> Author: kremenek Date: Sun Oct 28 18:38:38 2007 New Revision: 43425 URL: http://llvm.org/viewvc/llvm-project?rev=43425&view=rev Log: Fixed assertion in Deserializer::~Deserializer that checks for pointers that were not backpatched (previously checked the wrong invariant). Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Modified: llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp?rev=43425&r1=43424&r2=43425&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/Deserialize.cpp Sun Oct 28 18:38:38 2007 @@ -22,8 +22,12 @@ Deserializer::~Deserializer() { assert (RecIdx >= Record.size() && "Still scanning bitcode record when deserialization completed."); - - assert (FreeList == NULL && "Some pointers were not backpatched."); + +#ifdef NDEBUG + for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I) + assert (I->second.hasFinalPtr() && + "Some pointers were not backpatched."); +#endif } From sabre at nondot.org Sun Oct 28 21:30:38 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 29 Oct 2007 02:30:38 -0000 Subject: [llvm-commits] [llvm] r43426 - in /llvm/trunk: lib/Transforms/Utils/LoopSimplify.cpp test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll Message-ID: <200710290230.l9T2Uc0O004559@zion.cs.uiuc.edu> Author: lattner Date: Sun Oct 28 21:30:37 2007 New Revision: 43426 URL: http://llvm.org/viewvc/llvm-project?rev=43426&view=rev Log: Fix PR1752 and LoopSimplify/2007-10-28-InvokeCrash.ll: terminators can have uses too. Wouldn't it be nice if invoke didn't exist? :) Added: llvm/trunk/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Modified: llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp?rev=43426&r1=43425&r2=43426&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LoopSimplify.cpp Sun Oct 28 21:30:37 2007 @@ -34,7 +34,7 @@ #define DEBUG_TYPE "loopsimplify" #include "llvm/Transforms/Scalar.h" -#include "llvm/Constant.h" +#include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/Type.h" @@ -158,12 +158,14 @@ for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) TI->getSuccessor(i)->removePredecessor(BB); - // Add a new unreachable instruction. + // Add a new unreachable instruction before the old terminator. new UnreachableInst(TI); // Delete the dead terminator. - if (AA) AA->deleteValue(&BB->back()); - BB->getInstList().pop_back(); + if (AA) AA->deleteValue(TI); + if (!TI->use_empty()) + TI->replaceAllUsesWith(UndefValue::get(TI->getType())); + TI->eraseFromParent(); Changed |= true; } Added: llvm/trunk/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll?rev=43426&view=auto ============================================================================== --- llvm/trunk/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll (added) +++ llvm/trunk/test/Transforms/LoopSimplify/2007-10-28-InvokeCrash.ll Sun Oct 28 21:30:37 2007 @@ -0,0 +1,892 @@ +; RUN: llvm-as < %s | opt -loopsimplify -disable-output +; PR1752 +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-s0:0:64-f80:32:32" +target triple = "i686-pc-mingw32" + %struct.BigInt = type { %"struct.std::vector >" } + %struct.Fibonacci = type { %"struct.std::vector >" } + %struct.__false_type = type <{ i8 }> + %"struct.__gnu_cxx::__normal_iterator > >" = type { %struct.BigInt* } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { %struct.BigInt*, %struct.BigInt*, %struct.BigInt* } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { i32*, i32*, i32* } + %"struct.std::basic_ios >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream >"*, i8, i8, %"struct.std::basic_streambuf >"*, %"struct.std::ctype"*, %"struct.std::num_get > >"*, %"struct.std::num_get > >"* } + %"struct.std::basic_ostream >" = type { i32 (...)**, %"struct.std::basic_ios >" } + %"struct.std::basic_streambuf >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" } + %"struct.std::basic_string,std::allocator >" = type { %"struct.std::basic_string,std::allocator >::_Alloc_hider" } + %"struct.std::basic_string,std::allocator >::_Alloc_hider" = type { i8* } + %"struct.std::basic_stringbuf,std::allocator >" = type { %"struct.std::basic_streambuf >", i32, %"struct.std::basic_string,std::allocator >" } + %"struct.std::ctype" = type { %"struct.std::locale::facet", i32*, i8, i32*, i32*, i16*, i8, [256 x i8], [256 x i8], i8 } + %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" } + %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 } + %"struct.std::ios_base::_Words" = type { i8*, i32 } + %"struct.std::locale" = type { %"struct.std::locale::_Impl"* } + %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** } + %"struct.std::locale::facet" = type { i32 (...)**, i32 } + %"struct.std::num_get > >" = type { %"struct.std::locale::facet" } + %"struct.std::ostringstream" = type { [4 x i8], %"struct.std::basic_stringbuf,std::allocator >", %"struct.std::basic_ios >" } + %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } + %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } + at .str13 = external constant [6 x i8] ; <[6 x i8]*> [#uses=1] + at .str14 = external constant [5 x i8] ; <[5 x i8]*> [#uses=1] + at .str15 = external constant [2 x i8] ; <[2 x i8]*> [#uses=1] + at _ZSt4cout = external global %"struct.std::basic_ostream >" ; <%"struct.std::basic_ostream >"*> [#uses=1] + +declare void @_ZN9Fibonacci10get_numberEj(%struct.BigInt* sret , %struct.Fibonacci*, i32) + +declare %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream >"*, i8*) + +declare void @_ZNSsD1Ev(%"struct.std::basic_string,std::allocator >"*) + +declare %"struct.std::basic_ostream >"* @_ZNSolsEm(%"struct.std::basic_ostream >"*, i32) + +declare void @_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv(%"struct.std::basic_string,std::allocator >"* sret , %"struct.std::ostringstream"*) + +declare %"struct.std::basic_ostream >"* @_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E(%"struct.std::basic_ostream >"*, %"struct.std::basic_string,std::allocator >"*) + +declare void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev(%"struct.std::ostringstream"*) + +declare %"struct.std::basic_ostream >"* @___ZlsRSoRK6BigInt___ZN9__gnu_cxx13new_allocatorI6BigIntE10deallocateEPS1_j(i32, %"struct.std::basic_ostream >"*, %struct.BigInt*, %struct.__false_type*, i32) + +declare void @___ZNSt12_Vector_baseI6BigIntSaIS0_EE13_M_deallocateEPS0_j___ZNSt12_Vector_baseI6BigIntSaIS0_EED2Ev___ZNSt6vectorI6BigIntSaIS0_EEC1ERKS1_(%"struct.std::_Vector_base >"*, i32, %struct.BigInt*, i32, %"struct.std::vector >"*, %struct.__false_type*) + +declare i32 @___ZN9__gnu_cxxmiIPK6BigIntS3_St6vectorIS1_SaIS1_EEEENS_17__normal_iteratorIT_T1_E15difference_typeERKSA_RKNS7_IT0_S9_EE___ZNKSt6vectorI6BigIntSaIS0_EE4sizeEv___ZNK9Fibonacci16show_all_numbersEv___ZNKSt6vectorI6BigIntSaIS0_EE8capacityEv(%"struct.__gnu_cxx::__normal_iterator > >"*, %"struct.__gnu_cxx::__normal_iterator > >"*, %"struct.std::vector >"*, i32, %struct.Fibonacci*) + +declare %struct.BigInt* @___ZNSt6vectorI6BigIntSaIS0_EEixEj___ZNSt6vectorI6BigIntSaIS0_EE3endEv(%"struct.std::vector >"*, i32, i32) + +declare %"struct.__gnu_cxx::__normal_iterator > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_(i32, %"struct.__gnu_cxx::__normal_iterator > >"*, %"struct.std::vector >"*, %struct.BigInt*, %struct.__false_type*, %struct.BigInt*, %struct.__false_type* noalias ) + +declare void @___ZNSt6vectorI6BigIntSaIS0_EED1Ev___ZN9FibonacciD1Ev___ZNSt6vectorImSaImEEC1ERKS0_(i32, %"struct.std::vector >"*, %struct.Fibonacci*, %"struct.std::vector >"*, %struct.__false_type*) + +define void @___ZN9FibonacciC1Ej___ZN9Fibonacci11show_numberEm(%struct.Fibonacci* %this_this, i32 %functionID, i32 %n_i_n_i) { +bb_init: + br label %bb_main + +bb_main: ; preds = %meshBB349, %meshBB348, %meshBB347, %meshBB346, %meshBB345.unwinddest, %meshBB345, %meshBB344, %meshBB343, %meshBB342, %meshBB341, %meshBB340.normaldest, %meshBB340, %meshBB339, %invcont17.normaldest.normaldest, %invcont17.normaldest, %meshBB338.unwinddest, %meshBB338, %meshBB337.unwinddest, %meshBB337, %meshBB336.unwinddest, %meshBB336, %meshBB335, %meshBB334, %meshBB333, %meshBB332, %meshBB331, %meshBB330.normaldest, %meshBB330, %meshBB329.normaldest, %meshBB329, %meshBB328, %meshBB327, %meshBB326, %meshBB325.unwinddest, %meshBB325, %meshBB324, %meshBB323.normaldest, %meshBB323, %meshBB322.unwinddest, %meshBB322, %meshBB321, %meshBB320.unwinddest, %meshBB320, %meshBB319.unwinddest, %meshBB319, %meshBB318.unwinddest, %meshBB318, %meshBB317, %meshBB37.fragment, %meshBB37.unwinddest, %meshBB37, %meshBB36.fragment, %meshBB36, %meshBB35.fragment, %meshBB35, %meshBB34.fragment, %meshBB34, %meshBB33.fragment, %meshBB33, %meshBB32.fragment, %meshBB32, %meshBB3! 1.fragment, %meshBB31, %meshBB30.fragment, %meshBB30.normaldest, %meshBB30, %meshBB29.fragment, %meshBB29.unwinddest, %meshBB29, %meshBB28.fragment, %meshBB28.unwinddest, %meshBB28, %meshBB27.fragment, %meshBB27, %meshBB26.fragment, %meshBB26.normaldest, %meshBB26, %meshBB25.fragment, %meshBB25, %meshBB24.fragment, %meshBB24.unwinddest, %meshBB24, %meshBB23.fragment, %meshBB23.normaldest, %meshBB23, %entry1.fragment.normaldest.normaldest, %entry1.fragment.normaldest, %meshBB22.fragment, %meshBB22.unwinddest, %meshBB22, %meshBB.fragment, %meshBB.unwinddest, %meshBB, %Unwind20, %unwind78.Unwind_crit_edge, %unwind78.fragment.fragment, %unwind78.fragment, %unwind78.fragment316, %unwind78, %invcont70, %unwind66.Unwind_crit_edge, %unwind66.fragment.fragment, %unwind66.fragment, %unwind66.fragment315, %unwind66, %unwind53.nofilter_crit_edge, %unwind53.fragment.fragment, %unwind53.fragment, %unwind53.fragment314, %unwind53, %nofilter.Unwind_crit_edge.normaldest, %nofilter.Unwind_cr! it_edge, %nofilter, %unwind43.nofilter_crit_edge, %unwind43.fr! agment.f ragment, %unwind43.fragment, %unwind43.fragment313, %unwind43, %invcont41.normaldest, %invcont41, %unwind37.nofilter_crit_edge, %unwind37, %invcont36, %invcont33.unwind_crit_edge.unwinddest, %invcont33.unwind_crit_edge, %invcont30.unwind_crit_edge.unwinddest, %invcont30.unwind_crit_edge, %invcont30.normaldest, %invcont30, %invcont28.unwind_crit_edge, %invcont28.normaldest, %invcont28, %invcont25.unwind_crit_edge.unwinddest, %invcont25.unwind_crit_edge, %invcont25, %invcont22.unwind_crit_edge, %invcont22, %invcont17.unwind_crit_edge, %invcont17, %cond_next.unwind_crit_edge, %cond_next, %invcont12.cond_next_crit_edge, %invcont12.unwind_crit_edge, %invcont12, %cond_true.unwind_crit_edge.unwinddest, %cond_true.unwind_crit_edge, %invcont.cond_next_crit_edge, %invcont16.fragment, %invcont16, %unwind11.fragment, %unwind11, %entry.unwind_crit_edge, %entry1.fragment, %entry1.fragment312, %entry1, %Unwind, %unwind20.Unwind_crit_edge, %unwind20.fragment.fragment, %unwind20.fragment, %u! nwind20.fragment311, %unwind20, %invcont15, %invcont14.unwind10_crit_edge, %invcont14, %unwind10.Unwind_crit_edge, %unwind10.fragment, %unwind10.fragment310, %unwind10, %invcont.unwind10_crit_edge, %invcont, %unwind.fragment, %unwind, %entry.fragment, %entry.fragment309, %entry, %NewDefault, %LeafBlock, %LeafBlock914, %NodeBlock, %comb_entry.fragment, %old_entry, %bb_init + switch i32 0, label %old_entry [ + i32 2739, label %invcont28.fragment + i32 2688, label %meshBB28.fragment + i32 1318, label %meshBB32.fragment + i32 2964, label %unwind53.fragment.fragment + i32 824, label %unwind78.fragment.fragment + i32 1983, label %meshBB33.fragment + i32 2582, label %invcont30.fragment + i32 2235, label %meshBB36.fragment + i32 1275, label %meshBB343 + i32 2719, label %invcont.fragment + i32 1500, label %entry1.fragment.fragment + i32 815, label %unwind11.fragment + i32 1051, label %entry + i32 2342, label %unwind + i32 1814, label %invcont + i32 315, label %invcont.unwind10_crit_edge + i32 2422, label %unwind10 + i32 2663, label %unwind10.Unwind_crit_edge + i32 266, label %invcont14 + i32 367, label %invcont14.unwind10_crit_edge + i32 2242, label %invcont15 + i32 452, label %unwind20 + i32 419, label %invcont.cond_next_crit_edge + i32 181, label %cond_true + i32 2089, label %unwind20.Unwind_crit_edge + i32 633, label %filter + i32 455, label %Unwind + i32 2016, label %entry1 + i32 263, label %invcont33.unwind_crit_edge + i32 2498, label %invcont36 + i32 2992, label %unwind37 + i32 616, label %entry.unwind_crit_edge + i32 622, label %unwind11 + i32 875, label %invcont16 + i32 766, label %unwind53.nofilter_crit_edge + i32 668, label %filter62 + i32 2138, label %unwind66 + i32 713, label %unwind66.Unwind_crit_edge + i32 1422, label %invcont70 + i32 1976, label %cond_true.unwind_crit_edge + i32 1263, label %invcont12 + i32 2453, label %invcont12.unwind_crit_edge + i32 2876, label %invcont12.cond_next_crit_edge + i32 2271, label %cond_next + i32 2938, label %cond_next.unwind_crit_edge + i32 1082, label %invcont17 + i32 531, label %invcont17.unwind_crit_edge + i32 111, label %invcont22 + i32 1935, label %invcont22.unwind_crit_edge + i32 2004, label %invcont25 + i32 1725, label %invcont25.unwind_crit_edge + i32 1701, label %invcont28 + i32 957, label %invcont28.unwind_crit_edge + i32 165, label %invcont30 + i32 899, label %invcont30.unwind_crit_edge + i32 1092, label %invcont33 + i32 2869, label %unwind37.nofilter_crit_edge + i32 203, label %invcont41 + i32 693, label %unwind43 + i32 2895, label %unwind43.nofilter_crit_edge + i32 1174, label %invcont47 + i32 1153, label %filter19 + i32 2304, label %nofilter + i32 848, label %nofilter.Unwind_crit_edge + i32 1207, label %unwind53 + i32 2848, label %filter75 + i32 59, label %unwind78 + i32 1213, label %unwind78.Unwind_crit_edge + i32 2199, label %filter87 + i32 1268, label %Unwind20 + i32 743, label %old_entry + i32 1276, label %meshBB319 + i32 1619, label %meshBB320 + i32 2047, label %meshBB331 + i32 2828, label %meshBB23.fragment + i32 2530, label %meshBB332 + i32 1389, label %meshBB318 + i32 1450, label %meshBB317 + i32 1416, label %meshBB31.fragment + i32 82, label %meshBB322 + i32 853, label %unwind78.fragment316 + i32 107, label %meshBB24.fragment + i32 1200, label %meshBB37.fragment + i32 605, label %unwind53.fragment314 + i32 209, label %meshBB29.fragment + i32 1513, label %meshBB27.fragment + i32 1542, label %meshBB35.fragment + i32 1873, label %meshBB348 + i32 472, label %meshBB325 + i32 2615, label %meshBB22.fragment + i32 359, label %meshBB.fragment + i32 2467, label %Unwind20.fragment + i32 1671, label %unwind66.fragment.fragment + i32 1006, label %meshBB25.fragment + i32 1243, label %meshBB333 + i32 2795, label %unwind43.fragment313 + i32 1591, label %meshBB335 + i32 773, label %meshBB341 + i32 2440, label %cond_next.fragment + i32 487, label %meshBB326 + i32 394, label %meshBB324 + i32 14, label %invcont16.fragment + i32 574, label %entry1.fragment312 + i32 1453, label %meshBB35 + i32 345, label %entry1.fragment + i32 2951, label %unwind20.fragment + i32 1960, label %meshBB31 + i32 2163, label %meshBB32 + i32 1978, label %Unwind.fragment + i32 1559, label %unwind20.fragment.fragment + i32 950, label %unwind10.fragment + i32 1724, label %unwind53.fragment + i32 514, label %meshBB36 + i32 1928, label %unwind10.fragment.fragment + i32 1266, label %meshBB26 + i32 3148, label %unwind20.fragment311 + i32 1581, label %unwind43.fragment + i32 1829, label %meshBB34 + i32 1472, label %meshBB28 + i32 2657, label %unwind66.fragment + i32 2169, label %meshBB22 + i32 2619, label %meshBB + i32 1397, label %entry.fragment + i32 231, label %invcont41.fragment + i32 2557, label %meshBB338 + i32 2387, label %meshBB30.fragment + i32 2927, label %meshBB340 + i32 2331, label %meshBB321 + i32 47, label %meshBB328 + i32 1753, label %meshBB342 + i32 2074, label %meshBB323 + i32 2128, label %meshBB334 + i32 2396, label %meshBB337 + i32 1811, label %meshBB29 + i32 1113, label %meshBB27 + i32 2232, label %unwind10.fragment310 + i32 804, label %meshBB24 + i32 3099, label %meshBB30 + i32 564, label %meshBB33 + i32 1359, label %unwind.fragment + i32 1906, label %entry.fragment309 + i32 2644, label %entry.fragment.fragment + i32 134, label %entry1.fragment.normaldest + i32 2767, label %comb_entry.fragment + i32 2577, label %meshBB25 + i32 3128, label %meshBB37 + i32 2360, label %meshBB23 + i32 286, label %unwind78.fragment + i32 976, label %meshBB346 + i32 2412, label %meshBB339 + i32 876, label %meshBB345 + i32 3078, label %meshBB329 + i32 1297, label %meshBB347 + i32 3051, label %meshBB336 + i32 1342, label %meshBB344 + i32 728, label %meshBB330 + i32 1778, label %meshBB349 + i32 2784, label %meshBB327 + i32 1854, label %meshBB26.fragment + i32 1025, label %meshBB34.fragment + i32 2139, label %unwind43.fragment.fragment + i32 2217, label %nofilter.fragment + i32 665, label %invcont12.fragment + i32 316, label %invcont22.fragment + i32 1467, label %unwind66.fragment315 + i32 3018, label %unwind37.fragment + i32 1123, label %invcont17.normaldest + i32 2104, label %NewDefault + i32 1639, label %LeafBlock + i32 925, label %LeafBlock914 + i32 2880, label %NodeBlock + ] + +old_entry: ; preds = %bb_main, %bb_main + br label %bb_main + +comb_entry.fragment: ; preds = %bb_main + br label %bb_main + +NodeBlock: ; preds = %bb_main + br label %bb_main + +LeafBlock914: ; preds = %bb_main + br label %bb_main + +LeafBlock: ; preds = %bb_main + br label %bb_main + +NewDefault: ; preds = %bb_main + br label %bb_main + +entry: ; preds = %bb_main + br label %bb_main + +entry.fragment309: ; preds = %bb_main + br label %bb_main + +entry.fragment: ; preds = %bb_main + br label %bb_main + +entry.fragment.fragment: ; preds = %bb_main + invoke void @___ZNSt12_Vector_baseI6BigIntSaIS0_EE13_M_deallocateEPS0_j___ZNSt12_Vector_baseI6BigIntSaIS0_EED2Ev___ZNSt6vectorI6BigIntSaIS0_EEC1ERKS1_( %"struct.std::_Vector_base >"* null, i32 28, %struct.BigInt* null, i32 0, %"struct.std::vector >"* null, %struct.__false_type* null ) + to label %meshBB340 unwind label %meshBB325 + +unwind: ; preds = %bb_main + br label %bb_main + +unwind.fragment: ; preds = %bb_main + br label %bb_main + +invcont: ; preds = %bb_main + br label %bb_main + +invcont.fragment: ; preds = %bb_main + invoke void @_ZN9Fibonacci10get_numberEj( %struct.BigInt* null sret , %struct.Fibonacci* %this_this, i32 %n_i_n_i ) + to label %invcont14 unwind label %meshBB37 + +invcont.unwind10_crit_edge: ; preds = %bb_main + br label %bb_main + +unwind10: ; preds = %bb_main + br label %bb_main + +unwind10.fragment310: ; preds = %bb_main + br label %bb_main + +unwind10.fragment: ; preds = %bb_main + br label %bb_main + +unwind10.fragment.fragment: ; preds = %bb_main + invoke void @___ZNSt6vectorI6BigIntSaIS0_EED1Ev___ZN9FibonacciD1Ev___ZNSt6vectorImSaImEEC1ERKS0_( i32 57, %"struct.std::vector >"* null, %struct.Fibonacci* null, %"struct.std::vector >"* null, %struct.__false_type* null ) + to label %meshBB329 unwind label %meshBB24 + +unwind10.Unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont14: ; preds = %invcont.fragment, %bb_main + br label %bb_main + +invcont14.normaldest: ; No predecessors! + invoke %"struct.__gnu_cxx::__normal_iterator > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_( i32 14, %"struct.__gnu_cxx::__normal_iterator > >"* null, %"struct.std::vector >"* null, %struct.BigInt* null, %struct.__false_type* null, %struct.BigInt* null, %struct.__false_type* null noalias ) + to label %invcont15 unwind label %meshBB345 ; <%"struct.__gnu_cxx::__normal_iterator > >"*>:0 [#uses=0] + +invcont14.unwind10_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont15: ; preds = %invcont14.normaldest, %bb_main + br label %bb_main + +invcont15.normaldest: ; No predecessors! + br label %UnifiedReturnBlock + +unwind20: ; preds = %bb_main + br label %bb_main + +unwind20.fragment311: ; preds = %bb_main + br label %bb_main + +unwind20.fragment: ; preds = %bb_main + br label %bb_main + +unwind20.fragment.fragment: ; preds = %bb_main + br label %bb_main + +unwind20.Unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +filter: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +Unwind: ; preds = %bb_main + br label %bb_main + +Unwind.fragment: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +entry1: ; preds = %bb_main + br label %bb_main + +entry1.fragment312: ; preds = %bb_main + br label %bb_main + +entry1.fragment: ; preds = %bb_main + br label %bb_main + +entry1.fragment.fragment: ; preds = %bb_main + %tmp52 = invoke i32 @___ZN9__gnu_cxxmiIPK6BigIntS3_St6vectorIS1_SaIS1_EEEENS_17__normal_iteratorIT_T1_E15difference_typeERKSA_RKNS7_IT0_S9_EE___ZNKSt6vectorI6BigIntSaIS0_EE4sizeEv___ZNK9Fibonacci16show_all_numbersEv___ZNKSt6vectorI6BigIntSaIS0_EE8capacityEv( %"struct.__gnu_cxx::__normal_iterator > >"* null, %"struct.__gnu_cxx::__normal_iterator > >"* null, %"struct.std::vector >"* null, i32 16, %struct.Fibonacci* null ) + to label %entry1.fragment.normaldest unwind label %meshBB320 ; [#uses=0] + +entry.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +unwind11: ; preds = %bb_main + br label %bb_main + +unwind11.fragment: ; preds = %bb_main + br label %bb_main + +invcont16: ; preds = %bb_main + br label %bb_main + +invcont16.fragment: ; preds = %bb_main + br label %bb_main + +invcont.cond_next_crit_edge: ; preds = %bb_main + br label %bb_main + +cond_true: ; preds = %bb_main + invoke void @_ZN9Fibonacci10get_numberEj( %struct.BigInt* null sret , %struct.Fibonacci* %this_this, i32 %n_i_n_i ) + to label %meshBB323 unwind label %cond_true.unwind_crit_edge + +cond_true.unwind_crit_edge: ; preds = %cond_true, %bb_main + br label %bb_main + +cond_true.unwind_crit_edge.unwinddest: ; No predecessors! + br label %bb_main + +invcont12: ; preds = %bb_main + br label %bb_main + +invcont12.fragment: ; preds = %bb_main + invoke %"struct.__gnu_cxx::__normal_iterator > >"* @___ZN9__gnu_cxx17__normal_iteratorIP6BigIntSt6vectorIS1_SaIS1_EEEppEv___ZNSt6vectorImSaImEED1Ev___ZN6BigIntD1Ev___ZN9__gnu_cxx13new_allocatorI6BigIntE7destroyEPS1____ZSt8_DestroyIP6BigIntSaIS0_EEvT_S3_T0_( i32 14, %"struct.__gnu_cxx::__normal_iterator > >"* null, %"struct.std::vector >"* null, %struct.BigInt* null, %struct.__false_type* null, %struct.BigInt* null, %struct.__false_type* null noalias ) + to label %meshBB30 unwind label %meshBB337 ; <%"struct.__gnu_cxx::__normal_iterator > >"*>:1 [#uses=0] + +invcont12.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont12.cond_next_crit_edge: ; preds = %bb_main + br label %bb_main + +cond_next: ; preds = %bb_main + br label %bb_main + +cond_next.fragment: ; preds = %bb_main + %tmp183 = invoke %struct.BigInt* @___ZNSt6vectorI6BigIntSaIS0_EEixEj___ZNSt6vectorI6BigIntSaIS0_EE3endEv( %"struct.std::vector >"* null, i32 %n_i_n_i, i32 29 ) + to label %invcont17 unwind label %meshBB336 ; <%struct.BigInt*> [#uses=0] + +cond_next.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont17: ; preds = %cond_next.fragment, %bb_main + br label %bb_main + +invcont17.normaldest917: ; No predecessors! + %tmp23 = invoke %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream >"* null, i8* getelementptr ([6 x i8]* @.str13, i32 0, i32 0) ) + to label %invcont17.normaldest unwind label %meshBB318 ; <%"struct.std::basic_ostream >"*> [#uses=1] + +invcont17.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont22: ; preds = %bb_main + br label %bb_main + +invcont22.fragment: ; preds = %bb_main + %tmp26 = invoke %"struct.std::basic_ostream >"* @_ZNSolsEm( %"struct.std::basic_ostream >"* undef, i32 %n_i_n_i ) + to label %invcont25 unwind label %meshBB319 ; <%"struct.std::basic_ostream >"*> [#uses=1] + +invcont22.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont25: ; preds = %invcont22.fragment, %bb_main + br label %bb_main + +invcont25.normaldest: ; No predecessors! + %tmp2918 = invoke %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream >"* %tmp26, i8* getelementptr ([5 x i8]* @.str14, i32 0, i32 0) ) + to label %invcont28 unwind label %invcont25.unwind_crit_edge ; <%"struct.std::basic_ostream >"*> [#uses=0] + +invcont25.unwind_crit_edge: ; preds = %invcont25.normaldest, %bb_main + br label %bb_main + +invcont25.unwind_crit_edge.unwinddest: ; No predecessors! + br label %bb_main + +invcont28: ; preds = %invcont25.normaldest, %bb_main + br label %bb_main + +invcont28.normaldest: ; No predecessors! + br label %bb_main + +invcont28.fragment: ; preds = %bb_main + %tmp311 = invoke %"struct.std::basic_ostream >"* @___ZlsRSoRK6BigInt___ZN9__gnu_cxx13new_allocatorI6BigIntE10deallocateEPS1_j( i32 32, %"struct.std::basic_ostream >"* undef, %struct.BigInt* undef, %struct.__false_type* null, i32 0 ) + to label %invcont30 unwind label %meshBB322 ; <%"struct.std::basic_ostream >"*> [#uses=0] + +invcont28.unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont30: ; preds = %invcont28.fragment, %bb_main + br label %bb_main + +invcont30.normaldest: ; No predecessors! + br label %bb_main + +invcont30.fragment: ; preds = %bb_main + %tmp34 = invoke %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc( %"struct.std::basic_ostream >"* undef, i8* getelementptr ([2 x i8]* @.str15, i32 0, i32 0) ) + to label %meshBB26 unwind label %invcont30.unwind_crit_edge ; <%"struct.std::basic_ostream >"*> [#uses=0] + +invcont30.unwind_crit_edge: ; preds = %invcont30.fragment, %bb_main + br label %bb_main + +invcont30.unwind_crit_edge.unwinddest: ; No predecessors! + br label %bb_main + +invcont33: ; preds = %bb_main + invoke void @_ZNKSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE3strEv( %"struct.std::basic_string,std::allocator >"* null sret , %"struct.std::ostringstream"* null ) + to label %invcont36 unwind label %invcont33.unwind_crit_edge + +invcont33.unwind_crit_edge: ; preds = %invcont33, %bb_main + br label %bb_main + +invcont33.unwind_crit_edge.unwinddest: ; No predecessors! + br label %bb_main + +invcont36: ; preds = %invcont33, %bb_main + br label %bb_main + +invcont36.normaldest: ; No predecessors! + %tmp42 = invoke %"struct.std::basic_ostream >"* @_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E( %"struct.std::basic_ostream >"* @_ZSt4cout, %"struct.std::basic_string,std::allocator >"* null ) + to label %invcont41 unwind label %meshBB338 ; <%"struct.std::basic_ostream >"*> [#uses=0] + +unwind37: ; preds = %bb_main + br label %bb_main + +unwind37.fragment: ; preds = %bb_main + invoke void @_ZNSsD1Ev( %"struct.std::basic_string,std::allocator >"* null ) + to label %meshBB330 unwind label %meshBB22 + +unwind37.nofilter_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont41: ; preds = %invcont36.normaldest, %bb_main + br label %bb_main + +invcont41.normaldest: ; No predecessors! + br label %bb_main + +invcont41.fragment: ; preds = %bb_main + invoke void @_ZNSsD1Ev( %"struct.std::basic_string,std::allocator >"* null ) + to label %meshBB23 unwind label %meshBB29 + +unwind43: ; preds = %bb_main + br label %bb_main + +unwind43.fragment313: ; preds = %bb_main + br label %bb_main + +unwind43.fragment: ; preds = %bb_main + br label %bb_main + +unwind43.fragment.fragment: ; preds = %bb_main + br label %bb_main + +unwind43.nofilter_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont47: ; preds = %bb_main + invoke void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev( %"struct.std::ostringstream"* null ) + to label %invcont70 unwind label %meshBB28 + +filter19: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +nofilter: ; preds = %bb_main + br label %bb_main + +nofilter.fragment: ; preds = %bb_main + invoke void @_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev( %"struct.std::ostringstream"* null ) + to label %nofilter.Unwind_crit_edge unwind label %meshBB + +nofilter.Unwind_crit_edge: ; preds = %nofilter.fragment, %bb_main + br label %bb_main + +nofilter.Unwind_crit_edge.normaldest: ; No predecessors! + br label %bb_main + +unwind53: ; preds = %bb_main + br label %bb_main + +unwind53.fragment314: ; preds = %bb_main + br label %bb_main + +unwind53.fragment: ; preds = %bb_main + br label %bb_main + +unwind53.fragment.fragment: ; preds = %bb_main + br label %bb_main + +unwind53.nofilter_crit_edge: ; preds = %bb_main + br label %bb_main + +filter62: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +unwind66: ; preds = %bb_main + br label %bb_main + +unwind66.fragment315: ; preds = %bb_main + br label %bb_main + +unwind66.fragment: ; preds = %bb_main + br label %bb_main + +unwind66.fragment.fragment: ; preds = %bb_main + br label %bb_main + +unwind66.Unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +invcont70: ; preds = %invcont47, %bb_main + br label %bb_main + +invcont70.normaldest: ; No predecessors! + br label %UnifiedReturnBlock + +filter75: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +unwind78: ; preds = %bb_main + br label %bb_main + +unwind78.fragment316: ; preds = %bb_main + br label %bb_main + +unwind78.fragment: ; preds = %bb_main + br label %bb_main + +unwind78.fragment.fragment: ; preds = %bb_main + br label %bb_main + +unwind78.Unwind_crit_edge: ; preds = %bb_main + br label %bb_main + +filter87: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +Unwind20: ; preds = %bb_main + br label %bb_main + +Unwind20.fragment: ; preds = %bb_main + br label %UnifiedUnreachableBlock + +meshBB: ; preds = %nofilter.fragment, %bb_main + br label %bb_main + +meshBB.unwinddest: ; No predecessors! + br label %bb_main + +meshBB.fragment: ; preds = %bb_main + br label %bb_main + +meshBB22: ; preds = %unwind37.fragment, %bb_main + br label %bb_main + +meshBB22.unwinddest: ; No predecessors! + br label %bb_main + +meshBB22.fragment: ; preds = %bb_main + br label %bb_main + +entry1.fragment.normaldest: ; preds = %entry1.fragment.fragment, %bb_main + br label %bb_main + +entry1.fragment.normaldest.normaldest: ; No predecessors! + br label %bb_main + +meshBB23: ; preds = %invcont41.fragment, %bb_main + br label %bb_main + +meshBB23.normaldest: ; No predecessors! + br label %bb_main + +meshBB23.fragment: ; preds = %bb_main + br label %bb_main + +meshBB24: ; preds = %unwind10.fragment.fragment, %bb_main + br label %bb_main + +meshBB24.unwinddest: ; No predecessors! + br label %bb_main + +meshBB24.fragment: ; preds = %bb_main + br label %bb_main + +meshBB25: ; preds = %bb_main + br label %bb_main + +meshBB25.fragment: ; preds = %bb_main + br label %bb_main + +meshBB26: ; preds = %invcont30.fragment, %bb_main + br label %bb_main + +meshBB26.normaldest: ; No predecessors! + br label %bb_main + +meshBB26.fragment: ; preds = %bb_main + br label %bb_main + +meshBB27: ; preds = %bb_main + br label %bb_main + +meshBB27.fragment: ; preds = %bb_main + br label %bb_main + +meshBB28: ; preds = %invcont47, %bb_main + br label %bb_main + +meshBB28.unwinddest: ; No predecessors! + br label %bb_main + +meshBB28.fragment: ; preds = %bb_main + br label %bb_main + +meshBB29: ; preds = %invcont41.fragment, %bb_main + br label %bb_main + +meshBB29.unwinddest: ; No predecessors! + br label %bb_main + +meshBB29.fragment: ; preds = %bb_main + br label %bb_main + +meshBB30: ; preds = %invcont12.fragment, %bb_main + br label %bb_main + +meshBB30.normaldest: ; No predecessors! + br label %bb_main + +meshBB30.fragment: ; preds = %bb_main + br label %bb_main + +meshBB31: ; preds = %bb_main + br label %bb_main + +meshBB31.fragment: ; preds = %bb_main + br label %bb_main + +meshBB32: ; preds = %bb_main + br label %bb_main + +meshBB32.fragment: ; preds = %bb_main + br label %bb_main + +meshBB33: ; preds = %bb_main + br label %bb_main + +meshBB33.fragment: ; preds = %bb_main + br label %bb_main + +meshBB34: ; preds = %bb_main + br label %bb_main + +meshBB34.fragment: ; preds = %bb_main + br label %bb_main + +meshBB35: ; preds = %bb_main + br label %bb_main + +meshBB35.fragment: ; preds = %bb_main + br label %bb_main + +meshBB36: ; preds = %bb_main + br label %bb_main + +meshBB36.fragment: ; preds = %bb_main + br label %bb_main + +meshBB37: ; preds = %invcont.fragment, %bb_main + br label %bb_main + +meshBB37.unwinddest: ; No predecessors! + br label %bb_main + +meshBB37.fragment: ; preds = %bb_main + br label %bb_main + +meshBB317: ; preds = %bb_main + br label %bb_main + +meshBB318: ; preds = %invcont17.normaldest917, %bb_main + br label %bb_main + +meshBB318.unwinddest: ; No predecessors! + br label %bb_main + +meshBB319: ; preds = %invcont22.fragment, %bb_main + br label %bb_main + +meshBB319.unwinddest: ; No predecessors! + br label %bb_main + +meshBB320: ; preds = %entry1.fragment.fragment, %bb_main + br label %bb_main + +meshBB320.unwinddest: ; No predecessors! + br label %bb_main + +meshBB321: ; preds = %bb_main + br label %bb_main + +meshBB322: ; preds = %invcont28.fragment, %bb_main + br label %bb_main + +meshBB322.unwinddest: ; No predecessors! + br label %bb_main + +meshBB323: ; preds = %cond_true, %bb_main + br label %bb_main + +meshBB323.normaldest: ; No predecessors! + br label %bb_main + +meshBB324: ; preds = %bb_main + br label %bb_main + +meshBB325: ; preds = %entry.fragment.fragment, %bb_main + br label %bb_main + +meshBB325.unwinddest: ; No predecessors! + br label %bb_main + +meshBB326: ; preds = %bb_main + br label %bb_main + +meshBB327: ; preds = %bb_main + br label %bb_main + +meshBB328: ; preds = %bb_main + br label %bb_main + +meshBB329: ; preds = %unwind10.fragment.fragment, %bb_main + br label %bb_main + +meshBB329.normaldest: ; No predecessors! + br label %bb_main + +meshBB330: ; preds = %unwind37.fragment, %bb_main + br label %bb_main + +meshBB330.normaldest: ; No predecessors! + br label %bb_main + +meshBB331: ; preds = %bb_main + br label %bb_main + +meshBB332: ; preds = %bb_main + br label %bb_main + +meshBB333: ; preds = %bb_main + br label %bb_main + +meshBB334: ; preds = %bb_main + br label %bb_main + +meshBB335: ; preds = %bb_main + br label %bb_main + +meshBB336: ; preds = %cond_next.fragment, %bb_main + br label %bb_main + +meshBB336.unwinddest: ; No predecessors! + br label %bb_main + +meshBB337: ; preds = %invcont12.fragment, %bb_main + br label %bb_main + +meshBB337.unwinddest: ; No predecessors! + br label %bb_main + +meshBB338: ; preds = %invcont36.normaldest, %bb_main + br label %bb_main + +meshBB338.unwinddest: ; No predecessors! + br label %bb_main + +invcont17.normaldest: ; preds = %invcont17.normaldest917, %bb_main + br label %bb_main + +invcont17.normaldest.normaldest: ; No predecessors! + store %"struct.std::basic_ostream >"* %tmp23, %"struct.std::basic_ostream >"** undef + br label %bb_main + +meshBB339: ; preds = %bb_main + br label %bb_main + +meshBB340: ; preds = %entry.fragment.fragment, %bb_main + br label %bb_main + +meshBB340.normaldest: ; No predecessors! + br label %bb_main + +meshBB341: ; preds = %bb_main + br label %bb_main + +meshBB342: ; preds = %bb_main + br label %bb_main + +meshBB343: ; preds = %bb_main + br label %bb_main + +meshBB344: ; preds = %bb_main + br label %bb_main + +meshBB345: ; preds = %invcont14.normaldest, %bb_main + br label %bb_main + +meshBB345.unwinddest: ; No predecessors! + br label %bb_main + +meshBB346: ; preds = %bb_main + br label %bb_main + +meshBB347: ; preds = %bb_main + br label %bb_main + +meshBB348: ; preds = %bb_main + br label %bb_main + +meshBB349: ; preds = %bb_main + br label %bb_main + +UnifiedUnreachableBlock: ; preds = %Unwind20.fragment, %filter87, %filter75, %filter62, %filter19, %Unwind.fragment, %filter + unreachable + +UnifiedReturnBlock: ; preds = %invcont70.normaldest, %invcont15.normaldest + ret void +} From sabre at nondot.org Sun Oct 28 21:40:02 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 29 Oct 2007 02:40:02 -0000 Subject: [llvm-commits] [llvm] r43427 - in /llvm/trunk: lib/Target/TargetData.cpp test/Transforms/InstCombine/2007-10-28-EmptyField.ll Message-ID: <200710290240.l9T2e3Uv005072@zion.cs.uiuc.edu> Author: lattner Date: Sun Oct 28 21:40:02 2007 New Revision: 43427 URL: http://llvm.org/viewvc/llvm-project?rev=43427&view=rev Log: Fix PR1749 and InstCombine/2007-10-28-EmptyField.ll by handling zero-length fields better. Added: llvm/trunk/test/Transforms/InstCombine/2007-10-28-EmptyField.ll Modified: llvm/trunk/lib/Target/TargetData.cpp Modified: llvm/trunk/lib/Target/TargetData.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetData.cpp?rev=43427&r1=43426&r2=43427&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetData.cpp (original) +++ llvm/trunk/lib/Target/TargetData.cpp Sun Oct 28 21:40:02 2007 @@ -83,9 +83,15 @@ assert(SI != &MemberOffsets[0] && "Offset not in structure type!"); --SI; assert(*SI <= Offset && "upper_bound didn't work"); - assert((SI == &MemberOffsets[0] || *(SI-1) < Offset) && + assert((SI == &MemberOffsets[0] || *(SI-1) <= Offset) && (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) && "Upper bound didn't work!"); + + // Multiple fields can have the same offset if any of them are zero sized. + // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop + // at the i32 element, because it is the last element at that offset. This is + // the right one to return, because anything after it will have a higher + // offset, implying that this element is non-empty. return SI-&MemberOffsets[0]; } Added: llvm/trunk/test/Transforms/InstCombine/2007-10-28-EmptyField.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/2007-10-28-EmptyField.ll?rev=43427&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/2007-10-28-EmptyField.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/2007-10-28-EmptyField.ll Sun Oct 28 21:40:02 2007 @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -instcombine -disable-output +; PR1749 + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.__large_struct = type { [100 x i64] } + %struct.compat_siginfo = type { i32, i32, i32, { [29 x i32] } } + %struct.siginfo_t = type { i32, i32, i32, { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] } } + %struct.sigval_t = type { i8* } + +define i32 @copy_siginfo_to_user32(%struct.compat_siginfo* %to, %struct.siginfo_t* %from) { +entry: + %from_addr = alloca %struct.siginfo_t* ; <%struct.siginfo_t**> [#uses=1] + %tmp344 = load %struct.siginfo_t** %from_addr, align 8 ; <%struct.siginfo_t*> [#uses=1] + %tmp345 = getelementptr %struct.siginfo_t* %tmp344, i32 0, i32 3 ; <{ { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }*> [#uses=1] + %tmp346 = getelementptr { { i32, i32, [0 x i8], %struct.sigval_t, i32 }, [88 x i8] }* %tmp345, i32 0, i32 0 ; <{ i32, i32, [0 x i8], %struct.sigval_t, i32 }*> [#uses=1] + %tmp346347 = bitcast { i32, i32, [0 x i8], %struct.sigval_t, i32 }* %tmp346 to { i32, i32, %struct.sigval_t }* ; <{ i32, i32, %struct.sigval_t }*> [#uses=1] + %tmp348 = getelementptr { i32, i32, %struct.sigval_t }* %tmp346347, i32 0, i32 2 ; <%struct.sigval_t*> [#uses=1] + %tmp349 = getelementptr %struct.sigval_t* %tmp348, i32 0, i32 0 ; [#uses=1] + %tmp349350 = bitcast i8** %tmp349 to i32* ; [#uses=1] + %tmp351 = load i32* %tmp349350, align 8 ; [#uses=1] + %tmp360 = call i32 asm sideeffect "1:\09movl ${1:k},$2\0A2:\0A.section .fixup,\22ax\22\0A3:\09mov $3,$0\0A\09jmp 2b\0A.previous\0A.section __ex_table,\22a\22\0A\09.align 8\0A\09.quad 1b,3b\0A.previous", "=r,ir,*m,i,0,~{dirflag},~{fpsr},~{flags}"( i32 %tmp351, %struct.__large_struct* null, i32 -14, i32 0 ) ; [#uses=0] + unreachable +} From sabre at nondot.org Sun Oct 28 22:09:08 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 29 Oct 2007 03:09:08 -0000 Subject: [llvm-commits] [llvm] r43430 - in /llvm/trunk: lib/Target/X86/X86ATTAsmPrinter.cpp test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll Message-ID: <200710290309.l9T398jW006463@zion.cs.uiuc.edu> Author: lattner Date: Sun Oct 28 22:09:07 2007 New Revision: 43430 URL: http://llvm.org/viewvc/llvm-project?rev=43430&view=rev Log: Add support for the x86-64 'q' regigster modifier, and add support for the b/h/w/k/q inline asm memory modifiers, which are just ignored. This fixes PR1748 and CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll Added: llvm/trunk/test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Modified: llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp?rev=43430&r1=43429&r2=43430&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ATTAsmPrinter.cpp Sun Oct 28 22:09:07 2007 @@ -521,6 +521,9 @@ case 'k': // Print SImode register Reg = getX86SubSuperRegister(Reg, MVT::i32); break; + case 'q': // Print DImode register + Reg = getX86SubSuperRegister(Reg, MVT::i64); + break; } O << '%'; @@ -547,6 +550,7 @@ case 'h': // Print QImode high register case 'w': // Print HImode register case 'k': // Print SImode register + case 'q': // Print DImode register if (MI->getOperand(OpNo).isRegister()) return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]); printOperand(MI, OpNo); @@ -566,8 +570,20 @@ unsigned OpNo, unsigned AsmVariant, const char *ExtraCode) { - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier. + if (ExtraCode && ExtraCode[0]) { + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: return true; // Unknown modifier. + case 'b': // Print QImode register + case 'h': // Print QImode high register + case 'w': // Print HImode register + case 'k': // Print SImode register + case 'q': // Print SImode register + // These only apply to registers, ignore on mem. + break; + } + } printMemReference(MI, OpNo); return false; } Added: llvm/trunk/test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll?rev=43430&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll (added) +++ llvm/trunk/test/CodeGen/X86/2007-10-28-inlineasm-q-modifier.ll Sun Oct 28 22:09:07 2007 @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc +; PR1748 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @kernel_init(i8* %unused) { +entry: + call void asm sideeffect "foo ${0:q}", "=*imr"( i64* null ) + ret i32 0 +} + From sabre at nondot.org Sun Oct 28 22:14:56 2007 From: sabre at nondot.org (Chris Lattner) Date: Mon, 29 Oct 2007 03:14:56 -0000 Subject: [llvm-commits] [llvm] r43431 - /llvm/trunk/lib/VMCore/Verifier.cpp Message-ID: <200710290314.l9T3Eu2T006753@zion.cs.uiuc.edu> Author: lattner Date: Sun Oct 28 22:14:55 2007 New Revision: 43431 URL: http://llvm.org/viewvc/llvm-project?rev=43431&view=rev Log: I am not sure this is a good idea to be an option, but rename the option for now. It conflicts with clang's -pedantic flag. Modified: llvm/trunk/lib/VMCore/Verifier.cpp Modified: llvm/trunk/lib/VMCore/Verifier.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=43431&r1=43430&r2=43431&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Verifier.cpp (original) +++ llvm/trunk/lib/VMCore/Verifier.cpp Sun Oct 28 22:14:55 2007 @@ -69,7 +69,7 @@ namespace { // Anonymous namespace for class cl::opt - Pedantic("pedantic", + Pedantic("verify-pedantic", cl::desc("Reject code with undefined behaviour")); struct VISIBILITY_HIDDEN From clattner at apple.com Sun Oct 28 22:17:05 2007 From: clattner at apple.com (Chris Lattner) Date: Sun, 28 Oct 2007 20:17:05 -0700 Subject: [llvm-commits] [llvm] r43424 - /llvm/trunk/lib/VMCore/Verifier.cpp In-Reply-To: <200710282250.l9SMoWI9028509@zion.cs.uiuc.edu> References: <200710282250.l9SMoWI9028509@zion.cs.uiuc.edu> Message-ID: <5B46F47E-569B-40BA-B7EC-ACD95F5DFC60@apple.com> On Oct 28, 2007, at 3:50 PM, Anton Korobeynikov wrote: > Author: asl > Date: Sun Oct 28 17:50:32 2007 > New Revision: 43424 > > URL: http://llvm.org/viewvc/llvm-project?rev=43424&view=rev > Log: > Add 'pedantic' mode to verifier rejecting syntactically valid, but > 'bad' due to other reasons code I renamed the option, but independently of that, I don't think this is a good idea. The goal for this option is to support front-end who want to use the verifier to catch things are are likely to be malformed IR that they are constructing. As such, this should be added to the *API* for verifier, not as a command line option. What do you think? -Chris From resistor at mac.com Sun Oct 28 23:50:50 2007 From: resistor at mac.com (Owen Anderson) Date: Mon, 29 Oct 2007 04:50:50 -0000 Subject: [llvm-commits] [llvm] r43438 - in /llvm/trunk/include/llvm: Analysis/Dominators.h CodeGen/MachineDominators.h Message-ID: <200710290450.l9T4oobQ010589@zion.cs.uiuc.edu> Author: resistor Date: Sun Oct 28 23:50:50 2007 New Revision: 43438 URL: http://llvm.org/viewvc/llvm-project?rev=43438&view=rev Log: Add a first attempt at dominator information for MBB's. Use with caution: this has been tested to compile. It has not yet been confirmed to generate correct analysis. Added: llvm/trunk/include/llvm/CodeGen/MachineDominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h Modified: llvm/trunk/include/llvm/Analysis/Dominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Dominators.h?rev=43438&r1=43437&r2=43438&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/Dominators.h (original) +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Oct 28 23:50:50 2007 @@ -105,7 +105,7 @@ void setIDom(DomTreeNodeBase *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { - std::vector*>::iterator I = + typename std::vector*>::iterator I = std::find(IDom->Children.begin(), IDom->Children.end(), this); assert(I != IDom->Children.end() && "Not in immediate dominator children set!"); @@ -267,7 +267,7 @@ // Find NewBB's immediate dominator and create new dominator tree node for // NewBB. - BasicBlock *NewBBIDom = 0; + NodeT *NewBBIDom = 0; unsigned i = 0; for (i = 0; i < PredBlocks.size(); ++i) if (DT.isReachableFromEntry(PredBlocks[i])) { @@ -282,12 +282,12 @@ assert(NewBBIDom && "No immediate dominator found??"); // Create the new dominator tree node... and set the idom of NewBB. - DomTreeNode *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); + DomTreeNodeBase *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom); // If NewBB strictly dominates other blocks, then it is now the immediate // dominator of NewBBSucc. Update the dominator tree as appropriate. if (NewBBDominatesNewBBSucc) { - DomTreeNode *NewBBSuccNode = DT.getNode(NewBBSucc); + DomTreeNodeBase *NewBBSuccNode = DT.getNode(NewBBSucc); DT.changeImmediateDominator(NewBBSuccNode, NewBBNode); } } @@ -348,7 +348,7 @@ const bool isReachableFromEntry(NodeT* A) { assert (!this->isPostDominator() && "This is not implemented for post dominators"); - return dominates(&A->getParent()->getEntryBlock(), A); + return dominates(&A->getParent()->front(), A); } /// dominates - Returns true iff A dominates B. Note that this is not a @@ -398,7 +398,7 @@ && "Two blocks are not in same function"); // If either A or B is a entry block then it is nearest common dominator. - NodeT &Entry = A->getParent()->getEntryBlock(); + NodeT &Entry = A->getParent()->front(); if (A == &Entry || B == &Entry) return &Entry; @@ -447,7 +447,7 @@ assert(IDomNode && "Not immediate dominator specified for block!"); DFSInfoValid = false; return DomTreeNodes[BB] = - IDomNode->addChild(new DomTreeNode(BB, IDomNode)); + IDomNode->addChild(new DomTreeNodeBase(BB, IDomNode)); } /// changeImmediateDominator - This method is used to update the dominator Added: llvm/trunk/include/llvm/CodeGen/MachineDominators.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineDominators.h?rev=43438&view=auto ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineDominators.h (added) +++ llvm/trunk/include/llvm/CodeGen/MachineDominators.h Sun Oct 28 23:50:50 2007 @@ -0,0 +1,170 @@ +//=- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation --*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Owen Anderson and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes mirroring those in llvm/Analysis/Dominators.h, +// but for target-specific code rather than target-independent IR. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H +#define LLVM_CODEGEN_MACHINEDOMINATORS_H + +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DominatorInternals.h" + +namespace llvm { + +void WriteAsOperand(std::ostream &, const MachineBasicBlock*, bool t) { } + +//===------------------------------------- +/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to +/// compute a normal dominator tree. +/// +class MachineDominatorTree : public MachineFunctionPass { +public: + static char ID; // Pass ID, replacement for typeid + DominatorTreeBase* DT; + + MachineDominatorTree() : MachineFunctionPass(intptr_t(&ID)) { + DT = new DominatorTreeBase(false); + } + + ~MachineDominatorTree() { + DT->releaseMemory(); + delete DT; + } + + /// getRoots - Return the root blocks of the current CFG. This may include + /// multiple blocks if we are computing post dominators. For forward + /// dominators, this will always be a single block (the entry node). + /// + inline const std::vector &getRoots() const { + return DT->getRoots(); + } + + inline MachineBasicBlock *getRoot() const { + return DT->getRoot(); + } + + inline MachineDomTreeNode *getRootNode() const { + return DT->getRootNode(); + } + + virtual bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + + inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const { + return DT->dominates(A, B); + } + + inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const { + return DT->dominates(A, B); + } + + // dominates - Return true if A dominates B. This performs the + // special checks necessary if A and B are in the same basic block. + bool dominates(MachineInstr *A, MachineInstr *B) const { + MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); + if (BBA != BBB) return DT->dominates(BBA, BBB); + + // Loop through the basic block until we find A or B. + MachineBasicBlock::iterator I = BBA->begin(); + for (; &*I != A && &*I != B; ++I) /*empty*/; + + //if(!DT.IsPostDominators) { + // A dominates B if it is found first in the basic block. + return &*I == A; + //} else { + // // A post-dominates B if B is found first in the basic block. + // return &*I == B; + //} + } + + inline bool properlyDominates(const MachineDomTreeNode* A, + MachineDomTreeNode* B) const { + return DT->properlyDominates(A, B); + } + + inline bool properlyDominates(MachineBasicBlock* A, + MachineBasicBlock* B) const { + return DT->properlyDominates(A, B); + } + + /// findNearestCommonDominator - Find nearest common dominator basic block + /// for basic block A and B. If there is no such block then return NULL. + inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, + MachineBasicBlock *B) { + return DT->findNearestCommonDominator(A, B); + } + + inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { + return DT->getNode(BB); + } + + /// getNode - return the (Post)DominatorTree node for the specified basic + /// block. This is the same as using operator[] on this class. + /// + inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { + return DT->getNode(BB); + } + + /// addNewBlock - Add a new node to the dominator tree information. This + /// creates a new node as a child of DomBB dominator node,linking it into + /// the children list of the immediate dominator. + inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB, + MachineBasicBlock *DomBB) { + return DT->addNewBlock(BB, DomBB); + } + + /// changeImmediateDominator - This method is used to update the dominator + /// tree information when a node's immediate dominator changes. + /// + inline void changeImmediateDominator(MachineBasicBlock *N, + MachineBasicBlock* NewIDom) { + DT->changeImmediateDominator(N, NewIDom); + } + + inline void changeImmediateDominator(MachineDomTreeNode *N, + MachineDomTreeNode* NewIDom) { + DT->changeImmediateDominator(N, NewIDom); + } + + /// eraseNode - Removes a node from the dominator tree. Block must not + /// domiante any other blocks. Removes node from its immediate dominator's + /// children list. Deletes dominator node associated with basic block BB. + inline void eraseNode(MachineBasicBlock *BB) { + DT->eraseNode(BB); + } + + /// splitBlock - BB is split and now it has one successor. Update dominator + /// tree to reflect this change. + inline void splitBlock(MachineBasicBlock* NewBB) { + DT->splitBlock(NewBB); + } + + + virtual void releaseMemory() { + DT->releaseMemory(); + } + + virtual void print(std::ostream &OS, const Module* M= 0) const { + DT->print(OS, M); + } +}; + +} + +#endif \ No newline at end of file
      ANALYSIS PASSES
      OptionNameDirectory
      ANALYSIS PASSES
      OptionName
      -aa-evalExhaustive Alias Analysis Precision Evaluator
      -anders-aaAndersen's Interprocedural Alias Analysis
      -basicaaBasic Alias Analysis (default AA impl)
      -targetdataTarget Data Layout
      TRANSFORM PASSES
      OptionNameDirectory
      TRANSFORM PASSES
      OptionName
      -adceAggressive Dead Code Elimination
      -argpromotionPromote 'by reference' arguments to scalars
      -block-placementProfile Guided Basic Block Placement
      -tailduplicateTail Duplication
      UTILITY PASSES
      OptionNameDirectory
      UTILITY PASSES
      OptionName
      -deadarghaX0rDead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)
      -extract-blocksExtract Basic Blocks From Module (for bugpoint use)
      -emitbitcodeBitcode Writer
      -domtreeDominator Tree Construction
      -externalfnconstantsPrint external fn callsites passed constants
      -globalsmodref-aaSimple mod/ref analysis for globals
      -gvnGlobal Value Numbering
      -instcountCounts the various types of Instructions
      -intervalsInterval Partition Construction
      -load-vnLoad Value Numbering
      -gcseGlobal Common Subexpression Elimination
      -globaldceDead Global Elimination
      -globaloptGlobal Variable Optimizer
      -gvnGlobal Value Numbering
      -gvnpreGlobal Value Numbering/Partial Redundancy Elimination
      -indmemremIndirect Malloc and Free Removal
      -indvarsCanonicalize Induction Variables